Cleanup cached profile infos

This commit is contained in:
momo5502 2023-04-07 14:25:56 +02:00
parent 9e7a567acb
commit fd8460349f
8 changed files with 133 additions and 60 deletions

View File

@ -127,7 +127,7 @@ namespace auth
void handle_connect_packet(const game::netadr_t& target, const network::data_view& data) void handle_connect_packet(const game::netadr_t& target, const network::data_view& data)
{ {
if (!game::get_dvar_bool("sv_running")) if (!game::is_server_running())
{ {
return; return;
} }

View File

@ -122,7 +122,7 @@ namespace chat
// Overwrite say command // Overwrite say command
utils::hook::jump(0x14052A6C0_g, +[] utils::hook::jump(0x14052A6C0_g, +[]
{ {
if (!game::get_dvar_bool("sv_running")) if (!game::is_server_running())
{ {
printf("Server is not running\n"); printf("Server is not running\n");
return; return;
@ -138,7 +138,7 @@ namespace chat
// Overwrite tell command // Overwrite tell command
utils::hook::jump(0x14052A7E0_g, +[] utils::hook::jump(0x14052A7E0_g, +[]
{ {
if (!game::get_dvar_bool("sv_running")) if (!game::is_server_running())
{ {
printf("Server is not running\n"); printf("Server is not running\n");
return; return;

View File

@ -27,11 +27,11 @@ namespace dedicated_info
const auto mapname = game::get_dvar_string("mapname"); const auto mapname = game::get_dvar_string("mapname");
const std::string window_text = utils::string::va("%s on %s [%d/%d] (%d)", const std::string window_text = utils::string::va("%s on %s [%zu/%zu] (%zu)",
clean_server_name, clean_server_name,
mapname.data(), mapname.data(),
getinfo::get_client_count(), getinfo::get_client_count(),
getinfo::get_max_client_count(), game::get_max_client_count(),
getinfo::get_bot_count()); getinfo::get_bot_count());
console::set_title(window_text); console::set_title(window_text);

View File

@ -41,33 +41,28 @@ namespace getinfo
return count; return count;
} }
int get_client_count() size_t get_client_count()
{ {
if (game::is_server()) size_t count = 0;
game::foreach_connected_client([&count](const game::client_s&)
{ {
return get_client_count(*game::svs_clients); ++count;
});
return count;
} }
return get_client_count(*game::svs_clients_cl); size_t get_bot_count()
}
int get_bot_count()
{ {
const auto client_states = game::is_server() ? *game::svs_clients : *game::svs_clients_cl; size_t count = 0;
if (!client_states)
{
return 0;
}
int count = 0; game::foreach_connected_client([&count](const game::client_s&, const size_t index)
for (int i = 0; i < get_max_client_count(); ++i)
{ {
if (game::SV_IsTestClient(i)) if (game::SV_IsTestClient(static_cast<int>(index)))
{ {
++count; ++count;
} }
} });
return count; return count;
} }
@ -110,9 +105,9 @@ namespace getinfo
info.set("xuid", utils::string::va("%llX", steam::SteamUser()->GetSteamID().bits)); info.set("xuid", utils::string::va("%llX", steam::SteamUser()->GetSteamID().bits));
info.set("mapname", game::get_dvar_string("mapname")); info.set("mapname", game::get_dvar_string("mapname"));
info.set("isPrivate", game::get_dvar_string("g_password").empty() ? "0" : "1"); info.set("isPrivate", game::get_dvar_string("g_password").empty() ? "0" : "1");
info.set("clients", utils::string::va("%i", get_client_count())); info.set("clients", utils::string::va("%zu", get_client_count()));
info.set("bots", utils::string::va("%i", get_bot_count())); info.set("bots", utils::string::va("%zu", get_bot_count()));
info.set("sv_maxclients", utils::string::va("%i", get_max_client_count())); info.set("sv_maxclients", utils::string::va("%zu", get_max_client_count()));
info.set("protocol", utils::string::va("%i", PROTOCOL)); info.set("protocol", utils::string::va("%i", PROTOCOL));
info.set("playmode", utils::string::va("%i", game::Com_SessionMode_GetMode())); info.set("playmode", utils::string::va("%i", game::Com_SessionMode_GetMode()));
info.set("gamemode", utils::string::va("%i", Com_SessionMode_GetGameMode())); info.set("gamemode", utils::string::va("%i", Com_SessionMode_GetGameMode()));

View File

@ -2,8 +2,7 @@
namespace getinfo namespace getinfo
{ {
int get_max_client_count(); size_t get_client_count();
int get_client_count(); size_t get_bot_count();
int get_bot_count();
bool is_host(); bool is_host();
} }

View File

@ -44,33 +44,11 @@ namespace profile_infos
return {std::move(info)}; return {std::move(info)};
} }
int get_max_client_count()
{
return game::get_dvar_int("com_maxclients");
}
void send_profile_info(const game::netadr_t& address, const std::string& buffer) void send_profile_info(const game::netadr_t& address, const std::string& buffer)
{ {
network::send(address, "profileInfo", buffer); network::send(address, "profileInfo", buffer);
} }
template <typename T>
void distribute_profile_info(T* client_states, const std::string& buffer)
{
if (!client_states)
{
return;
}
for (int i = 0; i < get_max_client_count(); ++i)
{
if (client_states[i].client_state > 0)
{
send_profile_info(client_states[i].address, buffer);
}
}
}
void distribute_profile_info(const uint64_t user_id, const profile_info& info) void distribute_profile_info(const uint64_t user_id, const profile_info& info)
{ {
if (user_id == steam::SteamUser()->GetSteamID().bits) if (user_id == steam::SteamUser()->GetSteamID().bits)
@ -82,14 +60,12 @@ namespace profile_infos
buffer.write(user_id); buffer.write(user_id);
info.serialize(buffer); info.serialize(buffer);
if (game::is_server()) const std::string data = buffer.move_buffer();
game::foreach_connected_client([&](const game::client_s& client)
{ {
distribute_profile_info(*game::svs_clients, buffer.get_buffer()); send_profile_info(client.address, data);
} });
else
{
distribute_profile_info(*game::svs_clients_cl, buffer.get_buffer());
}
} }
void schedule_pcache_update() void schedule_pcache_update()
@ -107,14 +83,42 @@ namespace profile_infos
}, scheduler::main, 5s); }, scheduler::main, 5s);
} }
std::unordered_set<uint64_t> get_connected_client_xuids()
{
std::unordered_set<uint64_t> connected_clients{};
connected_clients.reserve(game::get_max_client_count());
game::foreach_connected_client([&](const game::client_s& client)
{
connected_clients.emplace(client.xuid);
});
return connected_clients;
}
void clean_cached_profile_infos() void clean_cached_profile_infos()
{ {
if (!game::get_dvar_bool("sv_running")) if (!game::is_server_running())
{ {
return; return;
} }
// TODO const auto xuids = get_connected_client_xuids();
profile_mapping.access([&](profile_map& profiles)
{
for (auto i = profiles.begin(); i != profiles.end();)
{
if (xuids.contains(i->first))
{
++i;
}
else
{
i = profiles.erase(i);
}
}
});
} }
} }

View File

@ -45,7 +45,8 @@ namespace game
return dvar->current.value.enabled; return dvar->current.value.enabled;
} }
const dvar_t* register_sessionmode_dvar_bool(const char* dvar_name, const bool value, const int flags, const char* description, const eModes mode) const dvar_t* register_sessionmode_dvar_bool(const char* dvar_name, const bool value, const int flags,
const char* description, const eModes mode)
{ {
const auto hash = Dvar_GenerateHash(dvar_name); const auto hash = Dvar_GenerateHash(dvar_name);
auto* registered_dvar = Dvar_SessionModeRegisterBool(hash, dvar_name, value, flags, description); auto* registered_dvar = Dvar_SessionModeRegisterBool(hash, dvar_name, value, flags, description);
@ -83,7 +84,8 @@ namespace game
return registered_dvar; return registered_dvar;
} }
const dvar_t* register_dvar_string(const char* dvar_name, const char* value, const int flags, const char* description) const dvar_t* register_dvar_string(const char* dvar_name, const char* value, const int flags,
const char* description)
{ {
const auto hash = Dvar_GenerateHash(dvar_name); const auto hash = Dvar_GenerateHash(dvar_name);
auto* registered_dvar = Dvar_RegisterString(hash, dvar_name, value, flags, description); auto* registered_dvar = Dvar_RegisterString(hash, dvar_name, value, flags, description);
@ -135,4 +137,67 @@ namespace game
dvar_to_change->flags = flags; dvar_to_change->flags = flags;
} }
bool is_server_running()
{
return get_dvar_bool("sv_running");
}
size_t get_max_client_count()
{
return static_cast<size_t>(get_dvar_int("com_maxclients"));
}
template <typename T>
static void foreach_client(T* client_states, const std::function<void(client_s&, size_t index)>& callback)
{
if (!client_states || !callback)
{
return;
}
for (size_t i = 0; i < get_max_client_count(); ++i)
{
callback(client_states[i], i);
}
}
void foreach_client(const std::function<void(client_s&, size_t index)>& callback)
{
if (is_server())
{
foreach_client(*svs_clients, callback);
}
else
{
foreach_client(*svs_clients_cl, callback);
}
}
void foreach_client(const std::function<void(client_s&)>& callback)
{
foreach_client([&](client_s& client, size_t)
{
callback(client);
});
}
void foreach_connected_client(const std::function<void(client_s&, size_t index)>& callback)
{
foreach_client([&](client_s& client, const size_t index)
{
if (client.client_state > 0)
{
callback(client, index);
}
});
}
void foreach_connected_client(const std::function<void(client_s&)>& callback)
{
foreach_connected_client([&](client_s& client, size_t)
{
callback(client);
});
}
} }

