diff options
-rw-r--r-- | src/cli.js | 11 | ||||
-rw-r--r-- | src/index.js | 336 | ||||
-rw-r--r-- | src/modules/gamepath.js | 61 | ||||
-rw-r--r-- | src/modules/ipc.js | 32 | ||||
-rw-r--r-- | src/modules/is_running.js | 5 | ||||
-rw-r--r-- | src/modules/kill.js | 15 | ||||
-rw-r--r-- | src/modules/launch.js | 6 | ||||
-rw-r--r-- | src/modules/mods.js | 86 | ||||
-rw-r--r-- | src/modules/packages.js | 12 | ||||
-rw-r--r-- | src/modules/releases.js | 12 | ||||
-rw-r--r-- | src/modules/requests.js | 19 | ||||
-rw-r--r-- | src/modules/settings.js | 28 | ||||
-rw-r--r-- | src/modules/update.js | 76 | ||||
-rw-r--r-- | src/modules/version.js | 17 | ||||
-rw-r--r-- | src/modules/window.js | 15 | ||||
-rw-r--r-- | src/win.js | 13 |
16 files changed, 400 insertions, 344 deletions
@@ -80,7 +80,16 @@ async function init() { // --update if (cli.hasSwitch("update") && gamepathExists()) {ipcMain.emit("update")} // --version - if (cli.hasSwitch("version") && gamepathExists()) {ipcMain.emit("version-cli")} + if (cli.hasSwitch("version") && gamepathExists()) { + let version = require("./modules/version"); + + console.log("Viper: v" + require("../package.json").version); + console.log("Titanfall 2: " + version.titanfall()); + console.log("Northstar: " + version.northstar()); + console.log("Node: " + process.version); + console.log("Electron: v" + process.versions.electron); + exit(); + } // --setpath if (cli.hasSwitch("setpath")) { diff --git a/src/index.js b/src/index.js index 82805d1..ef6703a 100644 --- a/src/index.js +++ b/src/index.js @@ -1,30 +1,24 @@ -const fs = require("fs"); const path = require("path"); -const { autoUpdater } = require("electron-updater"); -const { app, ipcMain, BrowserWindow, dialog } = require("electron"); +const { app, BrowserWindow } = require("electron"); // ensures PWD/CWD is the config folder where viper.json is located process.chdir(app.getPath("appData")); const cli = require("./cli"); -const lang = require("./lang"); +const main_win = require("./win"); -const json = require("./modules/json"); -const kill = require("./modules/kill"); const mods = require("./modules/mods"); const update = require("./modules/update"); -const launch = require("./modules/launch"); -const win_show = require("./modules/window"); const version = require("./modules/version"); -const gamepath = require("./modules/gamepath"); const settings = require("./modules/settings"); -const requests = require("./modules/requests"); -const releases = require("./modules/releases"); -const packages = require("./modules/packages"); -const is_running = require("./modules/is_running"); + +// loads `ipcMain` events that dont fit in any of the modules directly +require("./modules/ipc"); + +// required to load launch IPC events +require("./modules/launch"); console = require("./modules/console"); -var log = console.log; // Starts the actual BrowserWindow, which is only run when using the // GUI, for the CLI this function is never called. @@ -50,7 +44,16 @@ function start() { nodeIntegration: true, contextIsolation: false, }, - }); + }) + + // makes sending things to the renderer a little more readable + win.send = (channel, data) => { + win.webContents.send(channel, data); + }; send = win.send; + + // give `main_win` the main window, `main_win()` will then be equal + // to `win`, but its accessible anywhere + main_win.set(win); // when --devtools is added it'll open the dev tools if (cli.hasParam("devtools")) { @@ -63,159 +66,24 @@ function start() { }, 1) } - // general setup + // we dont need this! win.removeMenu(); + + // load `src/app/index.html` (the app) win.loadURL("file://" + __dirname + "/app/index.html", { userAgent: "viper/" + version.viper(), - }); - - win.send = (channel, data) => { - win.webContents.send(channel, data); - }; send = win.send; - - ipcMain.on("exit", () => { - if (settings().originkill) { - is_running.origin().then((running) => { - if (running) { - kill.origin().then(process.exit(0)) - } else { - process.exit(0) - } - }) - } else { - process.exit(0) - } - }); - - ipcMain.on("minimize", () => {win.minimize()}); - ipcMain.on("relaunch", () => { - app.relaunch({ - args: process.argv.slice(1) - }); - - app.exit(0); - }); - - ipcMain.on("kill-game", () => { - kill.game(); - }); - - ipcMain.on("kill-origin", () => { - kill.origin(); - }); - - ipcMain.on("delete-request-cache", () => { - requests.cache.delete.all(); - }); - - ipcMain.on("delete-install-cache", () => { - let delete_dirs = [ - path.join(app.getPath("cache"), "vipertmp"), - path.join(settings().gamepath, "northstar.zip") - ] - - for (let i = 0; i < delete_dirs.length; i++) { - if (fs.existsSync(delete_dirs[i])) { - fs.rmSync(delete_dirs[i], {recursive: true}); - } - } - }); - - ipcMain.on("reset-config", async () => { - let confirmation = await win_show.confirm( - lang("gui.settings.miscbuttons.reset_config_alert") - ) - - if (confirmation) { - fs.rmSync("viper.json"); - - app.relaunch({ - args: process.argv.slice(1) - }); - - app.exit(0); - } - }); - - // passthrough to renderer from main - ipcMain.on("win-log", (event, ...args) => {send("log", ...args)}); - ipcMain.on("win-alert", (event, msg, id) => { - send("alert", { - id: id, - message: msg, - }) - }); - - ipcMain.on("win-confirm", (event, msg, id) => { - send("confirm", { - id: id, - message: msg, - }) - }); - - // 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", mods.list())}); - ipcMain.on("installed-mod", (event, modname) => {send("installed-mod", modname)}); - ipcMain.on("no-internet", () => {send("no-internet")}); + }) + // print exceptions to terminal, and forward the exception to the + // renderer, it'll then show a more user friendly error message process.on("uncaughtException", (err) => { send("unknown-error", err); console.error(err); - }); - - // install calls - ipcMain.on("install-from-path", (event, path) => {mods.install(path)}); - ipcMain.on("install-from-url", (event, url, author, package_name, version) => { - packages.install(url, author, package_name, version); - }); - - // lets renderer use `requests.get()` - ipcMain.handle("request", async (e, ...args) => { - let res = false; - - try { - res = await requests.get(...args); - }catch(err) {} - - return res; }) + // load list of mods on initial load win.webContents.on("dom-ready", () => { send("mods", mods.list()); - }); - - // ensures gamepath still exists and is valid on startup - let gamepathlost = false; - ipcMain.on("gamepath-lost", (event, ...args) => { - if (! gamepathlost) { - gamepathlost = true; - send("gamepath-lost"); - } - }); - - ipcMain.on("save-settings", (event, obj) => { - settings().save(obj, false); - }); - - ipcMain.on("saved-settings", (event, obj) => { - send("changed-settings", obj); - }); - - // allows renderer to check for updates - ipcMain.on("ns-update-event", (event) => {send("ns-update-event", event)}); - - let update_active; - ipcMain.on("can-autoupdate", () => { - if (typeof update_active == "undefined") { - update_active = autoUpdater.isUpdaterActive(); - } - - if (! update_active || cli.hasParam("no-vp-updates")) { - send("cant-autoupdate"); - } }) // start auto-update process @@ -223,171 +91,29 @@ function start() { if (cli.hasParam("no-vp-updates")) { update.northstar_autoupdate(); } else { - update.viper(false) + update.viper(false); } } else { update.northstar_autoupdate(); } - - autoUpdater.on("update-downloaded", () => { - send("update-available"); - }); - - // updates and restarts Viper, if user says yes to do so. - // otherwise it'll do it on the next start up. - ipcMain.on("update-now", () => { - autoUpdater.quitAndInstall(); - }) - - setInterval(async () => { - send("is-running", await is_running.game()); - }, 1000) } -ipcMain.on("install-mod", () => { - if (cli.hasArgs()) { - mods.install(cli.param("installmod")); - } else { - dialog.showOpenDialog({properties: ["openFile"]}).then(res => { - if (res.filePaths.length != 0) { - mods.install(res.filePaths[0]); - } else { - send("set-buttons", true); - } - }).catch(err => {error(err)}); - } -}) - -ipcMain.on("remove-mod", (event, mod) => {mods.remove(mod)}); -ipcMain.on("toggle-mod", (event, mod) => {mods.toggle(mod)}); - -ipcMain.on("launch-ns", () => {launch()}); -ipcMain.on("launch-vanilla", () => {launch("vanilla")}); - -ipcMain.on("setlang", (event, lang) => { - settings().set("lang", lang); - settings().save(); -}); - -ipcMain.on("update-northstar", async (e, force_install) => { - if (await is_running.game()) { - return win_show.alert(lang("general.auto_updates.game_running")); - } - - update.northstar(force_install); -}) - -ipcMain.on("setpath-cli", () => {gamepath.set()}); -ipcMain.on("setpath", (event, value, force_dialog) => { - if (! value) { - if (! win.isVisible()) { - gamepath.set(win, force_dialog); - } else { - gamepath.set(win, force_dialog || true); - } - } else if (! win.isVisible()) { - win.show(); - } -}); - -// retrieves various local version numbers -function sendVersionsInfo() { - send("version", { - ns: version.northstar(), - tf2: version.titanfall(), - vp: "v" + version.viper() - }); -} - -// sends the version info back to the renderer -ipcMain.on("get-version", () => {sendVersionsInfo()}); - -// prints out version info for the CLI -ipcMain.on("version-cli", () => { - log("Viper: v" + require("../package.json").version); - log("Titanfall 2: " + version.titanfall()); - log("Northstar: " + version.northstar()); - log("Node: " + process.version); - log("Electron: v" + process.versions.electron); - cli.exit(); -}) - -// sends installed mods info to renderer -ipcMain.on("getmods", () => { - let mods = mods.list(); - if (mods.all.length > 0) { - log(`${lang("general.mods.installed")} ${mods.all.length}`); - log(`${lang("general.mods.enabled")} ${mods.enabled.length}`); - for (let i = 0; i < mods.enabled.length; i++) { - log(` ${mods.enabled[i].name} ${mods.enabled[i].version}`); - } - - if (mods.disabled.length > 0) { - log(`${lang("general.mods.disabled")} ${mods.disabled.length}`); - for (let i = 0; i < mods.disabled.length; i++) { - log(` ${mods.disabled[i].name} ${mods.disabled[i].version}`); - } - } - cli.exit(0); - } else { - log("No mods installed"); - cli.exit(0); - } -}) -// } - -// allows renderer to set a new renderer -ipcMain.on("newpath", (event, newpath) => { - if (newpath === false && ! win.isVisible()) { - win.send("no-path-selected"); - } else { - sendVersionsInfo(); - if (!win.isVisible()) { - win.show(); - } - } -}); ipcMain.on("wrong-path", () => { - win.send("wrong-path"); -}); - -ipcMain.on("found-missing-perms", async (e, selected_gamepath) => { - await win_show.alert(lang("gui.gamepath.found_missing_perms") + selected_gamepath); - ipcMain.emit("setpath", null, false, true); -}) - -ipcMain.on("missing-perms", async (e, selected_gamepath) => { - await win_show.alert(lang("gui.gamepath.missing_perms") + selected_gamepath); - ipcMain.emit("setpath"); -}) - -ipcMain.on("gamepath-lost-perms", async (e, selected_gamepath) => { - if (! gamepath.setting) { - gamepath.setting = true; - await win_show.alert(lang("gui.gamepath.lost_perms") + selected_gamepath); - ipcMain.emit("setpath"); - } -}) - // starts the GUI or CLI if (cli.hasArgs()) { if (cli.hasParam("update-viper")) { update.viper(true); } else { + // start the CLI cli.init(); } } else { app.on("ready", () => { + // makes it so Electron cache doesn't get stored in your system + // config folder, changing it over to actually using the system + // cache folder instead app.setPath("userData", path.join(app.getPath("cache"), app.name)); + // start the window/GUI start(); }) } - -// returns cached requests -ipcMain.on("get-ns-notes", async () => { - win.send("ns-notes", await releases.notes.northstar()); -}); - -ipcMain.on("get-vp-notes", async () => { - win.send("vp-notes", await releases.notes.viper()); -}); diff --git a/src/modules/gamepath.js b/src/modules/gamepath.js index 8d28c29..9d12854 100644 --- a/src/modules/gamepath.js +++ b/src/modules/gamepath.js @@ -1,18 +1,77 @@ const path = require("path"); const fs = require("fs-extra"); +const win = require("../win"); const { dialog, ipcMain } = require("electron"); const cli = require("../cli"); const lang = require("../lang"); +const version = require("./version"); const win_show = require("./window"); const settings = require("./settings"); const findgame = require("./findgame"); - let gamepath = {}; +ipcMain.on("setpath-cli", () => {gamepath.set()}); +ipcMain.on("setpath", (event, value, force_dialog) => { + if (! value) { + if (! win().isVisible()) { + gamepath.set(win(), force_dialog); + } else { + gamepath.set(win(), force_dialog || true); + } + } else if (! win().isVisible()) { + win().show(); + } +}) + + +// allows renderer to set a new renderer +ipcMain.on("newpath", (event, newpath) => { + if (newpath === false && ! win().isVisible()) { + win().send("no-path-selected"); + } else { + version.send_info(); + + if (! win().isVisible()) { + win().show(); + } + } +}) + +ipcMain.on("wrong-path", () => { + win().send("wrong-path"); +}) + +ipcMain.on("found-missing-perms", async (e, selected_gamepath) => { + await win_show.alert(lang("gui.gamepath.found_missing_perms") + selected_gamepath); + ipcMain.emit("setpath", null, false, true); +}) + +ipcMain.on("missing-perms", async (e, selected_gamepath) => { + await win_show.alert(lang("gui.gamepath.missing_perms") + selected_gamepath); + ipcMain.emit("setpath"); +}) + +ipcMain.on("gamepath-lost-perms", async (e, selected_gamepath) => { + if (! gamepath.setting) { + gamepath.setting = true; + await win_show.alert(lang("gui.gamepath.lost_perms") + selected_gamepath); + ipcMain.emit("setpath"); + } +}) + +// ensures gamepath still exists and is valid on startup +let gamepathlost = false; +ipcMain.on("gamepath-lost", (event, ...args) => { + if (! gamepathlost) { + gamepathlost = true; + win().send("gamepath-lost"); + } +}) + // returns true/false depending on if the gamepath currently exists/is // mounted, used to avoid issues... gamepath.exists = (folder) => { diff --git a/src/modules/ipc.js b/src/modules/ipc.js new file mode 100644 index 0000000..55737b7 --- /dev/null +++ b/src/modules/ipc.js @@ -0,0 +1,32 @@ +const win = require("../win"); +const { app, ipcMain } = require("electron"); + +const kill = require("./kill"); +const settings = require("./settings"); +const is_running = require("./is_running"); + +ipcMain.on("exit", () => { + if (settings().originkill) { + is_running.origin().then((running) => { + if (running) { + kill.origin().then(process.exit(0)); + } else { + process.exit(0) ; + } + }) + } else { + process.exit(0); + } +}) + +ipcMain.on("minimize", () => { + win().minimize(); +}) + +ipcMain.on("relaunch", () => { + app.relaunch({ + args: process.argv.slice(1) + }) + + app.exit(0); +}) diff --git a/src/modules/is_running.js b/src/modules/is_running.js index 1cfdc1d..b9fbde1 100644 --- a/src/modules/is_running.js +++ b/src/modules/is_running.js @@ -1,7 +1,12 @@ +const win = require("../win"); const exec = require("child_process").exec; let is_running = {}; +setInterval(async () => { + win().send("is-running", await is_running.game()); +}, 1000) + // a simple function that checks whether any of a given set of process // names are running, you can either input a string or an Array of // strings diff --git a/src/modules/kill.js b/src/modules/kill.js index 3c93f7b..43eda23 100644 --- a/src/modules/kill.js +++ b/src/modules/kill.js @@ -1,4 +1,13 @@ const exec = require("child_process").exec; +const ipcMain = require("electron").ipcMain; + +ipcMain.on("kill-game", () => { + kill.game(); +}) + +ipcMain.on("kill-origin", () => { + kill.origin(); +}) // a simple function to kill processes with a certain name async function kill(process_name) { @@ -9,13 +18,13 @@ async function kill(process_name) { case "linux": return "killall -9 " + proc; case "win32": return "taskkill /IM " + proc + " /F"; } - })(); + })() exec(cmd, (err, stdout) => { // just try and fail silently if we don't find it w/e resolve(true); - }); - }); + }) + }) } kill.process = kill; diff --git a/src/modules/launch.js b/src/modules/launch.js index bb094e9..e9ad1a3 100644 --- a/src/modules/launch.js +++ b/src/modules/launch.js @@ -1,4 +1,5 @@ const exec = require("child_process").exec; +const ipcMain = require("electron").ipcMain; const cli = require("../cli"); const lang = require("../lang"); @@ -8,6 +9,11 @@ const settings = require("./settings"); console = require("./console"); +ipcMain.on("launch-ns", launch); +ipcMain.on("launch-vanilla", () => { + launch("vanilla"); +}) + // launches the game // // either Northstar or Vanilla. Linux support is not currently a thing, diff --git a/src/modules/mods.js b/src/modules/mods.js index 122ff7f..2e9288b 100644 --- a/src/modules/mods.js +++ b/src/modules/mods.js @@ -2,8 +2,8 @@ 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 { app, ipcMain, dialog } = require("electron"); const json = require("./json"); const win = require("./window"); @@ -14,12 +14,72 @@ console = require("./console"); const cli = require("../cli"); const lang = require("../lang"); +const main_win = require("../win"); var mods = { installing: [], dupe_msg_sent: false, } +ipcMain.on("remove-mod", (event, mod) => { + mods.remove(mod); +}) + +ipcMain.on("toggle-mod", (event, mod) => { + mods.toggle(mod); +}) + +// lets renderer install mods from a path +ipcMain.on("install-from-path", (event, path) => { + mods.install(path); +}) + +ipcMain.on("no-internet", () => { + main_win().send("no-internet"); +}) + +ipcMain.on("install-mod", () => { + if (cli.hasArgs()) { + mods.install(cli.param("installmod")); + } else { + dialog.showOpenDialog({properties: ["openFile"]}).then(res => { + if (res.filePaths.length != 0) { + mods.install(res.filePaths[0]); + } else { + main_win().send("set-buttons", true); + } + }).catch(err => {error(err)}); + } +}) + +// sends installed mods info to renderer +ipcMain.on("gui-getmods", (event, ...args) => { + main_win().send("mods", mods.list()); +}) + +ipcMain.on("getmods", () => { + let mods = mods.list(); + + if (mods.all.length > 0) { + log(`${lang("general.mods.installed")} ${mods.all.length}`); + log(`${lang("general.mods.enabled")} ${mods.enabled.length}`); + for (let i = 0; i < mods.enabled.length; i++) { + log(` ${mods.enabled[i].name} ${mods.enabled[i].version}`); + } + + if (mods.disabled.length > 0) { + log(`${lang("general.mods.disabled")} ${mods.disabled.length}`); + for (let i = 0; i < mods.disabled.length; i++) { + log(` ${mods.disabled[i].name} ${mods.disabled[i].version}`); + } + } + cli.exit(0); + } else { + log("No mods installed"); + cli.exit(0); + } +}) + function update_path() { mods.path = path.join(settings().gamepath, "R2Northstar/mods"); }; update_path(); @@ -341,12 +401,12 @@ mods.install = (mod, opts) => { } } - ipcMain.emit("installed-mod", "", { + main_win().send("installed-mod", { name: modname, malformed: opts.malformed, - }); + }) - ipcMain.emit("gui-getmods"); + main_win().send("mods", mods.list()); return true; } @@ -360,7 +420,7 @@ mods.install = (mod, opts) => { if (! json(path.join(mod, "mod.json"))) { - ipcMain.emit("failed-mod"); + main_win().send("failed-mod"); return notamod(); } @@ -375,13 +435,13 @@ mods.install = (mod, opts) => { copy(mod, copydest, (err) => { if (err) { - ipcMain.emit("failed-mod"); + main_win().send("failed-mod"); return; } copy(opts.manifest_file, path.join(copydest, "manifest.json"), (err) => { if (err) { - ipcMain.emit("failed-mod"); + main_win().send("failed-mod"); return; } @@ -411,7 +471,7 @@ mods.install = (mod, opts) => { while (mods.installing.includes(mod_name)) { if (! mods.dupe_msg_sent) { mods.dupe_msg_sent = true; - ipcMain.emit("duped-mod", "", mod_name); + main_win().send("duped-mod", mod_name); } use_mod_name = true; @@ -490,7 +550,7 @@ mods.install = (mod, opts) => { } if (files.length == 0) { - ipcMain.emit("failed-mod"); + main_win().send("failed-mod"); return notamod(); } } @@ -612,14 +672,14 @@ mods.remove = (mod) => { console.ok(lang("cli.mods.removed")); cli.exit(); - ipcMain.emit("gui-getmods"); // send updated list to renderer + main_win().send("mods", mods.list()); // send updated list to renderer // tell the renderer that the mod has been removed, along with // relevant info for it to properly update everything graphically - ipcMain.emit("removed-mod", "", { + main_win().send("removed-mod", { name: mod.replace(/^.*(\\|\/|\:)/, ""), manifest_name: manifest_name - }); + }) } // toggles mods @@ -660,7 +720,7 @@ mods.toggle = (mod, fork) => { } // send updated modlist to renderer - ipcMain.emit("gui-getmods"); + main_win().send("mods", mods.list()); } module.exports = mods; diff --git a/src/modules/packages.js b/src/modules/packages.js index 392c550..88e389a 100644 --- a/src/modules/packages.js +++ b/src/modules/packages.js @@ -5,6 +5,7 @@ const { app, ipcMain } = require("electron"); const https = require("follow-redirects").https; const lang = require("../lang"); +const main_win = require("../win"); const json = require("./json"); const win = require("./window"); @@ -14,6 +15,11 @@ console = require("./console"); var packages = {}; +// lets renderer install packages +ipcMain.on("install-from-url", (event, url, author, package_name, version) => { + packages.install(url, author, package_name, version); +}) + function update_path() { packages.path = path.join(settings().gamepath, "R2Northstar/packages"); @@ -238,7 +244,7 @@ packages.install = async (url, author, package_name, version) => { } break; default: - ipcMain.emit("failed-mod", name); + main_win().send("failed-mod", name); // other unhandled error console.error( @@ -303,7 +309,7 @@ packages.install = async (url, author, package_name, version) => { let moved = packages.move(package_path); if (! moved) { - ipcMain.emit("failed-mod", name); + main_win().send("failed-mod", name); console.error("Moving package failed:", name); cleanup(); @@ -311,7 +317,7 @@ packages.install = async (url, author, package_name, version) => { return false; } - ipcMain.emit("installed-mod", "", { + main_win().send("installed-mod", { name: name, fancy_name: package_name }) diff --git a/src/modules/releases.js b/src/modules/releases.js index c071970..b041d38 100644 --- a/src/modules/releases.js +++ b/src/modules/releases.js @@ -1,3 +1,6 @@ +const win = require("../win"); +const ipcMain = require("electron").ipcMain; + const requests = require("./requests"); let releases = { @@ -5,6 +8,15 @@ let releases = { latest: {} } +// returns release notes to renderer +ipcMain.on("get-ns-notes", async () => { + win().send("ns-notes", await releases.notes.northstar()); +}) + +ipcMain.on("get-vp-notes", async () => { + win().send("vp-notes", await releases.notes.viper()); +}) + // gets and returns the release notes of a GitHub repo async function github_releases(repo) { let request = false; diff --git a/src/modules/requests.js b/src/modules/requests.js index d4ee678..60e0760 100644 --- a/src/modules/requests.js +++ b/src/modules/requests.js @@ -1,6 +1,6 @@ const fs = require("fs"); const path = require("path"); -const app = require("electron").app; +const { app, ipcMain } = require("electron"); const https = require("follow-redirects").https; const json = require("./json"); @@ -9,6 +9,23 @@ const version = require("./version"); var cache_dir = app.getPath("userData"); var cache_file = path.join(cache_dir, "cached-requests.json"); +// lets renderer delete request cache +ipcMain.on("delete-request-cache", () => { + requests.cache.delete.all(); +}) + +// lets renderer use `requests.get()` +ipcMain.handle("request", async (e, ...args) => { + let res = false; + + try { + res = await requests.get(...args); + }catch(err) {} + + return res; +}) + + // updates `cache_dir` and `cache_file` function set_paths() { cache_dir = app.getPath("userData"); diff --git a/src/modules/settings.js b/src/modules/settings.js index db6c68c..ae02c79 100644 --- a/src/modules/settings.js +++ b/src/modules/settings.js @@ -4,11 +4,37 @@ const { app, ipcMain } = require("electron"); const json = require("./json"); const lang = require("../lang"); +const win = require("./window"); console = require("./console"); var invalid_settings = false; +ipcMain.on("save-settings", (event, obj) => { + save(obj, false); +}) + +ipcMain.on("reset-config", async () => { + let confirmation = await win.confirm( + lang("gui.settings.miscbuttons.reset_config_alert") + ) + + if (confirmation) { + fs.rmSync("viper.json"); + + app.relaunch({ + args: process.argv.slice(1) + }) + + app.exit(0); + } +}) + +ipcMain.on("setlang", (event, lang) => { + set("lang", lang); + save(); +}) + // base settings var settings = { gamepath: "", @@ -81,7 +107,7 @@ let save = (obj = {}, notify_renderer = true) => { settings = settings_content; if (notify_renderer) { - ipcMain.emit("saved-settings", settings_content); + send("changed-settings", obj); } } diff --git a/src/modules/update.js b/src/modules/update.js index 6b31da7..1165622 100644 --- a/src/modules/update.js +++ b/src/modules/update.js @@ -1,9 +1,11 @@ const path = require("path"); const fs = require("fs-extra"); -const { ipcMain, Notification } = require("electron"); +const { autoUpdater } = require("electron-updater"); +const { app, ipcMain, Notification } = require("electron"); const cli = require("../cli"); const lang = require("../lang"); +const main_win = require("../win"); const win = require("./window"); const version = require("./version"); @@ -15,10 +17,60 @@ const is_running = require("./is_running"); console = require("./console"); const unzip = require("unzipper"); -const { https } = require("follow-redirects"); +const https = require("follow-redirects").https; let update = {}; +ipcMain.on("delete-install-cache", () => { + let delete_dirs = [ + path.join(app.getPath("cache"), "vipertmp"), + path.join(settings().gamepath, "northstar.zip") + ] + + for (let i = 0; i < delete_dirs.length; i++) { + if (fs.existsSync(delete_dirs[i])) { + fs.rmSync(delete_dirs[i], {recursive: true}); + } + } +}) + +ipcMain.on("update-northstar", async (e, force_install) => { + if (await is_running.game()) { + return win.alert(lang("general.auto_updates.game_running")); + } + + update.northstar(force_install); +}) + +// inform renderer that an update has been downloaded +autoUpdater.on("update-downloaded", () => { + main_win().send("update-available"); +}) + +// updates and restarts Viper, if user says yes to do so. +// otherwise it'll do it on the next start up. +ipcMain.on("update-now", () => { + autoUpdater.quitAndInstall(); +}) + +let update_active; + +// renderer requested a check for whether we can auto updates +ipcMain.on("can-autoupdate", () => { + // is this the first time we're checking? + if (typeof update_active == "undefined") { + // save auto updater status + update_active = autoUpdater.isUpdaterActive(); + } + + // if `update_active` is falsy or `--no-vp-updates` is set, + // inform the renderer that auto updates aren't possible + if (! update_active || cli.hasParam("no-vp-updates")) { + main_win().send("cant-autoupdate"); + } +}) + + // renames excluded files to their original name function restore_excluded_files() { if (! gamepath.exists()) {return} @@ -219,7 +271,7 @@ update.northstar = async (force_install) => { return; } - ipcMain.emit("ns-update-event", "cli.update.checking"); + main_win().send("ns-update-event", "cli.update.checking"); console.info(lang("cli.update.checking")); let ns_version = version.northstar(); @@ -227,13 +279,13 @@ update.northstar = async (force_install) => { if (latest && latest.version == false) { update.northstar.updating = false; - ipcMain.emit("ns-update-event", "cli.update.noInternet"); + main_win().send("ns-update-event", "cli.update.noInternet"); return; } // Makes sure it is not already the latest version if (! force_install && ! await northstar_update_available()) { - ipcMain.emit("ns-update-event", "cli.update.uptodate_short"); + main_win().send("ns-update-event", "cli.update.uptodate_short"); console.ok(lang("cli.update.uptodate").replace("%s", ns_version)); win.log(lang("gui.update.uptodate")); @@ -254,7 +306,7 @@ update.northstar = async (force_install) => { https.get(latest.download_link, (res) => { // cancel out if zip can't be retrieved and or found if (res.statusCode !== 200) { - ipcMain.emit("ns-update-event", "cli.update.uptodate_short"); + main_win().send("ns-update-event", "cli.update.uptodate_short"); console.ok(lang("cli.update.uptodate"), ns_version); update.northstar.updating = false; return false; @@ -279,11 +331,11 @@ update.northstar = async (force_install) => { } console.info(lang("cli.update.downloading") + ":", latest.version); - ipcMain.emit("ns-update-event", { + main_win().send("ns-update-event", { progress: 0, btn_text: "1/2", key: "cli.update.downloading", - }); + }) let tmp = path.dirname(settings().zip); @@ -317,7 +369,7 @@ update.northstar = async (force_install) => { percentage_str = " - " + current_percentage + "%"; } - ipcMain.emit("ns-update-event", { + main_win().send("ns-update-event", { key: key, progress: current_percentage, btn_text: "1/2" + percentage_str @@ -331,7 +383,7 @@ update.northstar = async (force_install) => { let extract = fs.createReadStream(settings().zip); win.log(lang("gui.update.extracting")); - ipcMain.emit("ns-update-event", { + main_win().send("ns-update-event", { progress: 0, btn_text: "2/2 - 0%", key: lang("gui.update.extracting") @@ -352,7 +404,7 @@ update.northstar = async (force_install) => { let percent = Math.floor(extracted / size * 100); let extracted_mb = (extracted / 1024 / 1024).toFixed(1); - ipcMain.emit("ns-update-event", { + main_win().send("ns-update-event", { progress: percent, btn_text: "2/2 - " + percent + "%", key: lang("gui.update.extracting") + @@ -368,7 +420,7 @@ update.northstar = async (force_install) => { ipcMain.emit("gui-getmods"); ipcMain.emit("get-version"); - ipcMain.emit("ns-update-event", "cli.update.uptodate_short"); + main_win().send("ns-update-event", "cli.update.uptodate_short"); win.log(lang("gui.update.finished")); console.ok(lang("cli.update.finished")); diff --git a/src/modules/version.js b/src/modules/version.js index da0a730..e337fc4 100644 --- a/src/modules/version.js +++ b/src/modules/version.js @@ -1,11 +1,28 @@ const path = require("path"); const fs = require("fs-extra"); +const ipcMain = require("electron").ipcMain; + +const win = require("../win"); const json = require("./json"); const settings = require("./settings"); let version = {}; +// sends the version info back to the renderer +ipcMain.on("get-version", () => { + version.send_info(); +}) + +// retrieves various local version numbers and sends them to the renderer +version.send_info = () => { + win().send("version", { + ns: version.northstar(), + tf2: version.titanfall(), + vp: "v" + version.viper() + }) +} + // returns the current Northstar version // if not installed it'll return "unknown" version.northstar = () => { diff --git a/src/modules/window.js b/src/modules/window.js index 6cc573c..ebb0165 100644 --- a/src/modules/window.js +++ b/src/modules/window.js @@ -1,10 +1,11 @@ +const main_win = require("../win"); const ipcMain = require("electron").ipcMain; let win = {}; // logs into the dev tools of the renderer -win.log = (msg) => { - ipcMain.emit("win-log", msg, msg); +win.log = (...args) => { + main_win().send("log", ...args); } // this increments for every alert that's created, the ID is used to @@ -20,7 +21,10 @@ win.alert = (msg) => { resolve(); }) - ipcMain.emit("win-alert", msg, msg, alert_id); + main_win().send("alert", { + id: alert_id, + message: msg + }) }) } @@ -37,7 +41,10 @@ win.confirm = (msg) => { resolve(confirmed); }) - ipcMain.emit("win-confirm", msg, msg, confirm_id); + main_win().send("confirm", { + message: msg, + id: confirm_id + }) }) } diff --git a/src/win.js b/src/win.js new file mode 100644 index 0000000..056dee8 --- /dev/null +++ b/src/win.js @@ -0,0 +1,13 @@ +let win = { + send: () => {} +} + +let func = () => { + return win; +} + +func.set = (main_window) => { + win = main_window; +} + +module.exports = func; |