From 1477b8c69ec3962cfacbd13f04b056c4f68e9b9c Mon Sep 17 00:00:00 2001 From: KebsCS Date: Sat, 7 Sep 2024 17:44:02 +0200 Subject: [PATCH] Fix dummy disconnecting on hot reload --- src/engine/client/client.cpp | 32 ++++++++++++++++++++++++++-- src/engine/client/client.h | 2 ++ src/engine/server/server.cpp | 18 +++++++++++++--- src/engine/server/server.h | 2 ++ src/engine/shared/protocol_ex_msgs.h | 1 + 5 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 108bfcaf1..1a857c369 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -762,6 +762,8 @@ void CClient::DummyDisconnect(const char *pReason) m_aReceivedSnapshots[1] = 0; m_DummyConnected = false; m_DummyConnecting = false; + m_DummyReconnectOnReload = false; + m_DummyDeactivateOnReconnect = false; GameClient()->OnDummyDisconnect(); } @@ -1520,7 +1522,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket, int Conn, bool Dummy) } } - if(m_DummyConnected) + if(m_DummyConnected && !m_DummyReconnectOnReload) { DummyDisconnect(0); } @@ -1649,9 +1651,25 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket, int Conn, bool Dummy) } } } + else if(Conn == CONN_MAIN && (pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_MAP_RELOAD) + { + if(m_DummyConnected) + { + m_DummyReconnectOnReload = true; + m_DummyDeactivateOnReconnect = g_Config.m_ClDummy == 0; + g_Config.m_ClDummy = 0; + } + else + m_DummyDeactivateOnReconnect = false; + } else if(Conn == CONN_MAIN && (pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_CON_READY) { GameClient()->OnConnected(); + if(m_DummyReconnectOnReload) + { + m_DummySendConnInfo = true; + m_DummyReconnectOnReload = false; + } } else if(Conn == CONN_DUMMY && Msg == NETMSG_CON_READY) { @@ -1659,7 +1677,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket, int Conn, bool Dummy) m_DummyConnecting = false; g_Config.m_ClDummy = 1; Rcon("crashmeplx"); - if(m_aRconAuthed[0]) + if(m_aRconAuthed[0] && !m_aRconAuthed[1]) RconAuth(m_aRconUsername, m_aRconPassword); } else if(Msg == NETMSG_PING) @@ -2746,6 +2764,16 @@ void CClient::Update() } } + if(m_DummyDeactivateOnReconnect && g_Config.m_ClDummy == 1) + { + m_DummyDeactivateOnReconnect = false; + g_Config.m_ClDummy = 0; + } + else if(!m_DummyConnected && m_DummyDeactivateOnReconnect) + { + m_DummyDeactivateOnReconnect = false; + } + m_LastDummy = (bool)g_Config.m_ClDummy; } diff --git a/src/engine/client/client.h b/src/engine/client/client.h index b272f8eaa..6113c4acf 100644 --- a/src/engine/client/client.h +++ b/src/engine/client/client.h @@ -182,6 +182,8 @@ class CClient : public IClient, public CDemoPlayer::IListener bool m_DummyConnecting = false; bool m_DummyConnected = false; float m_LastDummyConnectTime = 0.0f; + bool m_DummyReconnectOnReload = false; + bool m_DummyDeactivateOnReconnect = false; // graphs CGraph m_InputtimeMarginGraph; diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 65aaf57e7..c96a2bdd2 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -243,6 +243,7 @@ CServer::CServer() } m_MapReload = false; + m_SameMapReload = false; m_ReloadedWhenEmpty = false; m_aCurrentMap[0] = '\0'; @@ -1269,6 +1270,12 @@ void CServer::SendMapData(int ClientId, int Chunk) } } +void CServer::SendMapReload(int ClientId) +{ + CMsgPacker Msg(NETMSG_MAP_RELOAD, true); + SendMsg(&Msg, MSGFLAG_VITAL | MSGFLAG_FLUSH, ClientId); +} + void CServer::SendConnectionReady(int ClientId) { CMsgPacker Msg(NETMSG_CON_READY, true); @@ -2553,12 +2560,13 @@ void CServer::ChangeMap(const char *pMap) void CServer::ReloadMap() { - m_MapReload = true; + m_SameMapReload = true; } int CServer::LoadMap(const char *pMapName) { m_MapReload = false; + m_SameMapReload = false; char aBuf[IO_MAX_PATH_LENGTH]; str_format(aBuf, sizeof(aBuf), "maps/%s.map", pMapName); @@ -2805,8 +2813,9 @@ int CServer::Run() int NewTicks = 0; // load new map - if(m_MapReload || m_CurrentGameTick >= MAX_TICK) // force reload to make sure the ticks stay within a valid range + if(m_MapReload || m_SameMapReload || m_CurrentGameTick >= MAX_TICK) // force reload to make sure the ticks stay within a valid range { + const bool SameMapReload = m_SameMapReload; // load map if(LoadMap(Config()->m_SvMap)) { @@ -2831,6 +2840,9 @@ int CServer::Run() if(m_aClients[ClientId].m_State <= CClient::STATE_AUTH) continue; + if(SameMapReload) + SendMapReload(ClientId); + SendMap(ClientId); bool HasPersistentData = m_aClients[ClientId].m_HasPersistentData; m_aClients[ClientId].Reset(); @@ -3509,7 +3521,7 @@ void CServer::ConStopRecord(IConsole::IResult *pResult, void *pUser) void CServer::ConMapReload(IConsole::IResult *pResult, void *pUser) { - ((CServer *)pUser)->m_MapReload = true; + ((CServer *)pUser)->ReloadMap(); } void CServer::ConLogout(IConsole::IResult *pResult, void *pUser) diff --git a/src/engine/server/server.h b/src/engine/server/server.h index 57e249821..76f8730e5 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -219,6 +219,7 @@ public: int m_RunServer; bool m_MapReload; + bool m_SameMapReload; bool m_ReloadedWhenEmpty; int m_RconClientId; int m_RconAuthLevel; @@ -324,6 +325,7 @@ public: void SendCapabilities(int ClientId); void SendMap(int ClientId); void SendMapData(int ClientId, int Chunk); + void SendMapReload(int ClientId); void SendConnectionReady(int ClientId); void SendRconLine(int ClientId, const char *pLine); // Accepts -1 as ClientId to mean "all clients with at least auth level admin" diff --git a/src/engine/shared/protocol_ex_msgs.h b/src/engine/shared/protocol_ex_msgs.h index c1e792751..d137d5c17 100644 --- a/src/engine/shared/protocol_ex_msgs.h +++ b/src/engine/shared/protocol_ex_msgs.h @@ -35,3 +35,4 @@ UUID(NETMSG_CHECKSUM_ERROR, "checksum-error@ddnet.tw") UUID(NETMSG_REDIRECT, "redirect@ddnet.org") UUID(NETMSG_RCON_CMD_GROUP_START, "rcon-cmd-group-start@ddnet.org") UUID(NETMSG_RCON_CMD_GROUP_END, "rcon-cmd-group-end@ddnet.org") +UUID(NETMSG_MAP_RELOAD, "map-reload@ddnet.org")