Added installation/deletion of camera control plugin from manager

This commit is contained in:
Davide Passoni
2024-02-29 10:54:52 +01:00
parent 832568aa00
commit 4782596e3c
12 changed files with 175 additions and 42 deletions

View File

@@ -6,7 +6,7 @@ const { checkPort, fetchWithTimeout, getFreePort } = require('./net')
const dircompare = require('dir-compare');
const { spawn } = require('child_process');
const find = require('find-process');
const { installHooks, installMod, installJSON, applyConfiguration, installShortCuts, deleteMod, deleteHooks, deleteJSON, deleteShortCuts } = require('./filesystem')
const { installHooks, installMod, installJSON, applyConfiguration, installShortCuts, deleteMod, deleteHooks, deleteJSON, deleteShortCuts, installCameraPlugin, deleteCameraPlugin } = require('./filesystem')
const { showErrorPopup, showConfirmPopup, showWaitLoadingPopup, setPopupLoadingProgress } = require('./popup')
const { logger } = require("./filesystem")
const { hidePopup } = require('./popup');
@@ -129,6 +129,7 @@ class DCSInstance {
fps = 0;
installationType = 'singleplayer';
connectionsType = 'auto';
installCameraPlugin = 'install';
gameMasterPasswordEdited = false;
blueCommanderPasswordEdited = false;
redCommanderPasswordEdited = false;
@@ -154,6 +155,7 @@ class DCSInstance {
this.error = false;
this.installationType = 'singleplayer';
this.connectionsType = 'auto';
this.installCameraPlugin = 'install';
/* Check if the olympus.json file is detected. If true, Olympus is considered to be installed */
if (fs.existsSync(path.join(this.folder, "Config", "olympus.json"))) {
@@ -518,22 +520,28 @@ class DCSInstance {
await sleep(100);
await installHooks(getManager().getActiveInstance().folder);
setPopupLoadingProgress("Installing mod folder...", 20);
setPopupLoadingProgress("Installing mod folder...", 16);
await sleep(100);
await installMod(getManager().getActiveInstance().folder, getManager().getActiveInstance().name);
setPopupLoadingProgress("Installing JSON file...", 40);
setPopupLoadingProgress("Installing JSON file...", 33);
await sleep(100);
await installJSON(getManager().getActiveInstance().folder);
setPopupLoadingProgress("Applying configuration...", 60);
setPopupLoadingProgress("Applying configuration...", 50);
await sleep(100);
await applyConfiguration(getManager().getActiveInstance().folder, getManager().getActiveInstance());
setPopupLoadingProgress("Creating shortcuts...", 80);
setPopupLoadingProgress("Creating shortcuts...", 67);
await sleep(100);
await installShortCuts(getManager().getActiveInstance().folder, getManager().getActiveInstance().name);
if (getManager().getActiveInstance().installCameraPlugin === 'install') {
setPopupLoadingProgress("Installing camera plugin...", 83);
await sleep(100);
await installCameraPlugin(getManager().getActiveInstance().folder);
}
setPopupLoadingProgress("Installation completed!", 100);
await sleep(500);
logger.log(`Installation completed successfully`);
@@ -575,18 +583,22 @@ class DCSInstance {
await sleep(100);
await deleteMod(this.folder, this.name);
setPopupLoadingProgress("Deleting hook scripts...", 25);
setPopupLoadingProgress("Deleting hook scripts...", 20);
await sleep(100);
await deleteHooks(this.folder);
setPopupLoadingProgress("Deleting JSON...", 50);
setPopupLoadingProgress("Deleting JSON...", 40);
await sleep(100);
await deleteJSON(this.folder);
setPopupLoadingProgress("Deleting shortcuts...", 75);
setPopupLoadingProgress("Deleting shortcuts...", 60);
await sleep(100);
await deleteShortCuts(this.folder, this.name);
setPopupLoadingProgress("Deleting camera plugin...", 80);
await sleep(100);
await deleteCameraPlugin(this.folder);
await sleep(500);
setPopupLoadingProgress("Instance removed!", 100);
logger.log(`Olympus removed from ${this.folder}`)

View File

@@ -11,6 +11,8 @@ 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
@@ -172,6 +174,29 @@ async function applyConfiguration(folder, instance) {
}
}
/** 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
@@ -231,15 +256,40 @@ async function deleteShortCuts(folder, name) {
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,
installShortCuts: installShortCuts,
installCameraPlugin: installCameraPlugin,
deleteHooks: deleteHooks,
deleteJSON: deleteJSON,
deleteMod: deleteMod,
deleteShortCuts: deleteShortCuts,
deleteCameraPlugin: deleteCameraPlugin,
logger: logger
}

View File

@@ -32,6 +32,7 @@ class Manager {
connectionsTypePage = null;
connectionsPage = null;
passwordsPage = null;
cameraPage = null;
resultPage = null;
instancesPage = null;
expertSettingsPage = null;
@@ -103,9 +104,9 @@ class Manager {
/* Get my public IP */
this.getPublicIP().then(
(IP) => { this.setIP(IP); },
(err) => {
(err) => {
logger.log(err)
this.setIP(undefined);
this.setIP(undefined);
}
)
@@ -142,6 +143,7 @@ class Manager {
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.cameraPage = new WizardPage(this, "./ejs/camera.ejs");
this.resultPage = new ManagerPage(this, "./ejs/result.ejs");
this.instancesPage = new ManagerPage(this, "./ejs/instances.ejs");
this.expertSettingsPage = new WizardPage(this, "./ejs/expertsettings.ejs");
@@ -159,7 +161,7 @@ class Manager {
this.setPort('backend', this.getActiveInstance().backendPort);
}
}
/* Always force the IDLE state when reaching the menu page */
this.menuPage.options.onShow = async () => {
await this.setState('IDLE');
@@ -337,6 +339,17 @@ class Manager {
}
}
/* When the camera control installation is selected */
async onInstallCameraControlClicked(type) {
this.connectionsTypePage.getElement().querySelector(`.install`).classList.toggle("selected", type === 'install');
this.connectionsTypePage.getElement().querySelector(`.no-install`).classList.toggle("selected", type === 'no-install');
if (this.getActiveInstance())
this.getActiveInstance().installCameraPlugin = type;
else {
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${this.getLogLocation()} for more info. </div>`);
}
}
/* When the next button of a wizard page is clicked */
async onNextClicked() {
/* Choose which page to show depending on the active page */
@@ -360,11 +373,11 @@ class Manager {
this.activePage.hide();
this.typePage.show();
}
/* Installation type page */
/* Installation type page */
} else if (this.activePage == this.typePage) {
this.activePage.hide();
this.connectionsTypePage.show();
/* Connection type page */
/* Connection type page */
} else if (this.activePage == this.connectionsTypePage) {
if (this.getActiveInstance()) {
if (this.getActiveInstance().connectionsType === 'auto') {
@@ -374,24 +387,28 @@ class Manager {
else {
this.activePage.hide();
this.connectionsPage.show();
(this.getMode() === 'basic'? this.connectionsPage: this.expertSettingsPage).getElement().querySelector(".backend-address .checkbox").classList.toggle("checked", this.getActiveInstance().backendAddress === '*')
(this.getMode() === 'basic' ? this.connectionsPage : this.expertSettingsPage).getElement().querySelector(".backend-address .checkbox").classList.toggle("checked", this.getActiveInstance().backendAddress === '*')
}
} else {
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${this.getLogLocation()} for more info. </div>`)
}
/* Connection page */
/* Connection page */
} else if (this.activePage == this.connectionsPage) {
if (await this.checkPorts()) {
this.activePage.hide();
this.passwordsPage.show();
}
/* Passwords page */
}
/* Passwords page */
} else if (this.activePage == this.passwordsPage) {
if (await this.checkPasswords()) {
this.activePage.hide();
this.getState() === 'INSTALL' ? this.getActiveInstance().install() : this.getActiveInstance().edit();
this.cameraPage.show()
}
/* Expert settings page */
/* Installation type page */
} else if (this.activePage == this.cameraPage) {
this.activePage.hide();
this.getState() === 'INSTALL' ? this.getActiveInstance().install() : this.getActiveInstance().edit();
/* Expert settings page */
} else if (this.activePage == this.expertSettingsPage) {
if (await this.checkPorts() && await this.checkPasswords()) {
this.activePage.hide();
@@ -416,7 +433,7 @@ class Manager {
async onCancelClicked() {
this.activePage.hide();
await this.setState('IDLE');
if (this.getMode() === "basic")
if (this.getMode() === "basic")
this.menuPage.show(true);
else
this.instancesPage.show(true);
@@ -441,7 +458,7 @@ class Manager {
if (this.getActiveInstance())
this.getActiveInstance().setBlueCommanderPassword(value);
else
else
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${this.getLogLocation()} for more info. </div>`);
}
@@ -450,9 +467,9 @@ class Manager {
input.placeholder = "";
}
if (this.getActiveInstance())
if (this.getActiveInstance())
this.getActiveInstance().setRedCommanderPassword(value);
else
else
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${this.getLogLocation()} for more info. </div>`);
}
@@ -485,6 +502,20 @@ class Manager {
}
}
/* When the "Enable camera control plugin" checkbox is clicked */
async onEnableCameraPluginClicked() {
if (this.getActiveInstance()) {
if (this.getActiveInstance().installCameraPlugin === 'install') {
this.getActiveInstance().installCameraPlugin = 'no-install';
} else {
this.getActiveInstance().installCameraPlugin = 'install';
}
this.expertSettingsPage.getElement().querySelector(".camera-plugin .checkbox").classList.toggle("checked", this.getActiveInstance().installCameraPlugin === 'install')
} else {
showErrorPopup(`<div class='main-message'>A critical error occurred! </div><div class='sub-message'> Check ${this.getLogLocation()} for more info. </div>`)
}
}
/* When the "Return to manager" button is pressed */
async onReturnClicked() {
await this.reload();
@@ -562,7 +593,7 @@ class Manager {
this.setActiveInstance(instance);
await this.setState('EDIT');
this.activePage.hide();
(this.getMode() === 'basic'? this.typePage: this.expertSettingsPage).show();
(this.getMode() === 'basic' ? this.typePage : this.expertSettingsPage).show();
}
}
@@ -571,7 +602,7 @@ class Manager {
this.setActiveInstance(instance);
await this.setState('INSTALL');
this.activePage.hide();
(this.getMode() === 'basic'? this.typePage: this.expertSettingsPage).show();
(this.getMode() === 'basic' ? this.typePage : this.expertSettingsPage).show();
}
async onUninstallClicked(name) {
@@ -579,7 +610,7 @@ class Manager {
this.setActiveInstance(instance);
await this.setState('UNINSTALL');
if (instance.webserverOnline || instance.backendOnline)
showErrorPopup("<div class='main-message'>The selected Olympus instance is currently active </div><div class='sub-message'> Please stop DCS and Olympus Server/Client before removing it! </div>")
showErrorPopup("<div class='main-message'>The selected Olympus instance is currently active </div><div class='sub-message'> Please stop DCS and Olympus Server/Client before removing it! </div>")
else
await instance.uninstall();
}
@@ -620,11 +651,11 @@ class Manager {
this.getActiveInstance().setBackendPort(value);
}
var successEls = (this.getMode() === 'basic'? this.connectionsPage: this.expertSettingsPage).getElement().querySelector(`.${port}-port`).querySelectorAll(".success");
var successEls = (this.getMode() === 'basic' ? this.connectionsPage : this.expertSettingsPage).getElement().querySelector(`.${port}-port`).querySelectorAll(".success");
for (let i = 0; i < successEls.length; i++) {
successEls[i].classList.toggle("hide", !success);
}
var errorEls = (this.getMode() === 'basic'? this.connectionsPage: this.expertSettingsPage).getElement().querySelector(`.${port}-port`).querySelectorAll(".error");
var errorEls = (this.getMode() === 'basic' ? this.connectionsPage : this.expertSettingsPage).getElement().querySelector(`.${port}-port`).querySelectorAll(".error");
for (let i = 0; i < errorEls.length; i++) {
errorEls[i].classList.toggle("hide", success);
}
@@ -693,7 +724,7 @@ class Manager {
document.getElementById("loader").style.opacity = "0%";
window.setTimeout(() => {
document.getElementById("loader").classList.add("hide");
}, 250);
}, 250);
}
async setActiveInstance(newActiveInstance) {
@@ -718,12 +749,12 @@ class Manager {
async setLogLocation(newLogLocation) {
this.options.logLocation = newLogLocation;
}
}
async setState(newState) {
this.options.state = newState;
await DCSInstance.reloadInstances();
if (newState === 'IDLE')
if (newState === 'IDLE')
this.setActiveInstance(undefined);
}