maint(bots): update logic
This commit is contained in:
parent
12559da7d4
commit
97c48da499
@ -75,8 +75,8 @@ namespace bots
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* bot_name = game::SV_BotGetRandomName();
|
const auto* bot_name = game::SV_BotGetRandomName();
|
||||||
auto* bot_ent = game::SV_AddBot(bot_name, 26, 62, 0);
|
const auto* bot_ent = game::SV_AddBot(bot_name, 26, 62, 0);
|
||||||
if (bot_ent)
|
if (bot_ent)
|
||||||
{
|
{
|
||||||
spawn_bot(bot_ent->s.number);
|
spawn_bot(bot_ent->s.number);
|
||||||
@ -87,34 +87,13 @@ namespace bots
|
|||||||
volatile bool bot_names_received = false;
|
volatile bool bot_names_received = false;
|
||||||
std::vector<std::string> bot_names;
|
std::vector<std::string> bot_names;
|
||||||
|
|
||||||
const char* get_random_bot_name()
|
bool should_use_remote_bot_names()
|
||||||
{
|
|
||||||
if (bot_names.empty())
|
|
||||||
{
|
|
||||||
return get_bot_name_hook.invoke<const char*>();
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto index = std::rand() % bot_names.size();
|
|
||||||
const auto& name = bot_names.at(index);
|
|
||||||
|
|
||||||
return utils::string::va("%.*s", static_cast<int>(name.size()), name.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool should_update_bot_names()
|
|
||||||
{
|
{
|
||||||
|
#ifdef ALLOW_CUSTOM_BOT_NAMES
|
||||||
return !filesystem::exists("bots.txt");
|
return !filesystem::exists("bots.txt");
|
||||||
}
|
#else
|
||||||
|
return true;
|
||||||
void update_bot_names()
|
#endif
|
||||||
{
|
|
||||||
bot_names_received = false;
|
|
||||||
|
|
||||||
game::netadr_s master{};
|
|
||||||
if (server_list::get_master_server(master))
|
|
||||||
{
|
|
||||||
console::info("Getting bots...\n");
|
|
||||||
network::send(master, "getbots");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_bot_names_from_file()
|
void parse_bot_names_from_file()
|
||||||
@ -141,6 +120,37 @@ namespace bots
|
|||||||
bot_names.emplace_back(entry);
|
bot_names.emplace_back(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* get_random_bot_name()
|
||||||
|
{
|
||||||
|
if (!bot_names_received && bot_names.empty())
|
||||||
|
{
|
||||||
|
// last attempt to use custom names if they can be found
|
||||||
|
parse_bot_names_from_file();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bot_names.empty())
|
||||||
|
{
|
||||||
|
return get_bot_name_hook.invoke<const char*>();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto index = std::rand() % bot_names.size();
|
||||||
|
const auto& name = bot_names.at(index);
|
||||||
|
|
||||||
|
return utils::string::va("%.*s", static_cast<int>(name.size()), name.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_bot_names()
|
||||||
|
{
|
||||||
|
bot_names_received = false;
|
||||||
|
|
||||||
|
game::netadr_s master{};
|
||||||
|
if (server_list::get_master_server(master))
|
||||||
|
{
|
||||||
|
console::info("Getting bots...\n");
|
||||||
|
network::send(master, "getbots");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface
|
||||||
@ -159,23 +169,23 @@ namespace bots
|
|||||||
{
|
{
|
||||||
if (!game::SV_Loaded()) return;
|
if (!game::SV_Loaded()) return;
|
||||||
|
|
||||||
auto num_bots = 1;
|
std::size_t num_bots = 1;
|
||||||
if (params.size() == 2)
|
if (params.size() == 2)
|
||||||
{
|
{
|
||||||
num_bots = atoi(params.get(1));
|
num_bots = std::strtoul(params.get(1), nullptr, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
num_bots = std::min(num_bots, *game::mp::svs_clientCount);
|
num_bots = std::min(num_bots, static_cast<std::size_t>(*game::mp::svs_clientCount));
|
||||||
|
|
||||||
console::info("Spawning %i %s\n", num_bots, (num_bots == 1 ? "bot" : "bots"));
|
console::info("Spawning %zu %s\n", num_bots, (num_bots == 1 ? "bot" : "bots"));
|
||||||
|
|
||||||
for (auto i = 0; i < num_bots; i++)
|
for (std::size_t i = 0; i < num_bots; ++i)
|
||||||
{
|
{
|
||||||
scheduler::once(add_bot, scheduler::pipeline::server, 100ms * i);
|
scheduler::once(add_bot, scheduler::pipeline::server, 100ms * i);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (should_update_bot_names())
|
if (should_use_remote_bot_names())
|
||||||
{
|
{
|
||||||
scheduler::on_game_initialized([]()
|
scheduler::on_game_initialized([]()
|
||||||
{
|
{
|
||||||
|
@ -142,21 +142,21 @@ namespace network
|
|||||||
|
|
||||||
const char* net_adr_to_string(const game::netadr_s& a)
|
const char* net_adr_to_string(const game::netadr_s& a)
|
||||||
{
|
{
|
||||||
if (a.type == game::netadrtype_t::NA_LOOPBACK)
|
if (a.type == game::NA_LOOPBACK)
|
||||||
{
|
{
|
||||||
return "loopback";
|
return "loopback";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a.type == game::netadrtype_t::NA_BOT)
|
if (a.type == game::NA_BOT)
|
||||||
{
|
{
|
||||||
return "bot";
|
return "bot";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a.type == game::netadrtype_t::NA_IP || a.type == game::netadrtype_t::NA_BROADCAST)
|
if (a.type == game::NA_IP || a.type == game::NA_BROADCAST)
|
||||||
{
|
{
|
||||||
if (a.port)
|
if (a.port)
|
||||||
{
|
{
|
||||||
return utils::string::va("%u.%u.%u.%u:%u", a.ip[0], a.ip[1], a.ip[2], a.ip[3], htons(a.port));
|
return utils::string::va("%u.%u.%u.%u:%u", a.ip[0], a.ip[1], a.ip[2], a.ip[3], ::htons(a.port));
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils::string::va("%u.%u.%u.%u", a.ip[0], a.ip[1], a.ip[2], a.ip[3]);
|
return utils::string::va("%u.%u.%u.%u", a.ip[0], a.ip[1], a.ip[2], a.ip[3]);
|
||||||
@ -193,10 +193,9 @@ namespace network
|
|||||||
a.jmp(0x14041DFBD);
|
a.jmp(0x14041DFBD);
|
||||||
}
|
}
|
||||||
|
|
||||||
game::dvar_t* register_netport_stub(const char* dvarName, int value, int min, int max, unsigned int flags,
|
game::dvar_t* register_netport_stub(const char* dvarName, int value, int min, int max, unsigned int flags, const char* description)
|
||||||
const char* description)
|
|
||||||
{
|
{
|
||||||
auto dvar = game::Dvar_RegisterInt("net_port", 27016, 0, 0xFFFFu, game::DVAR_FLAG_LATCHED, "Network port");
|
auto* dvar = game::Dvar_RegisterInt("net_port", 27016, 0, std::numeric_limits<uint16_t>::max(), game::DVAR_FLAG_LATCHED, "Network port");
|
||||||
|
|
||||||
// read net_port from command line
|
// read net_port from command line
|
||||||
command::read_startup_variable("net_port");
|
command::read_startup_variable("net_port");
|
||||||
@ -231,7 +230,7 @@ namespace network
|
|||||||
utils::hook::set<uint8_t>(0x1402ECF1D, 0xEB);
|
utils::hook::set<uint8_t>(0x1402ECF1D, 0xEB);
|
||||||
utils::hook::set<uint8_t>(0x1402ED02A, 0xEB);
|
utils::hook::set<uint8_t>(0x1402ED02A, 0xEB);
|
||||||
utils::hook::set<uint8_t>(0x1402ED34D, 0xEB);
|
utils::hook::set<uint8_t>(0x1402ED34D, 0xEB);
|
||||||
utils::hook::set<uint8_t>(0x1402C4A1F, 0xEB); //
|
utils::hook::set<uint8_t>(0x1402C4A1F, 0xEB);
|
||||||
|
|
||||||
// ignore unregistered connection
|
// ignore unregistered connection
|
||||||
utils::hook::jump(0x140471AAC, reinterpret_cast<void*>(0x140471A50));
|
utils::hook::jump(0x140471AAC, reinterpret_cast<void*>(0x140471A50));
|
||||||
@ -285,7 +284,7 @@ namespace network
|
|||||||
utils::hook::set<std::uint8_t>(0x1402C6AA4, 0xEB);
|
utils::hook::set<std::uint8_t>(0x1402C6AA4, 0xEB);
|
||||||
|
|
||||||
// patch buffer overflow
|
// patch buffer overflow
|
||||||
utils::hook::call(0x14041D17E, memmove_stub);
|
utils::hook::call(0x14041D17E, memmove_stub); // NET_DeferPacketToClient
|
||||||
// this patches a crash found in a subroutine registered using atexit
|
// this patches a crash found in a subroutine registered using atexit
|
||||||
utils::hook::set<std::uint8_t>(0x140815D4E, 0xEB);
|
utils::hook::set<std::uint8_t>(0x140815D4E, 0xEB);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user