Added configuration file to set address and port

This commit is contained in:
Pax1601 2023-03-26 11:04:17 +02:00
parent 0f2d9feba5
commit 25d0f031d5
17 changed files with 110 additions and 288 deletions

View File

@ -2,6 +2,7 @@ var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var fs = require('fs');
var indexRouter = require('./routes/index');
var uikitRouter = require('./routes/uikit');
@ -21,12 +22,14 @@ app.use('/uikit', uikitRouter);
app.set('view engine', 'ejs');
let rawdata = fs.readFileSync('../olympus.json');
let config = JSON.parse(rawdata);
app.get('/config', (req, res) => res.send(config));
module.exports = app;
const DemoDataGenerator = require('./demo.js');
var demoDataGenerator = new DemoDataGenerator(10);
app.get('/demo/units', (req, res) => demoDataGenerator.units(req, res));
app.get('/demo/logs', (req, res) => demoDataGenerator.logs(req, res));
app.get('/demo/bullseyes', (req, res) => demoDataGenerator.bullseyes(req, res));

View File

@ -2,7 +2,7 @@
"name": "DCSOlympus",
"node-main": "./bin/www",
"main": "http://localhost:3000",
"version": "0.1.0-alpha",
"version": "0.1.1-alpha",
"private": true,
"scripts": {
"copy": "copy .\\node_modules\\leaflet\\dist\\leaflet.css .\\public\\stylesheets\\leaflet.css",

View File

@ -9,7 +9,7 @@ import { AIC } from "./aic/aic";
import { ATC } from "./atc/atc";
import { FeatureSwitches } from "./featureswitches";
import { LogPanel } from "./panels/logpanel";
import { getAirbases, getBullseye as getBullseyes, getMission, getUnits, toggleDemoEnabled } from "./server/server";
import { getAirbases, getBullseye as getBullseyes, getConfig, getMission, getUnits, setAddress, toggleDemoEnabled } from "./server/server";
import { UnitDataTable } from "./units/unitdatatable";
var map: Map;
@ -69,16 +69,33 @@ function setup() {
/* Setup event handlers */
setupEvents();
/* On the first connection, force request of full data */
getAirbases((data: AirbasesData) => getMissionData()?.update(data));
getBullseyes((data: BullseyesData) => getMissionData()?.update(data));
getMission((data: any) => {getMissionData()?.update(data)});
getUnits((data: UnitsData) => getUnitsManager()?.update(data), true /* Does a full refresh */);
/* Start periodically requesting updates */
startPeriodicUpdate();
getConfig(readConfig)
}
function readConfig(config: any)
{
if (config && config["server"] != undefined && config["server"]["address"] != undefined && config["server"]["port"] != undefined)
{
const address = config["server"]["address"];
const port = config["server"]["port"];
if ((typeof address === 'string' || address instanceof String) && typeof port == 'number')
{
setAddress(<string>address, <number>port);
}
/* On the first connection, force request of full data */
getAirbases((data: AirbasesData) => getMissionData()?.update(data));
getBullseyes((data: BullseyesData) => getMissionData()?.update(data));
getMission((data: any) => {getMissionData()?.update(data)});
getUnits((data: UnitsData) => getUnitsManager()?.update(data), true /* Does a full refresh */);
/* Start periodically requesting updates */
startPeriodicUpdate();
}
else {
throw new Error('Could not read configuration file!');
}
}
function startPeriodicUpdate() {
requestUpdate();

View File

@ -80,7 +80,7 @@ export class UnitControlPanel extends Panel {
var button = document.createElement("button");
const unitName = <HTMLInputElement>this.getElement().querySelector("#unit-name");
var callsign = aircraftDatabase.getByName(unit.getBaseData().unitName)?.label || "";
var callsign = unit.getBaseData().unitName || "";
button.innerText = "";
button.setAttribute("data-short-label", database?.getByName(unit.getBaseData().name)?.shortLabel || "");

View File

@ -2,9 +2,8 @@ import * as L from 'leaflet'
import { setConnected } from '..';
import { SpawnOptions } from '../controls/mapcontextmenu';
/* Edit here to change server address */
const REST_ADDRESS = "http://localhost:30000/olympus";
const DEMO_ADDRESS = "http://localhost:3000/demo";
var REST_ADDRESS = "http://localhost:30000/olympus";
var DEMO_ADDRESS = window.location.href + "demo";
const UNITS_URI = "units";
const LOGS_URI = "logs";
const AIRBASES_URI = "airbases";
@ -45,6 +44,25 @@ export function POST(request: object, callback: CallableFunction){
xhr.send(JSON.stringify(request));
}
export function getConfig(callback: CallableFunction) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", window.location.href + "config", true);
xmlHttp.onload = function (e) {
var data = JSON.parse(xmlHttp.responseText);
callback(data);
lastUpdateTime = parseInt(data.time);
};
xmlHttp.onerror = function () {
console.error("An error occurred during the XMLHttpRequest, could not retrieve configuration file");
};
xmlHttp.send(null);
}
export function setAddress(address: string, port: number) {
REST_ADDRESS = `http://${address}:${port}/olympus`
console.log(`Setting REST address to ${REST_ADDRESS}`)
}
export function getAirbases(callback: CallableFunction) {
GET(callback, AIRBASES_URI);
}

View File

@ -573,6 +573,15 @@ export class GroundUnit extends Unit {
super(ID, data);
}
getMarkerHTML() {
var role = groundUnitsDatabase.getByName(this.getBaseData().name)?.loadouts[0].roles[0];
return `<div class="unit" data-object="unit-${this.getMarkerCategory()}" data-coalition="${this.getMissionData().coalition}">
<div class="unit-selected-spotlight"></div>
<div class="unit-marker"></div>
<div class="unit-short-label">${role?.substring(0, 1)?.toUpperCase() || ""}</div>
</div>`
}
getMarkerCategory()
{
// TODO this is very messy

View File

@ -10,13 +10,13 @@
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;600;700;800&display=swap" rel="stylesheet">
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z4L2TC3YX0"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-Z4L2TC3YX0');
</script>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z4L2TC3YX0"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-Z4L2TC3YX0');
</script>
</head>

View File

@ -7,7 +7,7 @@
<div class="ol-select-options">
<div id="olympus-toolbar-summary">
<h3>Olympus</h3>
<div class="accent-green app-version-number">v0.1.0</div>
<div class="accent-green app-version-number">v0.1.1</div>
</div>
<div>
<a href="https://www.discord.com" target="_blank">Discord</a>

View File

@ -15,7 +15,7 @@ declare_plugin(self_ID,
shortName = "Olympus",
fileMenuName = "Olympus",
version = "0.1.0-alpha",
version = "0.1.1-alpha",
state = "installed",
developerName= "DCS Refugees 767 squadron",
info = _("DCS Olympus is a mod for DCS World. It allows users to spawn, control, task, group, and remove units from a DCS World server using a real-time map interface, similarly to Real Time Strategy games. The user interface also provides useful informations units, like loadouts, fuel, tasking, and so on. In the future, more features for DCS World GCI and JTAC will be available."),

6
olympus.json Normal file
View File

@ -0,0 +1,6 @@
{
"server": {
"address": "localhost",
"port": 30000
}
}

View File

@ -1,40 +0,0 @@
local version = 'v0.1.0-alpha'
Olympus = {}
Olympus.OlympusDLL = nil
Olympus.cppRESTDLL = nil
Olympus.DLLsloaded = false
Olympus.OlympusModPath = os.getenv('DCSOLYMPUS_PATH')..'\\bin\\'
log.write('Olympus.EXPORT.LUA', log.INFO, 'Executing OlympusExport.lua')
function Olympus.loadDLLs()
-- Add the .dll paths
package.cpath = package.cpath..';'..Olympus.OlympusModPath..'?.dll;'
local status
log.write('Olympus.HOOKS.LUA', log.INFO, 'Loading olympus.dll from ['..Olympus.OlympusModPath..']')
status, Olympus.OlympusDLL = pcall(require, 'olympus')
if status then
log.write('Olympus.HOOKS.LUA', log.INFO, 'olympus.dll loaded successfully')
return true
else
log.write('Olympus.HOOKS.LUA', log.ERROR, 'Error loading olympus.dll: '..Olympus.OlympusDLL)
return false
end
end
do
if isOlympusModuleInitialized~=true then
local OlympusName = 'Olympus ' .. version .. ' C++ module';
isOlympusModuleInitialized=true;
Olympus.DLLsloaded = Olympus.loadDLLs()
if Olympus.DLLsloaded then
log.write('Olympus.EXPORT.LUA', log.INFO, OlympusName..' successfully loaded.')
else
log.write('Olympus.EXPORT.LUA', log.ERROR, 'Failed to load '..OlympusName)
end
else
log.write('Olympus.EXPORT.LUA', log.INFO, 'olympus.dll already initialized')
end
end

View File

@ -1,4 +1,4 @@
local version = 'v0.1.0-alpha'
local version = 'v0.1.1-alpha'
Olympus = {}
Olympus.OlympusDLL = nil

View File

@ -1,135 +0,0 @@
local version = 'v0.1.0-alpha'
Olympus = {}
Olympus.groupIndex = 0
Olympus.groupStep = 40
function Olympus.notify(message, displayFor)
trigger.action.outText(message, displayFor)
end
function Olympus.setMissionData(arg, time)
local missionData = {}
-- Bullseye data
local bullseyes = {}
for i = 0, 2 do
local bullseyeVec3 = coalition.getMainRefPoint(i)
local bullseyeLatitude, bullseyeLongitude, bullseyeAltitude = coord.LOtoLL(bullseyeVec3)
bullseyes[i] = {}
bullseyes[i]["latitude"] = bullseyeLatitude
bullseyes[i]["longitude"] = bullseyeLongitude
end
-- Units tactical data
local unitsData = {}
local startIndex = Olympus.groupIndex
local endIndex = startIndex + Olympus.groupStep
local index = 0
for groupName, gp in pairs(mist.DBs.groupsByName) do
index = index + 1
if index > startIndex then
if groupName ~= nil then
local group = Group.getByName(groupName)
if group ~= nil then
local controller = group:getController()
for index, unit in pairs(group:getUnits()) do
local table = {}
table["targets"] = {}
table["targets"]["visual"] = controller:getDetectedTargets(1)
table["targets"]["radar"] = controller:getDetectedTargets(4)
table["targets"]["rwr"] = controller:getDetectedTargets(16)
table["targets"]["other"] = controller:getDetectedTargets(2, 8, 32)
table["hasTask"] = controller:hasTask()
table["ammo"] = unit:getAmmo()
table["fuel"] = unit:getFuel()
table["life"] = unit:getLife() / unit:getLife0()
unitsData[unit:getObjectID()] = table
end
end
end
end
if index >= endIndex then
break
end
end
if index ~= endIndex then
Olympus.groupIndex = 0
else
Olympus.groupIndex = endIndex
end
-- Airbases data
local base = world.getAirbases()
local airbases = {}
for i = 1, #base do
local info = {}
local latitude, longitude, altitude = coord.LOtoLL(Airbase.getPoint(base[i]))
info["callsign"] = Airbase.getCallsign(base[i])
local coalitionID = Airbase.getCoalition(base[i])
if coalitionID == 0 then
info["coalition"] = "neutral"
elseif coalitionID == 1 then
info["coalition"] = "red"
else
info["coalition"] = "blue"
end
info["latitude"] = latitude
info["longitude"] = longitude
if Airbase.getUnit(base[i]) then
info["unitId"] = Airbase.getUnit(base[i]):getID()
end
airbases[i] = info
end
local mission = {}
mission.theatre = env.mission.theatre
-- Assemble missionData table
missionData["bullseyes"] = bullseyes
missionData["unitsData"] = unitsData
missionData["airbases"] = airbases
missionData["mission"] = mission
local command = "Olympus.missionData = " .. Olympus.serializeTable(missionData) .. "\n" .. "Olympus.OlympusDLL.setMissionData()"
net.dostring_in("export", command)
return time + 1
end
function Olympus.serializeTable(val, name, skipnewlines, depth)
skipnewlines = skipnewlines or false
depth = depth or 0
local tmp = string.rep(" ", depth)
if name then
if type(name) == "number" then
tmp = tmp .. "[" .. name .. "]" .. " = "
else
tmp = tmp .. name .. " = "
end
end
if type(val) == "table" then
tmp = tmp .. "{" .. (not skipnewlines and "\n" or "")
for k, v in pairs(val) do
tmp = tmp .. Olympus.serializeTable(v, k, skipnewlines, depth + 1) .. "," .. (not skipnewlines and "\n" or "")
end
tmp = tmp .. string.rep(" ", depth) .. "}"
elseif type(val) == "number" then
tmp = tmp .. tostring(val)
elseif type(val) == "string" then
tmp = tmp .. string.format("%q", val)
elseif type(val) == "boolean" then
tmp = tmp .. (val and "true" or "false")
else
tmp = tmp .. "\"[inserializeable datatype:" .. type(val) .. "]\""
end
return tmp
end
timer.scheduleFunction(Olympus.setMissionData, {}, timer.getTime() + 1)
Olympus.notify("OlympusMission " .. version .. " script loaded correctly", 10)

Binary file not shown.

View File

@ -1,42 +0,0 @@
import shutil
import sys
START_STRING = "-- Olympus START\n"
END_STRING = "-- Olympus END\n"
EXPORT_STRING = "local Olympuslfs=require('lfs');dofile(Olympuslfs.writedir()..'Scripts/OlympusExport.lua')\n"
def main(flag):
if flag == "-i":
try:
with open("Export.lua", "r") as f:
shutil.copyfile("Export.lua", "Export.lua.bak")
lines = f.readlines()
if START_STRING in lines:
return
except FileNotFoundError:
print('File does not exist')
with open("Export.lua", "a") as f:
f.writelines(["\n", START_STRING, EXPORT_STRING, END_STRING, "\n"])
elif flag == "-u":
try:
with open("Export.lua", "r") as f:
shutil.copyfile("Export.lua", "Export.lua.bak")
lines = f.readlines()
except FileNotFoundError:
print('File does not exist')
with open("Export.lua", "w") as f:
block = False
for line in lines:
if line == START_STRING:
block = True
if not block:
f.write(line)
if line == END_STRING:
block = False
if __name__ == "__main__":
main(sys.argv[1])

View File

@ -1,44 +0,0 @@
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['OlympusPatcher.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='OlympusPatcher',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)

View File

@ -179,7 +179,37 @@ void Server::handle_put(http_request request)
void Server::task()
{
http_listener listener(wstring(REST_ADDRESS) + L"/" + wstring(REST_URI));
wstring address = wstring(REST_ADDRESS);
wstring modLocation;
char* buf = nullptr;
size_t sz = 0;
if (_dupenv_s(&buf, &sz, "DCSOLYMPUS_PATH") == 0 && buf != nullptr)
{
std::ifstream ifstream(string(buf) + "\\olympus.json");
std::stringstream ss;
ss << ifstream.rdbuf();
std::error_code errorCode;
json::value config = json::value::parse(to_wstring(ss.str()), errorCode);
log(to_string(config[L"server"].type()));
if (config.is_object() && config.has_object_field(L"server") &&
config[L"server"].has_string_field(L"address") && config[L"server"].has_number_field(L"port"))
{
log("Object");
address = L"http://" + config[L"server"][L"address"].as_string() + L":" + to_wstring(config[L"server"][L"port"].as_number().to_int32());
log(L"Starting server on " + address);
}
else
{
log(L"Error reading configuration file. Starting server on " + address);
}
free(buf);
}
else
{
log(L"DCSOLYMPUS_PATH environment variable is missing, starting server on " + address);
}
http_listener listener(address + L"/" + wstring(REST_URI));
std::function<void(http_request)> handle_options = std::bind(&Server::handle_options, this, std::placeholders::_1);
std::function<void(http_request)> handle_get = std::bind(&Server::handle_get, this, std::placeholders::_1);