From 92b1a46e8af10297d921c23e57ab06a0d39629f2 Mon Sep 17 00:00:00 2001 From: Pax1601 Date: Thu, 21 Dec 2023 18:06:59 +0100 Subject: [PATCH 1/3] Started wizard implementation --- manager/ejs/managerinstallations.ejs | 49 +++ manager/ejs/managermenu.ejs | 40 ++ manager/index.html | 14 +- manager/javascripts/filesystem.js | 115 ++++++ manager/javascripts/managerinstallations.js | 32 ++ manager/javascripts/managermenu.js | 23 ++ manager/javascripts/managerpage.js | 15 + manager/javascripts/net.js | 12 + manager/javascripts/old.js | 273 +++++++++++++ manager/javascripts/preload.js | 429 +------------------- manager/manager.js | 3 +- manager/stylesheets/style.css | 263 ++---------- 12 files changed, 613 insertions(+), 655 deletions(-) create mode 100644 manager/ejs/managerinstallations.ejs create mode 100644 manager/ejs/managermenu.ejs create mode 100644 manager/javascripts/filesystem.js create mode 100644 manager/javascripts/managerinstallations.js create mode 100644 manager/javascripts/managermenu.js create mode 100644 manager/javascripts/managerpage.js create mode 100644 manager/javascripts/net.js create mode 100644 manager/javascripts/old.js diff --git a/manager/ejs/managerinstallations.ejs b/manager/ejs/managerinstallations.ejs new file mode 100644 index 00000000..5cdb8b0e --- /dev/null +++ b/manager/ejs/managerinstallations.ejs @@ -0,0 +1,49 @@ + +
+ +
+ + Select the copies of DCS you want to install Olympus to. + + + For most people, this is your main DCS installation. + + + If you are running a dedicated server, you would also install Olympus to this DCS version. + +
+ <%= instances[0] %> + <% for (let i = 0; i < instances.length; i++) {%> +
+ <%= instances[i] %> +
+ <% } %> +
\ No newline at end of file diff --git a/manager/ejs/managermenu.ejs b/manager/ejs/managermenu.ejs new file mode 100644 index 00000000..21dc76ac --- /dev/null +++ b/manager/ejs/managermenu.ejs @@ -0,0 +1,40 @@ + +
+ +
+ Install Olympus +
+
+ Update/remove Olympus +
+
+ View and manage instances +
+
\ No newline at end of file diff --git a/manager/index.html b/manager/index.html index cb0091b1..8ff23a37 100644 --- a/manager/index.html +++ b/manager/index.html @@ -16,8 +16,8 @@
DCS Olympus manager
- - + +
-
- These are the DCS instances that the Olympus Manager has automatically detected in your system.
- You can install Olympus and manage your instances from here.
- Click on "Install Olympus to instance" to install Olympus. -
@@ -45,13 +40,13 @@ window.ipcRender.send('window:minimize'); }); - document.querySelector('.restore').addEventListener('click', () => { + /*document.querySelector('.restore').addEventListener('click', () => { window.ipcRender.send('window:restore'); }); document.querySelector('.maximize').addEventListener('click', () => { window.ipcRender.send('window:maximize'); - }); + });*/ document.querySelector('.close').addEventListener('click', () => { window.ipcRender.send('window:close'); @@ -66,7 +61,6 @@ document.querySelector('.restore').classList.add("hide"); document.querySelector('.maximize').classList.remove("hide"); }) - \ No newline at end of file diff --git a/manager/javascripts/filesystem.js b/manager/javascripts/filesystem.js new file mode 100644 index 00000000..0c0de091 --- /dev/null +++ b/manager/javascripts/filesystem.js @@ -0,0 +1,115 @@ +const sha256 = require('sha256') +const createShortcut = require('create-desktop-shortcuts'); + +export function installOlympus(folder) { + console.log(`Installing Olympus in ${folder}`); + try { + fs.cpSync(path.join("..", "mod"), path.join(folder, "Mods", "Services", "Olympus"), { recursive: true }); + fs.cpSync(path.join("..", "scripts", "OlympusHook.lua"), path.join(folder, "Scripts", "Hooks", "OlympusHook.lua")); + fs.cpSync(path.join("..", "olympus.json"), path.join(folder, "Config", "olympus.json")); + if (createShortcut({ + windows: { + filePath: path.resolve(__dirname, '..', '..', 'client', 'client.vbs'), + outputPath: folder, + name: "DCS Olympus Client", + arguments: `"${path.join(folder, "Config", "olympus.json")}"`, + icon: path.resolve(__dirname, '..', '..', 'img', 'olympus.ico'), + workingDirectory: path.resolve(__dirname, '..', '..', 'client') + } + }) && + createShortcut({ + windows: { + filePath: path.resolve(__dirname, '..', '..', 'client', 'server.vbs'), + outputPath: folder, + name: "DCS Olympus Server", + arguments: `"${path.join(folder, "Config", "olympus.json")}"`, + icon: path.resolve(__dirname, '..', '..', 'img', 'olympus_server.ico'), + workingDirectory: path.resolve(__dirname, '..', '..', 'client') + } + })) { + console.log("Shorcuts created succesfully") + } else { + return false; + } + } catch (e) { + console.error(e); + return false; + } + loadDivs(); + return true; +} + +export function uninstallOlympus(folder) { + console.log(`Uninstalling Olympus from ${folder}`); + try { + fs.rmSync(path.join(folder, "Mods", "Services", "Olympus"), { recursive: true, force: true }); + fs.rmSync(path.join(folder, "Config", "olympus.json"), {force: true}); + loadDivs(); + } catch (e) { + console.error(e); + return false; + } + return true; +} + +export function applyConfiguration(folder, data) { + console.log(`Applying configuration to Olympus from ${folder}`); + + if (fs.existsSync(path.join(folder, "Config", "olympus.json"))) { + var config = JSON.parse(fs.readFileSync(path.join(folder, "Config", "olympus.json"))); + + config["client"]["port"] = data["clientPort"]; + config["server"]["port"] = data["backendPort"]; + config["server"]["address"] = data["backendAddress"]; + config["authentication"]["gameMasterPassword"] = sha256(data["gameMasterPassword"]); + config["authentication"]["blueCommanderPassword"] = sha256(data["blueCommanderPassword"]); + config["authentication"]["redCommanderPassword"] = sha256(data["redCommanderPassword"]); + + try { + fs.writeFileSync(path.join(folder, "Config", "olympus.json"), JSON.stringify(config, null, 4)); + } catch (e) { + console.error(e); + return false; + } + } else { + return false; + } + return true; +} + +export function updateOlympus(folder) { + console.log(`Updating Olympus in ${folder}`); + try { + fs.cpSync(path.join("..", "mod"), path.join(folder, "Mods", "Services", "Olympus"), { recursive: true }); + fs.cpSync(path.join("..", "scripts", "OlympusHook.lua"), path.join(folder, "Scripts", "Hook", "OlympusHook.lua")); + loadDivs(); + } catch (e) { + console.error(e); + return false; + } + return true; +} + +export function createDesktopShortcuts(folder) { + if (createShortcut({ + windows: { + filePath: path.resolve(__dirname, '..', '..', 'client', 'client.vbs'), + name: "DCS Olympus Client", + arguments: `"${path.join(folder, "Config", "olympus.json")}"`, + icon: path.resolve(__dirname, '..', '..', 'img', 'olympus.ico'), + workingDirectory: path.resolve(__dirname, '..', '..', 'client') + } + }) && createShortcut({ + windows: { + filePath: path.resolve(__dirname, '..', '..', 'client', 'server.vbs'), + name: "DCS Olympus Server", + arguments: `"${path.join(folder, "Config", "olympus.json")}"`, + icon: path.resolve(__dirname, '..', '..', 'img', 'olympus_server.ico'), + workingDirectory: path.resolve(__dirname, '..', '..', 'client') + } + })) { + showPopup("Shortcuts created successfully!") + } else { + showPopup("And error occurred while creating the shortcuts.") + } +} \ No newline at end of file diff --git a/manager/javascripts/managerinstallations.js b/manager/javascripts/managerinstallations.js new file mode 100644 index 00000000..e448f281 --- /dev/null +++ b/manager/javascripts/managerinstallations.js @@ -0,0 +1,32 @@ +const ManagerPage = require("./managerpage"); +const ejs = require('ejs') + +class ManagerInstallations extends ManagerPage { + constructor(options) { + super(options); + + ejs.renderFile("./ejs/managerinstallations.ejs", options, {}, (err, str) => { + if (!err) { + this.render(str); + } else { + console.error(str); + } + }); + } + + render(str) { + const element = this.getElement(); + element.innerHTML = str; + + var options = element.querySelectorAll(".option"); + for (let i = 0; i < options.length; i++) { + options[i].onclick = (e) => {this.onOptionClicked(e);} + } + } + + onOptionClicked(e) { + e.target.classList.toggle("selected") + } +} + +module.exports = ManagerInstallations; \ No newline at end of file diff --git a/manager/javascripts/managermenu.js b/manager/javascripts/managermenu.js new file mode 100644 index 00000000..3ab7f035 --- /dev/null +++ b/manager/javascripts/managermenu.js @@ -0,0 +1,23 @@ +const ManagerPage = require("./managerpage"); +const ejs = require('ejs') + +class ManagerMenu extends ManagerPage { + constructor(options) { + super(options); + + ejs.renderFile("./ejs/managermenu.ejs", options, {}, (err, str) => { + if (!err) { + this.render(str); + } else { + console.error(str); + } + }); + } + + render(str) { + const element = this.getElement(); + element.innerHTML = str; + } +} + +module.exports = ManagerMenu; \ No newline at end of file diff --git a/manager/javascripts/managerpage.js b/manager/javascripts/managerpage.js new file mode 100644 index 00000000..848cd1f4 --- /dev/null +++ b/manager/javascripts/managerpage.js @@ -0,0 +1,15 @@ +class ManagerPage { + element; + + constructor(options) { + this.element = document.createElement('div'); + this.element.classList.add("manager-page"); + } + + getElement() { + return this.element; + } + +} + +module.exports = ManagerPage; \ No newline at end of file diff --git a/manager/javascripts/net.js b/manager/javascripts/net.js new file mode 100644 index 00000000..9b303f54 --- /dev/null +++ b/manager/javascripts/net.js @@ -0,0 +1,12 @@ +const portfinder = require('portfinder') + +export function checkPort(port, callback) { + portfinder.getPort({ port: port, stopPort: port }, (err, res) => { + if (err !== null) { + console.error(`Port ${port} already in use`); + callback(false); + } else { + callback(true); + } + }); +} diff --git a/manager/javascripts/old.js b/manager/javascripts/old.js new file mode 100644 index 00000000..49e09fb9 --- /dev/null +++ b/manager/javascripts/old.js @@ -0,0 +1,273 @@ + +function showPopup(message, otherButton, otherButtonCallback) { + var data = { + message: message, + otherButton: otherButton + }; + + var popups = document.querySelectorAll(".popup"); + + for (let i = 0; i < popups.length; i++) { + document.body.removeChild(popups[i]) + } + + ejs.renderFile("./ejs/popup.ejs", data, {}, (err, str) => { + var div = document.createElement("div"); + div.classList.add("popup"); + div.innerHTML = str; + document.body.appendChild(div); + + div.querySelector(".apply").addEventListener("click", () => { + document.body.removeChild(div); + }) + + div.querySelector(".other").addEventListener("click", () => { + otherButtonCallback(); + }) + }); +} + + +class InstanceDiv { + element = null; + parent = null; + folder = ""; + + constructor(parent, folder) { + this.element = parent; + this.folder = folder; + this.render(); + } + + render() { + this.element = document.createElement("div"); + + var data = { + folder: this.folder, + installed: false, + index: instanceDivs.length * 10 + }; + + var newVersionInfo = vi(path.join("..", "mod", "bin", "olympus.dll")); + data["newVersion"] = newVersionInfo.ProductVersion; + data["version"] = "n/a"; + + if (fs.existsSync(path.join(this.folder, "Config", "olympus.json"))) { + var config = JSON.parse(fs.readFileSync(path.join(this.folder, "Config", "olympus.json"))); + data = { + ...data, + ...config + } + data["installed"] = true; + + try { + data["version"] = vi(path.join(this.folder, "Mods", "Services", "Olympus", "bin", "olympus.dll")).ProductVersion; + } catch (e) { + data["version"] = "n/a"; + } + } + + ejs.renderFile("./ejs/instanceDiv.ejs", data, {}, (err, str) => { + this.element.innerHTML = str; + this.element.querySelector(".add").addEventListener("click", (e) => { + if (!e.srcElement.classList.contains("disabled")) { + showPopup("Please wait while Olympus is being installed"); + window.setTimeout(() => { + if (installOlympus(this.folder)) { + showPopup("Olympus installed successfully. Use the provided form to set Olympus properties. All fields are mandatory. Click on \"Create desktop shortcuts\" to generate Olympus shortcuts on your desktop.", "Create desktop shortcuts", () => { + createDesktopShortcuts(this.folder); + }); + } else { + showPopup("An error has occurred during installation"); + } + }, 100); + } + }); + + this.element.querySelector(".remove").addEventListener("click", (e) => { + if (!e.srcElement.classList.contains("disabled")) { + showPopup("Please wait while Olympus is being uninstalled from DCS instance"); + window.setTimeout(() => { + if (uninstallOlympus(this.folder)) { + showPopup("Olympus uninstalled successfully from DCS instance!"); + } else { + showPopup("An error has occurred during uninstallation"); + } + }, 100); + } + }); + + this.element.querySelector(".apply").addEventListener("click", (e) => { + e.srcElement.classList.remove("blink"); + if (!e.srcElement.classList.contains("disabled")) { + showPopup("Please wait while the configuration is being applied"); + window.setTimeout(() => { + if (applyConfiguration(this.folder, this.getFields())) { + showPopup("Olympus configuration applied successfully!"); + } else { + showPopup("An error has occurred while applying the configuration"); + } + }, 100) + } + }); + + this.element.querySelector(".update").addEventListener("click", (e) => { + if (!e.srcElement.classList.contains("disabled")) { + showPopup("Please wait while Olympus is being updated in the DCS instance"); + window.setTimeout(() => { + if (updateOlympus(this.folder)) { + showPopup("Olympus updated successfully from DCS instance!"); + } else { + showPopup("An error has occurred during the update"); + } + }, 100); + } + }); + + var inputs = this.element.querySelectorAll("input"); + for (let i = 0; i < inputs.length; i++) { + inputs[i].addEventListener("change", () => { + inputs[i].classList.remove("error"); + instanceDivs.forEach((instanceDiv) => instanceDiv.checkFields()) + }) + } + }); + } + + getDiv() { + return this.element; + } + + getFields() { + return { + clientPort: Number(this.element.querySelector("#client-port").value), + backendPort: Number(this.element.querySelector("#backend-port").value), + backendAddress: this.element.querySelector("#backend-address").value, + gameMasterPassword: this.element.querySelector("#game-master-password").value, + blueCommanderPassword: this.element.querySelector("#blue-commander-password").value, + redCommanderPassword: this.element.querySelector("#red-commander-password").value, + } + } + + checkFields() { + var data = this.getFields(); + + /* Clear existing errors */ + var inputs = this.element.querySelectorAll("input"); + for (let i = 0; i < inputs.length; i++) { + inputs[i].classList.remove("error"); + } + var messages = this.element.querySelectorAll(".error"); + for (let i = 0; i < messages.length; i++) { + messages[i].innerText = ""; + } + + /* Enable the button */ + this.element.querySelector(".apply").classList.remove("disabled"); + + if (data["clientPort"] !== 0 && data["backendPort"] !== 0) { + if (data["clientPort"] === data["backendPort"]) { + this.element.querySelector("#client-port").classList.add("error"); + this.element.querySelector("#client-port-error").innerText = "Ports must be different"; + this.element.querySelector("#backend-port").classList.add("error"); + this.element.querySelector("#backend-port-error").innerText = "Ports must be different"; + this.element.querySelector(".apply").classList.add("disabled"); + } + else { + checkPort(data["clientPort"], (res) => { + var otherInstanceUsesPort = instanceDivs.find((instanceDiv) => { + if (instanceDiv != this) { + var fields = instanceDiv.getFields(); + if (fields["clientPort"] === data["clientPort"] || fields["backendPort"] === data["clientPort"]) { + return true; + } + } + }) + + if (!res || otherInstanceUsesPort) { + this.element.querySelector("#client-port").classList.add("error"); + this.element.querySelector("#client-port-error").innerText = "Port already in use"; + this.element.querySelector(".apply").classList.add("disabled"); + } + }); + + checkPort(data["backendPort"], (res) => { + var otherInstanceUsesPort = instanceDivs.find((instanceDiv) => { + if (instanceDiv != this) { + var fields = instanceDiv.getFields(); + if (fields["clientPort"] === data["backendPort"] || fields["backendPort"] === data["backendPort"]) { + return true; + } + } + }) + + if (!res || otherInstanceUsesPort) { + this.element.querySelector("#backend-port").classList.add("error"); + this.element.querySelector("#backend-port-error").innerText = "Port already in use"; + this.element.querySelector(".apply").classList.add("disabled"); + } + }); + } + } + + if (data["gameMasterPassword"] !== "" && data["blueCommanderPassword"] !== "" && data["gameMasterPassword"] === data["blueCommanderPassword"]) { + this.element.querySelector("#game-master-password").classList.add("error"); + this.element.querySelector("#game-master-password-error").innerText = "Passwords must be different"; + this.element.querySelector("#blue-commander-password").classList.add("error"); + this.element.querySelector("#blue-commander-password-error").innerText = "Passwords must be different"; + this.element.querySelector(".apply").classList.add("disabled"); + } + + if (data["gameMasterPassword"] !== "" && data["redCommanderPassword"] !== "" && data["gameMasterPassword"] === data["redCommanderPassword"]) { + this.element.querySelector("#game-master-password").classList.add("error"); + this.element.querySelector("#game-master-password-error").innerText = "Passwords must be different"; + this.element.querySelector("#red-commander-password").classList.add("error"); + this.element.querySelector("#red-commander-password-error").innerText = "Passwords must be different"; + this.element.querySelector(".apply").classList.add("disabled"); + } + + if (data["blueCommanderPassword"] !== "" && data["redCommanderPassword"] !== "" && data["blueCommanderPassword"] === data["redCommanderPassword"]) { + this.element.querySelector("#blue-commander-password").classList.add("error"); + this.element.querySelector("#blue-commander-password-error").innerText = "Passwords must be different"; + this.element.querySelector("#red-commander-password").classList.add("error"); + this.element.querySelector("#red-commander-password-error").innerText = "Passwords must be different"; + this.element.querySelector(".apply").classList.add("disabled"); + } + + if (data["gameMasterPassword"] === "" || data["blueCommanderPassword"] === "" || data["redCommanderPassword"] === "") { + this.element.querySelector(".apply").classList.add("disabled"); + } + } +} + +function loadDivs() { + regedit.list(shellFoldersKey, function (err, result) { + if (err) { + console.log(err); + } + else { + if (result[shellFoldersKey] !== undefined && result[shellFoldersKey]["exists"] && result[shellFoldersKey]['values'][saveGamesKey] !== undefined && result[shellFoldersKey]['values'][saveGamesKey]['value'] !== undefined) { + const searchpath = result[shellFoldersKey]['values'][saveGamesKey]['value']; + const folders = fs.readdirSync(searchpath); + instanceDivs = []; + const mainDiv = document.getElementById("main-div"); + + folders.forEach((folder) => { + if (fs.existsSync(path.join(searchpath, folder, "Config", "appsettings.lua")) || + fs.existsSync(path.join(searchpath, folder, "Config", "serversettings.lua"))) { + instanceDivs.push(new InstanceDiv(mainDiv, path.join(searchpath, folder))); + } + }); + + mainDiv.replaceChildren(...instanceDivs.map((instanceDiv) => { + return instanceDiv.getDiv(); + })); + + instanceDivs.forEach((instanceDiv) => instanceDiv.checkFields()) + + } else { + console.error("An error occured while trying to fetch the location of the DCS folders.") + } + } + }) +} \ No newline at end of file diff --git a/manager/javascripts/preload.js b/manager/javascripts/preload.js index 38d6238a..607359b3 100644 --- a/manager/javascripts/preload.js +++ b/manager/javascripts/preload.js @@ -2,58 +2,59 @@ var regedit = require('regedit') var fs = require('fs') var path = require('path') const ejs = require('ejs') -const portfinder = require('portfinder') -const sha256 = require('sha256') + const contextBridge = require('electron').contextBridge; const ipcRenderer = require('electron').ipcRenderer; -const createShortcut = require('create-desktop-shortcuts'); + const vi = require('win-version-info'); +const ManagerMenu = require("./managermenu"); +const ManagerInstallations = require('./managerinstallations'); const shellFoldersKey = 'HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders' const saveGamesKey = '{4C5C32FF-BB9D-43B0-B5B4-2D72E54EAAA4}' var instanceDivs = []; -// White-listed channels. +/* White-listed channels. */ const ipc = { 'render': { - // From render to main. + /* From render to main. */ 'send': [ - 'window:minimize', // Channel names + 'window:minimize', 'window:maximize', 'window:restore', 'window:close' ], - // From main to render. + /* From main to render. */ 'receive': [ 'event:maximized', 'event:unmaximized' ], - // From render to main and back again. + /* From render to main and back again. */ 'sendReceive': [] } }; -// Exposed protected methods in the render process. +/* Exposed protected methods in the render process. */ contextBridge.exposeInMainWorld( - // Allowed 'ipcRenderer' methods. + /* Allowed 'ipcRenderer' methods. */ 'ipcRender', { - // From render to main. + /* From render to main. */ send: (channel, args) => { let validChannels = ipc.render.send; if (validChannels.includes(channel)) { ipcRenderer.send(channel, args); } }, - // From main to render. + /* From main to render. */ receive: (channel, listener) => { let validChannels = ipc.render.receive; if (validChannels.includes(channel)) { - // Deliberately strip event as it includes `sender`. + /* Deliberately strip event as it includes `sender`. */ ipcRenderer.on(channel, (event, ...args) => listener(...args)); } }, - // From render to main and back again. + /* From render to main and back again. */ invoke: (channel, args) => { let validChannels = ipc.render.sendReceive; if (validChannels.includes(channel)) { @@ -63,402 +64,10 @@ contextBridge.exposeInMainWorld( } ); -function showPopup(message, otherButton, otherButtonCallback) { - var data = { - message: message, - otherButton: otherButton - }; - - var popups = document.querySelectorAll(".popup"); - - for (let i = 0; i < popups.length; i++) { - document.body.removeChild(popups[i]) - } - - ejs.renderFile("./ejs/popup.ejs", data, {}, (err, str) => { - var div = document.createElement("div"); - div.classList.add("popup"); - div.innerHTML = str; - document.body.appendChild(div); - - div.querySelector(".apply").addEventListener("click", () => { - document.body.removeChild(div); - }) - - div.querySelector(".other").addEventListener("click", () => { - otherButtonCallback(); - }) - }); -} - -function checkPort(port, callback) { - portfinder.getPort({ port: port, stopPort: port }, (err, res) => { - if (err !== null) { - console.error(`Port ${port} already in use`); - callback(false); - } else { - callback(true); - } - }); -} - -function installOlympus(folder) { - console.log(`Installing Olympus in ${folder}`); - try { - fs.cpSync(path.join("..", "mod"), path.join(folder, "Mods", "Services", "Olympus"), { recursive: true }); - fs.cpSync(path.join("..", "scripts", "OlympusHook.lua"), path.join(folder, "Scripts", "Hooks", "OlympusHook.lua")); - fs.cpSync(path.join("..", "olympus.json"), path.join(folder, "Config", "olympus.json")); - if (createShortcut({ - windows: { - filePath: path.resolve(__dirname, '..', '..', 'client', 'client.vbs'), - outputPath: folder, - name: "DCS Olympus Client", - arguments: `"${path.join(folder, "Config", "olympus.json")}"`, - icon: path.resolve(__dirname, '..', '..', 'img', 'olympus.ico'), - workingDirectory: path.resolve(__dirname, '..', '..', 'client') - } - }) && - createShortcut({ - windows: { - filePath: path.resolve(__dirname, '..', '..', 'client', 'server.vbs'), - outputPath: folder, - name: "DCS Olympus Server", - arguments: `"${path.join(folder, "Config", "olympus.json")}"`, - icon: path.resolve(__dirname, '..', '..', 'img', 'olympus_server.ico'), - workingDirectory: path.resolve(__dirname, '..', '..', 'client') - } - })) { - console.log("Shorcuts created succesfully") - } else { - return false; - } - } catch (e) { - console.error(e); - return false; - } - loadDivs(); - return true; -} - -function uninstallOlympus(folder) { - console.log(`Uninstalling Olympus from ${folder}`); - try { - fs.rmSync(path.join(folder, "Mods", "Services", "Olympus"), { recursive: true, force: true }); - fs.rmSync(path.join(folder, "Config", "olympus.json"), {force: true}); - loadDivs(); - } catch (e) { - console.error(e); - return false; - } - return true; -} - -function applyConfiguration(folder, data) { - console.log(`Applying configuration to Olympus from ${folder}`); - - if (fs.existsSync(path.join(folder, "Config", "olympus.json"))) { - var config = JSON.parse(fs.readFileSync(path.join(folder, "Config", "olympus.json"))); - - config["client"]["port"] = data["clientPort"]; - config["server"]["port"] = data["backendPort"]; - config["server"]["address"] = data["backendAddress"]; - config["authentication"]["gameMasterPassword"] = sha256(data["gameMasterPassword"]); - config["authentication"]["blueCommanderPassword"] = sha256(data["blueCommanderPassword"]); - config["authentication"]["redCommanderPassword"] = sha256(data["redCommanderPassword"]); - - try { - fs.writeFileSync(path.join(folder, "Config", "olympus.json"), JSON.stringify(config, null, 4)); - } catch (e) { - console.error(e); - return false; - } - } else { - return false; - } - return true; -} - -function updateOlympus(folder) { - console.log(`Updating Olympus in ${folder}`); - try { - fs.cpSync(path.join("..", "mod"), path.join(folder, "Mods", "Services", "Olympus"), { recursive: true }); - fs.cpSync(path.join("..", "scripts", "OlympusHook.lua"), path.join(folder, "Scripts", "Hook", "OlympusHook.lua")); - loadDivs(); - } catch (e) { - console.error(e); - return false; - } - return true; -} - -function createDesktopShortcuts(folder) { - if (createShortcut({ - windows: { - filePath: path.resolve(__dirname, '..', '..', 'client', 'client.vbs'), - name: "DCS Olympus Client", - arguments: `"${path.join(folder, "Config", "olympus.json")}"`, - icon: path.resolve(__dirname, '..', '..', 'img', 'olympus.ico'), - workingDirectory: path.resolve(__dirname, '..', '..', 'client') - } - }) && createShortcut({ - windows: { - filePath: path.resolve(__dirname, '..', '..', 'client', 'server.vbs'), - name: "DCS Olympus Server", - arguments: `"${path.join(folder, "Config", "olympus.json")}"`, - icon: path.resolve(__dirname, '..', '..', 'img', 'olympus_server.ico'), - workingDirectory: path.resolve(__dirname, '..', '..', 'client') - } - })) { - showPopup("Shortcuts created successfully!") - } else { - showPopup("And error occurred while creating the shortcuts.") - } -} - -class InstanceDiv { - element = null; - parent = null; - folder = ""; - - constructor(parent, folder) { - this.element = parent; - this.folder = folder; - this.render(); - } - - render() { - this.element = document.createElement("div"); - - var data = { - folder: this.folder, - installed: false, - index: instanceDivs.length * 10 - }; - - var newVersionInfo = vi(path.join("..", "mod", "bin", "olympus.dll")); - data["newVersion"] = newVersionInfo.ProductVersion; - data["version"] = "n/a"; - - if (fs.existsSync(path.join(this.folder, "Config", "olympus.json"))) { - var config = JSON.parse(fs.readFileSync(path.join(this.folder, "Config", "olympus.json"))); - data = { - ...data, - ...config - } - data["installed"] = true; - - try { - data["version"] = vi(path.join(this.folder, "Mods", "Services", "Olympus", "bin", "olympus.dll")).ProductVersion; - } catch (e) { - data["version"] = "n/a"; - } - } - - ejs.renderFile("./ejs/instanceDiv.ejs", data, {}, (err, str) => { - this.element.innerHTML = str; - this.element.querySelector(".add").addEventListener("click", (e) => { - if (!e.srcElement.classList.contains("disabled")) { - showPopup("Please wait while Olympus is being installed"); - window.setTimeout(() => { - if (installOlympus(this.folder)) { - showPopup("Olympus installed successfully. Use the provided form to set Olympus properties. All fields are mandatory. Click on \"Create desktop shortcuts\" to generate Olympus shortcuts on your desktop.", "Create desktop shortcuts", () => { - createDesktopShortcuts(this.folder); - }); - } else { - showPopup("An error has occurred during installation"); - } - }, 100); - } - }); - - this.element.querySelector(".remove").addEventListener("click", (e) => { - if (!e.srcElement.classList.contains("disabled")) { - showPopup("Please wait while Olympus is being uninstalled from DCS instance"); - window.setTimeout(() => { - if (uninstallOlympus(this.folder)) { - showPopup("Olympus uninstalled successfully from DCS instance!"); - } else { - showPopup("An error has occurred during uninstallation"); - } - }, 100); - } - }); - - this.element.querySelector(".apply").addEventListener("click", (e) => { - e.srcElement.classList.remove("blink"); - if (!e.srcElement.classList.contains("disabled")) { - showPopup("Please wait while the configuration is being applied"); - window.setTimeout(() => { - if (applyConfiguration(this.folder, this.getFields())) { - showPopup("Olympus configuration applied successfully!"); - } else { - showPopup("An error has occurred while applying the configuration"); - } - }, 100) - } - }); - - this.element.querySelector(".update").addEventListener("click", (e) => { - if (!e.srcElement.classList.contains("disabled")) { - showPopup("Please wait while Olympus is being updated in the DCS instance"); - window.setTimeout(() => { - if (updateOlympus(this.folder)) { - showPopup("Olympus updated successfully from DCS instance!"); - } else { - showPopup("An error has occurred during the update"); - } - }, 100); - } - }); - - var inputs = this.element.querySelectorAll("input"); - for (let i = 0; i < inputs.length; i++) { - inputs[i].addEventListener("change", () => { - inputs[i].classList.remove("error"); - instanceDivs.forEach((instanceDiv) => instanceDiv.checkFields()) - }) - } - }); - } - - getDiv() { - return this.element; - } - - getFields() { - return { - clientPort: Number(this.element.querySelector("#client-port").value), - backendPort: Number(this.element.querySelector("#backend-port").value), - backendAddress: this.element.querySelector("#backend-address").value, - gameMasterPassword: this.element.querySelector("#game-master-password").value, - blueCommanderPassword: this.element.querySelector("#blue-commander-password").value, - redCommanderPassword: this.element.querySelector("#red-commander-password").value, - } - } - - checkFields() { - var data = this.getFields(); - - /* Clear existing errors */ - var inputs = this.element.querySelectorAll("input"); - for (let i = 0; i < inputs.length; i++) { - inputs[i].classList.remove("error"); - } - var messages = this.element.querySelectorAll(".error"); - for (let i = 0; i < messages.length; i++) { - messages[i].innerText = ""; - } - - /* Enable the button */ - this.element.querySelector(".apply").classList.remove("disabled"); - - if (data["clientPort"] !== 0 && data["backendPort"] !== 0) { - if (data["clientPort"] === data["backendPort"]) { - this.element.querySelector("#client-port").classList.add("error"); - this.element.querySelector("#client-port-error").innerText = "Ports must be different"; - this.element.querySelector("#backend-port").classList.add("error"); - this.element.querySelector("#backend-port-error").innerText = "Ports must be different"; - this.element.querySelector(".apply").classList.add("disabled"); - } - else { - checkPort(data["clientPort"], (res) => { - var otherInstanceUsesPort = instanceDivs.find((instanceDiv) => { - if (instanceDiv != this) { - var fields = instanceDiv.getFields(); - if (fields["clientPort"] === data["clientPort"] || fields["backendPort"] === data["clientPort"]) { - return true; - } - } - }) - - if (!res || otherInstanceUsesPort) { - this.element.querySelector("#client-port").classList.add("error"); - this.element.querySelector("#client-port-error").innerText = "Port already in use"; - this.element.querySelector(".apply").classList.add("disabled"); - } - }); - - checkPort(data["backendPort"], (res) => { - var otherInstanceUsesPort = instanceDivs.find((instanceDiv) => { - if (instanceDiv != this) { - var fields = instanceDiv.getFields(); - if (fields["clientPort"] === data["backendPort"] || fields["backendPort"] === data["backendPort"]) { - return true; - } - } - }) - - if (!res || otherInstanceUsesPort) { - this.element.querySelector("#backend-port").classList.add("error"); - this.element.querySelector("#backend-port-error").innerText = "Port already in use"; - this.element.querySelector(".apply").classList.add("disabled"); - } - }); - } - } - - if (data["gameMasterPassword"] !== "" && data["blueCommanderPassword"] !== "" && data["gameMasterPassword"] === data["blueCommanderPassword"]) { - this.element.querySelector("#game-master-password").classList.add("error"); - this.element.querySelector("#game-master-password-error").innerText = "Passwords must be different"; - this.element.querySelector("#blue-commander-password").classList.add("error"); - this.element.querySelector("#blue-commander-password-error").innerText = "Passwords must be different"; - this.element.querySelector(".apply").classList.add("disabled"); - } - - if (data["gameMasterPassword"] !== "" && data["redCommanderPassword"] !== "" && data["gameMasterPassword"] === data["redCommanderPassword"]) { - this.element.querySelector("#game-master-password").classList.add("error"); - this.element.querySelector("#game-master-password-error").innerText = "Passwords must be different"; - this.element.querySelector("#red-commander-password").classList.add("error"); - this.element.querySelector("#red-commander-password-error").innerText = "Passwords must be different"; - this.element.querySelector(".apply").classList.add("disabled"); - } - - if (data["blueCommanderPassword"] !== "" && data["redCommanderPassword"] !== "" && data["blueCommanderPassword"] === data["redCommanderPassword"]) { - this.element.querySelector("#blue-commander-password").classList.add("error"); - this.element.querySelector("#blue-commander-password-error").innerText = "Passwords must be different"; - this.element.querySelector("#red-commander-password").classList.add("error"); - this.element.querySelector("#red-commander-password-error").innerText = "Passwords must be different"; - this.element.querySelector(".apply").classList.add("disabled"); - } - - if (data["gameMasterPassword"] === "" || data["blueCommanderPassword"] === "" || data["redCommanderPassword"] === "") { - this.element.querySelector(".apply").classList.add("disabled"); - } - } -} - -function loadDivs() { - regedit.list(shellFoldersKey, function (err, result) { - if (err) { - console.log(err); - } - else { - if (result[shellFoldersKey] !== undefined && result[shellFoldersKey]["exists"] && result[shellFoldersKey]['values'][saveGamesKey] !== undefined && result[shellFoldersKey]['values'][saveGamesKey]['value'] !== undefined) { - const searchpath = result[shellFoldersKey]['values'][saveGamesKey]['value']; - const folders = fs.readdirSync(searchpath); - instanceDivs = []; - const mainDiv = document.getElementById("main-div"); - - folders.forEach((folder) => { - if (fs.existsSync(path.join(searchpath, folder, "Config", "appsettings.lua")) || - fs.existsSync(path.join(searchpath, folder, "Config", "serversettings.lua"))) { - instanceDivs.push(new InstanceDiv(mainDiv, path.join(searchpath, folder))); - } - }); - - mainDiv.replaceChildren(...instanceDivs.map((instanceDiv) => { - return instanceDiv.getDiv(); - })); - - instanceDivs.forEach((instanceDiv) => instanceDiv.checkFields()) - - } else { - console.error("An error occured while trying to fetch the location of the DCS folders.") - } - } - }) -} +var managerMenu = new ManagerMenu(); +var managerInstallations = new ManagerInstallations({instances: ["asd/asd1", "asd/asd2"]}); window.addEventListener('DOMContentLoaded', () => { - loadDivs(); + //document.body.appendChild(managerMenu.getElement()); + document.body.appendChild(managerInstallations.getElement()); }) \ No newline at end of file diff --git a/manager/manager.js b/manager/manager.js index be66a47a..626edd84 100644 --- a/manager/manager.js +++ b/manager/manager.js @@ -7,9 +7,10 @@ let window; function createWindow() { const window = new electronBrowserWindow({ - width: 1310, + width: 500, height: 800, frame: false, + resizable: false, webPreferences: { contextIsolation: true, preload: path.join(__dirname, "javascripts", 'preload.js'), diff --git a/manager/stylesheets/style.css b/manager/stylesheets/style.css index 8c8fe480..a2e8cd32 100644 --- a/manager/stylesheets/style.css +++ b/manager/stylesheets/style.css @@ -1,10 +1,20 @@ +:root { + --background: #181e25; + --offwhite: #F2F2F2; + --blue: #247be2; + --red: #FF5858; + --green: #8bff63; + --gray: #cfd9e8; + --darkgray: #3d4651; +} + * { font-family: "Open Sans", sans-serif; box-sizing: border-box; } body { - background-color: #181e25; + background-color: var(--background); padding: 0px; margin: 0px; } @@ -65,37 +75,15 @@ body { color: #F2F2F2; font-weight: bold; font-size: 16px; - padding: 20px; + padding: 20px 20px 0px 20px; column-gap: 10px; } -#header>div:first-of-type{ - width: 300px; -} - -#header>div:last-child { - font-size: 13px; - margin-left: 30px; - font-weight: 400; - text-align: right; - width: 100%; -} - .main-icon { width: 60px; height: 60px; } -#main-div { - display: flex; - flex-direction: row; - height: 100%; - row-gap: 30px; - column-gap: 30px; - flex-wrap: wrap; - padding: 25px; -} - body { overflow: auto; scrollbar-color: white transparent; @@ -121,233 +109,40 @@ body { opacity: 0.8; } -.instance-div { - display: flex; - flex-direction: column; - row-gap: 10px; - background-color: #3d4651; - height: fit-content; - padding: 20px 40px; - border-radius: 5px; - border-left: 5px solid #017DC1; - width: 600px; - box-shadow: 0px 0px 5px #000A; -} - -.instance-content { - display: flex; - flex-direction: column; - row-gap: 15px; -} - -.folder-name { - color: #F2F2F2; - font-weight: bold; - display: flex; - border-bottom: 1px solid #F2F2F2; - padding-bottom: 10px; - width: 100%; -} - -.folder-name span { - width: 500px; - overflow: hidden; - text-wrap: nowrap; - text-overflow: ellipsis; - direction: rtl; - text-align: left; -} - -.folder { - width: 20px; - height: 20px; - background-image: url("../icons/folder-open-solid.svg"); - margin-right: 15px; -} - -.version { - font-size: 13px; - color: #F2F2F2; -} - -.input-table { - padding: 0px; - margin: 0px; - border-width: 0px; - border-collapse: collapse; -} - -.input-table td { - color: #F2F2F2; - padding: 5px 0px; - font-size: 13px; - vertical-align: top; -} - -.input-table td>div { - display: flex; - flex-direction: column; - width: fit-content; -} - -.action-buttons { - display: flex; - flex-direction: row; - column-gap: 12px; - justify-content: start; -} - -.label { - display: flex; - align-items: center; - column-gap: 5px; -} - -.icon { - background-size: 100% 100%; - background-repeat: no-repeat; -} - -.button { - width: fit-content; - height: 40px; - color: #F2F2F2; - border: 1px solid #F2F2F2; - background-size: 40px 60%; - background-position: 0px 50%; - background-repeat: no-repeat; - border-radius: 5px; - padding: 5px 15px 5px 45px; - font-weight: 600; - display: flex; - align-items: center; - font-size: 14px; - background-color: transparent; -} - -.button:not(.disabled) { - cursor: pointer; -} - -.apply { - background-image: url("../icons/check-solid.svg"); - background-color: #017DC1; - border: 1px solid transparent; -} - -.add { - padding: 5px 15px 5px 15px; -} - -.update { - background-image: url("../icons/rotate-right-solid.svg"); -} - -.other { - padding: 5px 15px 5px 15px; -} - -.remove { - background-image: url("../icons/trash-can-regular.svg"); -} - -.disabled { - background-color: #797E83; -} - -.hide { - display: none; -} - -.message { - font-weight: 600; - height: 20px; - font-size: 13px; - color: #F2F2F2; -} - -input { - font-weight: 600; - font-size: 13px; - width: 240px; - border-radius: 4px; -} - -input:focus{ - outline: none; -} - -input.error { - border-color: #FF5858; -} - -.error { - font-weight: bold; - color: #FF5858; -} - .accent-red { - color: #FF5858; + color: var(--red); } .accent-green { - color: #8bff63; + color: var(--green); } -.info { - width: 12px; - height: 12px; - background-image: url("../icons/circle-info-solid.svg"); - background-position: 50% 50%; +.manager-page { + height: 100%; + padding: 35px; } -.blink { - animation: blinker 1s linear infinite; +.page-header { + font-size: 14px; + font-weight: 600; + color: var(--offwhite); + border-bottom: 1px solid var(--offwhite); + padding-bottom: 15px; + margin-bottom: 10px; } -@keyframes blinker { - 50% { - color: transparent; - } -} - -.popup { +.instruction { + color: var(--offwhite); display: flex; flex-direction: column; - row-gap: 15px; - height: 300px; - width: 500px; - position: absolute; - top: 50%; - left: 50%; - background-color: #181e25; - border-radius: 5px; - transform: translate(-250px, -150px); - padding: 30px; - box-shadow: 0px 0px 5px #000A; + row-gap: 4px; } -.popup-header { - height: 20px; - color: #F2F2F2; +.instruction>span:first-child { font-size: 14px; font-weight: 600; } -.popup-content { - height: calc(100% - 50px); - color: #F2F2F2; +.instruction>span:not(:first-child) { font-size: 13px; -} - -.popup-footer { - height: 30px; - display: flex; - justify-content: end; - column-gap: 15px; -} - -.popup-footer .apply { - background-image: none; - padding: 5px 15px 5px 15px; } \ No newline at end of file From 15e8c9e79172ec6ba3d82bc0c4048f72f8ed8df1 Mon Sep 17 00:00:00 2001 From: Pax1601 Date: Fri, 22 Dec 2023 18:44:31 +0100 Subject: [PATCH 2/3] Completed installation procedure on wizard --- manager/ejs/managerconnections.ejs | 110 +++++++++ manager/ejs/managerinstallations.ejs | 107 ++++++++- manager/ejs/managerinstances.ejs | 159 +++++++++++++ manager/ejs/managermenu.ejs | 11 +- manager/ejs/managerpasswords.ejs | 73 ++++++ manager/ejs/managerresult.ejs | 160 +++++++++++++ manager/icons/check-solid-green.svg | 1 + manager/icons/spinner-solid.svg | 1 + manager/icons/square-check-solid.svg | 1 + manager/icons/square-regular.svg | 1 + manager/icons/triangle-exclamation-solid.svg | 1 + manager/index.html | 10 + manager/javascripts/dcsinstance.js | 180 ++++++++++++++ manager/javascripts/filesystem.js | 233 +++++++++++-------- manager/javascripts/managerconnections.js | 69 ++++++ manager/javascripts/managerinstallations.js | 47 +++- manager/javascripts/managerinstances.js | 55 +++++ manager/javascripts/managermenu.js | 10 +- manager/javascripts/managerpage.js | 11 +- manager/javascripts/managerpasswords.js | 42 ++++ manager/javascripts/managerresult.js | 113 +++++++++ manager/javascripts/net.js | 4 +- manager/javascripts/popup.js | 19 ++ manager/javascripts/preload.js | 173 ++++++++++++-- manager/package.json | 1 + manager/stylesheets/style.css | 99 +++++++- 26 files changed, 1541 insertions(+), 150 deletions(-) create mode 100644 manager/ejs/managerconnections.ejs create mode 100644 manager/ejs/managerinstances.ejs create mode 100644 manager/ejs/managerpasswords.ejs create mode 100644 manager/ejs/managerresult.ejs create mode 100644 manager/icons/check-solid-green.svg create mode 100644 manager/icons/spinner-solid.svg create mode 100644 manager/icons/square-check-solid.svg create mode 100644 manager/icons/square-regular.svg create mode 100644 manager/icons/triangle-exclamation-solid.svg create mode 100644 manager/javascripts/dcsinstance.js create mode 100644 manager/javascripts/managerconnections.js create mode 100644 manager/javascripts/managerinstances.js create mode 100644 manager/javascripts/managerpasswords.js create mode 100644 manager/javascripts/managerresult.js create mode 100644 manager/javascripts/popup.js diff --git a/manager/ejs/managerconnections.ejs b/manager/ejs/managerconnections.ejs new file mode 100644 index 00000000..9471b01c --- /dev/null +++ b/manager/ejs/managerconnections.ejs @@ -0,0 +1,110 @@ + +
+ +
+ Client port + This port is used to allow access to Olympus. Be sure to allow this port through your firewall if you want people to connect remotely. +
+ "> + +
+ Port already in use +
+
+
+
+ Backend port + This port is used to communicate with DCS. It is not necessary to allow this port through your firewall. +
+ "> + +
+ Port already in use +
+
+
+
+ Backend address + This is the backend address Olympus will listen on. Unless you know what you are doing, leave it as localhost, even for dedicated server installations. + "> +
+ +
\ No newline at end of file diff --git a/manager/ejs/managerinstallations.ejs b/manager/ejs/managerinstallations.ejs index 5cdb8b0e..acf8bde4 100644 --- a/manager/ejs/managerinstallations.ejs +++ b/manager/ejs/managerinstallations.ejs @@ -1,15 +1,21 @@
-
+
- Select the copies of DCS you want to install Olympus to. + Select the copy of DCS you want to install Olympus to. For most people, this is your main DCS installation. @@ -40,10 +102,33 @@ If you are running a dedicated server, you would also install Olympus to this DCS version.
- <%= instances[0] %> - <% for (let i = 0; i < instances.length; i++) {%> -
- <%= instances[i] %> +
+
+ <% for (let i = 0; i < instances.length; i++) {%> +
+ +
+ <%= instances[i].name %> + + <%= instances[i].installed? (instances[i].error? 'Corrupted/outdated Olympus installation': 'Olympus already installed'): 'Olympus not installed yet' %> + + + <%= instances[i].folder %> +
+
+ <% } %>
- <% } %> +
+ +
\ No newline at end of file diff --git a/manager/ejs/managerinstances.ejs b/manager/ejs/managerinstances.ejs new file mode 100644 index 00000000..77193735 --- /dev/null +++ b/manager/ejs/managerinstances.ejs @@ -0,0 +1,159 @@ + +
+ +
+ + Select the copy of DCS you want to install Olympus to. + + + For most people, this is your main DCS installation. + + + If you are running a dedicated server, you would also install Olympus to this DCS version. + +
+
+
+ <% for (let i = 0; i < instances.length; i++) {%> +
+
+ <%= instances[i].name %> + + <%= instances[i].installed? (instances[i].error? 'Corrupted/outdated Olympus installation': ''): '' %> + + <%= instances[i].folder %> +
+
Client port
+
<%= instances[i].clientPort %>
+
+
+
Backend port
+
<%= instances[i].backendPort %>
+
+
+
Backend address
+
<%= instances[i].backendAddress %>
+
+
+
+ <% } %> +
+
+ +
\ No newline at end of file diff --git a/manager/ejs/managermenu.ejs b/manager/ejs/managermenu.ejs index 21dc76ac..70f0ebee 100644 --- a/manager/ejs/managermenu.ejs +++ b/manager/ejs/managermenu.ejs @@ -16,6 +16,11 @@ padding-left: 15px; align-items: center; border-radius: 5px; + cursor: pointer; + } + + #manager-menu>.option * { + pointer-events: none; } .inverted { @@ -28,13 +33,13 @@ -
+
Install Olympus
-
+
Update/remove Olympus
-
+
View and manage instances
\ No newline at end of file diff --git a/manager/ejs/managerpasswords.ejs b/manager/ejs/managerpasswords.ejs new file mode 100644 index 00000000..7b46f7bb --- /dev/null +++ b/manager/ejs/managerpasswords.ejs @@ -0,0 +1,73 @@ + +
+ +
+ Enter your passwords to access Olympus + By using the passwords below, you can access different roles in Olympus. +
+ +
+ Game Master Password + This password is used to access Olympus as Game Master with full priviledges. + +
+
+ Blue Commander Password + This password is used to access Olympus as blue coalition Commander. + +
+
+ Red Commander Password + This password is used to access Olympus as red coalition Commander. + +
+ +
\ No newline at end of file diff --git a/manager/ejs/managerresult.ejs b/manager/ejs/managerresult.ejs new file mode 100644 index 00000000..623b82ce --- /dev/null +++ b/manager/ejs/managerresult.ejs @@ -0,0 +1,160 @@ + +
+ +
+ Installing hook scripts +
+
+ Installing mod folder +
+
+ Installing configuration file +
+
+ Applying configuration +
+
+ Creating shortcuts +
+ +
+ Olympus successfully installed in the following DCS instance +
+ +
+ An error has occurred while installing Olympus +
+ +
+ +
+ + <%= instance.name %> + + + <%= instance.folder %> + +
+
+ +
+ You may now start DCS and use Olympus either with the shortcuts or the "View and manage Olympus" entry in the + main menu +
+ +
+ Please make sure DCS is not currently being executed +
+ + +
\ No newline at end of file diff --git a/manager/icons/check-solid-green.svg b/manager/icons/check-solid-green.svg new file mode 100644 index 00000000..96b80e24 --- /dev/null +++ b/manager/icons/check-solid-green.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/manager/icons/spinner-solid.svg b/manager/icons/spinner-solid.svg new file mode 100644 index 00000000..061f1932 --- /dev/null +++ b/manager/icons/spinner-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/manager/icons/square-check-solid.svg b/manager/icons/square-check-solid.svg new file mode 100644 index 00000000..9be69184 --- /dev/null +++ b/manager/icons/square-check-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/manager/icons/square-regular.svg b/manager/icons/square-regular.svg new file mode 100644 index 00000000..88fabee2 --- /dev/null +++ b/manager/icons/square-regular.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/manager/icons/triangle-exclamation-solid.svg b/manager/icons/triangle-exclamation-solid.svg new file mode 100644 index 00000000..3b18b9a9 --- /dev/null +++ b/manager/icons/triangle-exclamation-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/manager/index.html b/manager/index.html index 8ff23a37..001a5fab 100644 --- a/manager/index.html +++ b/manager/index.html @@ -29,6 +29,16 @@
+
+
+ \ No newline at end of file diff --git a/manager/javascripts/dcsinstance.js b/manager/javascripts/dcsinstance.js index 85b84b16..c0c73b9b 100644 --- a/manager/javascripts/dcsinstance.js +++ b/manager/javascripts/dcsinstance.js @@ -6,6 +6,7 @@ var path = require('path') const vi = require('win-version-info'); const checkPort = require('./net') const dircompare = require('dir-compare'); +const { installJSON } = require('./filesystem') class DCSInstance { static instances = null; @@ -64,6 +65,15 @@ class DCSInstance { this.name = path.basename(folder); if (fs.existsSync(path.join(folder, "Config", "olympus.json"))){ + try { + var config = JSON.parse(fs.readFileSync(path.join(folder, "Config", "olympus.json"))); + this.clientPort = config["client"]["port"]; + this.backendPort = config["server"]["port"]; + this.backendAddress = config["server"]["address"]; + } catch (err) { + console.error(err) + } + this.installed = true; const options = { compareContent: true }; var err1 = true; diff --git a/manager/javascripts/managerresult.js b/manager/javascripts/managerresult.js index 72157d7e..e9c29dec 100644 --- a/manager/javascripts/managerresult.js +++ b/manager/javascripts/managerresult.js @@ -16,7 +16,7 @@ class ManagerResult extends ManagerPage { element.innerHTML = str; this.element.querySelector(".back").addEventListener("click", (e) => this.onBackClicked(e)); - this.element.querySelector(".cancel").addEventListener("click", (e) => this.onCancelClicked(e)); + //this.element.querySelector(".cancel").addEventListener("click", (e) => this.onCancelClicked(e)); } show(instance) { diff --git a/manager/javascripts/preload.js b/manager/javascripts/preload.js index 9b633005..0fb2c1ec 100644 --- a/manager/javascripts/preload.js +++ b/manager/javascripts/preload.js @@ -110,7 +110,7 @@ async function setup() { } /* Instances */ - var managerInstances = new ManagerInstances({ instances: instances }); + var managerInstances = new ManagerInstances({ instances: instances.filter((instance) => {return instance.installed; }) }); managerInstances.onBackClicked = (e) => { managerInstances.hide(); managerMenu.show(); @@ -189,11 +189,11 @@ async function setup() { var managerResult = new ManagerResult(); managerResult.onBackClicked = (e) => { managerResult.hide(); - managerMenu.show(); + location.reload(); } managerResult.onCancelClicked = (e) => { managerResult.hide(); - managerMenu.show(); + location.reload(); } document.body.appendChild(managerMenu.getElement()); diff --git a/scripts/install.bat b/scripts/install.bat index 5862d51a..7ceea2d0 100644 --- a/scripts/install.bat +++ b/scripts/install.bat @@ -9,9 +9,17 @@ echo "* |_____/ \_____|_____/ \____/|_|\__, |_| |_| |_| .__/ \__,_|___/ * echo "* __/ | | | *" echo "* |___/ |_| *" echo "*********************************************************************" -echo Welcome to the DCS Olympus v{{OLYMPUS_VERSION_NUMBER}} installation script. Please wait while the necessary dependencies are installed! +echo Welcome to the DCS Olympus {{OLYMPUS_VERSION_NUMBER}} installation script. Please wait while the necessary dependencies are installed! echo: -echo The output of this script is also available in the file %CD%\output.log. If you encounter any error, make sure to attach that file to your help request! + + +WHERE /q powershell +if %ERRORLEVEL% NEQ 0 ( + echo Powershell not installed in the system, no output log available. +) else ( + echo The output of this script is also available in the file "%CD%\output.log". If you encounter any error, make sure to attach that file to your help request! +) + timeout /t 5 echo Checking if node.js framework is installed...