Added code to save edited database to disk

This commit is contained in:
Pax1601 2023-09-27 21:46:05 +02:00
parent 7a24e5d39d
commit 39ddf10ca7
19 changed files with 3836 additions and 43487 deletions

View File

@ -3,6 +3,7 @@ var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var fs = require('fs');
var bodyParser = require('body-parser');
var atcRouter = require('./routes/api/atc');
var airbasesRouter = require('./routes/api/airbases');
@ -12,12 +13,13 @@ var uikitRouter = require('./routes/uikit');
var usersRouter = require('./routes/users');
var resourcesRouter = require('./routes/resources');
var pluginsRouter = require('./routes/plugins');
var databasesRouter = require('./routes/databases');
var app = express();
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
@ -25,6 +27,7 @@ app.use('/', indexRouter);
app.use('/api/atc', atcRouter);
app.use('/api/airbases', airbasesRouter);
app.use('/api/elevation', elevationRouter);
app.use('/api/databases', databasesRouter);
app.use('/plugins', pluginsRouter)
app.use('/users', usersRouter);
app.use('/uikit', uikitRouter);

5356
client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,7 @@
"watch": "watchify .\\src\\index.ts --debug -o .\\public\\javascripts\\bundle.js -t [ babelify --global true --presets [ @babel/preset-env ] --extensions '.js'] -p [ tsify --noImplicitAny ]"
},
"dependencies": {
"body-parser": "^1.20.2",
"cookie-parser": "~1.4.4",
"debug": "~2.6.9",
"ejs": "^3.1.8",

View File

@ -1,4 +1,4 @@
import { OlympusPlugin } from "interfaces";
import { OlympusPlugin, UnitBlueprint } from "interfaces";
import { AirUnitEditor } from "./airuniteditor";
import { OlympusApp } from "olympusapp";
import { GroundUnitEditor } from "./grounduniteditor";
@ -88,7 +88,19 @@ export class DatabaseManagerPlugin implements OlympusPlugin {
this.#button5 = document.createElement("button");
this.#button5.textContent = "Save";
this.#button5.title = "Save the changes on the server"
this.#button5.onclick = () => { };
this.#button5.onclick = () => {
var aircraftDatabase = this.#aircraftEditor.getDatabase();
if (aircraftDatabase)
this.uploadDatabase(aircraftDatabase, "aircraftdatabase");
var helicopterDatabase = this.#helicopterEditor.getDatabase();
if (helicopterDatabase)
this.uploadDatabase(helicopterDatabase, "helicopterDatabase");
var groundUnitDatabase = this.#groundUnitEditor.getDatabase();
if (groundUnitDatabase)
this.uploadDatabase(groundUnitDatabase, "groundUnitDatabase");
};
bottomButtonContainer.appendChild(this.#button5);
this.#button6 = document.createElement("button");
@ -128,7 +140,10 @@ export class DatabaseManagerPlugin implements OlympusPlugin {
var arr = Array.prototype.slice.call(elements);
arr.splice(arr.length - 1, 0, mainButtonDiv);
toolbar.getMainDropdown().setOptionsElements(arr);
mainButton.onclick = () => { this.toggle(); }
mainButton.onclick = () => {
toolbar.getMainDropdown().close();
this.toggle();
}
return true;
}
@ -172,4 +187,18 @@ export class DatabaseManagerPlugin implements OlympusPlugin {
this.#button3.classList.remove("selected");
this.#button4.classList.remove("selected");
}
uploadDatabase(database: {blueprints: {[key: string]: UnitBlueprint}}, databaseName: string) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("PUT", "/api/databases/units/" + databaseName);
xmlHttp.setRequestHeader("Content-Type", "application/json");
xmlHttp.onload = (res: any) => {
this.#app?.getPopupsManager().get("infoPopup")?.setText(databaseName + " saved successfully");
};
xmlHttp.onerror = (res: any) => {
this.#app?.getPopupsManager().get("infoPopup")?.setText("An error has occurring saving the database: " + databaseName)
console.log(res);
}
xmlHttp.send(JSON.stringify(database));
}
}

View File

