Merge pull request #39 from diamante0018/bot

feature(bots): if bots.txt is empty use AW names
This commit is contained in:
Louve 2023-08-29 00:17:23 +02:00 committed by GitHub
commit 762c32d100
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 5 deletions

View File

@ -19,6 +19,8 @@ namespace Components
std::size_t Bots::BotDataIndex; std::size_t Bots::BotDataIndex;
std::vector<Bots::botData> Bots::RemoteBotNames;
struct BotMovementInfo struct BotMovementInfo
{ {
std::int32_t buttons; // Actions std::int32_t buttons; // Actions
@ -55,6 +57,17 @@ namespace Components
{ "activate", Game::CMD_BUTTON_ACTIVATE }, { "activate", Game::CMD_BUTTON_ACTIVATE },
}; };
void Bots::UpdateBotNames()
{
const auto masterPort = (*Game::com_masterPort)->current.integer;
const auto* masterServerName = (*Game::com_masterServerName)->current.string;
Network::Address master(Utils::String::VA("%s:%u", masterServerName, masterPort));
Logger::Print("Getting bots...\n");
Network::Send(master, "getbots");
}
std::vector<Bots::botData> Bots::LoadBotNames() std::vector<Bots::botData> Bots::LoadBotNames()
{ {
std::vector<botData> result; std::vector<botData> result;
@ -101,7 +114,7 @@ namespace Components
return result; return result;
} }
int Bots::BuildConnectString(char* buffer, const char* connectString, int num, int, int protocol, int checksum, int statVer, int statStuff, int port) int Bots::BuildConnectString(char* buffer, const char* connectString, int num, int, int protocol, int checksum, int statVer, int stats, int port)
{ {
std::string botName; std::string botName;
std::string clanName; std::string clanName;
@ -109,6 +122,11 @@ namespace Components
static const auto botNames = []() -> std::vector<botData> static const auto botNames = []() -> std::vector<botData>
{ {
auto names = LoadBotNames(); auto names = LoadBotNames();
if (names.empty())
{
Logger::Print("bots.txt was empty. Using the names from the master server\n");
names = RemoteBotNames;
}
if (sv_randomBotNames->current.enabled) if (sv_randomBotNames->current.enabled)
{ {
@ -133,7 +151,7 @@ namespace Components
clanName = "BOT"s; clanName = "BOT"s;
} }
return _snprintf_s(buffer, 0x400, _TRUNCATE, connectString, num, botName.data(), clanName.data(), protocol, checksum, statVer, statStuff, port); return _snprintf_s(buffer, 0x400, _TRUNCATE, connectString, num, botName.data(), clanName.data(), protocol, checksum, statVer, stats, port);
} }
void Bots::Spawn(unsigned int count) void Bots::Spawn(unsigned int count)
@ -446,9 +464,9 @@ namespace Components
} }
} }
count = std::min(Game::MAX_CLIENTS, count); count = std::clamp<std::size_t>(count, 1, Game::MAX_CLIENTS);
Logger::Print("Spawning {} {}", count, (count == 1 ? "bot" : "bots")); Logger::Print("Spawning {} {}\n", count, (count == 1 ? "bot" : "bots"));
Spawn(count); Spawn(count);
}); });
@ -476,6 +494,26 @@ namespace Components
sv_randomBotNames = Game::Dvar_RegisterBool("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."); sv_replaceBots = Game::Dvar_RegisterBool("sv_replaceBots", false, Game::DVAR_NONE, "Test clients will be replaced by connecting players when the server is full.");
Scheduler::OnGameInitialized(UpdateBotNames, Scheduler::Pipeline::MAIN);
Network::OnClientPacket("getbotsResponse", [](const Network::Address& address, const std::string& data)
{
const auto masterPort = (*Game::com_masterPort)->current.integer;
const auto* masterServerName = (*Game::com_masterServerName)->current.string;
Network::Address master(Utils::String::VA("%s:%u", masterServerName, masterPort));
if (master == address)
{
auto botNames = Utils::String::Split(data, '\n');
Logger::Print("Got {} names from the master server\n", botNames.size());
for (const auto& entry : botNames)
{
RemoteBotNames.emplace_back(entry, "BOT");
}
}
});
// Reset BotMovementInfo.active when client is dropped // Reset BotMovementInfo.active when client is dropped
Events::OnClientDisconnect([](const int clientNum) -> void Events::OnClientDisconnect([](const int clientNum) -> void
{ {

View File

@ -10,13 +10,17 @@ namespace Components
static void SV_DirectConnect_Full_Check(); static void SV_DirectConnect_Full_Check();
private: private:
using botData = std::pair< std::string, std::string>; using botData = std::pair<std::string, std::string>;
static const Game::dvar_t* sv_randomBotNames; static const Game::dvar_t* sv_randomBotNames;
static const Game::dvar_t* sv_replaceBots; static const Game::dvar_t* sv_replaceBots;
static std::size_t BotDataIndex; static std::size_t BotDataIndex;
static std::vector<botData> RemoteBotNames;
static void UpdateBotNames();
static std::vector<botData> LoadBotNames(); static std::vector<botData> LoadBotNames();
static int BuildConnectString(char* buffer, const char* connectString, int num, int, int protocol, int checksum, int statVer, int statStuff, int port); static int BuildConnectString(char* buffer, const char* connectString, int num, int, int protocol, int checksum, int statVer, int statStuff, int port);