diff --git a/src/client/component/console.cpp b/src/client/component/console.cpp index 3b07fd67..9db40451 100644 --- a/src/client/component/console.cpp +++ b/src/client/component/console.cpp @@ -1,4 +1,5 @@ #include +#include "console.hpp" #include "loader/component_loader.hpp" #include "resource.hpp" @@ -15,6 +16,11 @@ namespace console { + void set_title(const std::string& title) + { + SetWindowTextA(*game::s_wcd::hWnd, title.data()); + } + namespace { utils::image::object logo; @@ -205,17 +211,6 @@ namespace console { utils::hook::set(0x14133D2FE_g, 0xEB); // Always enable ingame console } - else - { - scheduler::once([]() - { - const auto server_name_dvar = game::Dvar_FindVar("live_steam_server_name"); - if (server_name_dvar) - { - SetWindowTextA(*game::s_wcd::hWnd, server_name_dvar->current.string); - } - }, scheduler::pipeline::main); - } utils::hook::jump(game::select(0x1423337F0, 0x1405976B0), queue_message); utils::hook::nop(game::select(0x14233380A, 0x1405976CA), 2); // Print from every thread diff --git a/src/client/component/console.hpp b/src/client/component/console.hpp new file mode 100644 index 00000000..a6526763 --- /dev/null +++ b/src/client/component/console.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace console +{ + void set_title(const std::string& title); +} diff --git a/src/client/component/dedicated_info.cpp b/src/client/component/dedicated_info.cpp new file mode 100644 index 00000000..19c475f4 --- /dev/null +++ b/src/client/component/dedicated_info.cpp @@ -0,0 +1,42 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" +#include "game/utils.hpp" +#include "scheduler.hpp" +#include "getinfo.hpp" +#include "console.hpp" + +#include + +namespace dedicated_info +{ + class component final : public server_component + { + public: + void post_unpack() override + { + scheduler::loop([]() + { + const auto sv_running = game::Dvar_FindVar("sv_running"); + + if (sv_running && sv_running->current.enabled) + { + const auto server_name = game::get_dvar_string("live_steam_server_name"); + const auto mapname = game::get_dvar_string("mapname"); + + std::string window_text = utils::string::va("%s on %s [%d/%d] (%d)", + server_name.data(), + mapname.data(), + getinfo::get_client_count(), + getinfo::get_max_client_count(), + getinfo::get_bot_count()); + + console::set_title(window_text); + } + }, scheduler::pipeline::main, 1s); + } + }; +} + +REGISTER_COMPONENT(dedicated_info::component) diff --git a/src/client/component/getinfo.cpp b/src/client/component/getinfo.cpp index 72a7db2c..c3bfe868 100644 --- a/src/client/component/getinfo.cpp +++ b/src/client/component/getinfo.cpp @@ -16,31 +16,46 @@ namespace getinfo { + int get_max_client_count() + { + return game::get_dvar_int("com_maxclients"); + } + + int get_client_count() + { + int count = 0; + const auto client_states = *reinterpret_cast(game::select(0x1576FB318, 0x14A178E98)); + const auto object_length = game::is_server() ? 0xE5110 : 0xE5170; + + 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) + { + ++count; + } + } + + return count; + } + + int get_bot_count() + { + int count = 0; + + for (int i = 0; i < get_max_client_count(); ++i) + { + if (game::SV_IsTestClient(i)) + { + ++count; + } + } + + return count; + } + namespace { - int get_max_client_count() - { - return game::get_dvar_int("com_maxclients"); - } - - int get_client_count() - { - int count = 0; - const auto client_states = *reinterpret_cast(game::select(0x1576FB318, 0x14A178E98)); - const auto object_length = game::is_server() ? 0xE5110 : 0xE5170; - - 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) - { - ++count; - } - } - - return count; - } - int Com_SessionMode_GetGameMode() { return *reinterpret_cast(game::select(0x1568EF7F4, 0x14948DB04)) << 14 >> 28; diff --git a/src/client/component/getinfo.hpp b/src/client/component/getinfo.hpp new file mode 100644 index 00000000..7d016ffa --- /dev/null +++ b/src/client/component/getinfo.hpp @@ -0,0 +1,8 @@ +#pragma once + +namespace getinfo +{ + int get_max_client_count(); + int get_client_count(); + int get_bot_count(); +} diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 4b20c533..24fcbf94 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -27,7 +27,7 @@ namespace game }; WEAK symbol Cbuf_AddText{0x1420EC8B0, 0x1404F75B0}; - WEAK symbol Cbuf_ExecuteBuffer{ + WEAK symbol Cbuf_ExecuteBuffer{ 0x14133BE10, 0x1404F78D0 }; WEAK symbol Cmd_AddCommandInternal{ @@ -99,8 +99,8 @@ namespace game WEAK symbol UI_AddMenu{ 0x1427024B0, 0x0 }; WEAK symbol UI_CoD_GetRootNameForController{ 0x141F291E0, 0x0 }; WEAK symbol Lua_CoD_LoadLuaFile{ 0x141F122C0, 0x0 }; - WEAK symbol CG_LUIHUDRestart{ 0x140F7E970 }; - WEAK symbol CL_CheckKeepDrawingConnectScreen{ 0x1413CCAE0 }; + WEAK symbol CG_LUIHUDRestart{ 0x140F7E970 }; + WEAK symbol CL_CheckKeepDrawingConnectScreen{ 0x1413CCAE0 }; // Scr WEAK symbol Scr_AddInt{0x0, 0x14016F160}; @@ -125,6 +125,7 @@ namespace game // SV WEAK symbol SV_AddTestClient{0x1422499A0, 0x14052E3E0}; WEAK symbol SV_SendServerCommand{0x0, 0x140537F10}; + WEAK symbol SV_IsTestClient{0x14224B5C0, 0x14052FF40}; // Variables