From 0ec46757e5c0521603b8356499e463ac740e6cfd Mon Sep 17 00:00:00 2001 From: githubawn <115191165+githubawn@users.noreply.github.com> Date: Thu, 30 Jul 2026 21:38:47 +0200 Subject: [PATCH 1/5] refactor(network): Remove obsolete Refresh NAT button and INI state --- .../Include/Common/OptionPreferences.h | 2 - .../Include/GameNetwork/FirewallHelper.h | 37 ++-- .../Source/Common/OptionPreferences.cpp | 29 ---- .../Source/GameNetwork/FirewallHelper.cpp | 161 ++++-------------- .../Source/GameNetwork/GameSpy/PeerDefs.cpp | 8 + Core/GameEngine/Source/GameNetwork/NAT.cpp | 24 +-- .../GameEngine/Include/Common/GlobalData.h | 2 - .../GameEngine/Source/Common/GlobalData.cpp | 6 - .../GUI/GUICallbacks/Menus/OptionsMenu.cpp | 24 +-- .../GUICallbacks/Menus/WOLGameSetupMenu.cpp | 86 +++++++++- .../GUI/GUICallbacks/Menus/WOLLoginMenu.cpp | 6 + .../GUICallbacks/Menus/WOLQuickMatchMenu.cpp | 23 ++- .../GUI/GUICallbacks/Menus/WOLWelcomeMenu.cpp | 21 +-- .../GameEngine/Source/GameNetwork/GameSpy.cpp | 21 +-- .../GameEngine/Include/Common/GlobalData.h | 2 - .../GameEngine/Source/Common/GlobalData.cpp | 5 - .../GUI/GUICallbacks/Menus/OptionsMenu.cpp | 23 +-- .../GUICallbacks/Menus/WOLGameSetupMenu.cpp | 86 +++++++++- .../GUI/GUICallbacks/Menus/WOLLoginMenu.cpp | 6 + .../GUICallbacks/Menus/WOLQuickMatchMenu.cpp | 23 ++- .../GUI/GUICallbacks/Menus/WOLWelcomeMenu.cpp | 21 +-- 21 files changed, 292 insertions(+), 324 deletions(-) diff --git a/Core/GameEngine/Include/Common/OptionPreferences.h b/Core/GameEngine/Include/Common/OptionPreferences.h index 85aba4228be..2b997d2b43a 100644 --- a/Core/GameEngine/Include/Common/OptionPreferences.h +++ b/Core/GameEngine/Include/Common/OptionPreferences.h @@ -84,10 +84,8 @@ class OptionPreferences : public UserPreferences Bool getScreenEdgeScrollEnabledInWindowedApp() const; Bool getScreenEdgeScrollEnabledInFullscreenApp() const; ScreenEdgeScrollMode getScreenEdgeScrollMode() const; - Int getFirewallBehavior(); Short getFirewallPortAllocationDelta(); UnsignedShort getFirewallPortOverride(); - Bool getFirewallNeedToRefresh(); Bool usesSystemMapDir(); AsciiString getPreferred3DProvider(); AsciiString getSpeakerType(); diff --git a/Core/GameEngine/Include/GameNetwork/FirewallHelper.h b/Core/GameEngine/Include/GameNetwork/FirewallHelper.h index 91a8cafdfe3..acc10984ee8 100644 --- a/Core/GameEngine/Include/GameNetwork/FirewallHelper.h +++ b/Core/GameEngine/Include/GameNetwork/FirewallHelper.h @@ -107,6 +107,8 @@ struct ManglerMessage { static const Int MAX_NUM_MANGLERS = 4; static const UnsignedShort MANGLER_PORT = 4321; +static const UnsignedInt BEHAVIOR_DETECTION_WAIT_TIME = 6000; + class FirewallHelperClass { public: @@ -171,20 +173,19 @@ class FirewallHelperClass { FirewallHelperClass(); virtual ~FirewallHelperClass(); Bool detectFirewall(); - UnsignedShort getRawFirewallBehavior() {return((UnsignedShort)m_behavior);} - Short getSourcePortAllocationDelta(); - Int getFirewallHardness(FirewallBehaviorType behavior); - Int getFirewallRetries(FirewallBehaviorType behavior); + void detectFirewallBehavior(); + UnsignedShort getRawFirewallBehavior() const {return((UnsignedShort)m_behavior);} + Short getSourcePortAllocationDelta() const; + Int getFirewallHardness(FirewallBehaviorType behavior) const; + Int getFirewallRetries(FirewallBehaviorType behavior) const; void setSourcePortPoolStart(Int port) {m_sourcePortPool = port;}; - Int getSourcePortPool() {return(m_sourcePortPool);}; - void readFirewallBehavior(); + Int getSourcePortPool() const {return(m_sourcePortPool);}; void reset(); Bool behaviorDetectionUpdate(); - FirewallBehaviorType getFirewallBehavior(); - void writeFirewallBehavior(); + FirewallBehaviorType getFirewallBehavior() const; - void flagNeedToRefresh(Bool flag); + Bool isBehaviorDetectionComplete() const {return(m_currentState == DETECTIONSTATE_DONE);} static void getManglerName(Int manglerIndex, Char *nameBuf); Bool sendToManglerFromPort(UnsignedInt address, UnsignedShort port, UnsignedShort packetID, Bool blitzme = FALSE); @@ -207,26 +208,23 @@ class FirewallHelperClass { /* ** Behavior query functions. */ - Bool isNAT() { + Bool isNAT() const { if (m_behavior == FIREWALL_TYPE_UNKNOWN || (m_behavior & FIREWALL_TYPE_SIMPLE) != 0) { return(FALSE); } return(TRUE); }; - Bool isNAT(FirewallBehaviorType behavior) { + Bool isNAT(FirewallBehaviorType behavior) const { if (behavior == FIREWALL_TYPE_UNKNOWN || (behavior & FIREWALL_TYPE_SIMPLE) != 0) { return(FALSE); } return(TRUE); }; - - private: Int getNATPortAllocationScheme(Int numPorts, UnsignedShort *originalPorts, UnsignedShort *mangledPorts, Bool &relativeDelta, Bool &looksGood); - void detectFirewallBehavior(/*Bool &canRecord*/); Bool getReferencePort(); SpareSocketStruct * findSpareSocketByPort(UnsignedShort port); @@ -239,21 +237,11 @@ class FirewallHelperClass { */ FirewallBehaviorType m_behavior; - /* - ** How did the firewall behave the last time we ran the game. - */ - FirewallBehaviorType m_lastBehavior; - /* ** What is the delta in our firewalls NAT port allocation scheme. */ Int m_sourcePortAllocationDelta; - /* - ** What was the delta the last time we ran? - */ - Int m_lastSourcePortAllocationDelta; - /* ** Source ports used only to discover port allocation patterns. ** Needs to be static so that previous communications with the manglers @@ -287,3 +275,4 @@ class FirewallHelperClass { extern FirewallHelperClass *TheFirewallHelper; FirewallHelperClass * createFirewallHelper(); + diff --git a/Core/GameEngine/Source/Common/OptionPreferences.cpp b/Core/GameEngine/Source/Common/OptionPreferences.cpp index e681ef8b192..8a6fa07ace3 100644 --- a/Core/GameEngine/Source/Common/OptionPreferences.cpp +++ b/Core/GameEngine/Source/Common/OptionPreferences.cpp @@ -451,20 +451,6 @@ Int OptionPreferences::getStaticGameDetail() return TheGameLODManager->getStaticGameLODIndex(it->second); } -Int OptionPreferences::getFirewallBehavior() -{ - OptionPreferences::const_iterator it = find("FirewallBehavior"); - if (it == end()) - return TheGlobalData->m_firewallBehavior; - - Int behavior = atoi(it->second.str()); - if (behavior < 0) - { - behavior = 0; - } - return behavior; -} - Short OptionPreferences::getFirewallPortAllocationDelta() { OptionPreferences::const_iterator it = find("FirewallPortAllocationDelta"); @@ -489,21 +475,6 @@ UnsignedShort OptionPreferences::getFirewallPortOverride() return portOverride; } -Bool OptionPreferences::getFirewallNeedToRefresh() -{ - OptionPreferences::const_iterator it = find("FirewallNeedToRefresh"); - if (it == end()) { - return FALSE; - } - - Bool retval = FALSE; - AsciiString str = it->second; - if (str.compareNoCase("TRUE") == 0) { - retval = TRUE; - } - return retval; -} - AsciiString OptionPreferences::getPreferred3DProvider() { OptionPreferences::const_iterator it = find("3DAudioProvider"); diff --git a/Core/GameEngine/Source/GameNetwork/FirewallHelper.cpp b/Core/GameEngine/Source/GameNetwork/FirewallHelper.cpp index 5698e3f47b0..da030b6e05a 100644 --- a/Core/GameEngine/Source/GameNetwork/FirewallHelper.cpp +++ b/Core/GameEngine/Source/GameNetwork/FirewallHelper.cpp @@ -54,6 +54,7 @@ #include "GameNetwork/NAT.h" #include "GameNetwork/udp.h" #include "GameNetwork/NetworkDefs.h" +#include "GameNetwork/IPEnumeration.h" #include "GameNetwork/GameSpy/GSConfig.h" @@ -61,7 +62,9 @@ FirewallHelperClass *TheFirewallHelper = nullptr; FirewallHelperClass * createFirewallHelper() { - return NEW FirewallHelperClass(); + FirewallHelperClass *helper = NEW FirewallHelperClass(); + helper->detectFirewallBehavior(); + return helper; } @@ -90,9 +93,7 @@ FirewallHelperClass::FirewallHelperClass() m_timeoutLength = 0; m_timeoutStart = 0; m_behavior = FIREWALL_TYPE_UNKNOWN; - m_lastBehavior = FIREWALL_TYPE_UNKNOWN; m_sourcePortAllocationDelta = 0; - m_lastSourcePortAllocationDelta = 0; Int i = 0; for (; i < MAX_SPARE_SOCKETS; ++i) { m_spareSockets[i].port = 0; @@ -154,6 +155,8 @@ void FirewallHelperClass::reset() m_currentState = DETECTIONSTATE_IDLE; for (Int i = 0; i < MAX_SPARE_SOCKETS; ++i) { m_messages[i].length = 0; + m_mangledPorts[i] = 0; + m_sparePorts[i] = 0; } } @@ -176,22 +179,12 @@ void FirewallHelperClass::reset() *=============================================================================================*/ Bool FirewallHelperClass::detectFirewall() { - OptionPreferences pref; - - OptionPreferences::const_iterator it = pref.find("FirewallNeedToRefresh"); - if (it != pref.end()) { - AsciiString str = it->second; - if (str.compareNoCase("TRUE") == 0) { - TheWritableGlobalData->m_firewallBehavior = FIREWALL_TYPE_UNKNOWN; - } - } - - if (TheWritableGlobalData->m_firewallBehavior == FIREWALL_TYPE_UNKNOWN) { + if (m_behavior == FIREWALL_TYPE_UNKNOWN) { detectFirewallBehavior(); return FALSE; } else { - DEBUG_LOG(("FirewallHelperClass::detectFirewall - firewall behavior already specified as %d, port allocation delta is %d, skipping detection.", TheWritableGlobalData->m_firewallBehavior, TheWritableGlobalData->m_firewallPortAllocationDelta)); + DEBUG_LOG(("FirewallHelperClass::detectFirewall - firewall behavior already specified as %d, port allocation delta is %d, skipping detection.", m_behavior, m_sourcePortAllocationDelta)); } return TRUE; @@ -480,93 +473,6 @@ UnsignedShort FirewallHelperClass::getManglerResponse(UnsignedShort packetID, In return mangled_port; } - - - -/*********************************************************************************************** - * FirewallHelperClass::Write_Firewall_Settings -- Save out firewall settings. * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 3/22/01 10:23PM ST : Created * - *=============================================================================================*/ -void FirewallHelperClass::writeFirewallBehavior() -{ - OptionPreferences pref; - - char num[16]; - num[0] = 0; - itoa(TheGlobalData->m_firewallBehavior, num, 10); - AsciiString numstr; - numstr = num; - (pref)["FirewallBehavior"] = numstr; - - TheWritableGlobalData->m_firewallPortAllocationDelta = getSourcePortAllocationDelta(); - num[0] = 0; - itoa(TheGlobalData->m_firewallPortAllocationDelta, num, 10); - numstr = num; - (pref)["FirewallPortAllocationDelta"] = numstr; - - pref.write(); -} - - -/*********************************************************************************************** - * FirewallHelperClass::flagNeedToRefresh -- Flag that the next time we log in we need to * - * refresh our firewall settings. * - * * - * * - * * - * INPUT: flag - whether or not to refresh...munkee * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 2/19/03 4:30PM BGC : Created * - *=============================================================================================*/ -void FirewallHelperClass::flagNeedToRefresh(Bool flag) -{ - OptionPreferences pref; - - (pref)["FirewallNeedToRefresh"] = flag ? "TRUE" : "FALSE"; - - pref.write(); -} - - -/*********************************************************************************************** - * FirewallHelperClass::Read_Firewall_Behavior -- Read in old firewall settings * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 3/22/01 10:25PM ST : Created * - *=============================================================================================*/ -void FirewallHelperClass::readFirewallBehavior() -{ -#if (0) - m_lastBehavior = (FirewallBehaviorType) ConfigINI.Get_Int("MultiPlayer", "FirewallSettings", FIREWALL_UNKNOWN); - m_lastSourcePortAllocationDelta = ConfigINI.Get_Int("MultiPlayer", "FirewallDelta", 1); -#endif //(0) -} - - - /*********************************************************************************************** * FHC::detectFirewallBehavior -- What is that wacky firewall doing to our packet headers? * * * @@ -581,19 +487,27 @@ void FirewallHelperClass::readFirewallBehavior() * HISTORY: * * 3/15/01 12:30PM ST : Created * *=============================================================================================*/ -void FirewallHelperClass::detectFirewallBehavior(/*Bool &canRecord*/) +void FirewallHelperClass::detectFirewallBehavior() { - m_behavior = FIREWALL_TYPE_SIMPLE; + reset(); + m_currentTry = 0; + m_numManglers = 0; + m_numResponses = 0; + m_packetID = 0; + m_timeoutLength = 0; + m_timeoutStart = 0; + + m_sourcePortAllocationDelta = 0; + m_behavior = FIREWALL_TYPE_UNKNOWN; m_currentState = DETECTIONSTATE_BEGIN; } -FirewallHelperClass::FirewallBehaviorType FirewallHelperClass::getFirewallBehavior() { - m_currentState = DETECTIONSTATE_IDLE; +FirewallHelperClass::FirewallBehaviorType FirewallHelperClass::getFirewallBehavior() const { return m_behavior; } -Short FirewallHelperClass::getSourcePortAllocationDelta() { +Short FirewallHelperClass::getSourcePortAllocationDelta() const { return m_sourcePortAllocationDelta; } @@ -608,6 +522,12 @@ Short FirewallHelperClass::getSourcePortAllocationDelta() { Bool FirewallHelperClass::detectionBeginUpdate() { // UnsignedShort mangler_port = MANGLER_PORT; m_packetID = 0x7f00; + + if (TheGameSpyConfig == nullptr) { + DEBUG_LOG(("FirewallHelperClass::detectionBeginUpdate - no GameSpy config, skipping detection.")); + m_currentState = DETECTIONSTATE_DONE; + return TRUE; + } //int current_mangler = 0; /* @@ -731,7 +651,7 @@ Bool FirewallHelperClass::detectionBeginUpdate() { ** Send to the mangler from this port until we get a response. */ m_timeoutStart = timeGetTime(); - m_timeoutLength = 6000; + m_timeoutLength = 3000; sendToManglerFromPort(m_manglers[0], m_sparePorts[0], m_packetID); m_currentState = DETECTIONSTATE_TEST1; @@ -781,7 +701,7 @@ Bool FirewallHelperClass::detectionTest1Update() { ** Send to the mangler from this port until we get a response. */ m_timeoutStart = timeGetTime(); - m_timeoutLength = 6000; + m_timeoutLength = 3000; m_mangledPorts[1] = 0; sendToManglerFromPort(m_manglers[1], m_sparePorts[0], m_packetID+1); @@ -896,7 +816,7 @@ Bool FirewallHelperClass::detectionTest3Update() { ** delay between initial sends due to the timeout in Get_Mangler_Response. */ m_timeoutStart = timeGetTime(); - m_timeoutLength = 12000; + m_timeoutLength = 6000; DEBUG_LOG(("FirewallHelperClass::detectionTest3Update - Sending to %d manglers", NUM_TEST_PORTS)); for (i=0 ; i (int)FIREWALL_TYPE_SIMPLE) { - /* - ** If the delta we got last time we played looks good then use that. - */ - m_sourcePortAllocationDelta = m_lastSourcePortAllocationDelta; - } DEBUG_LOG(("FirewallHelperClass::detectionTest3WaitForResponsesUpdate - didn't get enough responses, using %d as the source port allocation delta, finished test", m_sourcePortAllocationDelta)); m_currentState = DETECTIONSTATE_DONE; return TRUE; @@ -995,13 +909,6 @@ Bool FirewallHelperClass::detectionTest3WaitForResponsesUpdate() { DEBUG_LOG(("FirewallHelperClass::detectionTest3WaitForResponsesUpdate - setting source port delta to %d", delta)); } else { DEBUG_LOG(("FirewallHelperClass::detectionTest3WaitForResponsesUpdate - didn't get a delta value")); - if (m_lastSourcePortAllocationDelta != 0 && (Int)m_lastBehavior > (Int)FIREWALL_TYPE_SIMPLE) { - /* - ** If the delta we got last time we played looks good then use that. - */ - DEBUG_LOG(("FirewallHelperClass::detectionTest3WaitForResponsesUpdate - using the port allocation delta we have from before which is %d", m_lastSourcePortAllocationDelta)); - m_sourcePortAllocationDelta = m_lastSourcePortAllocationDelta; - } ++m_currentTry; m_currentState = DETECTIONSTATE_TEST3; return FALSE; @@ -1041,7 +948,7 @@ Bool FirewallHelperClass::detectionTest3WaitForResponsesUpdate() { ** Get a reference port. */ m_timeoutStart = timeGetTime(); - m_timeoutLength = 4000; + m_timeoutLength = 3000; m_mangledPorts[0] = 0; m_packetID += 10; @@ -1106,7 +1013,7 @@ Bool FirewallHelperClass::detectionTest4Stage1Update() { */ m_packetID++; m_timeoutStart = timeGetTime(); - m_timeoutLength = 4000; + m_timeoutLength = 3000; sendToManglerFromPort(m_manglers[0], m_sparePorts[1], m_packetID); @@ -1369,7 +1276,7 @@ Int FirewallHelperClass::getNATPortAllocationScheme(Int numPorts, UnsignedShort * HISTORY: * * 3/16/01 11:43AM ST : Created * *=============================================================================================*/ -Int FirewallHelperClass::getFirewallHardness(FirewallBehaviorType behavior) +Int FirewallHelperClass::getFirewallHardness(FirewallBehaviorType behavior) const { Int hardness = 0; @@ -1418,7 +1325,7 @@ Int FirewallHelperClass::getFirewallHardness(FirewallBehaviorType behavior) * HISTORY: * * 3/16/01 11:43AM ST : Created * *=============================================================================================*/ -Int FirewallHelperClass::getFirewallRetries(FirewallBehaviorType behavior) +Int FirewallHelperClass::getFirewallRetries(FirewallBehaviorType behavior) const { Int retries = 2; diff --git a/Core/GameEngine/Source/GameNetwork/GameSpy/PeerDefs.cpp b/Core/GameEngine/Source/GameNetwork/GameSpy/PeerDefs.cpp index 60d4be33148..26dbf840603 100644 --- a/Core/GameEngine/Source/GameNetwork/GameSpy/PeerDefs.cpp +++ b/Core/GameEngine/Source/GameNetwork/GameSpy/PeerDefs.cpp @@ -43,6 +43,7 @@ #include "GameNetwork/GameSpy/PersistentStorageThread.h" #include "GameNetwork/GameSpy/GSConfig.h" #include "GameNetwork/GameSpyOverlay.h" +#include "GameNetwork/FirewallHelper.h" #include "GameNetwork/RankPointValue.h" #include "GameLogic/GameLogic.h" @@ -633,6 +634,10 @@ void SetUpGameSpy( const char *motdBuffer, const char *configBuffer ) TheGameSpyConfig = GameSpyConfigInterface::create(configBuffer); + DEBUG_ASSERTCRASH(TheFirewallHelper == nullptr, ("TheFirewallHelper already exists!")); + delete TheFirewallHelper; + TheFirewallHelper = createFirewallHelper(); + TheLadderList = NEW LadderList; ThePinger = PingerInterface::createNewPingerInterface(); @@ -697,6 +702,9 @@ void TearDownGameSpy() delete TheLadderList; TheLadderList = nullptr; + delete TheFirewallHelper; + TheFirewallHelper = nullptr; + delete TheGameSpyConfig; TheGameSpyConfig = nullptr; diff --git a/Core/GameEngine/Source/GameNetwork/NAT.cpp b/Core/GameEngine/Source/GameNetwork/NAT.cpp index f566969ca98..2069af3d850 100644 --- a/Core/GameEngine/Source/GameNetwork/NAT.cpp +++ b/Core/GameEngine/Source/GameNetwork/NAT.cpp @@ -210,9 +210,6 @@ NATStateType NAT::update() { { m_NATState = NATSTATE_DONE; TheEstablishConnectionsMenu->endMenu(); - - delete TheFirewallHelper; - TheFirewallHelper = nullptr; } } else if (m_NATState == NATSTATE_DOCONNECTIONPATHS) { if (allConnectionsDoneThisRound() == TRUE) { @@ -227,10 +224,6 @@ NATStateType NAT::update() { // we're all done, time to go back home. m_NATState = NATSTATE_WAITFORSTATS; - // 2/19/03 BGC - we have successfully negotaited a NAT thingy, so our behavior must be correct - // so therefore we don't need to refresh our NAT even if we previously thought we had to. - TheFirewallHelper->flagNeedToRefresh(FALSE); - s_startStatWaitTime = timeGetTime(); DEBUG_LOG(("NAT::update - done with all connections, woohoo!!")); /* @@ -257,18 +250,7 @@ NATStateType NAT::update() { m_NATState = NATSTATE_FAILED; TheEstablishConnectionsMenu->endMenu(); if (TheFirewallHelper != nullptr) { - // we failed NAT negotiation, perhaps we need to redetect our firewall settings. - // We don't trust the user to do it for themselves so we force them to do it next time - // the log in. - // 2/19/03 - ok, we don't want to do this right away, if the user tries to play in another game - // before they log out and log back in the game won't have a chance at working. - // so we need to simply flag it so that when they log out the firewall behavior gets blown away. - TheFirewallHelper->flagNeedToRefresh(TRUE); -// TheWritableGlobalData->m_firewallBehavior = FirewallHelperClass::FIREWALL_TYPE_UNKNOWN; -// TheFirewallHelper->writeFirewallBehavior(); - - delete TheFirewallHelper; - TheFirewallHelper = nullptr; + TheFirewallHelper->detectFirewallBehavior(); } // we failed to connect, so we don't have to pass on the transport to the network. delete m_transport; @@ -711,7 +693,7 @@ void NAT::sendMangledSourcePort() { } // check to see if we are NAT'd at all. - if ((fwType == 0) || (fwType == FirewallHelperClass::FIREWALL_TYPE_SIMPLE)) { + if (fwType == FirewallHelperClass::FIREWALL_TYPE_SIMPLE) { // no mangling, just return the source port DEBUG_LOG(("NAT::sendMangledSourcePort - no mangling, just using the source port")); sendMangledPortNumberToTarget(sourcePort, targetSlot); @@ -790,7 +772,7 @@ void NAT::processManglerResponse(UnsignedShort mangledPort) { return; } - Short delta = TheGlobalData->m_firewallPortAllocationDelta; + Short delta = (TheFirewallHelper != nullptr) ? TheFirewallHelper->getSourcePortAllocationDelta() : 0; UnsignedShort sourcePort = getSlotPort(m_connectionNodes[m_localNodeNumber].m_slotIndex); UnsignedShort returnPort = 0; diff --git a/Generals/Code/GameEngine/Include/Common/GlobalData.h b/Generals/Code/GameEngine/Include/Common/GlobalData.h index e631654250d..2c503eeb05f 100644 --- a/Generals/Code/GameEngine/Include/Common/GlobalData.h +++ b/Generals/Code/GameEngine/Include/Common/GlobalData.h @@ -323,9 +323,7 @@ class GlobalData : public SubsystemInterface Int m_netMinPlayers; ///< Min players needed to start a net game UnsignedInt m_defaultIP; ///< preferred IP address for LAN - UnsignedInt m_firewallBehavior; ///< Last detected firewall behavior UnsignedInt m_firewallPortOverride; ///< User-specified port to be used - Short m_firewallPortAllocationDelta; ///< the port allocation delta last detected. Int m_baseValuePerSupplyBox; Real m_BuildSpeed; diff --git a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp index f7720c351a2..ae6b9363518 100644 --- a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp @@ -434,9 +434,7 @@ GlobalData* GlobalData::m_theOriginal = nullptr; { "ShellMapOn", INI::parseBool, nullptr, offsetof( GlobalData, m_shellMapOn ) }, { "PlayIntro", INI::parseBool, nullptr, offsetof( GlobalData, m_playIntro ) }, - { "FirewallBehavior", INI::parseInt, nullptr, offsetof( GlobalData, m_firewallBehavior ) }, { "FirewallPortOverride", INI::parseInt, nullptr, offsetof( GlobalData, m_firewallPortOverride ) }, - { "FirewallPortAllocationDelta",INI::parseInt, nullptr, offsetof( GlobalData, m_firewallPortAllocationDelta) }, { "GroupSelectMinSelectSize", INI::parseInt, nullptr, offsetof( GlobalData, m_groupSelectMinSelectSize ) }, { "GroupSelectVolumeBase", INI::parseReal, nullptr, offsetof( GlobalData, m_groupSelectVolumeBase ) }, @@ -936,11 +934,8 @@ GlobalData::GlobalData() m_textureFilteringMode = TextureFilterClass::TextureFilterMode::TEXTURE_FILTER_BILINEAR; m_textureAnisotropyLevel = TextureFilterClass::AnisotropicFilterMode::TEXTURE_FILTER_ANISOTROPIC_2X; -// m_languageFilterPref = false; m_languageFilterPref = true; - m_firewallBehavior = FirewallHelperClass::FIREWALL_TYPE_UNKNOWN; m_firewallPortOverride = 0; - m_firewallPortAllocationDelta = 0; m_loadScreenDemo = FALSE; m_disableRender = false; @@ -1204,7 +1199,6 @@ void GlobalData::parseGameDataDefinition( INI* ini ) TheWritableGlobalData->m_drawScrollAnchor = optionPref.getDrawScrollAnchor(); TheWritableGlobalData->m_moveScrollAnchor = optionPref.getMoveScrollAnchor(); TheWritableGlobalData->m_defaultIP = optionPref.getLANIPAddress(); - TheWritableGlobalData->m_firewallBehavior = optionPref.getFirewallBehavior(); TheWritableGlobalData->m_firewallPortAllocationDelta = optionPref.getFirewallPortAllocationDelta(); TheWritableGlobalData->m_firewallPortOverride = optionPref.getFirewallPortOverride(); diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp index c9a964f49a8..81dd20901da 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp @@ -118,8 +118,6 @@ static GameWindow * checkDrawAnchor = nullptr; static NameKeyType checkMoveAnchorID = NAMEKEY_INVALID; static GameWindow * checkMoveAnchor = nullptr; -static NameKeyType buttonFirewallRefreshID = NAMEKEY_INVALID; -static GameWindow * buttonFirewallRefresh = nullptr; // //static NameKeyType checkAudioHardwareID = NAMEKEY_INVALID; //static GameWindow * checkAudioHardware = nullptr; @@ -937,8 +935,6 @@ void OptionsMenuInit( WindowLayout *layout, void *userData ) checkLanguageFilterID = TheNameKeyGenerator->nameToKey( "OptionsMenu.wnd:CheckLanguageFilter" ); checkLanguageFilter = TheWindowManager->winGetWindowFromId( nullptr, checkLanguageFilterID ); - buttonFirewallRefreshID = TheNameKeyGenerator->nameToKey( "OptionsMenu.wnd:ButtonFirewallRefresh" ); - buttonFirewallRefresh = TheWindowManager->winGetWindowFromId( nullptr, buttonFirewallRefreshID); #if ENABLE_GUI_HACKS // TheSuperHackers @tweak 26/07/2026 The Send Delay feature was obsoleted because it only worked around @@ -946,8 +942,12 @@ void OptionsMenuInit( WindowLayout *layout, void *userData ) GameWindow *checkSendDelay = TheWindowManager->winGetWindowFromId(nullptr, NAMEKEY("OptionsMenu.wnd:CheckSendDelay")); if (checkSendDelay) checkSendDelay->winHide(TRUE); -#endif + // TheSuperHackers @tweak 25/07/2026 Hide the obsolete Refresh NAT button, because NAT detection is now self-healing + GameWindow *buttonFirewallRefresh = TheWindowManager->winGetWindowFromId(nullptr, NAMEKEY("OptionsMenu.wnd:ButtonFirewallRefresh")); + if (buttonFirewallRefresh) + buttonFirewallRefresh->winHide(TRUE); +#endif checkDrawAnchorID = TheNameKeyGenerator->nameToKey( "OptionsMenu.wnd:CheckBoxDrawAnchor" ); checkDrawAnchor = TheWindowManager->winGetWindowFromId( nullptr, checkDrawAnchorID); checkMoveAnchorID = TheNameKeyGenerator->nameToKey( "OptionsMenu.wnd:CheckBoxMoveAnchor" ); @@ -1365,8 +1365,6 @@ void OptionsMenuInit( WindowLayout *layout, void *userData ) if (comboBoxOnlineIP) comboBoxOnlineIP->winEnable(FALSE); - buttonFirewallRefresh->winEnable(FALSE); - if (comboBoxDetail) comboBoxDetail->winEnable(FALSE); @@ -1667,18 +1665,6 @@ WindowMsgHandledType OptionsMenuSystem( GameWindow *window, UnsignedInt msg, (*pref)["UseCameraInReplays"] = "no"; } } - else if (controlID == buttonFirewallRefreshID) - { - // setting the behavior to unknown will force the firewall helper to detect the firewall behavior - // the next time we log into gamespy/WOL/whatever. - char num[16]; - num[0] = 0; - TheWritableGlobalData->m_firewallBehavior = FirewallHelperClass::FIREWALL_TYPE_UNKNOWN; - itoa(TheGlobalData->m_firewallBehavior, num, 10); - AsciiString numstr; - numstr = num; - (*pref)["FirewallBehavior"] = numstr; - } break; } diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp index f0f4b8df4a5..706754d7639 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp @@ -1148,6 +1148,68 @@ static Bool initDone = false; UnsignedInt lastSlotlistTime = 0; UnsignedInt enterTime = 0; Bool initialAcceptEnable = FALSE; + +static FirewallHelperClass::FirewallBehaviorType publishedNATBehavior = FirewallHelperClass::FIREWALL_TYPE_UNKNOWN; +static Bool hasPublishedNATBehavior = FALSE; + +static void republishNATBehaviorIfChanged( void ) +{ + if (!hasPublishedNATBehavior || TheFirewallHelper == nullptr || TheGameSpyInfo == nullptr) + return; + + if (!TheFirewallHelper->isBehaviorDetectionComplete()) + return; + + FirewallHelperClass::FirewallBehaviorType behavior = TheFirewallHelper->getFirewallBehavior(); + if (behavior == publishedNATBehavior) + return; + + GameSpyStagingRoom *game = TheGameSpyInfo->getCurrentStagingRoom(); + if (game == nullptr) + return; + + GameSpyGameSlot *hostSlot = game->getGameSpySlot(0); + if (hostSlot == nullptr) + return; + + if (!TheGameSpyInfo->amIHost() && TheGameSpyPeerMessageQueue == nullptr) + return; + + DEBUG_LOG(("republishNATBehaviorIfChanged - NAT behavior changed from %d to %d, republishing", + publishedNATBehavior, behavior)); + publishedNATBehavior = behavior; + + if (TheGameSpyInfo->amIHost()) + { + hostSlot->setNATBehavior(behavior); + TheGameSpyInfo->setGameOptions(); + WOLDisplaySlotList(); + + if (TheGameSpyPeerMessageQueue) + { + PeerRequest slReq; + slReq.peerRequestType = PeerRequest::PEERREQUEST_UTMROOM; + slReq.UTM.isStagingRoom = TRUE; + slReq.id = "SL/"; + slReq.options = GameInfoToAsciiString(game).str(); + TheGameSpyPeerMessageQueue->addRequest(slReq); + } + } + else + { + AsciiString aName, options; + aName.translate(hostSlot->getName()); + + PeerRequest req; + req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER; + req.UTM.isStagingRoom = TRUE; + req.id = "REQ/"; + req.nick = aName.str(); + options.format("NAT=%d", behavior); + req.options = options.str(); + TheGameSpyPeerMessageQueue->addRequest(req); + } +} //------------------------------------------------------------------------------------------------- /** Initialize the Lan Game Options Menu */ //------------------------------------------------------------------------------------------------- @@ -1208,11 +1270,13 @@ void WOLGameSetupMenuInit( WindowLayout *layout, void *userData ) hostSlot->setAccept(); if (TheGameSpyInfo->amIHost()) { - OptionPreferences natPref; CustomMatchPreferences customPref; hostSlot->setColor( customPref.getPreferredColor() ); hostSlot->setPlayerTemplate( customPref.getPreferredFaction() ); - hostSlot->setNATBehavior((FirewallHelperClass::FirewallBehaviorType)natPref.getFirewallBehavior()); + FirewallHelperClass::FirewallBehaviorType natBehavior = (TheFirewallHelper != nullptr) ? TheFirewallHelper->getFirewallBehavior() : FirewallHelperClass::FIREWALL_TYPE_UNKNOWN; + publishedNATBehavior = natBehavior; + hasPublishedNATBehavior = TRUE; + hostSlot->setNATBehavior(natBehavior); hostSlot->setPingString(TheGameSpyInfo->getPingString()); game->setMap(customPref.getPreferredMap()); @@ -1243,7 +1307,6 @@ void WOLGameSetupMenuInit( WindowLayout *layout, void *userData ) } else { - OptionPreferences natPref; CustomMatchPreferences customPref; AsciiString options; PeerRequest req; @@ -1260,7 +1323,10 @@ void WOLGameSetupMenuInit( WindowLayout *layout, void *userData ) options.format("Color=%d", customPref.getPreferredColor()); req.options = options.str(); TheGameSpyPeerMessageQueue->addRequest(req); - options.format("NAT=%d", natPref.getFirewallBehavior()); + FirewallHelperClass::FirewallBehaviorType natBehavior = (TheFirewallHelper != nullptr) ? TheFirewallHelper->getFirewallBehavior() : FirewallHelperClass::FIREWALL_TYPE_UNKNOWN; + publishedNATBehavior = natBehavior; + hasPublishedNATBehavior = TRUE; + options.format("NAT=%d", natBehavior); req.options = options.str(); TheGameSpyPeerMessageQueue->addRequest(req); options.format("Ping=%s", TheGameSpyInfo->getPingString().str()); @@ -1368,6 +1434,7 @@ void WOLGameSetupMenuShutdown( WindowLayout *layout, void *userData ) TheEstablishConnectionsMenu->endMenu(); } initDone = false; + hasPublishedNATBehavior = FALSE; isShuttingDown = true; @@ -1418,6 +1485,17 @@ void WOLGameSetupMenuUpdate( WindowLayout * layout, void *userData) raiseMessageBoxes = false; } + if (TheFirewallHelper != nullptr) + { + TheFirewallHelper->behaviorDetectionUpdate(); + republishNATBehaviorIfChanged(); + + if (TheFirewallHelper->isBehaviorDetectionComplete() && TheFirewallHelper->getFirewallBehavior() == FirewallHelperClass::FIREWALL_TYPE_UNKNOWN) + { + TheFirewallHelper->detectFirewallBehavior(); + } + } + if (TheShell->isAnimFinished() && !buttonPushed && TheGameSpyPeerMessageQueue) { HandleBuddyResponses(); diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp index 6edaba07101..4d6ecacc211 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp @@ -66,6 +66,7 @@ #include "GameNetwork/GameSpy/PersistentStorageThread.h" #include "GameNetwork/GameSpyOverlay.h" +#include "GameNetwork/FirewallHelper.h" #include "GameNetwork/WOLBrowser/WebBrowser.h" @@ -811,6 +812,11 @@ void WOLLoginMenuUpdate( WindowLayout * layout, void *userData) if(isShuttingDown && TheShell->isAnimFinished() && TheTransitionHandler->isFinished()) shutdownComplete(layout); + if (TheFirewallHelper != nullptr) + { + TheFirewallHelper->behaviorDetectionUpdate(); + } + if (TheShell->isAnimFinished() && !buttonPushed && TheGameSpyPeerMessageQueue) { PingResponse pingResp; diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp index 1f8cbb310d5..47cc7e034df 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp @@ -1042,6 +1042,11 @@ void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData) raiseMessageBoxes = false; } + if (TheFirewallHelper != nullptr) + { + TheFirewallHelper->behaviorDetectionUpdate(); + } + /// @todo: MDC handle disconnects in-game the same way as Custom Match! if (TheShell->isAnimFinished() && !buttonPushed && TheGameSpyPeerMessageQueue) @@ -1573,6 +1578,21 @@ WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt ms } else if ( controlID == buttonStartID ) { + if (TheFirewallHelper != nullptr) + { + if (!TheFirewallHelper->isBehaviorDetectionComplete()) + { + TheGameSpyInfo->addText(TheGameText->fetch("GUI:UnknownConnectionState"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow); + break; + } + else if (TheFirewallHelper->getFirewallBehavior() == FirewallHelperClass::FIREWALL_TYPE_UNKNOWN) + { + TheFirewallHelper->detectFirewallBehavior(); + TheGameSpyInfo->addText(TheGameText->fetch("GUI:UnknownConnectionState"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow); + break; + } + } + PeerRequest req; req.peerRequestType = PeerRequest::PEERREQUEST_STARTQUICKMATCH; req.qmMaps.clear(); @@ -1691,8 +1711,7 @@ WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt ms index = (Int)GadgetComboBoxGetItemData( comboBoxColor, selected ); req.QM.color = index; - OptionPreferences natPref; - req.QM.NAT = natPref.getFirewallBehavior(); + req.QM.NAT = (TheFirewallHelper != nullptr) ? TheFirewallHelper->getFirewallBehavior() : FirewallHelperClass::FIREWALL_TYPE_UNKNOWN; if (ladderIndex) { diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLWelcomeMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLWelcomeMenu.cpp index 403d17c9bea..8b950d2382a 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLWelcomeMenu.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLWelcomeMenu.cpp @@ -489,11 +489,6 @@ void WOLWelcomeMenuInit( WindowLayout *layout, void *userData ) if (TheFirewallHelper == nullptr) { TheFirewallHelper = createFirewallHelper(); } - if (TheFirewallHelper->detectFirewall() == TRUE) { - // don't need to detect firewall, already been done. - delete TheFirewallHelper; - TheFirewallHelper = nullptr; - } /* if (TheGameSpyChat && TheGameSpyChat->isConnected()) @@ -550,9 +545,6 @@ void WOLWelcomeMenuShutdown( WindowLayout *layout, void *userData ) { listboxInfo = nullptr; - delete TheFirewallHelper; - TheFirewallHelper = nullptr; - isShuttingDown = TRUE; // if we are shutting down for an immediate pop, skip the animations @@ -590,18 +582,7 @@ void WOLWelcomeMenuUpdate( WindowLayout * layout, void *userData) if (TheFirewallHelper != nullptr) { - if (TheFirewallHelper->behaviorDetectionUpdate()) - { - TheWritableGlobalData->m_firewallBehavior = TheFirewallHelper->getFirewallBehavior(); - - TheFirewallHelper->writeFirewallBehavior(); - - TheFirewallHelper->flagNeedToRefresh(FALSE); // 2/19/03 BGC, we're done, so we don't need to refresh the NAT anymore. - - // we are now done with the firewall helper - delete TheFirewallHelper; - TheFirewallHelper = nullptr; - } + TheFirewallHelper->behaviorDetectionUpdate(); } if (TheShell->isAnimFinished() && !buttonPushed && TheGameSpyPeerMessageQueue) diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy.cpp index 8fd4ed5c6b4..96cded987da 100644 --- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy.cpp +++ b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy.cpp @@ -283,21 +283,7 @@ void GameSpyChat::update() } if (TheFirewallHelper != nullptr) { - if (TheFirewallHelper->behaviorDetectionUpdate()) { - TheGlobalData->m_firewallBehavior = TheFirewallHelper->getFirewallBehavior(); - OptionPreferences *pref = NEW OptionPreferences; - char num[16]; - num[0] = 0; - itoa(TheGlobalData->m_firewallBehavior, num, 10); - AsciiString numstr; - numstr = num; - (*pref)["FirewallBehavior"] = numstr; - pref->write(); - - // we are now done with the firewall helper - delete TheFirewallHelper; - TheFirewallHelper = nullptr; - } + TheFirewallHelper->behaviorDetectionUpdate(); } UnsignedInt now = timeGetTime(); @@ -773,7 +759,7 @@ static void PlayerUTMCallback(PEER peer, const char * nick, } else if (key == "NAT") { - if ((val >= FirewallHelperClass::FIREWALL_TYPE_SIMPLE) && + if ((val >= FirewallHelperClass::FIREWALL_TYPE_UNKNOWN) && (val <= FirewallHelperClass::FIREWALL_TYPE_DESTINATION_PORT_DELTA)) { slot->setNATBehavior((FirewallHelperClass::FirewallBehaviorType)val); @@ -965,7 +951,8 @@ void JoinRoomCallback(PEER peer, PEERBool success, PEERJoinResult result, RoomTy localIP = ntohl(localIP); // The IP returned from GetLocalChatConnectionAddress is in network byte order. options.format("IP=%d", localIP); peerUTMPlayer(TheGameSpyChat->getPeer(), hostName.str(), "REQ/", options.str(), PEERFalse); - options.format("NAT=%d", TheFirewallHelper->getFirewallBehavior()); + FirewallHelperClass::FirewallBehaviorType natBehavior = (TheFirewallHelper != nullptr) ? TheFirewallHelper->getFirewallBehavior() : FirewallHelperClass::FIREWALL_TYPE_UNKNOWN; + options.format("NAT=%d", natBehavior); peerUTMPlayer(TheGameSpyChat->getPeer(), hostName.str(), "REQ/", options.str(), PEERFalse); // refresh the map cache diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h index 7f484111672..a102e92827c 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h @@ -324,9 +324,7 @@ class GlobalData : public SubsystemInterface Int m_netMinPlayers; ///< Min players needed to start a net game UnsignedInt m_defaultIP; ///< preferred IP address for LAN - UnsignedInt m_firewallBehavior; ///< Last detected firewall behavior UnsignedInt m_firewallPortOverride; ///< User-specified port to be used - Short m_firewallPortAllocationDelta; ///< the port allocation delta last detected. Int m_baseValuePerSupplyBox; Real m_BuildSpeed; diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp index e862cd149d5..07ef2ab30e9 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp @@ -434,9 +434,7 @@ GlobalData* GlobalData::m_theOriginal = nullptr; { "ShellMapOn", INI::parseBool, nullptr, offsetof( GlobalData, m_shellMapOn ) }, { "PlayIntro", INI::parseBool, nullptr, offsetof( GlobalData, m_playIntro ) }, - { "FirewallBehavior", INI::parseInt, nullptr, offsetof( GlobalData, m_firewallBehavior ) }, { "FirewallPortOverride", INI::parseInt, nullptr, offsetof( GlobalData, m_firewallPortOverride ) }, - { "FirewallPortAllocationDelta",INI::parseInt, nullptr, offsetof( GlobalData, m_firewallPortAllocationDelta) }, { "GroupSelectMinSelectSize", INI::parseInt, nullptr, offsetof( GlobalData, m_groupSelectMinSelectSize ) }, { "GroupSelectVolumeBase", INI::parseReal, nullptr, offsetof( GlobalData, m_groupSelectVolumeBase ) }, @@ -945,9 +943,7 @@ GlobalData::GlobalData() // m_languageFilterPref = false; m_languageFilterPref = true; - m_firewallBehavior = FirewallHelperClass::FIREWALL_TYPE_UNKNOWN; m_firewallPortOverride = 0; - m_firewallPortAllocationDelta = 0; m_loadScreenDemo = FALSE; m_disableRender = false; @@ -1211,7 +1207,6 @@ void GlobalData::parseGameDataDefinition( INI* ini ) TheWritableGlobalData->m_drawScrollAnchor = optionPref.getDrawScrollAnchor(); TheWritableGlobalData->m_moveScrollAnchor = optionPref.getMoveScrollAnchor(); TheWritableGlobalData->m_defaultIP = optionPref.getLANIPAddress(); - TheWritableGlobalData->m_firewallBehavior = optionPref.getFirewallBehavior(); TheWritableGlobalData->m_firewallPortAllocationDelta = optionPref.getFirewallPortAllocationDelta(); TheWritableGlobalData->m_firewallPortOverride = optionPref.getFirewallPortOverride(); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp index 5fa7a3f8a6c..d34b1f4c95a 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp @@ -124,8 +124,6 @@ static GameWindow * checkDrawAnchor = nullptr; static NameKeyType checkMoveAnchorID = NAMEKEY_INVALID; static GameWindow * checkMoveAnchor = nullptr; -static NameKeyType buttonFirewallRefreshID = NAMEKEY_INVALID; -static GameWindow * buttonFirewallRefresh = nullptr; // //static NameKeyType checkAudioHardwareID = NAMEKEY_INVALID; //static GameWindow * checkAudioHardware = nullptr; @@ -967,8 +965,6 @@ void OptionsMenuInit( WindowLayout *layout, void *userData ) checkLanguageFilterID = TheNameKeyGenerator->nameToKey( "OptionsMenu.wnd:CheckLanguageFilter" ); checkLanguageFilter = TheWindowManager->winGetWindowFromId( nullptr, checkLanguageFilterID ); - buttonFirewallRefreshID = TheNameKeyGenerator->nameToKey( "OptionsMenu.wnd:ButtonFirewallRefresh" ); - buttonFirewallRefresh = TheWindowManager->winGetWindowFromId( nullptr, buttonFirewallRefreshID); #if ENABLE_GUI_HACKS // TheSuperHackers @tweak 26/07/2026 The Send Delay feature was obsoleted because it only worked around @@ -976,6 +972,11 @@ void OptionsMenuInit( WindowLayout *layout, void *userData ) GameWindow *checkSendDelay = TheWindowManager->winGetWindowFromId(nullptr, NAMEKEY("OptionsMenu.wnd:CheckSendDelay")); if (checkSendDelay) checkSendDelay->winHide(TRUE); + + // TheSuperHackers @tweak 25/07/2026 Hide the obsolete Refresh NAT button, because NAT detection is now self-healing + GameWindow *buttonFirewallRefresh = TheWindowManager->winGetWindowFromId(nullptr, NAMEKEY("OptionsMenu.wnd:ButtonFirewallRefresh")); + if (buttonFirewallRefresh) + buttonFirewallRefresh->winHide(TRUE); #endif checkDrawAnchorID = TheNameKeyGenerator->nameToKey( "OptionsMenu.wnd:CheckBoxDrawAnchor" ); @@ -1402,8 +1403,6 @@ void OptionsMenuInit( WindowLayout *layout, void *userData ) if (comboBoxOnlineIP) comboBoxOnlineIP->winEnable(FALSE); - buttonFirewallRefresh->winEnable(FALSE); - if (comboBoxDetail) comboBoxDetail->winEnable(FALSE); @@ -1704,18 +1703,6 @@ WindowMsgHandledType OptionsMenuSystem( GameWindow *window, UnsignedInt msg, (*pref)["UseCameraInReplays"] = "no"; } } - else if (controlID == buttonFirewallRefreshID) - { - // setting the behavior to unknown will force the firewall helper to detect the firewall behavior - // the next time we log into gamespy/WOL/whatever. - char num[16]; - num[0] = 0; - TheWritableGlobalData->m_firewallBehavior = FirewallHelperClass::FIREWALL_TYPE_UNKNOWN; - itoa(TheGlobalData->m_firewallBehavior, num, 10); - AsciiString numstr; - numstr = num; - (*pref)["FirewallBehavior"] = numstr; - } break; } diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp index f360ba9423b..359b318dfd0 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp @@ -1305,6 +1305,68 @@ static Bool initDone = false; UnsignedInt lastSlotlistTime = 0; UnsignedInt enterTime = 0; Bool initialAcceptEnable = FALSE; + +static FirewallHelperClass::FirewallBehaviorType publishedNATBehavior = FirewallHelperClass::FIREWALL_TYPE_UNKNOWN; +static Bool hasPublishedNATBehavior = FALSE; + +static void republishNATBehaviorIfChanged( void ) +{ + if (!hasPublishedNATBehavior || TheFirewallHelper == nullptr || TheGameSpyInfo == nullptr) + return; + + if (!TheFirewallHelper->isBehaviorDetectionComplete()) + return; + + FirewallHelperClass::FirewallBehaviorType behavior = TheFirewallHelper->getFirewallBehavior(); + if (behavior == publishedNATBehavior) + return; + + GameSpyStagingRoom *game = TheGameSpyInfo->getCurrentStagingRoom(); + if (game == nullptr) + return; + + GameSpyGameSlot *hostSlot = game->getGameSpySlot(0); + if (hostSlot == nullptr) + return; + + if (!TheGameSpyInfo->amIHost() && TheGameSpyPeerMessageQueue == nullptr) + return; + + DEBUG_LOG(("republishNATBehaviorIfChanged - NAT behavior changed from %d to %d, republishing", + publishedNATBehavior, behavior)); + publishedNATBehavior = behavior; + + if (TheGameSpyInfo->amIHost()) + { + hostSlot->setNATBehavior(behavior); + TheGameSpyInfo->setGameOptions(); + WOLDisplaySlotList(); + + if (TheGameSpyPeerMessageQueue) + { + PeerRequest slReq; + slReq.peerRequestType = PeerRequest::PEERREQUEST_UTMROOM; + slReq.UTM.isStagingRoom = TRUE; + slReq.id = "SL/"; + slReq.options = GameInfoToAsciiString(game).str(); + TheGameSpyPeerMessageQueue->addRequest(slReq); + } + } + else + { + AsciiString aName, options; + aName.translate(hostSlot->getName()); + + PeerRequest req; + req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER; + req.UTM.isStagingRoom = TRUE; + req.id = "REQ/"; + req.nick = aName.str(); + options.format("NAT=%d", behavior); + req.options = options.str(); + TheGameSpyPeerMessageQueue->addRequest(req); + } +} //------------------------------------------------------------------------------------------------- /** Initialize the Lan Game Options Menu */ //------------------------------------------------------------------------------------------------- @@ -1365,11 +1427,13 @@ void WOLGameSetupMenuInit( WindowLayout *layout, void *userData ) hostSlot->setAccept(); if (TheGameSpyInfo->amIHost()) { - OptionPreferences natPref; CustomMatchPreferences customPref; hostSlot->setColor( customPref.getPreferredColor() ); hostSlot->setPlayerTemplate( customPref.getPreferredFaction() ); - hostSlot->setNATBehavior((FirewallHelperClass::FirewallBehaviorType)natPref.getFirewallBehavior()); + FirewallHelperClass::FirewallBehaviorType natBehavior = (TheFirewallHelper != nullptr) ? TheFirewallHelper->getFirewallBehavior() : FirewallHelperClass::FIREWALL_TYPE_UNKNOWN; + publishedNATBehavior = natBehavior; + hasPublishedNATBehavior = TRUE; + hostSlot->setNATBehavior(natBehavior); hostSlot->setPingString(TheGameSpyInfo->getPingString()); game->setMap(customPref.getPreferredMap()); @@ -1420,7 +1484,6 @@ void WOLGameSetupMenuInit( WindowLayout *layout, void *userData ) } else { - OptionPreferences natPref; CustomMatchPreferences customPref; AsciiString options; PeerRequest req; @@ -1437,7 +1500,10 @@ void WOLGameSetupMenuInit( WindowLayout *layout, void *userData ) options.format("Color=%d", customPref.getPreferredColor()); req.options = options.str(); TheGameSpyPeerMessageQueue->addRequest(req); - options.format("NAT=%d", natPref.getFirewallBehavior()); + FirewallHelperClass::FirewallBehaviorType natBehavior = (TheFirewallHelper != nullptr) ? TheFirewallHelper->getFirewallBehavior() : FirewallHelperClass::FIREWALL_TYPE_UNKNOWN; + publishedNATBehavior = natBehavior; + hasPublishedNATBehavior = TRUE; + options.format("NAT=%d", natBehavior); req.options = options.str(); TheGameSpyPeerMessageQueue->addRequest(req); options.format("Ping=%s", TheGameSpyInfo->getPingString().str()); @@ -1547,6 +1613,7 @@ void WOLGameSetupMenuShutdown( WindowLayout *layout, void *userData ) TheEstablishConnectionsMenu->endMenu(); } initDone = false; + hasPublishedNATBehavior = FALSE; isShuttingDown = true; @@ -1597,6 +1664,17 @@ void WOLGameSetupMenuUpdate( WindowLayout * layout, void *userData) raiseMessageBoxes = false; } + if (TheFirewallHelper != nullptr) + { + TheFirewallHelper->behaviorDetectionUpdate(); + republishNATBehaviorIfChanged(); + + if (TheFirewallHelper->isBehaviorDetectionComplete() && TheFirewallHelper->getFirewallBehavior() == FirewallHelperClass::FIREWALL_TYPE_UNKNOWN) + { + TheFirewallHelper->detectFirewallBehavior(); + } + } + if (TheShell->isAnimFinished() && !buttonPushed && TheGameSpyPeerMessageQueue) { HandleBuddyResponses(); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp index 25d49d2daa2..0cf9d06be13 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp @@ -66,6 +66,7 @@ #include "GameNetwork/GameSpy/PersistentStorageThread.h" #include "GameNetwork/GameSpyOverlay.h" +#include "GameNetwork/FirewallHelper.h" #include "GameNetwork/WOLBrowser/WebBrowser.h" @@ -811,6 +812,11 @@ void WOLLoginMenuUpdate( WindowLayout * layout, void *userData) if(isShuttingDown && TheShell->isAnimFinished() && TheTransitionHandler->isFinished()) shutdownComplete(layout); + if (TheFirewallHelper != nullptr) + { + TheFirewallHelper->behaviorDetectionUpdate(); + } + if (TheShell->isAnimFinished() && !buttonPushed && TheGameSpyPeerMessageQueue) { PingResponse pingResp; diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp index 977f72e5a87..d9da80fe319 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp @@ -1021,6 +1021,11 @@ void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData) raiseMessageBoxes = false; } + if (TheFirewallHelper != nullptr) + { + TheFirewallHelper->behaviorDetectionUpdate(); + } + /// @todo: MDC handle disconnects in-game the same way as Custom Match! if (TheShell->isAnimFinished() && !buttonPushed && TheGameSpyPeerMessageQueue) @@ -1638,6 +1643,21 @@ WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt ms } else if ( controlID == buttonStartID ) { + if (TheFirewallHelper != nullptr) + { + if (!TheFirewallHelper->isBehaviorDetectionComplete()) + { + TheGameSpyInfo->addText(TheGameText->fetch("GUI:UnknownConnectionState"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow); + break; + } + else if (TheFirewallHelper->getFirewallBehavior() == FirewallHelperClass::FIREWALL_TYPE_UNKNOWN) + { + TheFirewallHelper->detectFirewallBehavior(); + TheGameSpyInfo->addText(TheGameText->fetch("GUI:UnknownConnectionState"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow); + break; + } + } + PeerRequest req; req.peerRequestType = PeerRequest::PEERREQUEST_STARTQUICKMATCH; req.qmMaps.clear(); @@ -1756,8 +1776,7 @@ WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt ms index = (Int)GadgetComboBoxGetItemData( comboBoxColor, selected ); req.QM.color = index; - OptionPreferences natPref; - req.QM.NAT = natPref.getFirewallBehavior(); + req.QM.NAT = (TheFirewallHelper != nullptr) ? TheFirewallHelper->getFirewallBehavior() : FirewallHelperClass::FIREWALL_TYPE_UNKNOWN; if (ladderIndex) { diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLWelcomeMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLWelcomeMenu.cpp index c84a8fd559e..ed18907163b 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLWelcomeMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLWelcomeMenu.cpp @@ -506,11 +506,6 @@ void WOLWelcomeMenuInit( WindowLayout *layout, void *userData ) if (TheFirewallHelper == nullptr) { TheFirewallHelper = createFirewallHelper(); } - if (TheFirewallHelper->detectFirewall() == TRUE) { - // don't need to detect firewall, already been done. - delete TheFirewallHelper; - TheFirewallHelper = nullptr; - } /* if (TheGameSpyChat && TheGameSpyChat->isConnected()) @@ -567,9 +562,6 @@ void WOLWelcomeMenuShutdown( WindowLayout *layout, void *userData ) { listboxInfo = nullptr; - delete TheFirewallHelper; - TheFirewallHelper = nullptr; - isShuttingDown = TRUE; // if we are shutting down for an immediate pop, skip the animations @@ -607,18 +599,7 @@ void WOLWelcomeMenuUpdate( WindowLayout * layout, void *userData) if (TheFirewallHelper != nullptr) { - if (TheFirewallHelper->behaviorDetectionUpdate()) - { - TheWritableGlobalData->m_firewallBehavior = TheFirewallHelper->getFirewallBehavior(); - - TheFirewallHelper->writeFirewallBehavior(); - - TheFirewallHelper->flagNeedToRefresh(FALSE); // 2/19/03 BGC, we're done, so we don't need to refresh the NAT anymore. - - // we are now done with the firewall helper - delete TheFirewallHelper; - TheFirewallHelper = nullptr; - } + TheFirewallHelper->behaviorDetectionUpdate(); } if (TheShell->isAnimFinished() && !buttonPushed && TheGameSpyPeerMessageQueue) From 45476e96f61292aa33a0349579261d1b2cbef740 Mon Sep 17 00:00:00 2001 From: githubawn <115191165+githubawn@users.noreply.github.com> Date: Thu, 30 Jul 2026 21:55:55 +0200 Subject: [PATCH 2/5] greptile feedback and fix compile after rebase --- Core/GameEngine/Include/GameNetwork/FirewallHelper.h | 2 ++ .../GameEngine/Source/GameNetwork/FirewallHelper.cpp | 12 ++++++++++++ .../GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp | 2 -- .../GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp | 2 -- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Core/GameEngine/Include/GameNetwork/FirewallHelper.h b/Core/GameEngine/Include/GameNetwork/FirewallHelper.h index acc10984ee8..4026db5e847 100644 --- a/Core/GameEngine/Include/GameNetwork/FirewallHelper.h +++ b/Core/GameEngine/Include/GameNetwork/FirewallHelper.h @@ -269,6 +269,8 @@ class FirewallHelperClass { Int m_numResponses; Int m_currentTry; + Int m_detectionRetries; + UnsignedInt m_lastDetectionTime; }; diff --git a/Core/GameEngine/Source/GameNetwork/FirewallHelper.cpp b/Core/GameEngine/Source/GameNetwork/FirewallHelper.cpp index da030b6e05a..7c6955d7032 100644 --- a/Core/GameEngine/Source/GameNetwork/FirewallHelper.cpp +++ b/Core/GameEngine/Source/GameNetwork/FirewallHelper.cpp @@ -87,6 +87,8 @@ FirewallHelperClass * createFirewallHelper() FirewallHelperClass::FirewallHelperClass() { m_currentTry = 0; + m_detectionRetries = 0; + m_lastDetectionTime = 0; m_numManglers = 0; m_numResponses = 0; m_packetID = 0; @@ -489,6 +491,16 @@ UnsignedShort FirewallHelperClass::getManglerResponse(UnsignedShort packetID, In *=============================================================================================*/ void FirewallHelperClass::detectFirewallBehavior() { + UnsignedInt currentTime = timeGetTime(); + if (m_detectionRetries >= 5) { + return; + } + if (m_lastDetectionTime != 0 && (currentTime - m_lastDetectionTime) < 5000) { + return; + } + m_lastDetectionTime = currentTime; + m_detectionRetries++; + reset(); m_currentTry = 0; m_numManglers = 0; diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp index 706754d7639..a0b5992b3de 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp @@ -1175,8 +1175,6 @@ static void republishNATBehaviorIfChanged( void ) if (!TheGameSpyInfo->amIHost() && TheGameSpyPeerMessageQueue == nullptr) return; - DEBUG_LOG(("republishNATBehaviorIfChanged - NAT behavior changed from %d to %d, republishing", - publishedNATBehavior, behavior)); publishedNATBehavior = behavior; if (TheGameSpyInfo->amIHost()) diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp index 359b318dfd0..43e24e36c01 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp @@ -1332,8 +1332,6 @@ static void republishNATBehaviorIfChanged( void ) if (!TheGameSpyInfo->amIHost() && TheGameSpyPeerMessageQueue == nullptr) return; - DEBUG_LOG(("republishNATBehaviorIfChanged - NAT behavior changed from %d to %d, republishing", - publishedNATBehavior, behavior)); publishedNATBehavior = behavior; if (TheGameSpyInfo->amIHost()) From 67e170ec39bb8ffb76235f133c592a70d1b1f44e Mon Sep 17 00:00:00 2001 From: githubawn <115191165+githubawn@users.noreply.github.com> Date: Thu, 30 Jul 2026 22:05:10 +0200 Subject: [PATCH 3/5] really fix build now --- .../Include/Common/OptionPreferences.h | 3 +-- .../Source/Common/OptionPreferences.cpp | 24 ------------------- .../GameEngine/Source/Common/GlobalData.cpp | 2 -- .../GameEngine/Source/Common/GlobalData.cpp | 2 -- 4 files changed, 1 insertion(+), 30 deletions(-) diff --git a/Core/GameEngine/Include/Common/OptionPreferences.h b/Core/GameEngine/Include/Common/OptionPreferences.h index 2b997d2b43a..9bf94f0bfb1 100644 --- a/Core/GameEngine/Include/Common/OptionPreferences.h +++ b/Core/GameEngine/Include/Common/OptionPreferences.h @@ -84,8 +84,7 @@ class OptionPreferences : public UserPreferences Bool getScreenEdgeScrollEnabledInWindowedApp() const; Bool getScreenEdgeScrollEnabledInFullscreenApp() const; ScreenEdgeScrollMode getScreenEdgeScrollMode() const; - Short getFirewallPortAllocationDelta(); - UnsignedShort getFirewallPortOverride(); + Bool usesSystemMapDir(); AsciiString getPreferred3DProvider(); AsciiString getSpeakerType(); diff --git a/Core/GameEngine/Source/Common/OptionPreferences.cpp b/Core/GameEngine/Source/Common/OptionPreferences.cpp index 8a6fa07ace3..d41cbfcd8d6 100644 --- a/Core/GameEngine/Source/Common/OptionPreferences.cpp +++ b/Core/GameEngine/Source/Common/OptionPreferences.cpp @@ -451,30 +451,6 @@ Int OptionPreferences::getStaticGameDetail() return TheGameLODManager->getStaticGameLODIndex(it->second); } -Short OptionPreferences::getFirewallPortAllocationDelta() -{ - OptionPreferences::const_iterator it = find("FirewallPortAllocationDelta"); - if (it == end()) { - return TheGlobalData->m_firewallPortAllocationDelta; - } - - Short delta = atoi(it->second.str()); - return delta; -} - -UnsignedShort OptionPreferences::getFirewallPortOverride() -{ - OptionPreferences::const_iterator it = find("FirewallPortOverride"); - if (it == end()) { - return TheGlobalData->m_firewallPortOverride; - } - - Int portOverride = atoi(it->second.str()); - if (portOverride < 0 || portOverride > 65535) - portOverride = 0; - return portOverride; -} - AsciiString OptionPreferences::getPreferred3DProvider() { OptionPreferences::const_iterator it = find("3DAudioProvider"); diff --git a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp index ae6b9363518..15754aa8b48 100644 --- a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp @@ -1199,8 +1199,6 @@ void GlobalData::parseGameDataDefinition( INI* ini ) TheWritableGlobalData->m_drawScrollAnchor = optionPref.getDrawScrollAnchor(); TheWritableGlobalData->m_moveScrollAnchor = optionPref.getMoveScrollAnchor(); TheWritableGlobalData->m_defaultIP = optionPref.getLANIPAddress(); - TheWritableGlobalData->m_firewallPortAllocationDelta = optionPref.getFirewallPortAllocationDelta(); - TheWritableGlobalData->m_firewallPortOverride = optionPref.getFirewallPortOverride(); TheWritableGlobalData->m_saveCameraInReplay = optionPref.saveCameraInReplays(); TheWritableGlobalData->m_useCameraInReplay = optionPref.useCameraInReplays(); diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp index 07ef2ab30e9..be8bd8b5835 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp @@ -1207,8 +1207,6 @@ void GlobalData::parseGameDataDefinition( INI* ini ) TheWritableGlobalData->m_drawScrollAnchor = optionPref.getDrawScrollAnchor(); TheWritableGlobalData->m_moveScrollAnchor = optionPref.getMoveScrollAnchor(); TheWritableGlobalData->m_defaultIP = optionPref.getLANIPAddress(); - TheWritableGlobalData->m_firewallPortAllocationDelta = optionPref.getFirewallPortAllocationDelta(); - TheWritableGlobalData->m_firewallPortOverride = optionPref.getFirewallPortOverride(); TheWritableGlobalData->m_saveCameraInReplay = optionPref.saveCameraInReplays(); TheWritableGlobalData->m_useCameraInReplay = optionPref.useCameraInReplays(); From 02fcd7573d7e8b574a20489faa8a0aa46fa71b1a Mon Sep 17 00:00:00 2001 From: githubawn <115191165+githubawn@users.noreply.github.com> Date: Thu, 30 Jul 2026 22:08:36 +0200 Subject: [PATCH 4/5] remove retry limit --- Core/GameEngine/Include/GameNetwork/FirewallHelper.h | 1 - Core/GameEngine/Source/GameNetwork/FirewallHelper.cpp | 5 ----- 2 files changed, 6 deletions(-) diff --git a/Core/GameEngine/Include/GameNetwork/FirewallHelper.h b/Core/GameEngine/Include/GameNetwork/FirewallHelper.h index 4026db5e847..929daad7efe 100644 --- a/Core/GameEngine/Include/GameNetwork/FirewallHelper.h +++ b/Core/GameEngine/Include/GameNetwork/FirewallHelper.h @@ -269,7 +269,6 @@ class FirewallHelperClass { Int m_numResponses; Int m_currentTry; - Int m_detectionRetries; UnsignedInt m_lastDetectionTime; }; diff --git a/Core/GameEngine/Source/GameNetwork/FirewallHelper.cpp b/Core/GameEngine/Source/GameNetwork/FirewallHelper.cpp index 7c6955d7032..f3062ae5f75 100644 --- a/Core/GameEngine/Source/GameNetwork/FirewallHelper.cpp +++ b/Core/GameEngine/Source/GameNetwork/FirewallHelper.cpp @@ -87,7 +87,6 @@ FirewallHelperClass * createFirewallHelper() FirewallHelperClass::FirewallHelperClass() { m_currentTry = 0; - m_detectionRetries = 0; m_lastDetectionTime = 0; m_numManglers = 0; m_numResponses = 0; @@ -492,14 +491,10 @@ UnsignedShort FirewallHelperClass::getManglerResponse(UnsignedShort packetID, In void FirewallHelperClass::detectFirewallBehavior() { UnsignedInt currentTime = timeGetTime(); - if (m_detectionRetries >= 5) { - return; - } if (m_lastDetectionTime != 0 && (currentTime - m_lastDetectionTime) < 5000) { return; } m_lastDetectionTime = currentTime; - m_detectionRetries++; reset(); m_currentTry = 0; From 3ab259f42e2108b94b040960699ffa614a7c694c Mon Sep 17 00:00:00 2001 From: githubawn <115191165+githubawn@users.noreply.github.com> Date: Thu, 30 Jul 2026 22:17:33 +0200 Subject: [PATCH 5/5] another grepfile round --- .../GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp | 10 ++++++++++ .../GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp index a0b5992b3de..59a01113520 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp @@ -2292,6 +2292,16 @@ void WOLGameSetupMenuUpdate( WindowLayout * layout, void *userData) DEBUG_LOG(("Slot value is color=%d, PlayerTemplate=%d, startPos=%d, team=%d, IP=0x%8.8X", slot->getColor(), slot->getPlayerTemplate(), slot->getStartPos(), slot->getTeamNumber(), slot->getIP())); DEBUG_LOG(("Slot list updated to %s", GameInfoToAsciiString(game).str())); + + if (TheGameSpyInfo->amIHost() && TheGameSpyPeerMessageQueue) + { + PeerRequest slReq; + slReq.peerRequestType = PeerRequest::PEERREQUEST_UTMROOM; + slReq.UTM.isStagingRoom = TRUE; + slReq.id = "SL/"; + slReq.options = GameInfoToAsciiString(game).str(); + TheGameSpyPeerMessageQueue->addRequest(slReq); + } } } } diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp index 43e24e36c01..04cf4c25ce4 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp @@ -2480,6 +2480,16 @@ void WOLGameSetupMenuUpdate( WindowLayout * layout, void *userData) DEBUG_LOG(("Slot value is color=%d, PlayerTemplate=%d, startPos=%d, team=%d, IP=0x%8.8X", slot->getColor(), slot->getPlayerTemplate(), slot->getStartPos(), slot->getTeamNumber(), slot->getIP())); DEBUG_LOG(("Slot list updated to %s", GameInfoToAsciiString(game).str())); + + if (TheGameSpyInfo->amIHost() && TheGameSpyPeerMessageQueue) + { + PeerRequest slReq; + slReq.peerRequestType = PeerRequest::PEERREQUEST_UTMROOM; + slReq.UTM.isStagingRoom = TRUE; + slReq.id = "SL/"; + slReq.options = GameInfoToAsciiString(game).str(); + TheGameSpyPeerMessageQueue->addRequest(slReq); + } } } }