diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index 0ac70162..07a2a241 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -7,6 +7,7 @@ #include #include +#include namespace command { @@ -66,15 +67,6 @@ namespace command } } - struct component final : generic_component - { - void post_unpack() override - { - // Disable whitelist - utils::hook::jump(game::select(0x1420EE860, 0x1404F9CD0), update_whitelist_stub); - } - }; - params::params() : nesting_(get_cmd_args()->nesting) { @@ -227,6 +219,15 @@ namespace command game::Cmd_AddServerCommandInternal(cmd_string, execute_custom_sv_command, allocator.allocate()); } + + struct component final : generic_component + { + void post_unpack() override + { + // Disable whitelist + utils::hook::jump(game::select(0x1420EE860, 0x1404F9CD0), update_whitelist_stub); + } + }; } REGISTER_COMPONENT(command::component) diff --git a/src/client/component/dedicated_patches.cpp b/src/client/component/dedicated_patches.cpp index 06c943ce..48ed8326 100644 --- a/src/client/component/dedicated_patches.cpp +++ b/src/client/component/dedicated_patches.cpp @@ -36,22 +36,22 @@ namespace dedicated_patches { const std::vector is_mod_loaded_addresses = { - { 0x14019CFC4_g }, - { 0x14024D4A0_g }, - { 0x14024D669_g }, - { 0x14024D939_g }, - { 0x14024DC64_g }, - { 0x14024E13A_g }, - { 0x14024E5A3_g }, - { 0x14024FFB9_g }, - { 0x140251E9E_g }, - { 0x140253680_g }, - { 0x140257BF6_g }, - { 0x1402D296D_g }, - { 0x1402D58E9_g }, - { 0x140468374_g }, - { 0x14046B796_g }, - { 0x14048003D_g }, + {0x14019CFC4_g}, + {0x14024D4A0_g}, + {0x14024D669_g}, + {0x14024D939_g}, + {0x14024DC64_g}, + {0x14024E13A_g}, + {0x14024E5A3_g}, + {0x14024FFB9_g}, + {0x140251E9E_g}, + {0x140253680_g}, + {0x140257BF6_g}, + {0x1402D296D_g}, + {0x1402D58E9_g}, + {0x140468374_g}, + {0x14046B796_g}, + {0x14048003D_g}, }; for (const auto& address : is_mod_loaded_addresses) @@ -68,15 +68,20 @@ namespace dedicated_patches spawn_server_hook.invoke(controllerIndex, server, preload, savegame); } - uint64_t sv_get_player_xuid_stub(int client_num) + uint64_t sv_get_player_xuid_stub(const int client_num) { - return static_cast((*game::svs_clients)[client_num].xuid); + const auto* clients = *game::svs_clients; + if (!clients) + { + return 0; + } + + return static_cast(clients[client_num].guid); } } struct component final : server_component { - static_assert(offsetof(game::client_s, xuid) == 0xBB354); void post_unpack() override { diff --git a/src/client/component/getinfo.cpp b/src/client/component/getinfo.cpp index 1deb6826..9e770266 100644 --- a/src/client/component/getinfo.cpp +++ b/src/client/component/getinfo.cpp @@ -21,21 +21,18 @@ namespace getinfo return game::get_dvar_int("com_maxclients"); } - int get_client_count() + template + int get_client_count(T* client_states) { - int count = 0; - const auto client_states = *reinterpret_cast(game::select(0x1576F9318, 0x14A178E98)); if (!client_states) { return 0; } - const auto object_length = game::is_server() ? 0xE5110 : 0xE5170; - + int count = 0; for (int i = 0; i < get_max_client_count(); ++i) { - const auto client_state = *reinterpret_cast(client_states + (i * object_length)); - if (client_state > 0) + if (client_states[i].client_state > 0) { ++count; } @@ -44,9 +41,19 @@ namespace getinfo return count; } + int get_client_count() + { + if (game::is_server()) + { + return get_client_count(*game::svs_clients); + } + + return get_client_count(*game::svs_clients_cl); + } + int get_bot_count() { - const auto client_states = *reinterpret_cast(game::select(0x1576F9318, 0x14A178E98)); + const auto client_states = game::is_server() ? *game::svs_clients : *game::svs_clients_cl; if (!client_states) { return 0; diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 9e6cd35a..9e35f729 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1544,15 +1544,32 @@ namespace game struct client_s { - char __pad0[0xBB354]; - int xuid; - char __pad1[0x8]; + int client_state; + char __pad0[0x28]; + netadr_t address; + char __pad1[0xBB318]; + int guid; + char __pad2[0x8]; bool bIsTestClient; - char __pad2[0x29DAC]; + char __pad3[0x25818]; + uint64_t xuid; + char __pad4[0x4588]; }; static_assert(sizeof(client_s) == 0xE5110); + static_assert(offsetof(game::client_s, address) == 0x2C); + static_assert(offsetof(game::client_s, guid) == 0xBB354); + static_assert(offsetof(game::client_s, bIsTestClient) == 0xBB360); + static_assert(offsetof(game::client_s, xuid) == 0xE0B80); + + struct client_s_cl : client_s + { + char __pad1_0[0x60]; + }; + + static_assert(sizeof(client_s_cl) == 0xE5170); + enum scriptInstance_t { SCRIPTINSTANCE_SERVER = 0x0, diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index c2fd5aec..6abf5b32 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -190,6 +190,8 @@ namespace game WEAK symbol s_dvarPool{0x157AC6220, 0x14A3CB620}; WEAK symbol g_dvarCount{0x157AC61CC, 0x14A3CB5FC}; + // Client and dedi struct size differs :( + WEAK symbol svs_clients_cl{0x1576F9318, 0}; WEAK symbol svs_clients{0x0, 0x14A178E98}; // Dvar variables