diff --git a/DiscordEuroscope/ConfigData.cpp b/DiscordEuroscope/ConfigData.cpp index b4e2f53..c95ce3e 100644 --- a/DiscordEuroscope/ConfigData.cpp +++ b/DiscordEuroscope/ConfigData.cpp @@ -31,6 +31,7 @@ namespace DiscordEuroScope_Configuration this->discord_presence_large_image_key = ""; this->discord_presence_small_image_key = ""; this->sweatbox_bypass = false; + this->loaded_from_ese = false; this->RadioCallsigns.clear(); for (int i = 0; i < 7; i++) { diff --git a/DiscordEuroscope/ConfigData.h b/DiscordEuroscope/ConfigData.h index eacde9a..67ac2c9 100644 --- a/DiscordEuroscope/ConfigData.h +++ b/DiscordEuroscope/ConfigData.h @@ -26,7 +26,14 @@ namespace DiscordEuroScope_Configuration { - typedef std::map typeRadioCallsigns; + typedef struct + { + std::string callsign; + std::string icao; + std::string frequency; + std::string radio_callsign; + } RadioCallsignElement_t; + typedef std::vector RadioCallsigns_t; enum States_Enum { State_Idle, @@ -56,7 +63,8 @@ namespace DiscordEuroScope_Configuration std::string discord_presence_small_image_key; bool sweatbox_bypass; State states[7]; - typeRadioCallsigns RadioCallsigns; + RadioCallsigns_t RadioCallsigns; + bool loaded_from_ese = false; ConfigData(); diff --git a/DiscordEuroscope/ConfigManager.cpp b/DiscordEuroscope/ConfigManager.cpp index 84cf86b..1b4e7cf 100644 --- a/DiscordEuroscope/ConfigManager.cpp +++ b/DiscordEuroscope/ConfigManager.cpp @@ -27,6 +27,11 @@ const char default_file_content[] = DEFAULT_FILE_CONTENT; +// caching so we don't regex every time +static std::string last_fetch_callsign = ""; +static std::string last_returned_rcallsign = ""; +static std::string last_fetch_frequency = ""; + namespace DiscordEuroScope_Configuration { ConfigManager::ConfigManager() @@ -129,56 +134,93 @@ namespace DiscordEuroScope_Configuration _ready = false; json_document.GetAllocator().Clear(); data.Cleanup(); + last_fetch_callsign = ""; + last_returned_rcallsign = ""; + last_fetch_frequency = ""; } void ConfigManager::LoadRadioCallsigns() { - if (json_document.HasMember("load_from_ese")) { - if (json_document["load_from_ese"].IsBool() && json_document["load_from_ese"].GetBool() && json_document["path_to_ese"].IsString()) + if (!json_document["radio_callsigns"].IsObject()) return; + auto& RadioCallsignObj = json_document["radio_callsigns"]; + auto& RadioCallsignConfigObj = RadioCallsignObj["config"]; + if (RadioCallsignConfigObj.HasMember("load_from_ese")) { + if (RadioCallsignConfigObj["load_from_ese"].IsBool() && RadioCallsignConfigObj["load_from_ese"].GetBool()) { - std::string relative_to_full_path; - std::string relative_path = json_document["path_to_ese"].GetString(); + std::string relative_to_absolute_path; + std::string relative_path = + RadioCallsignConfigObj.HasMember("path_to_ese") && RadioCallsignConfigObj["path_to_ese"].IsString() + ? RadioCallsignConfigObj["path_to_ese"].GetString() + : ".\\"; if (relative_path[1] == ':') - relative_to_full_path = relative_path; + relative_to_absolute_path = relative_path; else - relative_to_full_path = this->file_path.substr(0, this->file_path.find_last_of('\\') + 1) + relative_path; - if (ESEHandler::LocateESEFile(relative_to_full_path)) + relative_to_absolute_path = this->file_path.substr(0, this->file_path.find_last_of('\\') + 1) + relative_path; + if (ESEHandler::LocateESEFile(relative_to_absolute_path)) { - int p = ESEHandler::ParsePositions(); - ESEHandler::GetRadioCallsigns(data.RadioCallsigns); - return; + if (ESEHandler::ParsePositions() > 0) { + data.loaded_from_ese = true; + ESEHandler::GetRadioCallsigns(data.RadioCallsigns); + return; + } } } } - assert(json_document["radio_callsigns"].IsObject()); + assert(RadioCallsignObj.HasMember("custom") && RadioCallsignObj["custom"].IsArray()); data.RadioCallsigns.clear(); - for (auto& it : json_document["radio_callsigns"].GetObject()) + for (auto& it : RadioCallsignObj["custom"].GetArray()) { - if (it.name.GetType() == rapidjson::kStringType && it.value.GetType() == rapidjson::kStringType) + if (it.IsObject()) { - data.RadioCallsigns.insert(std::pair(it.name.GetString(), it.value.GetString())); + RadioCallsignElement_t element; + if (it.HasMember("callsign") && it["callsign"].IsString()) + element.callsign = std::string(it["callsign"].GetString()); + if (it.HasMember("frequency") && it["frequency"].IsString()) + element.frequency = std::string(it["frequency"].GetString()); + if (it.HasMember("rcallsign") && it["rcallsign"].IsString()) + element.radio_callsign = std::string(it["rcallsign"].GetString()); + + element.icao = element.callsign.substr(0, element.callsign.find_first_of('_')); + data.RadioCallsigns.push_back(element); } } } - void ConfigManager::FindRadioCallsign(std::string callsign, std::string& radio_callsign) + void ConfigManager::FindRadioCallsign(std::string callsign, std::string frequency, std::string& radio_callsign) { // caching so we don't regex every time - static std::string last_fetch_callsign = ""; - static std::string last_returned_rcallsign = ""; - if (callsign == last_fetch_callsign) + if (callsign == last_fetch_callsign && frequency == last_fetch_frequency) { radio_callsign = last_returned_rcallsign; // return cached result return; } last_fetch_callsign = callsign; + last_fetch_frequency = frequency; + std::string icao = callsign.substr(0, callsign.find_first_of('_')); + + if (data.loaded_from_ese) + { + for (auto& it : data.RadioCallsigns) + { + if (it.icao == icao && it.frequency == frequency) + { + radio_callsign = it.radio_callsign; + last_returned_rcallsign = radio_callsign; + return; + } + } + last_returned_rcallsign = radio_callsign = callsign; + return; + } + for (auto& it : data.RadioCallsigns) { - std::regex rgx(std::string(it.first)); + std::regex rgx(std::string(it.callsign)); std::smatch rgx_match; if(!std::regex_search(callsign, rgx_match, rgx)) continue; - radio_callsign = it.second; + if (!it.frequency.empty() && !(it.frequency == frequency && it.icao == icao)) continue; + radio_callsign = it.radio_callsign; std::vector dict; for (int rgx_it = 1; rgx_it < rgx_match.size(); rgx_it++) diff --git a/DiscordEuroscope/ConfigManager.h b/DiscordEuroscope/ConfigManager.h index e8681bc..39277dc 100644 --- a/DiscordEuroscope/ConfigManager.h +++ b/DiscordEuroscope/ConfigManager.h @@ -57,7 +57,7 @@ namespace DiscordEuroScope_Configuration void Cleanup(void); void LoadRadioCallsigns(void); void GenerateConfigFile(std::string filepath); - void FindRadioCallsign(std::string callsign, std::string& radio_callsign); + void FindRadioCallsign(std::string callsign, std::string frequency, std::string& radio_callsign); }; } diff --git a/DiscordEuroscope/DefaultFileContent.h b/DiscordEuroscope/DefaultFileContent.h index 7555911..afa1444 100644 --- a/DiscordEuroscope/DefaultFileContent.h +++ b/DiscordEuroscope/DefaultFileContent.h @@ -69,8 +69,20 @@ }\r\ },\r\ \"radio_callsigns\": {\r\ - \"^HECC_CTR$\": \"Cairo Control Bandbox\",\r\ - \"^HECC_(\\\\d+)(?:_)CTR$\" : \"Cairo Control ACC $0\"\r\ + \"config\": {\r\ + \"load_from_ese\": false,\r\ + \"path_to_ese\" : \"..\\\\..\\\\\"\r\ + },\r\ + \"custom\" : [\r\ + {\r\ + \"callsign\": \"^HECC_CTR$\",\r\ + \"rcallsign\" : \"Cairo Control Bandbox\"\r\ + },\r\ + {\r\ + \"callsign\": \"^HECC_(\\\\d+)(?:_)CTR$\",\r\ + \"rcallsign\" : \"Cairo Control ACC $0\"\r\ + }\r\ + ]\r\ }\r\ }\r\ ") \ No newline at end of file diff --git a/DiscordEuroscope/DiscordEuroscopeExt.cpp b/DiscordEuroscope/DiscordEuroscopeExt.cpp index 6f76c37..7a465e9 100644 --- a/DiscordEuroscope/DiscordEuroscopeExt.cpp +++ b/DiscordEuroscope/DiscordEuroscopeExt.cpp @@ -176,8 +176,9 @@ VOID CALLBACK DiscordTimer(_In_ HWND hwnd, _In_ UINT uMsg, _In_ UINT_PTR idEvent std::string freq_str(8, 0); std::snprintf((char*)freq_str.c_str(), 8, "%.3f", frequency); + freq_str = std::string(freq_str, 0, strlen(freq_str.c_str())); std::string radio_callsign; - pMyPlugIn->config.FindRadioCallsign(callsign, radio_callsign); + pMyPlugIn->config.FindRadioCallsign(callsign, freq_str, radio_callsign); const std::map Dictionary = { {"callsign", callsign}, diff --git a/DiscordEuroscope/ESEHandler.cpp b/DiscordEuroscope/ESEHandler.cpp index 751ae1d..3f0a636 100644 --- a/DiscordEuroscope/ESEHandler.cpp +++ b/DiscordEuroscope/ESEHandler.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "ESEHandler.h" +#include "ConfigData.h" #include #include @@ -58,11 +59,27 @@ int ESEHandler::ParsePositions(void) return positions.size(); } -void ESEHandler::GetRadioCallsigns(std::map& rcs) +void ESEHandler::GetRadioCallsigns(RadioCallsigns_t& rcs) { + using namespace DiscordEuroScope_Configuration; rcs.clear(); for (auto& pos : positions) { - rcs.insert(std::pair(pos.callsign, pos.radio_callsign)); + DiscordEuroScope_Configuration::RadioCallsignElement_t element; + element.callsign = pos.callsign; + element.frequency = pos.frequency; + element.icao = pos.callsign.substr(0, pos.callsign.find_first_of('_')); + element.radio_callsign = pos.radio_callsign; + bool flag = false; + for (auto& it : rcs) + { + if (it.callsign == element.callsign /* TEMP DISABLE || (it.icao == element.icao && it.frequency == element.frequency)*/) + { + flag = true; + break; + } + } + if(!flag) + rcs.push_back(element); } } diff --git a/DiscordEuroscope/ESEHandler.h b/DiscordEuroscope/ESEHandler.h index 7dfbdbd..86a4e13 100644 --- a/DiscordEuroscope/ESEHandler.h +++ b/DiscordEuroscope/ESEHandler.h @@ -19,7 +19,9 @@ #include #include #include +#include "ConfigData.h" +using DiscordEuroScope_Configuration::RadioCallsigns_t; struct ESEPositionItem { @@ -36,5 +38,5 @@ class ESEHandler public: static bool LocateESEFile(std::string relative_path_to_ese); static int ParsePositions(void); - static void GetRadioCallsigns(std::map& rcs); + static void GetRadioCallsigns(RadioCallsigns_t& rcs); };