diff options
author | 0neGal <mail@0negal.com> | 2022-01-26 00:23:30 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-26 00:23:30 +0100 |
commit | 66204f6f58dc90e1e9ee40c7ea691927d0c50b8d (patch) | |
tree | afb0172e5d4a6c4b9e4644513e012fde9efe65f5 | |
parent | 353db2c99fd26c3c925247b61b30619020a12b5a (diff) | |
parent | 6a08872d134f3afa3f81b92fabe51bdbd91f375d (diff) | |
download | Viper-66204f6f58dc90e1e9ee40c7ea691927d0c50b8d.tar.gz Viper-66204f6f58dc90e1e9ee40c7ea691927d0c50b8d.zip |
Merge pull request #53 from 0neGal/detect-gamepath
Detect gamepath automatically
-rw-r--r-- | package-lock.json | 11 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | src/app/main.js | 5 | ||||
-rw-r--r-- | src/extras/findgame.js | 67 | ||||
-rw-r--r-- | src/extras/requests.js (renamed from src/requests.js) | 0 | ||||
-rw-r--r-- | src/index.js | 12 | ||||
-rw-r--r-- | src/lang/en.json | 4 | ||||
-rw-r--r-- | src/lang/fr.json | 4 | ||||
-rw-r--r-- | src/utils.js | 57 |
9 files changed, 139 insertions, 22 deletions
diff --git a/package-lock.json b/package-lock.json index bfdbd43..2a396b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "fs-extra": "^10.0.0", "marked": "^4.0.10", "marked-man": "^0.7.0", + "simple-vdf": "^1.1.1", "unzipper": "^0.10.11" }, "devDependencies": { @@ -2671,6 +2672,11 @@ "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", "dev": true }, + "node_modules/simple-vdf": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/simple-vdf/-/simple-vdf-1.1.1.tgz", + "integrity": "sha1-B+LE3sBs9hTtb0IRsYzOEjyT/Kk=" + }, "node_modules/slice-ansi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", @@ -5271,6 +5277,11 @@ "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", "dev": true }, + "simple-vdf": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/simple-vdf/-/simple-vdf-1.1.1.tgz", + "integrity": "sha1-B+LE3sBs9hTtb0IRsYzOEjyT/Kk=" + }, "slice-ansi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", diff --git a/package.json b/package.json index 4e9fe07..eb772d7 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "fs-extra": "^10.0.0", "marked": "^4.0.10", "marked-man": "^0.7.0", + "simple-vdf": "^1.1.1", "unzipper": "^0.10.11" }, "devDependencies": { diff --git a/src/app/main.js b/src/app/main.js index 5f0cc9a..19f6c9e 100644 --- a/src/app/main.js +++ b/src/app/main.js @@ -26,13 +26,11 @@ if (fs.existsSync("viper.json")) { settings.zip = path.join(settings.gamepath + "/northstar.zip"); if (settings.gamepath.length === 0) { - alert(lang("general.missingpath")); setpath(false); } else { setpath(true); } } else { - alert(lang("general.missingpath")); setpath(); } @@ -156,6 +154,7 @@ function installmod() { // Frontend part of settings a new game path ipcRenderer.on("newpath", (event, newpath) => { settings.gamepath = newpath; + ipcRenderer.send("guigetmods"); }) // Continuation of log() @@ -164,6 +163,8 @@ ipcRenderer.on("alert", (event, msg) => {alert(msg)}) // Updates the installed mods ipcRenderer.on("mods", (event, mods) => { + if (! mods) {return} + modcount.innerHTML = `${lang("gui.mods.count")} ${mods.all.length}`; modsdiv.innerHTML = ""; diff --git a/src/extras/findgame.js b/src/extras/findgame.js new file mode 100644 index 0000000..42c9b85 --- /dev/null +++ b/src/extras/findgame.js @@ -0,0 +1,67 @@ +const fs = require("fs"); +const path = require("path"); +const vdf = require("simple-vdf"); +const { app } = require("electron"); + +const util = require("util"); +const exec = util.promisify(require("child_process").exec); + +module.exports = async () => { + let gamepath = ""; + + // Autodetect path + // Windows only using powershell and windows registery + // Get-Item -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Respawn\Titanfall2\ + if (process.platform == "win32") { + try { + const {stdout} = await exec("Get-ItemProperty -Path Registry::HKEY_LOCAL_MACHINE\\SOFTWARE\\Respawn\\Titanfall2\\ -Name \"Install Dir\"", {"shell":"powershell.exe"}); + + const gamepath = stdout.split('\n') + .filter(r => r.indexOf("Install Dir") !== -1)[0] + .replace(/\s+/g,' ') + .trim() + .replace("Install Dir : ",""); + + if (gamepath) {return gamepath} + } catch (err) {} + } + + // Detect using Steam VDF + function readvdf(data) { + // Parse read_data + data = vdf.parse(data); + + // `.length - 1` This is because the last value is `contentstatsid` + for (let pathIterator = 0; pathIterator < Object.values(data["libraryfolders"]).length - 1; pathIterator++) { + let data_array = Object.values(data["libraryfolders"][pathIterator]) + + if (fs.existsSync(data_array[0] + "/steamapps/common/Titanfall2/Titanfall2.exe")) { + return data_array[0] + "/steamapps/common/Titanfall2"; + } + } + } + + let folder = null; + switch (process.platform) { + case "win32": + folder = "C:\\Program Files (x86)\\Steam\\steamapps\\libraryfolders.vdf"; + break + case "linux": + case "openbsd": + case "freebsd": + folder = path.join(app.getPath("home"), "/.steam/steam/steamapps/libraryfolders.vdf"); + break + } + + if (fs.existsSync(folder) && folder) { + let data = fs.readFileSync(folder) + let read_vdf = readvdf(data.toString()) + if (read_vdf ) {return read_vdf} + } + + if (gamepath) { + return gamepath; + } else { + return false; + } +} diff --git a/src/requests.js b/src/extras/requests.js index 16b1330..16b1330 100644 --- a/src/requests.js +++ b/src/extras/requests.js diff --git a/src/index.js b/src/index.js index 3f50840..c8bfc53 100644 --- a/src/index.js +++ b/src/index.js @@ -8,7 +8,7 @@ const events = new Emitter(); const utils = require("./utils"); const cli = require("./cli"); -const requests = require("./requests"); +const requests = require("./extras/requests"); // Starts the actual BrowserWindow, which is only run when using the // GUI, for the CLI this function is never called. @@ -87,9 +87,13 @@ ipcMain.on("launchVanilla", (event) => {utils.launch("vanilla")}) ipcMain.on("update", (event) => {utils.update()}) ipcMain.on("setpathcli", (event) => {utils.setpath()}); ipcMain.on("setpath", (event, value) => { - if (!value) { - utils.setpath(win); - } else if (!win.isVisible()) { + if (! value) { + if (! win.isVisible()) { + utils.setpath(win); + } else { + utils.setpath(win, true); + } + } else if (! win.isVisible()) { win.show(); } }); diff --git a/src/lang/en.json b/src/lang/en.json index c2b6f98..fe9b0b0 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -42,7 +42,7 @@ "gui.versions.northstar": "Northstar version", "gui.exit": "Exit", "gui.update": "Update", - "gui.setpath": "Game Path", + "gui.setpath": "Change Game Path", "gui.update.check": "Check for updates", "gui.mods": "Mods", @@ -96,7 +96,7 @@ "general.mods.enabled": "Enabled mods:", "general.mods.disabled": "Disabled mods:", "general.mods.installed": "Installed mods:", - "general.missingpath": "Game path is not set!", + "general.missingpath": "Game location could not be found automatically! Please select it manually!", "general.notinstalled": "Northstar is not installed!", "general.launching": "Launching" } diff --git a/src/lang/fr.json b/src/lang/fr.json index 59a3090..2fbc89a 100644 --- a/src/lang/fr.json +++ b/src/lang/fr.json @@ -42,7 +42,7 @@ "gui.versions.northstar": "Version de Northstar", "gui.exit": "Fermer", "gui.update": "Mise à jour", - "gui.setpath": "Chemin du jeu", + "gui.setpath": "Mettre à jour le chemin du jeu", "gui.update.check": "Vérifier les mises à jour", "gui.mods": "Mods", @@ -96,7 +96,7 @@ "general.mods.enabled": "Mods activés :", "general.mods.disabled": "Mods désactivés :", "general.mods.installed": "Mods installés :", - "general.missingpath": "Le chemin du client n'est pas défini !", + "general.missingpath": "Le chemin du client n'a pu être trouvé automatiquement, merci de le sélectionner manuellement.", "general.notinstalled": "Northstar n'est pas installé !", "general.launching": "Lancement" } diff --git a/src/utils.js b/src/utils.js index 50ffed0..0507921 100644 --- a/src/utils.js +++ b/src/utils.js @@ -8,7 +8,8 @@ const events = new Emitter(); const cli = require("./cli"); const lang = require("./lang"); -const requests = require("./requests"); +const requests = require("./extras/requests"); +const findgame = require("./extras/findgame"); const unzip = require("unzipper"); const run = require("child_process").spawn; @@ -115,10 +116,37 @@ northstar_auto_updates: { // // If running with CLI it takes in the --setpath argument otherwise it // open the systems file browser for the user to select a path. -function setpath(win) { +async function setpath(win, forcedialog) { + function setGamepath(folder) { + settings.gamepath = folder; + settings.zip = path.join(settings.gamepath + "/northstar.zip"); + saveSettings(); + win.webContents.send("newpath", settings.gamepath); + ipcMain.emit("newpath", null, settings.gamepath); + } + if (! win) { // CLI - settings.gamepath = cli.param("setpath"); + setGamepath(cli.param("setpath")); } else { // GUI + if (! forcedialog) { + function setGamepath(folder, forcedialog) { + settings.gamepath = folder; + settings.zip = path.join(settings.gamepath + "/northstar.zip"); + saveSettings(); + win.webContents.send("newpath", settings.gamepath); + ipcMain.emit("newpath", null, settings.gamepath); + } + + let gamepath = await findgame(); + if (gamepath) { + setGamepath(gamepath); + return; + } + + winAlert(lang("general.missingpath")); + } + + // Fallback to manual selection dialog.showOpenDialog({properties: ["openDirectory"]}).then(res => { if (res.canceled) { ipcMain.emit("newpath", null, false); @@ -129,16 +157,12 @@ function setpath(win) { return; } - settings.gamepath = res.filePaths[0]; - settings.zip = path.join(settings.gamepath + "/northstar.zip"); - saveSettings(); - win.webContents.send("newpath", settings.gamepath); - ipcMain.emit("newpath", null, settings.gamepath); + setGamepath(res.filePaths[0]) + + cli.exit(); + return; }).catch(err => {console.error(err)}) } - - saveSettings(); - cli.exit(); } // As to not have to do the same one liner a million times, this @@ -315,7 +339,6 @@ function winAlert(msg) { // // We can both get list of disabled mods, remove/install/toggle mods and // other things akin to that, all kinds of mod related stuff -let modpath = path.join(settings.gamepath, "R2Northstar/mods"); const mods = { // Returns a list of mods // @@ -323,6 +346,8 @@ const mods = { // combination of the other two, enabled being enabled mods, and you // guessed it, disabled being disabled mods. list: () => { + let modpath = path.join(settings.gamepath, "R2Northstar/mods"); + if (getNSVersion() == "unknown") { winLog(lang("general.notinstalled")) console.log("error: " + lang("general.notinstalled")) @@ -389,6 +414,8 @@ const mods = { // the absolute basics will be provided and we can't know the // version or similar. get: (mod) => { + let modpath = path.join(settings.gamepath, "R2Northstar/mods"); + if (getNSVersion() == "unknown") { winLog(lang("general.notinstalled")) console.log("error: " + lang("general.notinstalled")) @@ -413,6 +440,8 @@ const mods = { // inside the zip or folder to see if buried in another folder or // not, as sometimes that's the case. install: (mod) => { + let modpath = path.join(settings.gamepath, "R2Northstar/mods"); + if (getNSVersion() == "unknown") { winLog(lang("general.notinstalled")) console.log("error: " + lang("general.notinstalled")) @@ -491,6 +520,8 @@ const mods = { // Takes in the names of the mod then removes it, no confirmation, // that'd be up to the GUI. remove: (mod) => { + let modpath = path.join(settings.gamepath, "R2Northstar/mods"); + if (getNSVersion() == "unknown") { winLog(lang("general.notinstalled")) console.log("error: " + lang("general.notinstalled")) @@ -541,6 +572,8 @@ const mods = { // you checked for if a mod is already disable and if not run the // function. However we currently have no need for that. toggle: (mod, fork) => { + let modpath = path.join(settings.gamepath, "R2Northstar/mods"); + if (getNSVersion() == "unknown") { winLog(lang("general.notinstalled")) console.log("error: " + lang("general.notinstalled")) |