aboutsummaryrefslogtreecommitdiff
path: root/src/utils.js
diff options
context:
space:
mode:
author0neGal <mail@0negal.com>2022-01-19 23:51:26 +0100
committerGitHub <noreply@github.com>2022-01-19 23:51:26 +0100
commit057b60f4843798441ad441370381b87299d5ad7f (patch)
treeef0ac85051f0abb8b0febfc507ad5c71a5e7e3e8 /src/utils.js
parent962265ffbe3aa0a9c2084d370c914c0265ee6bd9 (diff)
parentae7de46f4748c800097f0f3c700e6525d7d7cc4f (diff)
downloadViper-057b60f4843798441ad441370381b87299d5ad7f.tar.gz
Viper-057b60f4843798441ad441370381b87299d5ad7f.zip
Merge branch 'main' into enabledmods
Diffstat (limited to 'src/utils.js')
-rw-r--r--src/utils.js109
1 files changed, 100 insertions, 9 deletions
diff --git a/src/utils.js b/src/utils.js
index bdfa7f3..a41def4 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -17,17 +17,22 @@ const { https } = require("follow-redirects");
process.chdir(app.getPath("appData"));
+// Base settings
var settings = {
gamepath: "",
lang: "en-US",
autoupdate: true,
zip: "/northstar.zip",
+
+ // These files won't be overwritten when installing/updating
+ // Northstar, useful for config file.
excludes: [
"ns_startup_args.txt",
"ns_startup_args_dedi.txt"
]
}
+// Creates the settings file with the base settings if it doesn't exist.
if (fs.existsSync("viper.json")) {
settings = {...settings, ...JSON.parse(fs.readFileSync("viper.json", "utf8"))};
settings.zip = path.join(settings.gamepath + "/northstar.zip");
@@ -35,10 +40,14 @@ if (fs.existsSync("viper.json")) {
console.log(lang("general.missingpath"));
}
-
+// A simple function that checks if the game is running, which we use to
+// not update Northstar when it is running.
async function isGameRunning() {
return new Promise(resolve => {
let procs = ["Titanfall2.exe", "Titanfall2-unpacked.exe", "NorthstarLauncher.exe"];
+ // While we could use a Node module to do this instead, I
+ // decided not to do so. As this achieves exactly the same
+ // thing. And it's not much more clunky.
let cmd = (() => {
switch (process.platform) {
case "linux": return "ps -A";
@@ -59,6 +68,10 @@ async function isGameRunning() {
});
}
+// Handles auto updating Northstar.
+//
+// It uses isGameRunning() to ensure it doesn't run while the game is
+// running, as that may have all kinds of issues.
northstar_auto_updates: {
if (!settings.autoupdate || !fs.existsSync("viper.json") || settings.gamepath.length === 0) {
break northstar_auto_updates;
@@ -69,6 +82,7 @@ northstar_auto_updates: {
let distantVersion = await requests.getLatestNsVersion();
console.log(lang("cli.autoupdates.checking"));
+ // Checks if NS is outdated
if (localVersion !== distantVersion) {
console.log(lang("cli.autoupdates.available"));
if (await isGameRunning()) {
@@ -87,7 +101,9 @@ northstar_auto_updates: {
setTimeout(
_checkForUpdates,
- 15 * 60 * 1000 // update checking interval must be bigger than cache validity duration
+ 15 * 60 * 1000
+ // interval in between each update check
+ // by default 15 minutes.
);
}
@@ -95,10 +111,14 @@ northstar_auto_updates: {
}
+// Requests to set the game path
+//
+// 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) {
- if (! win) {
+ if (! win) { // CLI
settings.gamepath = cli.param("setpath");
- } else {
+ } else { // GUI
dialog.showOpenDialog({properties: ["openDirectory"]}).then(res => {
if (res.canceled) {
ipcMain.emit("newpath", null, false);
@@ -121,10 +141,15 @@ function setpath(win) {
cli.exit();
}
+// As to not have to do the same one liner a million times, this
+// function exists, as the name suggests, it simply writes the current
+// settings to the disk.
function saveSettings() {
fs.writeFileSync(app.getPath("appData") + "/viper.json", JSON.stringify(settings));
}
+// Returns the current Northstar version
+// If not installed it'll return "unknown"
function getNSVersion() {
var versionFilePath = path.join(settings.gamepath, "ns_version.txt");
@@ -137,11 +162,11 @@ function getNSVersion() {
}
-/**
- * Loads up Titanfall|2 version from gameversion.txt file.
- * TODO This file is present on Origin install, should check if it's present with
- * Steam install as well.
- */
+// Returns the Titanfall 2 version from gameversion.txt file.
+// If it fails it simply returns "unknown"
+//
+// TODO: This file is present on Origin install, should check if it's
+// present with Steam install as well.
function getTF2Version() {
var versionFilePath = path.join(settings.gamepath, "gameversion.txt");
if (fs.existsSync(versionFilePath)) {
@@ -151,7 +176,17 @@ function getTF2Version() {
}
}
+// Installs/Updates Northstar
+//
+// If Northstar is already installed it'll be an update, otherwise it'll
+// install it. It simply downloads the Northstar archive from GitHub, if
+// it's outdated, then extracts it into the game path.
+//
+// As to handle not overwriting files we rename certain files to
+// <file>.excluded, then rename them back after the extraction. The
+// unzip module does not support excluding files directly.
async function update() {
+ // Renames excluded files to <file>.excluded
for (let i = 0; i < settings.excludes.length; i++) {
let exclude = path.join(settings.gamepath + "/" + settings.excludes[i]);
if (fs.existsSync(exclude)) {
@@ -165,6 +200,7 @@ async function update() {
const latestAvailableVersion = await requests.getLatestNsVersion();
+ // Makes sure it is not already the latest version
if (version === latestAvailableVersion) {
ipcMain.emit("ns-update-event", "cli.update.uptodate.short");
console.log(lang("cli.update.uptodate"), version);
@@ -179,11 +215,14 @@ async function update() {
ipcMain.emit("ns-update-event", "cli.update.downloading");
}
+ // Start the download of the zip
https.get(requests.getLatestNsVersionLink(), (res) => {
let stream = fs.createWriteStream(settings.zip);
res.pipe(stream);
let received = 0;
+ // Progress messages, we should probably switch this to
+ // percentage instead of how much is downloaded.
res.on("data", (chunk) => {
received += chunk.length;
ipcMain.emit("ns-update-event", lang("gui.update.downloading") + " " + (received / 1024 / 1024).toFixed(1) + "mb");
@@ -194,11 +233,14 @@ async function update() {
winLog(lang("gui.update.extracting"));
ipcMain.emit("ns-update-event", "gui.update.extracting");
console.log(lang("cli.update.downloaddone"));
+ // Extracts the zip, this is the part where we're actually
+ // installing Northstar.
fs.createReadStream(settings.zip).pipe(unzip.Extract({path: settings.gamepath}))
.on("finish", () => {
fs.writeFileSync(path.join(settings.gamepath, "ns_version.txt"), latestAvailableVersion);
ipcMain.emit("getversion");
+ // Renames excluded files to their original name
for (let i = 0; i < settings.excludes.length; i++) {
let exclude = path.join(settings.gamepath + "/" + settings.excludes[i]);
if (fs.existsSync(exclude + ".excluded")) {
@@ -216,6 +258,11 @@ async function update() {
})
}
+// Updates Viper itself
+//
+// This uses electron updater to easily update and publish releases, it
+// simply fetches it from GitHub and updates if it's outdated, very
+// useful. Not much we have to do on our side.
function updatevp(autoinstall) {
const { autoUpdater } = require("electron-updater");
@@ -231,6 +278,10 @@ function updatevp(autoinstall) {
autoUpdater.checkForUpdatesAndNotify();
}
+// Launches the game
+//
+// Either Northstar or Vanilla. Linux support is not currently a thing,
+// however it'll be added at some point.
function launch(version) {
if (process.platform == "linux") {
console.error("error:", lang("cli.launch.linuxerror"))
@@ -250,16 +301,27 @@ function launch(version) {
}
}
+// Logs into the dev tools of the renderer
function winLog(msg) {
ipcMain.emit("winLog", msg, msg);
}
+// Sends an alert to the renderer
function winAlert(msg) {
ipcMain.emit("winAlert", msg, msg);
}
+// Used to manage mods.
+//
+// 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
+ //
+ // It'll return 3 arrays, all, enabled, disabled. all being a
+ // combination of the other two, enabled being enabled mods, and you
+ // guessed it, disabled being disabled mods.
list: () => {
if (getNSVersion() == "unknown") {
winLog(lang("general.notinstalled"))
@@ -319,6 +381,13 @@ const mods = {
all: [...mods, ...disabled]
};
},
+
+ // Gets information about a mod
+ //
+ // Folder name, version, name and whatever else is in the mod.json,
+ // keep in mind if the mod developer didn't format their JSON file
+ // the absolute basics will be provided and we can't know the
+ // version or similar.
get: (mod) => {
if (getNSVersion() == "unknown") {
winLog(lang("general.notinstalled"))
@@ -337,6 +406,11 @@ const mods = {
return false;
},
+
+ // Manages the enabledmods.json file
+ //
+ // It can both return info about the file, but also toggle mods in
+ // it, generate the file itself, and so on.
modfile: () => {
let file = path.join(modpath, "..", "enabledmods.json");
@@ -382,6 +456,12 @@ const mods = {
}
};
},
+
+ // Installs mods from a file path
+ //
+ // Either a zip or folder is supported, we'll also try to search
+ // inside the zip or folder to see if buried in another folder or
+ // not, as sometimes that's the case.
install: (mod) => {
if (getNSVersion() == "unknown") {
winLog(lang("general.notinstalled"))
@@ -456,6 +536,10 @@ const mods = {
}catch(err) {return notamod()}
}
},
+ // Removes mods
+ //
+ // Takes in the names of the mod then removes it, no confirmation,
+ // that'd be up to the GUI.
remove: (mod) => {
if (getNSVersion() == "unknown") {
winLog(lang("general.notinstalled"))
@@ -499,6 +583,13 @@ const mods = {
cli.exit(1);
}
},
+
+ // Toggles mods
+ //
+ // If a mod is enabled it'll disable it, vice versa it'll enable it
+ // if it's disabled. You could have a direct .disable() function if
+ // 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) => {
if (getNSVersion() == "unknown") {
winLog(lang("general.notinstalled"))