2023-12-19 18:20:07 +01:00

253 lines
11 KiB
JavaScript

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 shellFoldersKey = 'HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders'
const saveGamesKey = '{4C5C32FF-BB9D-43B0-B5B4-2D72E54EAAA4}'
var instanceDivs = [];
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}`);
fs.cpSync(path.join("..", "Mod"), path.join(folder, "Mods", "Services", "Olympus"), {recursive: true});
fs.cpSync(path.join("..", "Scripts", "OlympusHook.lua"), path.join(folder, "Scripts", "OlympusHook.lua"), {recursive: true});
fs.cpSync(path.join("..", "olympus.json"), path.join(folder, "Config", "olympus.json"), {recursive: true});
loadDivs();
}
function uninstallOlympus(folder) {
console.log(`Uninstalling Olympus from ${folder}`);
fs.rmSync(path.join(folder, "Mods", "Services", "Olympus"), {recursive: true});
fs.rmSync(path.join(folder, "Config", "olympus.json"), {recursive: true});
loadDivs();
}
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"]);
fs.writeFileSync(path.join(folder, "Config", "olympus.json"), JSON.stringify(config, null, 4));
}
}
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 * 9
};
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;
}
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"))
installOlympus(this.folder);
});
this.element.querySelector(".remove").addEventListener("click", (e) => {
if (!e.srcElement.classList.contains("disabled"))
uninstallOlympus(this.folder);
});
this.element.querySelector(".apply").addEventListener("click", (e) => {
if (!e.srcElement.classList.contains("disabled"))
applyConfiguration(this.folder, this.getFields());
});
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, "Logs", "dcs.log"))) {
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.")
}
}
})
}
window.addEventListener('DOMContentLoaded', () => {
loadDivs();
})