mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
310 lines
13 KiB
JavaScript
310 lines
13 KiB
JavaScript
const sha256 = require('sha256')
|
|
const createShortcut = require('create-desktop-shortcuts');
|
|
const fs = require('fs');
|
|
const fsp = require('fs').promises;
|
|
const path = require('path');
|
|
const { Console } = require('console');
|
|
const homeDir = require('os').homedir();
|
|
|
|
var output = fs.createWriteStream('./manager.log', { flags: 'a' });
|
|
var logger = new Console(output, output);
|
|
const date = new Date();
|
|
output.write(` ======================= New log starting at ${date.toString()} =======================\n`);
|
|
|
|
var EXPORT_STRING = "pcall(function() local olympusLFS=require('lfs');dofile(olympusLFS.writedir()..[[Mods\\Services\\Olympus\\Scripts\\OlympusCameraControl.lua]]); end,nil) ";
|
|
|
|
/** Conveniency function to asynchronously delete a single file, with error catching
|
|
*
|
|
* @param {String} filePath The path to the file to delete
|
|
*/
|
|
async function deleteFile(filePath) {
|
|
logger.log(`Deleting ${filePath}`);
|
|
if (await exists(filePath) && await fsp.rm(filePath))
|
|
logger.log(`Removed ${filePath}`);
|
|
else
|
|
logger.log(`${filePath} does not exist, nothing to do`);
|
|
}
|
|
|
|
/** Conveniency function to asynchronously check if a file or folder exists
|
|
*
|
|
* @param {*} location Path to the folder or file to check for existance
|
|
* @returns true if file exists, false if it doesn't
|
|
*/
|
|
async function exists(location) {
|
|
try {
|
|
await fsp.stat(location);
|
|
return true;
|
|
} catch (err) {
|
|
if (err.code === 'ENOENT') {
|
|
return false
|
|
} else {
|
|
throw err;
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Asynchronously installs the Hooks script
|
|
*
|
|
* @param {String} folder The base Saved Games folder where the hooks scripts should be installed
|
|
*/
|
|
async function installHooks(folder) {
|
|
logger.log(`Installing hooks in ${folder}`)
|
|
await fsp.cp(path.join("..", "scripts", "OlympusHook.lua"), path.join(folder, "Scripts", "Hooks", "OlympusHook.lua"));
|
|
logger.log(`Hooks succesfully installed in ${folder}`)
|
|
}
|
|
|
|
/** Asynchronously installs the Mod folder
|
|
*
|
|
* @param {String} folder The base Saved Games folder where the mod folder should be installed
|
|
* @param {String} name The name of the current DCS Instance, used to create backups of user created files
|
|
*/
|
|
|
|
async function installMod(folder, name) {
|
|
logger.log(`Installing mod in ${folder}`)
|
|
|
|
await fsp.cp(path.join("..", "mod"), path.join(folder, "Mods", "Services", "Olympus"), { recursive: true });
|
|
logger.log(`Mod succesfully installed in ${folder}`)
|
|
|
|
/* Check if backup user-editable files exist. If true copy them over */
|
|
logger.log(path.join(__dirname, "..", "..", "..", "DCS Olympus backups", name, "databases"));
|
|
if (await exists(path.join(__dirname, "..", "..", "..", "DCS Olympus backups", name, "databases"))) {
|
|
logger.log("Backup databases found, copying over");
|
|
|
|
// Changed in v2.0.0, only the mods database is copied over, if present
|
|
//await fsp.cp(path.join(__dirname, "..", "..", "..", "DCS Olympus backups", name, "databases"), path.join(folder, "Mods", "Services", "Olympus", "databases"), { recursive: true });
|
|
await fsp.cp(path.join(__dirname, "..", "..", "..", "DCS Olympus backups", name, "databases", "units", "mods.json"), path.join(folder, "Mods", "Services", "Olympus", "databases", "units", "mods.json"));
|
|
}
|
|
|
|
if (exists(path.join(__dirname, "..", "..", "..", "DCS Olympus backups", name, "scripts", "mods.lua"))) {
|
|
logger.log("Backup mods.lua found, copying over");
|
|
fsp.cp(path.join(__dirname, "..", "..", "..", "DCS Olympus backups", name, "scripts", "mods.lua"), path.join(folder, "Mods", "Services", "Olympus", "scripts", "mods.lua"));
|
|
}
|
|
}
|
|
|
|
/** Asynchronously installs the olympus.json file
|
|
*
|
|
* @param {String} folder The base Saved Games folder where the config json should be installed
|
|
*/
|
|
async function installJSON(folder) {
|
|
logger.log(`Installing config in ${folder}`)
|
|
await fsp.cp(path.join("..", "olympus.json"), path.join(folder, "Config", "olympus.json"));
|
|
logger.log(`Config succesfully installed in ${folder}`)
|
|
}
|
|
|
|
/** Asynchronously creates shortcuts both in the DCS Saved Games folder and on the desktop
|
|
*
|
|
* @param {String} folder The base Saved Games folder where the shortcuts should be installed
|
|
* @param {String} name The name of the current DCS Instance, used to create the shortcut names
|
|
*/
|
|
async function installShortCuts(folder, name) {
|
|
logger.log(`Installing shortcuts for Olympus in ${folder}`);
|
|
|
|
var res1 = createShortcut({
|
|
windows: {
|
|
filePath: path.resolve(__dirname, '..', '..', 'frontend', 'client.vbs'),
|
|
outputPath: folder,
|
|
name: `DCS Olympus Client (${name})`,
|
|
arguments: `"${path.join(folder, "Config", "olympus.json")}"`,
|
|
icon: path.resolve(__dirname, '..', '..', 'img', 'olympus.ico'),
|
|
workingDirectory: path.resolve(__dirname, '..', '..', 'frontend')
|
|
}
|
|
});
|
|
|
|
var res2 = createShortcut({
|
|
windows: {
|
|
filePath: path.resolve(__dirname, '..', '..', 'frontend', 'server.vbs'),
|
|
outputPath: folder,
|
|
name: `DCS Olympus Server (${name})`,
|
|
arguments: `"${path.join(folder, "Config", "olympus.json")}"`,
|
|
icon: path.resolve(__dirname, '..', '..', 'img', 'olympus_server.ico'),
|
|
workingDirectory: path.resolve(__dirname, '..', '..', 'frontend')
|
|
}
|
|
});
|
|
|
|
var res3 = createShortcut({
|
|
windows: {
|
|
filePath: path.resolve(__dirname, '..', '..', 'frontend', 'client.vbs'),
|
|
name: `DCS Olympus Client (${name})`,
|
|
arguments: `"${path.join(folder, "Config", "olympus.json")}"`,
|
|
icon: path.resolve(__dirname, '..', '..', 'img', 'olympus.ico'),
|
|
workingDirectory: path.resolve(__dirname, '..', '..', 'frontend')
|
|
}
|
|
});
|
|
|
|
var res4 = createShortcut({
|
|
windows: {
|
|
filePath: path.resolve(__dirname, '..', '..', 'frontend', 'server.vbs'),
|
|
name: `DCS Olympus Server (${name})`,
|
|
arguments: `"${path.join(folder, "Config", "olympus.json")}"`,
|
|
icon: path.resolve(__dirname, '..', '..', 'img', 'olympus_server.ico'),
|
|
workingDirectory: path.resolve(__dirname, '..', '..', 'frontend')
|
|
}
|
|
});
|
|
|
|
// TODO actually check if the shortcuts where created
|
|
if (!res1 || !res2 || !res3 || !res4)
|
|
throw "An error occurred while creating the shortcuts";
|
|
}
|
|
|
|
/** Asynchronously writes the configuration of an instance to the olympus.json file
|
|
*
|
|
* @param {String} folder The base Saved Games folder where Olympus should is installed
|
|
* @param {DCSInstance} instance The DCSInstance of which we want to apply the configuration
|
|
*/
|
|
async function applyConfiguration(folder, instance) {
|
|
logger.log(`Applying configuration to Olympus in ${folder}`);
|
|
|
|
if (await exists(path.join(folder, "Config", "olympus.json"))) {
|
|
var config = JSON.parse(await fsp.readFile(path.join(folder, "Config", "olympus.json")));
|
|
|
|
/* Automatically find free ports */
|
|
if (instance.connectionsType === 'auto') {
|
|
await instance.findFreePorts();
|
|
}
|
|
|
|
/* Apply the configuration */
|
|
config["frontend"]["port"] = instance.frontendPort;
|
|
config["frontend"]["autoconnectWhenLocal"] = instance.autoconnectWhenLocal;
|
|
config["backend"]["port"] = instance.backendPort;
|
|
config["backend"]["address"] = instance.backendAddress;
|
|
|
|
if (config["audio"] === undefined)
|
|
config["audio"] = {};
|
|
config["audio"]["SRSPort"] = instance.SRSPort;
|
|
|
|
if (instance.gameMasterPassword !== "")
|
|
config["authentication"]["gameMasterPassword"] = sha256(instance.gameMasterPassword);
|
|
|
|
if (instance.blueCommanderPassword !== "")
|
|
config["authentication"]["blueCommanderPassword"] = sha256(instance.blueCommanderPassword);
|
|
|
|
if (instance.redCommanderPassword !== "")
|
|
config["authentication"]["redCommanderPassword"] = sha256(instance.redCommanderPassword);
|
|
|
|
await fsp.writeFile(path.join(folder, "Config", "olympus.json"), JSON.stringify(config, null, 4));
|
|
logger.log(`Config succesfully applied in ${folder}`)
|
|
} else {
|
|
throw "File does not exist";
|
|
}
|
|
}
|
|
|
|
/** Asynchronously install the camera control plugin
|
|
*
|
|
* @param {String} folder The base Saved Games folder where Olympus is installed
|
|
*/
|
|
async function installCameraPlugin(folder) {
|
|
logger.log(`Installing camera support plugin to DCS in ${folder}`);
|
|
/* If the export file doesn't exist, create it */
|
|
if (!(await exists(path.join(folder, "Scripts", "export.lua")))) {
|
|
await fsp.writeFile(path.join(folder, "Scripts", "export.lua"), EXPORT_STRING);
|
|
} else {
|
|
let content = await fsp.readFile(path.join(folder, "Scripts", "export.lua"), { encoding: 'utf8' });
|
|
if (content.indexOf(EXPORT_STRING) != -1) {
|
|
/* Looks like the export string is already installed, nothing to do */
|
|
}
|
|
else {
|
|
/* Append the export string at the end of the file */
|
|
content += ("\n" + EXPORT_STRING);
|
|
}
|
|
/* Write the content of the file */
|
|
await fsp.writeFile(path.join(folder, "Scripts", "export.lua"), content)
|
|
}
|
|
}
|
|
|
|
/** Asynchronously deletes the Hooks script
|
|
*
|
|
* @param {String} folder The base Saved Games folder where Olympus is installed
|
|
*/
|
|
async function deleteHooks(folder) {
|
|
logger.log(`Deleting hooks from ${folder}`);
|
|
await deleteFile(path.join(folder, "Scripts", "Hooks", "OlympusHook.lua"));
|
|
}
|
|
|
|
/** Asynchronously deletes the Mod folder
|
|
*
|
|
* @param {String} folder The base Saved Games folder where Olympus is installed
|
|
*/
|
|
async function deleteMod(folder, name) {
|
|
logger.log(`Deleting mod from ${folder}`);
|
|
|
|
if (await exists(path.join(folder, "Mods", "Services", "Olympus"))) {
|
|
/* Make a copy of the user-editable files */
|
|
if (await exists(path.join(folder, "Mods", "Services", "Olympus", "databases")))
|
|
await fsp.cp(path.join(folder, "Mods", "Services", "Olympus", "databases"), path.join(__dirname, "..", "..", "..", "DCS Olympus backups", name, "databases"), { recursive: true });
|
|
else
|
|
logger.warn(`No database folder found in ${folder}, skipping backup...`)
|
|
|
|
if (await exists(path.join(folder, "Mods", "Services", "Olympus", "scripts", "mods.lua")))
|
|
await fsp.cp(path.join(folder, "Mods", "Services", "Olympus", "scripts", "mods.lua"), path.join(__dirname, "..", "..", "..", "DCS Olympus backups", name, "scripts", "mods.lua"));
|
|
else
|
|
logger.warn(`No mods.lua found in ${folder}, skipping backup...`)
|
|
|
|
/* Remove the mod folder */
|
|
await fsp.rmdir(path.join(folder, "Mods", "Services", "Olympus"), { recursive: true, force: true })
|
|
logger.log(`Mod succesfully removed from ${folder}`)
|
|
} else {
|
|
logger.warn(`Mod does not exist in ${folder}, nothing to do`)
|
|
}
|
|
}
|
|
|
|
/** Asynchronously deletes the olympus.json configuration file
|
|
*
|
|
* @param {String} folder The base Saved Games folder where Olympus is installed
|
|
*/
|
|
async function deleteJSON(folder) {
|
|
logger.log(`Deleting JSON from ${folder}`);
|
|
return deleteFile(path.join(folder, "Config", "olympus.json"));
|
|
}
|
|
|
|
/** Asynchronously deletes the shortcuts
|
|
*
|
|
* @param {String} folder The base Saved Games folder where Olympus is installed
|
|
* @param {String} name The name of the DCS Instance, used to find the correct shortcuts
|
|
*/
|
|
async function deleteShortCuts(folder, name) {
|
|
logger.log(`Deleting ShortCuts from ${folder} and desktop`);
|
|
await deleteFile(path.join(folder, `DCS Olympus Server (${name}).lnk`))
|
|
await deleteFile(path.join(folder, `DCS Olympus Client (${name}).lnk`))
|
|
await deleteFile(path.join(homeDir, "Desktop", `DCS Olympus Server (${name}).lnk`))
|
|
await deleteFile(path.join(homeDir, "Desktop", `DCS Olympus Client (${name}).lnk`))
|
|
logger.log(`ShortCuts deleted from ${folder} and desktop`);
|
|
}
|
|
|
|
/** Asynchronously removes the camera plugin string from the export lua file
|
|
*
|
|
* @param {String} folder The base Saved Games folder where Olympus is installed
|
|
*/
|
|
async function deleteCameraPlugin(folder) {
|
|
logger.log(`Deleting camera support plugin to DCS in ${folder}`);
|
|
if (!(await exists(path.join(folder, "Scripts", "export.lua")))) {
|
|
/* If the export file doesn't exist, nothing to do */
|
|
} else {
|
|
let content = await fsp.readFile(path.join(folder, "Scripts", "export.lua"), { encoding: 'utf8' });
|
|
if (content.indexOf(EXPORT_STRING) ==+ -1) {
|
|
/* Looks like the export string is not installed, nothing to do */
|
|
}
|
|
else {
|
|
/* Remove the export string from the file */
|
|
content = content.replace(EXPORT_STRING, "")
|
|
|
|
/* Write the content of the file */
|
|
await fsp.writeFile(path.join(folder, "Scripts", "export.lua"), content)
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
applyConfiguration: applyConfiguration,
|
|
installJSON: installJSON,
|
|
installHooks: installHooks,
|
|
installMod: installMod,
|
|
installShortCuts: installShortCuts,
|
|
installCameraPlugin: installCameraPlugin,
|
|
deleteHooks: deleteHooks,
|
|
deleteJSON: deleteJSON,
|
|
deleteMod: deleteMod,
|
|
deleteShortCuts: deleteShortCuts,
|
|
deleteCameraPlugin: deleteCameraPlugin,
|
|
logger: logger
|
|
}
|