From c9b1566e38fdc719e6703fc77073be75767869bb Mon Sep 17 00:00:00 2001 From: Edo Date: Sun, 16 Apr 2023 11:27:19 +0200 Subject: [PATCH] [Bots]: sv_replaceTestClients dvar (#930) --- src/Components/Modules/Auth.cpp | 4 ++++ src/Components/Modules/Bots.cpp | 26 +++++++++++++++++++++++--- src/Components/Modules/Bots.hpp | 5 ++++- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/Components/Modules/Auth.cpp b/src/Components/Modules/Auth.cpp index f150b107..86a377c6 100644 --- a/src/Components/Modules/Auth.cpp +++ b/src/Components/Modules/Auth.cpp @@ -4,6 +4,7 @@ #include #include "Bans.hpp" +#include "Bots.hpp" namespace Components { @@ -270,6 +271,9 @@ namespace Components HasAccessToReservedSlot = std::strcmp((*Game::sv_privatePassword)->current.string, value) == 0; + // This stubs runs right before the 'server is full check' so we can call this here + Bots::SV_DirectConnect_Full_Check(); + return value; } diff --git a/src/Components/Modules/Bots.cpp b/src/Components/Modules/Bots.cpp index 2deaba89..f53c61cb 100644 --- a/src/Components/Modules/Bots.cpp +++ b/src/Components/Modules/Bots.cpp @@ -15,7 +15,8 @@ namespace Components std::vector Bots::BotNames; - Dvar::Var Bots::SVRandomBotNames; + const Game::dvar_t* Bots::sv_randomBotNames; + const Game::dvar_t* Bots::sv_replaceBots; struct BotMovementInfo { @@ -113,7 +114,7 @@ namespace Components BotNames.emplace_back(entry, clanAbbrev); } - if (SVRandomBotNames.get()) + if (sv_randomBotNames->current.enabled) { RandomizeBotNames(); } @@ -378,6 +379,24 @@ namespace Components return Game::svs_clients[clientNum].ping; } + void Bots::SV_DirectConnect_Full_Check() + { + if (!sv_replaceBots->current.enabled) + { + return; + } + + for (auto i = 0; i < (*Game::sv_maxclients)->current.integer; ++i) + { + auto* cl = &Game::svs_clients[i]; + if (cl->bIsTestClient) + { + Game::SV_DropClient(cl, "EXE_DISCONNECTED", false); + return; + } + } + } + Bots::Bots() { AssertOffset(Game::client_t, bIsTestClient, 0x41AF0); @@ -397,7 +416,8 @@ namespace Components Utils::Hook(0x459654, SV_GetClientPing_Hk, HOOK_CALL).install()->quick(); - SVRandomBotNames = Dvar::Register("sv_randomBotNames", false, Game::DVAR_NONE, "Randomize the bots' names"); + sv_randomBotNames = Game::Dvar_RegisterBool("sv_randomBotNames", false, Game::DVAR_NONE, "Randomize the bots' names"); + sv_replaceBots = Game::Dvar_RegisterBool("sv_replaceBots", false, Game::DVAR_NONE, "Test clients will be replaced by connecting players when the server is full."); // Reset BotMovementInfo.active when client is dropped Events::OnClientDisconnect([](const int clientNum) -> void diff --git a/src/Components/Modules/Bots.hpp b/src/Components/Modules/Bots.hpp index b7094629..f2e7642c 100644 --- a/src/Components/Modules/Bots.hpp +++ b/src/Components/Modules/Bots.hpp @@ -7,11 +7,14 @@ namespace Components public: Bots(); + static void SV_DirectConnect_Full_Check(); + private: using botData = std::pair< std::string, std::string>; static std::vector BotNames; - static Dvar::Var SVRandomBotNames; + static const Game::dvar_t* sv_randomBotNames; + static const Game::dvar_t* sv_replaceBots; static void RandomizeBotNames(); static std::string TruncBotString(const std::string& input, std::size_t length);