@ -48,6 +48,10 @@ export abstract class UnitEditor {
this.contentDiv3.replaceChildren();
}
getDatabase() {
return this.database;
}
abstract setBlueprint(blueprint: UnitBlueprint): void;
abstract addBlueprint(key: string): void;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -100,7 +100,7 @@
top: 100px;
left: 50%;
translate: -50% 0%;
z-index: 9999;
z-index: 999999;
display: flex;
align-items: center;
}

View File

@ -1,8 +1,27 @@
.ol-popup {
display: flex;
flex-direction: column;
row-gap: 5px;
}
.ol-popup > div {
background-color: var(--background-steel);
border-radius: var(--border-radius-md);
box-shadow: 0px 2px 5px #000A;
color: white;
font-size: 12px;
height: fit-content;
width: fit-content;
padding-top: 5px;
padding-bottom: 5px;
padding-left: 15px;
padding-right: 15px;
}
.ol-popup-stack {
transform: translateY(+80%);
}
.visible {
opacity: 1;
}

View File

@ -117,7 +117,6 @@ form>div {
.ol-panel {
background-color: var(--background-steel);
border-radius: var(--border-radius-md);
;
box-shadow: 0px 2px 5px #000A;
color: white;
font-size: 12px;

View File

@ -0,0 +1,31 @@
const express = require('express');
const router = express.Router();
const fs = require("fs");
const path = require("path");
router.get('/:type/:name', function (req, res) {
console.log(req.params.database)
});
router.put('/:type/:name', function (req, res) {
var filepath = path.join("./public/databases", req.params.type, req.params.name + ".json");
if (fs.existsSync(filepath)) {
var newFilepath = filepath + ".old";
fs.copyFileSync(filepath, newFilepath);
if (fs.existsSync(newFilepath)) {
try {
var json = JSON.stringify(req.body.blueprints);
fs.writeFileSync(filepath, json, 'utf8');
res.send('OK')
} catch {
res.status(422);
}
} else {
res.status(422);
}
} else {
res.status(404);
}
});
module.exports = router;

View File

@ -44,10 +44,6 @@ export class OlympusApp {
#toolbarsManager: Manager | null = null;
#shortcutManager: ShortcutManager | null = null;
/* UI Toolbars */
#primaryToolbar: PrimaryToolbar | null = null;
#commandModeToolbar: CommandModeToolbar | null = null;
constructor() {
}

View File

@ -1,31 +1,58 @@
import { Panel } from "../panels/panel";
export class Popup extends Panel {
export class PopupMessage {
#element: HTMLDivElement;
#fadeTime: number = 2000; // Milliseconds
constructor( elementId:string ) {
super( elementId );
constructor(text: string, fateTime: number) {
this.#element = document.createElement("div");
this.#fadeTime = fateTime;
this.#element.innerText = text;
this.#element.classList.remove("invisible");
this.#element.classList.add("visible");
window.setTimeout(() => {
this.#element.classList.remove("visible");
this.#element.classList.add("invisible");
window.setTimeout(() => {
this.#element.dispatchEvent(new Event("removed"));
this.#element.remove();
}, 2000);
}, this.#fadeTime);
}
getElement() {
return this.#element;
}
}
export class Popup extends Panel {
#messages: PopupMessage[] = [];
#stackAfter: number;
constructor(ID: string, stackAfter: number = 5) {
super(ID);
this.show();
this.#stackAfter = stackAfter;
}
#fadeTime: number = 2000; // Milliseconds
#hideTimer: number | undefined = undefined;
#visibilityTimer: number | undefined = undefined;
setFadeTime(fadeTime: number) {
this.#fadeTime = fadeTime;
}
setText(text: string) {
(<HTMLElement> this.getElement().querySelector("div")).innerText = text;
this.show();
this.getElement().classList.remove("invisible");
this.getElement().classList.add("visible");
clearTimeout(this.#visibilityTimer);
clearTimeout(this.#hideTimer);
this.#visibilityTimer = window.setTimeout(() => {
this.getElement().classList.remove("visible");
this.getElement().classList.add("invisible");
this.#hideTimer = window.setTimeout(() => this.hide(), 2000);
}, this.#fadeTime);
setText(text: string) {
var message = new PopupMessage(text, this.#fadeTime);
message.getElement().addEventListener("removed", () => {
var index = this.#messages.indexOf(message);
if (index !== -1)
this.#messages.splice(index, 1);
})
this.getElement().appendChild(message.getElement());
this.#messages.push(message);
if (this.#messages.length > this.#stackAfter) {
this.#messages[this.#messages.length - this.#stackAfter].getElement().classList.add("ol-popup-stack");
}
}
}

View File

@ -86,7 +86,7 @@ export class ServerManager {
xmlHttp.send(null);
}
POST(request: object, callback: CallableFunction) {
PUT(request: object, callback: CallableFunction) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("PUT", this.#demoEnabled ? this.#DEMO_ADDRESS : this.#REST_ADDRESS);
xmlHttp.setRequestHeader("Content-Type", "application/json");
@ -148,49 +148,49 @@ export class ServerManager {
addDestination(ID: number, path: any, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "path": path }
var data = { "setPath": command }
this.POST(data, callback);
this.PUT(data, callback);
}
spawnSmoke(color: string, latlng: LatLng, callback: CallableFunction = () => {}) {
var command = { "color": color, "location": latlng };
var data = { "smoke": command }
this.POST(data, callback);
this.PUT(data, callback);
}
spawnExplosion(intensity: number, latlng: LatLng, callback: CallableFunction = () => {}) {
var command = { "intensity": intensity, "location": latlng };
var data = { "explosion": command }
this.POST(data, callback);
this.PUT(data, callback);
}
spawnAircrafts(units: any, coalition: string, airbaseName: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) {
var command = { "units": units, "coalition": coalition, "airbaseName": airbaseName, "country": country, "immediate": immediate, "spawnPoints": spawnPoints };
var data = { "spawnAircrafts": command }
this.POST(data, callback);
this.PUT(data, callback);
}
spawnHelicopters(units: any, coalition: string, airbaseName: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) {
var command = { "units": units, "coalition": coalition, "airbaseName": airbaseName, "country": country, "immediate": immediate, "spawnPoints": spawnPoints };
var data = { "spawnHelicopters": command }
this.POST(data, callback);
this.PUT(data, callback);
}
spawnGroundUnits(units: any, coalition: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) {
var command = { "units": units, "coalition": coalition, "country": country, "immediate": immediate, "spawnPoints": spawnPoints };;
var data = { "spawnGroundUnits": command }
this.POST(data, callback);
this.PUT(data, callback);
}
spawnNavyUnits(units: any, coalition: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) {
var command = { "units": units, "coalition": coalition, "country": country, "immediate": immediate, "spawnPoints": spawnPoints };
var data = { "spawnNavyUnits": command }
this.POST(data, callback);
this.PUT(data, callback);
}
attackUnit(ID: number, targetID: number, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "targetID": targetID };
var data = { "attackUnit": command }
this.POST(data, callback);
this.PUT(data, callback);
}
followUnit(ID: number, targetID: number, offset: { "x": number, "y": number, "z": number }, callback: CallableFunction = () => {}) {
@ -200,127 +200,127 @@ export class ServerManager {
var command = { "ID": ID, "targetID": targetID, "offsetX": offset["x"], "offsetY": offset["y"], "offsetZ": offset["z"] };
var data = { "followUnit": command }
this.POST(data, callback);
this.PUT(data, callback);
}
cloneUnits(units: {ID: number, location: LatLng}[], deleteOriginal: boolean, spawnPoints: number, callback: CallableFunction = () => {}) {
var command = { "units": units, "deleteOriginal": deleteOriginal, "spawnPoints": spawnPoints };
var data = { "cloneUnits": command }
this.POST(data, callback);
this.PUT(data, callback);
}
deleteUnit(ID: number, explosion: boolean, immediate: boolean, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "explosion": explosion, "immediate": immediate };
var data = { "deleteUnit": command }
this.POST(data, callback);
this.PUT(data, callback);
}
landAt(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "location": latlng };
var data = { "landAt": command }
this.POST(data, callback);
this.PUT(data, callback);
}
changeSpeed(ID: number, speedChange: string, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "change": speedChange }
var data = { "changeSpeed": command }
this.POST(data, callback);
this.PUT(data, callback);
}
setSpeed(ID: number, speed: number, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "speed": speed }
var data = { "setSpeed": command }
this.POST(data, callback);
this.PUT(data, callback);
}
setSpeedType(ID: number, speedType: string, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "speedType": speedType }
var data = { "setSpeedType": command }
this.POST(data, callback);
this.PUT(data, callback);
}
changeAltitude(ID: number, altitudeChange: string, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "change": altitudeChange }
var data = { "changeAltitude": command }
this.POST(data, callback);
this.PUT(data, callback);
}
setAltitudeType(ID: number, altitudeType: string, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "altitudeType": altitudeType }
var data = { "setAltitudeType": command }
this.POST(data, callback);
this.PUT(data, callback);
}
setAltitude(ID: number, altitude: number, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "altitude": altitude }
var data = { "setAltitude": command }
this.POST(data, callback);
this.PUT(data, callback);
}
createFormation(ID: number, isLeader: boolean, wingmenIDs: number[], callback: CallableFunction = () => {}) {
var command = { "ID": ID, "wingmenIDs": wingmenIDs, "isLeader": isLeader }
var data = { "setLeader": command }
this.POST(data, callback);
this.PUT(data, callback);
}
setROE(ID: number, ROE: string, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "ROE": ROEs.indexOf(ROE) }
var data = { "setROE": command }
this.POST(data, callback);
this.PUT(data, callback);
}
setReactionToThreat(ID: number, reactionToThreat: string, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "reactionToThreat": reactionsToThreat.indexOf(reactionToThreat) }
var data = { "setReactionToThreat": command }
this.POST(data, callback);
this.PUT(data, callback);
}
setEmissionsCountermeasures(ID: number, emissionCountermeasure: string, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "emissionsCountermeasures": emissionsCountermeasures.indexOf(emissionCountermeasure) }
var data = { "setEmissionsCountermeasures": command }
this.POST(data, callback);
this.PUT(data, callback);
}
setOnOff(ID: number, onOff: boolean, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "onOff": onOff }
var data = { "setOnOff": command }
this.POST(data, callback);
this.PUT(data, callback);
}
setFollowRoads(ID: number, followRoads: boolean, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "followRoads": followRoads }
var data = { "setFollowRoads": command }
this.POST(data, callback);
this.PUT(data, callback);
}
refuel(ID: number, callback: CallableFunction = () => {}) {
var command = { "ID": ID };
var data = { "refuel": command }
this.POST(data, callback);
this.PUT(data, callback);
}
bombPoint(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "location": latlng }
var data = { "bombPoint": command }
this.POST(data, callback);
this.PUT(data, callback);
}
carpetBomb(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "location": latlng }
var data = { "carpetBomb": command }
this.POST(data, callback);
this.PUT(data, callback);
}
bombBuilding(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "location": latlng }
var data = { "bombBuilding": command }
this.POST(data, callback);
this.PUT(data, callback);
}
fireAtArea(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "location": latlng }
var data = { "fireAtArea": command }
this.POST(data, callback);
this.PUT(data, callback);
}
setAdvacedOptions(ID: number, isTanker: boolean, isAWACS: boolean, TACAN: TACAN, radio: Radio, generalSettings: GeneralSettings, callback: CallableFunction = () => {}) {
@ -334,7 +334,7 @@ export class ServerManager {
};
var data = { "setAdvancedOptions": command };
this.POST(data, callback);
this.PUT(data, callback);
}
setCommandModeOptions(restrictSpawns: boolean, restrictToCoalition: boolean, spawnPoints: {blue: number, red: number}, eras: string[], setupTime: number, callback: CallableFunction = () => {}) {
@ -347,7 +347,7 @@ export class ServerManager {
};
var data = { "setCommandModeOptions": command };
this.POST(data, callback);
this.PUT(data, callback);
}
startUpdate() {

View File

@ -1,5 +1,3 @@
<div id="info-popup" class="ol-panel ol-popup hide" oncontextmenu="return false;">
<div>
<!-- Here the content of the popup will be shown -->
</div>
<div id="info-popup" class="ol-popup hide" oncontextmenu="return false;">
</div>