243 lines
5.5 KiB
JavaScript
243 lines
5.5 KiB
JavaScript
const fs = require("node:fs");
|
|
const https = require("node:https");
|
|
const path = require("node:path");
|
|
const child_process = require("node:child_process");
|
|
const crypto = require("node:crypto");
|
|
|
|
const manifestURLs = [
|
|
"https://cdn.plutonium.pw/updater/prod/info.json",
|
|
"https://cdn.kroniker.fr/updater/prod/info.json"
|
|
];
|
|
|
|
var basePath = path.join(process.env["LOCALAPPDATA"], "Plutonium");
|
|
|
|
var mustSkipCustom = false;
|
|
|
|
for (var a = 0; a < process.argv.length; a++) {
|
|
if (a > 0) {
|
|
switch (process.argv[a - 1]) {
|
|
case "--install-dir":
|
|
basePath = process.argv[a];
|
|
break;
|
|
default:
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch (process.argv[a]) {
|
|
case "--skip-custom":
|
|
mustSkipCustom = true;
|
|
break;
|
|
default:
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
var manifest = {
|
|
"files": []
|
|
};
|
|
|
|
function httpsGet(url) {
|
|
return new Promise(function (resolve, reject) {
|
|
var request = https.request(url, function (response) {
|
|
var body = "";
|
|
|
|
response.setEncoding("utf-8");
|
|
response.on("data", function (chunk) {
|
|
body += chunk;
|
|
});
|
|
|
|
response.on("end", function () {
|
|
resolve({
|
|
"status": response.statusCode,
|
|
"headers": response.headers,
|
|
"body": body
|
|
});
|
|
});
|
|
});
|
|
|
|
request.on("error", function (error) {
|
|
reject(error.message);
|
|
});
|
|
|
|
request.end();
|
|
});
|
|
}
|
|
|
|
function httpsDownload(url, filePath) {
|
|
return new Promise(function (resolve, reject) {
|
|
var fileDirectory = path.dirname(filePath);
|
|
|
|
if (!fs.existsSync(fileDirectory)) {
|
|
fs.mkdirSync(fileDirectory, {
|
|
"recursive": true
|
|
});
|
|
}
|
|
|
|
var fileWriter = fs.createWriteStream(filePath);
|
|
|
|
var request = https.request(url, function (response) {
|
|
var body = "";
|
|
|
|
response.pipe(fileWriter);
|
|
|
|
response.on("end", function () {
|
|
resolve();
|
|
});
|
|
});
|
|
|
|
request.on("error", function (error) {
|
|
reject(error.message);
|
|
fileWriter.close();
|
|
});
|
|
|
|
request.end();
|
|
});
|
|
}
|
|
|
|
function readAndMergeManifest(manifestURL) {
|
|
return new Promise(function (resolve, reject) {
|
|
httpsGet(manifestURL).then(function (response) {
|
|
try {
|
|
var data = JSON.parse(response.body);
|
|
|
|
if ("version" in data) manifest.version = data.version;
|
|
|
|
for (var f = 0; f < data.files.length; f++) {
|
|
var file = data.files[f];
|
|
file.baseUrl = data.baseUrl;
|
|
|
|
var fileMatch = manifest.files.find(entry => entry.name == file.name);
|
|
if (typeof fileMatch == "object") {
|
|
var matchIndex = manifest.files.indexOf(fileMatch);
|
|
manifest.files.splice(matchIndex, 1);
|
|
}
|
|
|
|
manifest.files.push(file);
|
|
}
|
|
|
|
resolve();
|
|
} catch (error) {
|
|
reject(error);
|
|
}
|
|
}).catch(function (error) {
|
|
reject(error);
|
|
});
|
|
});
|
|
}
|
|
|
|
function getFileSHA1(filePath) {
|
|
return new Promise(function (resolve, reject) {
|
|
var fileStream = fs.createReadStream(filePath);
|
|
|
|
var hash = crypto.createHash("sha1");
|
|
hash.setEncoding("hex");
|
|
|
|
fileStream.on("end", function () {
|
|
hash.end();
|
|
|
|
resolve(hash.read());
|
|
});
|
|
|
|
fileStream.pipe(hash);
|
|
});
|
|
}
|
|
|
|
async function checkFiles() {
|
|
var filesToDownload = [];
|
|
|
|
for (var f = 0; f < manifest.files.length; f++) {
|
|
var file = manifest.files[f];
|
|
var filePath = path.join(basePath, ...(file.name.split("/")));
|
|
|
|
if (!fs.existsSync(filePath)) {
|
|
console.log("\x1b[32mFile " + file.name + " needs to be downloaded.\x1b[0m");
|
|
filesToDownload.push(file);
|
|
continue;
|
|
}
|
|
|
|
var sum = await getFileSHA1(filePath);
|
|
|
|
if (sum !== file.hash) {
|
|
console.log("\x1b[33mFile " + file.name + " needs to be updated.\x1b[0m");
|
|
filesToDownload.push(file);
|
|
}
|
|
}
|
|
|
|
return filesToDownload;
|
|
}
|
|
|
|
async function downloadFiles(files) {
|
|
for (var f = 0; f < files.length; f++) {
|
|
var file = files[f];
|
|
var filePath = path.join(basePath, ...(file.name.split("/")));
|
|
|
|
console.log("\x1b[35mDownloading file " + file.name + "...\x1b[0m");
|
|
|
|
await httpsDownload(file.baseUrl + file.hash, filePath);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function launchLauncher() {
|
|
return new Promise(function (resolve, reject) {
|
|
var launcherPath = path.join(basePath, "bin", "plutonium-launcher-win32.exe");
|
|
|
|
var subprocess = child_process.spawn(launcherPath, [], {
|
|
"detached": true,
|
|
"stdio": "ignore"
|
|
});
|
|
|
|
subprocess.on("spawn", function () {
|
|
subprocess.unref();
|
|
resolve();
|
|
});
|
|
|
|
subprocess.on("error", function (error) {
|
|
reject(error);
|
|
});
|
|
});
|
|
}
|
|
|
|
process.title = "Kroniker Updater - Plutonium Black Ops II";
|
|
process.stdout.write("\x1b]0;Kroniker Updater - Plutonium Black Ops II\x07");
|
|
|
|
(async function () {
|
|
var manifestCount = mustSkipCustom ? 1 : manifestURLs.length;
|
|
|
|
for (var m = 0; m < manifestCount; m++) {
|
|
try {
|
|
await readAndMergeManifest(manifestURLs[m]);
|
|
} catch (error) {
|
|
console.error("An error has occurred while obtaining manifest " + (m + 1) + " : " + error.message);
|
|
}
|
|
}
|
|
console.log("\x1b[36mChecking the files...\x1b[0m");
|
|
checkFiles().then(function (wrongFiles) {
|
|
if (wrongFiles.length > 0) {
|
|
console.log("We have " + wrongFiles.length + " files to download. ");
|
|
downloadFiles(wrongFiles).then(function () {
|
|
launchLauncher().then(function () {
|
|
|
|
}).catch(function (error) {
|
|
console.error("An error has occurred while opening the launcher. \n" + error.stack);
|
|
});
|
|
|
|
}).catch(function (error) {
|
|
console.error("An error has occurred while downloading a file. \n" + error.stack);
|
|
});
|
|
} else {
|
|
launchLauncher().then(function () {
|
|
|
|
}).catch(function (error) {
|
|
console.error("An error has occurred while opening the launcher. \n" + error.stack);
|
|
});
|
|
}
|
|
}).catch(function (error) {
|
|
console.error("An error has occurred while checking the files. \n" + error.stack);
|
|
});
|
|
})();
|