From 710520e89436a97062a398407db72808ddc9a996 Mon Sep 17 00:00:00 2001 From: Daniel 'MrAdder' Green Date: Mon, 26 May 2025 13:47:39 +0100 Subject: [PATCH 1/9] Feat: Auto Logon | Retry Refactored and changed the Auto Logon and Retry features Currently untested --- vSMR/CPDLCSettingsDialog.cpp | 2 + vSMR/CPDLCSettingsDialog.hpp | 1 + vSMR/SMRPlugin.cpp | 294 ++++++++++++++++++++++++----------- vSMR/resource.h | Bin 3380 -> 3472 bytes vSMR/vSMR.rc | 7 +- 5 files changed, 211 insertions(+), 93 deletions(-) diff --git a/vSMR/CPDLCSettingsDialog.cpp b/vSMR/CPDLCSettingsDialog.cpp index d06970911..6df0135b8 100644 --- a/vSMR/CPDLCSettingsDialog.cpp +++ b/vSMR/CPDLCSettingsDialog.cpp @@ -15,6 +15,7 @@ CCPDLCSettingsDialog::CCPDLCSettingsDialog(CWnd* pParent /*=NULL*/) , m_Logon(_T("EGKK")) , m_Password(_T("PASSWORD")) , m_Sound(1) + , m_autoLogon(0) { } @@ -29,6 +30,7 @@ void CCPDLCSettingsDialog::DoDataExchange(CDataExchange* pDX) DDX_Text(pDX, IDC_LOGON, m_Logon); DDX_Text(pDX, IDC_PASSWORD, m_Password); DDX_Check(pDX, IDC_SOUND, m_Sound); + DDX_Check(pDX, IDC_AUTOLOGON, m_autoLogon); } diff --git a/vSMR/CPDLCSettingsDialog.hpp b/vSMR/CPDLCSettingsDialog.hpp index 44fd6b507..1405c2809 100644 --- a/vSMR/CPDLCSettingsDialog.hpp +++ b/vSMR/CPDLCSettingsDialog.hpp @@ -15,6 +15,7 @@ class CCPDLCSettingsDialog : public CDialogEx CString m_Logon; CString m_Password; int m_Sound; + int m_autoLogon; // Dialog Data enum { IDD = IDD_DIALOG2 }; diff --git a/vSMR/SMRPlugin.cpp b/vSMR/SMRPlugin.cpp index 061efb0cc..27957a32e 100644 --- a/vSMR/SMRPlugin.cpp +++ b/vSMR/SMRPlugin.cpp @@ -11,13 +11,17 @@ bool FailedToConnectMessage = false; string logonCode = ""; string logonCallsign = "EGKK"; -HttpHelper * httpHelper = NULL; +HttpHelper *httpHelper = NULL; bool BLINK = false; bool PlaySoundClr = false; -struct DatalinkPacket { +bool AutoConnect = false; +bool isConnecting = false; + +struct DatalinkPacket +{ string callsign; string destination; string sid; @@ -34,7 +38,8 @@ DatalinkPacket DatalinkToSend; string baseUrlDatalink = "http://www.hoppie.nl/acars/system/connect.html"; -struct AcarsMessage { +struct AcarsMessage +{ string from; string type; string message; @@ -53,6 +58,12 @@ string ttype; int messageId = 0; +// Retry Timer +int loginRetryCount = 0; +const int maxLoginRetries = 5; +const int loginRetryDelaySec = 120; // 2 minutes not to spam Hoppie server +time_t nextLoginRetryTime = 0; + clock_t timer; string myfrequency; @@ -64,9 +75,10 @@ bool startThreadvStrips = true; using namespace SMRPluginSharedData; char recv_buf[1024]; -vector RadarScreensOpened; +vector RadarScreensOpened; -void datalinkLogin(void * arg) { +void datalinkLogin(void *arg) +{ string raw; string url = baseUrlDatalink; url += "?logon="; @@ -76,16 +88,31 @@ void datalinkLogin(void * arg) { url += "&to=SERVER&type=PING"; raw.assign(httpHelper->downloadStringFromURL(url)); - if (startsWith("ok", raw.c_str())) { + if (startsWith("ok", raw.c_str())) + { HoppieConnected = true; ConnectionMessage = true; + loginRetryCount = 0; } - else { + else + { FailedToConnectMessage = true; + loginRetryCount++; + if (loginRetryCount <= maxLoginRetries) + { + // Set next retry time + nextLoginRetryTime = time(NULL) + loginRetryDelaySec; + } + else + { + loginRetryCount = 0; // Reset after giving up + nextLoginRetryTime = 0; + } } }; -void sendDatalinkMessage(void * arg) { +void sendDatalinkMessage(void *arg) +{ string raw; string url = baseUrlDatalink; @@ -101,24 +128,28 @@ void sendDatalinkMessage(void * arg) { url += tmessage; size_t start_pos = 0; - while ((start_pos = url.find(" ", start_pos)) != std::string::npos) { + while ((start_pos = url.find(" ", start_pos)) != std::string::npos) + { url.replace(start_pos, string(" ").length(), "%20"); start_pos += string("%20").length(); } raw.assign(httpHelper->downloadStringFromURL(url)); - if (startsWith("ok", raw.c_str())) { + if (startsWith("ok", raw.c_str())) + { if (PendingMessages.find(DatalinkToSend.callsign) != PendingMessages.end()) PendingMessages.erase(DatalinkToSend.callsign); - if (std::find(AircraftMessage.begin(), AircraftMessage.end(), DatalinkToSend.callsign.c_str()) != AircraftMessage.end()) { + if (std::find(AircraftMessage.begin(), AircraftMessage.end(), DatalinkToSend.callsign.c_str()) != AircraftMessage.end()) + { AircraftMessage.erase(std::remove(AircraftMessage.begin(), AircraftMessage.end(), DatalinkToSend.callsign.c_str()), AircraftMessage.end()); } AircraftMessageSent.push_back(DatalinkToSend.callsign.c_str()); } }; -void pollMessages(void * arg) { +void pollMessages(void *arg) +{ string raw = ""; string url = baseUrlDatalink; url += "?logon="; @@ -137,7 +168,8 @@ void pollMessages(void * arg) { string delimiter = "}} "; size_t pos = 0; std::string token; - while ((pos = raw.find(delimiter)) != std::string::npos) { + while ((pos = raw.find(delimiter)) != std::string::npos) + { token = raw.substr(1, pos); string parsed; @@ -158,27 +190,36 @@ void pollMessages(void * arg) { i++; } - if (message.type.find("telex") != std::string::npos || message.type.find("cpdlc") != std::string::npos) { - if (message.message.find("REQ") != std::string::npos || message.message.find("CLR") != std::string::npos || message.message.find("PDC") != std::string::npos || message.message.find("PREDEP") != std::string::npos || message.message.find("REQUEST") != std::string::npos) { - if (message.message.find("LOGON") != std::string::npos) { + if (message.type.find("telex") != std::string::npos || message.type.find("cpdlc") != std::string::npos) + { + if (message.message.find("REQ") != std::string::npos || message.message.find("CLR") != std::string::npos || message.message.find("PDC") != std::string::npos || message.message.find("PREDEP") != std::string::npos || message.message.find("REQUEST") != std::string::npos) + { + if (message.message.find("LOGON") != std::string::npos) + { tmessage = "UNABLE"; ttype = "CPDLC"; tdest = DatalinkToSend.callsign; _beginthread(sendDatalinkMessage, 0, NULL); - } else { - if (PlaySoundClr) { + } + else + { + if (PlaySoundClr) + { AFX_MANAGE_STATE(AfxGetStaticModuleState()); PlaySound(MAKEINTRESOURCE(IDR_WAVE1), AfxGetInstanceHandle(), SND_RESOURCE | SND_ASYNC); } AircraftDemandingClearance.push_back(message.from); } } - else if (message.message.find("WILCO") != std::string::npos || message.message.find("ROGER") != std::string::npos || message.message.find("RGR") != std::string::npos || message.message.find("ACCEPT") != std::string::npos) { - if (std::find(AircraftMessageSent.begin(), AircraftMessageSent.end(), message.from) != AircraftMessageSent.end()) { + else if (message.message.find("WILCO") != std::string::npos || message.message.find("ROGER") != std::string::npos || message.message.find("RGR") != std::string::npos || message.message.find("ACCEPT") != std::string::npos) + { + if (std::find(AircraftMessageSent.begin(), AircraftMessageSent.end(), message.from) != AircraftMessageSent.end()) + { AircraftWilco.push_back(message.from); } } - else if (message.message.length() != 0 ){ + else if (message.message.length() != 0) + { AircraftMessage.push_back(message.from); } PendingMessages[message.from] = message; @@ -186,11 +227,10 @@ void pollMessages(void * arg) { raw.erase(0, pos + delimiter.length()); } - - }; -void sendDatalinkClearance(void * arg) { +void sendDatalinkClearance(void *arg) +{ string raw; string url = baseUrlDatalink; url += "?logon="; @@ -214,22 +254,26 @@ void sendDatalinkClearance(void * arg) { url += "@ SQUAWK @"; url += DatalinkToSend.squawk; url += "@ "; - if (DatalinkToSend.ctot != "no" && DatalinkToSend.ctot.size() > 3) { + if (DatalinkToSend.ctot != "no" && DatalinkToSend.ctot.size() > 3) + { url += "CTOT @"; url += DatalinkToSend.ctot; url += "@ "; } - if (DatalinkToSend.asat != "no" && DatalinkToSend.asat.size() > 3) { + if (DatalinkToSend.asat != "no" && DatalinkToSend.asat.size() > 3) + { url += "TSAT @"; url += DatalinkToSend.asat; url += "@ "; } - if (DatalinkToSend.freq != "no" && DatalinkToSend.freq.size() > 5) { + if (DatalinkToSend.freq != "no" && DatalinkToSend.freq.size() > 5) + { url += "WHEN RDY CALL FREQ @"; url += DatalinkToSend.freq; url += "@"; } - else { + else + { url += "WHEN RDY CALL @"; url += myfrequency; url += "@"; @@ -239,18 +283,22 @@ void sendDatalinkClearance(void * arg) { url += DatalinkToSend.message; size_t start_pos = 0; - while ((start_pos = url.find(" ", start_pos)) != std::string::npos) { + while ((start_pos = url.find(" ", start_pos)) != std::string::npos) + { url.replace(start_pos, string(" ").length(), "%20"); start_pos += string("%20").length(); } raw.assign(httpHelper->downloadStringFromURL(url)); - if (startsWith("ok", raw.c_str())) { - if (std::find(AircraftDemandingClearance.begin(), AircraftDemandingClearance.end(), DatalinkToSend.callsign.c_str()) != AircraftDemandingClearance.end()) { + if (startsWith("ok", raw.c_str())) + { + if (std::find(AircraftDemandingClearance.begin(), AircraftDemandingClearance.end(), DatalinkToSend.callsign.c_str()) != AircraftDemandingClearance.end()) + { AircraftDemandingClearance.erase(std::remove(AircraftDemandingClearance.begin(), AircraftDemandingClearance.end(), DatalinkToSend.callsign.c_str()), AircraftDemandingClearance.end()); } - if (std::find(AircraftStandby.begin(), AircraftStandby.end(), DatalinkToSend.callsign.c_str()) != AircraftStandby.end()) { + if (std::find(AircraftStandby.begin(), AircraftStandby.end(), DatalinkToSend.callsign.c_str()) != AircraftStandby.end()) + { AircraftStandby.erase(std::remove(AircraftStandby.begin(), AircraftStandby.end(), DatalinkToSend.callsign.c_str()), AircraftStandby.end()); } if (PendingMessages.find(DatalinkToSend.callsign) != PendingMessages.end()) @@ -259,7 +307,7 @@ void sendDatalinkClearance(void * arg) { } }; -CSMRPlugin::CSMRPlugin(void) :CPlugIn(EuroScopePlugIn::COMPATIBILITY_CODE, MY_PLUGIN_NAME, MY_PLUGIN_VERSION, MY_PLUGIN_DEVELOPER, MY_PLUGIN_COPYRIGHT) +CSMRPlugin::CSMRPlugin(void) : CPlugIn(EuroScopePlugIn::COMPATIBILITY_CODE, MY_PLUGIN_NAME, MY_PLUGIN_VERSION, MY_PLUGIN_DEVELOPER, MY_PLUGIN_COPYRIGHT) { Logger::DLL_PATH = ""; @@ -280,7 +328,7 @@ CSMRPlugin::CSMRPlugin(void) :CPlugIn(EuroScopePlugIn::COMPATIBILITY_CODE, MY_PL if (httpHelper == NULL) httpHelper = new HttpHelper(); - const char * p_value; + const char *p_value; if ((p_value = GetDataFromSettings("cpdlc_logon")) != NULL) logonCallsign = p_value; @@ -288,6 +336,8 @@ CSMRPlugin::CSMRPlugin(void) :CPlugIn(EuroScopePlugIn::COMPATIBILITY_CODE, MY_PL logonCode = p_value; if ((p_value = GetDataFromSettings("cpdlc_sound")) != NULL) PlaySoundClr = bool(!!atoi(p_value)); + if ((p_value = GetDataFromSettings("cpdlc_autoconnect")) != NULL) + AutoConnect = bool(!!atoi(p_value)); char DllPathFile[_MAX_PATH]; string DllPath; @@ -307,31 +357,37 @@ CSMRPlugin::~CSMRPlugin() if (PlaySoundClr) temp = 1; SaveDataToSettings("cpdlc_sound", "Play sound on clearance request", std::to_string(temp).c_str()); + SaveDataToSettings("cpdlc_autoconnect", "Automatically connect to Hoppie server on startup", std::to_string(AutoConnect).c_str()); try { io_service.stop(); - //vStripsThread.join(); + // vStripsThread.join(); } - catch (std::exception& e) + catch (std::exception &e) { std::cerr << e.what() << std::endl; } } -bool CSMRPlugin::OnCompileCommand(const char * sCommandLine) { +bool CSMRPlugin::OnCompileCommand(const char *sCommandLine) +{ if (startsWith(".smr connect", sCommandLine)) { - if (ControllerMyself().IsController()) { - if (!HoppieConnected) { + if (ControllerMyself().IsController()) + { + if (!HoppieConnected) + { _beginthread(datalinkLogin, 0, NULL); } - else { + else + { HoppieConnected = false; DisplayUserMessage("CPDLC", "Server", "Logged off!", true, true, false, true, false); } } - else { + else + { DisplayUserMessage("CPDLC", "Error", "You are not logged in as a controller!", true, true, false, true, false); } @@ -339,12 +395,14 @@ bool CSMRPlugin::OnCompileCommand(const char * sCommandLine) { } else if (startsWith(".smr poll", sCommandLine)) { - if (HoppieConnected) { + if (HoppieConnected) + { _beginthread(pollMessages, 0, NULL); } return true; } - else if (strcmp(sCommandLine, ".smr log") == 0) { + else if (strcmp(sCommandLine, ".smr log") == 0) + { Logger::ENABLED = !Logger::ENABLED; return true; } @@ -354,6 +412,7 @@ bool CSMRPlugin::OnCompileCommand(const char * sCommandLine) { dia.m_Logon = logonCallsign.c_str(); dia.m_Password = logonCode.c_str(); dia.m_Sound = int(PlaySoundClr); + dia.m_autoLogon = int(AutoConnect); if (dia.DoModal() != IDOK) return true; @@ -361,23 +420,29 @@ bool CSMRPlugin::OnCompileCommand(const char * sCommandLine) { logonCallsign = dia.m_Logon; logonCode = dia.m_Password; PlaySoundClr = bool(!!dia.m_Sound); + AutoConnect = bool(!!dia.m_autoLogon); SaveDataToSettings("cpdlc_logon", "The CPDLC logon callsign", logonCallsign.c_str()); SaveDataToSettings("cpdlc_password", "The CPDLC logon password", logonCode.c_str()); int temp = 0; if (PlaySoundClr) temp = 1; SaveDataToSettings("cpdlc_sound", "Play sound on clearance request", std::to_string(temp).c_str()); + SaveDataToSettings("cpdlc_autoconnect", "Automatically connect to Hoppie server on startup", std::to_string(AutoConnect).c_str()); return true; } return false; } -void CSMRPlugin::OnGetTagItem(CFlightPlan FlightPlan, CRadarTarget RadarTarget, int ItemCode, int TagData, char sItemString[16], int * pColorCode, COLORREF * pRGB, double * pFontSize) { +void CSMRPlugin::OnGetTagItem(CFlightPlan FlightPlan, CRadarTarget RadarTarget, int ItemCode, int TagData, char sItemString[16], int *pColorCode, COLORREF *pRGB, double *pFontSize) +{ Logger::info(string(__FUNCSIG__)); - if (ItemCode == TAG_ITEM_DATALINK_STS) { - if (FlightPlan.IsValid()) { - if (std::find(AircraftDemandingClearance.begin(), AircraftDemandingClearance.end(), FlightPlan.GetCallsign()) != AircraftDemandingClearance.end()) { + if (ItemCode == TAG_ITEM_DATALINK_STS) + { + if (FlightPlan.IsValid()) + { + if (std::find(AircraftDemandingClearance.begin(), AircraftDemandingClearance.end(), FlightPlan.GetCallsign()) != AircraftDemandingClearance.end()) + { *pColorCode = TAG_COLOR_RGB_DEFINED; if (BLINK) *pRGB = RGB(130, 130, 130); @@ -389,7 +454,8 @@ void CSMRPlugin::OnGetTagItem(CFlightPlan FlightPlan, CRadarTarget RadarTarget, else strcpy_s(sItemString, 16, "R"); } - else if (std::find(AircraftMessage.begin(), AircraftMessage.end(), FlightPlan.GetCallsign()) != AircraftMessage.end()) { + else if (std::find(AircraftMessage.begin(), AircraftMessage.end(), FlightPlan.GetCallsign()) != AircraftMessage.end()) + { *pColorCode = TAG_COLOR_RGB_DEFINED; if (BLINK) *pRGB = RGB(130, 130, 130); @@ -397,17 +463,20 @@ void CSMRPlugin::OnGetTagItem(CFlightPlan FlightPlan, CRadarTarget RadarTarget, *pRGB = RGB(255, 255, 0); strcpy_s(sItemString, 16, "T"); } - else if (std::find(AircraftWilco.begin(), AircraftWilco.end(), FlightPlan.GetCallsign()) != AircraftWilco.end()) { + else if (std::find(AircraftWilco.begin(), AircraftWilco.end(), FlightPlan.GetCallsign()) != AircraftWilco.end()) + { *pColorCode = TAG_COLOR_RGB_DEFINED; *pRGB = RGB(0, 176, 0); strcpy_s(sItemString, 16, "V"); } - else if (std::find(AircraftMessageSent.begin(), AircraftMessageSent.end(), FlightPlan.GetCallsign()) != AircraftMessageSent.end()) { + else if (std::find(AircraftMessageSent.begin(), AircraftMessageSent.end(), FlightPlan.GetCallsign()) != AircraftMessageSent.end()) + { *pColorCode = TAG_COLOR_RGB_DEFINED; *pRGB = RGB(255, 255, 0); strcpy_s(sItemString, 16, "V"); } - else { + else + { *pColorCode = TAG_COLOR_RGB_DEFINED; *pRGB = RGB(130, 130, 130); @@ -417,16 +486,19 @@ void CSMRPlugin::OnGetTagItem(CFlightPlan FlightPlan, CRadarTarget RadarTarget, } } -void CSMRPlugin::OnFunctionCall(int FunctionId, const char * sItemString, POINT Pt, RECT Area) +void CSMRPlugin::OnFunctionCall(int FunctionId, const char *sItemString, POINT Pt, RECT Area) { Logger::info(string(__FUNCSIG__)); - if (FunctionId == TAG_FUNC_DATALINK_MENU) { + if (FunctionId == TAG_FUNC_DATALINK_MENU) + { CFlightPlan FlightPlan = FlightPlanSelectASEL(); bool menu_is_datalink = true; - if (FlightPlan.IsValid()) { - if (std::find(AircraftDemandingClearance.begin(), AircraftDemandingClearance.end(), FlightPlan.GetCallsign()) != AircraftDemandingClearance.end()) { + if (FlightPlan.IsValid()) + { + if (std::find(AircraftDemandingClearance.begin(), AircraftDemandingClearance.end(), FlightPlan.GetCallsign()) != AircraftDemandingClearance.end()) + { menu_is_datalink = false; } } @@ -440,35 +512,45 @@ void CSMRPlugin::OnFunctionCall(int FunctionId, const char * sItemString, POINT AddPopupListElement("Close", "", EuroScopePlugIn::TAG_ITEM_FUNCTION_NO, false, 2, false, true); } - if (FunctionId == TAG_FUNC_DATALINK_RESET) { + if (FunctionId == TAG_FUNC_DATALINK_RESET) + { CFlightPlan FlightPlan = FlightPlanSelectASEL(); - if (FlightPlan.IsValid()) { - if (std::find(AircraftDemandingClearance.begin(), AircraftDemandingClearance.end(), FlightPlan.GetCallsign()) != AircraftDemandingClearance.end()) { + if (FlightPlan.IsValid()) + { + if (std::find(AircraftDemandingClearance.begin(), AircraftDemandingClearance.end(), FlightPlan.GetCallsign()) != AircraftDemandingClearance.end()) + { AircraftDemandingClearance.erase(std::remove(AircraftDemandingClearance.begin(), AircraftDemandingClearance.end(), FlightPlan.GetCallsign()), AircraftDemandingClearance.end()); } - if (std::find(AircraftStandby.begin(), AircraftStandby.end(), FlightPlan.GetCallsign()) != AircraftStandby.end()) { + if (std::find(AircraftStandby.begin(), AircraftStandby.end(), FlightPlan.GetCallsign()) != AircraftStandby.end()) + { AircraftStandby.erase(std::remove(AircraftStandby.begin(), AircraftStandby.end(), FlightPlan.GetCallsign()), AircraftStandby.end()); } - if (std::find(AircraftMessageSent.begin(), AircraftMessageSent.end(), FlightPlan.GetCallsign()) != AircraftMessageSent.end()) { + if (std::find(AircraftMessageSent.begin(), AircraftMessageSent.end(), FlightPlan.GetCallsign()) != AircraftMessageSent.end()) + { AircraftMessageSent.erase(std::remove(AircraftMessageSent.begin(), AircraftMessageSent.end(), FlightPlan.GetCallsign()), AircraftMessageSent.end()); } - if (std::find(AircraftWilco.begin(), AircraftWilco.end(), FlightPlan.GetCallsign()) != AircraftWilco.end()) { + if (std::find(AircraftWilco.begin(), AircraftWilco.end(), FlightPlan.GetCallsign()) != AircraftWilco.end()) + { AircraftWilco.erase(std::remove(AircraftWilco.begin(), AircraftWilco.end(), FlightPlan.GetCallsign()), AircraftWilco.end()); } - if (std::find(AircraftMessage.begin(), AircraftMessage.end(), FlightPlan.GetCallsign()) != AircraftMessage.end()) { + if (std::find(AircraftMessage.begin(), AircraftMessage.end(), FlightPlan.GetCallsign()) != AircraftMessage.end()) + { AircraftMessage.erase(std::remove(AircraftMessage.begin(), AircraftMessage.end(), FlightPlan.GetCallsign()), AircraftMessage.end()); } - if (PendingMessages.find(FlightPlan.GetCallsign()) != PendingMessages.end()) { + if (PendingMessages.find(FlightPlan.GetCallsign()) != PendingMessages.end()) + { PendingMessages.erase(FlightPlan.GetCallsign()); } } } - if (FunctionId == TAG_FUNC_DATALINK_STBY) { + if (FunctionId == TAG_FUNC_DATALINK_STBY) + { CFlightPlan FlightPlan = FlightPlanSelectASEL(); - if (FlightPlan.IsValid()) { + if (FlightPlan.IsValid()) + { AircraftStandby.push_back(FlightPlan.GetCallsign()); tmessage = "STANDBY"; ttype = "CPDLC"; @@ -477,10 +559,12 @@ void CSMRPlugin::OnFunctionCall(int FunctionId, const char * sItemString, POINT } } - if (FunctionId == TAG_FUNC_DATALINK_MESSAGE) { + if (FunctionId == TAG_FUNC_DATALINK_MESSAGE) + { CFlightPlan FlightPlan = FlightPlanSelectASEL(); - if (FlightPlan.IsValid()) { + if (FlightPlan.IsValid()) + { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CDataLinkDialog dia; @@ -504,31 +588,36 @@ void CSMRPlugin::OnFunctionCall(int FunctionId, const char * sItemString, POINT } } - if (FunctionId == TAG_FUNC_DATALINK_VOICE) { + if (FunctionId == TAG_FUNC_DATALINK_VOICE) + { CFlightPlan FlightPlan = FlightPlanSelectASEL(); - if (FlightPlan.IsValid()) { + if (FlightPlan.IsValid()) + { tmessage = "UNABLE CALL ON FREQ"; ttype = "CPDLC"; tdest = FlightPlan.GetCallsign(); - if (std::find(AircraftDemandingClearance.begin(), AircraftDemandingClearance.end(), DatalinkToSend.callsign.c_str()) != AircraftDemandingClearance.end()) { + if (std::find(AircraftDemandingClearance.begin(), AircraftDemandingClearance.end(), DatalinkToSend.callsign.c_str()) != AircraftDemandingClearance.end()) + { AircraftDemandingClearance.erase(std::remove(AircraftDemandingClearance.begin(), AircraftDemandingClearance.end(), FlightPlan.GetCallsign()), AircraftDemandingClearance.end()); } - if (std::find(AircraftStandby.begin(), AircraftStandby.end(), DatalinkToSend.callsign.c_str()) != AircraftStandby.end()) { + if (std::find(AircraftStandby.begin(), AircraftStandby.end(), DatalinkToSend.callsign.c_str()) != AircraftStandby.end()) + { AircraftStandby.erase(std::remove(AircraftStandby.begin(), AircraftStandby.end(), FlightPlan.GetCallsign()), AircraftDemandingClearance.end()); } PendingMessages.erase(DatalinkToSend.callsign); _beginthread(sendDatalinkMessage, 0, NULL); } - } - if (FunctionId == TAG_FUNC_DATALINK_CONFIRM) { + if (FunctionId == TAG_FUNC_DATALINK_CONFIRM) + { CFlightPlan FlightPlan = FlightPlanSelectASEL(); - if (FlightPlan.IsValid()) { + if (FlightPlan.IsValid()) + { AFX_MANAGE_STATE(AfxGetStaticModuleState()); @@ -553,8 +642,10 @@ void CSMRPlugin::OnFunctionCall(int FunctionId, const char * sItemString, POINT int ClearedAltitude = FlightPlan.GetControllerAssignedData().GetClearedAltitude(); int Ta = GetTransitionAltitude(); - if (ClearedAltitude != 0) { - if (ClearedAltitude > Ta && ClearedAltitude > 2) { + if (ClearedAltitude != 0) + { + if (ClearedAltitude > Ta && ClearedAltitude > 2) + { string str = std::to_string(ClearedAltitude); for (size_t i = 0; i < 5 - str.length(); i++) str = "0" + str; @@ -563,8 +654,8 @@ void CSMRPlugin::OnFunctionCall(int FunctionId, const char * sItemString, POINT toReturn = "FL"; toReturn += str; } - else if (ClearedAltitude <= Ta && ClearedAltitude > 2) { - + else if (ClearedAltitude <= Ta && ClearedAltitude > 2) + { toReturn = std::to_string(ClearedAltitude); toReturn += "ft"; @@ -589,9 +680,7 @@ void CSMRPlugin::OnFunctionCall(int FunctionId, const char * sItemString, POINT myfrequency = std::to_string(ControllerMyself().GetPrimaryFrequency()).substr(0, 7); _beginthread(sendDatalinkClearance, 0, NULL); - } - } } @@ -612,22 +701,44 @@ void CSMRPlugin::OnTimer(int Counter) Logger::info(string(__FUNCSIG__)); BLINK = !BLINK; - if (HoppieConnected && ConnectionMessage) { + if (HoppieConnected && ConnectionMessage) + { DisplayUserMessage("CPDLC", "Server", "Logged in!", true, true, false, true, false); ConnectionMessage = false; } - if (FailedToConnectMessage) { + if (FailedToConnectMessage) + { DisplayUserMessage("CPDLC", "Server", "Could not login! Callsign probably in use.", true, true, false, true, false); FailedToConnectMessage = false; } - if (HoppieConnected && GetConnectionType() == CONNECTION_TYPE_NO) { + if (HoppieConnected && GetConnectionType() == CONNECTION_TYPE_NO) + { DisplayUserMessage("CPDLC", "Server", "Automatically logged off!", true, true, false, true, false); HoppieConnected = false; } - if (((clock() - timer) / CLOCKS_PER_SEC) > 10 && HoppieConnected) { + // Retry login + if (!HoppieConnected && nextLoginRetryTime > 0 && time(NULL) >= nextLoginRetryTime) + { + _beginthread(datalinkLogin, 0, NULL); + nextLoginRetryTime = 0; // Prevent multiple triggers + } + + if (AutoConnect && !HoppieConnected && !isConnecting) + { + isConnecting = true; + _beginthread(datalinkLogin, 0, NULL); + } + else if (!AutoConnect && HoppieConnected) + { + HoppieConnected = false; + DisplayUserMessage("CPDLC", "Server", "Logged off!", true, true, false, true, false); + } + + if (((clock() - timer) / CLOCKS_PER_SEC) > 10 && HoppieConnected) + { _beginthread(pollMessages, 0, NULL); timer = clock(); } @@ -636,19 +747,22 @@ void CSMRPlugin::OnTimer(int Counter) { CRadarTarget RadarTarget = RadarTargetSelect(ac.c_str()); - if (RadarTarget.IsValid()) { - if (RadarTarget.GetGS() > 160) { + if (RadarTarget.IsValid()) + { + if (RadarTarget.GetGS() > 160) + { AircraftWilco.erase(std::remove(AircraftWilco.begin(), AircraftWilco.end(), ac), AircraftWilco.end()); } } } }; -CRadarScreen * CSMRPlugin::OnRadarScreenCreated(const char * sDisplayName, bool NeedRadarContent, bool GeoReferenced, bool CanBeSaved, bool CanBeCreated) +CRadarScreen *CSMRPlugin::OnRadarScreenCreated(const char *sDisplayName, bool NeedRadarContent, bool GeoReferenced, bool CanBeSaved, bool CanBeCreated) { Logger::info(string(__FUNCSIG__)); - if (!strcmp(sDisplayName, MY_PLUGIN_VIEW_AVISO)) { - CSMRRadar* rd = new CSMRRadar(); + if (!strcmp(sDisplayName, MY_PLUGIN_VIEW_AVISO)) + { + CSMRRadar *rd = new CSMRRadar(); RadarScreensOpened.push_back(rd); return rd; } @@ -658,7 +772,7 @@ CRadarScreen * CSMRPlugin::OnRadarScreenCreated(const char * sDisplayName, bool //---EuroScopePlugInExit----------------------------------------------- -void __declspec (dllexport) EuroScopePlugInExit(void) +void __declspec(dllexport) EuroScopePlugInExit(void) { for each (auto var in RadarScreensOpened) { diff --git a/vSMR/resource.h b/vSMR/resource.h index 48b49b13ce53791739db64a80db607445cd5e462..143b78aaccbe8808464b8e2fe3d019c572b8e4ba 100644 GIT binary patch delta 42 vcmdlYH9>mA8Lr7U*dzoU8A2IC82lN0fY=>~{U&c@(q=YdFx-5cE0+lX1J?^2 delta 12 TcmbOry+vxn8LrJ5+!;&&AV~yJ diff --git a/vSMR/vSMR.rc b/vSMR/vSMR.rc index 4fddda0d4..6bd890815 100644 --- a/vSMR/vSMR.rc +++ b/vSMR/vSMR.rc @@ -176,18 +176,19 @@ BEGIN EDITTEXT IDC_CLB,141,52,29,14,ES_CENTER | ES_UPPERCASE | ES_AUTOHSCROLL | WS_DISABLED END -IDD_DIALOG2 DIALOGEX 0, 0, 142, 105 +IDD_DIALOG2 DIALOGEX 0, 0, 142, 125 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "CPDLC Settings" FONT 10, "Microsoft Sans Serif", 400, 0, 0x0 BEGIN - DEFPUSHBUTTON "OK",IDOK,85,84,50,14 - PUSHBUTTON "Cancel",IDCANCEL,7,84,50,14 + DEFPUSHBUTTON "OK",IDOK,85,104,50,14 + PUSHBUTTON "Cancel",IDCANCEL,7,104,50,14 EDITTEXT IDC_LOGON,61,15,74,14,ES_AUTOHSCROLL LTEXT "Logon Callsign",IDC_STATIC,7,18,46,8 EDITTEXT IDC_PASSWORD,61,43,74,14,ES_PASSWORD | ES_AUTOHSCROLL LTEXT "Logon Password",IDC_STATIC,7,46,52,8 CONTROL "Play sound on clearance request",IDC_SOUND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,65,128,10 + CONTROL "", IDC_AUTO, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 7, 80, 128, 20 END From 3497308cef03682aab30b48f75205847a2a32498 Mon Sep 17 00:00:00 2001 From: Daniel 'MrAdder' Green Date: Mon, 26 May 2025 13:50:08 +0100 Subject: [PATCH 2/9] Forgot to add Text --- vSMR/vSMR.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vSMR/vSMR.rc b/vSMR/vSMR.rc index 6bd890815..eab523582 100644 --- a/vSMR/vSMR.rc +++ b/vSMR/vSMR.rc @@ -188,7 +188,7 @@ BEGIN EDITTEXT IDC_PASSWORD,61,43,74,14,ES_PASSWORD | ES_AUTOHSCROLL LTEXT "Logon Password",IDC_STATIC,7,46,52,8 CONTROL "Play sound on clearance request",IDC_SOUND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,65,128,10 - CONTROL "", IDC_AUTO, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 7, 80, 128, 20 + CONTROL "Automatically connect to Hoppie server on startup", IDC_AUTOLOGON, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 7, 80, 128, 20 END From 64241b72256d29f36b54adb22272b143c3b9d322 Mon Sep 17 00:00:00 2001 From: Daniel 'MrAdder' Green Date: Mon, 26 May 2025 14:58:45 +0100 Subject: [PATCH 3/9] Possible build fix --- vSMR/CPDLCSettingsDialog.cpp | 4 ++-- vSMR/CPDLCSettingsDialog.hpp | 2 +- vSMR/SMRPlugin.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/vSMR/CPDLCSettingsDialog.cpp b/vSMR/CPDLCSettingsDialog.cpp index 6df0135b8..4348f9027 100644 --- a/vSMR/CPDLCSettingsDialog.cpp +++ b/vSMR/CPDLCSettingsDialog.cpp @@ -15,7 +15,7 @@ CCPDLCSettingsDialog::CCPDLCSettingsDialog(CWnd* pParent /*=NULL*/) , m_Logon(_T("EGKK")) , m_Password(_T("PASSWORD")) , m_Sound(1) - , m_autoLogon(0) + , m_AutoLogon(0) { } @@ -30,7 +30,7 @@ void CCPDLCSettingsDialog::DoDataExchange(CDataExchange* pDX) DDX_Text(pDX, IDC_LOGON, m_Logon); DDX_Text(pDX, IDC_PASSWORD, m_Password); DDX_Check(pDX, IDC_SOUND, m_Sound); - DDX_Check(pDX, IDC_AUTOLOGON, m_autoLogon); + DDX_Check(pDX, IDC_AUTOLOGON, m_AutoLogon); } diff --git a/vSMR/CPDLCSettingsDialog.hpp b/vSMR/CPDLCSettingsDialog.hpp index 1405c2809..89037baf4 100644 --- a/vSMR/CPDLCSettingsDialog.hpp +++ b/vSMR/CPDLCSettingsDialog.hpp @@ -15,7 +15,7 @@ class CCPDLCSettingsDialog : public CDialogEx CString m_Logon; CString m_Password; int m_Sound; - int m_autoLogon; + int m_AutoLogon; // Dialog Data enum { IDD = IDD_DIALOG2 }; diff --git a/vSMR/SMRPlugin.cpp b/vSMR/SMRPlugin.cpp index 27957a32e..ea5993f2c 100644 --- a/vSMR/SMRPlugin.cpp +++ b/vSMR/SMRPlugin.cpp @@ -412,7 +412,7 @@ bool CSMRPlugin::OnCompileCommand(const char *sCommandLine) dia.m_Logon = logonCallsign.c_str(); dia.m_Password = logonCode.c_str(); dia.m_Sound = int(PlaySoundClr); - dia.m_autoLogon = int(AutoConnect); + dia.m_AutoLogon = int(AutoConnect); if (dia.DoModal() != IDOK) return true; @@ -420,7 +420,7 @@ bool CSMRPlugin::OnCompileCommand(const char *sCommandLine) logonCallsign = dia.m_Logon; logonCode = dia.m_Password; PlaySoundClr = bool(!!dia.m_Sound); - AutoConnect = bool(!!dia.m_autoLogon); + AutoConnect = bool(!!dia.m_AutoLogon); SaveDataToSettings("cpdlc_logon", "The CPDLC logon callsign", logonCallsign.c_str()); SaveDataToSettings("cpdlc_password", "The CPDLC logon password", logonCode.c_str()); int temp = 0; From da493f8315cfa90f43a6fea2b48eaaff9a75cc9c Mon Sep 17 00:00:00 2001 From: Daniel 'MrAdder' Green Date: Mon, 26 May 2025 16:13:47 +0100 Subject: [PATCH 4/9] Updated Appveyor --- appveyor.yml => .appveyor.yml | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) rename appveyor.yml => .appveyor.yml (91%) diff --git a/appveyor.yml b/.appveyor.yml similarity index 91% rename from appveyor.yml rename to .appveyor.yml index 861a6c21e..22a306fcf 100644 --- a/appveyor.yml +++ b/.appveyor.yml @@ -9,17 +9,7 @@ #---------------------------------# # version format -version: 1.5.{build} - -# branches to build -branches: - # whitelist - only: - - master - - # blacklist - except: - - gh-pages +version: 1.6.{build} # Maximum number of concurrent jobs for the project max_jobs: 1 @@ -29,7 +19,7 @@ max_jobs: 1 #---------------------------------# # Build worker image (VM template) -os: Visual Studio 2019 +os: Visual Studio 2022 #---------------------------------# # build configuration # @@ -59,3 +49,5 @@ after_build: artifacts: - path: vSMR-nightly.zip + + From c5d23c98294259a66e3bdf94e0769bb372958a24 Mon Sep 17 00:00:00 2001 From: Daniel 'MrAdder' Green Date: Mon, 26 May 2025 16:54:29 +0100 Subject: [PATCH 5/9] Fixes Unset the isConnecting variable when actually connecting ready for reconnecting attempts --- vSMR/SMRPlugin.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/vSMR/SMRPlugin.cpp b/vSMR/SMRPlugin.cpp index ea5993f2c..df880d458 100644 --- a/vSMR/SMRPlugin.cpp +++ b/vSMR/SMRPlugin.cpp @@ -93,6 +93,7 @@ void datalinkLogin(void *arg) HoppieConnected = true; ConnectionMessage = true; loginRetryCount = 0; + isConnecting = false; } else { @@ -108,6 +109,7 @@ void datalinkLogin(void *arg) loginRetryCount = 0; // Reset after giving up nextLoginRetryTime = 0; } + isConnecting = false; } }; @@ -701,6 +703,7 @@ void CSMRPlugin::OnTimer(int Counter) Logger::info(string(__FUNCSIG__)); BLINK = !BLINK; + if (HoppieConnected && ConnectionMessage) { DisplayUserMessage("CPDLC", "Server", "Logged in!", true, true, false, true, false); @@ -722,10 +725,13 @@ void CSMRPlugin::OnTimer(int Counter) // Retry login if (!HoppieConnected && nextLoginRetryTime > 0 && time(NULL) >= nextLoginRetryTime) { + isConnecting = true; _beginthread(datalinkLogin, 0, NULL); nextLoginRetryTime = 0; // Prevent multiple triggers } + + //Auto connection if (AutoConnect && !HoppieConnected && !isConnecting) { isConnecting = true; @@ -734,7 +740,7 @@ void CSMRPlugin::OnTimer(int Counter) else if (!AutoConnect && HoppieConnected) { HoppieConnected = false; - DisplayUserMessage("CPDLC", "Server", "Logged off!", true, true, false, true, false); + DisplayUserMessage("CPDLC", "Server", "Please run .smr connect to login!", true, true, false, true, false); } if (((clock() - timer) / CLOCKS_PER_SEC) > 10 && HoppieConnected) From b0ec9468eb500e323babf9bd79a92a8b0888346d Mon Sep 17 00:00:00 2001 From: Daniel 'MrAdder' Green Date: Mon, 26 May 2025 17:52:13 +0100 Subject: [PATCH 6/9] Update SMRPlugin.cpp - ReAdded Checks for if the client is a controller or observer - Added notices Max retries and missing logon code - fixed the login loop from the autoconnection --- vSMR/SMRPlugin.cpp | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/vSMR/SMRPlugin.cpp b/vSMR/SMRPlugin.cpp index df880d458..bb75cc6a1 100644 --- a/vSMR/SMRPlugin.cpp +++ b/vSMR/SMRPlugin.cpp @@ -79,6 +79,14 @@ vector RadarScreensOpened; void datalinkLogin(void *arg) { + + // Check if logonCode is empty or only whitespace + if (logonCode.empty() || std::all_of(logonCode.begin(), logonCode.end(), isspace)) { + DisplayUserMessage("CPDLC", "Error", "Logon code is empty. Please set your CPDLC password in the settings.", true, true, false, true, false); + isConnecting = false; + return; + } + string raw; string url = baseUrlDatalink; url += "?logon="; @@ -106,6 +114,7 @@ void datalinkLogin(void *arg) } else { + DisplayUserMessage("CPDLC", "Error", "Maximum login retries reached. Please check your logon code and network connection.", true, true, false, true, false); loginRetryCount = 0; // Reset after giving up nextLoginRetryTime = 0; } @@ -723,24 +732,30 @@ void CSMRPlugin::OnTimer(int Counter) } // Retry login - if (!HoppieConnected && nextLoginRetryTime > 0 && time(NULL) >= nextLoginRetryTime) + if (ControllerMyself().IsController() && !HoppieConnected && nextLoginRetryTime > 0 && time(NULL) >= nextLoginRetryTime) { isConnecting = true; _beginthread(datalinkLogin, 0, NULL); nextLoginRetryTime = 0; // Prevent multiple triggers } - + else { + DisplayUserMessage("CPDLC", "Error", "You are not logged in as a controller!", true, true, false, true, false); + } //Auto connection - if (AutoConnect && !HoppieConnected && !isConnecting) + if (ControllerMyself().IsController() && AutoConnect && !HoppieConnected && !isConnecting) { - isConnecting = true; - _beginthread(datalinkLogin, 0, NULL); + if (loginRetryCount > 0 && nextLoginRetryTime > 0 && time(NULL) < nextLoginRetryTime) + { + return; // Wait for the next retry time + } + else { + isConnecting = true; + _beginthread(datalinkLogin, 0, NULL); + } } - else if (!AutoConnect && HoppieConnected) - { - HoppieConnected = false; - DisplayUserMessage("CPDLC", "Server", "Please run .smr connect to login!", true, true, false, true, false); + else { + DisplayUserMessage("CPDLC", "Error", "You are not logged in as a controller!", true, true, false, true, false); } if (((clock() - timer) / CLOCKS_PER_SEC) > 10 && HoppieConnected) From 68aad1226f215044faea51d84fe77f051bb7be36 Mon Sep 17 00:00:00 2001 From: Daniel 'MrAdder' Green Date: Mon, 26 May 2025 18:03:33 +0100 Subject: [PATCH 7/9] Update SMRPlugin.cpp --- vSMR/SMRPlugin.cpp | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/vSMR/SMRPlugin.cpp b/vSMR/SMRPlugin.cpp index bb75cc6a1..3ca4087e6 100644 --- a/vSMR/SMRPlugin.cpp +++ b/vSMR/SMRPlugin.cpp @@ -79,14 +79,6 @@ vector RadarScreensOpened; void datalinkLogin(void *arg) { - - // Check if logonCode is empty or only whitespace - if (logonCode.empty() || std::all_of(logonCode.begin(), logonCode.end(), isspace)) { - DisplayUserMessage("CPDLC", "Error", "Logon code is empty. Please set your CPDLC password in the settings.", true, true, false, true, false); - isConnecting = false; - return; - } - string raw; string url = baseUrlDatalink; url += "?logon="; @@ -114,7 +106,6 @@ void datalinkLogin(void *arg) } else { - DisplayUserMessage("CPDLC", "Error", "Maximum login retries reached. Please check your logon code and network connection.", true, true, false, true, false); loginRetryCount = 0; // Reset after giving up nextLoginRetryTime = 0; } @@ -389,7 +380,17 @@ bool CSMRPlugin::OnCompileCommand(const char *sCommandLine) { if (!HoppieConnected) { - _beginthread(datalinkLogin, 0, NULL); + if (isConnecting) + { + DisplayUserMessage("CPDLC", "Server", "Already trying to connect!", true, true, false, true, false); + } + else if (nextLoginRetryTime > 0 && time(NULL) < nextLoginRetryTime) + { + DisplayUserMessage("CPDLC", "Server", "Waiting for next retry time!", true, true, false, true, false); + } + else { + _beginthread(datalinkLogin, 0, NULL); + } } else { @@ -731,6 +732,13 @@ void CSMRPlugin::OnTimer(int Counter) HoppieConnected = false; } + // Check if logonCode is empty or only whitespace + if (ControllerMyself().IsController() && logonCode.empty() || std::all_of(logonCode.begin(), logonCode.end(), isspace)) { + DisplayUserMessage("CPDLC", "Error", "Logon code is empty. Please set your CPDLC password in the settings.", true, true, false, true, false); + isConnecting = false; + return; + } + // Retry login if (ControllerMyself().IsController() && !HoppieConnected && nextLoginRetryTime > 0 && time(NULL) >= nextLoginRetryTime) { @@ -738,7 +746,16 @@ void CSMRPlugin::OnTimer(int Counter) _beginthread(datalinkLogin, 0, NULL); nextLoginRetryTime = 0; // Prevent multiple triggers } - else { + else if (maxLoginRetries > 0 && loginRetryCount >= maxLoginRetries && nextLoginRetryTime == 0) + { + DisplayUserMessage("CPDLC", "Error", "Maximum login retries reached. Please check your settings.", true, true, false, true, false); + HoppieConnected = false; + loginRetryCount = 0; // Reset after giving up + nextLoginRetryTime = 0; // Reset next retry time + isConnecting = false; + return; + } + { DisplayUserMessage("CPDLC", "Error", "You are not logged in as a controller!", true, true, false, true, false); } From f4683ae75d8378ac335e96949a90e3ec7ad0c02d Mon Sep 17 00:00:00 2001 From: Daniel 'MrAdder' Green Date: Sun, 20 Jul 2025 11:14:26 +0100 Subject: [PATCH 8/9] Disable AutoConnect --- vSMR/SMRPlugin.cpp | 48 ++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/vSMR/SMRPlugin.cpp b/vSMR/SMRPlugin.cpp index 3ca4087e6..83e5504b5 100644 --- a/vSMR/SMRPlugin.cpp +++ b/vSMR/SMRPlugin.cpp @@ -17,7 +17,7 @@ bool BLINK = false; bool PlaySoundClr = false; -bool AutoConnect = false; +// bool AutoConnect = false; bool isConnecting = false; struct DatalinkPacket @@ -338,8 +338,8 @@ CSMRPlugin::CSMRPlugin(void) : CPlugIn(EuroScopePlugIn::COMPATIBILITY_CODE, MY_P logonCode = p_value; if ((p_value = GetDataFromSettings("cpdlc_sound")) != NULL) PlaySoundClr = bool(!!atoi(p_value)); - if ((p_value = GetDataFromSettings("cpdlc_autoconnect")) != NULL) - AutoConnect = bool(!!atoi(p_value)); + /* if ((p_value = GetDataFromSettings("cpdlc_autoconnect")) != NULL) + AutoConnect = bool(!!atoi(p_value)); */ char DllPathFile[_MAX_PATH]; string DllPath; @@ -359,7 +359,7 @@ CSMRPlugin::~CSMRPlugin() if (PlaySoundClr) temp = 1; SaveDataToSettings("cpdlc_sound", "Play sound on clearance request", std::to_string(temp).c_str()); - SaveDataToSettings("cpdlc_autoconnect", "Automatically connect to Hoppie server on startup", std::to_string(AutoConnect).c_str()); + // SaveDataToSettings("cpdlc_autoconnect", "Automatically connect to Hoppie server on startup", std::to_string(AutoConnect).c_str()); try { @@ -388,7 +388,8 @@ bool CSMRPlugin::OnCompileCommand(const char *sCommandLine) { DisplayUserMessage("CPDLC", "Server", "Waiting for next retry time!", true, true, false, true, false); } - else { + else + { _beginthread(datalinkLogin, 0, NULL); } } @@ -424,7 +425,7 @@ bool CSMRPlugin::OnCompileCommand(const char *sCommandLine) dia.m_Logon = logonCallsign.c_str(); dia.m_Password = logonCode.c_str(); dia.m_Sound = int(PlaySoundClr); - dia.m_AutoLogon = int(AutoConnect); + // dia.m_AutoLogon = int(AutoConnect); if (dia.DoModal() != IDOK) return true; @@ -439,7 +440,7 @@ bool CSMRPlugin::OnCompileCommand(const char *sCommandLine) if (PlaySoundClr) temp = 1; SaveDataToSettings("cpdlc_sound", "Play sound on clearance request", std::to_string(temp).c_str()); - SaveDataToSettings("cpdlc_autoconnect", "Automatically connect to Hoppie server on startup", std::to_string(AutoConnect).c_str()); + // SaveDataToSettings("cpdlc_autoconnect", "Automatically connect to Hoppie server on startup", std::to_string(AutoConnect).c_str()); return true; } @@ -713,7 +714,6 @@ void CSMRPlugin::OnTimer(int Counter) Logger::info(string(__FUNCSIG__)); BLINK = !BLINK; - if (HoppieConnected && ConnectionMessage) { DisplayUserMessage("CPDLC", "Server", "Logged in!", true, true, false, true, false); @@ -733,7 +733,8 @@ void CSMRPlugin::OnTimer(int Counter) } // Check if logonCode is empty or only whitespace - if (ControllerMyself().IsController() && logonCode.empty() || std::all_of(logonCode.begin(), logonCode.end(), isspace)) { + if (ControllerMyself().IsController() && logonCode.empty() || std::all_of(logonCode.begin(), logonCode.end(), isspace)) + { DisplayUserMessage("CPDLC", "Error", "Logon code is empty. Please set your CPDLC password in the settings.", true, true, false, true, false); isConnecting = false; return; @@ -750,30 +751,31 @@ void CSMRPlugin::OnTimer(int Counter) { DisplayUserMessage("CPDLC", "Error", "Maximum login retries reached. Please check your settings.", true, true, false, true, false); HoppieConnected = false; - loginRetryCount = 0; // Reset after giving up + loginRetryCount = 0; // Reset after giving up nextLoginRetryTime = 0; // Reset next retry time isConnecting = false; return; } + else { DisplayUserMessage("CPDLC", "Error", "You are not logged in as a controller!", true, true, false, true, false); } - - //Auto connection - if (ControllerMyself().IsController() && AutoConnect && !HoppieConnected && !isConnecting) - { - if (loginRetryCount > 0 && nextLoginRetryTime > 0 && time(NULL) < nextLoginRetryTime) + + // Auto connection + /* if (ControllerMyself().IsController() && AutoConnect && !HoppieConnected && !isConnecting) { - return; // Wait for the next retry time + if (loginRetryCount > 0 && nextLoginRetryTime > 0 && time(NULL) < nextLoginRetryTime) + { + return; // Wait for the next retry time + } + else { + isConnecting = true; + _beginthread(datalinkLogin, 0, NULL); + } } else { - isConnecting = true; - _beginthread(datalinkLogin, 0, NULL); - } - } - else { - DisplayUserMessage("CPDLC", "Error", "You are not logged in as a controller!", true, true, false, true, false); - } + DisplayUserMessage("CPDLC", "Error", "You are not logged in as a controller!", true, true, false, true, false); + } */ if (((clock() - timer) / CLOCKS_PER_SEC) > 10 && HoppieConnected) { From f93d6ef7784fd9976a21834456607ef25fb6b2d7 Mon Sep 17 00:00:00 2001 From: Daniel 'MrAdder' Green Date: Sun, 20 Jul 2025 11:27:24 +0100 Subject: [PATCH 9/9] Manual Merge of 56b96d3 Manual Merge of 56b96d3 --- vSMR/SMRPlugin.cpp | 49 +++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/vSMR/SMRPlugin.cpp b/vSMR/SMRPlugin.cpp index 83e5504b5..69aacf6a8 100644 --- a/vSMR/SMRPlugin.cpp +++ b/vSMR/SMRPlugin.cpp @@ -245,42 +245,43 @@ void sendDatalinkClearance(void *arg) messageId++; url += std::to_string(messageId); url += "//R/"; - url += "CLR TO @"; - url += DatalinkToSend.destination; - url += "@ RWY @"; - url += DatalinkToSend.rwy; - url += "@ DEP @"; - url += DatalinkToSend.sid; - url += "@ INIT CLB @"; - url += DatalinkToSend.climb; - url += "@ SQUAWK @"; - url += DatalinkToSend.squawk; - url += "@ "; - if (DatalinkToSend.ctot != "no" && DatalinkToSend.ctot.size() > 3) + if (DatalinkToSend.sid == "CHK" && DatalinkToSend.rwy == "09R") // CPT 09R { - url += "CTOT @"; - url += DatalinkToSend.ctot; - url += "@ "; + url += "@"; + url += DatalinkToSend.callsign; + url += "@ CLRD TO @"; + url += DatalinkToSend.destination; + url += "@ OFF RWY @"; + url += DatalinkToSend.rwy; + url += "@ VIA CPT AFTER DEP CLIMB STRAIGHT AHEAD - AT LON DME 2.0 TURN RIGHT HDG @220@ - CLIMB @6000FT"; } - if (DatalinkToSend.asat != "no" && DatalinkToSend.asat.size() > 3) + else { - url += "TSAT @"; - url += DatalinkToSend.asat; - url += "@ "; + url += "@"; + url += DatalinkToSend.callsign; + url += "@ CLRD TO @"; + url += DatalinkToSend.destination; + url += "@ OFF @"; + url += DatalinkToSend.rwy; + url += "@ VIA @"; + url += DatalinkToSend.sid; + url += "@ INIT CLB @"; + url += DatalinkToSend.climb; } + url += "@ SQUAWK @"; + url += DatalinkToSend.squawk; + url += "@ NEXT FREQ @"; if (DatalinkToSend.freq != "no" && DatalinkToSend.freq.size() > 5) { - url += "WHEN RDY CALL FREQ @"; url += DatalinkToSend.freq; - url += "@"; } else { - url += "WHEN RDY CALL @"; url += myfrequency; - url += "@"; } - url += " IF UNABLE CALL VOICE "; + + url += "@ "; + if (DatalinkToSend.message != "no" && DatalinkToSend.message.size() > 1) url += DatalinkToSend.message;