Multiple manager improvements and bug fixes

This commit is contained in:
Pax1601
2024-03-10 18:38:55 +01:00
parent 8c7f6abb1c
commit 396c061a3e
7 changed files with 154 additions and 53 deletions

View File

@@ -19,21 +19,21 @@
<span>Game Master Password<img src="./icons/circle-info-solid.svg" <span>Game Master Password<img src="./icons/circle-info-solid.svg"
title="This password is used to access Olympus as Game Master with full privileges."> title="This password is used to access Olympus as Game Master with full privileges.">
</span> </span>
<input type="password" minlength="8" onchange="signal('onGameMasterPasswordChanged', this.value)" placeholder="<%= !activeInstance["installed"] || activeInstance["gameMasterPasswordEdited"]? '': 'Keep old password'%>"> <input type="password" minlength="8" onchange="signal('onGameMasterPasswordChanged', this.value)" placeholder="<%= state === 'INSTALL' || activeInstance["gameMasterPasswordEdited"]? '': 'Keep old password'%>">
</div> </div>
<div class="input-group blue-commander"> <div class="input-group blue-commander">
<span>Blue Commander Password<img src="./icons/circle-info-solid.svg" <span>Blue Commander Password<img src="./icons/circle-info-solid.svg"
title="This password is used to access Olympus as blue coalition Commander."> title="This password is used to access Olympus as blue coalition Commander.">
</span> </span>
<input type="password" minlength="8" onchange="signal('onBlueCommanderPasswordChanged', this.value)" placeholder="<%= !activeInstance["installed"] || activeInstance["blueCommanderPasswordEdited"]? '': 'Keep old password'%>"> <input type="password" minlength="8" onchange="signal('onBlueCommanderPasswordChanged', this.value)" placeholder="<%= state === 'INSTALL' || activeInstance["blueCommanderPasswordEdited"]? '': 'Keep old password'%>">
</div> </div>
<div class="input-group red-commander"> <div class="input-group red-commander">
<span>Red Commander Password<img src="./icons/circle-info-solid.svg" <span>Red Commander Password<img src="./icons/circle-info-solid.svg"
title="This password is used to access Olympus as red coalition Commander."> title="This password is used to access Olympus as red coalition Commander.">
</span> </span>
<input type="password" minlength="8" onchange="signal('onRedCommanderPasswordChanged', this.value)" placeholder="<%= !activeInstance["installed"] || activeInstance["redCommanderPasswordEdited"]? '': 'Keep old password'%>"> <input type="password" minlength="8" onchange="signal('onRedCommanderPasswordChanged', this.value)" placeholder="<%= state === 'INSTALL' || activeInstance["redCommanderPasswordEdited"]? '': 'Keep old password'%>">
</div> </div>
<div class="<%= activeInstance["installed"]? '': 'hide' %>" style="color: var(--offwhite); font-size: var(--normal); color: var(--lightgray);"> <div class="<%= state !== 'INSTALL'? '': 'hide' %>" style="color: var(--offwhite); font-size: var(--normal); color: var(--lightgray);">
Note: to keep the old passwords, click <b>Next</b> without editing any value. Note: to keep the old passwords, click <b>Next</b> without editing any value.
</div> </div>
</div> </div>

View File

