Finished manager bugfix

This commit is contained in:
Pax1601 2024-01-31 12:59:46 +01:00
parent df7eebed39
commit f320cb122c
13 changed files with 397 additions and 256 deletions

View File

@ -4,7 +4,7 @@
<div id="connections-page">
<div class="instructions">
<div class="step">
Step <%= singleInstance? "3": "4" %> of <%= singleInstance? "4": "5" %>
Step <%= instances.length === 1? "3": "4" %> of <%= instances.length === 1? "4": "5" %>
</div>
<div class="title">
Manually set Olympus port and address settings

View File

@ -4,7 +4,7 @@
<div>
<div class="instructions">
<div class="step">
Step <%= singleInstance? "2": "3" %> of <%= singleInstance? "4": "5" %>
Step <%= instances.length === 1? "2": "3" %> of <%= instances.length === 1? "4": "5" %>
</div>
<div class="title">
Do you want to set port and address settings?

View File

@ -19,19 +19,19 @@
<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.">
</span>
<input type="password" minlength="8" onchange="signal('onGameMasterPasswordChanged', this.value)">
<input type="password" minlength="8" onchange="signal('onGameMasterPasswordChanged', this.value)" placeholder="<%= !activeInstance["installed"] || activeInstance["gameMasterPasswordEdited"]? '': 'Keep old password'%>">
</div>
<div class="input-group blue-commander">
<span>Blue Commander Password<img src="./icons/circle-info-solid.svg"
title="This password is used to access Olympus as blue coalition Commander.">
</span>
<input type="password" minlength="8" onchange="signal('onBlueCommanderPasswordChanged', this.value)">
<input type="password" minlength="8" onchange="signal('onBlueCommanderPasswordChanged', this.value)" placeholder="<%= !activeInstance["installed"] || activeInstance["blueCommanderPasswordEdited"]? '': 'Keep old password'%>">
</div>
<div class="input-group red-commander">
<span>Red Commander Password<img src="./icons/circle-info-solid.svg"
title="This password is used to access Olympus as red coalition Commander.">
</span>
<input type="password" minlength="8" onchange="signal('onRedCommanderPasswordChanged', this.value)">
<input type="password" minlength="8" onchange="signal('onRedCommanderPasswordChanged', this.value)" placeholder="<%= !activeInstance["installed"] || activeInstance["redCommanderPasswordEdited"]? '': 'Keep old password'%>">
</div>
<div class="<%= activeInstance["installed"]? '': '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.

View File

