Sync
This commit is contained in:
parent
6ee1cd793f
commit
5657184b08
@ -27,6 +27,9 @@
|
|||||||
</button>
|
</button>
|
||||||
</summary>
|
</summary>
|
||||||
<article>
|
<article>
|
||||||
|
<button class="classic" style="width: 100%;" onclick="system.call('app::devtools')">
|
||||||
|
Déconnexion
|
||||||
|
</button>
|
||||||
<button class="classic" style="background-color: #aa3939; width: 100%;" onclick="logout()">
|
<button class="classic" style="background-color: #aa3939; width: 100%;" onclick="logout()">
|
||||||
Déconnexion
|
Déconnexion
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
11
config.json
11
config.json
@ -3,12 +3,15 @@
|
|||||||
"base": "http://localhost:8535",
|
"base": "http://localhost:8535",
|
||||||
"endpoints": {
|
"endpoints": {
|
||||||
"fileHash": "/api/v1/file/hash/",
|
"fileHash": "/api/v1/file/hash/",
|
||||||
"checkBanStatus": "/api/v1/ban/iam"
|
"checkBanStatus": "/api/v1/ban/iam",
|
||||||
|
"telemetry": "/api/v1/telemetry",
|
||||||
|
"gameFiles": "/api/v1/file/game",
|
||||||
|
"downloadFile": "/api/v1/file/game/download"
|
||||||
},
|
},
|
||||||
"websockets": {
|
"websockets": {
|
||||||
"base": "wss://localhost:8535",
|
"base": {
|
||||||
"rooms": {
|
"host": "wss://localhost",
|
||||||
"updateGameFiles": "/game/updates"
|
"port": "8535"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
89
main.js
89
main.js
@ -1,14 +1,24 @@
|
|||||||
const { BrowserWindow, app, net, dialog, ipcMain, nativeImage, session, shell } = require("electron")
|
const { BrowserWindow, app, net, dialog, ipcMain, nativeImage, session, shell } = require("electron")
|
||||||
const msmc = require("msmc")
|
const msmc = require("msmc")
|
||||||
const os = require("os")
|
const os = require("node:os")
|
||||||
const hwid = require("./modules/hwid")
|
const fs = require("node:fs")
|
||||||
const path = require("node:path")
|
const path = require("node:path")
|
||||||
|
const hwid = require("./modules/hwid")
|
||||||
const serverPing = require("./modules/serverPing")
|
const serverPing = require("./modules/serverPing")
|
||||||
const gameOptions = require("./modules/gameOptions")
|
const gameOptions = require("./modules/gameOptions")
|
||||||
const launcherSettings = require("./modules/launcherSettings")
|
const launcherSettings = require("./modules/launcherSettings")
|
||||||
const config = require("./config.json")
|
const config = require("./config.json")
|
||||||
const { Authenticator } = require("minecraft-launcher-core")
|
const { Authenticator, Client } = require("minecraft-launcher-core")
|
||||||
let launcherWindow, auth
|
const fileManager = require("./modules/fileManager")
|
||||||
|
const launcher = new Client()
|
||||||
|
const { io } = require("socket.io-client")
|
||||||
|
const download = require("download")
|
||||||
|
const socket = io({
|
||||||
|
host: config.api.websockets.base.host,
|
||||||
|
port: config.api.websockets.base.port
|
||||||
|
})
|
||||||
|
|
||||||
|
let launcherWindow, auth, gamePlayable = false
|
||||||
|
|
||||||
async function createLauncherWindow() {
|
async function createLauncherWindow() {
|
||||||
gameOptions.initOptions(path.join(app.getPath("appData"), ".catboat", "options.txt"))
|
gameOptions.initOptions(path.join(app.getPath("appData"), ".catboat", "options.txt"))
|
||||||
@ -62,7 +72,6 @@ async function createLauncherWindow() {
|
|||||||
redirectURL: redirectUrl
|
redirectURL: redirectUrl
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
session.defaultSession.webRequest.onHeadersReceived({
|
session.defaultSession.webRequest.onHeadersReceived({
|
||||||
urls: [
|
urls: [
|
||||||
"https://www.twitch.tv/*",
|
"https://www.twitch.tv/*",
|
||||||
@ -87,7 +96,7 @@ async function createLauncherWindow() {
|
|||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dialog.showErrorBox("Erreur", error)
|
dialog.showErrorBox("Erreur", error.toString())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dialog.showErrorBox("Connexion internet", "Le launcher requiert une connexion internet.")
|
dialog.showErrorBox("Connexion internet", "Le launcher requiert une connexion internet.")
|
||||||
@ -171,6 +180,7 @@ ipcMain.on("call", async (event, data) => {
|
|||||||
case "auth::mojang":
|
case "auth::mojang":
|
||||||
if (data.args.trim() != "") {
|
if (data.args.trim() != "") {
|
||||||
auth = Authenticator.getAuth(data.args.username, data.args.password)
|
auth = Authenticator.getAuth(data.args.username, data.args.password)
|
||||||
|
await fetch(`${config.api.base}${config.api.endpoints.telemetry}/${hwid.getHWID()}/${(await auth).uuid}`)
|
||||||
await launcherWindow.loadFile(path.join(__dirname, "app", "logged.html"))
|
await launcherWindow.loadFile(path.join(__dirname, "app", "logged.html"))
|
||||||
} else {
|
} else {
|
||||||
dialog.showErrorBox("Erreur", "Le mot de passe n'est pas défini. Les comptes crackés ne sont pas supporté par le launcher.")
|
dialog.showErrorBox("Erreur", "Le mot de passe n'est pas défini. Les comptes crackés ne sont pas supporté par le launcher.")
|
||||||
@ -182,10 +192,10 @@ ipcMain.on("call", async (event, data) => {
|
|||||||
const xboxManager = await authManager.launch("raw")
|
const xboxManager = await authManager.launch("raw")
|
||||||
const token = await xboxManager.getMinecraft()
|
const token = await xboxManager.getMinecraft()
|
||||||
auth = token.mclc()
|
auth = token.mclc()
|
||||||
console.log(auth)
|
await fetch(`${config.api.base}${config.api.endpoints.telemetry}/${hwid.getHWID()}/${auth.uuid}`)
|
||||||
await launcherWindow.loadFile(path.join(__dirname, "app", "logged.html"))
|
await launcherWindow.loadFile(path.join(__dirname, "app", "logged.html"))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.error(error)
|
||||||
if (error == "error.gui.closed") {
|
if (error == "error.gui.closed") {
|
||||||
launcherWindow.webContents.send("Response<auth::microsoft>")
|
launcherWindow.webContents.send("Response<auth::microsoft>")
|
||||||
}
|
}
|
||||||
@ -200,18 +210,20 @@ ipcMain.on("call", async (event, data) => {
|
|||||||
const minecraft = await xboxManager.getMinecraft()
|
const minecraft = await xboxManager.getMinecraft()
|
||||||
auth = minecraft.mclc()
|
auth = minecraft.mclc()
|
||||||
await launcherWindow.loadFile(path.join(__dirname, "app", "logged.html"))
|
await launcherWindow.loadFile(path.join(__dirname, "app", "logged.html"))
|
||||||
|
await fetch(`${config.api.base}${config.api.endpoints.telemetry}/${hwid.getHWID()}/${auth.uuid}`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dialog.showErrorBox("Erreur lors de la connexion via token", error)
|
dialog.showErrorBox("Erreur lors de la connexion via token", error)
|
||||||
console.log(error)
|
console.error(error)
|
||||||
launcherWindow.webContents.send("Response<auth::refresh>")
|
launcherWindow.webContents.send("Response<auth::refresh>")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
auth = Authenticator.refreshAuth(user.access_token, user.client_token)
|
auth = Authenticator.refreshAuth(user.access_token, user.client_token)
|
||||||
await launcherWindow.loadFile(path.join(__dirname, "app", "logged.html"))
|
await launcherWindow.loadFile(path.join(__dirname, "app", "logged.html"))
|
||||||
|
await fetch(`${config.api.base}${config.api.endpoints.telemetry}/${hwid.getHWID()}/${(await auth).uuid}`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dialog.showErrorBox("Erreur lors de la connexion via token", error)
|
dialog.showErrorBox("Erreur lors de la connexion via token", error)
|
||||||
console.log(error)
|
console.error(error)
|
||||||
launcherWindow.webContents.send("Response<auth::refresh>")
|
launcherWindow.webContents.send("Response<auth::refresh>")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -255,5 +267,62 @@ ipcMain.on("call", async (event, data) => {
|
|||||||
const $launcherSettings = launcherSettings.readSettings()
|
const $launcherSettings = launcherSettings.readSettings()
|
||||||
launcherWindow.webContents.send("Response<settings::read>", $launcherSettings)
|
launcherWindow.webContents.send("Response<settings::read>", $launcherSettings)
|
||||||
break
|
break
|
||||||
|
case "game::launch":
|
||||||
|
const downloadQueue = []
|
||||||
|
const remoteFiles = await fileManager.getRemoteFiles()
|
||||||
|
const localFiles = fs.readdirSync(path.join(app.getPath("appData"), ".catboat"), { recursive: true })
|
||||||
|
launcherWindow.setProgressBar(10, {
|
||||||
|
mode: "indeterminate"
|
||||||
|
})
|
||||||
|
for (const remoteFile of remoteFiles) {
|
||||||
|
try {
|
||||||
|
const localFile = localFiles.find(file => file === remoteFile)
|
||||||
|
|
||||||
|
if (!localFile) {
|
||||||
|
downloadQueue.push(remoteFile)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const localHash = await fileManager.getFileHash(path.join(app.getPath("appData"), ".catboat", localFile))
|
||||||
|
const remoteHash = await fileManager.getRemoteFileHash(localFile)
|
||||||
|
if (localHash != remoteHash) {
|
||||||
|
downloadQueue.push(localFile)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const localFile of localFiles) {
|
||||||
|
if (!remoteFiles.find(remoteFile => remoteFile.path == localFile) && localFile.startsWith("/mods")) {
|
||||||
|
fs.unlinkSync(path.join(app.getPath("appData"), ".catboat", localFile))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const item of downloadQueue) {
|
||||||
|
const url = `${config.api.base}${config.api.endpoints.downloadFile}/${new String(item).replace(/\\/g, "/")}`
|
||||||
|
try {
|
||||||
|
await download(url, path.join(app.getPath("appData"), ".catboat", path.dirname(item)))
|
||||||
|
launcherWindow.setProgressBar(((downloadQueue.indexOf(item) + 1) / downloadQueue.length) * 100, {
|
||||||
|
mode: "normal"
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
launcherWindow.setProgressBar(((downloadQueue.indexOf(item) + 1) / downloadQueue.length) * 100, {
|
||||||
|
mode: "error"
|
||||||
|
})
|
||||||
|
dialog.showErrorBox("Erreur lors du téléchargement des fichiers", error.toString())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
launcherWindow.setProgressBar(0, {
|
||||||
|
mode: "none"
|
||||||
|
})
|
||||||
|
dialog.showMessageBox(launcherWindow, {
|
||||||
|
title: "Téléchargement des fichiers",
|
||||||
|
message: "Téléchargement fini."
|
||||||
|
})
|
||||||
|
break
|
||||||
|
case "app::devtools":
|
||||||
|
launcherWindow.webContents.openDevTools()
|
||||||
|
break
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -1,18 +0,0 @@
|
|||||||
const msmc = require("msmc")
|
|
||||||
const { Authenticator } = require("minecraft-launcher-core")
|
|
||||||
|
|
||||||
async function getMicrosoftAuth() {
|
|
||||||
const authManager = new msmc.Auth("select_account")
|
|
||||||
const xboxManager = await authManager.launch("raw")
|
|
||||||
const token = await xboxManager.getMinecraft()
|
|
||||||
return token.mclc()
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMojangAuth(username, password) {
|
|
||||||
return Authenticator.getAuth(username, password)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
getMicrosoftAuth,
|
|
||||||
getMojangAuth
|
|
||||||
}
|
|
||||||
@ -4,6 +4,17 @@ const https = require("node:https")
|
|||||||
const crypto = require("node:crypto")
|
const crypto = require("node:crypto")
|
||||||
const config = require("../config.json")
|
const config = require("../config.json")
|
||||||
|
|
||||||
|
async function getRemoteFiles() {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${config.api.base}${config.api.endpoints.gameFiles}`)
|
||||||
|
console.log(response.url)
|
||||||
|
const json = await response.json()
|
||||||
|
return json
|
||||||
|
} catch (error) {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function downloadFile(url, destination, hash) {
|
async function downloadFile(url, destination, hash) {
|
||||||
const file = fs.createWriteStream(destination)
|
const file = fs.createWriteStream(destination)
|
||||||
const protocol = url.startsWith("https://") ? http : https
|
const protocol = url.startsWith("https://") ? http : https
|
||||||
@ -73,8 +84,21 @@ async function checkFilesHash(root) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getRemoteFileHash(filePath) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${config.api.base}${config.api.endpoints.fileHash}/${filePath}`)
|
||||||
|
const text = await response.text()
|
||||||
|
return text
|
||||||
|
} catch (error) {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
getFileHash,
|
||||||
downloadFile,
|
downloadFile,
|
||||||
checkFileHash,
|
checkFileHash,
|
||||||
checkFilesHash
|
checkFilesHash,
|
||||||
|
getRemoteFiles,
|
||||||
|
getRemoteFileHash
|
||||||
}
|
}
|
||||||
0
modules/gameFiles.js
Normal file
0
modules/gameFiles.js
Normal file
1013
package-lock.json
generated
1013
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -24,6 +24,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"discord-rpc": "^4.0.1",
|
"discord-rpc": "^4.0.1",
|
||||||
|
"download": "^8.0.0",
|
||||||
"minecraft-launcher-core": "^3.18.2",
|
"minecraft-launcher-core": "^3.18.2",
|
||||||
"msmc": "^5.0.5",
|
"msmc": "^5.0.5",
|
||||||
"socket.io-client": "^4.8.1"
|
"socket.io-client": "^4.8.1"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user