@@ -1,4 +1,5 @@
const { getManager } = require('./managerfactory') const { getManager } = require('./managerfactory')
const { dialog } = require('@electron/remote');
var regedit = require('regedit').promisified; var regedit = require('regedit').promisified;
var fs = require('fs') var fs = require('fs')
var path = require('path') var path = require('path')
@@ -49,9 +50,13 @@ class DCSInstance {
var result = await regedit.list(shellFoldersKey); var result = await regedit.list(shellFoldersKey);
/* Check that the registry read was successfull */ /* Check that the registry read was successfull */
if (result[shellFoldersKey] !== undefined && result[shellFoldersKey]["exists"] && result[shellFoldersKey]['values'][saveGamesKey] !== undefined && result[shellFoldersKey]['values'][saveGamesKey]['value'] !== undefined) {
let customSavedGamesFolder = (await getManager().getOptions()).savedGamesFolder;
console.log((await getManager().getOptions()))
if (customSavedGamesFolder !== undefined || (result[shellFoldersKey] !== undefined && result[shellFoldersKey]["exists"] && result[shellFoldersKey]['values'][saveGamesKey] !== undefined && result[shellFoldersKey]['values'][saveGamesKey]['value'] !== undefined)) {
try {
/* Read all the folders in Saved Games */ /* Read all the folders in Saved Games */
const searchpath = result[shellFoldersKey]['values'][saveGamesKey]['value']; const searchpath = customSavedGamesFolder !== undefined ? customSavedGamesFolder : result[shellFoldersKey]['values'][saveGamesKey]['value'];
var folders = fs.readdirSync(searchpath).map((folder) => { return path.join(searchpath, folder); }); var folders = fs.readdirSync(searchpath).map((folder) => { return path.join(searchpath, folder); });
var instances = []; var instances = [];
folders = folders.concat(getManager().getAdditionalDCSInstances()); folders = folders.concat(getManager().getAdditionalDCSInstances());
@@ -69,9 +74,21 @@ class DCSInstance {
instances.push(newInstance); instances.push(newInstance);
} }
} }
} catch (err) {
showErrorPopup(`<div class='main-message'>A critical error has occurred while detecting your DCS Instances locations. </div><div class='sub-message'>You can find more info in ${path.join(__dirname, "..", "manager.log")}</div>`)
logger.error(err)
}
} else { } else {
logger.error("An error occured while trying to fetch the location of the DCS instances.") logger.error("An error occured while trying to fetch the location of the DCS instances.")
showErrorPopup(`<div class='main-message'>An error occured while trying to fetch the location of the DCS instances. </div><div class='sub-message'> You can find more info in ${getManager().getLogLocation()} </div>`); showErrorPopup(`<div class='main-message'>An error occured while trying to fetch the location of the DCS instances. </div><div class='sub-message'> After clicking <b>Close</b>, please select the location of your Saved Games folder. </div>`, async () => {
let res = await dialog.showOpenDialog({ properties: ["openDirectory"] });
if (!res.canceled) {
getManager().setSavedGamesFolder(res.filePaths[0]);
}
else {
window.location.reload();
}
});
} }
getManager().setLoadingProgress(`All DCS instances found!`, 100); getManager().setLoadingProgress(`All DCS instances found!`, 100);
@@ -114,7 +131,7 @@ class DCSInstance {
folder = ""; folder = "";
name = ""; name = "";
frontendPort = 3000; frontendPort = 3000;
backendPort = 3001; backendPort = 4512;
backendAddress = "localhost"; backendAddress = "localhost";
gameMasterPassword = ""; gameMasterPassword = "";
blueCommanderPassword = ""; blueCommanderPassword = "";
@@ -494,6 +511,16 @@ class DCSInstance {
await sleep(500); await sleep(500);
await applyConfiguration(getManager().getActiveInstance().folder, getManager().getActiveInstance()); await applyConfiguration(getManager().getActiveInstance().folder, getManager().getActiveInstance());
if (getManager().getActiveInstance().installCameraPlugin === 'install') {
setPopupLoadingProgress("Installing camera plugin...", 50);
await sleep(100);
await installCameraPlugin(getManager().getActiveInstance().folder);
} else {
setPopupLoadingProgress("Removing camera plugin (if installed)...", 50);
await sleep(100);
await deleteCameraPlugin(getManager().getActiveInstance().folder);
}
setPopupLoadingProgress("Editing completed!", 100); setPopupLoadingProgress("Editing completed!", 100);
await sleep(1500); await sleep(1500);
logger.log(`Editing completed successfully`); logger.log(`Editing completed successfully`);
@@ -540,6 +567,10 @@ class DCSInstance {
setPopupLoadingProgress("Installing camera plugin...", 83); setPopupLoadingProgress("Installing camera plugin...", 83);
await sleep(100); await sleep(100);
await installCameraPlugin(getManager().getActiveInstance().folder); await installCameraPlugin(getManager().getActiveInstance().folder);
} else {
setPopupLoadingProgress("Removing camera plugin (if installed)...", 83);
await sleep(100);
await deleteCameraPlugin(getManager().getActiveInstance().folder);
} }
setPopupLoadingProgress("Installation completed!", 100); setPopupLoadingProgress("Installation completed!", 100);

View File

@@ -163,8 +163,14 @@ async function applyConfiguration(folder, instance) {
config["frontend"]["port"] = instance.frontendPort; config["frontend"]["port"] = instance.frontendPort;
config["backend"]["port"] = instance.backendPort; config["backend"]["port"] = instance.backendPort;
config["backend"]["address"] = instance.backendAddress; config["backend"]["address"] = instance.backendAddress;
if (instance.gameMasterPassword !== "")
config["authentication"]["gameMasterPassword"] = sha256(instance.gameMasterPassword); config["authentication"]["gameMasterPassword"] = sha256(instance.gameMasterPassword);
if (instance.blueCommanderPassword !== "")
config["authentication"]["blueCommanderPassword"] = sha256(instance.blueCommanderPassword); config["authentication"]["blueCommanderPassword"] = sha256(instance.blueCommanderPassword);
if (instance.redCommanderPassword !== "")
config["authentication"]["redCommanderPassword"] = sha256(instance.redCommanderPassword); config["authentication"]["redCommanderPassword"] = sha256(instance.redCommanderPassword);
await fsp.writeFile(path.join(folder, "Config", "olympus.json"), JSON.stringify(config, null, 4)); await fsp.writeFile(path.join(folder, "Config", "olympus.json"), JSON.stringify(config, null, 4));

View File

@@ -2,7 +2,7 @@ const path = require("path")
const fs = require("fs"); const fs = require("fs");
const DCSInstance = require('./dcsinstance'); const DCSInstance = require('./dcsinstance');
const { showErrorPopup, showWaitPopup, showConfirmPopup } = require('./popup'); const { showErrorPopup, showConfirmPopup } = require('./popup');
const { logger } = require("./filesystem") const { logger } = require("./filesystem")
const ManagerPage = require("./managerpage"); const ManagerPage = require("./managerpage");
@@ -236,6 +236,17 @@ class Manager {
location.reload(); location.reload();
} }
async setSavedGamesFolder(folder) {
var options = JSON.parse(fs.readFileSync("options.json"));
options.savedGamesFolder = folder;
fs.writeFileSync("options.json", JSON.stringify(options, null, 2));
location.reload();
}
async getOptions() {
return JSON.parse(fs.readFileSync("options.json"));
}
/************************************************/ /************************************************/
/* CALLBACKS */ /* CALLBACKS */
/************************************************/ /************************************************/
@@ -341,8 +352,8 @@ class Manager {
/* When the camera control installation is selected */ /* When the camera control installation is selected */
async onInstallCameraControlClicked(type) { async onInstallCameraControlClicked(type) {
this.connectionsTypePage.getElement().querySelector(`.install`).classList.toggle("selected", type === 'install'); this.cameraPage.getElement().querySelector(`.install`).classList.toggle("selected", type === 'install');
this.connectionsTypePage.getElement().querySelector(`.no-install`).classList.toggle("selected", type === 'no-install'); this.cameraPage.getElement().querySelector(`.no-install`).classList.toggle("selected", type === 'no-install');
if (this.getActiveInstance()) if (this.getActiveInstance())
this.getActiveInstance().installCameraPlugin = type; this.getActiveInstance().installCameraPlugin = type;
else { else {
@@ -406,13 +417,33 @@ class Manager {
} }
/* Installation type page */ /* Installation type page */
} else if (this.activePage == this.cameraPage) { } else if (this.activePage == this.cameraPage) {
if (await this.checkDCSRunning()) {
showConfirmPopup(`<div class='main-message'>DCS is running!</div><div class='sub-message'> Please stop the DCS instance you are trying to add Olympus to, then select <b>Accept</b></div>`, async () => {
/* Nested popup calls need to wait for animation to complete */
await sleep(300);
this.activePage.hide(); this.activePage.hide();
this.getState() === 'INSTALL' ? this.getActiveInstance().install() : this.getActiveInstance().edit(); this.getState() === 'INSTALL' ? this.getActiveInstance().install() : this.getActiveInstance().edit();
});
} else {
this.activePage.hide();
this.getState() === 'INSTALL' ? this.getActiveInstance().install() : this.getActiveInstance().edit();
}
/* Expert settings page */ /* Expert settings page */
} else if (this.activePage == this.expertSettingsPage) { } else if (this.activePage == this.expertSettingsPage) {
if (await this.checkPorts() && await this.checkPasswords()) { if (await this.checkPorts() && await this.checkPasswords()) {
if (await this.checkDCSRunning()) {
showConfirmPopup(`<div class='main-message'>DCS is running!</div><div class='sub-message'> Please stop the DCS instance you are trying to add Olympus to, then select <b>Accept</b></div>`, async () => {
/* Nested popup calls need to wait for animation to complete */
await sleep(300);
this.activePage.hide(); this.activePage.hide();
this.getState() === 'INSTALL' ? this.getActiveInstance().install() : this.getActiveInstance().edit(); this.getState() === 'INSTALL' ? this.getActiveInstance().install() : this.getActiveInstance().edit();
});
} else {
this.activePage.hide();
this.getState() === 'INSTALL' ? this.getActiveInstance().install() : this.getActiveInstance().edit();
}
} }
} }
} }
@@ -541,7 +572,7 @@ class Manager {
async checkPasswords() { async checkPasswords() {
if (this.getActiveInstance()) { if (this.getActiveInstance()) {
if (this.getActiveInstance().installed && !this.getActiveInstance().arePasswordsEdited()) { if (this.getState() === 'EDIT' && !this.getActiveInstance().arePasswordsEdited()) {
return true; return true;
} }
else { else {
@@ -609,10 +640,20 @@ class Manager {
var instance = await this.getClickedInstance(name); var instance = await this.getClickedInstance(name);
this.setActiveInstance(instance); this.setActiveInstance(instance);
await this.setState('UNINSTALL'); await this.setState('UNINSTALL');
if (instance.webserverOnline || instance.backendOnline) if (instance.webserverOnline || instance.backendOnline) {
showErrorPopup("<div class='main-message'>The selected Olympus instance is currently active </div><div class='sub-message'> Please stop DCS and Olympus Server/Client before removing it! </div>") showErrorPopup("<div class='main-message'>The selected Olympus instance is currently active </div><div class='sub-message'> Please stop DCS and Olympus Server/Client before removing it! </div>")
else } else {
if (await this.checkDCSRunning()) {
showConfirmPopup(`<div class='main-message'>DCS is running!</div><div class='sub-message'> Please stop the DCS instance you are trying to remove Olympus from, then select <b>Accept</b></div>`, async () => {
/* Nested popup calls need to wait for animation to complete */
await sleep(300);
await instance.uninstall(); await instance.uninstall();
});
} else {
await instance.uninstall();
}
}
} }
async onLinkClicked(url) { async onLinkClicked(url) {
@@ -758,6 +799,24 @@ class Manager {
this.setActiveInstance(undefined); this.setActiveInstance(undefined);
} }
async checkDCSRunning() {
let ps = new Promise((res, rej) => {
exec('tasklist', function(err, stdout, stderr) {
console.log(stdout)
if (stdout.toLowerCase().includes("dcs.exe") || stdout.includes("dcs_server.exe")) {
res(true);
} else {
res(false);
}
});
})
try {
return await ps;
} catch {
return false; // An error occurred, let's hope DCS is not running!
}
}
/** Get the currently active instance, i.e. the instance that is being edited/installed/removed /** Get the currently active instance, i.e. the instance that is being edited/installed/removed
* *
* @returns The active instance * @returns The active instance

View File

@@ -8,6 +8,8 @@ let window;
/* Add the System32 folder to the environment for the shortcuts creation to work properly */ /* Add the System32 folder to the environment for the shortcuts creation to work properly */
process.env['PATH'] = process.env['PATH'] + "%WINDIR%\\System32;" process.env['PATH'] = process.env['PATH'] + "%WINDIR%\\System32;"
require('@electron/remote/main').initialize()
function createWindow() { function createWindow() {
const window = new electronBrowserWindow({ const window = new electronBrowserWindow({
width: 1200, width: 1200,
@@ -18,11 +20,13 @@ function createWindow() {
webPreferences: { webPreferences: {
contextIsolation: true, contextIsolation: true,
preload: path.join(__dirname, "javascripts", 'preload.js'), preload: path.join(__dirname, "javascripts", 'preload.js'),
nodeIntegration: true, nodeIntegration: true
}, },
icon: "./../img/olympus_configurator.ico" icon: "./../img/olympus_configurator.ico"
}); });
require("@electron/remote/main").enable(window.webContents);
window.loadFile('index.html').then(() => { window.show(); }); window.loadFile('index.html').then(() => { window.show(); });
window.on("maximize", () => { window.on("maximize", () => {

View File

@@ -10,6 +10,7 @@
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@electron/remote": "^2.1.2",
"adm-zip": "^0.5.10", "adm-zip": "^0.5.10",
"create-desktop-shortcuts": "^1.10.1", "create-desktop-shortcuts": "^1.10.1",
"dir-compare": "^4.2.0", "dir-compare": "^4.2.0",

View File

@@ -1,7 +1,7 @@
{ {
"backend": { "backend": {
"address": "localhost", "address": "localhost",
"port": 3001 "port": 4512
}, },
"authentication": { "authentication": {
"gameMasterPassword": "4b8823ed9e5c2392ab4a791913bb8ce41956ea32e308b760eefb97536746dd33", "gameMasterPassword": "4b8823ed9e5c2392ab4a791913bb8ce41956ea32e308b760eefb97536746dd33",