From 619d1993a7b481dc6eb8577f7a22363161cd96fd Mon Sep 17 00:00:00 2001 From: mjkzy Date: Tue, 5 Jul 2022 22:18:12 -0500 Subject: [PATCH 1/5] custom bot names --- src/client/component/bots.cpp | 70 +++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/src/client/component/bots.cpp b/src/client/component/bots.cpp index 019242fd..731f1c0d 100644 --- a/src/client/component/bots.cpp +++ b/src/client/component/bots.cpp @@ -2,9 +2,11 @@ #include "loader/component_loader.hpp" #include "command.hpp" +#include "console.hpp" #include "scheduler.hpp" #include "network.hpp" #include "party.hpp" +#include "scripting.hpp" #include "game/game.hpp" #include "game/scripting/execution.hpp" @@ -12,6 +14,7 @@ #include #include #include +#include namespace bots { @@ -53,10 +56,8 @@ namespace bots return; } - static auto first_bot = true; - - const auto bot_name = game::SV_BotGetRandomName(); - const auto bot_ent = game::SV_AddBot(bot_name); + const auto* const bot_name = game::SV_BotGetRandomName(); + const auto* bot_ent = game::SV_AddBot(bot_name); if (bot_ent) { @@ -70,6 +71,58 @@ namespace bots }, scheduler::pipeline::server, 100ms); } } + + utils::hook::detour get_bot_name_hook; + std::vector bot_names{}; + + void load_bot_data() + { + static const char* bots_json = "h1-mod/bots.json"; + + std::string bots_content; + + if (!utils::io::read_file(bots_json, &bots_content)) + { + console::error(utils::string::va("%s was not found.\n", bots_json)); + return; + } + + rapidjson::Document bots; + bots.Parse(bots_content.data()); + + // must be in a ["name1, "name2", "name3"] format + if (!bots.IsArray()) + { + console::error("bots.json must be a array of names.\n"); + return; + } + + const auto names = bots.GetArray(); + for (const auto& name : names) + { + bot_names.emplace_back(name.Get()); + } + } + + static size_t bot_id = 0; + + const char* get_random_bot_name() + { + if (bot_names.empty()) + { + load_bot_data(); + } + + // only use bot names once, no dupes in names + if (!bot_names.empty() && bot_id < bot_names.size()) + { + bot_id %= bot_names.size(); + const auto& entry = bot_names.at(bot_id++); + return utils::string::va("%.*s", static_cast(entry.size()), entry.data()); + } + + return get_bot_name_hook.invoke(); + } } class component final : public component_interface @@ -82,6 +135,8 @@ namespace bots return; } + get_bot_name_hook.create(game::SV_BotGetRandomName, get_random_bot_name); + command::add("spawnBot", [](const command::params& params) { if (!can_add()) @@ -102,6 +157,13 @@ namespace bots scheduler::once(add_bot, scheduler::pipeline::server, 100ms * i); } }); + + // Clear bot names and reset ID on game shutdown to allow new names to be added without restarting + scripting::on_shutdown([] + { + bot_names.clear(); + bot_id = 0; + }); } }; } From 0a44b99675ec33f9395c0c83114dfc1155b18ecd Mon Sep 17 00:00:00 2001 From: mjkzy Date: Tue, 5 Jul 2022 22:45:37 -0500 Subject: [PATCH 2/5] fix build by using std::string cast --- src/client/component/bots.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/component/bots.cpp b/src/client/component/bots.cpp index 731f1c0d..c74ec29f 100644 --- a/src/client/component/bots.cpp +++ b/src/client/component/bots.cpp @@ -100,7 +100,7 @@ namespace bots const auto names = bots.GetArray(); for (const auto& name : names) { - bot_names.emplace_back(name.Get()); + bot_names.emplace_back(std::string(name.GetString())); } } From 8503fc7223cb36800566ef01ba740bf7017950b5 Mon Sep 17 00:00:00 2001 From: mjkzy Date: Wed, 6 Jul 2022 10:35:38 -0500 Subject: [PATCH 3/5] use a normal text file instead --- src/client/component/bots.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/client/component/bots.cpp b/src/client/component/bots.cpp index c74ec29f..2db33b02 100644 --- a/src/client/component/bots.cpp +++ b/src/client/component/bots.cpp @@ -77,30 +77,26 @@ namespace bots void load_bot_data() { - static const char* bots_json = "h1-mod/bots.json"; + static const char* bots_txt = "h1-mod/bots.txt"; std::string bots_content; - - if (!utils::io::read_file(bots_json, &bots_content)) + if (!utils::io::read_file(bots_txt, &bots_content)) { - console::error(utils::string::va("%s was not found.\n", bots_json)); + console::error(utils::string::va("%s was not found.\n", bots_txt)); return; } - rapidjson::Document bots; - bots.Parse(bots_content.data()); - - // must be in a ["name1, "name2", "name3"] format - if (!bots.IsArray()) + auto names = utils::string::split(bots_content, '\n'); + for (auto& name : names) { - console::error("bots.json must be a array of names.\n"); - return; - } - - const auto names = bots.GetArray(); - for (const auto& name : names) - { - bot_names.emplace_back(std::string(name.GetString())); + name = utils::string::replace(name, "\r", ""); +#ifdef DEBUG + console::info(utils::string::va("Loading name '%s' for bot names...\n", name.data())); +#endif + if (!name.empty()) + { + bot_names.emplace_back(name); + } } } @@ -113,6 +109,10 @@ namespace bots load_bot_data(); } +#ifdef DEBUG + console::info(utils::string::va("Bot ID is %d\n", bot_id)); +#endif + // only use bot names once, no dupes in names if (!bot_names.empty() && bot_id < bot_names.size()) { From 415499a09cb67da55fb7ddaae2cbc7c1ed49bfb5 Mon Sep 17 00:00:00 2001 From: m Date: Thu, 7 Jul 2022 15:50:29 -0500 Subject: [PATCH 4/5] remove prints left from testing --- src/client/component/bots.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/client/component/bots.cpp b/src/client/component/bots.cpp index 2db33b02..068410a9 100644 --- a/src/client/component/bots.cpp +++ b/src/client/component/bots.cpp @@ -82,7 +82,6 @@ namespace bots std::string bots_content; if (!utils::io::read_file(bots_txt, &bots_content)) { - console::error(utils::string::va("%s was not found.\n", bots_txt)); return; } @@ -90,9 +89,6 @@ namespace bots for (auto& name : names) { name = utils::string::replace(name, "\r", ""); -#ifdef DEBUG - console::info(utils::string::va("Loading name '%s' for bot names...\n", name.data())); -#endif if (!name.empty()) { bot_names.emplace_back(name); @@ -100,19 +96,15 @@ namespace bots } } - static size_t bot_id = 0; - const char* get_random_bot_name() { + static size_t bot_id = 0; + if (bot_names.empty()) { load_bot_data(); } -#ifdef DEBUG - console::info(utils::string::va("Bot ID is %d\n", bot_id)); -#endif - // only use bot names once, no dupes in names if (!bot_names.empty() && bot_id < bot_names.size()) { From 46e0e7c8e1b45641f8f3ec136931e28c6c000731 Mon Sep 17 00:00:00 2001 From: m Date: Thu, 7 Jul 2022 16:07:16 -0500 Subject: [PATCH 5/5] fix build --- src/client/component/bots.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/component/bots.cpp b/src/client/component/bots.cpp index 068410a9..3bb8382d 100644 --- a/src/client/component/bots.cpp +++ b/src/client/component/bots.cpp @@ -95,11 +95,11 @@ namespace bots } } } + + size_t bot_id = 0; const char* get_random_bot_name() { - static size_t bot_id = 0; - if (bot_names.empty()) { load_bot_data();