diff options
author | 0neGal <mail@0negal.com> | 2022-06-29 21:27:40 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-29 21:27:40 +0200 |
commit | 0c54139fc9279fd081eb57e62008456585ffd927 (patch) | |
tree | 8c2e78470c0945e66895cf13cc231b4b672a5400 | |
parent | d21931a94c20bd37278986185433df60c495250a (diff) | |
parent | 4145f882671c5ddde487a456a15dada979ea35c1 (diff) | |
download | Viper-0c54139fc9279fd081eb57e62008456585ffd927.tar.gz Viper-0c54139fc9279fd081eb57e62008456585ffd927.zip |
Merge branch 'main' into deprecate-nsversiontxt
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | README.md | 6 | ||||
-rw-r--r-- | package-lock.json | 4 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/app/browser.js | 41 | ||||
-rw-r--r-- | src/app/css/launcher.css | 29 | ||||
-rw-r--r-- | src/app/css/popups.css | 18 | ||||
-rw-r--r-- | src/app/css/webview.css | 4 | ||||
-rw-r--r-- | src/app/icons/game.png | bin | 0 -> 1454 bytes | |||
-rw-r--r-- | src/app/icons/language.png | bin | 0 -> 7132 bytes | |||
-rw-r--r-- | src/app/icons/updates.png | bin | 0 -> 10300 bytes | |||
-rw-r--r-- | src/app/index.html | 33 | ||||
-rw-r--r-- | src/app/lang.js | 2 | ||||
-rw-r--r-- | src/app/launcher.js | 56 | ||||
-rw-r--r-- | src/app/main.css | 4 | ||||
-rw-r--r-- | src/app/main.js | 48 | ||||
-rw-r--r-- | src/app/settings.js | 14 | ||||
-rw-r--r-- | src/extras/findgame.js | 12 | ||||
-rw-r--r-- | src/index.js | 170 | ||||
-rw-r--r-- | src/lang/en.json | 8 | ||||
-rw-r--r-- | src/lang/es.json | 8 | ||||
-rw-r--r-- | src/lang/fr.json | 8 | ||||
-rw-r--r-- | src/utils.js | 176 |
23 files changed, 441 insertions, 204 deletions
@@ -1,2 +1,4 @@ +.vscode/ + dist/ node_modules/ @@ -1,6 +1,6 @@ <p align="center"> <img src="src/assets/icons/512x512.png" width="200px"><br> - <a href="https://github.com/0neGal/viper/releases/download/v1.5.1/Viper-Setup-1.5.1.exe"><img src="assets/download.png" width="300px"></a><br> + <a href="https://github.com/0neGal/viper/releases/download/v1.6.0/Viper-Setup-1.6.0.exe"><img src="assets/download.png" width="300px"></a><br> <a href="FAQ.md">FAQ</a> | <a href="https://github.com/0neGal/viper/releases">Releases</a><br> </p> @@ -15,9 +15,9 @@ Downloads are available on the [releases page](https://github.com/0neGal/viper/r Please note that some versions will update themselves automatically when a new release is available (just like Origin or Steam) and some will NOT, so choose it accordingly. Only the AppImage, Flatpak and Windows Setup/Installer can auto-update. -**Windows:** [`Viper Setup [x.y.z].exe`](https://github.com/0neGal/viper/releases/download/v1.5.1/Viper-Setup-1.5.1.exe) (auto-updates, and is recommanded), [`Viper [x.y.z].exe`](https://github.com/0neGal/viper/releases/download/v1.5.1/Viper-1.5.1.exe) (single executable, no fuss) +**Windows:** [`Viper Setup [x.y.z].exe`](https://github.com/0neGal/viper/releases/download/v1.6.0/Viper-Setup-1.6.0.exe) (auto-updates, and is recommanded), [`Viper [x.y.z].exe`](https://github.com/0neGal/viper/releases/download/v1.6.0/Viper-1.6.0.exe) (single executable, no fuss) -**Linux:** [`.AppImage`](https://github.com/0neGal/viper/releases/download/v1.5.1/Viper-1.5.1.AppImage) or [Flatpak](https://flathub.org/apps/details/com.github._0negal.Viper) (auto-updates), [AUR (unofficial)](https://aur.archlinux.org/packages/viper-bin), [`.deb`](https://github.com/0neGal/viper/releases/download/v1.5.1/viper-1.5.1_amd64.deb), [`.rpm`](https://github.com/0neGal/viper/releases/download/v1.5.1/Viper-1.5.1.x86_64.rpm), [`.tar.gz`](https://github.com/0neGal/viper/releases/download/v1.5.1/Viper-1.5.1.tar.gz) +**Linux:** [`.AppImage`](https://github.com/0neGal/viper/releases/download/v1.6.0/Viper-1.6.0.AppImage) or [Flatpak](https://flathub.org/apps/details/com.github._0negal.Viper) (auto-updates), [AUR (unofficial)](https://aur.archlinux.org/packages/viper-bin), [`.deb`](https://github.com/0neGal/viper/releases/download/v1.6.0/viper-1.6.0_amd64.deb), [`.rpm`](https://github.com/0neGal/viper/releases/download/v1.6.0/Viper-1.6.0.x86_64.rpm), [`.tar.gz`](https://github.com/0neGal/viper/releases/download/v1.6.0/Viper-1.6.0.tar.gz) ## What can it do specifically? diff --git a/package-lock.json b/package-lock.json index b735c85..636e03f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "viper", - "version": "1.5.1", + "version": "1.6.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "viper", - "version": "1.5.1", + "version": "1.6.0", "license": "GPL-3.0-or-later", "dependencies": { "electron-updater": "^4.6.1", diff --git a/package.json b/package.json index 25f33a4..08d694f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "viper", "productName": "Viper", - "version": "1.5.1", + "version": "1.6.0", "description": "Launcher+Updater for TF|2 Northstar", "main": "src/index.js", "build": { diff --git a/src/app/browser.js b/src/app/browser.js index a292cf6..4b9f2e3 100644 --- a/src/app/browser.js +++ b/src/app/browser.js @@ -18,7 +18,6 @@ var Browser = { } } - console.log(other) return pkgs; }, get: () => { @@ -88,8 +87,8 @@ var Browser = { toggle: (state) => { if (state) { browser.scrollTo(0, 0); - overlay.classList.add("shown") - browser.classList.add("shown") + overlay.classList.add("shown"); + browser.classList.add("shown"); if (browserEntries.querySelectorAll(".el").length == 0) { Browser.loadfront(); @@ -98,16 +97,16 @@ var Browser = { } else if (! state) { if (state != undefined) { Browser.filters.toggle(false); - overlay.classList.remove("shown") - browser.classList.remove("shown") - preview.classList.remove("shown") + overlay.classList.remove("shown"); + browser.classList.remove("shown"); + preview.classList.remove("shown"); return } } browser.scrollTo(0, 0); - overlay.classList.toggle("shown") - browser.classList.toggle("shown") + overlay.classList.toggle("shown"); + browser.classList.toggle("shown"); }, loadfront: async () => { Browser.loading(); @@ -162,11 +161,11 @@ var Browser = { } if (pkgs.length == 0 || isEnd) { - Browser.msg(`${lang('gui.browser.endoflist')}`) + Browser.msg(`${lang('gui.browser.endoflist')}`); return } - Browser.msg(`<button id="loadmore">${lang("gui.browser.loadmore")}</button>`) + Browser.msg(`<button id="loadmore">${lang("gui.browser.loadmore")}</button>`); loadmore.addEventListener("click", () => { Browser.loadpkgs(pkgs); Browser.endoflist(pkgs); @@ -177,7 +176,7 @@ var Browser = { let res = fuse.search(string); if (res.length < 1) { - Browser.loading(lang("gui.browser.noresults")) + Browser.loading(lang("gui.browser.noresults")); return } @@ -244,12 +243,11 @@ var Browser = { } Browser.endoflist(); - console.log(pkgs) break } try { - new BrowserElFromObj(pkgs[i]) + new BrowserElFromObj(pkgs[i]); }catch(e) {} count++; @@ -375,7 +373,7 @@ function BrowserEl(properties) { browserEntries.appendChild(entry); } -ipcRenderer.on("removedmod", (event, mod) => { +ipcRenderer.on("removed-mod", (event, mod) => { setButtons(true); Browser.setbutton(mod.name, lang("gui.browser.install")); if (mod.manifestname) { @@ -383,7 +381,7 @@ ipcRenderer.on("removedmod", (event, mod) => { } }) -ipcRenderer.on("failedmod", (event, modname) => { +ipcRenderer.on("failed-mod", (event, modname) => { setButtons(true); new Toast({ timeout: 10000, @@ -393,7 +391,7 @@ ipcRenderer.on("failedmod", (event, modname) => { }) }) -ipcRenderer.on("installedmod", (event, mod) => { +ipcRenderer.on("installed-mod", (event, mod) => { setButtons(true); Browser.setbutton(mod.name, lang("gui.browser.reinstall")); @@ -420,10 +418,12 @@ ipcRenderer.on("installedmod", (event, mod) => { function normalize(items) { let main = (string) => { - return string.replaceAll(" ", "").replaceAll(".", "").replaceAll("-", "").replaceAll("_", "").toLowerCase() + return string.replaceAll(" ", "") + .replaceAll(".", "").replaceAll("-", "") + .replaceAll("_", "").toLowerCase(); } if (typeof items == "string") { - return main(items) + return main(items); } else { let newArray = []; for (let i = 0; i < items.length; i++) { @@ -462,7 +462,6 @@ events.forEach((event) => { let mouseAt = document.elementsFromPoint(mouseX, mouseY); if (! mouseAt.includes(document.querySelector("#filter")) && ! mouseAt.includes(document.querySelector(".overlay"))) { - console.log(mouseAt) Browser.filters.toggle(false); } }) @@ -498,5 +497,7 @@ browser.addEventListener("mousemove", (event) => { let checks = document.querySelectorAll(".check"); for (let i = 0; i < checks.length; i++) { - checks[i].setAttribute("onclick", "this.classList.toggle('checked');Browser.loadfront();search.value = ''") + checks[i].setAttribute("onclick", + "this.classList.toggle('checked');Browser.loadfront();search.value = ''" + ) } diff --git a/src/app/css/launcher.css b/src/app/css/launcher.css index 03812c6..ce54ddf 100644 --- a/src/app/css/launcher.css +++ b/src/app/css/launcher.css @@ -297,3 +297,32 @@ code { margin-top: calc(var(--spacing) / 2); margin-bottom: calc(var(--spacing) / 2); } + +#serverstatus { + --spacing: calc(var(--padding) / 5); + + transition-duration: 0.2s; + transition-timing-function: ease-in-out; + transition-property: background, opacity; + + opacity: 0.0; + display: block; + margin: 0 auto; + font-weight: 700; + width: fit-content; + color: transparent; + border-radius: 50px; + flex-basis: max-content; + background: transparent; + margin-top: calc(var(--spacing) * 2); + padding: var(--spacing) calc(var(--spacing) * 3); +} + +#serverstatus.up, +#serverstatus.down { + color: white; + opacity: 1.0; +} + +#serverstatus.up {background: rgb(var(--blue));} +#serverstatus.down {background: rgb(var(--red));} diff --git a/src/app/css/popups.css b/src/app/css/popups.css index bff7d07..826955b 100644 --- a/src/app/css/popups.css +++ b/src/app/css/popups.css @@ -350,4 +350,22 @@ background: rgb(var(--red)); } +.switch.on:hover::after { + transform: scale(1.2); +} + +.title { + display: flex; +} + +.title img { + width: 30px; + height: 30px; + margin: auto 0; +} + +.title h2 { + margin-left: calc(var(--padding) / 3); +} + /* } */ diff --git a/src/app/css/webview.css b/src/app/css/webview.css index 9e26b5d..982ebfc 100644 --- a/src/app/css/webview.css +++ b/src/app/css/webview.css @@ -4,9 +4,11 @@ body { background-color: transparent !important; } +#ncmp_tool, .navbar, .bottom-padding, .card-header, .breadcrumb, -.list-group, .mb-4, .my-2, .mt-2 { +.list-group, .mb-4, .my-2, .mt-2, +#thunderstore-mod-manager-ad-alert { display: none !important; } diff --git a/src/app/icons/game.png b/src/app/icons/game.png Binary files differnew file mode 100644 index 0000000..7db058f --- /dev/null +++ b/src/app/icons/game.png diff --git a/src/app/icons/language.png b/src/app/icons/language.png Binary files differnew file mode 100644 index 0000000..011e1f9 --- /dev/null +++ b/src/app/icons/language.png diff --git a/src/app/icons/updates.png b/src/app/icons/updates.png Binary files differnew file mode 100644 index 0000000..4b505ee --- /dev/null +++ b/src/app/icons/updates.png diff --git a/src/app/index.html b/src/app/index.html index f67a7a8..819caac 100644 --- a/src/app/index.html +++ b/src/app/index.html @@ -36,7 +36,10 @@ </button> </div> <div class="options"> - <h2>%%gui.settings.title.ns%%</h2> + <div class="title"> + <img src="icons/game.png"> + <h2>%%gui.settings.title.ns%%</h2> + </div> <div class="option" name="nsargs"> <div class="text"> %%gui.settings.nsargs.title%% @@ -48,7 +51,10 @@ <input> </div> </div> - <h2>%%gui.settings.title.language%%</h2> + <div class="title"> + <img src="icons/language.png"> + <h2>%%gui.settings.title.language%%</h2> + </div> <div class="option" name="autolang"> <div class="text"> %%gui.settings.autolang.title%% @@ -73,7 +79,10 @@ </select> </div> </div> - <h2>%%gui.settings.title.updates%%</h2> + <div class="title"> + <img src="icons/updates.png"> + <h2>%%gui.settings.title.updates%%</h2> + </div> <div class="option" name="autoupdate"> <div class="text"> %%gui.settings.autoupdate.title%% @@ -107,6 +116,21 @@ <input type="text"> </div> </div> + <div class="title"> + <img src="icons/settings.png"> + <h2>%%gui.settings.title.misc%%</h2> + </div> + <div class="option" name="originkill"> + <div class="text"> + %%gui.settings.originkill.title%% + <div class="desc"> + %%gui.settings.originkill.desc%% + </div> + </div> + <div class="actions"> + <button class="switch off"></button> + </div> + </div> </div> </div> @@ -197,6 +221,7 @@ <div class="inline"> <div id="nsversion"></div> <a id="update" href="#" onclick="update()">(%%gui.update.check%%)</a> + <div id="serverstatus" class="checking"></div> </div> </div> </div> @@ -240,4 +265,4 @@ <script src="settings.js"></script> <script src="launcher.js"></script> </body> -</html> +< diff --git a/src/app/lang.js b/src/app/lang.js index 6fdcd8d..f1c31d3 100644 --- a/src/app/lang.js +++ b/src/app/lang.js @@ -10,7 +10,7 @@ function setlang() { if (html[i][0] != " " && html[i][html[i].length - 1] != " ") { // Replaces it with it's string - html[i] = lang(html[i]) + html[i] = lang(html[i]); } } diff --git a/src/app/launcher.js b/src/app/launcher.js index 51d3a63..fbeb703 100644 --- a/src/app/launcher.js +++ b/src/app/launcher.js @@ -1,10 +1,14 @@ const markdown = require("marked").parse; +var servercount; +var playercount; +var masterserver; + // Changes the main page // This is the tabs in the sidebar function page(page) { - let pages = document.querySelectorAll(".mainContainer .contentContainer") - let btns = document.querySelectorAll(".gamesContainer button") + let btns = document.querySelectorAll(".gamesContainer button"); + let pages = document.querySelectorAll(".mainContainer .contentContainer"); for (let i = 0; i < pages.length; i++) { pages[i].classList.add("hidden"); @@ -82,7 +86,10 @@ function showVpSection(section) { } function showNsSection(section) { - if (!["main", "release", "mods"].includes(section)) throw new Error("unknown ns section"); + if (!["main", "release", "mods"].includes(section)) { + throw new Error("unknown ns section"); + } + nsMainBtn.removeAttribute("active"); nsModsBtn.removeAttribute("active"); nsReleaseBtn.removeAttribute("active"); @@ -107,3 +114,46 @@ function showNsSection(section) { break; } } + +async function loadServers() { + serverstatus.classList.add("checking"); + + try { + let servers = await (await fetch("https://northstar.tf/client/servers")).json(); + masterserver = true; + + playercount = 0; + servercount = servers.length; + + for (let i = 0; i < servers.length; i++) { + playercount += servers[i].playerCount + } + }catch (err) { + playercount = 0; + servercount = 0; + masterserver = false; + } + + serverstatus.classList.remove("checking"); + + if (servercount == 0 || ! servercount || ! playercount) {masterserver = false} + + let playerstr = lang("gui.server.players"); + if (playercount == 1) { + playerstr = lang("gui.server.player"); + } + + if (masterserver) { + serverstatus.classList.add("up"); + serverstatus.innerHTML = `${servercount} ${lang("gui.server.servers")} - ${playercount} ${playerstr}`; + } else { + serverstatus.classList.add("down"); + serverstatus.innerHTML = lang("gui.server.offline"); + + } +}; loadServers() + +// Refreshes every 5 minutes +setInterval(() => { + loadServers(); +}, 300000) diff --git a/src/app/main.css b/src/app/main.css index ce45f35..f39c5a1 100644 --- a/src/app/main.css +++ b/src/app/main.css @@ -59,6 +59,10 @@ button:active {filter: brightness(90%)} #winbtns #minimize {background-image: url("icons/minimize.png")} #winbtns #settings {background-image: url("icons/settings.png")} +#winbtns #settings:hover { + transform: rotate(90deg); +} + #winbtns div:hover {opacity: 1.0} #winbtns div:active {transform: scale(0.95)} /* } */ diff --git a/src/app/main.js b/src/app/main.js index 362450a..9fb3191 100644 --- a/src/app/main.js +++ b/src/app/main.js @@ -14,6 +14,7 @@ var settings = { autolang: true, forcedlang: "en", autoupdate: true, + originkill: false, zip: "/northstar.zip", lang: navigator.language, excludes: [ @@ -36,9 +37,9 @@ if (fs.existsSync("viper.json")) { }catch (e) { let reset = confirm(lang("general.invalidconfig", navigator.language) + e); if (! reset) { - ipcRenderer.send("exit") + ipcRenderer.send("exit"); } else { - fs.writeFileSync("viper.json", "{}") + fs.writeFileSync("viper.json", "{}"); ipcRenderer.send("relaunch"); } @@ -76,12 +77,12 @@ function launch() { update(); shouldInstallNorthstar = false; } else { - ipcRenderer.send("launch"); + ipcRenderer.send("launch-ns"); } } // Tells the main process to launch the vanilla game -function launchVanilla() {ipcRenderer.send("launchVanilla")} +function launchVanilla() {ipcRenderer.send("launch-vanilla")} // In conjunction with utils.js' winLog(), it'll send log messages in // the devTools from utils.js @@ -100,13 +101,16 @@ function setButtons(state) { } } - disablearray(document.querySelectorAll(".playBtnContainer .playBtn")) - disablearray(document.querySelectorAll("#nsMods .buttons.modbtns button")) - disablearray(document.querySelectorAll("#browser #browserEntries .text button")) + disablearray(document.querySelectorAll(".playBtnContainer .playBtn")); + disablearray(document.querySelectorAll("#nsMods .buttons.modbtns button")); + disablearray(document.querySelectorAll("#browser #browserEntries .text button")); } -ipcRenderer.on("setbuttons", (event, state) => {setButtons(state)}) -ipcRenderer.on("gamepathlost", (event, state) => { +ipcRenderer.on("set-buttons", (event, state) => { + setButtons(state); +}) + +ipcRenderer.on("gamepath-lost", (event, state) => { page(0); setButtons(false); alert(lang("gui.gamepath.lost")); @@ -172,7 +176,7 @@ function selected(all) { } } - ipcRenderer.send("removemod", selected) + ipcRenderer.send("remove-mod", selected); }, toggle: () => { if (selected.match(/^Northstar\./)) { @@ -185,7 +189,7 @@ function selected(all) { } } - ipcRenderer.send("togglemod", selected) + ipcRenderer.send("toggle-mod", selected); } } } @@ -195,19 +199,18 @@ let installqueue = []; // Tells the main process to install a mod through the file selector function installmod() { setButtons(false); - ipcRenderer.send("installmod") + ipcRenderer.send("install-mod"); } // Tells the main process to directly install a mod from this path function installFromPath(path) { setButtons(false); - ipcRenderer.send("installfrompath", path) + ipcRenderer.send("install-from-path", path); } // Tells the main process to install a mod from a URL function installFromURL(url, dependencies, clearqueue) { if (clearqueue) {installqueue = []}; - console.log(installqueue) let prettydepends = []; @@ -215,7 +218,6 @@ function installFromURL(url, dependencies, clearqueue) { let newdepends = []; for (let i = 0; i < dependencies.length; i++) { let depend = dependencies[i].toLowerCase(); - console.log(depend) if (! depend.match(/northstar-northstar-.*/)) { depend = dependencies[i].replaceAll("-", "/"); let pkg = depend.split("/"); @@ -237,7 +239,7 @@ function installFromURL(url, dependencies, clearqueue) { } setButtons(false); - ipcRenderer.send("installfromurl", url, dependencies) + ipcRenderer.send("install-from-url", url, dependencies); if (dependencies) { installqueue = dependencies; @@ -262,7 +264,7 @@ function isModInstalled(modname) { // Frontend part of settings a new game path ipcRenderer.on("newpath", (event, newpath) => { settings.gamepath = newpath; - ipcRenderer.send("guigetmods"); + ipcRenderer.send("gui-getmods"); }) // Continuation of log() @@ -310,23 +312,23 @@ ipcRenderer.on("version", (event, versions) => { shouldInstallNorthstar = true; playNsBtn.innerText = lang("gui.installnorthstar"); } -}); ipcRenderer.send("getversion"); +}); ipcRenderer.send("get-version"); // When an update is available it'll ask the user about it -ipcRenderer.on("updateavailable", () => { +ipcRenderer.on("update-available", () => { if (confirm(lang("gui.update.available"))) { - ipcRenderer.send("updatenow"); + ipcRenderer.send("update-now"); } }) // Error out when no game path is set -ipcRenderer.on("nopathselected", () => { +ipcRenderer.on("no-path-selected", () => { alert(lang("gui.gamepath.must")); exit(); }); // Error out when game path is wrong -ipcRenderer.on("wrongpath", () => { +ipcRenderer.on("wrong-path", () => { alert(lang("gui.gamepath.wrong")); setpath(false); }); @@ -355,7 +357,7 @@ document.addEventListener("drop", (e) => { event.stopPropagation(); dragUI.classList.remove("shown"); - installFromPath(event.dataTransfer.files[0].path) + installFromPath(event.dataTransfer.files[0].path); }); document.body.addEventListener("keyup", (e) => { diff --git a/src/app/settings.js b/src/app/settings.js index 23b38c9..63b4b99 100644 --- a/src/app/settings.js +++ b/src/app/settings.js @@ -3,26 +3,26 @@ var Settings = { if (state) { Settings.load(); options.scrollTo(0, 0); - overlay.classList.add("shown") - options.classList.add("shown") + overlay.classList.add("shown"); + options.classList.add("shown"); return } else if (! state) { if (state != undefined) { - overlay.classList.remove("shown") - options.classList.remove("shown") + overlay.classList.remove("shown"); + options.classList.remove("shown"); return } } Settings.load(); options.scrollTo(0, 0); - overlay.classList.toggle("shown") - options.classList.toggle("shown") + overlay.classList.toggle("shown"); + options.classList.toggle("shown"); }, apply: () => { settings = {...settings, ...Settings.get()}; - ipcRenderer.send("savesettings", Settings.get()); + ipcRenderer.send("save-settings", Settings.get()); }, reloadSwitches: () => { let switches = document.querySelectorAll(".switch"); diff --git a/src/extras/findgame.js b/src/extras/findgame.js index 3beca23..615c5b4 100644 --- a/src/extras/findgame.js +++ b/src/extras/findgame.js @@ -38,13 +38,13 @@ module.exports = async () => { // `.length - 1` This is because the last value is `contentstatsid` for (let i = 0; i < values.length; i++) { - let data_array = Object.values(values[i]) + let data_array = Object.values(values[i]); if (fs.existsSync(data_array[0] + "/steamapps/common/Titanfall2/Titanfall2.exe")) { - console.log("Found game in:", data_array[0]) + console.log("Found game in:", data_array[0]); return data_array[0] + "/steamapps/common/Titanfall2"; } else { - console.log("Game not in:", data_array[0]) + console.log("Game not in:", data_array[0]); } } } @@ -69,10 +69,10 @@ module.exports = async () => { if (folders.length > 0) { for (let i = 0; i < folders.length; i++) { if (! fs.existsSync(folders[i])) {continue} - console.log("Searching VDF file at:", folders[i]) + console.log("Searching VDF file at:", folders[i]); - let data = fs.readFileSync(folders[i]) - let read_vdf = readvdf(data.toString()) + let data = fs.readFileSync(folders[i]); + let read_vdf = readvdf(data.toString()); if (read_vdf) {return read_vdf} } } diff --git a/src/index.js b/src/index.js index e718ef9..2c03529 100644 --- a/src/index.js +++ b/src/index.js @@ -3,79 +3,103 @@ const path = require("path"); const { autoUpdater } = require("electron-updater"); const { app, ipcMain, BrowserWindow, dialog } = require("electron"); -const Emitter = require("events"); -const events = new Emitter(); - const utils = require("./utils"); const cli = require("./cli"); const requests = require("./extras/requests"); +var log = console.log; + // Starts the actual BrowserWindow, which is only run when using the // GUI, for the CLI this function is never called. function start() { win = new BrowserWindow({ width: 1000, height: 600, + title: "Viper", // Hides the window initially, it'll be shown when the DOM is // loaded, as to not cause visual issues. show: false, - title: "Viper", // In the future we may want to allow the user to resize the window, // as it's fairly responsive, but for now we won't allow that. resizable: false, - titleBarStyle: "hidden", + frame: false, + titleBarStyle: "hidden", icon: path.join(__dirname, "assets/icons/512x512.png"), webPreferences: { webviewTag: true, nodeIntegration: true, contextIsolation: false, }, - }); + }); - // When --debug is added it'll open the dev tools + // when --debug is added it'll open the dev tools if (cli.hasParam("debug")) {win.openDevTools()} - // General setup + // general setup win.removeMenu(); win.loadFile(__dirname + "/app/index.html"); + win.send = (channel, data) => { + win.webContents.send(channel, data); + }; send = win.send; + + ipcMain.on("exit", () => { + if (utils.settings.originkill) { + utils.isOriginRunning().then((running) => { + if (running) { + utils.killOrigin().then(process.exit(0)) + } else { + process.exit(0) + } + }) + } else { + process.exit(0) + } + }); + ipcMain.on("minimize", () => {win.minimize()}); + ipcMain.on("relaunch", () => {app.relaunch(); app.exit()}); + + // passthrough to renderer from main + ipcMain.on("win-log", (event, ...args) => {send("log", ...args)}); + ipcMain.on("win-alert", (event, ...args) => {send("alert", ...args)}); + + // mod states + 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("installed-mod", (event, modname) => {send("installed-mod", modname)}); - ipcMain.on("exit", () => {process.exit(0)}) - ipcMain.on("minimize", () => {win.minimize()}) - ipcMain.on("relaunch", () => {app.relaunch();app.exit()}) - ipcMain.on("installfrompath", (event, path) => {utils.mods.install(path)}) - ipcMain.on("installfromurl", (event, url) => {utils.mods.installFromURL(url)}) - ipcMain.on("winLog", (event, ...args) => {win.webContents.send("log", ...args)}); - ipcMain.on("winAlert", (event, ...args) => {win.webContents.send("alert", ...args)}); - ipcMain.on("ns-update-event", (event) => win.webContents.send("ns-update-event", event)); - ipcMain.on("failedmod", (event, modname) => {win.webContents.send("failedmod", modname)}); - ipcMain.on("removedmod", (event, modname) => {win.webContents.send("removedmod", modname)}); - ipcMain.on("installedmod", (event, modname) => {win.webContents.send("installedmod", modname)}); - ipcMain.on("guigetmods", (event, ...args) => {win.webContents.send("mods", utils.mods.list())}); + // install calls + ipcMain.on("install-from-path", (event, path) => {utils.mods.install(path)}); + ipcMain.on("install-from-url", (event, url) => {utils.mods.installFromURL(url)}); + + win.webContents.on("dom-ready", () => { + send("mods", utils.mods.list()); + }); + // ensures gamepath still exists and is valid on startup let gamepathlost = false; - ipcMain.on("gamepathlost", (event, ...args) => { + ipcMain.on("gamepath-lost", (event, ...args) => { if (! gamepathlost) { gamepathlost = true; - win.webContents.send("gamepathlost"); + send("gamepath-lost"); } }); - ipcMain.on("savesettings", (event, obj) => {utils.saveSettings(obj)}) + ipcMain.on("save-settings", (event, obj) => {utils.saveSettings(obj)}); - ipcMain.on("can-autoupdate", (event) => { - if (! require("electron-updater").autoUpdater.isUpdaterActive() || cli.hasParam("no-vp-updates")) { - win.webContents.send("cant-autoupdate") + // allows renderer to check for updates + ipcMain.on("ns-update-event", (event) => {send("ns-update-event", event)}); + ipcMain.on("can-autoupdate", () => { + if (! autoUpdater.isUpdaterActive() || cli.hasParam("no-vp-updates")) { + send("cant-autoupdate"); } }) - win.webContents.on("dom-ready", () => { - win.webContents.send("mods", utils.mods.list()); - }); - + // start auto-update process if (utils.settings.autoupdate) { if (cli.hasParam("no-vp-updates")) { utils.handleNorthstarUpdating(); @@ -87,41 +111,42 @@ function start() { } autoUpdater.on("update-downloaded", () => { - win.webContents.send("updateavailable") + 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("updatenow", () => { + // 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(); }) } // General events used to handle utils.js stuff without requiring the // module inside the file that sent the event. { -ipcMain.on("installmod", () => { +ipcMain.on("install-mod", () => { if (cli.hasArgs()) { - utils.mods.install(cli.param("installmod")) + utils.mods.install(cli.param("installmod")); } else { dialog.showOpenDialog({properties: ["openFile"]}).then(res => { if (res.filePaths.length != 0) { utils.mods.install(res.filePaths[0]); } else { - win.webContents.send("setbuttons", true); + send("set-buttons", true); } - }).catch(err => {console.error(err)}) + }).catch(err => {error(err)}); } }) -ipcMain.on("removemod", (event, mod) => {utils.mods.remove(mod)}) -ipcMain.on("togglemod", (event, mod) => {utils.mods.toggle(mod)}) +ipcMain.on("remove-mod", (event, mod) => {utils.mods.remove(mod)}); +ipcMain.on("toggle-mod", (event, mod) => {utils.mods.toggle(mod)}); + +ipcMain.on("launch-ns", () => {utils.launch()}); +ipcMain.on("launch-vanilla", () => {utils.launch("vanilla")}); -ipcMain.on("launch", (event) => {utils.launch()}) -ipcMain.on("setlang", (event, lang) => {utils.setlang(lang)}) -ipcMain.on("launchVanilla", (event) => {utils.launch("vanilla")}) +ipcMain.on("setlang", (event, lang) => {utils.setlang(lang)}); -ipcMain.on("update", (event) => {utils.update()}) -ipcMain.on("setpathcli", (event) => {utils.setpath()}); +ipcMain.on("update", () => {utils.update()}) +ipcMain.on("setpath-cli", () => {utils.setpath()}); ipcMain.on("setpath", (event, value) => { if (! value) { if (! win.isVisible()) { @@ -134,66 +159,69 @@ ipcMain.on("setpath", (event, value) => { } }); -function _sendVersionsInfo() { - win.webContents.send("version", { +// retrieves various local version numbers +function sendVersionsInfo() { + send("version", { ns: utils.getNSVersion(), tf2: utils.getTF2Version(), vp: "v" + require("../package.json").version }); } -// Sends the version info back to the renderer -ipcMain.on("getversion", () => {_sendVersionsInfo()}); +// sends the version info back to the renderer +ipcMain.on("get-version", () => {sendVersionsInfo()}); -// Prints out version info for the CLI -ipcMain.on("versioncli", () => { - console.log("Viper: v" + require("../package.json").version); - console.log("Northstar: " + utils.getNSVersion()); - console.log("Node: " + process.version); - console.log("Electron: v" + process.versions.electron); +// prints out version info for the CLI +ipcMain.on("version-cli", () => { + log("Viper: v" + require("../package.json").version); + log("Northstar: " + utils.getNSVersion()); + log("Node: " + process.version); + log("Electron: v" + process.versions.electron); cli.exit(); }) -ipcMain.on("getmods", (event) => { +// sends installed mods info to renderer +ipcMain.on("getmods", () => { let mods = utils.mods.list(); if (mods.all.length > 0) { - console.log(`${utils.lang("general.mods.installed")} ${mods.all.length}`) - console.log(`${utils.lang("general.mods.enabled")} ${mods.enabled.length}`) + log(`${utils.lang("general.mods.installed")} ${mods.all.length}`); + log(`${utils.lang("general.mods.enabled")} ${mods.enabled.length}`); for (let i = 0; i < mods.enabled.length; i++) { - console.log(` ${mods.enabled[i].Name} ${mods.enabled[i].Version}`) + log(` ${mods.enabled[i].Name} ${mods.enabled[i].Version}`); } if (mods.disabled.length > 0) { - console.log(`${utils.lang("general.mods.disabled")} ${mods.disabled.length}`) + log(`${utils.lang("general.mods.disabled")} ${mods.disabled.length}`); for (let i = 0; i < mods.disabled.length; i++) { - console.log(` ${mods.disabled[i].Name} ${mods.disabled[i].Version}`) + log(` ${mods.disabled[i].Name} ${mods.disabled[i].Version}`); } } cli.exit(0); } else { - console.log("No mods installed"); + 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.webContents.send("nopathselected"); + if (newpath === false && ! win.isVisible()) { + win.send("no-path-selected"); } else { _sendVersionsInfo(); if (!win.isVisible()) { win.show(); } } -}); ipcMain.on("wrongpath", (event) => { - win.webContents.send("wrongpath"); +}); ipcMain.on("wrong-path", () => { + win.send("wrong-path"); }); -// Ensures ./ is the config folder where viper.json is located. +// ensures PWD/CWD is the config folder where viper.json is located process.chdir(app.getPath("appData")); -// Starts the GUI or CLI +// starts the GUI or CLI if (cli.hasArgs()) { if (cli.hasParam("updatevp")) { utils.updatevp(true); @@ -207,11 +235,11 @@ if (cli.hasArgs()) { }) } -// Returns cached requests +// returns cached requests ipcMain.on("get-ns-notes", async () => { - win.webContents.send("ns-notes", await requests.getNsReleaseNotes()); + win.send("ns-notes", await requests.getNsReleaseNotes()); }); ipcMain.on("get-vp-notes", async () => { - win.webContents.send("vp-notes", await requests.getVpReleaseNotes()); + win.send("vp-notes", await requests.getVpReleaseNotes()); }); diff --git a/src/lang/en.json b/src/lang/en.json index 2c068ac..8cece10 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -91,6 +91,7 @@ "gui.settings.title.ns": "Northstar", "gui.settings.title.language": "Language", "gui.settings.title.updates": "Updates", + "gui.settings.title.misc": "Miscellaneous", "gui.settings.nsargs.title": "Launch options", "gui.settings.nsargs.desc": "Here you can add launch options for Northstar/Titanfall.", "gui.settings.autolang.title": "Auto-Detect Language", @@ -103,6 +104,8 @@ "gui.settings.nsupdate.desc": "Viper will automatically keep Northstar up-to-date, however it can still manually be updated through the Northstar page.", "gui.settings.excludes.title": "Retain files on update", "gui.settings.excludes.desc": "When Northstar is updated, files specified here will not be overwritten by files from the new Northstar update, unless you know what you're changing, you should probably not change anything here. Each file is separated with a space.", + "gui.settings.originkill.title": "Automatically quit Origin", + "gui.settings.originkill.desc": "When Viper exits, automatically quit Origin as well.", "gui.update.downloading": "Downloading...", "gui.update.extracting": "Extracting update...", @@ -113,6 +116,11 @@ "gui.nsupdate.gaming.title": "Northstar update available!", "gui.nsupdate.gaming.body": "An update for Northstar is available.\nYou can force its installation after closing the game.", + "gui.server.player": "player", + "gui.server.players": "players", + "gui.server.servers": "servers", + "gui.server.offline": "Masterserver is Offline", + "gui.launch": "Launch", "gui.launchvanilla": "Vanilla", "gui.launchnorthstar": "Northstar", diff --git a/src/lang/es.json b/src/lang/es.json index 8128440..c341143 100644 --- a/src/lang/es.json +++ b/src/lang/es.json @@ -90,6 +90,7 @@ "gui.settings.discard": "Descartar", "gui.settings.title.ns": "Northstar", "gui.settings.title.updates": "Actualizaciones", + "gui.settings.title.misc": "Misceláneos", "gui.settings.nsargs.title": "Opciones de lanzamiento", "gui.settings.nsargs.desc": "Aqui puedes añadir opciones de lanzamiento para Northstar/Titanfall.", "gui.settings.autoupdate.title": "Actualizaciones automáticas de Viper", @@ -98,6 +99,8 @@ "gui.settings.nsupdate.desc": "Viper mantendrá Northstar actualizado automáticamente, sin embargo, todavía se puede actualizar manualmente a través de la sección de Northstar.", "gui.settings.excludes.title": "Conservar archivos en la actualización", "gui.settings.excludes.desc": "Cuando se actualice Northstar, los archivos especificados aquí no se sobrescribirán con archivos de la nueva actualización de Northstar. A menos que sepa lo que está cambiando, probablemente no debería cambiar nada aquí. Cada archivo se debe separar con un espacio.", + "gui.settings.originkill.title": "Cerrar Origin automáticamente", + "gui.settings.originkill.desc": "Cuando Viper se cierra, cerrar automáticamente Origin también.", "gui.settings.title.language": "Idioma", "gui.settings.autolang.title": "Detectar automáticamente el idioma", "gui.settings.autolang.desc": "Cuando está habilitado, Viper intenta detectar automáticamente el idioma de su sistema, cuando está deshabilitado, puede cambiar manualmente el idioma a continuación.", @@ -130,6 +133,11 @@ "gui.toast.desc.malformed": "tiene una estructura de carpetas incorrecta, si usted es el desarrollador, debe corregir esto.", "gui.toast.desc.failed": "Se produjo un error desconocido al intentar instalar la modificación. Esto puede ser culpa del autor de la modificación, y también puede ser culpa de Viper.", + "gui.server.player": "jugador", + "gui.server.players": "jugadores", + "gui.server.servers": "servidores", + "gui.server.offline": "El servidor Master está desconectado", + "viper.menu.main": "Viper", "viper.menu.release": "Notas de la versión", "viper.menu.info": "Extras", diff --git a/src/lang/fr.json b/src/lang/fr.json index 1f37948..1fde982 100644 --- a/src/lang/fr.json +++ b/src/lang/fr.json @@ -91,6 +91,7 @@ "gui.settings.title.ns": "Northstar", "gui.settings.title.language": "Langue", "gui.settings.title.updates": "Mises à jour", + "gui.settings.title.misc": "Divers", "gui.settings.nsargs.title": "Options de lancement", "gui.settings.nsargs.desc": "Vous pouvez ajouter ici des options de démarrage pour Northstar/Titanfall.", "gui.settings.autolang.title": "Auto-détection de la langue", @@ -103,6 +104,8 @@ "gui.settings.nsupdate.desc": "Viper tient automatiquement Northstar à jour (n'empêche pas de le mettre à jour manuellement via sa page dédiée).", "gui.settings.excludes.title": "Fichiers à conserver", "gui.settings.excludes.desc": "Lorsque Northstar est mis à jour, ces fichiers ne seront pas écrasés par ceux provenant de la mise à jour; les noms de fichiers sont séparés par un espace.", + "gui.settings.originkill.title": "Quitter automatiquement Origin", + "gui.settings.originkill.desc": "Lorsque Viper est fermé, Origin sera également automatiquement fermé.", "gui.update.downloading": "Téléchargement de la mise à jour...", "gui.update.extracting": "Extraction des fichiers...", @@ -113,6 +116,11 @@ "gui.nsupdate.gaming.title": "Mise à jour Northstar disponible !", "gui.nsupdate.gaming.body": "Une mise à jour pour Northstar est disponible.\nVous pourrez l'installer après avoir fermé le jeu.", + "gui.server.player": "joueur", + "gui.server.players": "joueurs", + "gui.server.servers": "serveurs", + "gui.server.offline": "Le serveur maître est hors-ligne", + "gui.launch": "Jouer", "gui.launchvanilla": "Vanilla", "gui.launchnorthstar": "Northstar", diff --git a/src/utils.js b/src/utils.js index a47bff1..b6622d9 100644 --- a/src/utils.js +++ b/src/utils.js @@ -29,6 +29,7 @@ var settings = { autolang: true, forcedlang: "en", autoupdate: true, + originkill: false, nsargs: "-multiple", zip: "/northstar.zip", @@ -42,12 +43,12 @@ var settings = { // Logs into the dev tools of the renderer function winLog(msg) { - ipcMain.emit("winLog", msg, msg); + ipcMain.emit("win-log", msg, msg); } // Sends an alert to the renderer function winAlert(msg) { - ipcMain.emit("winAlert", msg, msg); + ipcMain.emit("win-alert", msg, msg); } // Creates the settings file with the base settings if it doesn't exist. @@ -101,6 +102,47 @@ async function isGameRunning() { }); } +// checks if any origin processes are running +async function isOriginRunning() { + return new Promise(resolve => { + let procs = ["Origin.exe", "OriginClientService.exe"]; + let cmd = (() => { + switch (process.platform) { + case "linux": return "ps -A"; + case "win32": return "tasklist"; + } + })(); + + exec(cmd, (err, stdout) => { + procs.forEach(proc => { + if (stdout.includes(proc)) { + resolve(true); + return; + } + resolve(false); + }); + }); + }); +} + +// kill origin processes +async function killOrigin() { + return new Promise(resolve => { + let proc = "Origin.exe"; //I'm pretty sure we only have to kill this one + let cmd = (() => { + switch (process.platform) { + case "linux": return "killall " + 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); + }); + }); +} + // Handles auto updating Northstar. // // It uses isGameRunning() to ensure it doesn't run while the game is @@ -121,7 +163,7 @@ function handleNorthstarUpdating() { if (await isGameRunning()) { console.log(lang("cli.autoupdates.gamerunning")); new Notification({ - title: lang("gui.nsupdate.gaming.title"), + title: lang("gui.nsupdate.gaming.title"), body: lang("gui.nsupdate.gaming.body") }).show(); } else { @@ -129,11 +171,11 @@ function handleNorthstarUpdating() { update(); } } else { - console.log(lang("cli.autoupdates.noupdate")) + console.log(lang("cli.autoupdates.noupdate")); } setTimeout( - _checkForUpdates, + _checkForUpdates, 15 * 60 * 1000 // interval in between each update check // by default 15 minutes. @@ -187,11 +229,11 @@ async function setpath(win, forcedialog) { return; } if (! fs.existsSync(path.join(res.filePaths[0], "Titanfall2.exe"))) { - ipcMain.emit("wrongpath"); + ipcMain.emit("wrong-path"); return; } - setGamepath(res.filePaths[0]) + setGamepath(res.filePaths[0]); cli.exit(); return; @@ -294,7 +336,7 @@ function restoreExcludedFiles() { for (let i = 0; i < settings.excludes.length; i++) { let exclude = path.join(settings.gamepath + "/" + settings.excludes[i]); if (fs.existsSync(exclude + ".excluded")) { - fs.renameSync(exclude + ".excluded", exclude) + fs.renameSync(exclude + ".excluded", exclude); } } } @@ -331,7 +373,7 @@ async function update() { } else { if (version != "unknown") { console.log(lang("cli.update.current"), version); - }; + }; console.log(lang("cli.update.downloading") + ":", latestAvailableVersion); ipcMain.emit("ns-update-event", "cli.update.downloading"); } @@ -340,7 +382,7 @@ async function update() { for (let i = 0; i < settings.excludes.length; i++) { let exclude = path.join(settings.gamepath + "/" + settings.excludes[i]); if (fs.existsSync(exclude)) { - fs.renameSync(exclude, exclude + ".excluded") + fs.renameSync(exclude, exclude + ".excluded"); } } @@ -370,7 +412,7 @@ async function update() { restoreExcludedFiles(); - ipcMain.emit("guigetmods"); + ipcMain.emit("gui-getmods"); ipcMain.emit("ns-update-event", "cli.update.uptodate.short"); winLog(lang("gui.update.finished")); console.log(lang("cli.update.finished")); @@ -420,19 +462,21 @@ function updatevp(autoinstall) { // however it'll be added at some point. function launch(version) { if (process.platform == "linux") { - console.error("error:", lang("cli.launch.linuxerror")) + winAlert(lang("cli.launch.linuxerror")); + console.error("error:", lang("cli.launch.linuxerror")); cli.exit(1); + return; } process.chdir(settings.gamepath); switch(version) { case "vanilla": - console.log(lang("general.launching"), "Vanilla...") - run(path.join(settings.gamepath + "/Titanfall2.exe")) + console.log(lang("general.launching"), "Vanilla..."); + run(path.join(settings.gamepath + "/Titanfall2.exe")); break; default: - console.log(lang("general.launching"), "Northstar...") - run(path.join(settings.gamepath + "/NorthstarLauncher.exe")) + console.log(lang("general.launching"), "Northstar..."); + run(path.join(settings.gamepath + "/NorthstarLauncher.exe")); break; } } @@ -458,8 +502,8 @@ const mods = { let modpath = path.join(settings.gamepath, "R2Northstar/mods"); if (getNSVersion() == "unknown") { - winLog(lang("general.notinstalled")) - console.log("error: " + lang("general.notinstalled")) + winLog(lang("general.notinstalled")); + console.log("error: " + lang("general.notinstalled")); cli.exit(1); return false; } @@ -468,7 +512,7 @@ const mods = { let disabled = []; if (! fs.existsSync(modpath)) { - fs.mkdirSync(path.join(modpath), {recursive: true}) + fs.mkdirSync(path.join(modpath), {recursive: true}); return { enabled: [], disabled: [], @@ -476,7 +520,7 @@ const mods = { }; } - files = fs.readdirSync(modpath) + files = fs.readdirSync(modpath); files.forEach((file) => { if (fs.statSync(path.join(modpath, file)).isDirectory()) { let modjson = path.join(modpath, file, "mod.json"); @@ -527,8 +571,8 @@ const mods = { let modpath = path.join(settings.gamepath, "R2Northstar/mods"); if (getNSVersion() == "unknown") { - winLog(lang("general.notinstalled")) - console.log("error: " + lang("general.notinstalled")) + winLog(lang("general.notinstalled")); + console.log("error: " + lang("general.notinstalled")); cli.exit(1); return false; } @@ -553,11 +597,11 @@ const mods = { let file = path.join(modpath, "..", "enabledmods.json"); if (! fs.existsSync(modpath)) { - fs.mkdirSync(path.join(modpath), {recursive: true}) + fs.mkdirSync(path.join(modpath), {recursive: true}); } if (! fs.existsSync(file)) { - fs.writeFileSync(file, "{}") + fs.writeFileSync(file, "{}"); } return { @@ -568,7 +612,7 @@ const mods = { names[list[i].Name] = true } - fs.writeFileSync(file, JSON.stringify(names)) + fs.writeFileSync(file, JSON.stringify(names)); }, disable: (mod) => { let data = JSON.parse(repair(fs.readFileSync(file, "utf8"))); @@ -614,15 +658,15 @@ const mods = { let modname = mod.replace(/^.*(\\|\/|\:)/, ""); if (getNSVersion() == "unknown") { - winLog(lang("general.notinstalled")) - console.log("error: " + lang("general.notinstalled")) + 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")) + winLog(lang("gui.mods.notamod")); + console.log("error: " + lang("cli.mods.notamod")); cli.exit(1); return false; } @@ -631,30 +675,30 @@ const mods = { console.log(lang("cli.mods.installed")); cli.exit(); - winLog(lang("gui.mods.installedmod")) + winLog(lang("gui.mods.installedmod")); if (modname == "mods") { - let manifest = path.join(app.getPath("userData"), "Archives/manifest.json") + let manifest = path.join(app.getPath("userData"), "Archives/manifest.json"); if (fs.existsSync(manifest)) { modname = require(manifest).name; } } - ipcMain.emit("installedmod", "", { + ipcMain.emit("installed-mod", "", { name: modname, malformed: malformed, }); - ipcMain.emit("guigetmods"); + ipcMain.emit("gui-getmods"); return true; } if (! fs.existsSync(mod)) {return notamod()} if (fs.statSync(mod).isDirectory()) { - winLog(lang("gui.mods.installing")) + winLog(lang("gui.mods.installing")); files = fs.readdirSync(mod); - if (fs.existsSync(path.join(mod, "mod.json")) && + if (fs.existsSync(path.join(mod, "mod.json")) && fs.statSync(path.join(mod, "mod.json")).isFile()) { if (fs.existsSync(path.join(modpath, modname))) { @@ -662,8 +706,8 @@ const mods = { } let copydest = path.join(modpath, modname); if (typeof destname == "string") {copydest = path.join(modpath, destname)} - copy(mod, copydest) - copy(manifestfile, path.join(copydest, "manifest.json")) + copy(mod, copydest); + copy(manifestfile, path.join(copydest, "manifest.json")); return installed(); } else { @@ -674,7 +718,7 @@ const mods = { if (fs.existsSync(path.join(mod, files[i], "mod.json")) && fs.statSync(path.join(mod, files[i], "mod.json")).isFile()) { - mods.install(path.join(mod, files[i])) + mods.install(path.join(mod, files[i])); if (mods.install(path.join(mod, files[i]))) {return true}; } } @@ -685,7 +729,7 @@ const mods = { return notamod(); } else { - winLog(lang("gui.mods.extracting")) + winLog(lang("gui.mods.extracting")); let cache = path.join(app.getPath("userData"), "Archives"); if (fs.existsSync(cache)) { fs.rmSync(cache, {recursive: true}); @@ -717,7 +761,7 @@ const mods = { } if (files.length == 0) { - ipcMain.emit("failedmod"); + ipcMain.emit("failed-mod"); return notamod(); } } @@ -748,12 +792,12 @@ const mods = { if (fs.existsSync(tmp)) { if (! fs.statSync(tmp).isDirectory()) { - fs.rmSync(tmp) + fs.rmSync(tmp); } } else { - fs.mkdirSync(tmp) + fs.mkdirSync(tmp); if (fs.existsSync(modlocation)) { - fs.rmSync(modlocation) + fs.rmSync(modlocation); } } @@ -775,8 +819,8 @@ const mods = { let modpath = path.join(settings.gamepath, "R2Northstar/mods"); if (getNSVersion() == "unknown") { - winLog(lang("general.notinstalled")) - console.log("error: " + lang("general.notinstalled")) + winLog(lang("general.notinstalled")); + console.log("error: " + lang("general.notinstalled")); cli.exit(1); return false; } @@ -784,19 +828,19 @@ const mods = { if (mod == "allmods") { let modlist = mods.list().all; for (let i = 0; i < modlist.length; i++) { - mods.remove(modlist[i].Name) + mods.remove(modlist[i].Name); } return } let disabled = path.join(modpath, "disabled"); if (! fs.existsSync(disabled)) { - fs.mkdirSync(disabled) + fs.mkdirSync(disabled); } let modName = mods.get(mod).FolderName; if (! modName) { - console.log("error: " + lang("cli.mods.cantfind")) + console.log("error: " + lang("cli.mods.cantfind")); cli.exit(1); return; } @@ -816,8 +860,8 @@ const mods = { fs.rmSync(modPath, {recursive: true}); console.log(lang("cli.mods.removed")); cli.exit(); - ipcMain.emit("guigetmods"); - ipcMain.emit("removedmod", "", { + ipcMain.emit("gui-getmods"); + ipcMain.emit("removed-mod", "", { name: mod.replace(/^.*(\\|\/|\:)/, ""), manifestname: manifestname }); @@ -834,8 +878,8 @@ const mods = { // 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")) + winLog(lang("general.notinstalled")); + console.log("error: " + lang("general.notinstalled")); cli.exit(1); return false; } @@ -843,7 +887,7 @@ const mods = { if (mod == "allmods") { let modlist = mods.list().all; for (let i = 0; i < modlist.length; i++) { - mods.toggle(modlist[i].Name, true) + mods.toggle(modlist[i].Name, true); } console.log(lang("cli.mods.toggledall")); @@ -856,17 +900,17 @@ const mods = { console.log(lang("cli.mods.toggled")); cli.exit(); } - ipcMain.emit("guigetmods"); + ipcMain.emit("gui-getmods"); } }; setInterval(() => { if (gamepathExists()) { - ipcMain.emit("guigetmods"); + ipcMain.emit("gui-getmods"); } else { if (fs.existsSync("viper.json")) { if (settings.gamepath != "") { - ipcMain.emit("gamepathlost"); + ipcMain.emit("gamepath-lost"); } } } @@ -874,19 +918,27 @@ setInterval(() => { module.exports = { mods, - lang, winLog, - launch, + update, - setpath, updatevp, - settings, - saveSettings, getNSVersion, getTF2Version, + handleNorthstarUpdating, + + launch, + killOrigin, isGameRunning, + isOriginRunning, + + + settings, + saveSettings, + + setpath, gamepathExists, - handleNorthstarUpdating, + + lang, setlang: (lang) => { settings.lang = lang; saveSettings(); |