From d0dfb3fdae236efa7ce8f0ba84e735f58995cceb Mon Sep 17 00:00:00 2001 From: Tin Tin Hamans <5984296+tintinhamans@users.noreply.github.com> Date: Sat, 10 Oct 2026 17:59:06 +0200 Subject: [PATCH 1/4] fix(lanapi): Fix GameInfo memory leaks in LANAPI::OnGameStart(), LANAPI::RequestGameLeave() (#3462) (cherry picked from commit ac4965a0251bbbf28ea11ccdf940356d2865fae2) --- Core/GameEngine/Include/GameNetwork/GameInfo.h | 1 + .../GameEngine/Include/GameNetwork/GameSpy/StagingRoomGameInfo.h | 1 + Core/GameEngine/Include/GameNetwork/LANGameInfo.h | 1 + Core/GameEngine/Source/GameNetwork/LANAPI.cpp | 1 + Core/GameEngine/Source/GameNetwork/LANAPICallbacks.cpp | 1 + Generals/Code/GameEngine/Include/Common/Recorder.h | 1 + Generals/Code/GameEngine/Include/GameNetwork/GameSpyGameInfo.h | 1 + GeneralsMD/Code/GameEngine/Include/Common/Recorder.h | 1 + GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyGameInfo.h | 1 + 9 files changed, 9 insertions(+) diff --git a/Core/GameEngine/Include/GameNetwork/GameInfo.h b/Core/GameEngine/Include/GameNetwork/GameInfo.h index 5483bbeba58..06a44239451 100644 --- a/Core/GameEngine/Include/GameNetwork/GameInfo.h +++ b/Core/GameEngine/Include/GameNetwork/GameInfo.h @@ -302,6 +302,7 @@ class SkirmishGameInfo : public GameInfo, public Snapshot for (Int i = 0; i< MAX_SLOTS; ++i) setSlotPointer(i, &m_skirmishSlot[i]); } + virtual ~SkirmishGameInfo() override {} }; extern SkirmishGameInfo *TheSkirmishGameInfo; diff --git a/Core/GameEngine/Include/GameNetwork/GameSpy/StagingRoomGameInfo.h b/Core/GameEngine/Include/GameNetwork/GameSpy/StagingRoomGameInfo.h index d17569bc807..5ed92588a8b 100644 --- a/Core/GameEngine/Include/GameNetwork/GameSpy/StagingRoomGameInfo.h +++ b/Core/GameEngine/Include/GameNetwork/GameSpy/StagingRoomGameInfo.h @@ -96,6 +96,7 @@ class GameSpyStagingRoom : public GameInfo public: GameSpyStagingRoom(); + virtual ~GameSpyStagingRoom() override {} virtual void reset() override; void cleanUpSlotPointers(); diff --git a/Core/GameEngine/Include/GameNetwork/LANGameInfo.h b/Core/GameEngine/Include/GameNetwork/LANGameInfo.h index 2d0cdbd202a..1296d47dcb4 100644 --- a/Core/GameEngine/Include/GameNetwork/LANGameInfo.h +++ b/Core/GameEngine/Include/GameNetwork/LANGameInfo.h @@ -79,6 +79,7 @@ class LANGameInfo : public GameInfo public: LANGameInfo(); + virtual ~LANGameInfo() override {} void setSlot( Int slotNum, LANGameSlot slotInfo ); ///< Set the slot state (human, open, AI, etc) LANGameSlot* getLANSlot( Int slotNum ); ///< Get the slot const LANGameSlot* getConstLANSlot( Int slotNum ) const; ///< Get the slot diff --git a/Core/GameEngine/Source/GameNetwork/LANAPI.cpp b/Core/GameEngine/Source/GameNetwork/LANAPI.cpp index ef244dd8675..e5d5accb78f 100644 --- a/Core/GameEngine/Source/GameNetwork/LANAPI.cpp +++ b/Core/GameEngine/Source/GameNetwork/LANAPI.cpp @@ -693,6 +693,7 @@ void LANAPI::RequestGameLeave() // Exit out immediately if we're hosting OnPlayerLeave(m_name); removeGame(m_currentGame); + delete m_currentGame; m_currentGame = nullptr; m_inLobby = true; } diff --git a/Core/GameEngine/Source/GameNetwork/LANAPICallbacks.cpp b/Core/GameEngine/Source/GameNetwork/LANAPICallbacks.cpp index 701ef3e987e..5075b7cfba0 100644 --- a/Core/GameEngine/Source/GameNetwork/LANAPICallbacks.cpp +++ b/Core/GameEngine/Source/GameNetwork/LANAPICallbacks.cpp @@ -233,6 +233,7 @@ void LANAPI::OnGameStart() DEBUG_LOG(("After transfer, we didn't really have the map. Bailing...")); OnPlayerLeave(m_name); removeGame(m_currentGame); + delete m_currentGame; m_currentGame = nullptr; m_inLobby = TRUE; diff --git a/Generals/Code/GameEngine/Include/Common/Recorder.h b/Generals/Code/GameEngine/Include/Common/Recorder.h index bd7b030e146..110e58bbc3f 100644 --- a/Generals/Code/GameEngine/Include/Common/Recorder.h +++ b/Generals/Code/GameEngine/Include/Common/Recorder.h @@ -42,6 +42,7 @@ class ReplayGameInfo : public GameInfo for (Int i = 0; i< MAX_SLOTS; ++i) setSlotPointer(i, &m_ReplaySlot[i]); } + virtual ~ReplayGameInfo() override {} }; enum RecorderModeType CPP_11(: Int) { diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpyGameInfo.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpyGameInfo.h index 5d136972f72..9664361f0c4 100644 --- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpyGameInfo.h +++ b/Generals/Code/GameEngine/Include/GameNetwork/GameSpyGameInfo.h @@ -67,6 +67,7 @@ class GameSpyGameInfo : public GameInfo public: GameSpyGameInfo(); + virtual ~GameSpyGameInfo() override {} inline void setServer(SBServer server) { m_server = server; } inline SBServer getServer() { return m_server; } diff --git a/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h b/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h index fba73ad5ec3..1a82d84adfc 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h @@ -44,6 +44,7 @@ class ReplayGameInfo : public GameInfo for (Int i = 0; i< MAX_SLOTS; ++i) setSlotPointer(i, &m_ReplaySlot[i]); } + virtual ~ReplayGameInfo() override {} }; enum RecorderModeType CPP_11(: Int) { diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyGameInfo.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyGameInfo.h index a1acedac598..4b1e8ee7100 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyGameInfo.h +++ b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyGameInfo.h @@ -67,6 +67,7 @@ class GameSpyGameInfo : public GameInfo public: GameSpyGameInfo(); + virtual ~GameSpyGameInfo() override {} inline void setServer(SBServer server) { m_server = server; } inline SBServer getServer() { return m_server; } From f0c531a82a7483c026783711b462dfb314902501 Mon Sep 17 00:00:00 2001 From: Tin Tin Hamans <5984296+tintinhamans@users.noreply.github.com> Date: Mon, 12 Oct 2026 22:23:15 +0200 Subject: [PATCH 2/4] bugfix(network): Close sockets that fail to bind (#3488) (cherry picked from commit 2d6761cc0ff3d53a257f395ac46ef11dbcb8d865) --- Core/GameEngine/Source/GameNetwork/FirewallHelper.cpp | 2 ++ Core/GameEngine/Source/GameNetwork/udp.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Core/GameEngine/Source/GameNetwork/FirewallHelper.cpp b/Core/GameEngine/Source/GameNetwork/FirewallHelper.cpp index 04e5f7166b0..0cb350227bc 100644 --- a/Core/GameEngine/Source/GameNetwork/FirewallHelper.cpp +++ b/Core/GameEngine/Source/GameNetwork/FirewallHelper.cpp @@ -1529,6 +1529,8 @@ Bool FirewallHelperClass::openSpareSocket(UnsignedShort port) { if (m_spareSockets[i].udp->Bind((UnsignedInt)0, port) != 0) { DEBUG_CRASH(("FirewallHelperClass::openSpareSocket - Failed to init spare socket")); + delete m_spareSockets[i].udp; + m_spareSockets[i].udp = nullptr; return FALSE; } diff --git a/Core/GameEngine/Source/GameNetwork/udp.cpp b/Core/GameEngine/Source/GameNetwork/udp.cpp index e5f30ccb795..e3ab907928b 100644 --- a/Core/GameEngine/Source/GameNetwork/udp.cpp +++ b/Core/GameEngine/Source/GameNetwork/udp.cpp @@ -174,6 +174,8 @@ Int UDP::Bind(UnsignedInt IP,UnsignedShort Port) { status=GetStatus(); //CERR("Bind failure (" << status << ") IP " << IP << " PORT " << Port ) + closesocket(fd); + fd=0; return(status); } From 6df9ee2828ef987cbffe12e63e49cf27ed018585 Mon Sep 17 00:00:00 2001 From: Tin Tin Hamans <5984296+tintinhamans@users.noreply.github.com> Date: Thu, 15 Oct 2026 19:02:43 +0200 Subject: [PATCH 3/4] fix(network): Release the disconnect chat message after sending it (#3498) (cherry picked from commit a8464bcffa362652a765966216c5095a41c7764b) --- Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp b/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp index f347db5a83f..6f08930bd3c 100644 --- a/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp +++ b/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp @@ -2509,6 +2509,8 @@ void ConnectionManager::sendDisconnectChat(UnicodeString text) { sendLocalCommandDirect(msg, 0xff ^ (1 << m_localSlot)); processDisconnectChat(msg); + + msg->detach(); } UnsignedShort ConnectionManager::sendFileAnnounce(AsciiString path, UnsignedByte playerMask) From a972880aeec061daf65db8fba45c2ba0ce4aa752 Mon Sep 17 00:00:00 2001 From: Tin Tin Hamans <5984296+tintinhamans@users.noreply.github.com> Date: Thu, 15 Oct 2026 19:03:59 +0200 Subject: [PATCH 4/4] fix(lanapi): Delete the lobby player when they leave the lobby (#3499) (cherry picked from commit 4a4a1b23f4436616e2879d894ade7f30df462453) --- Core/GameEngine/Source/GameNetwork/LANAPIhandlers.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/GameEngine/Source/GameNetwork/LANAPIhandlers.cpp b/Core/GameEngine/Source/GameNetwork/LANAPIhandlers.cpp index 7f88b835f86..6aa2956df0d 100644 --- a/Core/GameEngine/Source/GameNetwork/LANAPIhandlers.cpp +++ b/Core/GameEngine/Source/GameNetwork/LANAPIhandlers.cpp @@ -567,6 +567,7 @@ void LANAPI::handleRequestLobbyLeave( LANMessage *msg, UnsignedInt senderIP ) if (player->getIP() == senderIP) { removePlayer(player); + delete player; OnPlayerList(m_lobbyPlayers); break; }