View File

@ -11,6 +11,16 @@ namespace game
const dvar_t* register_dvar_bool(const char* dvar_name, bool value, int flags, const char* description); const dvar_t* register_dvar_bool(const char* dvar_name, bool value, int flags, const char* description);
const dvar_t* register_sessionmode_dvar_bool(const char* dvar_name, bool value, int flags, const char* description, eModes mode = MODE_COUNT); const dvar_t* register_sessionmode_dvar_bool(const char* dvar_name, bool value, int flags, const char* description, eModes mode = MODE_COUNT);
const dvar_t* register_dvar_string(const char* dvar_name, const char* value, int flags, const char* description); const dvar_t* register_dvar_string(const char* dvar_name, const char* value, int flags, const char* description);
void dvar_add_flags(const char* dvar, dvarFlags_e flags); void dvar_add_flags(const char* dvar, dvarFlags_e flags);
void dvar_set_flags(const char* dvar_name, dvarFlags_e flags); void dvar_set_flags(const char* dvar_name, dvarFlags_e flags);
bool is_server_running();
size_t get_max_client_count();
void foreach_client(const std::function<void(client_s&, size_t index)>& callback);
void foreach_client(const std::function<void(client_s&)>& callback);
void foreach_connected_client(const std::function<void(client_s&, size_t index)>& callback);
void foreach_connected_client(const std::function<void(client_s&)>& callback);
} }