From 8490344d9353e0e9401cae430992f4e8cf1dbe0b Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Thu, 5 Dec 2024 20:10:07 +0100 Subject: [PATCH] Server: fix bug in CC_CreateFakePlayer_f - We don't need to call CVEngineServer::LockNetworkStringTables, as CVEngineServer::CreateFakeClient already does this. - We should never run CVEngineServer::CreateFakeClient() and CServerGameClients::ClientFullyConnect() when we aren't doing this from the server frame thread, or when we are doing it outside the server frame thread while its active. We not wait and help with other jobs until the server frame thread is finished before adding our bot. - Removed team number check, this is already performed in CClient::SetTeam(). --- src/game/server/player.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/game/server/player.cpp b/src/game/server/player.cpp index e7888b2d..9361b490 100644 --- a/src/game/server/player.cpp +++ b/src/game/server/player.cpp @@ -258,23 +258,19 @@ static void CC_CreateFakePlayer_f(const CCommand& args) if (numPlayers >= g_ServerGlobalVariables->maxClients) return; - const char* playerName = args.Arg(1); + const char* const playerName = args.Arg(1); + const int teamNum = atoi(args.Arg(2)); - int teamNum = atoi(args.Arg(2)); - const int maxTeams = int(g_pServer->GetMaxTeams()) + 1; - - // Clamp team count, going above the limit will - // cause a crash. Going below 0 means that the - // engine will assign the bot to the last team. - if (teamNum > maxTeams) - teamNum = maxTeams; - - g_pEngineServer->LockNetworkStringTables(true); + // The following code must either run inside the server frame thread, or + // after it has finished. Lock here and help with other jobs until the + // server has finished running the frame. + ThreadJoinServerJob(); + // note(amos): if you call CServer::CreateFakeClient() directly, you also + // need to lock the string tables with LockNetworkStringTables. The + // CVEngineServer method automatically locks and unlocks the string tables. const edict_t nHandle = g_pEngineServer->CreateFakeClient(playerName, teamNum); g_pServerGameClients->ClientFullyConnect(nHandle, false); - - g_pEngineServer->LockNetworkStringTables(false); } static ConCommand sv_addbot("sv_addbot", CC_CreateFakePlayer_f, "Creates a bot on the server", FCVAR_RELEASE);