mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Added config page and loading bars
This commit is contained in:
parent
1d38bd6fea
commit
613aed2d2b
@ -30,7 +30,7 @@
|
||||
<div id="connections-page">
|
||||
<div class="instructions">
|
||||
<div class="step">
|
||||
Step 3 of 4
|
||||
Step <%= singleInstance? "3": "4" %> of <%= singleInstance? "4": "5" %>
|
||||
</div>
|
||||
<div class="title">
|
||||
Manually set Olympus port and address settings
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<div>
|
||||
<div class="instructions">
|
||||
<div class="step">
|
||||
Step 2 of 4
|
||||
Step <%= singleInstance? "2": "3" %> of <%= singleInstance? "4": "5" %>
|
||||
</div>
|
||||
<div class="title">
|
||||
Do you want to set port and address settings?
|
||||
@ -15,10 +15,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="wizard-inputs">
|
||||
<div class="button radio auto selected" onclick="signal('onConnectionsTypeClicked', 'auto')">
|
||||
<div class="button radio auto <%= activeInstance.connectionsType === 'auto'? 'selected': '' %>" onclick="signal('onConnectionsTypeClicked', 'auto')">
|
||||
Auto apply settings
|
||||
</div>
|
||||
<div class="button radio manual" onclick="signal('onConnectionsTypeClicked', 'manual')">
|
||||
<div class="button radio manual <%= activeInstance.connectionsType !== 'auto'? 'selected': '' %>" onclick="signal('onConnectionsTypeClicked', 'manual')">
|
||||
Manually set
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<div>
|
||||
<div class="instructions">
|
||||
<div class="step">
|
||||
Step 1 of 4
|
||||
Step 1 of <%= singleInstance? "4": "5" %>
|
||||
</div>
|
||||
<div class="title">
|
||||
Which DCS instance you want to add Olympus to?
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<div id="passwords-page">
|
||||
<div class="instructions">
|
||||
<div class="step">
|
||||
Step 4 of 4
|
||||
Step <%= singleInstance? "4": "5" %> of <%= singleInstance? "4": "5" %>
|
||||
</div>
|
||||
<div class="title">
|
||||
Enter your passwords for Olympus
|
||||
|
||||
263
manager/ejs/settings.ejs
Normal file
263
manager/ejs/settings.ejs
Normal file
@ -0,0 +1,263 @@
|
||||
<style>
|
||||
#manager-settings .scroll-container {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
max-width: 100% !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#manager-settings .scrollable {
|
||||
display: flex;
|
||||
row-gap: 15px;
|
||||
column-gap: 15px;
|
||||
height: fit-content;
|
||||
width: 100%;
|
||||
flex-wrap: wrap;
|
||||
padding: 15px 40px;
|
||||
}
|
||||
|
||||
#manager-settings .option {
|
||||
background-color: var(--darkgray);
|
||||
width: 48%;
|
||||
color: white;
|
||||
display: flex;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
padding: 15px;
|
||||
align-items: center;
|
||||
border-radius: 5px;
|
||||
border-left: 5px solid var(--blue);
|
||||
flex-direction: column;
|
||||
row-gap: 25px;
|
||||
}
|
||||
|
||||
#manager-settings .option:not(.installed) {
|
||||
background-color: var(--background-disabled);
|
||||
}
|
||||
|
||||
#manager-settings .option:not(.installed) .info {
|
||||
opacity: 50%;
|
||||
}
|
||||
|
||||
#manager-settings .option:not(.installed) .server-data {
|
||||
opacity: 50%;
|
||||
}
|
||||
|
||||
#manager-settings .button.cancel {
|
||||
position: absolute;
|
||||
left: 110px;
|
||||
top: 130px;
|
||||
}
|
||||
|
||||
#manager-settings .server-data {
|
||||
display: flex;
|
||||
column-gap: 15px;
|
||||
row-gap: 5px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
#manager-settings .server-status {
|
||||
font-weight: 600;
|
||||
font-size: 15;
|
||||
display: flex;
|
||||
column-gap: 5px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#manager-settings .server-status::before {
|
||||
display: block;
|
||||
content: "";
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border-radius: 999px;
|
||||
background-color: var(--gray);
|
||||
}
|
||||
|
||||
#manager-settings .server-status.offline {
|
||||
color: var(--gray)
|
||||
}
|
||||
|
||||
#manager-settings .server-status.offline::before {
|
||||
background-color: var(--gray);
|
||||
}
|
||||
|
||||
#manager-settings .server-status.online {
|
||||
color: var(--green)
|
||||
}
|
||||
|
||||
#manager-settings .server-status.online::before {
|
||||
background-color: var(--green);
|
||||
}
|
||||
|
||||
#manager-settings .server-status.backend {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
#manager-settings .server-data-entry {
|
||||
display: flex;
|
||||
column-gap: 5px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#manager-settings .server-data-entry span:nth-child(2) {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
#manager-settings .server-data-entry span:nth-child(3) {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#manager-settings .instance-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#manager-settings .instance-info>span:nth-child(1) {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
#manager-settings .instance-info>span:nth-child(2) {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--lightgray);
|
||||
}
|
||||
|
||||
#manager-settings .instance-info>span:nth-child(2).installed {
|
||||
font-weight: 600;
|
||||
color: var(--green);
|
||||
}
|
||||
|
||||
#manager-settings .instance-info>span:nth-child(2).error {
|
||||
font-weight: 600;
|
||||
color: orange;
|
||||
}
|
||||
|
||||
#manager-settings .instance-info>span:nth-child(3) {
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
color: var(--lightgray);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 8px;
|
||||
}
|
||||
|
||||
#manager-settings .instance-info>span:nth-child(4) {
|
||||
display: flex;
|
||||
column-gap: 10px;
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#manager-settings .instance-buttons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
column-gap: 10px;
|
||||
}
|
||||
|
||||
#manager-settings .instance-info .info {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#manager-settings .instance-info .info>div:nth-child(1) {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#manager-settings .instance-info .info>div:nth-child(2) {
|
||||
font-weight: normal;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#manager-settings .instance-info .divider {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
#manager-settings .start, #manager-settings .open-browser {
|
||||
margin-right: auto;
|
||||
color: var(--offwhite);
|
||||
background-color: var(--blue);
|
||||
}
|
||||
|
||||
#manager-settings .start {
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
#manager-settings .start>div {
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
#manager-settings .edit,
|
||||
#manager-settings .install,
|
||||
#manager-settings .uninstall,
|
||||
#manager-settings .stop {
|
||||
color: var(--offwhite);
|
||||
background-color: transparent;
|
||||
border: 1px solid var(--offwhite);
|
||||
}
|
||||
|
||||
#manager-settings .edit:hover,
|
||||
#manager-settings .install:hover,
|
||||
#manager-settings .uninstall:hover,
|
||||
#manager-settings .stop:hover {
|
||||
color: var(--background);
|
||||
background-color: var(--offwhite);
|
||||
}
|
||||
|
||||
#manager-settings .install {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
</style>
|
||||
<div id="manager-settings" style="margin-bottom: 10px;">
|
||||
<div class="content">
|
||||
<div class="instructions" style="display: flex; flex-direction: column; row-gap: 10px; align-items: center; padding: 20px;">
|
||||
<span style="color: var(--offwhite); font-size: 18px; font-weight: 600;">
|
||||
View and manage installs
|
||||
</span>
|
||||
<span style="color: var(--offwhite); font-size: 14px; text-align: center;">
|
||||
The following DCS installations have been identified. <br>You can modify settings and uninstall below.
|
||||
</span>
|
||||
</div>
|
||||
<div class="scroll-container">
|
||||
<div class="scrollable">
|
||||
<% for (let i = 0; i < instances.length; i++) {%>
|
||||
<% if (instances[i].installed) { %>
|
||||
<div class="option <%= instances[i].installed? 'installed': '' %>" data-folder="<%= instances[i].folder %>">
|
||||
<div class="instance-info">
|
||||
<span><%= instances[i].name %></span>
|
||||
<span><img src="./icons/folder-open-solid.svg"> <%= instances[i].folder %></span>
|
||||
<div class="divider"></div>
|
||||
<div style="display: flex; flex-direction: column; row-gap: 5px;">
|
||||
<div class="info">
|
||||
<div>Client port</div>
|
||||
<div> <%= instances[i].installed? instances[i].clientPort: "N/A" %> </div>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div>Backend port</div>
|
||||
<div> <%= instances[i].installed? instances[i].backendPort: "N/A" %> </div>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div>Backend address</div>
|
||||
<div> <%= instances[i].installed? instances[i].backendAddress: "N/A" %> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="instance-buttons">
|
||||
<div class="button edit" onclick="signal('onEditClicked', '<%= instances[i].name %>')">Edit settings</div>
|
||||
<div class="button uninstall" onclick="signal('onUninstallClicked', '<%= instances[i].name %>')">Uninstall Olympus</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -4,7 +4,7 @@
|
||||
<div>
|
||||
<div class="instructions">
|
||||
<div class="step">
|
||||
Step 1 of 4
|
||||
Step <%= singleInstance? "1": "2" %> of <%= singleInstance? "4": "5" %>
|
||||
</div>
|
||||
<div class="title">
|
||||
Do you want to add Olympus for singleplayer or multiplayer?
|
||||
@ -15,10 +15,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="wizard-inputs">
|
||||
<div class="button radio singleplayer selected" onclick="signal('onInstallTypeClicked', 'singleplayer')">
|
||||
<div class="button radio singleplayer <%= activeInstance.installationType === 'singleplayer'? 'selected': '' %>" onclick="signal('onInstallTypeClicked', 'singleplayer')">
|
||||
Singleplayer
|
||||
</div>
|
||||
<div class="button radio multiplayer" onclick="signal('onInstallTypeClicked', 'multiplayer')">
|
||||
<div class="button radio multiplayer <%= activeInstance.installationType !== 'singleplayer'? 'selected': '' %>" onclick="signal('onInstallTypeClicked', 'multiplayer')">
|
||||
Multiplayer
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
flex-direction: column;
|
||||
row-gap: 30px;
|
||||
padding: 60px 120px;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.buttons-footer {
|
||||
@ -34,6 +35,11 @@
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.content {
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.content > div {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
@ -37,7 +37,9 @@
|
||||
<div class="link" onclick="signal('reload')">Debug reload</div>
|
||||
</div>
|
||||
<div id="loader" class="manager-page hide">
|
||||
Loading, please wait...
|
||||
<div style="font-weight: bold;">Loading, please wait...</div>
|
||||
<div class="loading-bar" style="width: 400px; height: 15px;"></div>
|
||||
<div class="loading-message" style="font-size: 14px; color: var(--lightgray)"></div>
|
||||
</div>
|
||||
<div id="grayout" class="hide"></div>
|
||||
<div id="popup" class="hide">
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
const { getManager } = require('./managerfactory')
|
||||
var regedit = require('regedit')
|
||||
var regedit = require('regedit').promisified;
|
||||
const shellFoldersKey = 'HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders'
|
||||
const saveGamesKey = '{4C5C32FF-BB9D-43B0-B5B4-2D72E54EAAA4}'
|
||||
var fs = require('fs')
|
||||
@ -9,7 +9,7 @@ const dircompare = require('dir-compare');
|
||||
const { spawn } = require('child_process');
|
||||
const find = require('find-process');
|
||||
const { uninstallInstance, installHooks, installMod, installJSON, applyConfiguration, installShortCuts } = require('./filesystem')
|
||||
const { showErrorPopup, showConfirmPopup, showWaitPopup } = require('./popup')
|
||||
const { showErrorPopup, showConfirmPopup } = require('./popup')
|
||||
const { logger } = require("./filesystem")
|
||||
const { hidePopup } = require('./popup')
|
||||
|
||||
@ -21,47 +21,50 @@ class DCSInstance {
|
||||
*/
|
||||
static async getInstances() {
|
||||
if (this.instances === null) {
|
||||
this.instances = await this.findInstances();
|
||||
var ans = this.findInstances();
|
||||
console.log(ans)
|
||||
return this.findInstances();
|
||||
}
|
||||
return this.instances;
|
||||
else
|
||||
return DCSInstance.instances;
|
||||
}
|
||||
|
||||
/** Static asynchronous method to find all existing DCS instances
|
||||
*
|
||||
*/
|
||||
static async findInstances() {
|
||||
let promise = new Promise((res, rej) => {
|
||||
/* Get the Saved Games folder from the registry */
|
||||
regedit.list(shellFoldersKey, function (err, result) {
|
||||
if (err) {
|
||||
rej(err);
|
||||
/* Get the Saved Games folder from the registry */
|
||||
getManager().setLoadingProgress("Finding DCS instances...");
|
||||
|
||||
var result = await regedit.list(shellFoldersKey);
|
||||
/* 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) {
|
||||
/* Read all the folders in Saved Games */
|
||||
const searchpath = result[shellFoldersKey]['values'][saveGamesKey]['value'];
|
||||
const folders = fs.readdirSync(searchpath);
|
||||
var instances = [];
|
||||
|
||||
/* 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(searchpath, folder, "Config", "appsettings.lua")) ||
|
||||
fs.existsSync(path.join(searchpath, folder, "Config", "serversettings.lua"))) {
|
||||
logger.log(`Found instance in ${folder}, checking for Olympus`)
|
||||
getManager().setLoadingProgress(`Found instance in ${folder}, checking for Olympus...`, (i + 1) / folders.length * 100);
|
||||
var newInstance = new DCSInstance(path.join(searchpath, folder));
|
||||
await newInstance.checkInstallation();
|
||||
instances.push(newInstance);
|
||||
}
|
||||
else {
|
||||
/* 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) {
|
||||
/* Read all the folders in Saved Games */
|
||||
const searchpath = result[shellFoldersKey]['values'][saveGamesKey]['value'];
|
||||
const folders = fs.readdirSync(searchpath);
|
||||
var instances = [];
|
||||
}
|
||||
|
||||
/* A DCS Instance is created if either the appsettings.lua or serversettings.lua file is detected */
|
||||
folders.forEach((folder) => {
|
||||
if (fs.existsSync(path.join(searchpath, folder, "Config", "appsettings.lua")) ||
|
||||
fs.existsSync(path.join(searchpath, folder, "Config", "serversettings.lua"))) {
|
||||
instances.push(new DCSInstance(path.join(searchpath, folder)));
|
||||
}
|
||||
})
|
||||
DCSInstance.instances = instances;
|
||||
} else {
|
||||
logger.error("An error occured while trying to fetch the location of the DCS instances.")
|
||||
Promise.reject("An error occured while trying to fetch the location of the DCS instances.");
|
||||
}
|
||||
getManager().setLoadingProgress(`All DCS instances found!`, 100);
|
||||
|
||||
res(instances);
|
||||
} else {
|
||||
logger.error("An error occured while trying to fetch the location of the DCS instances.")
|
||||
rej("An error occured while trying to fetch the location of the DCS instances.");
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
return promise;
|
||||
return instances;
|
||||
}
|
||||
|
||||
folder = "";
|
||||
@ -90,11 +93,20 @@ class DCSInstance {
|
||||
this.folder = folder;
|
||||
this.name = path.basename(folder);
|
||||
|
||||
/* Periodically "ping" Olympus to check if either the client or the backend are active */
|
||||
window.setInterval(async () => {
|
||||
await this.getData();
|
||||
getManager().updateInstances();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
async checkInstallation() {
|
||||
/* Check if the olympus.json file is detected. If true, Olympus is considered to be installed */
|
||||
if (fs.existsSync(path.join(folder, "Config", "olympus.json"))) {
|
||||
if (fs.existsSync(path.join(this.folder, "Config", "olympus.json"))) {
|
||||
getManager().setLoadingProgress(`Olympus installed in ${this.folder}`);
|
||||
try {
|
||||
/* Read the olympus.json */
|
||||
var config = JSON.parse(fs.readFileSync(path.join(folder, "Config", "olympus.json")));
|
||||
var config = JSON.parse(fs.readFileSync(path.join(this.folder, "Config", "olympus.json")));
|
||||
this.clientPort = config["client"]["port"];
|
||||
this.backendPort = config["server"]["port"];
|
||||
this.backendAddress = config["server"]["address"];
|
||||
@ -115,8 +127,12 @@ class DCSInstance {
|
||||
var res1;
|
||||
var res2;
|
||||
try {
|
||||
res1 = dircompare.compareSync(path.join("..", "mod"), path.join(folder, "Mods", "Services", "Olympus"), options);
|
||||
res2 = dircompare.compareSync(path.join("..", "scripts", "OlympusHook.lua"), path.join(folder, "Scripts", "Hooks", "OlympusHook.lua"), options);
|
||||
logger.log(`Comparing Mods content in ${this.folder}`)
|
||||
getManager().setLoadingProgress(`Comparing Mods content in ${this.folder}`);
|
||||
res1 = await dircompare.compare(path.join("..", "mod"), path.join(this.folder, "Mods", "Services", "Olympus"), options);
|
||||
logger.log(`Comparing Scripts content in ${this.folder}`)
|
||||
getManager().setLoadingProgress(`Comparing Scripts content in ${this.folder}`);
|
||||
res2 = await dircompare.compareSync(path.join("..", "scripts", "OlympusHook.lua"), path.join(this.folder, "Scripts", "Hooks", "OlympusHook.lua"), options);
|
||||
err1 = res1.differences !== 0;
|
||||
err2 = res2.differences !== 0;
|
||||
} catch (e) {
|
||||
@ -125,14 +141,13 @@ class DCSInstance {
|
||||
|
||||
if (err1 || err2) {
|
||||
this.error = true;
|
||||
getManager().setLoadingProgress(`Differences found in ${this.folder}`);
|
||||
logger.log("Differences found!")
|
||||
} else {
|
||||
getManager().setLoadingProgress(`No differences found in ${this.folder}`);
|
||||
}
|
||||
}
|
||||
|
||||
/* Periodically "ping" Olympus to check if either the client or the backend are active */
|
||||
window.setInterval(async () => {
|
||||
await this.getData();
|
||||
getManager().updateInstances();
|
||||
}, 1000);
|
||||
return this.error;
|
||||
}
|
||||
|
||||
/** Asynchronously set the client port
|
||||
@ -197,7 +212,7 @@ class DCSInstance {
|
||||
/** Check if the client port is free
|
||||
*
|
||||
*/
|
||||
async checkClientPort(port) {
|
||||
checkClientPort(port) {
|
||||
var promise = new Promise((res, rej) => {
|
||||
checkPort(port, async (portFree) => {
|
||||
if (portFree) {
|
||||
@ -229,7 +244,7 @@ class DCSInstance {
|
||||
/** Check if the backend port is free
|
||||
*
|
||||
*/
|
||||
async checkBackendPort(port) {
|
||||
checkBackendPort(port) {
|
||||
var promise = new Promise((res, rej) => {
|
||||
checkPort(port, async (portFree) => {
|
||||
if (portFree) {
|
||||
@ -356,29 +371,30 @@ class DCSInstance {
|
||||
}
|
||||
|
||||
/* Install this instance */
|
||||
install() {
|
||||
install() {
|
||||
getManager().setPopupLoadingProgress("Installing hook scripts...", 0)
|
||||
installHooks(getManager().getActiveInstance().folder).then(
|
||||
() => {},
|
||||
() => {getManager().setPopupLoadingProgress("Installing mod folder...", 20) },
|
||||
(err) => {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
).then(() => installMod(getManager().getActiveInstance().folder, getManager().getActiveInstance().name)).then(
|
||||
() => {},
|
||||
() => {getManager().setPopupLoadingProgress("Installing JSON file...", 40) },
|
||||
(err) => {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
).then(() => installJSON(getManager().getActiveInstance().folder)).then(
|
||||
() => {},
|
||||
() => {getManager().setPopupLoadingProgress("Applying configuration...", 60) },
|
||||
(err) => {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
).then(() => applyConfiguration(getManager().getActiveInstance().folder, getManager().getActiveInstance())).then(
|
||||
() => {},
|
||||
() => {getManager().setPopupLoadingProgress("Creating shortcuts...", 80) },
|
||||
(err) => {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
).then(() => installShortCuts(getManager().getActiveInstance().folder, getManager().getActiveInstance().name)).then(
|
||||
() => {},
|
||||
() => {getManager().setPopupLoadingProgress("Installation completed!", 100) },
|
||||
(err) => {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ async function fixInstances(instances) {
|
||||
*/
|
||||
async function uninstallInstance(folder, name) {
|
||||
logger.log(`Uninstalling Olympus from ${folder}`)
|
||||
showWaitPopup("Please wait while the Olympus installation is being uninstalled.")
|
||||
showWaitPopup("Please wait while the Olympus installation is being removed.")
|
||||
var promise = new Promise((res, rej) => {
|
||||
deleteMod(folder, name)
|
||||
.then(() => deleteHooks(folder), (err) => { return Promise.reject(err); })
|
||||
|
||||
@ -19,6 +19,7 @@ class Manager {
|
||||
|
||||
activePage = null;
|
||||
welcomePage = null;
|
||||
settingsPage = null;
|
||||
folderPage = null;
|
||||
typePage = null;
|
||||
connectionsTypePage = null;
|
||||
@ -73,64 +74,81 @@ class Manager {
|
||||
}
|
||||
|
||||
/* Get the list of DCS instances */
|
||||
this.options.instances = await DCSInstance.getInstances();
|
||||
this.setLoadingProgress("Retrieving DCS instances...", 0);
|
||||
DCSInstance.getInstances().then((instances) => {
|
||||
this.setLoadingProgress(`Analysis completed, starting manager!`, 100);
|
||||
|
||||
/* Get my public IP */
|
||||
this.getPublicIP().then(
|
||||
(ip) => {
|
||||
this.options.ip = ip;
|
||||
},
|
||||
() => {
|
||||
this.options.ip = undefined;
|
||||
this.options.instances = instances;
|
||||
|
||||
/* Get my public IP */
|
||||
this.getPublicIP().then(
|
||||
(ip) => {
|
||||
this.options.ip = ip;
|
||||
},
|
||||
() => {
|
||||
this.options.ip = undefined;
|
||||
}
|
||||
)
|
||||
|
||||
/* Check if there are corrupted or outdate instances */
|
||||
if (this.options.instances.some((instance) => {
|
||||
return instance.installed && instance.error;
|
||||
})) {
|
||||
/* Ask the user for confirmation */
|
||||
showConfirmPopup("<div style='font-size: 18px; max-width: 100%;'>One or more of your Olympus instances are not up to date! </div> <br> <br> If you have just updated Olympus this is normal. <br> <br> Press Accept and the Manager will fix your instances for you. <br> Press Close to update your instances manually using the Installation Wizard", async () => {
|
||||
showWaitPopup("Please wait while your instances are being fixed.")
|
||||
fixInstances(this.options.instances.filter((instance) => {
|
||||
return instance.installed && instance.error;
|
||||
})).then(
|
||||
() => { location.reload() },
|
||||
(err) => {
|
||||
logger.error(err);
|
||||
showErrorPopup(`An error occurred while trying to fix your installations. Please reinstall Olympus manually. <br><br> You can find more info in ${path.join(__dirname, "..", "manager.log")}`);
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
/* Check if there are corrupted or outdate instances */
|
||||
if (this.options.instances.some((instance) => {
|
||||
return instance.installed && instance.error;
|
||||
})) {
|
||||
/* Ask the user for confirmation */
|
||||
showConfirmPopup("<div style='font-size: 18px; max-width: 100%;'>One or more of your Olympus instances are not up to date! </div> <br> <br> If you have just updated Olympus this is normal. <br> <br> Press Accept and the Manager will fix your instances for you. <br> Press Close to update your instances manually using the Installation Wizard", async () => {
|
||||
showWaitPopup("Please wait while your instances are being fixed.")
|
||||
fixInstances(this.options.instances.filter((instance) => {
|
||||
return instance.installed && instance.error;
|
||||
})).then(
|
||||
() => { location.reload() },
|
||||
(err) => {
|
||||
logger.error(err);
|
||||
showErrorPopup(`An error occurred while trying to fix your installations. Please reinstall Olympus manually. <br><br> You can find more info in ${path.join(__dirname, "..", "manager.log")}`);
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
this.options.installEnabled = true;
|
||||
this.options.editEnabled = this.options.instances.find(instance => instance.installed);
|
||||
this.options.uninstallEnabled = this.options.instances.find(instance => instance.installed);
|
||||
|
||||
this.options.installEnabled = true;
|
||||
this.options.editEnabled = this.options.instances.find(instance => instance.installed);
|
||||
this.options.uninstallEnabled = this.options.instances.find(instance => instance.installed);
|
||||
/* Hide the loading page */
|
||||
document.getElementById("loader").classList.add("hide");
|
||||
|
||||
/* Hide the loading page */
|
||||
document.getElementById("loader").classList.add("hide");
|
||||
this.options.singleInstance = this.options.instances.length === 1;
|
||||
|
||||
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");
|
||||
|
||||
/* Create all the HTML pages */
|
||||
this.menuPage = new ManagerPage(this, "./ejs/menu.ejs");
|
||||
this.folderPage = new WizardPage(this, "./ejs/folder.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");
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
/* Send an event on manager started */
|
||||
document.dispatchEvent(new CustomEvent("managerStarted"));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,40 +195,39 @@ class Manager {
|
||||
|
||||
/* Show the type selection page */
|
||||
if (!this.options.activeInstance.installed) {
|
||||
this.menuPage.hide();
|
||||
this.activePage.hide()
|
||||
this.typePage.show();
|
||||
} else {
|
||||
showConfirmPopup("<div style='font-size: 18px; max-width: 100%; margin-bottom: 8px;'> Olympus is already installed in this instance! </div> 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?",
|
||||
() => {
|
||||
this.menuPage.hide();
|
||||
this.activePage.hide()
|
||||
this.typePage.show();
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
/* Show the folder selection page */
|
||||
this.menuPage.hide();
|
||||
this.activePage.hide()
|
||||
this.folderPage.show();
|
||||
}
|
||||
}
|
||||
|
||||
/* When the edit button is clicked go to the instances page */
|
||||
onEditMenuClicked() {
|
||||
this.instancesPage.hide();
|
||||
this.activePage.hide()
|
||||
this.options.install = false;
|
||||
|
||||
if (this.options.singleInstance) {
|
||||
this.options.activeInstance = this.options.instances[0];
|
||||
this.typePage.show();
|
||||
} else {
|
||||
this.folderPage.show();
|
||||
this.settingsPage.show();
|
||||
}
|
||||
}
|
||||
|
||||
onFolderClicked(name) {
|
||||
this.getClickedInstance(name).then((instance) => {
|
||||
var instanceDivs = this.folderPage.getElement().querySelectorAll(".button.radio");
|
||||
console.log(instanceDivs);
|
||||
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)
|
||||
@ -257,8 +274,6 @@ class Manager {
|
||||
else {
|
||||
this.activePage.hide();
|
||||
this.connectionsPage.show();
|
||||
this.setPort('client', this.options.activeInstance.clientPort);
|
||||
this.setPort('backend', this.options.activeInstance.backendPort);
|
||||
this.connectionsPage.getElement().querySelector(".backend-address .checkbox").classList.toggle("checked", this.options.activeInstance.backendAddress === '*')
|
||||
}
|
||||
} else {
|
||||
@ -267,8 +282,6 @@ class Manager {
|
||||
} else if (this.activePage == this.connectionsPage) {
|
||||
this.options.activeInstance.checkClientPort(this.options.activeInstance.clientPort).then(
|
||||
(portFree) => {
|
||||
console.log(this.options.activeInstance.clientPort)
|
||||
console.log(portFree)
|
||||
if (portFree) {
|
||||
return this.options.activeInstance.checkBackendPort(this.options.activeInstance.backendPort);
|
||||
} else {
|
||||
@ -289,8 +302,8 @@ class Manager {
|
||||
if (this.options.activeInstance) {
|
||||
if (this.options.activeInstance.installed && !this.options.activeInstance.arePasswordsEdited()) {
|
||||
this.activePage.hide();
|
||||
showWaitPopup(`<span>Please wait while Olympus is being installed in <i>${this.options.activeInstance.name}</i></span><div class="loading-bar" style="width: 100%; height: 10px;"></div><div class="loading-message" style="font-weight: normal; text-align: center;"></div>`);
|
||||
this.options.activeInstance.install();
|
||||
showWaitPopup(`<span>Please wait while Olympus is being installed in <i>${this.options.activeInstance.name}</i></span>`);
|
||||
}
|
||||
else {
|
||||
if (!this.options.activeInstance.arePasswordsSet()) {
|
||||
@ -299,8 +312,8 @@ class Manager {
|
||||
showErrorPopup('Please, set different passwords for the Game Master, Blue Commander, and Red Commander roles!');
|
||||
} else {
|
||||
this.activePage.hide();
|
||||
showWaitPopup(`<span>Please wait while Olympus is being installed in <i>${this.options.activeInstance.name}</i></span><div class="loading-bar" style="width: 100%; height: 10px;"></div><div class="loading-message" style="font-weight: normal; text-align: center;"></div>`);
|
||||
this.options.activeInstance.install();
|
||||
showWaitPopup(`<span>Please wait while Olympus is being installed in <i>${this.options.activeInstance.name}</i></span>`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -415,7 +428,7 @@ class Manager {
|
||||
showErrorPopup("Error, the selected Olympus instance is currently active, please stop Olympus before editing it!")
|
||||
} else {
|
||||
this.options.activeInstance = instance;
|
||||
this.instancesPage.hide();
|
||||
this.activePage.hide();
|
||||
this.typePage.show();
|
||||
}
|
||||
});
|
||||
@ -426,7 +439,7 @@ class Manager {
|
||||
this.options.activeInstance = instance;
|
||||
this.options.install = true;
|
||||
this.options.singleInstance = false;
|
||||
this.instancesPage.hide();
|
||||
this.activePage.hide();
|
||||
this.typePage.show();
|
||||
});
|
||||
}
|
||||
@ -447,13 +460,10 @@ class Manager {
|
||||
|
||||
async getClickedInstanceDiv(name) {
|
||||
var instance = await this.getClickedInstance(name);
|
||||
console.log(instance)
|
||||
var instanceDivs = this.instancesPage.getElement().querySelectorAll(`.option`);
|
||||
for (let i = 0; i < instanceDivs.length; i++) {
|
||||
var instanceDiv = instanceDivs[i];
|
||||
console.log(instanceDiv.dataset.folder)
|
||||
if (instanceDiv.dataset.folder === instance.folder) {
|
||||
console.log(instanceDiv)
|
||||
return instanceDiv;
|
||||
}
|
||||
}
|
||||
@ -525,9 +535,24 @@ class Manager {
|
||||
}
|
||||
|
||||
reload() {
|
||||
console.log("reload")
|
||||
this.activePage.show();
|
||||
}
|
||||
|
||||
setLoadingProgress(message, percent) {
|
||||
document.querySelector("#loader .loading-message").innerHTML = message;
|
||||
if (percent) {
|
||||
var style = document.querySelector('#loader .loading-bar').style;
|
||||
style.setProperty('--percent', `${percent}%`);
|
||||
}
|
||||
}
|
||||
|
||||
setPopupLoadingProgress(message, percent) {
|
||||
document.querySelector("#popup .loading-message").innerHTML = message;
|
||||
if (percent) {
|
||||
var style = document.querySelector('#popup .loading-bar').style;
|
||||
style.setProperty('--percent', `${percent}%`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Manager;
|
||||
@ -33,6 +33,9 @@ class ManagerPage {
|
||||
|
||||
this.previousPage = ignorePreviousPage ? this.previousPage : this.manager.activePage;
|
||||
this.manager.activePage = this;
|
||||
|
||||
if (this.options.onShow)
|
||||
this.options.onShow();
|
||||
}
|
||||
|
||||
hide() {
|
||||
|
||||
@ -258,12 +258,8 @@ contextBridge.exposeInMainWorld(
|
||||
|
||||
/* On content loaded */
|
||||
window.addEventListener('DOMContentLoaded', async () => {
|
||||
/* Compute the height of the content page */
|
||||
computePagesHeight();
|
||||
document.getElementById("loader").classList.remove("hide");
|
||||
await getManager().start();
|
||||
/* Compute the height of the content page to account for the pages created by the manager*/
|
||||
computePagesHeight();
|
||||
|
||||
/* Create event listeners for the hyperlinks */
|
||||
var links = document.querySelectorAll(".link");
|
||||
@ -278,6 +274,17 @@ window.addEventListener('DOMContentLoaded', async () => {
|
||||
})
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
/* Compute the height of the content page */
|
||||
computePagesHeight();
|
||||
})
|
||||
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
/* Compute the height of the content page */
|
||||
computePagesHeight();
|
||||
})
|
||||
|
||||
document.addEventListener('managerStarted', () => {
|
||||
/* Compute the height of the content page */
|
||||
computePagesHeight();
|
||||
})
|
||||
|
||||
|
||||
@ -152,6 +152,22 @@ body {
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
row-gap: 10px;
|
||||
}
|
||||
|
||||
.loading-bar {
|
||||
border: 1px solid var(--offwhite);
|
||||
border-radius: 2px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.loading-bar::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: var(--percent);
|
||||
background-color: var(--offwhite);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
@ -298,6 +314,9 @@ input {
|
||||
padding: 15px 0px !important;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: 10px;
|
||||
}
|
||||
|
||||
#popup .footer {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user