From 43424e78c7cbfe61b32010cd8b88bb47f97146cc Mon Sep 17 00:00:00 2001 From: ZeFlyingGnome <149818766+ZeFlyingGnome@users.noreply.github.com> Date: Sat, 4 Oct 2025 19:33:19 +0200 Subject: [PATCH 1/5] Bug fix Correctly set AORT if not set when setting up AOBT --- src/core/TagFunctions.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/TagFunctions.h b/src/core/TagFunctions.h index bf65f2a..84c8672 100644 --- a/src/core/TagFunctions.h +++ b/src/core/TagFunctions.h @@ -139,8 +139,8 @@ void vACDM::OnFunctionCall(int functionId, const char *itemString, POINT pt, REC break; } case AOBT_NOW_AND_STATE: { - // set ASRT if ASRT has not been set yet - if (pilot.asrt == types::defaultTime) { + // set AORT if AORT has not been set yet + if (pilot.aort == types::defaultTime) { DataManager::instance().handleTagFunction(DataManager::MessageType::UpdateAORT, pilot.callsign, std::chrono::utc_clock::now()); } From 3f0d5b9f3e7e542964374b1c2ca6e46dc30aef4a Mon Sep 17 00:00:00 2001 From: ZeFlyingGnome <149818766+ZeFlyingGnome@users.noreply.github.com> Date: Sat, 4 Oct 2025 20:18:54 +0200 Subject: [PATCH 2/5] Bug fix Correctly retrieve only aircrafts in active airports --- src/core/Server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/Server.cpp b/src/core/Server.cpp index 475318a..61f4033 100644 --- a/src/core/Server.cpp +++ b/src/core/Server.cpp @@ -144,7 +144,7 @@ std::list Server::getPilots(const std::list airports) // Add airport filter if specified if (!airports.empty()) { - url += "?airports="; + url += "?adep="; url += std::accumulate(std::next(airports.begin()), airports.end(), *airports.begin(), [](const std::string& a, const std::string& b) { return a + "," + b; }); } From f9f405f61be01b7dce26882a82e9ed7ec0bd7aae Mon Sep 17 00:00:00 2001 From: ZeFlyingGnome <149818766+ZeFlyingGnome@users.noreply.github.com> Date: Tue, 7 Oct 2025 08:35:02 +0200 Subject: [PATCH 3/5] Improvement Only handle CDM supported platforms in DataManager --- src/core/DataManager.cpp | 15 ++++++++++++++- src/core/Server.cpp | 30 ++++++++++++++++++++++++++++++ src/core/Server.h | 5 +++++ src/vACDM.cpp | 1 + 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/core/DataManager.cpp b/src/core/DataManager.cpp index 7514e98..b5612d6 100644 --- a/src/core/DataManager.cpp +++ b/src/core/DataManager.cpp @@ -355,7 +355,20 @@ DataManager::MessageType DataManager::deltaEuroscopeToBackend(const std::array activeAirports) { std::lock_guard guard(this->m_airportLock); - this->m_activeAirports = activeAirports; + + std::list supportedAirports = Server::instance().getSupportedAirports(); + std::list cdmActiveAirports; + + for (const auto& activeAirport : activeAirports) { + for (const auto& supportedAirport : supportedAirports) { + if (supportedAirport == activeAirport) { + cdmActiveAirports.push_back(supportedAirport); + break; + } + } + } + + this->m_activeAirports = cdmActiveAirports; } void DataManager::queueFlightplanUpdate(EuroScopePlugIn::CFlightPlan flightplan) { diff --git a/src/core/Server.cpp b/src/core/Server.cpp index 61f4033..dc409a4 100644 --- a/src/core/Server.cpp +++ b/src/core/Server.cpp @@ -134,6 +134,36 @@ Server::ServerConfiguration Server::getServerConfig() { return ServerConfiguration(); } +void Server::retrieveSupportedAirports() { + if (false == this->m_apiIsChecked || false == this->m_apiIsValid) { return; } + + std::lock_guard guard(m_clientMutex); + if (m_client) { + std::string url = "/api/v1/airports"; + auto result = m_client->Get(url); + + if (result && result->status == 200) { + nlohmann::json root; + + try { + root = nlohmann::json::parse(result->body); + std::list airports; + for (const auto& airport : std::as_const(root)) { + airports.push_back(airport["icao"].get()); + } + m_supportedAirports = airports; + } catch (const std::exception& e) { + SpdLogger::log(SpdLogger::LogSender::Server, "Failed to parse response JSON: " + std::string(e.what()), + SpdLogger::LogLevel::Info); + } + } + } +} + +std::list Server::getSupportedAirports() { return m_supportedAirports; }; + + + std::list Server::getPilots(const std::list airports) { std::lock_guard guard(m_clientMutex); if (!m_client) { diff --git a/src/core/Server.h b/src/core/Server.h index 7298d6b..934aa2d 100644 --- a/src/core/Server.h +++ b/src/core/Server.h @@ -35,6 +35,8 @@ class Server { std::string m_errorCode; ServerConfiguration m_serverConfiguration; + std::list m_supportedAirports; + public: ~Server(); Server(const Server&) = delete; @@ -78,6 +80,9 @@ class Server { void setMaster(bool master); bool getMaster(); + void retrieveSupportedAirports(); + std::list getSupportedAirports(); + private: // Helper method to initialize/reinitialize the HTTP client void initClient(); diff --git a/src/vACDM.cpp b/src/vACDM.cpp index 1d3cbaf..efc6381 100644 --- a/src/vACDM.cpp +++ b/src/vACDM.cpp @@ -57,6 +57,7 @@ void vACDM::checkServerConfiguration() { } else { std::string serverName = Server::instance().getServerConfig().name; DisplayMessage(("Connected to " + serverName), "Server"); + Server::instance().retrieveSupportedAirports(); // set active airports and runways this->OnAirportRunwayActivityChanged(); } From 33fe02f69a058804b521baf5e6f2fa6429d51c68 Mon Sep 17 00:00:00 2001 From: ZeFlyingGnome <149818766+ZeFlyingGnome@users.noreply.github.com> Date: Tue, 7 Oct 2025 08:45:01 +0200 Subject: [PATCH 4/5] Bugfix Correctly retrieve multiple airports --- src/core/Server.cpp | 137 ++++++++++++++++++++++---------------------- 1 file changed, 67 insertions(+), 70 deletions(-) diff --git a/src/core/Server.cpp b/src/core/Server.cpp index dc409a4..ffe7766 100644 --- a/src/core/Server.cpp +++ b/src/core/Server.cpp @@ -170,83 +170,80 @@ std::list Server::getPilots(const std::list airports) return {}; } - std::string url = "/api/v1/pilots"; + std::list pilots; + std::string baseUrl = "/api/v1/pilots?adep="; - // Add airport filter if specified - if (!airports.empty()) { - url += "?adep="; - url += std::accumulate(std::next(airports.begin()), airports.end(), *airports.begin(), - [](const std::string& a, const std::string& b) { return a + "," + b; }); - } + for (const auto& airport : airports) { + std::string url = baseUrl + airport; - SpdLogger::log(SpdLogger::LogSender::Server, url, SpdLogger::LogLevel::Info); + SpdLogger::log(SpdLogger::LogSender::Server, url, SpdLogger::LogLevel::Info); - auto result = m_client->Get(url); - if (result && result->status == 200) { - nlohmann::json root; - - try { - root = nlohmann::json::parse(result->body); - std::list pilots; - - for (const auto& pilot : std::as_const(root)) { - pilots.push_back(types::Pilot()); - - pilots.back().callsign = pilot["callsign"].get(); - pilots.back().lastUpdate = utils::Date::isoStringToTimestamp(pilot["updatedAt"].get()); - pilots.back().inactive = pilot["inactive"].get(); - - // position data - pilots.back().latitude = pilot["position"]["lat"].get(); - pilots.back().longitude = pilot["position"]["lon"].get(); - pilots.back().taxizoneIsTaxiout = pilot["vacdm"]["taxizoneIsTaxiout"].get(); - - // flightplan & clearance data - pilots.back().origin = pilot["flightplan"]["departure"].get(); - pilots.back().destination = pilot["flightplan"]["arrival"].get(); - pilots.back().runway = pilot["clearance"]["dep_rwy"].get(); - pilots.back().sid = pilot["clearance"]["sid"].get(); - - // ACDM procedure data - pilots.back().eobt = utils::Date::isoStringToTimestamp(pilot["vacdm"]["eobt"].get()); - pilots.back().tobt = utils::Date::isoStringToTimestamp(pilot["vacdm"]["tobt"].get()); - pilots.back().tobt_state = pilot["vacdm"]["tobt_state"].get(); - pilots.back().ctot = utils::Date::isoStringToTimestamp(pilot["vacdm"]["ctot"].get()); - pilots.back().ttot = utils::Date::isoStringToTimestamp(pilot["vacdm"]["ttot"].get()); - pilots.back().tsat = utils::Date::isoStringToTimestamp(pilot["vacdm"]["tsat"].get()); - pilots.back().exot = - std::chrono::utc_clock::time_point(std::chrono::minutes(pilot["vacdm"]["exot"].get())); - pilots.back().asat = utils::Date::isoStringToTimestamp(pilot["vacdm"]["asat"].get()); - pilots.back().aobt = utils::Date::isoStringToTimestamp(pilot["vacdm"]["aobt"].get()); - pilots.back().atot = utils::Date::isoStringToTimestamp(pilot["vacdm"]["atot"].get()); - pilots.back().asrt = utils::Date::isoStringToTimestamp(pilot["vacdm"]["asrt"].get()); - pilots.back().aort = utils::Date::isoStringToTimestamp(pilot["vacdm"]["aort"].get()); - - // ECFMP measures - nlohmann::json measuresArray = pilot["measures"]; - std::vector parsedMeasures; - for (const auto& measureObject : std::as_const(measuresArray)) { - vacdm::types::EcfmpMeasure measure; - - measure.ident = measureObject["ident"].get(); - measure.value = measureObject["value"].get(); - - parsedMeasures.push_back(measure); - } - pilots.back().measures = parsedMeasures; + auto result = m_client->Get(url); + if (result && result->status == 200) { + nlohmann::json root; + + try { + root = nlohmann::json::parse(result->body); - // event booking data - pilots.back().hasBooking = pilot["hasBooking"].get(); + for (const auto& pilot : std::as_const(root)) { + pilots.push_back(types::Pilot()); + + pilots.back().callsign = pilot["callsign"].get(); + pilots.back().lastUpdate = utils::Date::isoStringToTimestamp(pilot["updatedAt"].get()); + pilots.back().inactive = pilot["inactive"].get(); + + // position data + pilots.back().latitude = pilot["position"]["lat"].get(); + pilots.back().longitude = pilot["position"]["lon"].get(); + pilots.back().taxizoneIsTaxiout = pilot["vacdm"]["taxizoneIsTaxiout"].get(); + + // flightplan & clearance data + pilots.back().origin = pilot["flightplan"]["departure"].get(); + pilots.back().destination = pilot["flightplan"]["arrival"].get(); + pilots.back().runway = pilot["clearance"]["dep_rwy"].get(); + pilots.back().sid = pilot["clearance"]["sid"].get(); + + // ACDM procedure data + pilots.back().eobt = utils::Date::isoStringToTimestamp(pilot["vacdm"]["eobt"].get()); + pilots.back().tobt = utils::Date::isoStringToTimestamp(pilot["vacdm"]["tobt"].get()); + pilots.back().tobt_state = pilot["vacdm"]["tobt_state"].get(); + pilots.back().ctot = utils::Date::isoStringToTimestamp(pilot["vacdm"]["ctot"].get()); + pilots.back().ttot = utils::Date::isoStringToTimestamp(pilot["vacdm"]["ttot"].get()); + pilots.back().tsat = utils::Date::isoStringToTimestamp(pilot["vacdm"]["tsat"].get()); + pilots.back().exot = + std::chrono::utc_clock::time_point(std::chrono::minutes(pilot["vacdm"]["exot"].get())); + pilots.back().asat = utils::Date::isoStringToTimestamp(pilot["vacdm"]["asat"].get()); + pilots.back().aobt = utils::Date::isoStringToTimestamp(pilot["vacdm"]["aobt"].get()); + pilots.back().atot = utils::Date::isoStringToTimestamp(pilot["vacdm"]["atot"].get()); + pilots.back().asrt = utils::Date::isoStringToTimestamp(pilot["vacdm"]["asrt"].get()); + pilots.back().aort = utils::Date::isoStringToTimestamp(pilot["vacdm"]["aort"].get()); + + // ECFMP measures + nlohmann::json measuresArray = pilot["measures"]; + std::vector parsedMeasures; + for (const auto& measureObject : std::as_const(measuresArray)) { + vacdm::types::EcfmpMeasure measure; + + measure.ident = measureObject["ident"].get(); + measure.value = measureObject["value"].get(); + + parsedMeasures.push_back(measure); + } + pilots.back().measures = parsedMeasures; + + // event booking data + pilots.back().hasBooking = pilot["hasBooking"].get(); + } + } catch (const std::exception& e) { + SpdLogger::log(SpdLogger::LogSender::Server, "Failed to parse response JSON: " + std::string(e.what()), + SpdLogger::LogLevel::Info); } - SpdLogger::log(SpdLogger::LogSender::Server, "Pilots size: " + std::to_string(pilots.size()), - SpdLogger::LogLevel::Info); - return pilots; - } catch (const std::exception& e) { - SpdLogger::log(SpdLogger::LogSender::Server, "Failed to parse response JSON: " + std::string(e.what()), - SpdLogger::LogLevel::Info); } } - return {}; + + SpdLogger::log(SpdLogger::LogSender::Server, "Pilots size: " + std::to_string(pilots.size()), + SpdLogger::LogLevel::Info); + return pilots; } void Server::sendPostMessage(const std::string& endpointUrl, const nlohmann::json& root) { From 02e4bdd0a60e9e38a57a8326219725b5f6da81d6 Mon Sep 17 00:00:00 2001 From: ZeFlyingGnome <149818766+ZeFlyingGnome@users.noreply.github.com> Date: Sun, 22 Feb 2026 19:29:24 +0100 Subject: [PATCH 5/5] Clang format --- src/core/Server.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/core/Server.cpp b/src/core/Server.cpp index ffe7766..3252c9a 100644 --- a/src/core/Server.cpp +++ b/src/core/Server.cpp @@ -135,7 +135,9 @@ Server::ServerConfiguration Server::getServerConfig() { } void Server::retrieveSupportedAirports() { - if (false == this->m_apiIsChecked || false == this->m_apiIsValid) { return; } + if (false == this->m_apiIsChecked || false == this->m_apiIsValid) { + return; + } std::lock_guard guard(m_clientMutex); if (m_client) { @@ -154,7 +156,7 @@ void Server::retrieveSupportedAirports() { m_supportedAirports = airports; } catch (const std::exception& e) { SpdLogger::log(SpdLogger::LogSender::Server, "Failed to parse response JSON: " + std::string(e.what()), - SpdLogger::LogLevel::Info); + SpdLogger::LogLevel::Info); } } } @@ -162,8 +164,6 @@ void Server::retrieveSupportedAirports() { std::list Server::getSupportedAirports() { return m_supportedAirports; }; - - std::list Server::getPilots(const std::list airports) { std::lock_guard guard(m_clientMutex); if (!m_client) { @@ -210,8 +210,8 @@ std::list Server::getPilots(const std::list airports) pilots.back().ctot = utils::Date::isoStringToTimestamp(pilot["vacdm"]["ctot"].get()); pilots.back().ttot = utils::Date::isoStringToTimestamp(pilot["vacdm"]["ttot"].get()); pilots.back().tsat = utils::Date::isoStringToTimestamp(pilot["vacdm"]["tsat"].get()); - pilots.back().exot = - std::chrono::utc_clock::time_point(std::chrono::minutes(pilot["vacdm"]["exot"].get())); + pilots.back().exot = std::chrono::utc_clock::time_point( + std::chrono::minutes(pilot["vacdm"]["exot"].get())); pilots.back().asat = utils::Date::isoStringToTimestamp(pilot["vacdm"]["asat"].get()); pilots.back().aobt = utils::Date::isoStringToTimestamp(pilot["vacdm"]["aobt"].get()); pilots.back().atot = utils::Date::isoStringToTimestamp(pilot["vacdm"]["atot"].get()); @@ -236,14 +236,14 @@ std::list Server::getPilots(const std::list airports) } } catch (const std::exception& e) { SpdLogger::log(SpdLogger::LogSender::Server, "Failed to parse response JSON: " + std::string(e.what()), - SpdLogger::LogLevel::Info); + SpdLogger::LogLevel::Info); } } } SpdLogger::log(SpdLogger::LogSender::Server, "Pilots size: " + std::to_string(pilots.size()), - SpdLogger::LogLevel::Info); - return pilots; + SpdLogger::LogLevel::Info); + return pilots; } void Server::sendPostMessage(const std::string& endpointUrl, const nlohmann::json& root) {