Minor bugfix

This commit is contained in:
Pax1601 2023-03-07 22:47:12 +01:00
parent 1eb5d22f6b
commit dec50648f9
11 changed files with 92 additions and 19 deletions

View File

@ -1,5 +1,6 @@
interface UnitsData {
units: {[key: string]: UnitData},
units: {[key: string]: UnitData},
sessionHash: string
}
interface AirbasesData {

View File

@ -30,6 +30,8 @@ var logPanel: LogPanel;
var connected: boolean = false;
var activeCoalition: string = "blue";
var sessionHash: string | null = null;
var featureSwitches;
function setup() {
@ -43,7 +45,7 @@ function setup() {
contextMenu = new ContextMenu("contextmenu");
unitInfoPanel = new UnitInfoPanel("unit-info-panel");
//unitInfoPanel = new UnitInfoPanel("unit-info-panel");
unitControlPanel = new UnitControlPanel("unit-control-panel");
connectionStatusPanel = new ConnectionStatusPanel("connection-status-panel");
mouseInfoPanel = new MouseInfoPanel("mouse-info-panel");
@ -147,7 +149,10 @@ function startPeriodicUpdate()
function requestUpdate() {
/* Main update rate = 250ms is minimum time, equal to server update time. */
getUnits((data: UnitsData) => getUnitsManager()?.update(data), false);
getUnits((data: UnitsData) => {
getUnitsManager()?.update(data);
checkSessionHash(data.sessionHash);
}, false);
setTimeout(() => requestUpdate(), getConnected() ? 250 : 1000);
getConnectionStatusPanel()?.update(getConnected());
@ -155,8 +160,24 @@ function requestUpdate() {
function requestRefresh() {
/* Main refresh rate = 5000ms. */
getUnits((data: UnitsData) => getUnitsManager()?.update(data), true);
setTimeout(() => requestUpdate(), 5000);
getUnits((data: UnitsData) => {
getUnitsManager()?.update(data);
getAirbases((data: AirbasesData) => getMissionData()?.update(data));
getBulllseye((data: BullseyesData) => getMissionData()?.update(data));
checkSessionHash(data.sessionHash);
}, true);
setTimeout(() => requestRefresh(), 5000);
}
function checkSessionHash(newSessionHash: string)
{
if (sessionHash != null)
{
if (newSessionHash != sessionHash)
location.reload();
}
else
sessionHash = newSessionHash;
}
export function getMap() {

View File

@ -2,7 +2,7 @@ import * as L from 'leaflet'
import { setConnected } from '..';
/* Edit here to change server address */
const REST_ADDRESS = "http://localhost:3000/demo";
const REST_ADDRESS = "http://localhost:30000/olympus";
const UNITS_URI = "units";
const REFRESH_URI = "refresh";
const UPDATE_URI = "update";

View File

@ -88,15 +88,30 @@ export class Unit extends Marker {
setData(data: UnitData) {
document.dispatchEvent(new CustomEvent("unitUpdated", { detail: this }));
var updateMarker = true;
//if (this.getFlightData().latitude != response.flightData.latitude ||
// this.getFlightData().longitude != response.flightData.longitude ||
// this.getData().alive != response.alive ||
// this.#forceUpdate ||
// !getMap().hasLayer(this.#marker))
// updateMarker = true;
var updateMarker = false;
if (this.getFlightData().latitude != data.flightData.latitude ||
this.getFlightData().longitude != data.flightData.longitude ||
this.getData().alive != data.alive || this.#forceUpdate || !getMap().hasLayer(this))
updateMarker = true;
this.#data.AI = data.AI;
this.#data.name = data.name;
this.#data.unitName = data.unitName;
this.#data.groupName = data.groupName;
this.#data.alive = data.alive;
this.#data.category = data.category;
if (data.flightData != undefined)
this.#data.flightData = data.flightData;
if (data.missionData != undefined)
this.#data.missionData = data.missionData;
if (data.formationData != undefined)
this.#data.formationData = data.formationData;
if (data.taskData != undefined)
this.#data.taskData = data.taskData;
if (data.optionsData != undefined)
this.#data.optionsData = data.optionsData;
this.#data = data;
/* Dead units can't be selected */
this.setSelected(this.getSelected() && this.getData().alive)
@ -163,7 +178,7 @@ export class Unit extends Marker {
addDestination(latlng: L.LatLng) {
var path: any = {};
if (this.getTaskData().activePath != null) {
if (this.getTaskData().activePath != undefined) {
path = this.getTaskData().activePath;
path[(Object.keys(path).length + 1).toString()] = latlng;
}
@ -174,7 +189,7 @@ export class Unit extends Marker {
}
clearDestinations() {
this.getTaskData().activePath = null;
this.getTaskData().activePath = undefined;
}
getHidden() {
@ -191,7 +206,7 @@ export class Unit extends Marker {
getWingmen() {
var wingmen: Unit[] = [];
if (this.getFormationData().wingmenIDs != null) {
if (this.getFormationData().wingmenIDs != undefined) {
for (let ID of this.getFormationData().wingmenIDs) {
var unit = getUnitsManager().getUnitByID(ID)
if (unit)
@ -318,7 +333,7 @@ export class Unit extends Marker {
}
#drawPath() {
if (this.getTaskData().activePath != null) {
if (this.getTaskData().activePath != undefined) {
var points = [];
points.push(new LatLng(this.getFlightData().latitude, this.getFlightData().longitude));

View File

@ -34,6 +34,7 @@ public:
void setROE(wstring newROE);
void setReactionToThreat(wstring newReactionToThreat);
void landAt(Coords loc);
void setHasNewData(bool newHasNewData) { hasNewData = newHasNewData; }
int getID() { return ID; }
wstring getName() { return name; }
@ -56,6 +57,7 @@ public:
bool getIsLeader() { return isLeader; }
bool getIsWingman() { return isWingman; }
wstring getFormation() { return formation; }
bool getHasNewData() { return hasNewData; }
virtual double getTargetSpeed() { return targetSpeed; };
virtual double getTargetAltitude() { return targetAltitude; };
@ -68,6 +70,8 @@ public:
protected:
int ID;
bool hasNewData = false;
int newDataCounter = 0;
int state = State::IDLE;
bool hasTask = false;
bool AI = false;
@ -104,6 +108,8 @@ protected:
Coords activeDestination = Coords(0);
Coords oldPosition = Coords(0); // Used to approximate speed
list<pair<int, std::function<void(void)>>> schedule;
virtual void AIloop() = 0;
};

View File

@ -16,6 +16,7 @@ Unit::Unit(json::value json, int ID) :
ID(ID)
{
log("Creating unit with ID: " + to_string(ID));
newDataCounter = 1.0 / UPDATE_TIME_INTERVAL > 0? 1.0 / UPDATE_TIME_INTERVAL: 1; // Mark the unit has hasNewData for 1 second
}
Unit::~Unit()
@ -25,6 +26,10 @@ Unit::~Unit()
void Unit::updateExportData(json::value json)
{
if (newDataCounter > 0)
newDataCounter--;
setHasNewData(newDataCounter);
/* Compute speed (loGetWorldObjects does not provide speed, we compute it for better performance instead of relying on many lua calls) */
if (oldPosition != NULL)
{
@ -69,6 +74,7 @@ void Unit::updateExportData(json::value json)
void Unit::updateMissionData(json::value json)
{
newDataCounter = 1.0 / UPDATE_TIME_INTERVAL > 0 ? 1.0 / UPDATE_TIME_INTERVAL : 1; // Mark the unit has hasNewData for 1 second
if (json.has_number_field(L"fuel"))
fuel = int(json[L"fuel"].as_number().to_double() * 100);
if (json.has_object_field(L"ammo"))
@ -99,7 +105,7 @@ json::value Unit::json(bool fullRefresh)
json[L"flightData"][L"speed"] = speed;
json[L"flightData"][L"heading"] = heading;
if (fullRefresh)
if (fullRefresh || getHasNewData())
{
/********** Mission data **********/
json[L"missionData"] = json::value::object();

View File

@ -15,6 +15,7 @@ json::value airbasesData;
json::value bullseyesData;
mutex mutexLock;
bool initialized = false;
string sessionHash;
/* Called when DCS simulation stops. All singleton instances are deleted. */
extern "C" DllExport int coreDeinit(lua_State* L)
@ -38,6 +39,7 @@ extern "C" DllExport int coreDeinit(lua_State* L)
/* Called when DCS simulation starts. All singletons are instantiated, and the custom Lua functions are registered in the Lua state. */
extern "C" DllExport int coreInit(lua_State* L)
{
sessionHash = random_string(16);
unitsManager = new UnitsManager(L);
server = new Server(L);
scheduler = new Scheduler(L);

View File

@ -12,6 +12,7 @@ extern Scheduler* scheduler;
extern json::value airbasesData;
extern json::value bullseyesData;
extern mutex mutexLock;
extern string sessionHash;
void handle_eptr(std::exception_ptr eptr)
{
@ -93,7 +94,10 @@ void Server::handle_get(http_request request)
answer[L"airbases"] = airbasesData;
else if (path[0] == BULLSEYE_URI)
answer[L"bullseyes"] = bullseyesData;
answer[L"sessionHash"] = json::value::string(to_wstring(sessionHash));
}
response.set_body(answer);
}
catch (...) {

View File

@ -17,6 +17,7 @@ struct Offset {
const DllExport std::string CurrentDateTime();
std::wstring DllExport to_wstring(const std::string& str);
std::string DllExport to_string(const std::wstring& wstr);
std::string DllExport random_string(size_t length);
bool DllExport operator== (const Coords& a, const Coords& b);
bool DllExport operator!= (const Coords& a, const Coords& b);
@ -27,3 +28,4 @@ bool DllExport operator== (const Offset& a, const Offset& b);
bool DllExport operator!= (const Offset& a, const Offset& b);
bool DllExport operator== (const Offset& a, const int& b);
bool DllExport operator!= (const Offset& a, const int& b);

View File

@ -38,6 +38,22 @@ std::string to_string(const std::wstring& wstr)
return result;
}
std::string random_string(size_t length)
{
auto randchar = []() -> char
{
const char charset[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
const size_t max_index = (sizeof(charset) - 1);
return charset[rand() % max_index];
};
std::string str(length, 0);
std::generate_n(str.begin(), length, randchar);
return str;
}
bool operator== (const Coords& a, const Coords& b) { return a.lat == b.lat && a.lng == b.lng && a.alt == b.alt; }
bool operator!= (const Coords& a, const Coords& b) { return !(a == b); }
bool operator== (const Coords& a, const int& b) { return a.lat == b && a.lng == b && a.alt == b; }