diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/index.js | 19 | ||||
-rw-r--r-- | src/modules/mods.js | 546 | ||||
-rw-r--r-- | src/utils.js | 520 |
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, |