From 4dfd0bfda0e3ee9284c0858ec933c5df416d0015 Mon Sep 17 00:00:00 2001 From: erik4tw <148548319+erik4tw@users.noreply.github.com> Date: Wed, 25 Mar 2026 15:40:49 +0100 Subject: [PATCH 1/8] Added Handover functionality --- airport.h | 1 + configparser.cpp | 25 ++++++++++++++++++++++++- configparser.h | 1 + constants.h | 3 +++ flightplan.h | 3 ++- vSIDPlugin.cpp | 33 +++++++++++++++++++++++++++++++++ vSidConfig.json | 8 ++++++-- 7 files changed, 70 insertions(+), 4 deletions(-) diff --git a/airport.h b/airport.h index fb99d1b..0a5d8d8 100644 --- a/airport.h +++ b/airport.h @@ -81,6 +81,7 @@ namespace vsid //bool arrAsDep = false; int transAlt = 0; int maxInitialClimb = 0; + bool autoHandoff = true; std::map settings = {}; std::map controllers = {}; //************************************ diff --git a/configparser.cpp b/configparser.cpp index 35e2afa..11f1013 100644 --- a/configparser.cpp +++ b/configparser.cpp @@ -55,6 +55,8 @@ void vsid::ConfigParser::loadMainConfig() this->notifyUpdate = this->vSidConfig.value("notifyUpdate", 1); + this->hovWarningAlt = this->vSidConfig.value("hovWarningAlt", 1000); + try { // import colors or set default values @@ -338,6 +340,26 @@ void vsid::ConfigParser::loadMainConfig() } else this->colors["reqIndicator"] = RGB(255, 255, 255); + if (this->vSidConfig.at("colors").contains("hovNeutral")) + { + this->colors["hovNeutral"] = RGB( + this->vSidConfig.at("colors").at("hovNeutral").value("r", 250), + this->vSidConfig.at("colors").at("hovNeutral").value("g", 250), + this->vSidConfig.at("colors").at("hovNeutral").value("b", 0) + ); + } + else this->colors["hovNeutral"] = RGB(250, 250, 0); + + if (this->vSidConfig.at("colors").contains("hovWarning")) + { + this->colors["hovWarning"] = RGB( + this->vSidConfig.at("colors").at("hovWarning").value("r", 250), + this->vSidConfig.at("colors").at("hovWarning").value("g", 0), + this->vSidConfig.at("colors").at("hovWarning").value("b", 0) + ); + } + else this->colors["hovWarning"] = RGB(250, 0, 0); + // pseudo values for special color use cases if (!this->colors.contains("squawkSet")) this->colors["squawkSet"] = RGB(300, 300, 300); } @@ -478,6 +500,7 @@ void vsid::ConfigParser::loadAirportConfig(std::map aptInfo.requests["departure"] = {}; aptInfo.requests["vfr"] = {}; aptInfo.rwyrequests["startup"] = {}; + aptInfo.autoHandoff = this->parsedConfig.at(icao).value("autoHandoff", true); // customRules @@ -1411,4 +1434,4 @@ int vsid::ConfigParser::getReqTime(std::string time) messageHandler->writeMessage("ERROR", "Failed to retrieve request time setting for key \"" + time + "\""); return 0; } -} \ No newline at end of file +} diff --git a/configparser.h b/configparser.h index 9e93d86..8735b5c 100644 --- a/configparser.h +++ b/configparser.h @@ -161,6 +161,7 @@ namespace vsid std::set rnavList; bool preferTopsky; int notifyUpdate; + int hovWarningAlt; private: std::set configPaths; diff --git a/constants.h b/constants.h index 811eb1b..95bb3b0 100644 --- a/constants.h +++ b/constants.h @@ -58,6 +58,9 @@ const int TAG_FUNC_VSID_INTS_SET = 750; const int TAG_FUNC_VSID_TSSQUAWK = 940; +const int TAG_ITEM_VSID_HOVF = 995; +const int TAG_FUNC_VSID_HOV = 996; + // menues const int MENU = 100; diff --git a/flightplan.h b/flightplan.h index b9d5553..a500959 100644 --- a/flightplan.h +++ b/flightplan.h @@ -54,6 +54,7 @@ namespace vsid bool mapp = false; // altitude tracking during acft landing phase int ldgAlt = 0; + bool hov = false; }; namespace fplnhelper @@ -226,4 +227,4 @@ namespace vsid //************************************ bool restoreIC(const vsid::Fpln& fplnInfo, EuroScopePlugIn::CFlightPlan FlightPlan, EuroScopePlugIn::CController atcMyself); } -} \ No newline at end of file +} diff --git a/vSIDPlugin.cpp b/vSIDPlugin.cpp index c81e508..a91e78b 100644 --- a/vSIDPlugin.cpp +++ b/vSIDPlugin.cpp @@ -69,6 +69,9 @@ vsid::VSIDPlugin::VSIDPlugin() : EuroScopePlugIn::CPlugIn(EuroScopePlugIn::COMPA RegisterTagItemFunction("Auto-Assign Squawk (TopSky)", TAG_FUNC_VSID_TSSQUAWK); + RegisterTagItemType("Handover Flag", TAG_ITEM_VSID_HOVF); + RegisterTagItemFunction("Set handover flag", TAG_FUNC_VSID_HOV); + this->loadEse(); // load and parse ese file UpdateActiveAirports(); // preload rwy settings @@ -2633,6 +2636,11 @@ void vsid::VSIDPlugin::OnFunctionCall(int FunctionId, const char * sItemString, { this->processed[callsign].ctlLocal = !this->processed[callsign].ctlLocal; } + + if (FunctionId == TAG_FUNC_VSID_HOV) + { + this->processed[callsign].hov = !this->processed[callsign].hov; + } } void vsid::VSIDPlugin::OnGetTagItem(EuroScopePlugIn::CFlightPlan FlightPlan, EuroScopePlugIn::CRadarTarget RadarTarget, int ItemCode, int TagData, char sItemString[16], int* pColorCode, COLORREF* pRGB, double* pFontSize) @@ -3302,6 +3310,31 @@ void vsid::VSIDPlugin::OnGetTagItem(EuroScopePlugIn::CFlightPlan FlightPlan, Eur strcpy_s(sItemString, 16, this->processed[callsign].intsec.first.c_str()); } } + + if (ItemCode == TAG_ITEM_VSID_HOVF) + { + if (RadarTarget.GetGS() < 50) return; + if (this->activeAirports[adep].autoHandoff) return; + + int alt = RadarTarget.GetPosition().GetPressureAltitude(); + int hovWarningAlt = this->getConfigParser().hovWarningAlt; + EuroScopePlugIn::CFlightPlan fpln = FlightPlan; + *pColorCode = EuroScopePlugIn::TAG_COLOR_RGB_DEFINED; + + if (!this->processed[callsign].hov) + { + if (alt >= fpln.GetClearedAltitude() - hovWarningAlt) + { + *pRGB = this->configParser.getColor("hovWarning"); + strcpy_s(sItemString, 16, "HOV!"); + } + else + { + *pRGB = this->configParser.getColor("hovNeutral"); + strcpy_s(sItemString, 16, "HOV"); + } + } + } } if (ItemCode == TAG_ITEM_VSID_CTLF) diff --git a/vSidConfig.json b/vSidConfig.json index cff295c..9bc9d01 100644 --- a/vSidConfig.json +++ b/vSidConfig.json @@ -122,7 +122,10 @@ }, "reqIndicator": {"r": 255, "g": 255, "b": 255}, "intsecSetIndicator": {"r": 0, "g": 150, "b": 50}, - "intsecAbleIndicator": {"r": 200, "g": 150, "b": 0} + "intsecAbleIndicator": {"r": 200, "g": 150, "b": 0 + }, + "hovNeutral": {"r": 255,"g": 160,"b": 0}, + "hovWarning": {"r": 255,"g": 0,"b": 0} }, "requests": { "caution": 2, @@ -134,6 +137,7 @@ "altCaution": 1500, "altWarning": 500 }, + "hovWarningAlt": 1500, "display": { "showPbIndicatorOn": "Ground Radar display", "enablePbIndicator": true, @@ -145,4 +149,4 @@ "indicatorZoomScale": 0.5, "indicatorShowBelowZoom": 600 } -} \ No newline at end of file +} From c591dbc1ee8afc59ed8a1d900fb41a1059680232 Mon Sep 17 00:00:00 2001 From: erik4tw <148548319+erik4tw@users.noreply.github.com> Date: Wed, 25 Mar 2026 15:41:40 +0100 Subject: [PATCH 2/8] Added EDDF auto handoff false --- config/eddf.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/eddf.json b/config/eddf.json index 0d3272a..b290d80 100644 --- a/config/eddf.json +++ b/config/eddf.json @@ -4,6 +4,7 @@ "runways": "25C,25L,07C,07R,18", "transAlt": 5000, "maxInitialClimb": 7000, + "autoHandoff": false, "customRules" : {"allnorth":false, "sulus18": false}, "timeMode": true, "timezone": "Europe/Berlin", @@ -926,4 +927,4 @@ } } } -} \ No newline at end of file +} From 3b36ffbe1a1c30fd39a1283f635098a2d7929d97 Mon Sep 17 00:00:00 2001 From: Phil7789 <87429599+Phil7789@users.noreply.github.com> Date: Wed, 6 May 2026 20:55:49 +0200 Subject: [PATCH 3/8] Fix indentation type / Fix inconsistent default colors --- configparser.cpp | 1526 +++++++++++++++++++++++----------------------- 1 file changed, 763 insertions(+), 763 deletions(-) diff --git a/configparser.cpp b/configparser.cpp index 11f1013..17776e2 100644 --- a/configparser.cpp +++ b/configparser.cpp @@ -17,59 +17,59 @@ vsid::ConfigParser::~ConfigParser() = default; void vsid::ConfigParser::loadMainConfig() { - char path[MAX_PATH + 1] = { 0 }; - GetModuleFileNameA((HINSTANCE)&__ImageBase, path, MAX_PATH); - PathRemoveFileSpecA(path); - std::filesystem::path basePath = path; - - std::ifstream configFile(basePath.append("vSidConfig.json").string()); - - try - { - this->vSidConfig = json::parse(configFile); - } - catch(const json::parse_error &e) - { - messageHandler->writeMessage("ERROR", "Failed to parse main config: " + std::string(e.what())); - } - catch (const json::type_error& e) - { - messageHandler->writeMessage("ERROR", "Failed to parse main config: " + std::string(e.what())); - } - catch (const json::other_error& e) - { - messageHandler->writeMessage("ERROR", "Failed to parse main config: " + std::string(e.what())); - } - - if (this->vSidConfig.is_null()) - { - messageHandler->writeMessage("ERROR", "Failed to parse main config. (Critical!)"); - return; - } - - // set topsky preference - - this->preferTopsky = this->vSidConfig.value("preferTopsky", true); - - // set update notification - - this->notifyUpdate = this->vSidConfig.value("notifyUpdate", 1); - - this->hovWarningAlt = this->vSidConfig.value("hovWarningAlt", 1000); - - try - { - // import colors or set default values - - if (this->vSidConfig.at("colors").contains("sidSuggestion")) - { + char path[MAX_PATH + 1] = { 0 }; + GetModuleFileNameA((HINSTANCE)&__ImageBase, path, MAX_PATH); + PathRemoveFileSpecA(path); + std::filesystem::path basePath = path; + + std::ifstream configFile(basePath.append("vSidConfig.json").string()); + + try + { + this->vSidConfig = json::parse(configFile); + } + catch(const json::parse_error &e) + { + messageHandler->writeMessage("ERROR", "Failed to parse main config: " + std::string(e.what())); + } + catch (const json::type_error& e) + { + messageHandler->writeMessage("ERROR", "Failed to parse main config: " + std::string(e.what())); + } + catch (const json::other_error& e) + { + messageHandler->writeMessage("ERROR", "Failed to parse main config: " + std::string(e.what())); + } + + if (this->vSidConfig.is_null()) + { + messageHandler->writeMessage("ERROR", "Failed to parse main config. (Critical!)"); + return; + } + + // set topsky preference + + this->preferTopsky = this->vSidConfig.value("preferTopsky", true); + + // set update notification + + this->notifyUpdate = this->vSidConfig.value("notifyUpdate", 1); + + this->hovWarningAlt = this->vSidConfig.value("hovWarningAlt", 1500); + + try + { + // import colors or set default values + + if (this->vSidConfig.at("colors").contains("sidSuggestion")) + { this->colors["sidSuggestion"] = RGB( this->vSidConfig.at("colors").at("sidSuggestion").value("r", 255), this->vSidConfig.at("colors").at("sidSuggestion").value("g", 255), this->vSidConfig.at("colors").at("sidSuggestion").value("b", 255) ); - } - else this->colors["sidSuggestion"] = RGB(255, 255, 255); + } + else this->colors["sidSuggestion"] = RGB(255, 255, 255); if (this->vSidConfig.at("colors").contains("suggestedSidSet")) { @@ -341,307 +341,307 @@ void vsid::ConfigParser::loadMainConfig() else this->colors["reqIndicator"] = RGB(255, 255, 255); if (this->vSidConfig.at("colors").contains("hovNeutral")) - { - this->colors["hovNeutral"] = RGB( - this->vSidConfig.at("colors").at("hovNeutral").value("r", 250), - this->vSidConfig.at("colors").at("hovNeutral").value("g", 250), - this->vSidConfig.at("colors").at("hovNeutral").value("b", 0) - ); - } - else this->colors["hovNeutral"] = RGB(250, 250, 0); - - if (this->vSidConfig.at("colors").contains("hovWarning")) - { - this->colors["hovWarning"] = RGB( - this->vSidConfig.at("colors").at("hovWarning").value("r", 250), - this->vSidConfig.at("colors").at("hovWarning").value("g", 0), - this->vSidConfig.at("colors").at("hovWarning").value("b", 0) - ); - } - else this->colors["hovWarning"] = RGB(250, 0, 0); - - // pseudo values for special color use cases - if (!this->colors.contains("squawkSet")) this->colors["squawkSet"] = RGB(300, 300, 300); - } - catch (std::error_code& e) - { - messageHandler->writeMessage("ERROR", "Failed to import colors: " + e.message()); - } - catch (const json::parse_error& e) - { - messageHandler->writeMessage("ERROR", "[Parse Error] in color config section: " + std::string(e.what())); - } - catch (const json::type_error& e) - { - messageHandler->writeMessage("ERROR", "[Type Error] in color config section: " + std::string(e.what())); - } - catch (const json::other_error& e) - { - messageHandler->writeMessage("ERROR", "[Other Error] in color config section: " + std::string(e.what())); - } - catch (const json::out_of_range& e) - { - messageHandler->writeMessage("ERROR", "[Out of Range] in color config section: " + std::string(e.what())); - } - - // get request times - - try - { - this->reqTimes.insert({ "caution", this->vSidConfig.at("requests").value("caution", 2) }); - this->reqTimes.insert({ "warning", this->vSidConfig.at("requests").value("warning", 5) }); - } - catch (json::parse_error& e) - { - messageHandler->writeMessage("ERROR", "Failed to get request timers: " + std::string(e.what())); - } - - // get clrf min values - - try - { - this->clrf.altCaution = this->vSidConfig.at("clrf").value("altCaution", 1500); - this->clrf.altWarning = this->vSidConfig.at("clrf").value("altWarning", 500); - this->clrf.distCaution = this->vSidConfig.at("clrf").value("distCaution", 10.0); - this->clrf.distWarning = this->vSidConfig.at("clrf").value("distWarning", 2.0); - } - catch (json::out_of_range& e) - { - messageHandler->writeMessage("ERROR", "Failed to get clrf min values: " + std::string(e.what())); - } - - // get indicator reference values - - try - { - this->indicator.offset = this->vSidConfig.at("display").value("indicatorOffset", 20); - this->indicator.zoomScale = this->vSidConfig.at("display").value("indicatorZoomScale", 0.5); - this->indicator.showBelowZoom = this->vSidConfig.at("display").value("indicatorShowBelowZoom", 600); - } - catch (json::out_of_range& e) - { - messageHandler->writeMessage("ERROR", "Failed to get indicator default reference values: " + std::string(e.what())); - } + { + this->colors["hovNeutral"] = RGB( + this->vSidConfig.at("colors").at("hovNeutral").value("r", 250), + this->vSidConfig.at("colors").at("hovNeutral").value("g", 160), + this->vSidConfig.at("colors").at("hovNeutral").value("b", 0) + ); + } + else this->colors["hovNeutral"] = RGB(250, 160, 0); + + if (this->vSidConfig.at("colors").contains("hovWarning")) + { + this->colors["hovWarning"] = RGB( + this->vSidConfig.at("colors").at("hovWarning").value("r", 250), + this->vSidConfig.at("colors").at("hovWarning").value("g", 0), + this->vSidConfig.at("colors").at("hovWarning").value("b", 0) + ); + } + else this->colors["hovWarning"] = RGB(250, 0, 0); + + // pseudo values for special color use cases + if (!this->colors.contains("squawkSet")) this->colors["squawkSet"] = RGB(300, 300, 300); + } + catch (std::error_code& e) + { + messageHandler->writeMessage("ERROR", "Failed to import colors: " + e.message()); + } + catch (const json::parse_error& e) + { + messageHandler->writeMessage("ERROR", "[Parse Error] in color config section: " + std::string(e.what())); + } + catch (const json::type_error& e) + { + messageHandler->writeMessage("ERROR", "[Type Error] in color config section: " + std::string(e.what())); + } + catch (const json::other_error& e) + { + messageHandler->writeMessage("ERROR", "[Other Error] in color config section: " + std::string(e.what())); + } + catch (const json::out_of_range& e) + { + messageHandler->writeMessage("ERROR", "[Out of Range] in color config section: " + std::string(e.what())); + } + + // get request times + + try + { + this->reqTimes.insert({ "caution", this->vSidConfig.at("requests").value("caution", 2) }); + this->reqTimes.insert({ "warning", this->vSidConfig.at("requests").value("warning", 5) }); + } + catch (json::parse_error& e) + { + messageHandler->writeMessage("ERROR", "Failed to get request timers: " + std::string(e.what())); + } + + // get clrf min values + + try + { + this->clrf.altCaution = this->vSidConfig.at("clrf").value("altCaution", 1500); + this->clrf.altWarning = this->vSidConfig.at("clrf").value("altWarning", 500); + this->clrf.distCaution = this->vSidConfig.at("clrf").value("distCaution", 10.0); + this->clrf.distWarning = this->vSidConfig.at("clrf").value("distWarning", 2.0); + } + catch (json::out_of_range& e) + { + messageHandler->writeMessage("ERROR", "Failed to get clrf min values: " + std::string(e.what())); + } + + // get indicator reference values + + try + { + this->indicator.offset = this->vSidConfig.at("display").value("indicatorOffset", 20); + this->indicator.zoomScale = this->vSidConfig.at("display").value("indicatorZoomScale", 0.5); + this->indicator.showBelowZoom = this->vSidConfig.at("display").value("indicatorShowBelowZoom", 600); + } + catch (json::out_of_range& e) + { + messageHandler->writeMessage("ERROR", "Failed to get indicator default reference values: " + std::string(e.what())); + } } void vsid::ConfigParser::loadAirportConfig(std::map &activeAirports, - std::map>& savedCustomRules, - std::map>& savedSettings, - std::map>& savedAreas, - std::map, vsid::Airport::compreq>>>& savedRequests, - std::map, vsid::Airport::compreq>>>>& savedRwyRequests - ) + std::map>& savedCustomRules, + std::map>& savedSettings, + std::map>& savedAreas, + std::map, vsid::Airport::compreq>>>& savedRequests, + std::map, vsid::Airport::compreq>>>>& savedRwyRequests + ) { - // get the current path where plugins .dll is stored - char path[MAX_PATH + 1] = { 0 }; - GetModuleFileNameA((HINSTANCE)&__ImageBase, path, MAX_PATH); - PathRemoveFileSpecA(path); - std::filesystem::path basePath = path; - - if (this->vSidConfig.contains("airportConfigs")) - { - basePath.append(this->vSidConfig.value("airportConfigs", "")).make_preferred(); - } - else - { - messageHandler->writeMessage("ERROR", "No config path for airports in main config"); - return; - } - - if (!std::filesystem::exists(basePath)) - { - messageHandler->writeMessage("ERROR", "No airport config folder found at: " + basePath.string()); - return; - } - - std::vector files; - std::set aptConfig; + // get the current path where plugins .dll is stored + char path[MAX_PATH + 1] = { 0 }; + GetModuleFileNameA((HINSTANCE)&__ImageBase, path, MAX_PATH); + PathRemoveFileSpecA(path); + std::filesystem::path basePath = path; + + if (this->vSidConfig.contains("airportConfigs")) + { + basePath.append(this->vSidConfig.value("airportConfigs", "")).make_preferred(); + } + else + { + messageHandler->writeMessage("ERROR", "No config path for airports in main config"); + return; + } + + if (!std::filesystem::exists(basePath)) + { + messageHandler->writeMessage("ERROR", "No airport config folder found at: " + basePath.string()); + return; + } + + std::vector files; + std::set aptConfig; /* for (const std::filesystem::path& entry : std::filesystem::recursive_directory_iterator(basePath)) // needs further #evaluate - can cause slow loading - { - if (!std::filesystem::is_directory(entry) && entry.extension() == ".json") - { - this->configPaths.insert(entry); - } - }*/ - - for (auto &[icao, aptInfo] : activeAirports) - { - for (const std::filesystem::path& entry : std::filesystem::directory_iterator(basePath)) - //for (const std::filesystem::path& entry : this->configPaths) - { - if (!std::filesystem::is_directory(entry) && entry.extension() == ".json") - { - std::ifstream configFile(entry.string()); - - try - { - this->parsedConfig = json::parse(configFile); - - if (!this->parsedConfig.contains(icao)) continue; - else - { - aptConfig.insert(icao); - - // general settings - - aptInfo.icao = icao; - aptInfo.elevation = this->parsedConfig.at(icao).value("elevation", 0); - aptInfo.equipCheck = this->parsedConfig.at(icao).value("equipCheck", true); - aptInfo.enableRVSids = this->parsedConfig.at(icao).value("enableRVSids", true); - aptInfo.allRwys = vsid::utils::split(this->parsedConfig.at(icao).value("runways", ""), ','); - aptInfo.transAlt = this->parsedConfig.at(icao).value("transAlt", 0); - aptInfo.maxInitialClimb = this->parsedConfig.at(icao).value("maxInitialClimb", 0); - aptInfo.timezone = this->parsedConfig.at(icao).value("timezone", "Etc/UTC"); - aptInfo.requests["clearance"] = {}; - aptInfo.requests["startup"] = {}; - aptInfo.requests["pushback"] = {}; - aptInfo.requests["taxi"] = {}; - aptInfo.requests["departure"] = {}; - aptInfo.requests["vfr"] = {}; - aptInfo.rwyrequests["startup"] = {}; + { + if (!std::filesystem::is_directory(entry) && entry.extension() == ".json") + { + this->configPaths.insert(entry); + } + }*/ + + for (auto &[icao, aptInfo] : activeAirports) + { + for (const std::filesystem::path& entry : std::filesystem::directory_iterator(basePath)) + //for (const std::filesystem::path& entry : this->configPaths) + { + if (!std::filesystem::is_directory(entry) && entry.extension() == ".json") + { + std::ifstream configFile(entry.string()); + + try + { + this->parsedConfig = json::parse(configFile); + + if (!this->parsedConfig.contains(icao)) continue; + else + { + aptConfig.insert(icao); + + // general settings + + aptInfo.icao = icao; + aptInfo.elevation = this->parsedConfig.at(icao).value("elevation", 0); + aptInfo.equipCheck = this->parsedConfig.at(icao).value("equipCheck", true); + aptInfo.enableRVSids = this->parsedConfig.at(icao).value("enableRVSids", true); + aptInfo.allRwys = vsid::utils::split(this->parsedConfig.at(icao).value("runways", ""), ','); + aptInfo.transAlt = this->parsedConfig.at(icao).value("transAlt", 0); + aptInfo.maxInitialClimb = this->parsedConfig.at(icao).value("maxInitialClimb", 0); + aptInfo.timezone = this->parsedConfig.at(icao).value("timezone", "Etc/UTC"); + aptInfo.requests["clearance"] = {}; + aptInfo.requests["startup"] = {}; + aptInfo.requests["pushback"] = {}; + aptInfo.requests["taxi"] = {}; + aptInfo.requests["departure"] = {}; + aptInfo.requests["vfr"] = {}; + aptInfo.rwyrequests["startup"] = {}; aptInfo.autoHandoff = this->parsedConfig.at(icao).value("autoHandoff", true); - // customRules - - std::map customRules; - for (auto &el : this->parsedConfig.at(icao).value("customRules", std::map{})) - { - std::pair rule = { vsid::utils::toupper(el.first), el.second }; - customRules.insert(rule); - } - - // overwrite loaded rule settings from config with current values at the apt - - if (savedCustomRules.contains(icao)) - { - for (std::pair& rule : savedCustomRules[icao]) - { - if (customRules.contains(rule.first)) - { - customRules[rule.first] = rule.second; - } - } - } - aptInfo.customRules = customRules; - - std::set appSI; - int appSIPrio = 0; - for (std::string& si : vsid::utils::split(this->parsedConfig.at(icao).value("appSI", ""), ',')) - { - aptInfo.appSI[si] = appSIPrio; - appSIPrio++; - } - - // areas - - if (this->parsedConfig.at(icao).contains("areas")) - { - for (auto& area : this->parsedConfig.at(icao).at("areas").items()) - { - std::vector> coords; - bool isActive = false; - bool arrAsDep = false; - for (auto& coord : this->parsedConfig.at(icao).at("areas").at(area.key()).items()) - { - if (coord.key() == "active") - { - isActive = this->parsedConfig.at(icao).at("areas").at(area.key()).value("active", false); - continue; - } - else if (coord.key() == "arrAsDep") - { - arrAsDep = this->parsedConfig.at(icao).at("areas").at(area.key()).value("arrAsDep", false); - continue; - } - std::string lat = this->parsedConfig.at(icao).at("areas").at(area.key()).at(coord.key()).value("lat", ""); - std::string lon = this->parsedConfig.at(icao).at("areas").at(area.key()).at(coord.key()).value("lon", ""); - - if (lat == "" || lon == "") - { - messageHandler->writeMessage("ERROR", "Couldn't read LAT or LON value for \"" + - coord.key() + "\" in area \"" + area.key() + "\" at \"" + - icao + "\""); - break; - } - coords.push_back({ lat, lon }); - } - if (coords.size() < 3) - { - messageHandler->writeMessage("ERROR", "Area \"" + area.key() + "\" in \"" + - icao + "\" has not enough points configured (less than 3)."); - continue; - } - if (savedAreas.contains(icao)) - { - if (savedAreas[icao].contains(vsid::utils::toupper(area.key()))) - { - isActive = savedAreas[icao][vsid::utils::toupper(area.key())].isActive; - } - } - aptInfo.areas.insert({ vsid::utils::toupper(area.key()), vsid::Area{coords, isActive, arrAsDep} }); - } - } - - // intersections - - if (this->parsedConfig.at(icao).contains("intersections")) - { - for (auto& intsecList : this->parsedConfig.at(icao).at("intersections").items()) - { - std::string rwy = intsecList.key(); - std::vector intsec = vsid::utils::split(intsecList.value(), ','); - - aptInfo.intsec.insert({ rwy, intsec }); - } - } - - // airport settings - - if (savedSettings.contains(icao)) - { - aptInfo.settings = savedSettings[icao]; - } - else - { - aptInfo.settings = { {"lvp", false}, - {"time", this->parsedConfig.at(icao).value("timeMode", false)}, - {"auto", false} - }; - } - - // saved requests - if not found base settings already in general settings - - if (savedRequests.contains(icao)) aptInfo.requests = savedRequests[icao]; - - // saved rwy requests - if not found base settings already in general settings - - if (savedRwyRequests.contains(icao)) aptInfo.rwyrequests = savedRwyRequests[icao]; - - // sids + // customRules + + std::map customRules; + for (auto &el : this->parsedConfig.at(icao).value("customRules", std::map{})) + { + std::pair rule = { vsid::utils::toupper(el.first), el.second }; + customRules.insert(rule); + } + + // overwrite loaded rule settings from config with current values at the apt + + if (savedCustomRules.contains(icao)) + { + for (std::pair& rule : savedCustomRules[icao]) + { + if (customRules.contains(rule.first)) + { + customRules[rule.first] = rule.second; + } + } + } + aptInfo.customRules = customRules; + + std::set appSI; + int appSIPrio = 0; + for (std::string& si : vsid::utils::split(this->parsedConfig.at(icao).value("appSI", ""), ',')) + { + aptInfo.appSI[si] = appSIPrio; + appSIPrio++; + } + + // areas + + if (this->parsedConfig.at(icao).contains("areas")) + { + for (auto& area : this->parsedConfig.at(icao).at("areas").items()) + { + std::vector> coords; + bool isActive = false; + bool arrAsDep = false; + for (auto& coord : this->parsedConfig.at(icao).at("areas").at(area.key()).items()) + { + if (coord.key() == "active") + { + isActive = this->parsedConfig.at(icao).at("areas").at(area.key()).value("active", false); + continue; + } + else if (coord.key() == "arrAsDep") + { + arrAsDep = this->parsedConfig.at(icao).at("areas").at(area.key()).value("arrAsDep", false); + continue; + } + std::string lat = this->parsedConfig.at(icao).at("areas").at(area.key()).at(coord.key()).value("lat", ""); + std::string lon = this->parsedConfig.at(icao).at("areas").at(area.key()).at(coord.key()).value("lon", ""); + + if (lat == "" || lon == "") + { + messageHandler->writeMessage("ERROR", "Couldn't read LAT or LON value for \"" + + coord.key() + "\" in area \"" + area.key() + "\" at \"" + + icao + "\""); + break; + } + coords.push_back({ lat, lon }); + } + if (coords.size() < 3) + { + messageHandler->writeMessage("ERROR", "Area \"" + area.key() + "\" in \"" + + icao + "\" has not enough points configured (less than 3)."); + continue; + } + if (savedAreas.contains(icao)) + { + if (savedAreas[icao].contains(vsid::utils::toupper(area.key()))) + { + isActive = savedAreas[icao][vsid::utils::toupper(area.key())].isActive; + } + } + aptInfo.areas.insert({ vsid::utils::toupper(area.key()), vsid::Area{coords, isActive, arrAsDep} }); + } + } + + // intersections + + if (this->parsedConfig.at(icao).contains("intersections")) + { + for (auto& intsecList : this->parsedConfig.at(icao).at("intersections").items()) + { + std::string rwy = intsecList.key(); + std::vector intsec = vsid::utils::split(intsecList.value(), ','); + + aptInfo.intsec.insert({ rwy, intsec }); + } + } + + // airport settings + + if (savedSettings.contains(icao)) + { + aptInfo.settings = savedSettings[icao]; + } + else + { + aptInfo.settings = { {"lvp", false}, + {"time", this->parsedConfig.at(icao).value("timeMode", false)}, + {"auto", false} + }; + } + + // saved requests - if not found base settings already in general settings + + if (savedRequests.contains(icao)) aptInfo.requests = savedRequests[icao]; + + // saved rwy requests - if not found base settings already in general settings + + if (savedRwyRequests.contains(icao)) aptInfo.rwyrequests = savedRwyRequests[icao]; + + // sids // initialize default values - vsid::tmpSidSettings fieldSetting; - vsid::tmpSidSettings wptSetting; - vsid::tmpSidSettings desSetting; - vsid::tmpSidSettings idSetting; - - // "field level" - iterates over restrictions and sid way points / bases - - for (auto &sidField : this->parsedConfig.at(icao).at("sids").items()) - { - std::string fixedNumber = ""; - - if (sidField.key() == "allowDiffNumbers") fieldSetting.allowDiffNumbers = this->parsedConfig.at(icao).at("sids").at(sidField.key()); - else if (sidField.key() == "initial") fieldSetting.initial = this->parsedConfig.at(icao).at("sids").at(sidField.key()); - else if (sidField.key() == "climbvia") fieldSetting.via = this->parsedConfig.at(icao).at("sids").at(sidField.key()); - else if (sidField.key() == "wpt") fieldSetting.wpt = this->parsedConfig.at(icao).at("sids").at(sidField.key()); - else if (sidField.key() == "pilotfiled") fieldSetting.pilotfiled = this->parsedConfig.at(icao).at("sids").at(sidField.key()); - else if (sidField.key() == "wingType") fieldSetting.wingType = this->parsedConfig.at(icao).at("sids").at(sidField.key()); - else if (sidField.key() == "acftType") fieldSetting.acftType = this->parsedConfig.at(icao).at("sids").at(sidField.key()); - else if (sidField.key() == "dest") fieldSetting.dest = this->parsedConfig.at(icao).at("sids").at(sidField.key()); - else if (sidField.key() == "route") - { + vsid::tmpSidSettings fieldSetting; + vsid::tmpSidSettings wptSetting; + vsid::tmpSidSettings desSetting; + vsid::tmpSidSettings idSetting; + + // "field level" - iterates over restrictions and sid way points / bases + + for (auto &sidField : this->parsedConfig.at(icao).at("sids").items()) + { + std::string fixedNumber = ""; + + if (sidField.key() == "allowDiffNumbers") fieldSetting.allowDiffNumbers = this->parsedConfig.at(icao).at("sids").at(sidField.key()); + else if (sidField.key() == "initial") fieldSetting.initial = this->parsedConfig.at(icao).at("sids").at(sidField.key()); + else if (sidField.key() == "climbvia") fieldSetting.via = this->parsedConfig.at(icao).at("sids").at(sidField.key()); + else if (sidField.key() == "wpt") fieldSetting.wpt = this->parsedConfig.at(icao).at("sids").at(sidField.key()); + else if (sidField.key() == "pilotfiled") fieldSetting.pilotfiled = this->parsedConfig.at(icao).at("sids").at(sidField.key()); + else if (sidField.key() == "wingType") fieldSetting.wingType = this->parsedConfig.at(icao).at("sids").at(sidField.key()); + else if (sidField.key() == "acftType") fieldSetting.acftType = this->parsedConfig.at(icao).at("sids").at(sidField.key()); + else if (sidField.key() == "dest") fieldSetting.dest = this->parsedConfig.at(icao).at("sids").at(sidField.key()); + else if (sidField.key() == "route") + { if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).contains("allow")) { for (const auto& id : this->parsedConfig.at(icao).at("sids").at(sidField.key()).at("allow").items()) @@ -665,16 +665,16 @@ void vsid::ConfigParser::loadAirportConfig(std::map if (!configRoute.empty()) fieldSetting.route["deny"].insert({ routeId, configRoute }); } } - } - else if (sidField.key() == "wtc") fieldSetting.wtc = this->parsedConfig.at(icao).at("sids").at(sidField.key()); - else if (sidField.key() == "engineType") fieldSetting.engineType = this->parsedConfig.at(icao).at("sids").at(sidField.key()); - else if (sidField.key() == "engineCount") fieldSetting.engineCount = this->parsedConfig.at(icao).at("sids").at(sidField.key()); - else if (sidField.key() == "mtow") fieldSetting.mtow = this->parsedConfig.at(icao).at("sids").at(sidField.key()); - else if (sidField.key() == "customRule") fieldSetting.customRule = vsid::utils::toupper(this->parsedConfig.at(icao).at("sids").at(sidField.key())); - else if (sidField.key() == "area") fieldSetting.area = vsid::utils::toupper(this->parsedConfig.at(icao).at("sids").at(sidField.key())); - else if (sidField.key() == "equip") - { - fieldSetting.equip = this->parsedConfig.at(icao).at("sids").at(sidField.key()); + } + else if (sidField.key() == "wtc") fieldSetting.wtc = this->parsedConfig.at(icao).at("sids").at(sidField.key()); + else if (sidField.key() == "engineType") fieldSetting.engineType = this->parsedConfig.at(icao).at("sids").at(sidField.key()); + else if (sidField.key() == "engineCount") fieldSetting.engineCount = this->parsedConfig.at(icao).at("sids").at(sidField.key()); + else if (sidField.key() == "mtow") fieldSetting.mtow = this->parsedConfig.at(icao).at("sids").at(sidField.key()); + else if (sidField.key() == "customRule") fieldSetting.customRule = vsid::utils::toupper(this->parsedConfig.at(icao).at("sids").at(sidField.key())); + else if (sidField.key() == "area") fieldSetting.area = vsid::utils::toupper(this->parsedConfig.at(icao).at("sids").at(sidField.key())); + else if (sidField.key() == "equip") + { + fieldSetting.equip = this->parsedConfig.at(icao).at("sids").at(sidField.key()); // updating equipment codes to upper case if in lower case @@ -684,29 +684,29 @@ void vsid::ConfigParser::loadAirportConfig(std::map { std::pair cap = { vsid::utils::toupper(it->first), it->second }; it = fieldSetting.equip.erase(it); - fieldSetting.equip.insert(it, cap); + fieldSetting.equip.insert(it, cap); continue; } ++it; } - } - else if (sidField.key() == "lvp") fieldSetting.lvp = this->parsedConfig.at(icao).at("sids").at(sidField.key()); - else if (sidField.key() == "actArrRwy") - { - if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).contains("allow")) - { + } + else if (sidField.key() == "lvp") fieldSetting.lvp = this->parsedConfig.at(icao).at("sids").at(sidField.key()); + else if (sidField.key() == "actArrRwy") + { + if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).contains("allow")) + { fieldSetting.actArrRwy["allow"]["all"] = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at("allow").value("all", ""); fieldSetting.actArrRwy["allow"]["any"] = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at("allow").value("any", ""); - } + } if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).contains("deny")) { fieldSetting.actArrRwy["deny"]["all"] = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at("deny").value("all", ""); fieldSetting.actArrRwy["deny"]["any"] = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at("deny").value("any", ""); } - } - else if (sidField.key() == "actDepRwy") - { + } + else if (sidField.key() == "actDepRwy") + { if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).contains("allow")) { fieldSetting.actDepRwy["allow"]["all"] = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at("allow").value("all", ""); @@ -718,42 +718,42 @@ void vsid::ConfigParser::loadAirportConfig(std::map fieldSetting.actDepRwy["deny"]["all"] = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at("deny").value("all", ""); fieldSetting.actDepRwy["deny"]["any"] = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at("deny").value("any", ""); } - } - else if (sidField.key() == "timeFrom") fieldSetting.timeFrom = this->parsedConfig.at(icao).at("sids").at(sidField.key()); - else if (sidField.key() == "timeTo") fieldSetting.timeTo = this->parsedConfig.at(icao).at("sids").at(sidField.key()); - else if (sidField.key() == "sidHighlight") fieldSetting.sidHighlight = this->parsedConfig.at(icao).at("sids").at(sidField.key()); - else if (sidField.key() == "clmbHighlight") fieldSetting.clmbHighlight = this->parsedConfig.at(icao).at("sids").at(sidField.key()); - else if (!this->isConfigValue(sidField.key())) - { - // special check for possible military SIDs / OIDs (format: XY12) - - if (vsid::utils::lastIsDigit(sidField.key()) && vsid::utils::countDigits(sidField.key()) > 1 && sidField.key().length() > 2) - { - fieldSetting.base = sidField.key().substr(0, sidField.key().length() - 1); - fixedNumber = sidField.key().back(); - - messageHandler->writeMessage("DEBUG", "[" + sidField.key() + "] contained a number - setting as fixed SID number: " + - fixedNumber, vsid::MessageHandler::DebugArea::Conf); - } - else - { + } + else if (sidField.key() == "timeFrom") fieldSetting.timeFrom = this->parsedConfig.at(icao).at("sids").at(sidField.key()); + else if (sidField.key() == "timeTo") fieldSetting.timeTo = this->parsedConfig.at(icao).at("sids").at(sidField.key()); + else if (sidField.key() == "sidHighlight") fieldSetting.sidHighlight = this->parsedConfig.at(icao).at("sids").at(sidField.key()); + else if (sidField.key() == "clmbHighlight") fieldSetting.clmbHighlight = this->parsedConfig.at(icao).at("sids").at(sidField.key()); + else if (!this->isConfigValue(sidField.key())) + { + // special check for possible military SIDs / OIDs (format: XY12) + + if (vsid::utils::lastIsDigit(sidField.key()) && vsid::utils::countDigits(sidField.key()) > 1 && sidField.key().length() > 2) + { + fieldSetting.base = sidField.key().substr(0, sidField.key().length() - 1); + fixedNumber = sidField.key().back(); + + messageHandler->writeMessage("DEBUG", "[" + sidField.key() + "] contained a number - setting as fixed SID number: " + + fixedNumber, vsid::MessageHandler::DebugArea::Conf); + } + else + { fieldSetting.base = sidField.key(); fieldSetting.wpt = fieldSetting.base; // #evaluate - remove from field settings and always overwrite in wptSettings? - } + } - // "waypoint / base level" - iterates over restrictions and sid designators + // "waypoint / base level" - iterates over restrictions and sid designators - wptSetting = fieldSetting; + wptSetting = fieldSetting; - for (auto& sidWpt : this->parsedConfig.at(icao).at("sids").at(sidField.key()).items()) - { - if (sidWpt.key() == "allowDiffNumbers") wptSetting.allowDiffNumbers = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()); - else if (sidWpt.key() == "initial") wptSetting.initial = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()); - else if(sidWpt.key() == "climbvia") wptSetting.via = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()); - else if (sidWpt.key() == "wpt") wptSetting.wpt = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()); + for (auto& sidWpt : this->parsedConfig.at(icao).at("sids").at(sidField.key()).items()) + { + if (sidWpt.key() == "allowDiffNumbers") wptSetting.allowDiffNumbers = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()); + else if (sidWpt.key() == "initial") wptSetting.initial = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()); + else if(sidWpt.key() == "climbvia") wptSetting.via = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()); + else if (sidWpt.key() == "wpt") wptSetting.wpt = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()); else if (sidWpt.key() == "trans") { - wptSetting.transition.clear(); + wptSetting.transition.clear(); for (auto& base : this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).items()) { @@ -761,21 +761,21 @@ void vsid::ConfigParser::loadAirportConfig(std::map trans.base = base.key(); - if (std::string desig = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(base.key()); desig != "XXX") - trans.designator = desig; + if (std::string desig = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(base.key()); desig != "XXX") + trans.designator = desig; wptSetting.transition.insert({ base.key(), trans }); } } - else if(sidWpt.key() == "pilotfiled") wptSetting.pilotfiled = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()); - else if (sidWpt.key() == "wingType") wptSetting.wingType = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()); + else if(sidWpt.key() == "pilotfiled") wptSetting.pilotfiled = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()); + else if (sidWpt.key() == "wingType") wptSetting.wingType = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()); else if (sidWpt.key() == "acftType") wptSetting.acftType = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()); else if (sidWpt.key() == "dest") wptSetting.dest = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()); else if (sidWpt.key() == "route") { if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).contains("allow")) { - wptSetting.route["allow"].clear(); + wptSetting.route["allow"].clear(); for (const auto& id : this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at("allow").items()) { @@ -789,7 +789,7 @@ void vsid::ConfigParser::loadAirportConfig(std::map if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).contains("deny")) { - wptSetting.route["deny"].clear(); + wptSetting.route["deny"].clear(); for (const auto& id : this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at("deny").items()) { @@ -809,7 +809,7 @@ void vsid::ConfigParser::loadAirportConfig(std::map else if (sidWpt.key() == "area") wptSetting.area = vsid::utils::toupper(this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key())); else if (sidWpt.key() == "equip") { - wptSetting.equip = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()); + wptSetting.equip = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()); // updating equipment codes to upper case if in lower case @@ -819,7 +819,7 @@ void vsid::ConfigParser::loadAirportConfig(std::map { std::pair cap = { vsid::utils::toupper(it->first), it->second }; it = wptSetting.equip.erase(it); - wptSetting.equip.insert(it, cap); + wptSetting.equip.insert(it, cap); continue; } ++it; @@ -830,14 +830,14 @@ void vsid::ConfigParser::loadAirportConfig(std::map { if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).contains("allow")) { - wptSetting.actArrRwy["allow"]["all"] = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at("allow").value("all", ""); - wptSetting.actArrRwy["allow"]["any"] = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at("allow").value("any", ""); + wptSetting.actArrRwy["allow"]["all"] = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at("allow").value("all", ""); + wptSetting.actArrRwy["allow"]["any"] = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at("allow").value("any", ""); } if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).contains("deny")) { - wptSetting.actArrRwy["deny"]["all"] = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at("deny").value("all", ""); - wptSetting.actArrRwy["deny"]["any"] = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at("deny").value("any", ""); + wptSetting.actArrRwy["deny"]["all"] = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at("deny").value("all", ""); + wptSetting.actArrRwy["deny"]["any"] = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at("deny").value("any", ""); } } else if (sidWpt.key() == "actDepRwy") @@ -858,58 +858,58 @@ void vsid::ConfigParser::loadAirportConfig(std::map else if (sidWpt.key() == "timeTo") wptSetting.timeTo = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()); else if (sidWpt.key() == "sidHighlight") wptSetting.sidHighlight = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()); else if (sidWpt.key() == "clmbHighlight") wptSetting.clmbHighlight = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()); - else if (!this->isConfigValue(sidWpt.key())) - { - if(!vsid::utils::containsDigit(sidWpt.key()) && sidWpt.key() != "XXX") wptSetting.desig = sidWpt.key(); + else if (!this->isConfigValue(sidWpt.key())) + { + if(!vsid::utils::containsDigit(sidWpt.key()) && sidWpt.key() != "XXX") wptSetting.desig = sidWpt.key(); - // "designator level" - iterates over restrictions and sid ids + // "designator level" - iterates over restrictions and sid ids - desSetting = wptSetting; + desSetting = wptSetting; - for (auto& sidDes : this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).items()) - { - if (sidDes.key() == "rwy") - desSetting.rwys = vsid::utils::split(this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()), ','); + for (auto& sidDes : this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).items()) + { + if (sidDes.key() == "rwy") + desSetting.rwys = vsid::utils::split(this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()), ','); else if (sidDes.key() == "allowDiffNumbers") desSetting.allowDiffNumbers = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); - else if (sidDes.key() == "initial") - desSetting.initial = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); + else if (sidDes.key() == "initial") + desSetting.initial = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); else if (sidDes.key() == "climbvia") - desSetting.via = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); - else if (sidDes.key() == "wpt") - desSetting.wpt = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); + desSetting.via = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); + else if (sidDes.key() == "wpt") + desSetting.wpt = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); else if (sidDes.key() == "trans") { - desSetting.transition.clear(); + desSetting.transition.clear(); for (auto& base : this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).items()) { vsid::Transition trans; trans.base = base.key(); - if (std::string desig = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()). - at(sidDes.key()).at(base.key()); desig != "XXX") - trans.designator = desig; + if (std::string desig = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()). + at(sidDes.key()).at(base.key()); desig != "XXX") + trans.designator = desig; desSetting.transition.insert({ base.key(), trans }); } - if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()) - .at(sidDes.key()).size() == 0) desSetting.transition.clear(); + if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()) + .at(sidDes.key()).size() == 0) desSetting.transition.clear(); } else if (sidDes.key() == "pilotfiled") - desSetting.pilotfiled = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); + desSetting.pilotfiled = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); else if (sidDes.key() == "wingType") desSetting.wingType = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); else if (sidDes.key() == "acftType") - desSetting.acftType = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); + desSetting.acftType = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); else if (sidDes.key() == "dest") - desSetting.dest = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); + desSetting.dest = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); else if (sidDes.key() == "route") { if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).contains("allow")) { - desSetting.route["allow"].clear(); + desSetting.route["allow"].clear(); for (const auto& id : this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at("allow").items()) { @@ -923,7 +923,7 @@ void vsid::ConfigParser::loadAirportConfig(std::map if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).contains("deny")) { - desSetting.route["deny"].clear(); + desSetting.route["deny"].clear(); for (const auto& id : this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at("deny").items()) { @@ -936,22 +936,22 @@ void vsid::ConfigParser::loadAirportConfig(std::map } } else if (sidDes.key() == "wtc") - desSetting.wtc = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); + desSetting.wtc = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); else if (sidDes.key() == "engineType") - desSetting.engineType = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); + desSetting.engineType = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); else if (sidDes.key() == "engineCount") - desSetting.engineCount = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); + desSetting.engineCount = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); else if (sidDes.key() == "mtow") - desSetting.mtow = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); + desSetting.mtow = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); else if (sidDes.key() == "customRule") - desSetting.customRule = vsid::utils::toupper(this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key())); + desSetting.customRule = vsid::utils::toupper(this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key())); else if (sidDes.key() == "area") - desSetting.area = vsid::utils::toupper(this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key())); + desSetting.area = vsid::utils::toupper(this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key())); else if (sidDes.key() == "equip") { - desSetting.equip = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); + desSetting.equip = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); - // updating equipment codes to upper case if in lower case + // updating equipment codes to upper case if in lower case for (std::map::iterator it = desSetting.equip.begin(); it != desSetting.equip.end();) { @@ -959,30 +959,30 @@ void vsid::ConfigParser::loadAirportConfig(std::map { std::pair cap = { vsid::utils::toupper(it->first), it->second }; it = desSetting.equip.erase(it); - desSetting.equip.insert(it, cap); + desSetting.equip.insert(it, cap); continue; } ++it; } } else if (sidDes.key() == "lvp") - desSetting.lvp = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); + desSetting.lvp = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); else if (sidDes.key() == "actArrRwy") { if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).contains("allow")) { - desSetting.actArrRwy["allow"]["all"] = - this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at("allow").value("all", ""); - desSetting.actArrRwy["allow"]["any"] = - this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at("allow").value("any", ""); + desSetting.actArrRwy["allow"]["all"] = + this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at("allow").value("all", ""); + desSetting.actArrRwy["allow"]["any"] = + this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at("allow").value("any", ""); } if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).contains("deny")) { - desSetting.actArrRwy["deny"]["all"] = - this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at("deny").value("all", ""); - desSetting.actArrRwy["deny"]["any"] = - this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at("deny").value("any", ""); + desSetting.actArrRwy["deny"]["all"] = + this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at("deny").value("all", ""); + desSetting.actArrRwy["deny"]["any"] = + this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at("deny").value("any", ""); } } else if (sidDes.key() == "actDepRwy") @@ -1004,148 +1004,148 @@ void vsid::ConfigParser::loadAirportConfig(std::map } } else if (sidDes.key() == "timeFrom") - desSetting.timeFrom = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); + desSetting.timeFrom = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); else if (sidDes.key() == "timeTo") - desSetting.timeTo = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); + desSetting.timeTo = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); else if (sidDes.key() == "sidHighlight") - desSetting.sidHighlight = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); + desSetting.sidHighlight = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); else if (sidDes.key() == "clmbHighlight") - desSetting.clmbHighlight = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); - else if (!this->isConfigValue(sidDes.key())) - { - desSetting.id = sidDes.key(); + desSetting.clmbHighlight = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()); + else if (!this->isConfigValue(sidDes.key())) + { + desSetting.id = sidDes.key(); - // "id level" - iterates over restrictions on id level (highest priority) + // "id level" - iterates over restrictions on id level (highest priority) - idSetting = desSetting; + idSetting = desSetting; - for (auto& sidId : this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).items()) - { - if (sidId.key() == "rwy") - idSetting.rwys = vsid::utils::split(this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()), ','); - else if (sidId.key() == "prio") - idSetting.prio = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); + for (auto& sidId : this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).items()) + { + if (sidId.key() == "rwy") + idSetting.rwys = vsid::utils::split(this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()), ','); + else if (sidId.key() == "prio") + idSetting.prio = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); else if (sidId.key() == "allowDiffNumbers") idSetting.allowDiffNumbers = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); - else if (sidId.key() == "initial") - idSetting.initial = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); - else if (sidId.key() == "climbvia") - idSetting.via = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); + else if (sidId.key() == "initial") + idSetting.initial = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); + else if (sidId.key() == "climbvia") + idSetting.via = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); else if (sidId.key() == "wpt") - idSetting.wpt = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); - else if (sidId.key() == "trans") - { - idSetting.transition.clear(); - - for (auto &base : this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()).items()) - { - vsid::Transition trans; - - trans.base = base.key(); - if (std::string desig = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()) - .at(sidDes.key()).at(sidId.key()).at(base.key()); desig != "XXX") - trans.designator = desig; - - idSetting.transition.insert({ base.key(), trans}); - } - - if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()) - .at(sidDes.key()).at(sidId.key()).size() == 0) idSetting.transition.clear(); - } - else if (sidId.key() == "pilotfiled") - idSetting.pilotfiled = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); + idSetting.wpt = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); + else if (sidId.key() == "trans") + { + idSetting.transition.clear(); + + for (auto &base : this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()).items()) + { + vsid::Transition trans; + + trans.base = base.key(); + if (std::string desig = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()) + .at(sidDes.key()).at(sidId.key()).at(base.key()); desig != "XXX") + trans.designator = desig; + + idSetting.transition.insert({ base.key(), trans}); + } + + if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()) + .at(sidDes.key()).at(sidId.key()).size() == 0) idSetting.transition.clear(); + } + else if (sidId.key() == "pilotfiled") + idSetting.pilotfiled = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); else if (sidId.key() == "wingType") idSetting.wingType = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); - else if (sidId.key() == "acftType") - idSetting.acftType = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); - else if (sidId.key() == "dest") - idSetting.dest = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); - else if (sidId.key() == "route") - { - if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()).contains("allow")) - { - idSetting.route["allow"].clear(); - - for (const auto& id : this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()).at("allow").items()) - { - std::string routeId = id.key(); - std::vector configRoute = - vsid::utils::split(this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()).at("allow").value(routeId, ""), ','); - - if (!configRoute.empty()) idSetting.route["allow"].insert({ routeId, configRoute }); - } - } - - if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()).contains("deny")) - { - idSetting.route["deny"].clear(); - - for (const auto& id : this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()).at("deny").items()) - { - std::string routeId = id.key(); - std::vector configRoute = - vsid::utils::split(this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()).at("deny").value(routeId, ""), ','); - - if (!configRoute.empty()) idSetting.route["deny"].insert({ routeId, configRoute }); - } - } - } - else if (sidId.key() == "wtc") - idSetting.wtc = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); - else if (sidId.key() == "engineType") - idSetting.engineType = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); - else if (sidId.key() == "engineCount") - idSetting.engineCount = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); - else if (sidId.key() == "mtow") - idSetting.mtow = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); - else if (sidId.key() == "customRule") - idSetting.customRule = vsid::utils::toupper(this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key())); - else if (sidId.key() == "area") - idSetting.area = vsid::utils::toupper(this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key())); - else if (sidId.key() == "equip") - { - idSetting.equip = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); - - // updating equipment codes to upper case if in lower case - - for (std::map::iterator it = idSetting.equip.begin(); it != idSetting.equip.end();) - { - if (it->first != vsid::utils::toupper(it->first)) - { - std::pair cap = { vsid::utils::toupper(it->first), it->second }; - it = idSetting.equip.erase(it); - idSetting.equip.insert(it, cap); - continue; - } - ++it; - } - } - else if (sidId.key() == "lvp") - idSetting.lvp = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); - else if (sidId.key() == "actArrRwy") - { + else if (sidId.key() == "acftType") + idSetting.acftType = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); + else if (sidId.key() == "dest") + idSetting.dest = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); + else if (sidId.key() == "route") + { if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()).contains("allow")) { - idSetting.actArrRwy["allow"]["all"] = + idSetting.route["allow"].clear(); + + for (const auto& id : this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()).at("allow").items()) + { + std::string routeId = id.key(); + std::vector configRoute = + vsid::utils::split(this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()).at("allow").value(routeId, ""), ','); + + if (!configRoute.empty()) idSetting.route["allow"].insert({ routeId, configRoute }); + } + } + + if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()).contains("deny")) + { + idSetting.route["deny"].clear(); + + for (const auto& id : this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()).at("deny").items()) + { + std::string routeId = id.key(); + std::vector configRoute = + vsid::utils::split(this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()).at("deny").value(routeId, ""), ','); + + if (!configRoute.empty()) idSetting.route["deny"].insert({ routeId, configRoute }); + } + } + } + else if (sidId.key() == "wtc") + idSetting.wtc = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); + else if (sidId.key() == "engineType") + idSetting.engineType = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); + else if (sidId.key() == "engineCount") + idSetting.engineCount = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); + else if (sidId.key() == "mtow") + idSetting.mtow = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); + else if (sidId.key() == "customRule") + idSetting.customRule = vsid::utils::toupper(this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key())); + else if (sidId.key() == "area") + idSetting.area = vsid::utils::toupper(this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key())); + else if (sidId.key() == "equip") + { + idSetting.equip = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); + + // updating equipment codes to upper case if in lower case + + for (std::map::iterator it = idSetting.equip.begin(); it != idSetting.equip.end();) + { + if (it->first != vsid::utils::toupper(it->first)) + { + std::pair cap = { vsid::utils::toupper(it->first), it->second }; + it = idSetting.equip.erase(it); + idSetting.equip.insert(it, cap); + continue; + } + ++it; + } + } + else if (sidId.key() == "lvp") + idSetting.lvp = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); + else if (sidId.key() == "actArrRwy") + { + if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()).contains("allow")) + { + idSetting.actArrRwy["allow"]["all"] = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()) - .at("allow").value("all", ""); - idSetting.actArrRwy["allow"]["any"] = + .at("allow").value("all", ""); + idSetting.actArrRwy["allow"]["any"] = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()) - .at("allow").value("any", ""); + .at("allow").value("any", ""); } if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()).contains("deny")) { - idSetting.actArrRwy["deny"]["all"] = + idSetting.actArrRwy["deny"]["all"] = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()) - .at("deny").value("all", ""); - idSetting.actArrRwy["deny"]["any"] = + .at("deny").value("all", ""); + idSetting.actArrRwy["deny"]["any"] = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()) - .at("deny").value("any", ""); + .at("deny").value("any", ""); } - } - else if (sidId.key() == "actDepRwy") - { + } + else if (sidId.key() == "actDepRwy") + { if (this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()).contains("allow")) { idSetting.actDepRwy["allow"]["all"] = @@ -1165,37 +1165,37 @@ void vsid::ConfigParser::loadAirportConfig(std::map this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()) .at("deny").value("any", ""); } - } - else if (sidId.key() == "timeFrom") - idSetting.timeFrom = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); - else if (sidId.key() == "timeTo") - idSetting.timeTo = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); + } + else if (sidId.key() == "timeFrom") + idSetting.timeFrom = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); + else if (sidId.key() == "timeTo") + idSetting.timeTo = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); else if (sidId.key() == "sidHighlight") - idSetting.sidHighlight = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); + idSetting.sidHighlight = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); else if (sidId.key() == "clmbHighlight") - idSetting.clmbHighlight = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); + idSetting.clmbHighlight = this->parsedConfig.at(icao).at("sids").at(sidField.key()).at(sidWpt.key()).at(sidDes.key()).at(sidId.key()); - if (idSetting.equip.empty()) idSetting.equip["RNAV"] = true; - } + if (idSetting.equip.empty()) idSetting.equip["RNAV"] = true; + } - // save new sid + // save new sid - vsid::Sid newSid = { idSetting.base, idSetting.wpt, idSetting.id, fixedNumber, idSetting.desig, idSetting.rwys, idSetting.transition, - idSetting.allowDiffNumbers, idSetting.equip, idSetting.initial, idSetting.via, idSetting.prio, idSetting.pilotfiled, - idSetting.actArrRwy, idSetting.actDepRwy, idSetting.wtc, idSetting.engineType, idSetting.wingType, - idSetting.acftType, idSetting.engineCount, idSetting.mtow, idSetting.dest, idSetting.route, - idSetting.customRule, idSetting.area, idSetting.lvp, idSetting.timeFrom, idSetting.timeTo, - idSetting.sidHighlight, idSetting.clmbHighlight }; + vsid::Sid newSid = { idSetting.base, idSetting.wpt, idSetting.id, fixedNumber, idSetting.desig, idSetting.rwys, idSetting.transition, + idSetting.allowDiffNumbers, idSetting.equip, idSetting.initial, idSetting.via, idSetting.prio, idSetting.pilotfiled, + idSetting.actArrRwy, idSetting.actDepRwy, idSetting.wtc, idSetting.engineType, idSetting.wingType, + idSetting.acftType, idSetting.engineCount, idSetting.mtow, idSetting.dest, idSetting.route, + idSetting.customRule, idSetting.area, idSetting.lvp, idSetting.timeFrom, idSetting.timeTo, + idSetting.sidHighlight, idSetting.clmbHighlight }; aptInfo.sids.push_back(newSid); if (newSid.timeFrom != -1 && newSid.timeTo != -1) aptInfo.timeSids.push_back(newSid); // #dev - debugging msgs for evaluation of sid restriction levels std::string sidName = newSid.base + ((newSid.number.empty()) ? "_" : newSid.number) + newSid.designator + " (ID: " + newSid.id + ")"; messageHandler->writeMessage("DEBUG", "[" + sidName + "] wpt: " + newSid.waypoint, vsid::MessageHandler::DebugArea::Conf); - for (auto& [_, trans] : newSid.transition) - { - messageHandler->writeMessage("DEBUG", "[" + sidName + "] trans: " + trans.base + "_" + trans.designator, vsid::MessageHandler::DebugArea::Conf); - } + for (auto& [_, trans] : newSid.transition) + { + messageHandler->writeMessage("DEBUG", "[" + sidName + "] trans: " + trans.base + "_" + trans.designator, vsid::MessageHandler::DebugArea::Conf); + } messageHandler->writeMessage("DEBUG", "[" + sidName + "] rwys: " + vsid::utils::join(newSid.rwys, ','), vsid::MessageHandler::DebugArea::Conf); for (auto& [sEquip, allow] : newSid.equip) { @@ -1207,23 +1207,23 @@ void vsid::ConfigParser::loadAirportConfig(std::map messageHandler->writeMessage("DEBUG", "[" + sidName + "] pilotfiled: " + ((newSid.pilotfiled) ? "TRUE" : "FALSE"), vsid::MessageHandler::DebugArea::Conf); for (auto& [actArrList, arrType] : newSid.actArrRwy) { - for(auto& [arrWhich, actArr] : arrType) - { - messageHandler->writeMessage("DEBUG", "[" + sidName + "] actArrRwy: " + actArrList + " - " + arrWhich + " - " + actArr, vsid::MessageHandler::DebugArea::Conf); - } + for(auto& [arrWhich, actArr] : arrType) + { + messageHandler->writeMessage("DEBUG", "[" + sidName + "] actArrRwy: " + actArrList + " - " + arrWhich + " - " + actArr, vsid::MessageHandler::DebugArea::Conf); + } } for (auto& [actDepList, depType] : newSid.actDepRwy) { - for (auto& [depWhich, actDep] : depType) - { - messageHandler->writeMessage("DEBUG", "[" + sidName + "] actDepRwy: " + actDepList + " - " + depWhich + " - " + actDep, vsid::MessageHandler::DebugArea::Conf); - } + for (auto& [depWhich, actDep] : depType) + { + messageHandler->writeMessage("DEBUG", "[" + sidName + "] actDepRwy: " + actDepList + " - " + depWhich + " - " + actDep, vsid::MessageHandler::DebugArea::Conf); + } } messageHandler->writeMessage("DEBUG", "[" + sidName + "] wtc: " + newSid.wtc, vsid::MessageHandler::DebugArea::Conf); messageHandler->writeMessage("DEBUG", "[" + sidName + "] engType: " + newSid.engineType, vsid::MessageHandler::DebugArea::Conf); - messageHandler->writeMessage("DEBUG", "[" + sidName + "] wingType: " + newSid.wingType, vsid::MessageHandler::DebugArea::Conf); + messageHandler->writeMessage("DEBUG", "[" + sidName + "] wingType: " + newSid.wingType, vsid::MessageHandler::DebugArea::Conf); for (auto& [sAcftType, allow] : newSid.acftType) { messageHandler->writeMessage("DEBUG", "[" + sidName + "] acftType: " + sAcftType + " allowed " + ((allow) ? "TRUE" : "FALSE"), vsid::MessageHandler::DebugArea::Conf); @@ -1248,190 +1248,190 @@ void vsid::ConfigParser::loadAirportConfig(std::map messageHandler->writeMessage("DEBUG", "[" + sidName + "] timeFrom: " + std::to_string(newSid.timeFrom), vsid::MessageHandler::DebugArea::Conf); messageHandler->writeMessage("DEBUG", "[" + sidName + "] timeTo: " + std::to_string(newSid.timeTo), vsid::MessageHandler::DebugArea::Conf); // end dev - debugging msgs for sid restriction levels - } - } - } - } - } - } - } - } - catch (const json::parse_error& e) - { - messageHandler->writeMessage("ERROR", "[Parse] Failed to load airport config (" + icao + "): " + std::string(e.what())); - } - catch (const json::type_error& e) - { - messageHandler->writeMessage("ERROR", "[Type] Failed to load airport config (" + icao + "): " + std::string(e.what())); - } - catch (const json::out_of_range& e) - { - messageHandler->writeMessage("ERROR", "[Range] Failed to load airport config (" + icao + "): " + std::string(e.what())); - } - catch (const json::other_error& e) - { - messageHandler->writeMessage("ERROR", "[Other] Failed to load airport config (" + icao + "): " + std::string(e.what())); - } - catch (const std::exception &e) - { - messageHandler->writeMessage("ERROR", "Failure in config (" + icao + "): " + std::string(e.what())); - } - - /* DOCUMENTATION on how to get all values below a key - json waypoint = this->configFile.at("EDDF").at("sids").at("MARUN"); - for (auto it : waypoint.items()) - { - vsid::messagehandler::LogMessage("JSON it:", it.value().dump()); - }*/ - } - } - } - - // airport health check - remove apt without config - - for (std::map::iterator it = activeAirports.begin(); it != activeAirports.end();) - { - if (aptConfig.contains(it->first)) ++it; - else - { - messageHandler->writeMessage("INFO", "No config found for: " + it->first); - it = activeAirports.erase(it); - } - } + } + } + } + } + } + } + } + } + catch (const json::parse_error& e) + { + messageHandler->writeMessage("ERROR", "[Parse] Failed to load airport config (" + icao + "): " + std::string(e.what())); + } + catch (const json::type_error& e) + { + messageHandler->writeMessage("ERROR", "[Type] Failed to load airport config (" + icao + "): " + std::string(e.what())); + } + catch (const json::out_of_range& e) + { + messageHandler->writeMessage("ERROR", "[Range] Failed to load airport config (" + icao + "): " + std::string(e.what())); + } + catch (const json::other_error& e) + { + messageHandler->writeMessage("ERROR", "[Other] Failed to load airport config (" + icao + "): " + std::string(e.what())); + } + catch (const std::exception &e) + { + messageHandler->writeMessage("ERROR", "Failure in config (" + icao + "): " + std::string(e.what())); + } + + /* DOCUMENTATION on how to get all values below a key + json waypoint = this->configFile.at("EDDF").at("sids").at("MARUN"); + for (auto it : waypoint.items()) + { + vsid::messagehandler::LogMessage("JSON it:", it.value().dump()); + }*/ + } + } + } + + // airport health check - remove apt without config + + for (std::map::iterator it = activeAirports.begin(); it != activeAirports.end();) + { + if (aptConfig.contains(it->first)) ++it; + else + { + messageHandler->writeMessage("INFO", "No config found for: " + it->first); + it = activeAirports.erase(it); + } + } } void vsid::ConfigParser::loadGrpConfig() { - // get the current path where plugins .dll is stored - char path[MAX_PATH + 1] = { 0 }; - GetModuleFileNameA((HINSTANCE)&__ImageBase, path, MAX_PATH); - PathRemoveFileSpecA(path); - std::filesystem::path basePath = path; - - if (!this->vSidConfig.empty()) - { - basePath.append(this->vSidConfig.value("grp", "")).make_preferred(); - } - - if (!std::filesystem::exists(basePath)) - { - messageHandler->writeMessage("ERROR", "No grp config found in: " + basePath.string()); - return; - } - for (const std::filesystem::path& entry : std::filesystem::directory_iterator(basePath)) - { - if (entry.extension() == ".json") - { - if (entry.filename().string() != "ICAO_Aircraft.json") continue; - - std::ifstream configFile(entry.string()); - - try - { - this->grpConfig = json::parse(configFile); - } - catch (const json::parse_error& e) - { - messageHandler->writeMessage("ERROR:", "Failed to load grp config: " + std::string(e.what())); - } - catch (const json::type_error& e) - { - messageHandler->writeMessage("ERROR:", "Failed to load grp config: " + std::string(e.what())); - } - } - } + // get the current path where plugins .dll is stored + char path[MAX_PATH + 1] = { 0 }; + GetModuleFileNameA((HINSTANCE)&__ImageBase, path, MAX_PATH); + PathRemoveFileSpecA(path); + std::filesystem::path basePath = path; + + if (!this->vSidConfig.empty()) + { + basePath.append(this->vSidConfig.value("grp", "")).make_preferred(); + } + + if (!std::filesystem::exists(basePath)) + { + messageHandler->writeMessage("ERROR", "No grp config found in: " + basePath.string()); + return; + } + for (const std::filesystem::path& entry : std::filesystem::directory_iterator(basePath)) + { + if (entry.extension() == ".json") + { + if (entry.filename().string() != "ICAO_Aircraft.json") continue; + + std::ifstream configFile(entry.string()); + + try + { + this->grpConfig = json::parse(configFile); + } + catch (const json::parse_error& e) + { + messageHandler->writeMessage("ERROR:", "Failed to load grp config: " + std::string(e.what())); + } + catch (const json::type_error& e) + { + messageHandler->writeMessage("ERROR:", "Failed to load grp config: " + std::string(e.what())); + } + } + } } void vsid::ConfigParser::loadRnavList() { - // get the current path where plugins .dll is stored - char path[MAX_PATH + 1] = { 0 }; - GetModuleFileNameA((HINSTANCE)&__ImageBase, path, MAX_PATH); - PathRemoveFileSpecA(path); - std::filesystem::path basePath = path; - - if (!this->vSidConfig.empty()) - { - basePath.append(this->vSidConfig.value("RNAV", "")).make_preferred(); - } - - if (!std::filesystem::exists(basePath)) - { - messageHandler->writeMessage("ERROR", "Path to check for RNAV List does not exist: " + basePath.string()); - return; - } - - for (const std::filesystem::path& entry : std::filesystem::directory_iterator(basePath)) - { - if (entry.extension() != ".json") continue; - if (entry.filename().string() != "RNAV_List.json") continue; - - std::ifstream configFile(entry.string()); - json rnavConfigFile; - - try - { - rnavConfigFile = json::parse(configFile); - } - catch (const json::parse_error& e) - { - messageHandler->writeMessage("ERROR:", "Failed to load rnav list: " + std::string(e.what())); - } - catch (const json::type_error& e) - { - messageHandler->writeMessage("ERROR:", "Failed to load rnav list: " + std::string(e.what())); - } - - if (rnavConfigFile.empty()) - { - messageHandler->writeMessage("ERROR", "RNAV List is empty. Is it present besides the plugin DLL file?"); - return; - } - - try - { - this->rnavList = rnavConfigFile.value("RNAV", std::set{}); - } - catch (json::type_error &e) - { - messageHandler->writeMessage("ERROR", "Failed to read rnav list: " + std::string(e.what())); - } - - return; - } - messageHandler->writeMessage("ERROR", "No RNAV capable list found at: " + basePath.string()); + // get the current path where plugins .dll is stored + char path[MAX_PATH + 1] = { 0 }; + GetModuleFileNameA((HINSTANCE)&__ImageBase, path, MAX_PATH); + PathRemoveFileSpecA(path); + std::filesystem::path basePath = path; + + if (!this->vSidConfig.empty()) + { + basePath.append(this->vSidConfig.value("RNAV", "")).make_preferred(); + } + + if (!std::filesystem::exists(basePath)) + { + messageHandler->writeMessage("ERROR", "Path to check for RNAV List does not exist: " + basePath.string()); + return; + } + + for (const std::filesystem::path& entry : std::filesystem::directory_iterator(basePath)) + { + if (entry.extension() != ".json") continue; + if (entry.filename().string() != "RNAV_List.json") continue; + + std::ifstream configFile(entry.string()); + json rnavConfigFile; + + try + { + rnavConfigFile = json::parse(configFile); + } + catch (const json::parse_error& e) + { + messageHandler->writeMessage("ERROR:", "Failed to load rnav list: " + std::string(e.what())); + } + catch (const json::type_error& e) + { + messageHandler->writeMessage("ERROR:", "Failed to load rnav list: " + std::string(e.what())); + } + + if (rnavConfigFile.empty()) + { + messageHandler->writeMessage("ERROR", "RNAV List is empty. Is it present besides the plugin DLL file?"); + return; + } + + try + { + this->rnavList = rnavConfigFile.value("RNAV", std::set{}); + } + catch (json::type_error &e) + { + messageHandler->writeMessage("ERROR", "Failed to read rnav list: " + std::string(e.what())); + } + + return; + } + messageHandler->writeMessage("ERROR", "No RNAV capable list found at: " + basePath.string()); } const COLORREF vsid::ConfigParser::getColor(std::string color) { - if (this->colors.contains(color)) - { - messageHandler->removeGenError(ERROR_CONF_COLOR + "_" + color); - - return this->colors[color]; - } - else - { - if (!messageHandler->genErrorsContains(ERROR_CONF_COLOR + "_" + color)) - { - messageHandler->writeMessage("ERROR", "Failed to retrieve color: \"" + color + "\". Code: " + ERROR_CONF_COLOR); - messageHandler->addGenError(ERROR_CONF_COLOR + "_" + color); - } - // return purple if color could not be found to signal error - COLORREF rgbColor = RGB(190, 30, 190); - return rgbColor; - } + if (this->colors.contains(color)) + { + messageHandler->removeGenError(ERROR_CONF_COLOR + "_" + color); + + return this->colors[color]; + } + else + { + if (!messageHandler->genErrorsContains(ERROR_CONF_COLOR + "_" + color)) + { + messageHandler->writeMessage("ERROR", "Failed to retrieve color: \"" + color + "\". Code: " + ERROR_CONF_COLOR); + messageHandler->addGenError(ERROR_CONF_COLOR + "_" + color); + } + // return purple if color could not be found to signal error + COLORREF rgbColor = RGB(190, 30, 190); + return rgbColor; + } } int vsid::ConfigParser::getReqTime(std::string time) { - if (this->reqTimes.contains(time)) - { - return this->reqTimes[time]; - } - else - { - messageHandler->writeMessage("ERROR", "Failed to retrieve request time setting for key \"" + time + "\""); - return 0; - } + if (this->reqTimes.contains(time)) + { + return this->reqTimes[time]; + } + else + { + messageHandler->writeMessage("ERROR", "Failed to retrieve request time setting for key \"" + time + "\""); + return 0; + } } From b3bb0f9333fe5eda502efe5256387336fbf9eab9 Mon Sep 17 00:00:00 2001 From: Phil7789 <87429599+Phil7789@users.noreply.github.com> Date: Wed, 6 May 2026 20:58:01 +0200 Subject: [PATCH 4/8] Fix wrong function position * Add guard in HOVF item * Remove type copies * Change HOVF to skip if autoHandoff is true first and then check GS --- vSIDPlugin.cpp | 35 +++++++++-------------------------- 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/vSIDPlugin.cpp b/vSIDPlugin.cpp index 02448f7..ec8f5df 100644 --- a/vSIDPlugin.cpp +++ b/vSIDPlugin.cpp @@ -2623,6 +2623,11 @@ void vsid::VSIDPlugin::OnFunctionCall(int FunctionId, const char * sItemString, if (this->topskyLoaded) this->addOrSetSquawk(callsign, true); else messageHandler->writeMessage("ERROR", "TopSky auto-assign squawk called, but TopSky was not detected."); } + + if (FunctionId == TAG_FUNC_VSID_HOV) + { + this->processed[callsign].hov = !this->processed[callsign].hov; + } } if (FunctionId == TAG_FUNC_VSID_CTL) @@ -2637,11 +2642,6 @@ void vsid::VSIDPlugin::OnFunctionCall(int FunctionId, const char * sItemString, { this->processed[callsign].ctlLocal = !this->processed[callsign].ctlLocal; } - - if (FunctionId == TAG_FUNC_VSID_HOV) - { - this->processed[callsign].hov = !this->processed[callsign].hov; - } } void vsid::VSIDPlugin::OnGetTagItem(EuroScopePlugIn::CFlightPlan FlightPlan, EuroScopePlugIn::CRadarTarget RadarTarget, int ItemCode, int TagData, char sItemString[16], int* pColorCode, COLORREF* pRGB, double* pFontSize) @@ -3314,17 +3314,14 @@ void vsid::VSIDPlugin::OnGetTagItem(EuroScopePlugIn::CFlightPlan FlightPlan, Eur if (ItemCode == TAG_ITEM_VSID_HOVF) { - if (RadarTarget.GetGS() < 50) return; if (this->activeAirports[adep].autoHandoff) return; + if (RadarTarget.GetGS() < 50) return; - int alt = RadarTarget.GetPosition().GetPressureAltitude(); - int hovWarningAlt = this->getConfigParser().hovWarningAlt; - EuroScopePlugIn::CFlightPlan fpln = FlightPlan; *pColorCode = EuroScopePlugIn::TAG_COLOR_RGB_DEFINED; - if (!this->processed[callsign].hov) + if (this->processed.contains(callsign) && !this->processed[callsign].hov) { - if (alt >= fpln.GetClearedAltitude() - hovWarningAlt) + if (RadarTarget.GetPosition().GetPressureAltitude() >= FlightPlan.GetClearedAltitude() - this->getConfigParser().hovWarningAlt) { *pRGB = this->configParser.getColor("hovWarning"); strcpy_s(sItemString, 16, "HOV!"); @@ -3495,20 +3492,6 @@ bool vsid::VSIDPlugin::OnCompileCommand(const char* sCommandLine) { std::vector command = vsid::utils::split(sCommandLine, ' '); - /*if (command[0] == ".vsidcrash") // #dev - only for testing crash handling - { - auto triggercrash = []() - { - volatile int* badPointer = nullptr; - - *badPointer = 42; - }; - - triggercrash(); - - return true; - }*/ - if (command[0] == ".vsid") { if (command.size() == 1) @@ -5141,7 +5124,7 @@ void vsid::VSIDPlugin::UpdateActiveAirports() this->SelectActiveSectorfile(); this->activeAirports.clear(); - + // get active airports for (EuroScopePlugIn::CSectorElement sfe = this->SectorFileElementSelectFirst(EuroScopePlugIn::SECTOR_ELEMENT_AIRPORT); sfe.IsValid(); From 0473bb0937735a8bf7d0d4d0b0cbf01e02d5431a Mon Sep 17 00:00:00 2001 From: Phil7789 <87429599+Phil7789@users.noreply.github.com> Date: Wed, 6 May 2026 21:16:42 +0200 Subject: [PATCH 5/8] Update Changelog.txt --- Changelog.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Changelog.txt b/Changelog.txt index bf06a47..1f2dad4 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,9 +1,12 @@ [Changelog v0.15.0] :new: **New Features** -* GEN - added crash handling +* GEN - add crash handling * a .txt file is generated with a small stacktrace showing the line or offset, depending if the pdb file was present at the time of the crash * a .dmp file is generated (default is a minidump - a fulldump can be generated by adding a file "create_fulldump" without file ending next to the dll) * the pdb file is generated during the build process +* FPLN - add "handover" flag for airports where the TWR controller sends pilots over to radar +* FPLN - add set / confirmation function for the handover flag to suppress the warning color +* CONF - add color values for the handover flag (neutral - white, warning - orange) :lady_beetle: **Fixes** * CONF - fix crash during coordinate conversion while parsing the .ese file for atc stations and vis points From 7f37e0a36ebfa20003c8bde8da3cc64b2ee17970 Mon Sep 17 00:00:00 2001 From: Phil7789 <87429599+Phil7789@users.noreply.github.com> Date: Wed, 6 May 2026 21:17:05 +0200 Subject: [PATCH 6/8] Update format --- vSidConfig.json | 141 +++++++++--------------------------------------- 1 file changed, 24 insertions(+), 117 deletions(-) diff --git a/vSidConfig.json b/vSidConfig.json index 9bc9d01..affba9e 100644 --- a/vSidConfig.json +++ b/vSidConfig.json @@ -3,127 +3,34 @@ "preferTopsky": true, "esePath": "../../../../", "colors": { - "sidSuggestion": { - "r": 255, - "g": 255, - "b": 255 - }, - "suggestedSidSet": { - "r": 0, - "g": 255, - "b": 0 - }, - "customSidSuggestion": { - "r": 255, - "g": 255, - "b": 180 - }, - "customSidSet": { - "r": 255, - "g": 120, - "b": 30 - }, - "noSid": { - "r": 220, - "g": 30, - "b": 20 - }, - "sidHighlight": { - "r": 240, - "g": 90, - "b": 190 - }, - "suggestedClmb": { - "r": 255, - "g": 255, - "b": 255 - }, - "customClmbSet": { - "r": 255, - "g": 120, - "b": 30 - }, - "clmbSet": { - "r": 50, - "g": 240, - "b": 210 - }, - "clmbViaSet": { - "r": 0, - "g": 255, - "b": 0 - }, - "clmbHighlight": { - "r": 240, - "g": 90, - "b": 190 - }, - "rwyNotSet": { - "r": 255, - "g": 255, - "b": 255 - }, - "rwySet": { - "r": 0, - "g": 255, - "b": 0 - }, - "notDepRwySet": { - "r": 230, - "g": 230, - "b": 60 - }, - "squawkSet": { - "r": 255, - "g": 255, - "b": 255 - }, - "squawkNotSet": { - "r": 230, - "g": 230, - "b": 60 - }, - "requestNeutral": { - "r": 128, - "g": 128, - "b": 128 - }, - "requestCaution": { - "r": 230, - "g": 230, - "b": 60 - }, - "requestWarning": { - "r": 220, - "g": 30, - "b": 20 - }, - "clrfSet": { - "r": 0, - "g": 160, - "b": 30 - }, - "clrfCaution": { - "r": 250, - "g": 160, - "b": 0 - }, - "clrfWarning": { - "r": 200, - "g": 10, - "b": 10 - }, + "sidSuggestion": {"r": 255, "g": 255, "b": 255}, + "suggestedSidSet": {"r": 0, "g": 255, "b": 0}, + "customSidSuggestion": {"r": 255, "g": 255, "b": 180}, + "customSidSet": {"r": 255, "g": 120, "b": 30}, + "noSid": {"r": 220, "g": 30, "b": 20}, + "sidHighlight": {"r": 240, "g": 90, "b": 190}, + "suggestedClmb": {"r": 255, "g": 255, "b": 255}, + "customClmbSet": {"r": 255, "g": 120, "b": 30}, + "clmbSet": {"r": 50, "g": 240, "b": 210}, + "clmbViaSet": {"r": 0, "g": 255, "b": 0}, + "clmbHighlight": {"r": 240, "g": 90, "b": 190}, + "rwyNotSet": {"r": 255, "g": 255, "b": 255}, + "rwySet": {"r": 0, "g": 255, "b": 0}, + "notDepRwySet": {"r": 230, "g": 230, "b": 60}, + "squawkSet": {"r": 255, "g": 255, "b": 255}, + "squawkNotSet": {"r": 230, "g": 230, "b": 60}, + "requestNeutral": {"r": 128, "g": 128, "b": 128}, + "requestCaution": {"r": 230, "g": 230, "b": 60}, + "requestWarning": {"r": 220, "g": 30,"b": 20}, + "clrfSet": {"r": 0, "g": 160, "b": 30}, + "clrfCaution": {"r": 250, "g": 160, "b": 0}, + "clrfWarning": {"r": 200, "g": 10, "b": 10}, "intsecSet": {"r": 0, "g": 150, "b": 50}, "intsecAble": {"r": 200, "g": 150, "b": 0}, - "pbIndicator": { - "r": 0, - "g": 255, - "b": 0 - }, + "pbIndicator": {"r": 0, "g": 255, "b": 0}, "reqIndicator": {"r": 255, "g": 255, "b": 255}, "intsecSetIndicator": {"r": 0, "g": 150, "b": 50}, - "intsecAbleIndicator": {"r": 200, "g": 150, "b": 0 - }, + "intsecAbleIndicator": {"r": 200, "g": 150, "b": 0}, "hovNeutral": {"r": 255,"g": 160,"b": 0}, "hovWarning": {"r": 255,"g": 0,"b": 0} }, From 19de86049032d0c4a9365d3673fb39f7b8e5fa05 Mon Sep 17 00:00:00 2001 From: Phil7789 <87429599+Phil7789@users.noreply.github.com> Date: Mon, 25 May 2026 14:53:16 +0200 Subject: [PATCH 7/8] Update Changelog.txt --- Changelog.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Changelog.txt b/Changelog.txt index 1f2dad4..8f8906f 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -5,8 +5,14 @@ * a .dmp file is generated (default is a minidump - a fulldump can be generated by adding a file "create_fulldump" without file ending next to the dll) * the pdb file is generated during the build process * FPLN - add "handover" flag for airports where the TWR controller sends pilots over to radar -* FPLN - add set / confirmation function for the handover flag to suppress the warning color -* CONF - add color values for the handover flag (neutral - white, warning - orange) + * flag is shown immediately after takeoff / airborne + * airport config values: + * "autoHandoff" (default: true) - if the pilot has to switch frequency on his own + * "hovWarningAlt" (default: 1500) - cleared altitude minus warning alt is the (actual pressure altitude) threshold after which the color switches to warning +* FPLN - add set / confirmation function for the handover flag to suppress the warning color (confirmation is synced) +* CONF - add color values for the handover flag + * "hovNeutral" (default: orange) - caution / information color + * "hovWarning" (default: red) - warning color :lady_beetle: **Fixes** * CONF - fix crash during coordinate conversion while parsing the .ese file for atc stations and vis points From 9618e6bdf5d5e6ce7ef82ba95fbaef45ff061ac5 Mon Sep 17 00:00:00 2001 From: Phil7789 <87429599+Phil7789@users.noreply.github.com> Date: Mon, 25 May 2026 14:54:14 +0200 Subject: [PATCH 8/8] Add hov flag sync --- vSIDPlugin.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/vSIDPlugin.cpp b/vSIDPlugin.cpp index ec8f5df..4bfd189 100644 --- a/vSIDPlugin.cpp +++ b/vSIDPlugin.cpp @@ -9,6 +9,7 @@ #include #include +#include #include "display.h" #include "airport.h" @@ -2627,6 +2628,8 @@ void vsid::VSIDPlugin::OnFunctionCall(int FunctionId, const char * sItemString, if (FunctionId == TAG_FUNC_VSID_HOV) { this->processed[callsign].hov = !this->processed[callsign].hov; + this->addSyncQueue(callsign, std::format(".VSID_HOV_{}", this->processed[callsign].hov ? "TRUE" : "FALSE"), + fpln.GetControllerAssignedData().GetScratchPadString()); } } @@ -4695,6 +4698,20 @@ void vsid::VSIDPlugin::OnFlightPlanControllerAssignedDataUpdate(EuroScopePlugIn: if (this->spReleased.contains(callsign)) this->updateSPSyncRelease(callsign); } + + // handover flag + + if (scratchpad.find(".VSID_HOV_") != std::string::npos) + { + std::string toFind = ".VSID_HOV_"; + size_t pos = scratchpad.find(toFind); + + bool hov = scratchpad.substr(pos + toFind.size(), scratchpad.size()) == "TRUE" ? true : false; + + this->processed[callsign].hov = hov; + + if (this->spReleased.contains(callsign)) this->updateSPSyncRelease(callsign); + } } }