From a12c73e95f7de4167d4e20f77d5e942f1e12d179 Mon Sep 17 00:00:00 2001 From: 0neGal Date: Wed, 23 Nov 2022 00:49:58 +0100 Subject: actually fix duplicate mods If a mod has multiple mod folders inside it, however all with the same name, they'll be merged together, this now fixes that, by adding "(dupe)" to the end of it, along with displaying an error, however it will install successfully. This also happens to add some duplicate toast protection, however this should be reworked, but I am not bothered to deal with it right now, and I instead will be putting this on future me. --- src/app/browser.js | 30 +++++++++++++++++++++ src/index.js | 1 + src/lang/en.json | 2 ++ src/utils.js | 76 +++++++++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 99 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/app/browser.js b/src/app/browser.js index db68d31..995a276 100644 --- a/src/app/browser.js +++ b/src/app/browser.js @@ -373,6 +373,17 @@ function BrowserEl(properties) { browserEntries.appendChild(entry); } +let recent_toasts = {}; +function add_recent_toast(name, timeout = 3000) { + if (recent_toasts[name]) {return} + + recent_toasts[name] = true; + + setTimeout(() => { + delete recent_toasts[name]; + }, timeout) +} + ipcRenderer.on("removed-mod", (event, mod) => { setButtons(true); Browser.setbutton(mod.name, lang("gui.browser.install")); @@ -382,6 +393,9 @@ ipcRenderer.on("removed-mod", (event, mod) => { }) ipcRenderer.on("failed-mod", (event, modname) => { + if (recent_toasts["failed" + modname]) {return} + add_recent_toast("failed" + modname); + setButtons(true); new Toast({ timeout: 10000, @@ -391,6 +405,19 @@ ipcRenderer.on("failed-mod", (event, modname) => { }) }) +ipcRenderer.on("duped-mod", (event, modname) => { + if (recent_toasts["duped" + modname]) {return} + add_recent_toast("duped" + modname); + + setButtons(true); + new Toast({ + timeout: 10000, + scheme: "warning", + title: lang("gui.toast.title.duped"), + description: modname + " " + lang("gui.toast.desc.duped") + }) +}) + ipcRenderer.on("no-internet", (event, modname) => { setButtons(true); new Toast({ @@ -402,6 +429,9 @@ ipcRenderer.on("no-internet", (event, modname) => { }) ipcRenderer.on("installed-mod", (event, mod) => { + if (recent_toasts["installed" + mod.name]) {return} + add_recent_toast("installed" + mod.name); + setButtons(true); Browser.setbutton(mod.name, lang("gui.browser.reinstall")); diff --git a/src/index.js b/src/index.js index 30e36f5..02a7a60 100644 --- a/src/index.js +++ b/src/index.js @@ -67,6 +67,7 @@ function start() { ipcMain.on("win-alert", (event, ...args) => {send("alert", ...args)}); // mod states + 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())}); diff --git a/src/lang/en.json b/src/lang/en.json index 51093fa..aadcee0 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -133,11 +133,13 @@ "gui.gamepath.lost": "Gamepath no longer exists/can't be found!\n\nMake sure your drive is mounted properly, or if you moved your game location that you update the game path.\n\nViper may not work properly until next restart!", "gui.toast.title.installed": "Mod installed!", + "gui.toast.title.duped": "Duplicate folder names!", "gui.toast.title.failed": "Failed to install", "gui.toast.title.malformed": "Incorrect folder structure!", "gui.toast.desc.installed": "has been installed successfully!", "gui.toast.desc.malformed": "has an incorrect folder structure, if you're the developer, you should fix this.", "gui.toast.desc.failed": "An unknown error occurred while trying to install the mod. This may be the author's fault, and it may also be Viper's fault.", + "gui.toast.desc.duped": "has multiple mod folders in it, with the same name, causing duplicate folders, if you're the developer, you should fix this.", "gui.toast.noInternet.title": "No Internet", "gui.toast.noInternet.desc": "Viper may not work properly.", diff --git a/src/utils.js b/src/utils.js index 5f74f3d..890fc8c 100644 --- a/src/utils.js +++ b/src/utils.js @@ -672,14 +672,30 @@ const mods = { }; }, + 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, destname, manifestfile, malformed = false) => { + install: (mod, opts ) => { let modname = mod.replace(/^.*(\\|\/|\:)/, ""); + opts = { + forked: 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")); @@ -710,7 +726,7 @@ const mods = { ipcMain.emit("installed-mod", "", { name: modname, - malformed: malformed, + malformed: opts.malformed, }); ipcMain.emit("gui-getmods"); @@ -728,7 +744,6 @@ const mods = { try { JSON.parse(fs.readFileSync(path.join(mod, "mod.json"))); }catch(err) { - console.log("json failed") ipcMain.emit("failed-mod"); return notamod(); } @@ -738,10 +753,12 @@ const mods = { } let copydest = path.join(modpath, modname); - if (typeof destname == "string") {copydest = path.join(modpath, destname)} + if (typeof opts.destname == "string") { + copydest = path.join(modpath, opts.destname) + } copy(mod, copydest); - copy(manifestfile, path.join(copydest, "manifest.json")); + copy(opts.manifest_file, path.join(copydest, "manifest.json")); return installed(); } else { @@ -752,8 +769,34 @@ const mods = { if (fs.existsSync(path.join(mod, mod_files[i], "mod.json")) && fs.statSync(path.join(mod, mod_files[i], "mod.json")).isFile()) { - mods.install(path.join(mod, mod_files[i])); - if (mods.install(path.join(mod, mod_files[i]))) {return true}; + 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]), { + forked: true, + destname: mod_name, + }) + } else { + install = mods.install(path.join(mod, mod_files[i]), { + forked: true + }) + } + + if (install) {return true}; } } } @@ -781,7 +824,13 @@ const mods = { 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)) { + if (mods.install(path.join(cache, "mods"), { + forked: true, + malformed: true, + manifest_file: manifest, + destname: require(manifest).name + })) { + return true; } } else { @@ -789,7 +838,14 @@ const mods = { let mod = path.join(cache, "mods", files[i]); if (fs.statSync(mod).isDirectory()) { setTimeout(() => { - if (mods.install(mod, false, manifest)) {return true}; + if (mods.install(mod, { + forked: true, + destname: false, + manifest_file: manifest + })) { + + return true + } }, 1000) } } @@ -803,7 +859,7 @@ const mods = { return notamod(); } - if (mods.install(cache)) { + if (mods.install(cache, { forked: true })) { installed(); } else {return notamod()} }, 1000) -- cgit v1.2.3