aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author0neGal <mail@0negal.com>2022-01-26 00:23:30 +0100
committerGitHub <noreply@github.com>2022-01-26 00:23:30 +0100
commit66204f6f58dc90e1e9ee40c7ea691927d0c50b8d (patch)
treeafb0172e5d4a6c4b9e4644513e012fde9efe65f5
parent353db2c99fd26c3c925247b61b30619020a12b5a (diff)
parent6a08872d134f3afa3f81b92fabe51bdbd91f375d (diff)
downloadViper-66204f6f58dc90e1e9ee40c7ea691927d0c50b8d.tar.gz
Viper-66204f6f58dc90e1e9ee40c7ea691927d0c50b8d.zip
Merge pull request #53 from 0neGal/detect-gamepath
Detect gamepath automatically
-rw-r--r--package-lock.json11
-rw-r--r--package.json1
-rw-r--r--src/app/main.js5
-rw-r--r--src/extras/findgame.js67
-rw-r--r--src/extras/requests.js (renamed from src/requests.js)0
-rw-r--r--src/index.js12
-rw-r--r--src/lang/en.json4
-rw-r--r--src/lang/fr.json4
-rw-r--r--src/utils.js57
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"))