Add code to launch games
This commit is contained in:
parent
a748c07a8d
commit
cfde9a9119
126
src/main.js
126
src/main.js
@ -6,16 +6,22 @@ const os = require("node:os");
|
||||
const child_process = require("node:child_process");
|
||||
const electron = require("electron");
|
||||
|
||||
const update = require(path.join(__dirname, "update.js"));
|
||||
|
||||
let configFilePath;
|
||||
let plutoniumInstallDirectory;
|
||||
switch (os.platform()) {
|
||||
case "win32":
|
||||
configFilePath = path.join(process.env["LOCALAPPDATA"], "Plutonium", "open-plutonium-launcher.json");
|
||||
plutoniumInstallDirectory = path.join(process.env["LOCALAPPDATA"], "Plutonium");
|
||||
break;
|
||||
case "linux":
|
||||
configFilePath = path.join(os.userInfo().homedir, ".config", "open-plutonium-launcher.json");
|
||||
plutoniumInstallDirectory = path.join(os.userInfo().homedir, ".local", "share", "Plutonium");
|
||||
break;
|
||||
case "darwin":
|
||||
configFilePath = path.join(os.userInfo().homedir, "Library", "Application Support", "open-plutonium-launcher.json");
|
||||
plutoniumInstallDirectory = path.join(os.userInfo().homedir, "Library", "Application Support", "Plutonium");
|
||||
break;
|
||||
default:
|
||||
electron.dialog.showErrorBox("Incompatible system", "Sorry, your operating system doesn't seem to be supported...");
|
||||
@ -93,6 +99,101 @@ function fetchPlutoniumManifest() {
|
||||
});
|
||||
}
|
||||
|
||||
function getPlutoniumSession(game, token) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
let payload = JSON.stringify({
|
||||
"game": game
|
||||
});
|
||||
|
||||
let request = https.request("https://nix.plutonium.pw/api/auth/session", {
|
||||
"method": "POST",
|
||||
"headers": {
|
||||
"Content-Type": "application/json",
|
||||
"Content-Length": payload.length,
|
||||
"Authorization": "UserToken " + token,
|
||||
"X-Plutonium-Revision": String(plutoniumManifest.revision),
|
||||
"User-Agent": "Nix/3.0"
|
||||
}
|
||||
}, function (response) {
|
||||
if (response.statusCode !== 200) {
|
||||
return resolve({
|
||||
"status": "unauthenticated",
|
||||
"successful": false
|
||||
});
|
||||
}
|
||||
|
||||
response.setEncoding("utf-8");
|
||||
|
||||
let body = "";
|
||||
response.on("data", function (chunk) {
|
||||
body += chunk;
|
||||
});
|
||||
response.on("end", function () {
|
||||
try {
|
||||
let data = JSON.parse(body);
|
||||
|
||||
if (!("token" in data)) {
|
||||
reject(new Error("Authentication seems to be successful but no token was returned."));
|
||||
}
|
||||
|
||||
resolve({
|
||||
"status": "authenticated",
|
||||
"successful": true,
|
||||
...data
|
||||
});
|
||||
|
||||
userInfo = data;
|
||||
|
||||
mainWindow.loadFile(path.join(__dirname, "src", "views", "games.html"));
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
request.on("error", function (error) {
|
||||
reject(error);
|
||||
});
|
||||
|
||||
request.write(payload);
|
||||
request.end();
|
||||
});
|
||||
}
|
||||
|
||||
function launch(plutoniumInstallDirectory, game, gameInstallDirectory, online) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
getPlutoniumSession(game, userInfo.token).then(function (data) {
|
||||
if (!data.successful) {
|
||||
return reject(new Error("Authentication has failed."));
|
||||
}
|
||||
|
||||
let bootstrapperBinary = path.join(plutoniumInstallDirectory, "bin", "plutonium-bootstrapper-win32.exe");
|
||||
let bootstrapperArguments = [game, gameInstallDirectory];
|
||||
|
||||
if (online) {
|
||||
bootstrapperArguments.push("-token");
|
||||
bootstrapperArguments.push(data.token);
|
||||
} else {
|
||||
bootstrapperArguments.push("+name");
|
||||
bootstrapperArguments.push(userInfo.username);
|
||||
bootstrapperArguments.push("-lan");
|
||||
}
|
||||
|
||||
let gameProcess = child_process.spawn(bootstrapperBinary, bootstrapperArguments, {
|
||||
"detached": true,
|
||||
"stdio": "ignore"
|
||||
});
|
||||
|
||||
gameProcess.on("spawn", function () {
|
||||
resolve(true);
|
||||
});
|
||||
gameProcess.on("error", function (error) {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
electron.app.once("ready", function () {
|
||||
createMainWindow();
|
||||
fetchPlutoniumManifest().then(function (manifest) {
|
||||
@ -167,3 +268,28 @@ electron.ipcMain.handle("login", function (event, username, password) {
|
||||
request.end();
|
||||
});
|
||||
});
|
||||
|
||||
electron.ipcMain.handle("launch", function (event, game, online = true) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (!(game in config.gameDirectories)) {
|
||||
return resolve(false);
|
||||
}
|
||||
let gameInstallDirectory = config.gameDirectories[game];
|
||||
|
||||
update.checkFiles(plutoniumManifest, plutoniumInstallDirectory).then(function (fileList) {
|
||||
let filesToUpdate = fileList.filter(function (file) {
|
||||
return !file.ok;
|
||||
});
|
||||
|
||||
update.downloadFiles(plutoniumInstallDirectory, plutoniumManifest.baseUrl, filesToUpdate).then(function () {
|
||||
launch(plutoniumInstallDirectory, game, gameInstallDirectory, online).then(function (result) {
|
||||
resolve(result);
|
||||
});
|
||||
}).catch(function (error) {
|
||||
reject(error);
|
||||
});
|
||||
}).catch(function (error) {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -63,25 +63,37 @@ function processDownloadQueue(baseDirectory, baseURL, fileEntries) {
|
||||
let queue = [...fileEntries];
|
||||
|
||||
let finishCallback = function () {
|
||||
if (queue.length > 0) {
|
||||
runningDownloads--;
|
||||
|
||||
if (queue.length > 0 && runningDownloads < module.exports.concurrentDownloads) {
|
||||
let currentEntry = queue.shift();
|
||||
|
||||
downloadFile(baseURL + currentEntry.hash, path.join(baseDirectory, currentEntry.name)).then(finishCallback).catch((errorCallback).bind(currentEntry));
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
|
||||
let errorCallback = function (error) {
|
||||
runningDownloads--;
|
||||
|
||||
if (!this.retries) {
|
||||
this.retries = 0;
|
||||
}
|
||||
if (this.retries > 3) return reject(error);
|
||||
|
||||
this.retries++;
|
||||
queue.push(this);
|
||||
};
|
||||
|
||||
for (let d = 0; d < module.exports.concurrentDownloads; d++) {
|
||||
if (queue.length < 1) break;
|
||||
|
||||
let currentEntry = queue.shift();
|
||||
|
||||
downloadFile(baseURL + currentEntry.hash, path.join(baseDirectory, currentEntry.name)).then(finishCallback).catch((function (error) {
|
||||
if (!this.retries) {
|
||||
this.retries = 0;
|
||||
}
|
||||
if (this.retries > 3) return reject(error);
|
||||
runningDownloads++;
|
||||
|
||||
this.retries++;
|
||||
queue.push(this);
|
||||
}).bind(currentEntry));
|
||||
downloadFile(baseURL + currentEntry.hash, path.join(baseDirectory, currentEntry.name)).then(finishCallback).catch((errorCallback).bind(currentEntry));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -107,9 +119,15 @@ module.exports = {
|
||||
},
|
||||
"downloadFiles": function (baseDirectory, baseURL, fileEntries) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
processDownloadQueue(baseDirectory, baseURL, fileEntries.filter(function (entry) {
|
||||
let filesToProcess = fileEntries.filter(function (entry) {
|
||||
return !entry.ok;
|
||||
})).then(function () {
|
||||
});
|
||||
|
||||
if (filesToProcess.length < 1) {
|
||||
return resolve(true);
|
||||
}
|
||||
|
||||
processDownloadQueue(baseDirectory, baseURL, filesToProcess).then(function () {
|
||||
resolve(true);
|
||||
}).catch(function (error) {
|
||||
reject(error);
|
||||
|
Loading…
Reference in New Issue
Block a user