aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/index.js19
-rw-r--r--src/modules/mods.js546
-rw-r--r--src/utils.js520
3 files changed, 557 insertions, 528 deletions
diff --git a/src/index.js b/src/index.js
index c3d3556..16eebfe 100644
--- a/src/index.js
+++ b/src/index.js
@@ -8,6 +8,7 @@ process.chdir(app.getPath("appData"));
const utils = require("./utils");
const cli = require("./cli");
+const mods = require("./modules/mods");
const settings = require("./modules/settings");
const requests = require("./modules/requests");
@@ -74,7 +75,7 @@ function start() {
ipcMain.on("duped-mod", (event, modname) => {send("duped-mod", modname)});
ipcMain.on("failed-mod", (event, modname) => {send("failed-mod", modname)});
ipcMain.on("removed-mod", (event, modname) => {send("removed-mod", modname)});
- ipcMain.on("gui-getmods", (event, ...args) => {send("mods", utils.mods.list())});
+ ipcMain.on("gui-getmods", (event, ...args) => {send("mods", mods.list())});
ipcMain.on("installed-mod", (event, modname) => {send("installed-mod", modname)});
ipcMain.on("no-internet", () => {send("no-internet")});
@@ -84,11 +85,11 @@ function start() {
});
// install calls
- ipcMain.on("install-from-path", (event, path) => {utils.mods.install(path)});
- ipcMain.on("install-from-url", (event, url, author) => {utils.mods.installFromURL(url, author)});
+ ipcMain.on("install-from-path", (event, path) => {mods.install(path)});
+ ipcMain.on("install-from-url", (event, url, author) => {mods.installFromURL(url, author)});
win.webContents.on("dom-ready", () => {
- send("mods", utils.mods.list());
+ send("mods", mods.list());
});
// ensures gamepath still exists and is valid on startup
@@ -136,11 +137,11 @@ function start() {
// module inside the file that sent the event. {
ipcMain.on("install-mod", () => {
if (cli.hasArgs()) {
- utils.mods.install(cli.param("installmod"));
+ mods.install(cli.param("installmod"));
} else {
dialog.showOpenDialog({properties: ["openFile"]}).then(res => {
if (res.filePaths.length != 0) {
- utils.mods.install(res.filePaths[0]);
+ mods.install(res.filePaths[0]);
} else {
send("set-buttons", true);
}
@@ -148,8 +149,8 @@ ipcMain.on("install-mod", () => {
}
})
-ipcMain.on("remove-mod", (event, mod) => {utils.mods.remove(mod)});
-ipcMain.on("toggle-mod", (event, mod) => {utils.mods.toggle(mod)});
+ipcMain.on("remove-mod", (event, mod) => {mods.remove(mod)});
+ipcMain.on("toggle-mod", (event, mod) => {mods.toggle(mod)});
ipcMain.on("launch-ns", () => {utils.launch()});
ipcMain.on("launch-vanilla", () => {utils.launch("vanilla")});
@@ -193,7 +194,7 @@ ipcMain.on("version-cli", () => {
// sends installed mods info to renderer
ipcMain.on("getmods", () => {
- let mods = utils.mods.list();
+ let mods = mods.list();
if (mods.all.length > 0) {
log(`${utils.lang("general.mods.installed")} ${mods.all.length}`);
log(`${utils.lang("general.mods.enabled")} ${mods.enabled.length}`);
diff --git a/src/modules/mods.js b/src/modules/mods.js
new file mode 100644
index 0000000..1cb919a
--- /dev/null
+++ b/src/modules/mods.js
@@ -0,0 +1,546 @@
+const path = require("path");
+const fs = require("fs-extra");
+const unzip = require("unzipper");
+const copy = require("recursive-copy");
+const { app, ipcMain } = require("electron");
+const { https } = require("follow-redirects");
+
+const json = require("./json");
+const settings = require("./settings");
+
+const cli = require("../cli");
+const lang = require("../lang");
+const utils = require("../utils");
+
+var mods = {
+ installing: [],
+ dupe_msg_sent: false,
+}
+
+function update_path() {
+ mods.path = path.join(settings.gamepath, "R2Northstar/mods");
+}; update_path();
+
+// Returns a list of mods
+//
+// It'll return 3 arrays, all, enabled, disabled. all being a
+// combination of the other two, enabled being enabled mods, and you
+// guessed it, disabled being disabled mods.
+mods.list = () => {
+ update_path();
+
+ if (utils.getNSVersion() == "unknown") {
+ utils.winLog(lang("general.notinstalled"));
+ console.log("error: " + lang("general.notinstalled"));
+ cli.exit(1);
+ return false;
+ }
+
+ let enabled = [];
+ let disabled = [];
+
+ if (! fs.existsSync(mods.path)) {
+ fs.mkdirSync(path.join(mods.path), {recursive: true});
+ return {
+ enabled: [],
+ disabled: [],
+ all: []
+ };
+ }
+
+ let files = fs.readdirSync(mods.path);
+ files.forEach((file) => {
+ if (fs.statSync(path.join(mods.path, file)).isDirectory()) {
+ let modjson = path.join(mods.path, file, "mod.json");
+ if (fs.existsSync(modjson)) {
+ let mod = json(modjson);
+ if (! mod) {return}
+
+ let obj = {
+ Version: "unknown",
+ Name: "unknown",
+ FolderName: file,
+ ...mod}
+
+ obj.Disabled = ! mods.modfile.get(obj.Name);
+
+ let manifestfile = path.join(mods.path, file, "manifest.json");
+ if (fs.existsSync(manifestfile)) {
+ let manifest = json(manifestfile);
+ if (manifest != false) {
+ obj.ManifestName = manifest.name;
+ if (obj.Version == "unknown") {
+ obj.Version = manifest.version_number;
+ }
+ }
+ }
+
+ if (obj.Disabled) {
+ disabled.push(obj);
+ } else {
+ enabled.push(obj);
+ }
+ }
+ }
+ })
+
+ return {
+ enabled: enabled,
+ disabled: disabled,
+ all: [...enabled, ...disabled]
+ };
+}
+
+// Gets information about a mod
+//
+// Folder name, version, name and whatever else is in the mod.json, keep
+// in mind if the mod developer didn't format their JSON file the
+// absolute basics will be provided and we can't know the version or
+// similar.
+mods.get = (mod) => {
+ update_path();
+
+ if (utils.getNSVersion() == "unknown") {
+ utils.winLog(lang("general.notinstalled"));
+ console.log("error: " + lang("general.notinstalled"));
+ cli.exit(1);
+ return false;
+ }
+
+ 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;
+}
+
+function modfile_pre() {
+ mods.modfile.file = path.join(mods.path, "..", "enabledmods.json");
+
+ if (! fs.existsSync(mods.path)) {
+ fs.mkdirSync(path.join(mods.path), {recursive: true});
+ }
+
+ if (! fs.existsSync(mods.modfile.file)) {
+ fs.writeFileSync(mods.modfile.file, "{}");
+ }
+}
+
+// Manages the enabledmods.json file
+//
+// It can both return info about the file, but also toggle mods in it,
+// generate the file itself, and so on.
+mods.modfile = {};
+
+mods.modfile.gen = () => {
+ modfile_pre();
+
+ let names = {};
+ let list = mods.list().all;
+ for (let i = 0; i < list.length; i++) {
+ names[list[i].Name] = true
+ }
+
+ fs.writeFileSync(mods.modfile.file, JSON.stringify(names));
+}
+
+mods.modfile.disable = (mod) => {
+ modfile_pre();
+
+ let data = json(mods.modfile.file);
+ data[mod] = false;
+ fs.writeFileSync(mods.modfile.file, JSON.stringify(data));
+}
+
+mods.modfile.enable = (mod) => {
+ modfile_pre();
+
+ let data = json(mods.modfile.file);
+ data[mod] = true;
+ fs.writeFileSync(mods.modfile.file, JSON.stringify(data));
+}
+
+mods.modfile.toggle = (mod) => {
+ modfile_pre();
+
+ let data = json(mods.modfile.file);
+ if (data[mod] != undefined) {
+ data[mod] = ! data[mod];
+ } else {
+ data[mod] = false;
+ }
+
+ fs.writeFileSync(mods.modfile.file, JSON.stringify(data));
+}
+
+mods.modfile.get = (mod) => {
+ modfile_pre();
+
+ let data = json(mods.modfile.file);
+
+ if (data[mod]) {
+ return true;
+ } else if (data[mod] === false) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+// Installs mods from a file path
+//
+// 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.
+mods.install = (mod, opts) => {
+ update_path();
+
+ let modname = mod.replace(/^.*(\\|\/|\:)/, "");
+
+ opts = {
+ forked: false,
+ author: false,
+ destname: false,
+ malformed: false,
+ manifest_file: false,
+ ...opts
+ }
+
+ if (! opts.forked) {
+ mods.installing = [];
+ mods.dupe_msg_sent = false;
+ }
+
+ if (utils.getNSVersion() == "unknown") {
+ utils.winLog(lang("general.notinstalled"));
+ console.log("error: " + lang("general.notinstalled"));
+ cli.exit(1);
+ return false;
+ }
+
+ let notamod = () => {
+ utils.winLog(lang("gui.mods.notamod"));
+ console.log("error: " + lang("cli.mods.notamod"));
+ cli.exit(1);
+ return false;
+ }
+
+ let installed = () => {
+ console.log(lang("cli.mods.installed"));
+ cli.exit();
+
+ utils.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("installed-mod", "", {
+ name: modname,
+ malformed: opts.malformed,
+ });
+
+ ipcMain.emit("gui-getmods");
+ return true;
+ }
+
+ if (! fs.existsSync(mod)) {return notamod()}
+
+ if (fs.statSync(mod).isDirectory()) {
+ utils.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()) {
+
+
+ if (! json(path.join(mod, "mod.json"))) {
+ ipcMain.emit("failed-mod");
+ return notamod();
+ }
+
+ if (fs.existsSync(path.join(mods.path, modname))) {
+ fs.rmSync(path.join(mods.path, modname), {recursive: true});
+ }
+
+ let copydest = path.join(mods.path, modname);
+ if (typeof opts.destname == "string") {
+ copydest = path.join(mods.path, opts.destname)
+ }
+
+ copy(mod, copydest, (err) => {
+ if (err) {
+ ipcMain.emit("failed-mod");
+ return;
+ }
+
+ copy(opts.manifest_file, path.join(copydest, "manifest.json"), (err) => {
+ if (err) {
+ ipcMain.emit("failed-mod");
+ return;
+ }
+
+ if (opts.author) {
+ fs.writeFileSync(
+ path.join(copydest, "thunderstore_author.txt"),
+ opts.author
+ )
+ }
+
+ return installed();
+ });
+ });
+
+ return;
+ } else {
+ mod_files = fs.readdirSync(mod);
+
+ for (let i = 0; i < mod_files.length; i++) {
+ if (fs.statSync(path.join(mod, mod_files[i])).isDirectory()) {
+ if (fs.existsSync(path.join(mod, mod_files[i], "mod.json")) &&
+ fs.statSync(path.join(mod, mod_files[i], "mod.json")).isFile()) {
+
+ let mod_name = mod_files[i];
+ let use_mod_name = false;
+
+ while (mods.installing.includes(mod_name)) {
+ if (! mods.dupe_msg_sent) {
+ mods.dupe_msg_sent = true;
+ ipcMain.emit("duped-mod", "", mod_name);
+ }
+
+ use_mod_name = true;
+ mod_name = mod_name + " (dupe)";
+ }
+
+ mods.installing.push(mod_name);
+
+ let install = false;
+ if (use_mod_name) {
+ install = mods.install(path.join(mod, mod_files[i]), {
+ ...opts,
+ forked: true,
+ destname: mod_name,
+ })
+ } else {
+ install = mods.install(path.join(mod, mod_files[i]), {
+ ...opts,
+ forked: true
+ })
+ }
+
+ if (install) {return true};
+ }
+ }
+ }
+
+ return notamod();
+ }
+ } else {
+ utils.winLog(lang("gui.mods.extracting"));
+ let cache = path.join(app.getPath("userData"), "Archives");
+ if (fs.existsSync(cache)) {
+ fs.rmSync(cache, {recursive: true});
+ fs.mkdirSync(path.join(cache, "mods"), {recursive: true});
+ } else {
+ fs.mkdirSync(path.join(cache, "mods"), {recursive: true});
+ }
+
+ try {
+ if (mod.replace(/.*\./, "").toLowerCase() == "zip") {
+ fs.createReadStream(mod).pipe(unzip.Extract({path: cache}))
+ .on("finish", () => {
+ 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"), {
+ ...opts,
+
+ forked: true,
+ malformed: true,
+ manifest_file: manifest,
+ destname: require(manifest).name
+ })) {
+
+ 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, {
+ ...opts,
+ forked: true,
+ destname: false,
+ manifest_file: manifest
+ })) {
+
+ return true
+ }
+ }, 1000)
+ }
+ }
+
+ if (files.length == 0) {
+ ipcMain.emit("failed-mod");
+ return notamod();
+ }
+ }
+
+ return notamod();
+ }
+
+ if (mods.install(cache, {
+ ...opts,
+ forked: true
+ })) {
+ installed();
+ } else {return notamod()}
+ }, 1000)
+ });
+ } else {
+ return notamod();
+ }
+ }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()
+mods.installFromURL = (url, author) => {
+ update_path();
+
+ 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);
+
+ stream.on("finish", () => {
+ stream.close();
+ mods.install(modlocation, {
+ author: author
+ })
+ })
+ })
+}
+
+// Removes mods
+//
+// Takes in the names of the mod then removes it, no confirmation,
+// that'd be up to the GUI.
+mods.remove = (mod) => {
+ update_path();
+
+ if (utils.getNSVersion() == "unknown") {
+ utils.winLog(lang("general.notinstalled"));
+ console.log("error: " + lang("general.notinstalled"));
+ cli.exit(1);
+ return false;
+ }
+
+ if (mod == "allmods") {
+ let modlist = mods.list().all;
+ for (let i = 0; i < modlist.length; i++) {
+ mods.remove(modlist[i].Name);
+ }
+ return
+ }
+
+ let disabled = path.join(mods.path, "disabled");
+ if (! fs.existsSync(disabled)) {
+ fs.mkdirSync(disabled);
+ }
+
+ let mod_name = mods.get(mod).FolderName;
+ if (! mod_name) {
+ console.log("error: " + lang("cli.mods.cantfind"));
+ cli.exit(1);
+ return;
+ }
+
+ let path_to_mod = path.join(mods.path, mod_name);
+
+ if (mods.get(mod).Disabled) {
+ path_to_mod = path.join(disabled, mod_name);
+ }
+
+ if (fs.statSync(path_to_mod).isDirectory()) {
+ let manifestname = null;
+ if (fs.existsSync(path.join(path_to_mod, "manifest.json"))) {
+ manifestname = require(path.join(path_to_mod, "manifest.json")).name;
+ }
+
+ fs.rmSync(path_to_mod, {recursive: true});
+ console.log(lang("cli.mods.removed"));
+ cli.exit();
+ ipcMain.emit("gui-getmods");
+ ipcMain.emit("removed-mod", "", {
+ name: mod.replace(/^.*(\\|\/|\:)/, ""),
+ manifestname: manifestname
+ });
+ } else {
+ cli.exit(1);
+ }
+}
+
+// Toggles mods
+//
+// If a mod is enabled it'll disable it, vice versa it'll enable it if
+// it's disabled. You could have a direct .disable() function if you
+// checked for if a mod is already disable and if not run the function.
+// However we currently have no need for that.
+mods.toggle = (mod, fork) => {
+ update_path();
+
+ if (utils.getNSVersion() == "unknown") {
+ utils.winLog(lang("general.notinstalled"));
+ console.log("error: " + lang("general.notinstalled"));
+ cli.exit(1);
+ return false;
+ }
+
+ if (mod == "allmods") {
+ let modlist = mods.list().all;
+ for (let i = 0; i < modlist.length; i++) {
+ mods.toggle(modlist[i].Name, true);
+ }
+
+ console.log(lang("cli.mods.toggledall"));
+ cli.exit(0);
+ return
+ }
+
+ mods.modfile.toggle(mod);
+ if (! fork) {
+ console.log(lang("cli.mods.toggled"));
+ cli.exit();
+ }
+ ipcMain.emit("gui-getmods");
+}
+
+module.exports = mods;
diff --git a/src/utils.js b/src/utils.js
index 6cfdb19..9beaa3e 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -1,7 +1,6 @@
const path = require("path");
const fs = require("fs-extra");
-const copy = require("recursive-copy");
-const { app, dialog, ipcMain, Notification } = require("electron");
+const { dialog, ipcMain, Notification } = require("electron");
const Emitter = require("events");
const events = new Emitter();
@@ -441,522 +440,6 @@ function gamepathExists() {
return fs.existsSync(settings.gamepath);
}
-// Used to manage mods.
-//
-// We can both get list of disabled mods, remove/install/toggle mods and
-// other things akin to that, all kinds of mod related stuff
-let modpath = path.join(settings.gamepath, "R2Northstar/mods");
-const mods = {
- // Returns a list of mods
- //
- // It'll return 3 arrays, all, enabled, disabled. all being a
- // 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"));
- cli.exit(1);
- return false;
- }
-
- let enabled = [];
- let disabled = [];
-
- if (! fs.existsSync(modpath)) {
- fs.mkdirSync(path.join(modpath), {recursive: true});
- return {
- enabled: [],
- disabled: [],
- all: []
- };
- }
-
- files = fs.readdirSync(modpath);
- files.forEach((file) => {
- if (fs.statSync(path.join(modpath, file)).isDirectory()) {
- let modjson = path.join(modpath, file, "mod.json");
- if (fs.existsSync(modjson)) {
- let mod = json(modjson);
- if (! mod) {return}
-
- let obj = {
- Version: "unknown",
- Name: "unknown",
- FolderName: file,
- ...mod}
-
- obj.Disabled = ! mods.modfile().get(obj.Name);
-
- let manifestfile = path.join(modpath, file, "manifest.json");
- if (fs.existsSync(manifestfile)) {
- let manifest = json(manifestfile);
- if (manifest != false) {
- obj.ManifestName = manifest.name;
- if (obj.Version == "unknown") {
- obj.Version = manifest.version_number;
- }
- }
- }
-
- if (obj.Disabled) {
- disabled.push(obj);
- } else {
- enabled.push(obj);
- }
- }
- }
- })
-
- return {
- enabled: enabled,
- disabled: disabled,
- all: [...enabled, ...disabled]
- };
- },
-
- // Gets information about a mod
- //
- // Folder name, version, name and whatever else is in the mod.json,
- // keep in mind if the mod developer didn't format their JSON file
- // 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"));
- cli.exit(1);
- return false;
- }
-
- 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;
- },
-
- // Manages the enabledmods.json file
- //
- // It can both return info about the file, but also toggle mods in
- // it, generate the file itself, and so on.
- modfile: () => {
- let modpath = path.join(settings.gamepath, "R2Northstar/mods");
- let file = path.join(modpath, "..", "enabledmods.json");
-
- if (! fs.existsSync(modpath)) {
- fs.mkdirSync(path.join(modpath), {recursive: true});
- }
-
- if (! fs.existsSync(file)) {
- fs.writeFileSync(file, "{}");
- }
-
- return {
- gen: () => {
- let names = {};
- let list = mods.list().all;
- for (let i = 0; i < list.length; i++) {
- names[list[i].Name] = true
- }
-
- fs.writeFileSync(file, JSON.stringify(names));
- },
- disable: (mod) => {
- let data = json(file);
- data[mod] = false;
- fs.writeFileSync(file, JSON.stringify(data));
- },
- enable: (mod) => {
- let data = json(file);
- data[mod] = true;
- fs.writeFileSync(file, JSON.stringify(data));
- },
- toggle: (mod) => {
- let data = json(file);
- if (data[mod] != undefined) {
- data[mod] = ! data[mod];
- } else {
- data[mod] = false;
- }
-
- fs.writeFileSync(file, JSON.stringify(data));
- },
- get: (mod) => {
- let data = json(file);
- let names = Object.keys(data);
-
- if (data[mod]) {
- return true;
- } else if (data[mod] === false) {
- return false;
- } else {
- return true;
- }
- }
- };
- },
-
- installing: [],
- dupe_msg_sent: false,
-
- // Installs mods from a file path
- //
- // 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, opts) => {
- let modname = mod.replace(/^.*(\\|\/|\:)/, "");
-
- opts = {
- forked: false,
- author: false,
- destname: false,
- malformed: false,
- manifest_file: false,
- ...opts
- }
-
- if (! opts.forked) {
- mods.installing = [];
- mods.dupe_msg_sent = false;
- }
-
- if (getNSVersion() == "unknown") {
- winLog(lang("general.notinstalled"));
- console.log("error: " + lang("general.notinstalled"));
- cli.exit(1);
- return false;
- }
-
- let notamod = () => {
- winLog(lang("gui.mods.notamod"));
- console.log("error: " + lang("cli.mods.notamod"));
- cli.exit(1);
- return false;
- }
-
- let installed = () => {
- console.log(lang("cli.mods.installed"));
- 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("installed-mod", "", {
- name: modname,
- malformed: opts.malformed,
- });
-
- ipcMain.emit("gui-getmods");
- return true;
- }
-
- if (! fs.existsSync(mod)) {return notamod()}
-
- 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()) {
-
-
- if (! json(path.join(mod, "mod.json"))) {
- ipcMain.emit("failed-mod");
- return notamod();
- }
-
- if (fs.existsSync(path.join(modpath, modname))) {
- fs.rmSync(path.join(modpath, modname), {recursive: true});
- }
-
- let copydest = path.join(modpath, modname);
- if (typeof opts.destname == "string") {
- copydest = path.join(modpath, opts.destname)
- }
-
- copy(mod, copydest, (err, res) => {
- if (err) {
- ipcMain.emit("failed-mod");
- return;
- }
-
- copy(opts.manifest_file, path.join(copydest, "manifest.json"), (err, res) => {
- if (err) {
- ipcMain.emit("failed-mod");
- return;
- }
-
- if (opts.author) {
- fs.writeFileSync(
- path.join(copydest, "thunderstore_author.txt"),
- opts.author
- )
- }
-
- return installed();
- });
- });
-
- return;
- } else {
- mod_files = fs.readdirSync(mod);
-
- for (let i = 0; i < mod_files.length; i++) {
- if (fs.statSync(path.join(mod, mod_files[i])).isDirectory()) {
- if (fs.existsSync(path.join(mod, mod_files[i], "mod.json")) &&
- fs.statSync(path.join(mod, mod_files[i], "mod.json")).isFile()) {
-
- let mod_name = mod_files[i];
- let use_mod_name = false;
-
- while (mods.installing.includes(mod_name)) {
- if (! mods.dupe_msg_sent) {
- mods.dupe_msg_sent = true;
- ipcMain.emit("duped-mod", "", mod_name);
- }
-
- use_mod_name = true;
- mod_name = mod_name + " (dupe)";
- }
-
- mods.installing.push(mod_name);
-
- let install = false;
- if (use_mod_name) {
- install = mods.install(path.join(mod, mod_files[i]), {
- ...opts,
- forked: true,
- destname: mod_name,
- })
- } else {
- install = mods.install(path.join(mod, mod_files[i]), {
- ...opts,
- forked: true
- })
- }
-
- if (install) {return true};
- }
- }
- }
-
- 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(path.join(cache, "mods"), {recursive: true});
- } else {
- fs.mkdirSync(path.join(cache, "mods"), {recursive: true});
- }
-
- try {
- if (mod.replace(/.*\./, "").toLowerCase() == "zip") {
- fs.createReadStream(mod).pipe(unzip.Extract({path: cache}))
- .on("finish", () => {
- 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"), {
- ...opts,
-
- forked: true,
- malformed: true,
- manifest_file: manifest,
- destname: require(manifest).name
- })) {
-
- 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, {
- ...opts,
- forked: true,
- destname: false,
- manifest_file: manifest
- })) {
-
- return true
- }
- }, 1000)
- }
- }
-
- if (files.length == 0) {
- ipcMain.emit("failed-mod");
- return notamod();
- }
- }
-
- return notamod();
- }
-
- if (mods.install(cache, {
- ...opts,
- forked: true
- })) {
- installed();
- } else {return notamod()}
- }, 1000)
- });
- } else {
- return notamod();
- }
- }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, author) => {
- 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);
-
- stream.on("finish", () => {
- stream.close();
- mods.install(modlocation, {
- author: author
- })
- })
- })
- },
-
- // 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"));
- cli.exit(1);
- return false;
- }
-
- if (mod == "allmods") {
- let modlist = mods.list().all;
- for (let i = 0; i < modlist.length; i++) {
- mods.remove(modlist[i].Name);
- }
- return
- }
-
- let disabled = path.join(modpath, "disabled");
- if (! fs.existsSync(disabled)) {
- fs.mkdirSync(disabled);
- }
-
- let modName = mods.get(mod).FolderName;
- if (! modName) {
- console.log("error: " + lang("cli.mods.cantfind"));
- cli.exit(1);
- return;
- }
-
- let modPath = path.join(modpath, modName);
-
- if (mods.get(mod).Disabled) {
- modPath = path.join(disabled, modName);
- }
-
- 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("gui-getmods");
- ipcMain.emit("removed-mod", "", {
- name: mod.replace(/^.*(\\|\/|\:)/, ""),
- manifestname: manifestname
- });
- } else {
- cli.exit(1);
- }
- },
-
- // Toggles mods
- //
- // If a mod is enabled it'll disable it, vice versa it'll enable it
- // if it's disabled. You could have a direct .disable() function if
- // 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) => {
- if (getNSVersion() == "unknown") {
- winLog(lang("general.notinstalled"));
- console.log("error: " + lang("general.notinstalled"));
- cli.exit(1);
- return false;
- }
-
- if (mod == "allmods") {
- let modlist = mods.list().all;
- for (let i = 0; i < modlist.length; i++) {
- mods.toggle(modlist[i].Name, true);
- }
-
- console.log(lang("cli.mods.toggledall"));
- cli.exit(0);
- return
- }
-
- mods.modfile().toggle(mod);
- if (! fork) {
- console.log(lang("cli.mods.toggled"));
- cli.exit();
- }
- ipcMain.emit("gui-getmods");
- }
-};
-
setInterval(() => {
if (gamepathExists()) {
ipcMain.emit("gui-getmods");
@@ -970,7 +453,6 @@ setInterval(() => {
}, 1500)
module.exports = {
- mods,
winLog,
updateViper,