aboutsummaryrefslogtreecommitdiff
path: root/src/utils.js
diff options
context:
space:
mode:
author0neGal <mail@0negal.com>2022-02-13 23:32:44 +0100
committerGitHub <noreply@github.com>2022-02-13 23:32:44 +0100
commit9f2f77558238c28ceb8ff4fca2096602671779e5 (patch)
treec15586b60de31de094c2f811832ef9ad6df2f50a /src/utils.js
parent057b60f4843798441ad441370381b87299d5ad7f (diff)
parentb2f826a39e8ecf77f85ca56906758edaa3f1dac3 (diff)
downloadViper-9f2f77558238c28ceb8ff4fca2096602671779e5.tar.gz
Viper-9f2f77558238c28ceb8ff4fca2096602671779e5.zip
Merge branch 'main' into enabledmods
Diffstat (limited to 'src/utils.js')
-rw-r--r--src/utils.js240
1 files changed, 195 insertions, 45 deletions
diff --git a/src/utils.js b/src/utils.js
index a41def4..a0c88ef 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -1,6 +1,6 @@
const path = require("path");
const fs = require("fs-extra");
-const copy = require("copy-dir");
+const copy = require("recursive-copy");
const { app, dialog, ipcMain, Notification } = require("electron");
const Emitter = require("events");
@@ -8,7 +8,8 @@ const events = new Emitter();
const cli = require("./cli");
const lang = require("./lang");
-const requests = require("./requests");
+const requests = require("./extras/requests");
+const findgame = require("./extras/findgame");
const unzip = require("unzipper");
const run = require("child_process").spawn;
@@ -115,10 +116,39 @@ northstar_auto_updates: {
//
// If running with CLI it takes in the --setpath argument otherwise it
// open the systems file browser for the user to select a path.
-function setpath(win) {
+async function setpath(win, forcedialog) {
+ function setGamepath(folder) {
+ settings.gamepath = folder;
+ settings.zip = path.join(settings.gamepath + "/northstar.zip");
+ saveSettings();
+ win.webContents.send("newpath", settings.gamepath);
+ ipcMain.emit("newpath", null, settings.gamepath);
+
+ modpath = path.join(settings.gamepath, "R2Northstar/mods");
+ }
+
if (! win) { // CLI
- settings.gamepath = cli.param("setpath");
+ setGamepath(cli.param("setpath"));
} else { // GUI
+ if (! forcedialog) {
+ function setGamepath(folder, forcedialog) {
+ settings.gamepath = folder;
+ settings.zip = path.join(settings.gamepath + "/northstar.zip");
+ saveSettings();
+ win.webContents.send("newpath", settings.gamepath);
+ ipcMain.emit("newpath", null, settings.gamepath);
+ }
+
+ let gamepath = await findgame();
+ if (gamepath) {
+ setGamepath(gamepath);
+ return;
+ }
+
+ winAlert(lang("general.missingpath"));
+ }
+
+ // Fallback to manual selection
dialog.showOpenDialog({properties: ["openDirectory"]}).then(res => {
if (res.canceled) {
ipcMain.emit("newpath", null, false);
@@ -129,16 +159,12 @@ function setpath(win) {
return;
}
- settings.gamepath = res.filePaths[0];
- settings.zip = path.join(settings.gamepath + "/northstar.zip");
- saveSettings();
- win.webContents.send("newpath", settings.gamepath);
- ipcMain.emit("newpath", null, settings.gamepath);
+ setGamepath(res.filePaths[0])
+
+ cli.exit();
+ return;
}).catch(err => {console.error(err)})
}
-
- saveSettings();
- cli.exit();
}
// As to not have to do the same one liner a million times, this
@@ -176,6 +202,19 @@ function getTF2Version() {
}
}
+
+// Renames excluded files to their original name
+function restoreExcludedFiles() {
+ for (let i = 0; i < settings.excludes.length; i++) {
+ let exclude = path.join(settings.gamepath + "/" + settings.excludes[i]);
+ if (fs.existsSync(exclude + ".excluded")) {
+ fs.renameSync(exclude + ".excluded", exclude)
+ }
+ }
+}
+// At start, restore excluded files who might have been created by an incomplete update process.
+restoreExcludedFiles();
+
// Installs/Updates Northstar
//
// If Northstar is already installed it'll be an update, otherwise it'll
@@ -186,14 +225,6 @@ function getTF2Version() {
// <file>.excluded, then rename them back after the extraction. The
// unzip module does not support excluding files directly.
async function update() {
- // Renames excluded files to <file>.excluded
- for (let i = 0; i < settings.excludes.length; i++) {
- let exclude = path.join(settings.gamepath + "/" + settings.excludes[i]);
- if (fs.existsSync(exclude)) {
- fs.renameSync(exclude, exclude + ".excluded")
- }
- }
-
ipcMain.emit("ns-update-event", "cli.update.checking");
console.log(lang("cli.update.checking"));
var version = getNSVersion();
@@ -215,6 +246,14 @@ async function update() {
ipcMain.emit("ns-update-event", "cli.update.downloading");
}
+ // Renames excluded files to <file>.excluded
+ for (let i = 0; i < settings.excludes.length; i++) {
+ let exclude = path.join(settings.gamepath + "/" + settings.excludes[i]);
+ if (fs.existsSync(exclude)) {
+ fs.renameSync(exclude, exclude + ".excluded")
+ }
+ }
+
// Start the download of the zip
https.get(requests.getLatestNsVersionLink(), (res) => {
let stream = fs.createWriteStream(settings.zip);
@@ -237,16 +276,10 @@ async function update() {
// installing Northstar.
fs.createReadStream(settings.zip).pipe(unzip.Extract({path: settings.gamepath}))
.on("finish", () => {
- fs.writeFileSync(path.join(settings.gamepath, "ns_version.txt"), latestAvailableVersion);
- ipcMain.emit("getversion");
-
- // Renames excluded files to their original name
- for (let i = 0; i < settings.excludes.length; i++) {
- let exclude = path.join(settings.gamepath + "/" + settings.excludes[i]);
- if (fs.existsSync(exclude + ".excluded")) {
- fs.renameSync(exclude + ".excluded", exclude)
- }
- }
+ fs.writeFileSync(path.join(settings.gamepath, "ns_version.txt"), latestAvailableVersion);
+ ipcMain.emit("getversion");
+
+ restoreExcludedFiles();
ipcMain.emit("guigetmods");
ipcMain.emit("ns-update-event", "cli.update.uptodate.short");
@@ -323,6 +356,8 @@ const mods = {
// combination of the other two, enabled being enabled mods, and you
// guessed it, disabled being disabled mods.
list: () => {
+ let modpath = path.join(settings.gamepath, "R2Northstar/mods");
+
if (getNSVersion() == "unknown") {
winLog(lang("general.notinstalled"))
console.log("error: " + lang("general.notinstalled"))
@@ -349,9 +384,14 @@ const mods = {
try {
mods.push({...require(path.join(modpath, file, "mod.json")), FolderName: file, Disabled: false})
}catch(err) {
- console.log("error: " + lang("cli.mods.improperjson"), file)
+ if (cli.hasArgs()) {console.log("error: " + lang("cli.mods.improperjson"), file)}
mods.push({Name: file, FolderName: file, Version: "unknown", Disabled: false})
}
+
+ let manifest = path.join(modpath, file, "manifest.json");
+ if (fs.existsSync(manifest)) {
+ try {mods[mods.length - 1].ManifestName = require(manifest).name}catch(err){}
+ }
}
}
})
@@ -368,10 +408,15 @@ const mods = {
try {
disabled.push({...require(path.join(disabledPath, file, "mod.json")), FolderName: file, Disabled: true})
}catch(err) {
- console.log("error: " + lang("cli.mods.improperjson"), file)
+ if (cli.hasArgs()) {console.log("error: " + lang("cli.mods.improperjson"), file)}
disabled.push({Name: file, FolderName: file, Version: "unknown", Disabled: true})
}
}
+
+ let manifest = path.join(modpath, file, "manifest.json");
+ if (fs.existsSync(manifest)) {
+ try {mods[mods.length - 1].ManifestName = require(manifest).name}catch(err){}
+ }
}
})
@@ -389,6 +434,8 @@ const mods = {
// the absolute basics will be provided and we can't know the
// version or similar.
get: (mod) => {
+ let modpath = path.join(settings.gamepath, "R2Northstar/mods");
+
if (getNSVersion() == "unknown") {
winLog(lang("general.notinstalled"))
console.log("error: " + lang("general.notinstalled"))
@@ -462,7 +509,9 @@ const mods = {
// Either a zip or folder is supported, we'll also try to search
// inside the zip or folder to see if buried in another folder or
// not, as sometimes that's the case.
- install: (mod) => {
+ install: (mod, destname, manifestfile, malformed = false) => {
+ let modname = mod.replace(/^.*(\\|\/|\:)/, "");
+
if (getNSVersion() == "unknown") {
winLog(lang("general.notinstalled"))
console.log("error: " + lang("general.notinstalled"))
@@ -482,6 +531,19 @@ const mods = {
cli.exit();
winLog(lang("gui.mods.installedmod"))
+
+ if (modname == "mods") {
+ let manifest = path.join(app.getPath("userData"), "Archives/manifest.json")
+
+ if (fs.existsSync(manifest)) {
+ modname = require(manifest).name;
+ }
+ }
+
+ ipcMain.emit("installedmod", "", {
+ name: modname,
+ malformed: malformed,
+ });
ipcMain.emit("guigetmods");
return true;
}
@@ -490,14 +552,17 @@ const mods = {
if (fs.statSync(mod).isDirectory()) {
winLog(lang("gui.mods.installing"))
+ files = fs.readdirSync(mod);
if (fs.existsSync(path.join(mod, "mod.json")) &&
fs.statSync(path.join(mod, "mod.json")).isFile()) {
- copy.sync(mod, path.join(modpath, mod.replace(/^.*(\\|\/|\:)/, "")), {
- mode: true,
- cover: true,
- utimes: true,
- });
+ if (fs.existsSync(path.join(modpath, modname))) {
+ fs.rmSync(path.join(modpath, modname), {recursive: true});
+ }
+ let copydest = path.join(modpath, modname);
+ if (typeof destname == "string") {copydest = path.join(modpath, destname)}
+ copy(mod, copydest)
+ copy(manifestfile, path.join(copydest, "manifest.json"))
return installed();
} else {
@@ -508,39 +573,110 @@ const mods = {
if (fs.existsSync(path.join(mod, files[i], "mod.json")) &&
fs.statSync(path.join(mod, files[i], "mod.json")).isFile()) {
+ mods.install(path.join(mod, files[i]))
if (mods.install(path.join(mod, files[i]))) {return true};
}
}
}
- notamod();
- return false;
+ return notamod();
}
+
+ return notamod();
} else {
winLog(lang("gui.mods.extracting"))
let cache = path.join(app.getPath("userData"), "Archives");
if (fs.existsSync(cache)) {
fs.rmSync(cache, {recursive: true});
- fs.mkdirSync(cache);
+ fs.mkdirSync(path.join(cache, "mods"), {recursive: true});
} else {
- fs.mkdirSync(cache);
+ fs.mkdirSync(path.join(cache, "mods"), {recursive: true});
}
try {
fs.createReadStream(mod).pipe(unzip.Extract({path: cache}))
.on("finish", () => {
- if (mods.install(cache)) {
- installed();
- } else {return notamod()}
+ setTimeout(() => {
+ let manifest = path.join(cache, "manifest.json");
+ if (fs.existsSync(manifest)) {
+ files = fs.readdirSync(path.join(cache, "mods"));
+ if (fs.existsSync(path.join(cache, "mods/mod.json"))) {
+ if (mods.install(path.join(cache, "mods"), require(manifest).name, manifest, true)) {
+ return true;
+ }
+ } else {
+ for (let i = 0; i < files.length; i++) {
+ let mod = path.join(cache, "mods", files[i]);
+ if (fs.statSync(mod).isDirectory()) {
+ setTimeout(() => {
+ if (mods.install(mod, false, manifest)) {return true};
+ }, 1000)
+ }
+ }
+
+ if (files.length == 0) {
+ ipcMain.emit("failedmod");
+ return notamod();
+ }
+ }
+
+ return notamod();
+ }
+
+ if (mods.install(cache)) {
+ installed();
+ } else {return notamod()}
+ }, 1000)
});
}catch(err) {return notamod()}
}
},
+
+ // Installs mods from URL's
+ //
+ // This'll simply download the file that the URL points to and then
+ // install it with mods.install()
+ installFromURL: (url) => {
+ https.get(url, (res) => {
+ let tmp = path.join(app.getPath("cache"), "vipertmp");
+ let modlocation = path.join(tmp, "/mod.zip");
+
+ if (fs.existsSync(tmp)) {
+ if (! fs.statSync(tmp).isDirectory()) {
+ fs.rmSync(tmp)
+ }
+ } else {
+ fs.mkdirSync(tmp)
+ if (fs.existsSync(modlocation)) {
+ fs.rmSync(modlocation)
+ }
+ }
+
+ let stream = fs.createWriteStream(modlocation);
+ res.pipe(stream);
+
+ // let received = 0;
+ // // Progress messages, we should probably switch this to
+ // // percentage instead of how much is downloaded.
+ // res.on("data", (chunk) => {
+ // received += chunk.length;
+ // ipcMain.emit("ns-update-event", lang("gui.update.downloading") + " " + (received / 1024 / 1024).toFixed(1) + "mb");
+ // })
+
+ stream.on("finish", () => {
+ stream.close();
+ mods.install(modlocation);
+ })
+ })
+ },
+
// Removes mods
//
// Takes in the names of the mod then removes it, no confirmation,
// that'd be up to the GUI.
remove: (mod) => {
+ let modpath = path.join(settings.gamepath, "R2Northstar/mods");
+
if (getNSVersion() == "unknown") {
winLog(lang("general.notinstalled"))
console.log("error: " + lang("general.notinstalled"))
@@ -575,10 +711,19 @@ const mods = {
}
if (fs.statSync(modPath).isDirectory()) {
+ let manifestname = null;
+ if (fs.existsSync(path.join(modPath, "manifest.json"))) {
+ manifestname = require(path.join(modPath, "manifest.json")).name;
+ }
+
fs.rmSync(modPath, {recursive: true});
console.log(lang("cli.mods.removed"));
cli.exit();
ipcMain.emit("guigetmods");
+ ipcMain.emit("removedmod", "", {
+ name: mod.replace(/^.*(\\|\/|\:)/, ""),
+ manifestname: manifestname
+ });
} else {
cli.exit(1);
}
@@ -591,6 +736,8 @@ const mods = {
// you checked for if a mod is already disable and if not run the
// function. However we currently have no need for that.
toggle: (mod, fork) => {
+ let modpath = path.join(settings.gamepath, "R2Northstar/mods");
+
if (getNSVersion() == "unknown") {
winLog(lang("general.notinstalled"))
console.log("error: " + lang("general.notinstalled"))
@@ -639,6 +786,9 @@ const mods = {
};
console.log(mods.modfile().get())
+setInterval(() => {
+ ipcMain.emit("guigetmods");
+}, 1500)
module.exports = {
mods,