aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author0neGal <mail@0negal.com>2022-01-02 03:36:39 +0100
committer0neGal <mail@0negal.com>2022-01-02 03:36:39 +0100
commit9c4b2aa7bfe2a96354f968c23a98213995242380 (patch)
treec2247f0aa5c5678d49d469fd55c2a9758c043b28
parent80eeab10e81a32c00c24608be83e7ea75ff9accf (diff)
downloadViper-9c4b2aa7bfe2a96354f968c23a98213995242380.tar.gz
Viper-9c4b2aa7bfe2a96354f968c23a98213995242380.zip
toggling, removing and installing mods works
Mostly, the installing part needs a bit more look at, to support archives and different layouts for the mod. Such as searching through an archive to find the right folder because some mods don't use a proper layout. I also somewhat mitigated the whole issue of JSON files not being formatted properly by the mod developer (please just fix your formatting, I beg you.) by simply assigning the absolute basics, however we can't know the versions of the mods. I am not going to go out of my way to write code which can parse a file that wasn't made to be parsed because whoever wrote it doesn't know what a JSON file is made of. Simply not happening. I also added a few locatiolization related things, along with more info for --mods, so besides the normal counter for "Installed mods" you also have "Enabled mods" and "Disabled mods", very useful. The GUI also has a new added "Disabled" tag to mods that are disabled, however this is a temporary, it looks bad and I don't want it in release, I just needed a way to distinquish when testing. Because you can now also enable and disable mods, mods.list() gives back an Object that goes more or less something like: {all: ..., enabled: ..., disabled: ... }, take your guesses as to what everything means, you might even get it in the first try.
-rw-r--r--package-lock.json11
-rw-r--r--package.json3
-rw-r--r--src/app/main.css8
-rw-r--r--src/app/main.js22
-rw-r--r--src/index.js16
-rw-r--r--src/lang/en.json5
-rw-r--r--src/utils.js99
7 files changed, 150 insertions, 14 deletions
diff --git a/package-lock.json b/package-lock.json
index 96d23eb..8bb3e29 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
"version": "0.9.0",
"license": "GPL-3.0-or-later",
"dependencies": {
+ "copy-dir": "^1.3.0",
"electron-updater": "^4.6.1",
"follow-redirects": "^1.14.6",
"marked-man": "^0.7.0",
@@ -1085,6 +1086,11 @@
"node": ">=8"
}
},
+ "node_modules/copy-dir": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/copy-dir/-/copy-dir-1.3.0.tgz",
+ "integrity": "sha512-Q4+qBFnN4bwGwvtXXzbp4P/4iNk0MaiGAzvQ8OiMtlLjkIKjmNN689uVzShSM0908q7GoFHXIPx4zi75ocoaHw=="
+ },
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
@@ -4540,6 +4546,11 @@
"xdg-basedir": "^4.0.0"
}
},
+ "copy-dir": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/copy-dir/-/copy-dir-1.3.0.tgz",
+ "integrity": "sha512-Q4+qBFnN4bwGwvtXXzbp4P/4iNk0MaiGAzvQ8OiMtlLjkIKjmNN689uVzShSM0908q7GoFHXIPx4zi75ocoaHw=="
+ },
"core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
diff --git a/package.json b/package.json
index 449adb7..45eb7fc 100644
--- a/package.json
+++ b/package.json
@@ -29,11 +29,9 @@
"start": "npx electron src/index.js",
"debug": "npx electron src/index.js --debug",
"man": "npx marked-man docs/viper.1.md > docs/viper.1",
-
"build": "npx electron-builder --win nsis --win portable --linux",
"build:windows": "npx electron-builder --win nsis --win portable",
"build:linux": "npx electron-builder --linux",
-
"publish": "npx electron-builder --win nsis --win portable --linux -p always",
"publish:windows": "npx electron-builder --win nsis --win portable -p always",
"publish:linux": "npx electron-builder --linux -p always"
@@ -49,6 +47,7 @@
},
"homepage": "https://github.com/0neGal/viper#readme",
"dependencies": {
+ "copy-dir": "^1.3.0",
"electron-updater": "^4.6.1",
"follow-redirects": "^1.14.6",
"marked-man": "^0.7.0",
diff --git a/src/app/main.css b/src/app/main.css
index c6c9bb9..8776ec9 100644
--- a/src/app/main.css
+++ b/src/app/main.css
@@ -47,11 +47,19 @@ nobr {white-space: nowrap}
}
#modsdiv {
+ padding: 1px;
border-radius: var(--padding);
background: var(--boxbackground);
margin: calc(var(--padding) / 3) var(--padding);
}
+.mod {
+ margin: calc(var(--padding) / 3);
+ border-radius: calc(var(--padding) / 2) !important;
+}
+
+.mod.selected {background: var(--background)}
+
.buttons {
text-align: right;
margin-left: auto;
diff --git a/src/app/main.js b/src/app/main.js
index ab80ba9..c500ba3 100644
--- a/src/app/main.js
+++ b/src/app/main.js
@@ -45,6 +45,18 @@ function setButtons(state) {
}
}
+function select(entry) {
+ let entries = document.querySelectorAll("#modsdiv .mod");
+
+ for (let i = 0; i < entries.length; i++) {
+ if (entries[i].innerHTML == entry) {
+ entries[i].classList.add("selected");
+ } else {
+ entries[i].classList.remove("selected");
+ }
+ }
+}
+
ipcRenderer.on("ns-updated", () => {setButtons(true)})
ipcRenderer.on("ns-updating", () => {setButtons(false)})
@@ -55,10 +67,14 @@ ipcRenderer.on("newpath", (event, newpath) => {
ipcRenderer.on("log", (event, msg) => {log(msg)})
ipcRenderer.on("mods", (event, mods) => {
- modcount.innerHTML = `${lang("gui.mods.count")} ${mods.length}`;
+ modcount.innerHTML = `${lang("gui.mods.count")} ${mods.all.length}`;
modsdiv.innerHTML = "";
- for (let i = 0; i < mods.length; i++) {
- modsdiv.innerHTML += `<div class="mod">${mods[i].Name}</div>`;
+ for (let i = 0; i < mods.enabled.length; i++) {
+ modsdiv.innerHTML += `<div onclick="select('${mods.enabled[i].Name}')" class="mod">${mods.enabled[i].Name}</div>`;
+ }
+
+ for (let i = 0; i < mods.disabled.length; i++) {
+ modsdiv.innerHTML += `<div onclick="select('${mods.disabled[i].Name} - Disabled')" class="mod">${mods.disabled[i].Name} - Disabled</div>`;
}
})
diff --git a/src/index.js b/src/index.js
index 511aadb..161092a 100644
--- a/src/index.js
+++ b/src/index.js
@@ -83,10 +83,18 @@ ipcMain.on("versioncli", () => {
ipcMain.on("getmods", (event) => {
let mods = utils.mods.list();
- if (mods.length > 0) {
- console.log(`${utils.lang("general.mods.installed")} ${mods.length}`)
- for (let i = 0; i < mods.length; i++) {
- console.log(` ${mods[i].Name} ${mods[i].Version}`)
+ if (mods.all.length > 0) {
+ console.log(`${utils.lang("general.mods.installed")} ${mods.all.length}`)
+ console.log(`${utils.lang("general.mods.enabled")} ${mods.enabled.length}`)
+ for (let i = 0; i < mods.enabled.length; i++) {
+ console.log(` ${mods.enabled[i].Name} ${mods.enabled[i].Version}`)
+ }
+
+ if (mods.disabled.length > 0) {
+ console.log(`${utils.lang("general.mods.disabled")} ${mods.disabled.length}`)
+ for (let i = 0; i < mods.disabled.length; i++) {
+ console.log(` ${mods.disabled[i].Name} ${mods.disabled[i].Version}`)
+ }
}
cli.exit(0);
} else {
diff --git a/src/lang/en.json b/src/lang/en.json
index 4221edb..c5e0d77 100644
--- a/src/lang/en.json
+++ b/src/lang/en.json
@@ -18,6 +18,9 @@
"cli.launch.linuxerror": "Launching the game is not currently supported on Linux",
+ "cli.mods.notamod": "Selected folder/file is not a mod",
+ "cli.mods.improperjson": "%s's mod.json has formatting errors",
+
"gui.welcome": "Welcome to Viper!",
"gui.versions.viper": "Viper version",
"gui.versions.northstar": "Northstar version",
@@ -47,6 +50,8 @@
"general.launching": "Launching",
+ "general.mods.enabled": "Enabled mods:",
+ "general.mods.disabled": "Disabled mods:",
"general.mods.installed": "Installed mods:",
"general.missingpath": "Game path is not set!"
}
diff --git a/src/utils.js b/src/utils.js
index c89a033..88e5f3a 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -1,5 +1,6 @@
-const fs = require("fs");
const path = require("path");
+const fs = require("fs-extra");
+const copy = require("copy-dir");
const { app, dialog, ipcMain } = require("electron");
const Emitter = require("events");
@@ -164,23 +165,111 @@ function winLog(msg) {
ipcMain.emit("winLog", msg, msg);
}
+let modpath = path.join(settings.gamepath, "R2Northstar/mods");
const mods = {
list: () => {
let mods = [];
- let modpath = path.join(settings.gamepath, "R2Northstar/mods");
+ let disabled = [];
files = fs.readdirSync(modpath)
files.forEach((file) => {
if (fs.statSync(path.join(modpath, file)).isDirectory()) {
if (fs.existsSync(path.join(modpath, file, "mod.json"))) {
- mods.push(require(path.join(modpath, file, "mod.json")))
+ try {
+ mods.push({...require(path.join(modpath, file, "mod.json")), FolderName: file, Disabled: false})
+ }catch(err) {
+ console.log("error: " + lang("cli.mods.improperjson"), file)
+ mods.push({Name: file, FolderName: file, Version: "unknown", Disabled: false})
+ }
+ }
+ }
+ })
+
+ let disabledPath = path.join(modpath, "disabled")
+ files = fs.readdirSync(disabledPath)
+ files.forEach((file) => {
+ if (fs.statSync(path.join(disabledPath, file)).isDirectory()) {
+ if (fs.existsSync(path.join(disabledPath, file, "mod.json"))) {
+ try {
+ disabled.push({...require(path.join(disabledPath, file, "mod.json")), FolderName: file, Disabled: true})
+ }catch(err) {
+ console.log("error: " + lang("cli.mods.improperjson"), file)
+ disabled.push({Name: file, FolderName: file, Version: "unknown", Disabled: false})
+ }
}
}
})
- return mods;
+ return {
+ enabled: mods,
+ disabled: disabled,
+ all: [...mods, ...disabled]
+ };
},
-}
+ get: (mod) => {
+ let list = mods.list().all;
+
+ for (let i = 0; i < list.length; i++) {
+ if (list[i].Name == mod) {
+ return list[i];
+ } else {continue}
+ }
+
+ return false;
+ },
+ install: (mod) => {
+ if (fs.statSync(mod).isDirectory()) {
+ if (fs.statSync(path.join(mod, "mod.json"))) {
+ copy(mod, path.join(modpath, mod.replace(/^.*(\\|\/|\:)/, "")), {
+ mode: true,
+ cover: true,
+ utimes: true,
+ }, (err) => {
+ if(err) {console.log("error:", err)};
+ console.log();
+ });
+ cli.exit();
+ return
+ } else {
+ console.log("error: " + lang("cli.mods.notamod"))
+ cli.exit(1);
+ return;
+ }
+ }
+
+ fs.createReadStream(mod).pipe(unzip.Extract({path: modpath}))
+ .on("finish", () => {
+ cli.exit();
+ });
+ },
+ remove: (mod) => {
+ let modName = mods.get(mod).FolderName;
+ let modPath = path.join(modpath, modName);
+ if (fs.statSync(modPath).isDirectory()) {
+ fs.rmSync(modPath, {recursive: true});
+ cli.exit();
+ } else {
+ cli.exit(1);
+ }
+ },
+ toggle: (mod) => {
+ let disabled = path.join(modpath, "disabled");
+ if (! fs.existsSync(disabled)) {
+ fs.mkdirSync(disabled)
+ }
+
+ let modName = mods.get(mod).FolderName;
+ let modPath = path.join(modpath, modName);
+ let dest = path.join(disabled, modName);
+
+ if (mods.get(mod).Disabled) {
+ modPath = path.join(disabled, modName);
+ dest = path.join(modpath, modName);
+ }
+
+ fs.moveSync(modPath, dest)
+ }
+};
module.exports = {
mods,