From 7b5357ef971bb9312c180fcc4352cad40a18d050 Mon Sep 17 00:00:00 2001 From: 0neGal Date: Thu, 2 Jan 2025 21:32:59 +0100 Subject: [PATCH] initial support for new enabledmods.json format --- src/app/js/mods.js | 6 +- src/modules/mods.js | 133 ++++++++++++++++++++++++++++++++++++++------ 2 files changed, 121 insertions(+), 18 deletions(-) diff --git a/src/app/js/mods.js b/src/app/js/mods.js index 511c338..fcd38b9 100644 --- a/src/app/js/mods.js +++ b/src/app/js/mods.js @@ -264,6 +264,10 @@ mods.toggle = (mod) => { for (let mod_obj of mods_list.disabled) { // if `mod` is `mod_obj`, update `is_disabled` if (mod_obj.name.toLowerCase() == mod.toLowerCase()) { + if (version && mod_obj.version != version) { + continue; + } + is_disabled = true; break; } @@ -279,7 +283,7 @@ mods.toggle = (mod) => { } } - ipcRenderer.send("toggle-mod", mod); + ipcRenderer.send("toggle-mod", mod, version); } mods.install_queue = []; diff --git a/src/modules/mods.js b/src/modules/mods.js index aecb5e3..3db0693 100644 --- a/src/modules/mods.js +++ b/src/modules/mods.js @@ -21,16 +21,16 @@ var mods = { dupe_msg_sent: false, } -ipcMain.on("remove-mod", (event, mod) => { +ipcMain.on("remove-mod", (_, mod) => { mods.remove(mod); }) -ipcMain.on("toggle-mod", (event, mod) => { - mods.toggle(mod); +ipcMain.on("toggle-mod", (_, mod, mod_version) => { + mods.toggle(mod, mod_version); }) // lets renderer install mods from a path -ipcMain.on("install-from-path", (event, path) => { +ipcMain.on("install-from-path", (_, path) => { mods.install(path); }) @@ -240,7 +240,7 @@ mods.list = () => { // 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) => { +mods.get = (mod, mod_version) => { update_path(); // make sure Northstar is actually installed @@ -262,6 +262,13 @@ mods.get = (mod) => { // search for mod in list for (let i = 0; i < list.length; i++) { if (list[i].name == mod) { + // make sure `version` is correct, if specified + if (mod_version + && list[i].version != mod_version) { + + continue; + } + // found mod, return data return list[i]; } else {continue} @@ -309,42 +316,105 @@ mods.modfile.gen = () => { } // enable/disable a mod inside enabledmods.json -mods.modfile.set = (mod, state) => { +mods.modfile.set = (mod, mod_version, state) => { modfile_pre(); let data = json(mods.modfile.file); // get current data - data[mod] = state; // set mod state + + // if `mod_version` is specified, attempt to find it + if (! mod_version) { + let mod_obj = mods.get(mod); + + if (mod_obj) { + mod_version = mod_obj.version; + } + } + + // set mod state + if (mod_version) { // set using object format + if (typeof data[mod] != "object") { + data[mod] = {}; + } + + data[mod][mod_version] = state; + } else { // set using legacy method + data[mod] = state; + } // write new data fs.writeFileSync(mods.modfile.file, JSON.stringify(data)); + + mods.modfile.cleanup(); } // disable a mod inside enabledmods.json -mods.modfile.disable = (mod) => { - return mods.modfile.set(mod, false); +mods.modfile.disable = (mod, mod_version) => { + mods.modfile.set(mod, mod_version, false); } // enable a mod inside enabledmods.json -mods.modfile.enable = (mod) => { - return mods.modfile.set(mod, true); +mods.modfile.enable = (mod, mod_version) => { + mods.modfile.set(mod, mod_version, true); } // toggle a mod inside enabledmods.json -mods.modfile.toggle = (mod) => { +mods.modfile.toggle = (mod, mod_version) => { modfile_pre(); - let data = json(mods.modfile.file); - if (data[mod] != undefined) { - data[mod] = ! data[mod]; + let is_enabled = mods.modfile.get(mod, mod_version); + if (is_enabled) { + mods.modfile.disable(mod, mod_version); } else { - data[mod] = false; + mods.modfile.enable(mod, mod_version); } +} + +// runs through `enabledmods.json` and finds mods that are installed, +// but have version entries that aren't installed, and optionally +// upgrades the version entry +mods.modfile.cleanup = () => { + // read enabledmods.json + let data = json(mods.modfile.file); + + for (let mod in data) { + // don't do anything if we're not dealing with the object format + if (typeof data[mod] != "object") { + continue; + } + // run through all mods + for (let mod_version in data[mod]) { + // get data with the specified version + let mod_data = mods.get(mod, mod_version); + + // does no mod exists with the specified version? + if (! mod_data) { + // attempt to get without version + mod_data = mods.get(mod); + + // if the mod exists, but just not with the correct + // version, and the correct version doesn't exist, we + // copy the state of the incorrect version to the + // correct version, this is useful for package updates + if (mod_data + && ! data[mod][mod_data.version]) { + + data[mod][mod_data.version] = + data[mod][mod_version] + } + + // delete orphan version + delete data[mod][mod_version]; + } + } + } + + // write new data fs.writeFileSync(mods.modfile.file, JSON.stringify(data)); } // return whether a mod is disabled or enabled -mods.modfile.get = (mod) => { +mods.modfile.get = (mod, mod_version) => { modfile_pre(); // read enabledmods.json @@ -354,6 +424,31 @@ mods.modfile.get = (mod) => { return true; } + // get state from object format + if (typeof data[mod] == "object") { + // if mod and version is found directly, return it's state + if (mod_version && data[mod][mod_version]) { + return data[mod][mod_version]; + } + + // if version isn't specified, use the first one that's found + if (! mod_version) { + for (let mod_version in data[mod]) { + // found disabled + if (data[mod][mod_version] === false) { + return false; + } + + // found enabled + if (data[mod][mod_version]) { + return true; + } + } + } + + return false; + } + if (data[mod]) { // enabled return true; } else if (data[mod] === false) { // disabled @@ -402,6 +497,7 @@ mods.install = (mod, opts) => { let notamod = () => { win().log(lang("gui.mods.not_a_mod")); console.error(lang("cli.mods.not_a_mod")); + mods.modfile.cleanup(); cli.exit(1); return false; } @@ -426,6 +522,9 @@ mods.install = (mod, opts) => { }) win().send("mods", mods.list()); + + mods.modfile.cleanup(); + return true; }