mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Transitioned server to typescript
This commit is contained in:
78
frontend/server/src/app.ts
Normal file
78
frontend/server/src/app.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
/* Requires */
|
||||
import express = require("express");
|
||||
import path = require("path");
|
||||
import logger = require("morgan");
|
||||
import fs = require("fs");
|
||||
import bodyParser = require("body-parser");
|
||||
import cors = require("cors");
|
||||
|
||||
/* Load the proxy middleware plugin */
|
||||
import httpProxyMiddleware = require("http-proxy-middleware");
|
||||
|
||||
module.exports = function (configLocation) {
|
||||
/* Config specific routers */
|
||||
const elevationRouter = require("./routes/api/elevation")(configLocation);
|
||||
const resourcesRouter = require("./routes/resources")(configLocation);
|
||||
|
||||
/* Default routers */
|
||||
const airbasesRouter = require("./routes/api/airbases");
|
||||
const databasesRouter = require("./routes/api/databases")(
|
||||
path.join(
|
||||
path.dirname(configLocation),
|
||||
"..",
|
||||
"Mods",
|
||||
"Services",
|
||||
"Olympus",
|
||||
"databases"
|
||||
)
|
||||
);
|
||||
const indexRouter = require("./routes/index");
|
||||
const pluginsRouter = require("./routes/plugins");
|
||||
|
||||
/* Load the config and create the express app */
|
||||
let config = {};
|
||||
console.log(`Loading configuration file from ${configLocation}`);
|
||||
if (fs.existsSync(configLocation)) {
|
||||
let rawdata = fs.readFileSync(configLocation, { encoding: "utf-8" });
|
||||
config = JSON.parse(rawdata);
|
||||
} else {
|
||||
console.error("Error loading configuration file.");
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/* Load the backend address where DCS is listening */
|
||||
const backendAddress = config["backend"]["address"];
|
||||
|
||||
/* Start the express app */
|
||||
const app = express();
|
||||
|
||||
/* Define middleware */
|
||||
app.use(logger("dev"));
|
||||
app.use(
|
||||
"/olympus",
|
||||
httpProxyMiddleware.createProxyMiddleware({
|
||||
target: `http://${
|
||||
backendAddress === "*" ? "localhost" : backendAddress
|
||||
}:${config["backend"]["port"]}/`,
|
||||
changeOrigin: true,
|
||||
})
|
||||
);
|
||||
app.use(
|
||||
"/vite",
|
||||
httpProxyMiddleware.createProxyMiddleware({ target: `http://localhost:8080/`, ws: true })
|
||||
);
|
||||
app.use(bodyParser.json({ limit: "50mb" }));
|
||||
app.use(bodyParser.urlencoded({ limit: "50mb", extended: true }));
|
||||
app.use(express.static(path.join(__dirname, "public")));
|
||||
app.use(cors());
|
||||
|
||||
/* Apply routers */
|
||||
app.use("/", indexRouter);
|
||||
app.use("/api/airbases", airbasesRouter);
|
||||
app.use("/api/elevation", elevationRouter);
|
||||
app.use("/api/databases", databasesRouter);
|
||||
app.use("/plugins", pluginsRouter);
|
||||
app.use("/resources", resourcesRouter);
|
||||
|
||||
return app;
|
||||
};
|
||||
652
frontend/server/src/demo/demo.ts
Normal file
652
frontend/server/src/demo/demo.ts
Normal file
@@ -0,0 +1,652 @@
|
||||
const TEST_UNIT_GENERATION = false;
|
||||
|
||||
module.exports = function (configLocation) {
|
||||
var basicAuth = require("express-basic-auth");
|
||||
var logger = require("morgan");
|
||||
var enc = new TextEncoder();
|
||||
const path = require("path");
|
||||
var cors = require("cors");
|
||||
|
||||
var express = require("express");
|
||||
var fs = require("fs");
|
||||
|
||||
let rawdata = fs.readFileSync(configLocation);
|
||||
let config = JSON.parse(rawdata);
|
||||
|
||||
var app = express();
|
||||
|
||||
app.use(logger("dev"));
|
||||
app.use(cors());
|
||||
|
||||
const DEMO_UNIT_DATA = {};
|
||||
const DEMO_WEAPONS_DATA = {};
|
||||
|
||||
class DemoDataGenerator {
|
||||
startTime: number;
|
||||
|
||||
constructor(app, config) {
|
||||
app.get("/olympus/units", (req, res) => this.units(req, res));
|
||||
app.get("/olympus/weapons", (req, res) => this.weapons(req, res));
|
||||
app.get("/olympus/logs", (req, res) => this.logs(req, res));
|
||||
app.get("/olympus/bullseyes", (req, res) => this.bullseyes(req, res));
|
||||
app.get("/olympus/airbases", (req, res) => this.airbases(req, res));
|
||||
app.get("/olympus/mission", (req, res) => this.mission(req, res));
|
||||
app.get("/olympus/commands", (req, res) => this.command(req, res));
|
||||
app.put("/olympus", (req, res) => this.put(req, res));
|
||||
|
||||
app.use(
|
||||
"/olympus",
|
||||
basicAuth({
|
||||
users: {
|
||||
admin: config["authentication"]["gameMasterPassword"],
|
||||
blue: config["authentication"]["blueCommanderPassword"],
|
||||
red: config["authentication"]["redCommanderPassword"],
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
let baseData = {
|
||||
alive: true,
|
||||
human: false,
|
||||
controlled: true,
|
||||
coalition: 2,
|
||||
country: 0,
|
||||
unitName: "Cool guy",
|
||||
groupName: "Cool group 1",
|
||||
state: 13,
|
||||
task: "Being cool!",
|
||||
hasTask: true,
|
||||
position: { lat: 37, lng: -116, alt: 1000 },
|
||||
speed: 200,
|
||||
horizontalVelocity: 200,
|
||||
verticalVelicity: 0,
|
||||
heading: 45,
|
||||
track: 45,
|
||||
isActiveTanker: false,
|
||||
isActiveAWACS: false,
|
||||
onOff: true,
|
||||
followRoads: false,
|
||||
fuel: 50,
|
||||
desiredSpeed: 300,
|
||||
desiredSpeedType: 1,
|
||||
desiredAltitude: 1000,
|
||||
desiredAltitudeType: 1,
|
||||
leaderID: 0,
|
||||
formationOffset: { x: 0, y: 0, z: 0 },
|
||||
targetID: 0,
|
||||
targetPosition: { lat: 0, lng: 0, alt: 0 },
|
||||
ROE: 1,
|
||||
reactionToThreat: 1,
|
||||
emissionsCountermeasures: 1,
|
||||
TACAN: { isOn: false, XY: "Y", callsign: "TKR", channel: 40 },
|
||||
radio: { frequency: 124000000, callsign: 1, callsignNumber: 1 },
|
||||
generalSettings: {
|
||||
prohibitAA: false,
|
||||
prohibitAfterburner: false,
|
||||
prohibitAG: false,
|
||||
prohibitAirWpn: false,
|
||||
prohibitJettison: false,
|
||||
},
|
||||
ammo: [],
|
||||
contacts: [],
|
||||
activePath: [{ lat: 37.1, lng: -116.1 }],
|
||||
isLeader: true,
|
||||
};
|
||||
|
||||
if (TEST_UNIT_GENERATION) {
|
||||
const aircraftDatabase = require(path.join(
|
||||
path.dirname(configLocation),
|
||||
"../../Mods/Services/Olympus/databases/units/aircraftdatabase.json"
|
||||
));
|
||||
const helicopterDatabase = require(path.join(
|
||||
path.dirname(configLocation),
|
||||
"../../Mods/Services/Olympus/databases/units/helicopterdatabase.json"
|
||||
));
|
||||
const groundUnitDatabase = require(path.join(
|
||||
path.dirname(configLocation),
|
||||
"../../Mods/Services/Olympus/databases/units/groundunitdatabase.json"
|
||||
));
|
||||
const navyUnitDatabase = require(path.join(
|
||||
path.dirname(configLocation),
|
||||
"../../Mods/Services/Olympus/databases/units/navyunitdatabase.json"
|
||||
));
|
||||
|
||||
var databases = Object.assign(
|
||||
{},
|
||||
aircraftDatabase,
|
||||
helicopterDatabase,
|
||||
groundUnitDatabase,
|
||||
navyUnitDatabase
|
||||
);
|
||||
var t = Object.keys(databases).length;
|
||||
var l = Math.floor(Math.sqrt(t));
|
||||
let latIdx = 0;
|
||||
let lngIdx = 0;
|
||||
let idx = 1;
|
||||
|
||||
for (let name in databases) {
|
||||
if (databases[name].enabled) {
|
||||
DEMO_UNIT_DATA[idx] = JSON.parse(JSON.stringify(baseData));
|
||||
DEMO_UNIT_DATA[idx].name = name;
|
||||
DEMO_UNIT_DATA[idx].groupName = `Group-${idx}`;
|
||||
DEMO_UNIT_DATA[idx].position.lat += latIdx / 5;
|
||||
DEMO_UNIT_DATA[idx].position.lng += lngIdx / 5;
|
||||
DEMO_UNIT_DATA[idx].coalition = Math.floor(Math.random() * 3);
|
||||
|
||||
latIdx += 1;
|
||||
if (latIdx === l) {
|
||||
latIdx = 0;
|
||||
lngIdx += 1;
|
||||
}
|
||||
|
||||
if (name in aircraftDatabase)
|
||||
DEMO_UNIT_DATA[idx].category = "Aircraft";
|
||||
else if (name in helicopterDatabase)
|
||||
DEMO_UNIT_DATA[idx].category = "Helicopter";
|
||||
else if (name in groundUnitDatabase)
|
||||
DEMO_UNIT_DATA[idx].category = "GroundUnit";
|
||||
else if (name in navyUnitDatabase)
|
||||
DEMO_UNIT_DATA[idx].category = "NavyUnit";
|
||||
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let idx = 1;
|
||||
DEMO_UNIT_DATA[idx] = JSON.parse(JSON.stringify(baseData));
|
||||
DEMO_UNIT_DATA[idx].name = "S_75M_Volhov";
|
||||
DEMO_UNIT_DATA[idx].groupName = `Group`;
|
||||
DEMO_UNIT_DATA[idx].position.lat += idx / 100;
|
||||
DEMO_UNIT_DATA[idx].category = "GroundUnit";
|
||||
DEMO_UNIT_DATA[idx].isLeader = true;
|
||||
|
||||
idx += 1;
|
||||
DEMO_UNIT_DATA[idx] = JSON.parse(JSON.stringify(baseData));
|
||||
DEMO_UNIT_DATA[idx].name = "SNR_75V";
|
||||
DEMO_UNIT_DATA[idx].groupName = `Group`;
|
||||
DEMO_UNIT_DATA[idx].position.lat += idx / 100;
|
||||
DEMO_UNIT_DATA[idx].category = "GroundUnit";
|
||||
DEMO_UNIT_DATA[idx].isLeader = false;
|
||||
|
||||
idx += 1;
|
||||
DEMO_UNIT_DATA[idx] = JSON.parse(JSON.stringify(baseData));
|
||||
DEMO_UNIT_DATA[idx].name = "Ural-4320 APA-5D";
|
||||
DEMO_UNIT_DATA[idx].groupName = `Group`;
|
||||
DEMO_UNIT_DATA[idx].position.lat += idx / 100;
|
||||
DEMO_UNIT_DATA[idx].category = "GroundUnit";
|
||||
DEMO_UNIT_DATA[idx].isLeader = false;
|
||||
|
||||
idx += 1;
|
||||
DEMO_UNIT_DATA[idx] = JSON.parse(JSON.stringify(baseData));
|
||||
DEMO_UNIT_DATA[idx].name = "F-14B";
|
||||
DEMO_UNIT_DATA[idx].groupName = `Group-1`;
|
||||
DEMO_UNIT_DATA[idx].position.lat += idx / 100;
|
||||
DEMO_UNIT_DATA[idx].category = "Aircraft";
|
||||
DEMO_UNIT_DATA[idx].isLeader = false;
|
||||
DEMO_UNIT_DATA[idx].coalition = 1;
|
||||
DEMO_UNIT_DATA[idx].desiredAltitude = 10000;
|
||||
DEMO_UNIT_DATA[idx].desiredAltitudeType = 0;
|
||||
|
||||
idx += 1;
|
||||
DEMO_UNIT_DATA[idx] = JSON.parse(JSON.stringify(baseData));
|
||||
DEMO_UNIT_DATA[idx].name = "Infantry AK";
|
||||
DEMO_UNIT_DATA[idx].groupName = `Group-2`;
|
||||
DEMO_UNIT_DATA[idx].position.lat += idx / 100;
|
||||
DEMO_UNIT_DATA[idx].category = "GroundUnit";
|
||||
DEMO_UNIT_DATA[idx].isLeader = true;
|
||||
DEMO_UNIT_DATA[idx].coalition = 0;
|
||||
DEMO_UNIT_DATA[idx].operateAs = 2;
|
||||
|
||||
idx += 1;
|
||||
DEMO_UNIT_DATA[idx] = JSON.parse(JSON.stringify(baseData));
|
||||
DEMO_UNIT_DATA[idx].name = "Infantry AK";
|
||||
DEMO_UNIT_DATA[idx].groupName = `Group-3`;
|
||||
DEMO_UNIT_DATA[idx].position.lat += idx / 100;
|
||||
DEMO_UNIT_DATA[idx].category = "GroundUnit";
|
||||
DEMO_UNIT_DATA[idx].isLeader = true;
|
||||
DEMO_UNIT_DATA[idx].coalition = 0;
|
||||
DEMO_UNIT_DATA[idx].operateAs = 1;
|
||||
|
||||
idx += 1;
|
||||
DEMO_UNIT_DATA[idx] = JSON.parse(JSON.stringify(baseData));
|
||||
DEMO_UNIT_DATA[idx].name = "KC-135";
|
||||
DEMO_UNIT_DATA[idx].groupName = `Group-4`;
|
||||
DEMO_UNIT_DATA[idx].position.lat += idx / 100;
|
||||
DEMO_UNIT_DATA[idx].category = "Aircraft";
|
||||
DEMO_UNIT_DATA[idx].isLeader = true;
|
||||
|
||||
this.startTime = Date.now();
|
||||
}
|
||||
}
|
||||
|
||||
units(req, res) {
|
||||
var array = new Uint8Array();
|
||||
var time = Date.now();
|
||||
array = this.concat(array, this.uint64ToByteArray(BigInt(time)));
|
||||
if (req.query["time"] == 0) {
|
||||
for (let idx in DEMO_UNIT_DATA) {
|
||||
const unit = DEMO_UNIT_DATA[idx];
|
||||
var dataIndex = 1;
|
||||
array = this.concat(array, this.uint32ToByteArray(idx));
|
||||
array = this.appendString(array, unit.category, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint8(array, unit.alive, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint8(array, unit.human, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint8(array, unit.controlled, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint16(array, unit.coalition, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint8(array, unit.country, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendString(array, unit.name, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendString(array, unit.unitName, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendString(array, unit.groupName, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint8(array, unit.state, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendString(array, unit.task, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint8(array, unit.hasTask, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendCoordinates(array, unit.position, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendDouble(array, unit.speed, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendDouble(array, unit.horizontalVelocity, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendDouble(array, unit.verticalVelicity, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendDouble(array, unit.heading, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendDouble(array, unit.track, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint8(array, unit.isActiveTanker, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint8(array, unit.isActiveAWACS, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint8(array, unit.onOff, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint8(array, unit.followRoads, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint16(array, unit.fuel, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendDouble(array, unit.desiredSpeed, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint8(array, unit.desiredSpeedType, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendDouble(array, unit.desiredAltitude, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint8(array, unit.desiredAltitudeType, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint32(array, unit.leaderID, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendOffset(array, unit.formationOffset, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint32(array, unit.targetID, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendCoordinates(array, unit.targetPosition, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint8(array, unit.ROE, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint8(array, unit.reactionToThreat, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint8(
|
||||
array,
|
||||
unit.emissionsCountermeasures,
|
||||
dataIndex
|
||||
);
|
||||
dataIndex++;
|
||||
array = this.appendTACAN(array, unit.TACAN, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendRadio(array, unit.radio, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendRadio(array, unit.generalSettings, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendAmmo(array, unit.ammo, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendContacts(array, unit.contacts, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendActivePath(array, unit.activePath, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint8(array, unit.isLeader, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.appendUint8(array, unit.operateAs, dataIndex);
|
||||
dataIndex++;
|
||||
array = this.concat(array, this.uint8ToByteArray(255));
|
||||
}
|
||||
}
|
||||
res.end(Buffer.from(array));
|
||||
}
|
||||
|
||||
weapons(req, res) {
|
||||
var array = new Uint8Array();
|
||||
var time = Date.now();
|
||||
array = this.concat(array, this.uint64ToByteArray(BigInt(time)));
|
||||
for (let idx in DEMO_WEAPONS_DATA) {
|
||||
const weapon = DEMO_WEAPONS_DATA[idx];
|
||||
array = this.concat(array, this.uint32ToByteArray(idx));
|
||||
array = this.appendString(array, weapon.category, 1);
|
||||
array = this.appendUint8(array, weapon.alive, 2);
|
||||
array = this.appendUint16(array, weapon.coalition, 5);
|
||||
array = this.appendString(array, weapon.name, 7);
|
||||
array = this.appendCoordinates(array, weapon.position, 13);
|
||||
array = this.appendDouble(array, weapon.speed, 14);
|
||||
array = this.appendDouble(array, weapon.heading, 15);
|
||||
array = this.concat(array, this.uint8ToByteArray(255));
|
||||
}
|
||||
res.end(Buffer.from(array));
|
||||
}
|
||||
|
||||
concat(array1, array2) {
|
||||
var mergedArray = new Uint8Array(array1.length + array2.length);
|
||||
mergedArray.set(array1);
|
||||
mergedArray.set(array2, array1.length);
|
||||
return mergedArray;
|
||||
}
|
||||
|
||||
uint8ToByteArray(number) {
|
||||
var buffer = new ArrayBuffer(1);
|
||||
var longNum = new Uint8Array(buffer);
|
||||
longNum[0] = number;
|
||||
return Array.from(new Uint8Array(buffer));
|
||||
}
|
||||
|
||||
uint16ToByteArray(number) {
|
||||
var buffer = new ArrayBuffer(2);
|
||||
var longNum = new Uint16Array(buffer);
|
||||
longNum[0] = number;
|
||||
return Array.from(new Uint8Array(buffer));
|
||||
}
|
||||
|
||||
uint32ToByteArray(number) {
|
||||
var buffer = new ArrayBuffer(4);
|
||||
var longNum = new Uint32Array(buffer);
|
||||
longNum[0] = number;
|
||||
return Array.from(new Uint8Array(buffer));
|
||||
}
|
||||
|
||||
uint64ToByteArray(number) {
|
||||
var buffer = new ArrayBuffer(8);
|
||||
var longNum = new BigUint64Array(buffer);
|
||||
longNum[0] = number;
|
||||
return Array.from(new Uint8Array(buffer));
|
||||
}
|
||||
|
||||
doubleToByteArray(number) {
|
||||
var buffer = new ArrayBuffer(8);
|
||||
var longNum = new Float64Array(buffer);
|
||||
longNum[0] = number;
|
||||
return Array.from(new Uint8Array(buffer));
|
||||
}
|
||||
|
||||
appendUint8(array, number, datumIndex) {
|
||||
array = this.concat(array, this.uint8ToByteArray(datumIndex));
|
||||
array = this.concat(array, this.uint8ToByteArray(number));
|
||||
return array;
|
||||
}
|
||||
|
||||
appendUint16(array, number, datumIndex) {
|
||||
array = this.concat(array, this.uint8ToByteArray(datumIndex));
|
||||
array = this.concat(array, this.uint16ToByteArray(number));
|
||||
return array;
|
||||
}
|
||||
|
||||
appendUint32(array, number, datumIndex) {
|
||||
array = this.concat(array, this.uint8ToByteArray(datumIndex));
|
||||
array = this.concat(array, this.uint32ToByteArray(number));
|
||||
return array;
|
||||
}
|
||||
|
||||
appendDouble(array, number, datumIndex) {
|
||||
array = this.concat(array, this.uint8ToByteArray(datumIndex));
|
||||
array = this.concat(array, this.doubleToByteArray(number));
|
||||
return array;
|
||||
}
|
||||
|
||||
appendCoordinates(array, coordinates, datumIndex) {
|
||||
array = this.concat(array, this.uint8ToByteArray(datumIndex));
|
||||
array = this.concat(array, this.doubleToByteArray(coordinates.lat));
|
||||
array = this.concat(array, this.doubleToByteArray(coordinates.lng));
|
||||
array = this.concat(array, this.doubleToByteArray(coordinates.alt));
|
||||
return array;
|
||||
}
|
||||
|
||||
appendOffset(array, offset, datumIndex) {
|
||||
array = this.concat(array, this.uint8ToByteArray(datumIndex));
|
||||
array = this.concat(array, this.doubleToByteArray(offset.x));
|
||||
array = this.concat(array, this.doubleToByteArray(offset.y));
|
||||
array = this.concat(array, this.doubleToByteArray(offset.z));
|
||||
return array;
|
||||
}
|
||||
|
||||
appendString(array, string, datumIndex) {
|
||||
array = this.concat(array, this.uint8ToByteArray(datumIndex));
|
||||
array = this.concat(array, this.uint16ToByteArray(string.length));
|
||||
array = this.concat(array, enc.encode(string));
|
||||
return array;
|
||||
}
|
||||
|
||||
padString(string, length) {
|
||||
while (string.length < length) string += " ";
|
||||
return string.substring(0, length);
|
||||
}
|
||||
|
||||
appendTACAN(array, TACAN, datumIndex) {
|
||||
array = this.concat(array, this.uint8ToByteArray(datumIndex));
|
||||
array = this.concat(array, this.uint8ToByteArray(TACAN.isOn));
|
||||
array = this.concat(array, this.uint8ToByteArray(TACAN.channel));
|
||||
array = this.concat(array, enc.encode(TACAN.XY));
|
||||
array = this.concat(array, enc.encode(this.padString(TACAN.callsign, 4)));
|
||||
return array;
|
||||
}
|
||||
|
||||
appendRadio(array, radio, datumIndex) {
|
||||
array = this.concat(array, this.uint8ToByteArray(datumIndex));
|
||||
array = this.concat(array, this.uint32ToByteArray(radio.frequency));
|
||||
array = this.concat(array, this.uint8ToByteArray(radio.callsign));
|
||||
array = this.concat(array, this.uint8ToByteArray(radio.callsignNumber));
|
||||
return array;
|
||||
}
|
||||
|
||||
appendGeneralSettings(array, generalSettings, datumIndex) {
|
||||
array = this.concat(array, this.uint8ToByteArray(datumIndex));
|
||||
array = this.concat(
|
||||
array,
|
||||
this.uint8ToByteArray(generalSettings.prohibitAA)
|
||||
);
|
||||
array = this.concat(
|
||||
array,
|
||||
this.uint8ToByteArray(generalSettings.prohibitAfterburner)
|
||||
);
|
||||
array = this.concat(
|
||||
array,
|
||||
this.uint8ToByteArray(generalSettings.prohibitAG)
|
||||
);
|
||||
array = this.concat(
|
||||
array,
|
||||
this.uint8ToByteArray(generalSettings.prohibitAirWpn)
|
||||
);
|
||||
array = this.concat(
|
||||
array,
|
||||
this.uint8ToByteArray(generalSettings.prohibitJettison)
|
||||
);
|
||||
return array;
|
||||
}
|
||||
|
||||
appendAmmo(array, ammo, datumIndex) {
|
||||
array = this.concat(array, this.uint8ToByteArray(datumIndex));
|
||||
array = this.concat(array, this.uint16ToByteArray(ammo.length));
|
||||
ammo.forEach((element) => {
|
||||
array = this.concat(array, this.uint16ToByteArray(element.quantity));
|
||||
array = this.concat(
|
||||
array,
|
||||
enc.encode(this.padString(element.name, 33))
|
||||
);
|
||||
array = this.concat(array, this.uint8ToByteArray(element.guidance));
|
||||
array = this.concat(array, this.uint8ToByteArray(element.category));
|
||||
array = this.concat(
|
||||
array,
|
||||
this.uint8ToByteArray(element.missileCategory)
|
||||
);
|
||||
});
|
||||
return array;
|
||||
}
|
||||
|
||||
appendContacts(array, contacts, datumIndex) {
|
||||
array = this.concat(array, this.uint8ToByteArray(datumIndex));
|
||||
array = this.concat(array, this.uint16ToByteArray(contacts.length));
|
||||
contacts.forEach((element) => {
|
||||
array = this.concat(array, this.uint32ToByteArray(element.ID));
|
||||
array = this.concat(
|
||||
array,
|
||||
this.uint8ToByteArray(element.detectionMethod)
|
||||
);
|
||||
});
|
||||
return array;
|
||||
}
|
||||
|
||||
appendActivePath(array, activePath, datumIndex) {
|
||||
array = this.concat(array, this.uint8ToByteArray(datumIndex));
|
||||
array = this.concat(array, this.uint16ToByteArray(activePath.length));
|
||||
activePath.forEach((element) => {
|
||||
array = this.concat(array, this.doubleToByteArray(element.lat));
|
||||
array = this.concat(array, this.doubleToByteArray(element.lng));
|
||||
array = this.concat(array, this.doubleToByteArray(element.alt));
|
||||
});
|
||||
return array;
|
||||
}
|
||||
|
||||
logs(req, res) {
|
||||
var ret = {
|
||||
logs: { "1": "I'm a log!", "2": "I'm a different log!" },
|
||||
time: Date.now(),
|
||||
frameRate: 60,
|
||||
load: 0,
|
||||
};
|
||||
|
||||
res.send(JSON.stringify(ret));
|
||||
}
|
||||
|
||||
airbases(req, res) {
|
||||
var ret = {
|
||||
airbases: {
|
||||
["0"]: {
|
||||
callsign: "Nellis",
|
||||
latitude: 37.3,
|
||||
longitude: -115.8,
|
||||
coalition: "neutral",
|
||||
},
|
||||
["1"]: {
|
||||
callsign: "Red",
|
||||
latitude: 37.3,
|
||||
longitude: -115.75,
|
||||
coalition: "red",
|
||||
},
|
||||
["2"]: {
|
||||
callsign: "Blue",
|
||||
latitude: 37.3,
|
||||
longitude: -115.7,
|
||||
coalition: "blue",
|
||||
},
|
||||
},
|
||||
time: Date.now(),
|
||||
};
|
||||
res.send(JSON.stringify(ret));
|
||||
}
|
||||
|
||||
bullseyes(req, res) {
|
||||
var ret = {
|
||||
bullseyes: {
|
||||
"0": {
|
||||
latitude: 37.25,
|
||||
longitude: -115.8,
|
||||
coalition: "neutral",
|
||||
},
|
||||
"1": {
|
||||
latitude: 37.25,
|
||||
longitude: -115.75,
|
||||
coalition: "red",
|
||||
},
|
||||
"2": {
|
||||
latitude: 37.25,
|
||||
longitude: -115.7,
|
||||
coalition: "blue",
|
||||
},
|
||||
},
|
||||
time: Date.now(),
|
||||
};
|
||||
res.send(JSON.stringify(ret));
|
||||
}
|
||||
|
||||
mission(req, res) {
|
||||
var ret = {
|
||||
mission: {
|
||||
theatre: "Nevada",
|
||||
dateAndTime: {
|
||||
time: { h: 10, m: 15, s: 34 },
|
||||
date: "",
|
||||
elapsedTime: (Date.now() - this.startTime) / 1000,
|
||||
startTime: 0,
|
||||
},
|
||||
coalitions: {
|
||||
red: ["RUSSIA", "CHINA"],
|
||||
blue: ["UK", "USA"],
|
||||
neutral: ["ITALY"],
|
||||
},
|
||||
commandModeOptions: {
|
||||
restrictSpawns: true,
|
||||
restrictToCoalition: true,
|
||||
setupTime: 0,
|
||||
spawnPoints: {
|
||||
red: 400,
|
||||
blue: 400,
|
||||
},
|
||||
eras: ["WW2", "Early Cold War", "Late Cold War", "Modern"],
|
||||
commandMode: "",
|
||||
},
|
||||
},
|
||||
time: Date.now(),
|
||||
};
|
||||
|
||||
var auth = req.get("Authorization");
|
||||
if (auth) {
|
||||
var username = Buffer.from(auth.replace("Basic ", ""), "base64")
|
||||
.toString("binary")
|
||||
.split(":")[0];
|
||||
var password = Buffer.from(auth.replace("Basic ", ""), "base64")
|
||||
.toString("binary")
|
||||
.split(":")[1];
|
||||
switch (password) {
|
||||
case "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918":
|
||||
ret.mission.commandModeOptions.commandMode = "Game master";
|
||||
break;
|
||||
case "16477688c0e00699c6cfa4497a3612d7e83c532062b64b250fed8908128ed548":
|
||||
ret.mission.commandModeOptions.commandMode = "Blue commander";
|
||||
break;
|
||||
case "b1f51a511f1da0cd348b8f8598db32e61cb963e5fc69e2b41485bf99590ed75a":
|
||||
ret.mission.commandModeOptions.commandMode = "Red commander";
|
||||
break;
|
||||
}
|
||||
}
|
||||
res.send(JSON.stringify(ret));
|
||||
}
|
||||
|
||||
command(req, res) {
|
||||
var ret = { commandExecuted: Math.random() > 0.5 };
|
||||
res.send(JSON.stringify(ret));
|
||||
}
|
||||
|
||||
put(req, res) {
|
||||
var ret = { commandHash: Math.random().toString(36).slice(2, 19) };
|
||||
res.send(JSON.stringify(ret));
|
||||
}
|
||||
}
|
||||
|
||||
const demoDataGenerator = new DemoDataGenerator(app, config);
|
||||
|
||||
return app;
|
||||
};
|
||||
112
frontend/server/src/demo/www.ts
Normal file
112
frontend/server/src/demo/www.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
import yargs = require("yargs");
|
||||
import fs = require("fs");
|
||||
import http = require("http");
|
||||
|
||||
/* Define configuration parameter */
|
||||
yargs
|
||||
.alias("c", "config")
|
||||
.describe("c", "olympus.json config location")
|
||||
.string("rp");
|
||||
const args = yargs.argv;
|
||||
|
||||
console.log("Please wait while DCS Olympus DEMO Backend Server starts up...");
|
||||
console.log(`Config location: ${args["config"]}`);
|
||||
|
||||
let rawdata = fs.readFileSync(args["config"], "utf-8");
|
||||
let config = JSON.parse(rawdata);
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var app = require("./demo")(args["config"]);
|
||||
|
||||
/**
|
||||
* Get port from environment and store in Express.
|
||||
*/
|
||||
|
||||
var configPort = null;
|
||||
if (config["backend"] != undefined && config["backend"]["port"] != undefined) {
|
||||
configPort = config["backend"]["port"];
|
||||
}
|
||||
|
||||
var port = normalizePort(configPort || "3001");
|
||||
app.set("port", port);
|
||||
console.log("Express server listening on port: " + port);
|
||||
|
||||
/**
|
||||
* Create HTTP server.
|
||||
*/
|
||||
|
||||
var server = http.createServer(app);
|
||||
|
||||
/**
|
||||
* Listen on provided port, on all network interfaces.
|
||||
*/
|
||||
|
||||
server.listen(port);
|
||||
server.on("error", onError);
|
||||
server.on("listening", onListening);
|
||||
|
||||
/**
|
||||
* Normalize a port into a number, string, or false.
|
||||
*/
|
||||
|
||||
function normalizePort(val) {
|
||||
var port = parseInt(val, 10);
|
||||
|
||||
if (isNaN(port)) {
|
||||
// named pipe
|
||||
return val;
|
||||
}
|
||||
|
||||
if (port >= 0) {
|
||||
// port number
|
||||
return port;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Event listener for HTTP server "error" event.
|
||||
*/
|
||||
|
||||
function onError(error) {
|
||||
if (error.syscall !== "listen") {
|
||||
throw error;
|
||||
}
|
||||
|
||||
var bind = typeof port === "string" ? "Pipe " + port : "Port " + port;
|
||||
|
||||
// handle specific listen errors with friendly messages
|
||||
switch (error.code) {
|
||||
case "EACCES":
|
||||
console.error(bind + " requires elevated privileges");
|
||||
process.exit(1);
|
||||
break;
|
||||
case "EADDRINUSE":
|
||||
console.error(bind + " is already in use");
|
||||
process.exit(1);
|
||||
break;
|
||||
default:
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event listener for HTTP server "listening" event.
|
||||
*/
|
||||
|
||||
function onListening() {
|
||||
var addr = server.address();
|
||||
var bind = typeof addr === "string" ? "pipe " + addr : "port " + addr.port;
|
||||
console.log("Listening on " + bind);
|
||||
}
|
||||
|
||||
console.log(
|
||||
"DCS Olympus DEMO Backend Server {{OLYMPUS_VERSION_NUMBER}}.{{OLYMPUS_COMMIT_HASH}} started correctly!"
|
||||
);
|
||||
console.log("Waiting for connections...");
|
||||
|
||||
process.title = `DCS Olympus DEMO Backend Server {{OLYMPUS_VERSION_NUMBER}} (${port})`;
|
||||
83
frontend/server/src/routes/api/airbases.ts
Normal file
83
frontend/server/src/routes/api/airbases.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import express = require("express");
|
||||
import fs = require("fs");
|
||||
|
||||
const app = express();
|
||||
|
||||
const allowedTheatres = [
|
||||
"caucasus",
|
||||
"falklands",
|
||||
"marianas",
|
||||
"nevada",
|
||||
"normandy",
|
||||
"persiangulf",
|
||||
"sinaimap",
|
||||
"syria",
|
||||
"thechannel",
|
||||
"kola",
|
||||
];
|
||||
|
||||
function getAirbasesData(theatreName) {
|
||||
if (!isValidTheatre(theatreName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return JSON.parse(
|
||||
fs.readFileSync(`public/databases/airbases/${theatreName}.json`, {
|
||||
encoding: "utf-8",
|
||||
})
|
||||
).airfields;
|
||||
}
|
||||
|
||||
function isValidTheatre(theatre) {
|
||||
return allowedTheatres.indexOf(theatre) > -1;
|
||||
}
|
||||
|
||||
function sendInvalidTheatre(res) {
|
||||
res
|
||||
.status(400)
|
||||
.send(
|
||||
"Missing/invalid theatre name; must be one of:\n\t" +
|
||||
allowedTheatres.join("\n\t")
|
||||
);
|
||||
}
|
||||
|
||||
/**************************************************************************************************************/
|
||||
// Endpoints
|
||||
/**************************************************************************************************************/
|
||||
app.get("/", (req, res) => {
|
||||
sendInvalidTheatre(res);
|
||||
});
|
||||
|
||||
app.get("/:theatreName/:airbaseName", (req, res) => {
|
||||
const airbases = getAirbasesData(req.params.theatreName);
|
||||
if (!airbases) {
|
||||
sendInvalidTheatre(res);
|
||||
return;
|
||||
}
|
||||
|
||||
const airbaseName = req.params.airbaseName;
|
||||
if (!airbases.hasOwnProperty(airbaseName)) {
|
||||
res
|
||||
.status(404)
|
||||
.send(
|
||||
`Unknown airbase name "${airbaseName}". Available options are:\n\t` +
|
||||
Object.keys(airbases).join("\n\t")
|
||||
);
|
||||
} else {
|
||||
res.status(200).json(airbases[airbaseName]);
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/:theatreName", (req, res) => {
|
||||
const theatreName = req.params.theatreName.toLowerCase().replace(/\s*/g, "");
|
||||
const airbases = getAirbasesData(theatreName);
|
||||
|
||||
if (!airbases) {
|
||||
sendInvalidTheatre(res);
|
||||
return;
|
||||
}
|
||||
|
||||
res.status(200).json(airbases);
|
||||
});
|
||||
|
||||
module.exports = app;
|
||||
62
frontend/server/src/routes/api/databases.ts
Normal file
62
frontend/server/src/routes/api/databases.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import express = require('express');
|
||||
import fs = require("fs");
|
||||
import path = require("path");
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
module.exports = function (databasesLocation) {
|
||||
router.get('/:type/:name', function (req, res) {
|
||||
var contents = fs.readFileSync(path.join(databasesLocation, req.params.type, req.params.name + ".json"));
|
||||
res.status(200).send(contents);
|
||||
});
|
||||
|
||||
router.put('/save/:type/:name', function (req, res) {
|
||||
var dir = path.join(databasesLocation, req.params.type, "old");
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir);
|
||||
}
|
||||
|
||||
var filepath = path.join(databasesLocation, req.params.type, req.params.name + ".json");
|
||||
if (fs.existsSync(filepath)) {
|
||||
var newFilepath = path.join(databasesLocation, req.params.type, "old", req.params.name + ".json");
|
||||
fs.copyFileSync(filepath, newFilepath);
|
||||
if (fs.existsSync(newFilepath)) {
|
||||
try {
|
||||
var json = JSON.stringify(req.body.blueprints, null, "\t");
|
||||
fs.writeFileSync(filepath, json, 'utf8');
|
||||
res.send("OK");
|
||||
} catch {
|
||||
res.status(422).send("Error");
|
||||
}
|
||||
} else {
|
||||
res.status(422).send("Error");
|
||||
}
|
||||
} else {
|
||||
res.status(404).send('Not found');
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/reset/:type/:name', function (req, res) {
|
||||
var filepath = path.join(databasesLocation, req.params.type, "default", req.params.name + ".json");
|
||||
if (fs.existsSync(filepath)) {
|
||||
var newFilepath = path.join(databasesLocation, req.params.type, req.params.name + ".json");
|
||||
fs.copyFileSync(filepath, newFilepath);
|
||||
res.send("OK");
|
||||
} else {
|
||||
res.status(404).send('Not found');
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/restore/:type/:name', function (req, res) {
|
||||
var filepath = path.join(databasesLocation, req.params.type, "old", req.params.name + ".json");
|
||||
if (fs.existsSync(filepath)) {
|
||||
var newFilepath = path.join(databasesLocation, req.params.type, req.params.name + ".json");
|
||||
fs.copyFileSync(filepath, newFilepath);
|
||||
res.send("OK");
|
||||
} else {
|
||||
res.status(404).send('Not found');
|
||||
}
|
||||
});
|
||||
|
||||
return router;
|
||||
}
|
||||
32
frontend/server/src/routes/api/elevation.ts
Normal file
32
frontend/server/src/routes/api/elevation.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import express = require('express');
|
||||
import fs = require('fs');
|
||||
import srtmElevation = require('srtm-elevation');
|
||||
|
||||
const TileSet = srtmElevation.TileSet;
|
||||
const SRTMElevationDownloader = srtmElevation.SRTMElevationDownloader;
|
||||
const router = express.Router();
|
||||
|
||||
module.exports = function (configLocation) {
|
||||
let rawdata = fs.readFileSync(configLocation, "utf-8");
|
||||
let config = JSON.parse(rawdata);
|
||||
var tileset = null;
|
||||
|
||||
if (config["frontend"] === undefined || config["frontend"]["elevationProvider"] === undefined)
|
||||
tileset = new TileSet('./hgt');
|
||||
else
|
||||
tileset = new TileSet('./hgt', {downloader: new SRTMElevationDownloader('./hgt', config["frontend"]["elevationProvider"])});
|
||||
|
||||
router.get( "/:lat/:lng", ( req, res ) => {
|
||||
tileset.getElevation([req.params.lat, req.params.lng], function(err, elevation) {
|
||||
if (err) {
|
||||
console.log('getElevation failed: ' + err.message);
|
||||
res.send("n/a");
|
||||
} else {
|
||||
res.send(String(elevation));
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
return router;
|
||||
}
|
||||
9
frontend/server/src/routes/index.ts
Normal file
9
frontend/server/src/routes/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import express = require('express');
|
||||
const router = express.Router();
|
||||
|
||||
/* GET home page. */
|
||||
router.get('/', function (req, res, next) {
|
||||
res.render('index', { title: 'Express' });
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
21
frontend/server/src/routes/plugins.ts
Normal file
21
frontend/server/src/routes/plugins.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import express = require('express');
|
||||
import fs = require('fs');
|
||||
import path = require('path');
|
||||
|
||||
const pluginsDirectory = "./public/plugins"
|
||||
const router = express.Router();
|
||||
|
||||
function listDirectories(source) {
|
||||
const directories = fs.readdirSync(source, { withFileTypes: true })
|
||||
.filter(dirent => dirent.isDirectory())
|
||||
.map(dirent => dirent.name);
|
||||
|
||||
return directories;
|
||||
}
|
||||
|
||||
router.get('/list', function (req, res) {
|
||||
var directories = listDirectories(pluginsDirectory);
|
||||
res.send(directories.filter(directory => fs.existsSync(path.join(pluginsDirectory, directory))));
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
18
frontend/server/src/routes/resources.ts
Normal file
18
frontend/server/src/routes/resources.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import express = require('express');
|
||||
import fs = require('fs');
|
||||
const router = express.Router();
|
||||
|
||||
module.exports = function (configLocation) {
|
||||
router.get('/config', function (req, res, next) {
|
||||
if (fs.existsSync(configLocation)) {
|
||||
let rawdata = fs.readFileSync(configLocation, "utf-8");
|
||||
const config = JSON.parse(rawdata);
|
||||
res.send(JSON.stringify(config.frontend));
|
||||
res.end()
|
||||
} else {
|
||||
res.sendStatus(404);
|
||||
}
|
||||
});
|
||||
|
||||
return router;
|
||||
}
|
||||
112
frontend/server/src/www.ts
Normal file
112
frontend/server/src/www.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
import yargs = require("yargs");
|
||||
import fs = require("fs");
|
||||
import http = require("http");
|
||||
|
||||
/* Define configuration parameter */
|
||||
yargs
|
||||
.alias("c", "config")
|
||||
.describe("c", "olympus.json config location")
|
||||
.string("rp");
|
||||
const args = yargs.argv;
|
||||
|
||||
/* Startup print */
|
||||
console.log("Please wait while DCS Olympus Server starts up...");
|
||||
console.log(`Config location: ${args["config"]}`);
|
||||
|
||||
/* Load the configuration file */
|
||||
let httpPort = 0;
|
||||
if (fs.existsSync(args["config"])) {
|
||||
const json = JSON.parse(fs.readFileSync(args["config"], "utf-8"));
|
||||
httpPort = json["frontend"]["port"];
|
||||
|
||||
/* Load the dependencies. The app is loaded providing the configuration file location */
|
||||
const app = require("./app")(args["config"]);
|
||||
|
||||
/* Normalize port */
|
||||
const port = normalizePort(httpPort);
|
||||
app.set("port", port);
|
||||
console.log("Express server listening on port: " + port);
|
||||
|
||||
/* Create HTTP server */
|
||||
const server = http.createServer(app);
|
||||
|
||||
/* Listen on provided port, on all network interfaces. */
|
||||
server.listen(port);
|
||||
server.on("error", (error) => onError(error, port));
|
||||
server.on("listening", () => onListening(server.address()));
|
||||
|
||||
/* Optional https support */
|
||||
let https = null;
|
||||
let credentials = null;
|
||||
let httpsServer = null;
|
||||
if (json["frontend"]["https"] === true) {
|
||||
https = require("https");
|
||||
const privateKey = fs.readFileSync(
|
||||
json["frontend"]["keyPath"] ?? "./cert/default.key",
|
||||
"utf8"
|
||||
);
|
||||
const certificate = fs.readFileSync(
|
||||
json["frontend"]["certPath"] ?? "./cert/default.crt",
|
||||
"utf8"
|
||||
);
|
||||
const httpsPort = json["frontend"]["httpsPort"] ?? 3433;
|
||||
credentials = { key: privateKey, cert: certificate };
|
||||
httpsServer = https.createServer(credentials, app);
|
||||
httpsServer.listen(httpsPort);
|
||||
console.log("Express server listening on SSL port: " + httpsPort);
|
||||
}
|
||||
|
||||
/* Final user friendly printing */
|
||||
console.log(
|
||||
"DCS Olympus server {{OLYMPUS_VERSION_NUMBER}}.{{OLYMPUS_COMMIT_HASH}} started correctly!"
|
||||
);
|
||||
console.log("Waiting for connections...");
|
||||
process.title = `DCS Olympus server {{OLYMPUS_VERSION_NUMBER}} (${port})`;
|
||||
} else {
|
||||
console.log("Failed to read config, aborting!");
|
||||
}
|
||||
|
||||
/* Normalize a port into a number, string, or false. */
|
||||
function normalizePort(val) {
|
||||
let port = parseInt(val, 10);
|
||||
|
||||
if (isNaN(port)) {
|
||||
return val;
|
||||
}
|
||||
|
||||
if (port >= 0) {
|
||||
return port;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Event listener for HTTP server "error" event. */
|
||||
function onError(error, port: number) {
|
||||
if (error.syscall !== "listen") {
|
||||
throw error;
|
||||
}
|
||||
|
||||
const bind = typeof port === "string" ? "Pipe " + port : "Port " + port;
|
||||
|
||||
/* Handle specific listen errors with friendly messages */
|
||||
switch (error.code) {
|
||||
case "EACCES":
|
||||
console.error(bind + " requires elevated privileges");
|
||||
process.exit(1);
|
||||
break;
|
||||
case "EADDRINUSE":
|
||||
console.error(bind + " is already in use");
|
||||
process.exit(1);
|
||||
break;
|
||||
default:
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Event listener for HTTP server "listening" event. */
|
||||
function onListening(address) {
|
||||
const bind =
|
||||
typeof address === "string" ? "pipe " + address : "port " + address.port;
|
||||
console.log("Listening on " + bind);
|
||||
}
|
||||
Reference in New Issue
Block a user