@ -3,16 +3,28 @@
</style>
<div>
<div class="instructions">
<div class="step">
Step 1 of <%= singleInstance? "4": "5" %>
</div>
<div class="title">
Which DCS instance you want to add Olympus to?
</div>
<div class="description">
Olympus is added to DCS instances individually, and will only work for that specific instance. <br>
You can have Olympus installed across multiple DCS instances. Re-run in the install wizard to add Olympus to another DCS install.
</div>
<% if (instances.length > 0) { %>
<div class="step">
Step 1 of <%= instances.length === 1? "4": "5" %>
</div>
<div class="title">
Which DCS instance you want to add Olympus to?
</div>
<div class="description">
Olympus is added to DCS instances individually, and will only work for that specific instance. <br>
You can have Olympus installed across multiple DCS instances. Re-run in the install wizard to add Olympus to another DCS install.
</div>
<% } else { %>
<span class="title">
No DCS installs detected
</span>
<span class="description">
Please ensure you have DCS installed correctly. <br>
Olympus cannot be added unless there is a DCS Saved Games folder on your computer. <br><br>
If you are still having issues, try re-installing DCS and Olympus <br><br>
<b>If DCS is installed but Olympus is failing to detect it, you can add it manually.<br> See the troubleshooting guide for more info.</b>
</span>
<% } %>
</div>
<div class="wizard-inputs">
<% for (var i = 0; i < instances.length; i++) { %>

View File

@ -3,47 +3,57 @@
</style>
<div class="dashboard">
<% if (operation === 'INSTALL') { %>
<div class="result-summary success <%= (typeof activeInstance !== 'undefined' && !activeInstance["error"] && activeInstance["installed"])? "": "hide" %>">
<% if (state === 'INSTALL') { %>
<div class="result-summary success <%= (activeInstance !== undefined && !activeInstance["error"] && activeInstance["installed"])? "": "hide" %>">
<div class="title"><img src="./icons/check-solid-background.svg">Olympus installed successfully in
<i style="margin-left: 3px"><%= typeof activeInstance !== 'undefined'? activeInstance["name"]: "" %></i>!</div>
<i style="margin-left: 3px"><%= activeInstance !== undefined? activeInstance["name"]: "" %></i>!</div>
</div>
<div class="result-summary error <%= (typeof activeInstance !== 'undefined' && (activeInstance["error"] || !activeInstance["installed"]))? "": "hide" %>">
<div class="result-summary error <%= (activeInstance !== undefined && (activeInstance["error"] || !activeInstance["installed"]))? "": "hide" %>">
<div class="title"><img src="./icons/triangle-exclamation-solid-background.svg">An error occurred while installing Olympus in
<i style="margin-left: 3px"><%= typeof activeInstance !== 'undefined'? activeInstance["name"]: "" %></i></div>
<i style="margin-left: 3px"><%= activeInstance !== undefined? activeInstance["name"]: "" %></i></div>
</div>
<% } else if (operation === 'EDIT') {%>
<div class="result-summary success <%= (typeof activeInstance !== 'undefined' && !activeInstance["error"])? "": "hide" %>">
<% } else if (state === 'EDIT') {%>
<div class="result-summary success <%= (activeInstance !== undefined && !activeInstance["error"])? "": "hide" %>">
<div class="title"><img src="./icons/check-solid-background.svg">Olympus settings updated for
<i style="margin-left: 3px"><%= typeof activeInstance !== 'undefined'? activeInstance["name"]: "" %></i>!</div>
<i style="margin-left: 3px"><%= activeInstance !== undefined? activeInstance["name"]: "" %></i>!</div>
</div>
<div class="result-summary error <%= (typeof activeInstance !== 'undefined' && activeInstance["error"])? "": "hide" %>">
<div class="result-summary error <%= (activeInstance !== undefined && activeInstance["error"])? "": "hide" %>">
<div class="title"><img src="./icons/triangle-exclamation-solid-background.svg">An error occurred while updating Olympus settings for
<i style="margin-left: 3px"><%= typeof activeInstance !== 'undefined'? activeInstance["name"]: "" %></i></div>
<i style="margin-left: 3px"><%= activeInstance !== undefined? activeInstance["name"]: "" %></i></div>
</div>
<% } else {%>
<div class="result-summary success <%= (typeof activeInstance !== 'undefined' && !activeInstance["installed"])? "": "hide" %>">
<div class="result-summary success <%= (activeInstance !== undefined && !activeInstance["installed"])? "": "hide" %>">
<div class="title"><img src="./icons/check-solid-background.svg">Olympus removed successfully from
<i style="margin-left: 3px"><%= typeof activeInstance !== 'undefined'? activeInstance["name"]: "" %></i>!</div>
<i style="margin-left: 3px"><%= activeInstance !== undefined? activeInstance["name"]: "" %></i>!</div>
</div>
<div class="result-summary error <%= (typeof activeInstance !== 'undefined' && activeInstance["installed"])? "": "hide" %>">
<div class="result-summary error <%= (activeInstance !== undefined && activeInstance["installed"])? "": "hide" %>">
<div class="title"><img src="./icons/triangle-exclamation-solid-background.svg">An error occurred while removing Olympus settings from
<i style="margin-left: 3px"><%= typeof activeInstance !== 'undefined'? activeInstance["name"]: "" %></i></div>
<i style="margin-left: 3px"><%= activeInstance !== undefined? activeInstance["name"]: "" %></i></div>
</div>
<% } %>
<div class="content">
<div class="instructions">
<span class="title">
View and manage installs
</span>
<span class="subtitle">
The following DCS installations have been identified. <br>You can start an Olympus server, modify settings and uninstall below.
</span>
</div>
<div style="font-size: var(--very-large); color: var(--offwhite); font-weight: bold; margin-top: 150px; text-align: center;" class="<%= instances.length > 0? "hide": "" %>">
No instances detected!
<% if (instances.length > 0) { %>
<span class="title">
View and manage installs
</span>
<span class="subtitle">
The following DCS installations have been identified. <br>You can start an Olympus server, modify settings and uninstall below.
</span>
<% } else { %>
<span class="title" style="margin-top: 150px;">
No DCS installs detected
</span>
<span class="subtitle">
Please ensure you have DCS installed correctly. <br>
Olympus cannot be added unless there is a DCS Saved Games folder on your computer. <br><br>
If you are still having issues, try re-installing DCS and Olympus <br><br>
<b>If DCS is installed but Olympus is failing to detect it, you can add it manually.<br> See the troubleshooting guide for more info.</b>
</span>
<% } %>
</div>
<div class="scroll-container">
<div class="scrollable">
<% for (let i = 0; i < instances.length; i++) {%>

View File

@ -84,13 +84,13 @@
</div>
</div>
<div id="menu" style="row-gap: 20px; width: 60%;">
<div class="option <%= installEnabled? '': 'disabled' %>" onclick="signal('onInstallMenuClicked')">
<div class="option" onclick="signal('onInstallMenuClicked')">
Add Olympus
<div>
Add or update Olympus to a new DCS instance
</div>
</div>
<div class="option <%= editEnabled? '': 'disabled' %>" onclick="signal('onEditMenuClicked')">
<div class="option <%= instances.find(instance => instance.installed)? '': 'disabled' %>" onclick="signal('onEditMenuClicked')">
Change settings
<div>
Adjust port, address and password settings

View File

@ -4,7 +4,7 @@
<div id="passwords-page">
<div class="instructions">
<div class="step">
Step <%= singleInstance? "4": "5" %> of <%= singleInstance? "4": "5" %>
Step <%= instances.length === 1? "4": "5" %> of <%= instances.length === 1? "4": "5" %>
</div>
<div class="title">
Enter your passwords for Olympus
@ -19,19 +19,19 @@
<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.">
</span>
<input type="password" minlength="8" onchange="signal('onGameMasterPasswordChanged', this.value)">
<input type="password" minlength="8" onchange="signal('onGameMasterPasswordChanged', this.value)" placeholder="<%= !activeInstance["installed"] || activeInstance["gameMasterPasswordEdited"]? '': 'Keep old password'%>">
</div>
<div class="input-group blue-commander">
<span>Blue Commander Password<img src="./icons/circle-info-solid.svg"
title="This password is used to access Olympus as blue coalition Commander.">
</span>
<input type="password" minlength="8" onchange="signal('onBlueCommanderPasswordChanged', this.value)">
<input type="password" minlength="8" onchange="signal('onBlueCommanderPasswordChanged', this.value)" placeholder="<%= !activeInstance["installed"] || activeInstance["blueCommanderPasswordEdited"]? '': 'Keep old password'%>">
</div>
<div class="input-group red-commander">
<span>Red Commander Password<img src="./icons/circle-info-solid.svg"
title="This password is used to access Olympus as red coalition Commander.">
</span>
<input type="password" minlength="8" onchange="signal('onRedCommanderPasswordChanged', this.value)">
<input type="password" minlength="8" onchange="signal('onRedCommanderPasswordChanged', this.value)" placeholder="<%= !activeInstance["installed"] || activeInstance["redCommanderPasswordEdited"]? '': 'Keep old password'%>">
</div>
<div class="<%= activeInstance["installed"]? '': '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.

View File

@ -96,7 +96,7 @@
<div>
<img src="./icons/chrome.svg">
<div>
To access Olympus remotely visit <div class="link" onclick="signal('onLinkClicked', 'http://<%= ip %>:<%= activeInstance["clientPort"] %>')">http://<%= ip %>:<%= activeInstance["clientPort"] %></div> <b>in a web browser</b> (Google Chrome recommended).
To access Olympus remotely visit <div class="link" onclick="signal('onLinkClicked', 'http://<%= IP %>:<%= activeInstance["clientPort"] %>')">http://<%= IP %>:<%= activeInstance["clientPort"] %></div> <b>in a web browser</b> (Google Chrome recommended).
</div>
</div>
<img src="./icons/arrow-right-solid.svg">

View File

@ -5,27 +5,28 @@
<div class="cancel" style="font-size: var(--normal); font-weight: 600; color: var(--offwhite); display: flex; align-items: center; column-gap: 10px; cursor: pointer; text-decoration: underline; " onclick="signal('onCancelClicked')">
<img src="./icons/chevron-left-solid.svg" style=" height: 14px;">Back to menu
</div>
<% if (operation === 'EDIT') {%>
<div class="result-summary success <%= (typeof activeInstance !== 'undefined' && !activeInstance["error"])? "": "hide" %>">
<% if (state === 'EDIT') {%>
<div class="result-summary success <%= (activeInstance !== undefined && !activeInstance["error"])? "": "hide" %>">
<div class="title"><img src="./icons/check-solid-background.svg">Olympus settings updated for
<i style="margin-left: 3px"><%= typeof activeInstance !== 'undefined'? activeInstance["name"]: "" %></i>!</div>
<i style="margin-left: 3px"><%= activeInstance !== undefined? activeInstance["name"]: "" %></i>!</div>
</div>
<div class="result-summary error <%= (typeof activeInstance !== 'undefined' && activeInstance["error"])? "": "hide" %>">
<div class="result-summary error <%= (activeInstance !== undefined && activeInstance["error"])? "": "hide" %>">
<div class="title"><img src="./icons/triangle-exclamation-solid-background.svg">An error occurred while updating Olympus settings for
<i style="margin-left: 3px"><%= typeof activeInstance !== 'undefined'? activeInstance["name"]: "" %></i></div>
<i style="margin-left: 3px"><%= activeInstance !== undefined? activeInstance["name"]: "" %></i></div>
</div>
<% } else {%>
<div class="result-summary success <%= (typeof activeInstance !== 'undefined' && !activeInstance["installed"])? "": "hide" %>">
<div class="result-summary success <%= (activeInstance !== undefined && !activeInstance["installed"])? "": "hide" %>">
<div class="title"><img src="./icons/check-solid-background.svg">Olympus removed successfully from
<i style="margin-left: 3px"><%= typeof activeInstance !== 'undefined'? activeInstance["name"]: "" %></i>!</div>
<i style="margin-left: 3px"><%= activeInstance !== undefined? activeInstance["name"]: "" %></i>!</div>
</div>
<div class="result-summary error <%= (typeof activeInstance !== 'undefined' && activeInstance["installed"])? "": "hide" %>">
<div class="result-summary error <%= (activeInstance !== undefined && activeInstance["installed"])? "": "hide" %>">
<div class="title"><img src="./icons/triangle-exclamation-solid-background.svg">An error occurred while removing Olympus settings from
<i style="margin-left: 3px"><%= typeof activeInstance !== 'undefined'? activeInstance["name"]: "" %></i></div>
<i style="margin-left: 3px"><%= activeInstance !== undefined? activeInstance["name"]: "" %></i></div>
</div>
<% } %>
<div class="content">
<div class="instructions">
<% if (instances.some(instance => instance.installed)) { %>
<span class="title">
Change settings
</span>
@ -33,9 +34,15 @@
Here you can see the DCS instances on your computer that have Olympus installed. <br>
You can edit settings and uninstall Olympus from this screen.
</span>
</div>
<div style="font-size: var(--very-large); color: var(--offwhite); font-weight: bold; margin-top: 150px; text-align: center;" class="<%= instances.some(instance => instance.installed)? "hide": "" %>">
No instances detected!
<% } else { %>
<span class="title" style="margin-top: 150px;">
No Olympus installs detected
</span>
<span class="subtitle">
Use the <b>Add Olympus</b> option in the main manu to install Olympus in your DCS instance. <br>
If you have more than one DCS instance, you will need to add Olympus to each one of them.
</span>
<% } %>
</div>
<div class="scroll-container">
<div class="scrollable">

View File

@ -4,7 +4,7 @@
<div>
<div class="instructions">
<div class="step">
Step <%= singleInstance? "1": "2" %> of <%= singleInstance? "4": "5" %>
Step <%= instances.length === 1? "1": "2" %> of <%= instances.length === 1? "4": "5" %>
</div>
<div class="title">
Do you want to add Olympus for singleplayer or multiplayer?

View File

@ -71,7 +71,7 @@
</style>
<div class="wizard-page">
<div class="cancel" style="font-size: var(--normal); font-weight: 600; color: var(--offwhite); display: flex; align-items: center; column-gap: 10px; cursor: pointer; text-decoration: underline;" onclick="signal('onCancelClicked')">
<img src="./icons/chevron-left-solid.svg" style=" height: 14px;"><%= operation === 'INSTALL'? "Cancel install": "Cancel editing" %>
<img src="./icons/chevron-left-solid.svg" style=" height: 14px;"><%= state === 'INSTALL'? "Cancel install": "Cancel editing" %>
</div>
<div class="content">

View File

@ -28,14 +28,15 @@ class DCSInstance {
return DCSInstance.instances;
}
/** Static asynchronous method to reload all DCS instances. It will not detect any new instance, but it will determine the
* installation status of the existing instances.
*
*/
static async reloadInstances() {
var instances = await this.getInstances();
console.log(instances);
for (let instance of instances) {
await instance.checkInstallation();
console.log(instance.installed);
}
return true;
}
/** Static asynchronous method to find all existing DCS instances
@ -53,12 +54,12 @@ class DCSInstance {
const searchpath = result[shellFoldersKey]['values'][saveGamesKey]['value'];
var folders = fs.readdirSync(searchpath).map((folder) => {return path.join(searchpath, folder);});
var instances = [];
folders = folders.concat(getManager().options.additionalDCSInstances);
folders = folders.concat(getManager().getAdditionalDCSInstances());
/* A DCS Instance is created if either the appsettings.lua or serversettings.lua file is detected */
for (let i = 0; i < folders.length; i++) {
const folder = folders[i];
if (fs.existsSync(path.join(folder, "Config", "appsettings.lua")) || fs.existsSync(path.join(folder, "Config", "serversettings.lua")) || getManager().options.additionalDCSInstances.includes(folder)) {
if (fs.existsSync(path.join(folder, "Config", "appsettings.lua")) || fs.existsSync(path.join(folder, "Config", "serversettings.lua")) || getManager().getAdditionalDCSInstances().includes(folder)) {
logger.log(`Found instance in ${folder}, checking for Olympus`)
var newInstance = new DCSInstance(path.join(folder));
@ -70,7 +71,7 @@ class DCSInstance {
}
} else {
logger.error("An error occured while trying to fetch the location of the DCS instances.")
throw "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>`);
}
getManager().setLoadingProgress(`All DCS instances found!`, 100);
@ -148,8 +149,15 @@ class DCSInstance {
* @returns true if the instance has any error or is outdated
*/
async checkInstallation() {
/* Reset values */
this.installed = false;
this.error = false;
this.installationType = 'singleplayer';
this.connectionsType = 'auto';
/* Check if the olympus.json file is detected. If true, Olympus is considered to be installed */
if (fs.existsSync(path.join(this.folder, "Config", "olympus.json"))) {
getManager().setLoadingProgress(`Olympus installed in ${this.folder}`);
try {
/* Read the olympus.json */
@ -158,6 +166,11 @@ class DCSInstance {
this.backendPort = config["server"]["port"];
this.backendAddress = config["server"]["address"];
this.gameMasterPasswordHash = config["authentication"]["gameMasterPassword"];
this.gameMasterPasswordEdited = false;
this.blueCommanderPasswordEdited = false;
this.redCommanderPasswordEdited = false;
} catch (err) {
showErrorPopup(`<div class='main-message'>A critical error has occurred while reading your Olympus configuration file. </div><div class='sub-message'> Please, manually reinstall olympus in ${this.folder}. </div>`)
logger.error(err)
@ -205,7 +218,6 @@ class DCSInstance {
*
* @param {Number} newPort The new client port to set
*/
setClientPort(newPort) {
logger.log(`Instance ${this.folder} client port set to ${newPort}`)
this.clientPort = newPort;
@ -374,7 +386,7 @@ class DCSInstance {
*
*/
async getData() {
if (this.installed && !this.error) {
if (this.installed) {
fetchWithTimeout(`http://localhost:${this.clientPort}`, { timeout: 250 })
.then(async (response) => {
this.webserverOnline = (await response.text()).includes("Olympus");
@ -485,13 +497,13 @@ class DCSInstance {
logger.log(`Editing completed successfully`);
hidePopup();
getManager().options.mode === "basic"? getManager().settingsPage.show(): getManager().instancesPage.show();
getManager().getMode() === "basic"? getManager().settingsPage.show(): getManager().instancesPage.show();
} catch (err) {
logger.log(`An error occurred during editing: ${err}`);
getManager().getActiveInstance().error = true;
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${getManager().options.logLocation} for more info. </div>`)
getManager().options.mode === "basic"? getManager().settingsPage.show(): getManager().instancesPage.show();
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${getManager().getLogLocation()} for more info. </div>`)
getManager().getMode() === "basic"? getManager().settingsPage.show(): getManager().instancesPage.show();
}
}
@ -526,7 +538,7 @@ class DCSInstance {
await sleep(500);
logger.log(`Installation completed successfully`);
hidePopup();
if (getManager().options.mode === 'basic') {
if (getManager().getMode() === 'basic') {
getManager().resultPage.show();
getManager().resultPage.getElement().querySelector(".result-summary.success").classList.remove("hide");
getManager().resultPage.getElement().querySelector(".result-summary.error").classList.add("hide");
@ -538,7 +550,7 @@ class DCSInstance {
} catch (err) {
logger.log(`An error occurred during installation: ${err}`);
hidePopup();
if (getManager().options.mode === 'basic') {
if (getManager().getMode() === 'basic') {
getManager().resultPage.show();
getManager().resultPage.getElement().querySelector(".result-summary.success").classList.add("hide");
getManager().resultPage.getElement().querySelector(".result-summary.error").classList.remove("hide");
@ -581,7 +593,7 @@ class DCSInstance {
hidePopup();
await getManager().reload();
if (getManager().options.mode === 'basic')
if (getManager().getMode() === 'basic')
getManager().settingsPage.show();
else
getManager().instancesPage.show();
@ -589,12 +601,14 @@ class DCSInstance {
} catch (err) {
logger.error(err)
showErrorPopup(`<div class='main-message'>An error has occurred while uninstalling the Olympus instance. </div><div class='sub-message'> Make sure Olympus and DCS are not running. </div><div class='sub-message'>You can find more info in ${path.join(__dirname, "..", "manager.log")} </div>`, () => {
if (getManager().options.mode === 'basic')
if (getManager().getMode() === 'basic')
getManager().settingsPage.show();
else
getManager().instancesPage.show();
});
}
}
}, () => {
getManager().setState('IDLE');
});
}
}

View File

@ -13,11 +13,17 @@ const { sleep } = require("./utils");
class Manager {
options = {
logLocation: path.join(__dirname, "..", "manager.log"),
activeInstance: undefined,
additionalDCSInstances: [],
configLoaded: false,
operation: 'NONE'
instances: [],
IP: undefined,
logLocation: path.join(__dirname, "..", "manager.log"),
mode: 'basic',
state: 'IDLE'
};
/* Manager pages */
activePage = null;
welcomePage = null;
settingsPage = null;
@ -43,6 +49,10 @@ class Manager {
console.error(e);
}
});
window.olympus = {
manager: this
};
}
/** Asynchronously start the manager
@ -55,14 +65,14 @@ class Manager {
/* Load the options from the json file */
try {
this.options = { ...this.options, ...JSON.parse(fs.readFileSync("options.json")) };
this.options.configLoaded = true;
this.setConfigLoaded(true);
} catch (e) {
logger.error(`An error occurred while reading the options.json file: ${e}`);
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${getManager().options.logLocation} for more info. </div>`)
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${this.getLogLocation()} for more info. </div>`)
}
}
if (!this.options.configLoaded) {
if (!this.getConfigLoaded()) {
this.hideLoadingPage();
/* Show page to select basic vs expert mode */
@ -73,7 +83,7 @@ class Manager {
document.getElementById("header").classList.remove("hide");
/* Initialize mode switching */
if (this.options.mode === "basic") {
if (this.getMode() === "basic") {
document.getElementById("switch-mode").innerText = "Expert mode";
document.getElementById("switch-mode").onclick = () => { this.switchMode("expert"); }
}
@ -84,108 +94,110 @@ class Manager {
/* Get the list of DCS instances */
this.setLoadingProgress("Retrieving DCS instances...", 0);
DCSInstance.getInstances().then(async (instances) => {
this.setLoadingProgress(`Analysis completed, starting manager...`, 100);
await sleep(100);
var instances = await DCSInstance.getInstances();
this.setLoadingProgress(`Analysis completed, starting manager...`, 100);
await sleep(100);
this.options.instances = instances;
this.setInstances(instances);
/* Get my public IP */
this.getPublicIP().then(
(ip) => { this.options.ip = ip; },
() => { this.options.ip = undefined; }
)
/* Check if there are corrupted or outdated instances */
if (this.options.instances.some((instance) => {
return instance.installed && instance.error;
})) {
/* Ask the user for confirmation */
showConfirmPopup("<div class='main-message'> One or more of your Olympus instances are not up to date! </div><div class='sub-message'> If you have just updated Olympus this is normal.<br><br> Press <b>Accept</b> and the Manager will update your instances for you. <br> Press <b>Close</b> to update your instances manually using the Installation Wizard</div>", async () => {
try {
await sleep(300);
await DCSInstance.fixInstances();
location.reload();
} catch (err) {
logger.error(err);
await sleep(300);
showErrorPopup(`<div class='main-message'>An error occurred while trying to fix your installations. Please reinstall Olympus manually. </div><div class='sub-message'> You can find more info in ${this.options.logLocation} </div>`);
}
})
/* Get my public IP */
this.getPublicIP().then(
(IP) => { this.setIP(IP); },
(err) => {
logger.log(err)
this.setIP(undefined);
}
)
this.options.installEnabled = true;
this.options.editEnabled = this.options.instances.find(instance => instance.installed);
/* Hide the loading page */
this.hideLoadingPage();
this.options.singleInstance = this.options.instances.length === 1;
/* Create all the HTML pages */
this.menuPage = new ManagerPage(this, "./ejs/menu.ejs");
this.folderPage = new WizardPage(this, "./ejs/folder.ejs");
this.settingsPage = new ManagerPage(this, "./ejs/settings.ejs");
this.typePage = new WizardPage(this, "./ejs/type.ejs");
this.connectionsTypePage = new WizardPage(this, "./ejs/connectionsType.ejs");
this.connectionsPage = new WizardPage(this, "./ejs/connections.ejs");
this.passwordsPage = new WizardPage(this, "./ejs/passwords.ejs");
this.resultPage = new ManagerPage(this, "./ejs/result.ejs");
this.instancesPage = new ManagerPage(this, "./ejs/instances.ejs");
this.expertSettingsPage = new WizardPage(this, "./ejs/expertsettings.ejs");
/* Force the setting of the ports whenever the page is shown */
this.connectionsPage.options.onShow = () => {
if (this.options.activeInstance) {
this.setPort('client', this.options.activeInstance.clientPort);
this.setPort('backend', this.options.activeInstance.backendPort);
/* Check if there are corrupted or outdated instances */
if (this.getInstances().some((instance) => {
return instance.installed && instance.error;
})) {
/* Ask the user for confirmation */
showConfirmPopup("<div class='main-message'> One or more of your Olympus instances are not up to date! </div><div class='sub-message'> If you have just updated Olympus this is normal.<br><br> Press <b>Accept</b> and the Manager will update your instances for you. <br> Press <b>Close</b> to update your instances manually using the Installation Wizard</div>", async () => {
try {
await sleep(300);
await DCSInstance.fixInstances();
location.reload();
} catch (err) {
logger.error(err);
await sleep(300);
showErrorPopup(`<div class='main-message'>An error occurred while trying to fix your installations. Please reinstall Olympus manually. </div><div class='sub-message'> You can find more info in ${this.options.logLocation} </div>`);
}
}
this.expertSettingsPage.options.onShow = () => {
if (this.options.activeInstance) {
this.setPort('client', this.options.activeInstance.clientPort);
this.setPort('backend', this.options.activeInstance.backendPort);
}
}
})
}
this.instancesPage.options.onShow = () => {
this.updateInstances();
}
/* Hide the loading page */
this.hideLoadingPage();
if (this.options.mode === "basic") {
/* In basic mode no dashboard is shown */
this.menuPage.show();
} else {
/* In Expert mode we go directly to the dashboard */
this.instancesPage.show();
this.updateInstances();
}
/* Create all the HTML pages */
this.menuPage = new ManagerPage(this, "./ejs/menu.ejs");
this.folderPage = new WizardPage(this, "./ejs/folder.ejs");
this.settingsPage = new ManagerPage(this, "./ejs/settings.ejs");
this.typePage = new WizardPage(this, "./ejs/type.ejs");
this.connectionsTypePage = new WizardPage(this, "./ejs/connectionsType.ejs");
this.connectionsPage = new WizardPage(this, "./ejs/connections.ejs");
this.passwordsPage = new WizardPage(this, "./ejs/passwords.ejs");
this.resultPage = new ManagerPage(this, "./ejs/result.ejs");
this.instancesPage = new ManagerPage(this, "./ejs/instances.ejs");
this.expertSettingsPage = new WizardPage(this, "./ejs/expertsettings.ejs");
/* Send an event on manager started */
document.dispatchEvent(new CustomEvent("managerStarted"));
});
/* Force the setting of the ports whenever the page is shown */
this.connectionsPage.options.onShow = () => {
if (this.getActiveInstance()) {
this.setPort('client', this.getActiveInstance().clientPort);
this.setPort('backend', this.getActiveInstance().backendPort);
}
}
this.expertSettingsPage.options.onShow = () => {
if (this.getActiveInstance()) {
this.setPort('client', this.getActiveInstance().clientPort);
this.setPort('backend', this.getActiveInstance().backendPort);
}
}
/* Always force the IDLE state when reaching the menu page */
this.menuPage.options.onShow = async () => {
await this.setState('IDLE');
}
/* Update the instances when showing the dashboard */
this.instancesPage.options.onShow = () => {
this.updateInstances();
}
/* Reload the instances when we get to the folder page */
this.folderPage.options.onShow = async () => {
if (this.getInstances().length > 0)
this.setActiveInstance(this.getInstances()[0]);
await DCSInstance.reloadInstances();
}
if (this.getMode() === "basic") {
/* In basic mode no dashboard is shown */
this.menuPage.show();
} else {
/* In Expert mode we go directly to the dashboard */
this.instancesPage.show();
this.updateInstances();
}
/* Send an event on manager started */
document.dispatchEvent(new CustomEvent("managerStarted"));
}
}
/** Get the currently active instance, i.e. the instance that is being edited/installed/removed
*
* @returns The active instance
*/
getActiveInstance() {
return this.options.activeInstance;
}
/** Creates the options file. This is done only the very first time you start Olympus.
*
* @param {String} mode The mode, either Basic or Expert
*/
createOptionsFile(mode) {
async createOptionsFile(mode) {
try {
fs.writeFileSync("options.json", JSON.stringify({ mode: mode, additionalDCSInstances: [] }, null, 2));
location.reload();
} catch (err) {
logger.log(err);
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${getManager().options.logLocation} for more info. </div>`)
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${this.getLogLocation()} for more info. </div>`)
}
}
@ -193,7 +205,7 @@ class Manager {
*
* @param {String} newMode The mode to switch to
*/
switchMode(newMode) {
async switchMode(newMode) {
/* Change the mode in the options.json and reload the page */
var options = JSON.parse(fs.readFileSync("options.json"));
options.mode = newMode;
@ -207,38 +219,42 @@ class Manager {
/** Switch to basic mode
*
*/
onBasicClicked() {
async onBasicClicked() {
this.createOptionsFile("basic");
}
/** Switch to expert mode
*
*/
onExpertClicked() {
async onExpertClicked() {
this.createOptionsFile("expert");
}
/** When the install button is clicked go the installation page
*
*/
onInstallMenuClicked() {
this.options.operation = 'INSTALL';
async onInstallMenuClicked() {
await this.setState('INSTALL');
if (this.options.instances.length == 0) {
if (this.getInstances().length == 0) {
// TODO: show error
}
this.options.activeInstance = this.options.instances[0];
if (this.options.singleInstance) {
if (this.getInstances().length === 1) {
this.setActiveInstance(this.getInstances()[0]);
/* Show the type selection page */
if (!this.options.activeInstance.installed) {
if (!this.getActiveInstance().installed) {
this.activePage.hide()
this.typePage.show();
} else {
showConfirmPopup("<div class='main-message'> Olympus is already installed in this instance! </div> <div class='sub-message'>If you click Accept, it will be installed again and all changes, e.g. custom databases or mods support, will be lost. Are you sure you want to continue?</div>",
() => {
this.activePage.hide()
this.activePage.hide();
this.typePage.show();
},
async () => {
await this.setState('IDLE');
}
)
}
@ -252,10 +268,9 @@ class Manager {
/** When the edit button is clicked go to the settings page
*
*/
onEditMenuClicked() {
this.activePage.hide()
this.options.operation = 'EDIT';
delete this.options.activeInstance;
async onEditMenuClicked() {
this.activePage.hide();
await this.setState('IDLE');
this.settingsPage.show();
}
@ -271,37 +286,38 @@ class Manager {
for (let i = 0; i < instanceDivs.length; i++) {
instanceDivs[i].classList.toggle('selected', instanceDivs[i].dataset.folder === instance.folder);
if (instanceDivs[i].dataset.folder === instance.folder)
this.options.activeInstance = instance;
this.setActiveInstance(instance);
}
}
/* When the installation type is selected */
onInstallTypeClicked(type) {
async onInstallTypeClicked(type) {
this.typePage.getElement().querySelector(`.singleplayer`).classList.toggle("selected", type === 'singleplayer');
this.typePage.getElement().querySelector(`.multiplayer`).classList.toggle("selected", type === 'multiplayer');
if (this.options.activeInstance)
this.options.activeInstance.installationType = type;
if (this.getActiveInstance())
this.getActiveInstance().installationType = type;
else {
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${getManager().options.logLocation} for more info. </div>`);
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${this.getLogLocation()} for more info. </div>`);
}
}
/* When the connections type is selected */
onConnectionsTypeClicked(type) {
async onConnectionsTypeClicked(type) {
this.connectionsTypePage.getElement().querySelector(`.auto`).classList.toggle("selected", type === 'auto');
this.connectionsTypePage.getElement().querySelector(`.manual`).classList.toggle("selected", type === 'manual');
if (this.options.activeInstance)
this.options.activeInstance.connectionsType = type;
if (this.getActiveInstance())
this.getActiveInstance().connectionsType = type;
else {
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${getManager().options.logLocation} for more info. </div>`);
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${this.getLogLocation()} for more info. </div>`);
}
}
/* When the next button of a wizard page is clicked */
async onNextClicked() {
/* Choose which page to show depending on the active page */
/* Folder selection page */
if (this.activePage == this.folderPage) {
if (this.options.activeInstance.installed) {
if (this.getActiveInstance().installed) {
showConfirmPopup("<div class='main-message'> Olympus is already installed in this instance! </div> <div class='sub-message'>If you click Accept, it will be installed again and all changes, e.g. custom databases or mods support, will be lost. Are you sure you want to continue?</div>",
() => {
this.activePage.hide()
@ -312,111 +328,128 @@ class Manager {
this.activePage.hide();
this.typePage.show();
}
/* Installation type page */
} else if (this.activePage == this.typePage) {
this.activePage.hide();
this.connectionsTypePage.show();
/* Connection type page */
} else if (this.activePage == this.connectionsTypePage) {
if (this.options.activeInstance) {
if (this.options.activeInstance.connectionsType === 'auto') {
if (this.getActiveInstance()) {
if (this.getActiveInstance().connectionsType === 'auto') {
this.activePage.hide();
this.passwordsPage.show();
}
else {
this.activePage.hide();
this.connectionsPage.show();
(this.options.mode === 'basic'? this.connectionsPage: this.expertSettingsPage).getElement().querySelector(".backend-address .checkbox").classList.toggle("checked", this.options.activeInstance.backendAddress === '*')
(this.getMode() === 'basic'? this.connectionsPage: this.expertSettingsPage).getElement().querySelector(".backend-address .checkbox").classList.toggle("checked", this.getActiveInstance().backendAddress === '*')
}
} else {
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${getManager().options.logLocation} for more info. </div>`)
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${this.getLogLocation()} for more info. </div>`)
}
/* Connection page */
} else if (this.activePage == this.connectionsPage) {
if (await this.checkPorts()) {
this.activePage.hide();
this.passwordsPage.show();
}
/* Passwords page */
} else if (this.activePage == this.passwordsPage) {
if (await this.checkPasswords()) {
this.activePage.hide();
this.options.operation === 'INSTALL' ? this.options.activeInstance.install() : this.options.activeInstance.edit();
this.getState() === 'INSTALL' ? this.getActiveInstance().install() : this.getActiveInstance().edit();
}
/* Expert settings page */
} else if (this.activePage == this.expertSettingsPage) {
if (await this.checkPorts() && await this.checkPasswords()) {
this.activePage.hide();
this.options.operation === 'INSTALL' ? this.options.activeInstance.install() : this.options.activeInstance.edit();
this.getState() === 'INSTALL' ? this.getActiveInstance().install() : this.getActiveInstance().edit();
}
}
}
/* When the back button of a wizard page is clicked */
onBackClicked() {
async onBackClicked() {
this.activePage.hide();
/* If we have backed to the menu, instances or settings page, reset the active instance */
if ([this.instancesPage, this.settingsPage].includes(this.activePage.previousPage)) {
delete this.options.activeInstance;
await this.setState('IDLE');
}
this.activePage.previousPage.show(true); // Don't change the previous page
this.activePage.previousPage.show(true); // Don't change the previous page (or we get stuck in a loop)
this.updateInstances();
}
onCancelClicked() {
async onCancelClicked() {
this.activePage.hide();
delete this.options.activeInstance;
if (this.options.mode === "basic")
await this.setState('IDLE');
if (this.getMode() === "basic")
this.menuPage.show(true);
else
this.instancesPage.show(true);
this.updateInstances();
}
onGameMasterPasswordChanged(value) {
if (this.options.activeInstance)
this.options.activeInstance.setGameMasterPassword(value);
async onGameMasterPasswordChanged(value) {
for (let input of this.activePage.getElement().querySelectorAll("input[type='password']")) {
input.placeholder = "";
}
if (this.getActiveInstance())
this.getActiveInstance().setGameMasterPassword(value);
else
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${getManager().options.logLocation} for more info. </div>`);
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${this.getLogLocation()} for more info. </div>`);
}
onBlueCommanderPasswordChanged(value) {
if (this.options.activeInstance)
this.options.activeInstance.setBlueCommanderPassword(value);
async onBlueCommanderPasswordChanged(value) {
for (let input of this.activePage.getElement().querySelectorAll("input[type='password']")) {
input.placeholder = "";
}
if (this.getActiveInstance())
this.getActiveInstance().setBlueCommanderPassword(value);
else
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${getManager().options.logLocation} for more info. </div>`);
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${this.getLogLocation()} for more info. </div>`);
}
onRedCommanderPasswordChanged(value) {
if (this.options.activeInstance)
this.options.activeInstance.setRedCommanderPassword(value);
async onRedCommanderPasswordChanged(value) {
for (let input of this.activePage.getElement().querySelectorAll("input[type='password']")) {
input.placeholder = "";
}
if (this.getActiveInstance())
this.getActiveInstance().setRedCommanderPassword(value);
else
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${getManager().options.logLocation} for more info. </div>`);
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${this.getLogLocation()} for more info. </div>`);
}
/* When the client port input value is changed */
onClientPortChanged(value) {
async onClientPortChanged(value) {
this.setPort('client', Number(value));
}
/* When the backend port input value is changed */
onBackendPortChanged(value) {
async onBackendPortChanged(value) {
this.setPort('backend', Number(value));
}
/* When the "Enable API connection" checkbox is clicked */
onEnableAPIClicked() {
if (this.options.activeInstance) {
if (this.options.activeInstance.backendAddress === 'localhost') {
this.options.activeInstance.backendAddress = '*';
async onEnableAPIClicked() {
if (this.getActiveInstance()) {
if (this.getActiveInstance().backendAddress === 'localhost') {
this.getActiveInstance().backendAddress = '*';
} else {
this.options.activeInstance.backendAddress = 'localhost';
this.getActiveInstance().backendAddress = 'localhost';
}
if (this.options.mode === 'basic') {
this.connectionsPage.getElement().querySelector(".note.warning").classList.toggle("hide", this.options.activeInstance.backendAddress !== '*')
this.connectionsPage.getElement().querySelector(".backend-address .checkbox").classList.toggle("checked", this.options.activeInstance.backendAddress === '*')
if (this.getMode() === 'basic') {
this.connectionsPage.getElement().querySelector(".note.warning").classList.toggle("hide", this.getActiveInstance().backendAddress !== '*')
this.connectionsPage.getElement().querySelector(".backend-address .checkbox").classList.toggle("checked", this.getActiveInstance().backendAddress === '*')
} else {
this.expertSettingsPage.getElement().querySelector(".backend-address .checkbox").classList.toggle("checked", this.options.activeInstance.backendAddress === '*')
this.expertSettingsPage.getElement().querySelector(".backend-address .checkbox").classList.toggle("checked", this.getActiveInstance().backendAddress === '*')
}
} else {
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${getManager().options.logLocation} for more info. </div>`)
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${this.getLogLocation()} for more info. </div>`)
}
}
@ -428,13 +461,13 @@ class Manager {
}
/* When the "Close manager" button is pressed */
onCloseManagerClicked() {
async onCloseManagerClicked() {
document.querySelector('.close').click();
}
async checkPorts() {
var clientPortFree = await this.options.activeInstance.checkClientPort();
var backendPortFree = await this.options.activeInstance.checkBackendPort();
var clientPortFree = await this.getActiveInstance().checkClientPort();
var backendPortFree = await this.getActiveInstance().checkBackendPort();
if (clientPortFree && backendPortFree) {
return true;
} else {
@ -444,15 +477,15 @@ class Manager {
}
async checkPasswords() {
if (this.options.activeInstance) {
if (this.options.activeInstance.installed && !this.options.activeInstance.arePasswordsEdited()) {
if (this.getActiveInstance()) {
if (this.getActiveInstance().installed && !this.getActiveInstance().arePasswordsEdited()) {
return true;
}
else {
if (!this.options.activeInstance.arePasswordsSet()) {
if (!this.getActiveInstance().arePasswordsSet()) {
showErrorPopup(`<div class='main-message'>Please, make sure all passwords are set!</div><div class='sub-message'>The role users will fulfill depends on the password they enter at login. </div>`);
return false;
} else if (!this.options.activeInstance.arePasswordsDifferent()) {
} else if (!this.getActiveInstance().arePasswordsDifferent()) {
showErrorPopup(`<div class='main-message'>Please, set different passwords! </div><div class='sub-message'>The role users will fulfill depends on the password they enter at login. </div>`);
return false;
} else {
@ -460,7 +493,7 @@ class Manager {
}
}
} else {
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${getManager().options.logLocation} for more info. </div>`)
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${this.getLogLocation()} for more info. </div>`)
return false;
}
}
@ -492,40 +525,38 @@ class Manager {
async onEditClicked(name) {
var instance = await this.getClickedInstance(name);
if (instance.webserverOnline || instance.backendOnline) {
showErrorPopup("<div class='main-message'>Error, the selected Olympus instance is currently active </div><div class='sub-message'> Please stop Olympus before editing 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 editing it! </div>")
} else {
this.options.activeInstance = instance;
this.options.operation = 'EDIT';
this.setActiveInstance(instance);
await this.setState('EDIT');
this.activePage.hide();
(this.options.mode === 'basic'? this.typePage: this.expertSettingsPage).show();
(this.getMode() === 'basic'? this.typePage: this.expertSettingsPage).show();
}
}
async onInstallClicked(name) {
var instance = await this.getClickedInstance(name);
this.options.activeInstance = instance;
this.options.operation = 'INSTALL';
this.options.singleInstance = false;
this.setActiveInstance(instance);
await this.setState('INSTALL');
this.activePage.hide();
(this.options.mode === 'basic'? this.typePage: this.expertSettingsPage).show();
(this.getMode() === 'basic'? this.typePage: this.expertSettingsPage).show();
}
async onUninstallClicked(name) {
var instance = await this.getClickedInstance(name);
this.options.activeInstance = instance;
this.options.operation = 'UNINSTALL';
this.setActiveInstance(instance);
await this.setState('UNINSTALL');
if (instance.webserverOnline || instance.backendOnline)
showErrorPopup("<div class='main-message'>Error, the selected Olympus instance is currently active </div><div class='sub-message'> Please stop Olympus 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
await instance.uninstall();
}
onLinkClicked(url) {
async onLinkClicked(url) {
exec(`start ${url}`);
}
onTextFileClicked(path) {
async onTextFileClicked(path) {
exec(`notepad "${path}"`);
}
@ -549,19 +580,19 @@ class Manager {
async setPort(port, value) {
var success;
if (port === 'client') {
success = await this.options.activeInstance.checkClientPort(value);
this.options.activeInstance.setClientPort(value);
success = await this.getActiveInstance().checkClientPort(value);
this.getActiveInstance().setClientPort(value);
}
else {
success = await this.options.activeInstance.checkBackendPort(value);
this.options.activeInstance.setBackendPort(value);
success = await this.getActiveInstance().checkBackendPort(value);
this.getActiveInstance().setBackendPort(value);
}
var successEls = (this.options.mode === 'basic'? this.connectionsPage: this.expertSettingsPage).getElement().querySelector(`.${port}-port`).querySelectorAll(".success");
var successEls = (this.getMode() === 'basic'? this.connectionsPage: this.expertSettingsPage).getElement().querySelector(`.${port}-port`).querySelectorAll(".success");
for (let i = 0; i < successEls.length; i++) {
successEls[i].classList.toggle("hide", !success);
}
var errorEls = (this.options.mode === 'basic'? this.connectionsPage: this.expertSettingsPage).getElement().querySelector(`.${port}-port`).querySelectorAll(".error");
var errorEls = (this.getMode() === 'basic'? this.connectionsPage: this.expertSettingsPage).getElement().querySelector(`.${port}-port`).querySelectorAll(".error");
for (let i = 0; i < errorEls.length; i++) {
errorEls[i].classList.toggle("hide", success);
}
@ -573,11 +604,11 @@ class Manager {
return data.ip;
}
updateInstances() {
async updateInstances() {
var instanceDivs = this.instancesPage.getElement().querySelectorAll(`.option`);
for (let i = 0; i < instanceDivs.length; i++) {
var instanceDiv = instanceDivs[i];
var instance = this.options.instances.find((instance) => { return instance.folder === instanceDivs[i].dataset.folder; })
var instance = this.getInstances().find((instance) => { return instance.folder === instanceDivs[i].dataset.folder; })
if (instance) {
instanceDiv.querySelector(".button.install").classList.toggle("hide", instance.installed);
instanceDiv.querySelector(".button.start").classList.toggle("hide", !instance.installed);
@ -614,10 +645,10 @@ class Manager {
await DCSInstance.reloadInstances();
this.options.installEnabled = true;
this.options.editEnabled = this.options.instances.find(instance => instance.installed);
this.options.editEnabled = this.getInstances().find(instance => instance.installed);
}
setLoadingProgress(message, percent) {
async setLoadingProgress(message, percent) {
document.querySelector("#loader .loading-message").innerHTML = message;
if (percent) {
var style = document.querySelector('#loader .loading-bar').style;
@ -625,13 +656,80 @@ class Manager {
}
}
hideLoadingPage() {
async hideLoadingPage() {
/* Hide the loading page */
document.getElementById("loader").style.opacity = "0%";
window.setTimeout(() => {
document.getElementById("loader").classList.add("hide");
}, 250);
}
async setActiveInstance(newActiveInstance) {
this.options.activeInstance = newActiveInstance;
}
async setAdditionalDCSInstances(newAdditionalDCSInstances) {
this.options.additionalDCSInstances = newAdditionalDCSInstances;
}
async setConfigLoaded(newConfigLoaded) {
this.options.configLoaded = newConfigLoaded;
}
async setInstances(newInstances) {
this.options.instances = newInstances;
}
async setIP(newIP) {
this.options.IP = newIP;
}
async setLogLocation(newLogLocation) {
this.options.logLocation = newLogLocation;
}
async setState(newState) {
this.options.state = newState;
await DCSInstance.reloadInstances();
if (newState === 'IDLE')
this.setActiveInstance(undefined);
}
/** Get the currently active instance, i.e. the instance that is being edited/installed/removed
*
* @returns The active instance
*/
getActiveInstance() {
return this.options.activeInstance;
}
getAdditionalDCSInstances() {
return this.options.additionalDCSInstances
}
getConfigLoaded() {
return this.options.configLoaded;
}
getInstances() {
return this.options.instances;
}
getIP() {
return this.options.IP;
}
getLogLocation() {
return this.options.logLocation;
}
getState() {
return this.options.state;
}
getMode() {
return this.options.mode;
}
}
module.exports = Manager;