From 724c7026ef64d22c1fc1a8fc023b3dd055e21ad5 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Mon, 3 Apr 2023 17:38:03 +0200 Subject: [PATCH 01/23] Prepare new authentication protocol --- src/client/component/auth.cpp | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index edac9e7b..2af779c1 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -2,6 +2,8 @@ #include "loader/component_loader.hpp" #include "auth.hpp" +#include "command.hpp" +#include "network.hpp" #include @@ -92,16 +94,32 @@ namespace auth return !is_first; } - int send_connect_data_stub(const game::netsrc_t sock, game::netadr_t* adr, const char* data, const int len) + int send_connect_data_stub(const game::netsrc_t sock, game::netadr_t* adr, const char* data, int len) { - /*const auto is_connect_sequence = len >= 7 && strncmp("connect", data, 7) == 0; + std::string buffer{}; + + const auto is_connect_sequence = len >= 7 && strncmp("connect", data, 7) == 0; if (is_connect_sequence) { - MessageBoxA(0, "CONNECT", 0, 0); - }*/ + buffer.append("connect "); + buffer.append(data, len); + + data = buffer.data(); + len = static_cast(buffer.size()); + } return reinterpret_cast(0x142173600_g)(sock, adr, data, len); } + + void handle_connect_packet(const game::netadr_t& target, const network::data_view& data) + { + const std::string text(data.begin(), data.end()); + command::params_sv params(text); + + MessageBoxA(0, "Connecting", 0, 0); + + game::SV_DirectConnect(target); + } } uint64_t get_guid() @@ -123,6 +141,10 @@ namespace auth { void post_unpack() override { + // Skip connect handler + utils::hook::set(game::select(0x142253EFA, 0x14053714A), 0xEB); + network::on("connect", handle_connect_packet); + // Patch steam id bit check std::vector> patches{}; const auto p = [&patches](const size_t a, const size_t b) From 27ab6193e51c37d1bdf26ef53504fb36767df302 Mon Sep 17 00:00:00 2001 From: Maurice Heumann Date: Mon, 3 Apr 2023 19:03:54 +0200 Subject: [PATCH 02/23] Prepare auth data --- src/client/component/auth.cpp | 23 ++++++-- src/client/component/network.cpp | 13 ++++- src/client/component/party.cpp | 12 ++++- src/client/game/structs.hpp | 2 +- src/common/utils/byte_buffer.cpp | 85 +++++++++++++++++++++++++++++ src/common/utils/byte_buffer.hpp | 91 ++++++++++++++++++++++++++++++++ 6 files changed, 217 insertions(+), 9 deletions(-) create mode 100644 src/common/utils/byte_buffer.cpp create mode 100644 src/common/utils/byte_buffer.hpp diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 2af779c1..4a76dddb 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -94,6 +95,14 @@ namespace auth return !is_first; } + std::string serialize_connect_data(const std::vector& data) + { + utils::byte_buffer buffer{}; + buffer.write_vector(data); + + return buffer.move_buffer(); + } + int send_connect_data_stub(const game::netsrc_t sock, game::netadr_t* adr, const char* data, int len) { std::string buffer{}; @@ -101,8 +110,12 @@ namespace auth const auto is_connect_sequence = len >= 7 && strncmp("connect", data, 7) == 0; if (is_connect_sequence) { - buffer.append("connect "); - buffer.append(data, len); + std::vector connect_data{}; + connect_data.assign(data, data + len); + + buffer.append("connect"); + buffer.push_back(' '); + buffer.append(serialize_connect_data(connect_data)); data = buffer.data(); len = static_cast(buffer.size()); @@ -113,10 +126,10 @@ namespace auth void handle_connect_packet(const game::netadr_t& target, const network::data_view& data) { - const std::string text(data.begin(), data.end()); - command::params_sv params(text); + utils::byte_buffer buffer(data); - MessageBoxA(0, "Connecting", 0, 0); + const auto text = buffer.read_vector(); + command::params_sv params(std::string(text.data(), text.size())); game::SV_DirectConnect(target); } diff --git a/src/client/component/network.cpp b/src/client/component/network.cpp index 4dbe5f1a..9a722405 100644 --- a/src/client/component/network.cpp +++ b/src/client/component/network.cpp @@ -35,7 +35,18 @@ namespace network const std::basic_string_view data(message->data + offset, message->cursize - offset); - handler->second(*address, data); + try + { + handler->second(*address, data); + } + catch (const std::exception& e) + { + printf("Error: %s\n", e.what()); + } + catch (...) + { + } + return 0; } diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index bf5caebe..be598d14 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -36,7 +36,7 @@ namespace party } void connect_to_lobby(const game::netadr_t& addr, const std::string& mapname, const std::string& gamemode, - const std::string& pub_id) + const std::string& pub_id) { workshop::load_usermap_mod_if_needed(pub_id); @@ -55,7 +55,8 @@ namespace party } void connect_to_lobby_with_mode(const game::netadr_t& addr, const game::eModes mode, const std::string& mapname, - const std::string& gametype, const std::string& pub_id, const bool was_retried = false) + const std::string& gametype, const std::string& pub_id, + const bool was_retried = false) { if (game::Com_SessionMode_IsMode(mode)) { @@ -144,6 +145,13 @@ namespace party is_connecting_to_dedi = info.get("dedicated") == "1"; + if (atoi(info.get("protocol").data()) != PROTOCOL) + { + const auto str = "Invalid protocol."; + printf("%s\n", str); + return; + } + const auto gamename = info.get("gamename"); if (gamename != "T7"s) { diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index be6386f3..f48fb2eb 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1,6 +1,6 @@ #pragma once -#define PROTOCOL 1 +#define PROTOCOL 2 #ifdef __cplusplus namespace game diff --git a/src/common/utils/byte_buffer.cpp b/src/common/utils/byte_buffer.cpp new file mode 100644 index 00000000..c471858a --- /dev/null +++ b/src/common/utils/byte_buffer.cpp @@ -0,0 +1,85 @@ +#include "byte_buffer.hpp" + +#include +#include + +namespace utils +{ + byte_buffer::byte_buffer() + : writing_(true) + { + } + + byte_buffer::byte_buffer(std::string buffer) + : writing_(false) + , buffer_(std::move(buffer)) + { + } + + void byte_buffer::write(const void* buffer, const size_t length) + { + if (!writing_) + { + throw std::runtime_error("Writing to readable byte buffer"); + } + + buffer_.append(static_cast(buffer), length); + } + + void byte_buffer::read(void* data, const size_t length) + { + if (writing_) + { + throw std::runtime_error("Reading from writable byte buffer"); + } + + if (offset_ + length > buffer_.size()) + { + throw std::runtime_error("Out of bounds read from byte buffer"); + } + + memcpy(data, buffer_.data() + offset_, length); + offset_ += length; + } + + std::string byte_buffer::read_string() + { + std::string result{}; + + while (true) + { + const auto b = read(); + if (!b) + { + break; + } + + result.push_back(b); + } + + return result; + } + + std::string byte_buffer::read_string(const size_t length) + { + std::string result{}; + result.reserve(length); + + for (size_t i = 0; i < length; ++i) + { + result.push_back(read()); + } + + return result; + } + + std::vector byte_buffer::read_data(const size_t length) + { + std::vector result{}; + result.resize(length); + + read(result.data(), result.size()); + + return result; + } +} diff --git a/src/common/utils/byte_buffer.hpp b/src/common/utils/byte_buffer.hpp new file mode 100644 index 00000000..662a5919 --- /dev/null +++ b/src/common/utils/byte_buffer.hpp @@ -0,0 +1,91 @@ +#pragma once + +#include +#include + +namespace utils +{ + class byte_buffer + { + public: + byte_buffer(); + byte_buffer(std::string buffer); + + template + byte_buffer(const std::basic_string_view& buffer) + : byte_buffer(std::string(reinterpret_cast(buffer.data()), buffer.size() * sizeof(T))) + { + } + + void write(const void* buffer, size_t length); + + void write(const std::string& string, const bool null_terminate = false) + { + const size_t addend = null_terminate ? 1 : 0; + write(string.data(), string.size() + addend); + } + + void write_string(const std::string& string) + { + write(string, true); + } + + template + void write(const T& object) + { + write(&object, sizeof(object)); + } + + template + void write(const std::vector& vec) + { + write(vec.data(), vec.size() * sizeof(T)); + } + + template + void write_vector(const std::vector& vec) + { + write(static_cast(vec.size())); + write(vec); + } + + const std::string& get_buffer() const + { + return buffer_; + } + + std::string move_buffer() + { + return std::move(buffer_); + } + + void read(void* data, size_t length); + + template + T read() + { + T object{}; + read(&object, sizeof(object)); + return object; + } + + template + std::vector read_vector() + { + std::vector result{}; + result.resize(read()); + read(result.data(), result.size() * sizeof(T)); + + return result; + } + + std::string read_string(); + std::string read_string(size_t length); + std::vector read_data(size_t length); + + private: + bool writing_{false}; + size_t offset_{0}; + std::string buffer_{}; + }; +} From 077167e81baa6c434c7b622e149b60c75b78b09f Mon Sep 17 00:00:00 2001 From: Maurice Heumann Date: Tue, 4 Apr 2023 18:23:10 +0200 Subject: [PATCH 03/23] Fix bytebuffer --- src/common/utils/byte_buffer.cpp | 1 - src/common/utils/byte_buffer.hpp | 10 ++++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/common/utils/byte_buffer.cpp b/src/common/utils/byte_buffer.cpp index c471858a..2ef0a3b0 100644 --- a/src/common/utils/byte_buffer.cpp +++ b/src/common/utils/byte_buffer.cpp @@ -1,7 +1,6 @@ #include "byte_buffer.hpp" #include -#include namespace utils { diff --git a/src/common/utils/byte_buffer.hpp b/src/common/utils/byte_buffer.hpp index 662a5919..6a801968 100644 --- a/src/common/utils/byte_buffer.hpp +++ b/src/common/utils/byte_buffer.hpp @@ -2,6 +2,7 @@ #include #include +#include namespace utils { @@ -73,8 +74,13 @@ namespace utils std::vector read_vector() { std::vector result{}; - result.resize(read()); - read(result.data(), result.size() * sizeof(T)); + const auto size = read(); + if (offset_ + size > buffer_.size()) + { + throw std::runtime_error("Out of bounds read from byte buffer"); + } + + read(result.data(), size); return result; } From 23c7228214d8442bc047d273d5c5d978c633f5ae Mon Sep 17 00:00:00 2001 From: Diavolo Date: Mon, 3 Apr 2023 19:14:45 +0200 Subject: [PATCH 04/23] fix getguid & getxuid --- src/client/component/bots.cpp | 2 ++ src/client/component/dedicated_patches.cpp | 20 ++++++++++++++++++++ src/client/game/structs.hpp | 4 ++++ src/client/game/symbols.hpp | 6 ++++++ 4 files changed, 32 insertions(+) diff --git a/src/client/component/bots.cpp b/src/client/component/bots.cpp index 2f334f62..0d06afd0 100644 --- a/src/client/component/bots.cpp +++ b/src/client/component/bots.cpp @@ -115,6 +115,8 @@ namespace bots struct component final : generic_component { + static_assert(offsetof(game::client_s, bIsTestClient) == 0xBB360); + void post_unpack() override { utils::hook::jump(game::select(0x141653B70, 0x1402732E0), get_bot_name); diff --git a/src/client/component/dedicated_patches.cpp b/src/client/component/dedicated_patches.cpp index 45a961c1..bb936719 100644 --- a/src/client/component/dedicated_patches.cpp +++ b/src/client/component/dedicated_patches.cpp @@ -67,10 +67,27 @@ namespace dedicated_patches spawn_server_hook.invoke(controllerIndex, server, preload, savegame); } + + uint64_t sv_get_player_xuid_stub(int client_num) + { + return game::svs_clients[client_num].xuid; + } + + int sv_get_guid(int client_num) + { + if (client_num < 0 || client_num >= game::Dvar_GetInt(*game::com_maxclients)) + { + return 0; + } + + return game::svs_clients[client_num].xuid; + } } struct component final : server_component { + static_assert(offsetof(game::client_s, xuid) == 0xBB354); + void post_unpack() override { // Fix infinite loop @@ -90,6 +107,9 @@ namespace dedicated_patches // Don't count server as client utils::hook::jump(0x14052F0F5_g, 0x14052F139_g); + + utils::hook::call(0x1402853D7_g, sv_get_player_xuid_stub); // PlayerCmd_GetXuid + utils::hook::call(0x140283303_g, sv_get_guid); // PlayerCmd_GetGuid } }; } diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index f48fb2eb..6ba49856 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1544,6 +1544,10 @@ namespace game struct client_s { + char __pad0[0xBB354]; + int xuid; + char __pad1[0x8]; + bool bIsTestClient; }; enum scriptInstance_t diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 4e325035..029c3d5f 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -104,6 +104,7 @@ namespace game WEAK symbol Dvar_GetString{0x1422BF590, 0x140575E30}; WEAK symbol Dvar_DisplayableValue{0x1422BC080}; WEAK symbol Dvar_GetBool{0x1422BCED0}; + WEAK symbol Dvar_GetInt{0x0, 0x140575C20}; WEAK symbol Dvar_RegisterBool{ 0x1422D0900, 0x14057B500 @@ -189,6 +190,11 @@ namespace game WEAK symbol s_dvarPool{0x157AC6220, 0x14A3CB620}; WEAK symbol g_dvarCount{0x157AC61CC, 0x14A3CB5FC}; + WEAK symbol svs_clients{0x0, 0x14A178E98}; + + // Dvar variables + WEAK symbol com_maxclients{0x0, 0x14948EE70}; + namespace s_wcd { WEAK symbol codLogo{0x157E75A50, 0x14A640BC0}; From fcec2f9b89d6873fe6a7d42864891f976a074274 Mon Sep 17 00:00:00 2001 From: Diavolo Date: Mon, 3 Apr 2023 19:18:37 +0200 Subject: [PATCH 05/23] forgot to fill out rest of struct --- src/client/game/structs.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 6ba49856..9e6cd35a 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1548,8 +1548,11 @@ namespace game int xuid; char __pad1[0x8]; bool bIsTestClient; + char __pad2[0x29DAC]; }; + static_assert(sizeof(client_s) == 0xE5110); + enum scriptInstance_t { SCRIPTINSTANCE_SERVER = 0x0, From 4e713355f2cd4321dbb4b389852a76aba6e869be Mon Sep 17 00:00:00 2001 From: Edo Date: Mon, 3 Apr 2023 19:54:45 +0200 Subject: [PATCH 06/23] dedicated_patche: handle conversion to unsigned --- src/client/component/dedicated_patches.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/component/dedicated_patches.cpp b/src/client/component/dedicated_patches.cpp index bb936719..307f1095 100644 --- a/src/client/component/dedicated_patches.cpp +++ b/src/client/component/dedicated_patches.cpp @@ -70,7 +70,7 @@ namespace dedicated_patches uint64_t sv_get_player_xuid_stub(int client_num) { - return game::svs_clients[client_num].xuid; + return static_cast(game::svs_clients[client_num].xuid); } int sv_get_guid(int client_num) From 5ca61c83530f6e3f1f7dd77d216543c8f58b6d5a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 18:03:23 +0000 Subject: [PATCH 07/23] Bump deps/libtommath from `886126c` to `53fdf5f` Bumps [deps/libtommath](https://github.com/libtom/libtommath) from `886126c` to `53fdf5f`. - [Release notes](https://github.com/libtom/libtommath/releases) - [Commits](https://github.com/libtom/libtommath/compare/886126cb45bac67da77f4238bef6ffb843e9e26f...53fdf5f9c73cb4fde599dd07e54bac8264f7b236) --- updated-dependencies: - dependency-name: deps/libtommath dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/libtommath | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/libtommath b/deps/libtommath index 886126cb..53fdf5f9 160000 --- a/deps/libtommath +++ b/deps/libtommath @@ -1 +1 @@ -Subproject commit 886126cb45bac67da77f4238bef6ffb843e9e26f +Subproject commit 53fdf5f9c73cb4fde599dd07e54bac8264f7b236 From 6686f9f2ea3e79c14bc83d8ee4b36cce2ba448f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 18:03:29 +0000 Subject: [PATCH 08/23] Bump deps/curl from `3797f1a` to `a13ef31` Bumps [deps/curl](https://github.com/curl/curl) from `3797f1a` to `a13ef31`. - [Release notes](https://github.com/curl/curl/releases) - [Commits](https://github.com/curl/curl/compare/3797f1a4ca8fbd1c73a93ea973a3a6931b6e689b...a13ef31d0fbbf98120b711746bd8802acaba6b0a) --- updated-dependencies: - dependency-name: deps/curl dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/curl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/curl b/deps/curl index 3797f1a4..a13ef31d 160000 --- a/deps/curl +++ b/deps/curl @@ -1 +1 @@ -Subproject commit 3797f1a4ca8fbd1c73a93ea973a3a6931b6e689b +Subproject commit a13ef31d0fbbf98120b711746bd8802acaba6b0a From 9ffb5d62445d92daf1c2f3e91928fccc18a7f50c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 18:03:48 +0000 Subject: [PATCH 09/23] Bump deps/libtomcrypt from `05f9407` to `fae62af` Bumps [deps/libtomcrypt](https://github.com/libtom/libtomcrypt) from `05f9407` to `fae62af`. - [Release notes](https://github.com/libtom/libtomcrypt/releases) - [Commits](https://github.com/libtom/libtomcrypt/compare/05f94077cc0aa42f550e85d2785a92b668117ada...fae62af0ab16f469c2512ec04575dd60ca018657) --- updated-dependencies: - dependency-name: deps/libtomcrypt dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/libtomcrypt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/libtomcrypt b/deps/libtomcrypt index 05f94077..fae62af0 160000 --- a/deps/libtomcrypt +++ b/deps/libtomcrypt @@ -1 +1 @@ -Subproject commit 05f94077cc0aa42f550e85d2785a92b668117ada +Subproject commit fae62af0ab16f469c2512ec04575dd60ca018657 From 45b1462dca41c6e85262cb391256a05f67a06fb1 Mon Sep 17 00:00:00 2001 From: Diavolo Date: Mon, 3 Apr 2023 21:51:30 +0200 Subject: [PATCH 10/23] fix: forgot to * the array of clients --- src/client/component/dedicated_patches.cpp | 4 ++-- src/client/game/symbols.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/component/dedicated_patches.cpp b/src/client/component/dedicated_patches.cpp index 307f1095..b535a7be 100644 --- a/src/client/component/dedicated_patches.cpp +++ b/src/client/component/dedicated_patches.cpp @@ -70,7 +70,7 @@ namespace dedicated_patches uint64_t sv_get_player_xuid_stub(int client_num) { - return static_cast(game::svs_clients[client_num].xuid); + return static_cast((*game::svs_clients)[client_num].xuid); } int sv_get_guid(int client_num) @@ -80,7 +80,7 @@ namespace dedicated_patches return 0; } - return game::svs_clients[client_num].xuid; + return (*game::svs_clients)[client_num].xuid; } } diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 029c3d5f..c2fd5aec 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -190,7 +190,7 @@ namespace game WEAK symbol s_dvarPool{0x157AC6220, 0x14A3CB620}; WEAK symbol g_dvarCount{0x157AC61CC, 0x14A3CB5FC}; - WEAK symbol svs_clients{0x0, 0x14A178E98}; + WEAK symbol svs_clients{0x0, 0x14A178E98}; // Dvar variables WEAK symbol com_maxclients{0x0, 0x14948EE70}; From 04ad73f5ea5611fccce42d74b406a7d36c68b578 Mon Sep 17 00:00:00 2001 From: Diavolo Date: Mon, 3 Apr 2023 21:54:00 +0200 Subject: [PATCH 11/23] fix: this function did not need to be patched. Oops --- src/client/component/dedicated_patches.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/client/component/dedicated_patches.cpp b/src/client/component/dedicated_patches.cpp index b535a7be..06c943ce 100644 --- a/src/client/component/dedicated_patches.cpp +++ b/src/client/component/dedicated_patches.cpp @@ -72,16 +72,6 @@ namespace dedicated_patches { return static_cast((*game::svs_clients)[client_num].xuid); } - - int sv_get_guid(int client_num) - { - if (client_num < 0 || client_num >= game::Dvar_GetInt(*game::com_maxclients)) - { - return 0; - } - - return (*game::svs_clients)[client_num].xuid; - } } struct component final : server_component @@ -109,7 +99,6 @@ namespace dedicated_patches utils::hook::jump(0x14052F0F5_g, 0x14052F139_g); utils::hook::call(0x1402853D7_g, sv_get_player_xuid_stub); // PlayerCmd_GetXuid - utils::hook::call(0x140283303_g, sv_get_guid); // PlayerCmd_GetGuid } }; } From 34eca16e16cf58f25f7557038b0e99c5420e3af9 Mon Sep 17 00:00:00 2001 From: Diavolo Date: Tue, 4 Apr 2023 10:37:21 +0200 Subject: [PATCH 12/23] feat: implement sv_lanOnly & fix heart beat delay --- src/client/component/dedicated.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/client/component/dedicated.cpp b/src/client/component/dedicated.cpp index 6a5cde7f..9a66d959 100644 --- a/src/client/component/dedicated.cpp +++ b/src/client/component/dedicated.cpp @@ -15,6 +15,8 @@ namespace dedicated { namespace { + const game::dvar_t* sv_lan_only; + void sv_con_tell_f_stub(game::client_s* cl_0, game::svscmd_type type, [[maybe_unused]] const char* fmt, [[maybe_unused]] int c, char* text) { @@ -23,6 +25,11 @@ namespace dedicated void send_heartbeat_packet() { + if (sv_lan_only->current.value.enabled) + { + return; + } + game::netadr_t target{}; if (server_list::get_master_server(target)) { @@ -64,11 +71,14 @@ namespace dedicated // Fix tell command for IW4M utils::hook::call(0x14052A8CF_g, sv_con_tell_f_stub); + scheduler::once(send_heartbeat, scheduler::pipeline::main); scheduler::loop(send_heartbeat, scheduler::pipeline::main, 5min); command::add("heartbeat", send_heartbeat); // Hook GScr_ExitLevel utils::hook::jump(0x1402D1AA0_g, trigger_map_rotation); + + sv_lan_only = game::register_dvar_bool("sv_lanOnly", false, game::DVAR_NONE, "Don't send heartbeats"); } }; } From fcd41ddca8160b376478335e8494b8c41ff0c3f8 Mon Sep 17 00:00:00 2001 From: Maurice Heumann Date: Tue, 4 Apr 2023 20:40:20 +0200 Subject: [PATCH 13/23] Temporarily disable hooks --- src/client/component/auth.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 4a76dddb..fba96ad8 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -155,8 +155,8 @@ namespace auth void post_unpack() override { // Skip connect handler - utils::hook::set(game::select(0x142253EFA, 0x14053714A), 0xEB); - network::on("connect", handle_connect_packet); + //utils::hook::set(game::select(0x142253EFA, 0x14053714A), 0xEB); + //network::on("connect", handle_connect_packet); // Patch steam id bit check std::vector> patches{}; @@ -203,7 +203,7 @@ namespace auth p(0x141EB5992_g, 0x141EB59D5_g); p(0x141EB74D2_g, 0x141EB7515_g); // ? - utils::hook::call(0x14134BF7D_g, send_connect_data_stub); + //utils::hook::call(0x14134BF7D_g, send_connect_data_stub); } for (const auto& patch : patches) From 163f9c53b871c233c0be1bf13b2a3031e705d713 Mon Sep 17 00:00:00 2001 From: Maurice Heumann Date: Tue, 4 Apr 2023 20:40:48 +0200 Subject: [PATCH 14/23] Some cleanup and svs_clients --- src/client/component/command.cpp | 19 +++++----- src/client/component/dedicated_patches.cpp | 43 ++++++++++++---------- src/client/component/getinfo.cpp | 23 ++++++++---- src/client/game/structs.hpp | 25 +++++++++++-- src/client/game/symbols.hpp | 2 + 5 files changed, 72 insertions(+), 40 deletions(-) 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 From 70ea07fd905c986000b32435207b3267f8dd8b9e Mon Sep 17 00:00:00 2001 From: momo5502 Date: Thu, 6 Apr 2023 21:16:42 +0200 Subject: [PATCH 15/23] Fix bytebuffer --- src/client/component/auth.cpp | 6 +++--- src/common/utils/byte_buffer.cpp | 18 +++++++++--------- src/common/utils/byte_buffer.hpp | 25 ++++++++++++++----------- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index fba96ad8..4a76dddb 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -155,8 +155,8 @@ namespace auth void post_unpack() override { // Skip connect handler - //utils::hook::set(game::select(0x142253EFA, 0x14053714A), 0xEB); - //network::on("connect", handle_connect_packet); + utils::hook::set(game::select(0x142253EFA, 0x14053714A), 0xEB); + network::on("connect", handle_connect_packet); // Patch steam id bit check std::vector> patches{}; @@ -203,7 +203,7 @@ namespace auth p(0x141EB5992_g, 0x141EB59D5_g); p(0x141EB74D2_g, 0x141EB7515_g); // ? - //utils::hook::call(0x14134BF7D_g, send_connect_data_stub); + utils::hook::call(0x14134BF7D_g, send_connect_data_stub); } for (const auto& patch : patches) diff --git a/src/common/utils/byte_buffer.cpp b/src/common/utils/byte_buffer.cpp index 2ef0a3b0..76e02a00 100644 --- a/src/common/utils/byte_buffer.cpp +++ b/src/common/utils/byte_buffer.cpp @@ -17,28 +17,28 @@ namespace utils void byte_buffer::write(const void* buffer, const size_t length) { - if (!writing_) + if (!this->writing_) { throw std::runtime_error("Writing to readable byte buffer"); } - buffer_.append(static_cast(buffer), length); + this->buffer_.append(static_cast(buffer), length); } void byte_buffer::read(void* data, const size_t length) { - if (writing_) + if (this->writing_) { throw std::runtime_error("Reading from writable byte buffer"); } - if (offset_ + length > buffer_.size()) + if (this->offset_ + length > this->buffer_.size()) { throw std::runtime_error("Out of bounds read from byte buffer"); } - memcpy(data, buffer_.data() + offset_, length); - offset_ += length; + memcpy(data, this->buffer_.data() + this->offset_, length); + this->offset_ += length; } std::string byte_buffer::read_string() @@ -47,7 +47,7 @@ namespace utils while (true) { - const auto b = read(); + const auto b = this->read(); if (!b) { break; @@ -66,7 +66,7 @@ namespace utils for (size_t i = 0; i < length; ++i) { - result.push_back(read()); + result.push_back(this->read()); } return result; @@ -77,7 +77,7 @@ namespace utils std::vector result{}; result.resize(length); - read(result.data(), result.size()); + this->read(result.data(), result.size()); return result; } diff --git a/src/common/utils/byte_buffer.hpp b/src/common/utils/byte_buffer.hpp index 6a801968..8989cbbd 100644 --- a/src/common/utils/byte_buffer.hpp +++ b/src/common/utils/byte_buffer.hpp @@ -23,41 +23,41 @@ namespace utils void write(const std::string& string, const bool null_terminate = false) { const size_t addend = null_terminate ? 1 : 0; - write(string.data(), string.size() + addend); + this->write(string.data(), string.size() + addend); } void write_string(const std::string& string) { - write(string, true); + this->write(string, true); } template void write(const T& object) { - write(&object, sizeof(object)); + this->write(&object, sizeof(object)); } template void write(const std::vector& vec) { - write(vec.data(), vec.size() * sizeof(T)); + this->write(vec.data(), vec.size() * sizeof(T)); } template void write_vector(const std::vector& vec) { - write(static_cast(vec.size())); - write(vec); + this->write(static_cast(vec.size())); + this->write(vec); } const std::string& get_buffer() const { - return buffer_; + return this->buffer_; } std::string move_buffer() { - return std::move(buffer_); + return std::move(this->buffer_); } void read(void* data, size_t length); @@ -66,7 +66,7 @@ namespace utils T read() { T object{}; - read(&object, sizeof(object)); + this->read(&object, sizeof(object)); return object; } @@ -75,12 +75,15 @@ namespace utils { std::vector result{}; const auto size = read(); - if (offset_ + size > buffer_.size()) + const auto totalSize = size * sizeof(T); + + if (this->offset_ + totalSize > this->buffer_.size()) { throw std::runtime_error("Out of bounds read from byte buffer"); } - read(result.data(), size); + result.resize(size); + this->read(result.data(), totalSize); return result; } From c569ed5d8dc23a3222f7c5eb7db8e2f64fe6d194 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Thu, 6 Apr 2023 22:04:20 +0200 Subject: [PATCH 16/23] Prepare profile info distribution --- src/client/component/auth.cpp | 31 ++++++++++----- src/client/component/profile_infos.cpp | 55 +++++++++++++++++++++----- src/client/component/profile_infos.hpp | 14 ++++++- src/common/utils/byte_buffer.cpp | 31 --------------- src/common/utils/byte_buffer.hpp | 37 ++++++++++++----- src/common/utils/info_string.cpp | 5 +++ src/common/utils/info_string.hpp | 5 ++- 7 files changed, 116 insertions(+), 62 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 4a76dddb..22086bce 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -4,6 +4,7 @@ #include "auth.hpp" #include "command.hpp" #include "network.hpp" +#include "profile_infos.hpp" #include @@ -15,6 +16,7 @@ #include #include + namespace auth { namespace @@ -95,10 +97,10 @@ namespace auth return !is_first; } - std::string serialize_connect_data(const std::vector& data) + std::string serialize_connect_data(const char* data, const int length) { utils::byte_buffer buffer{}; - buffer.write_vector(data); + buffer.write_string(data, static_cast(length)); return buffer.move_buffer(); } @@ -110,12 +112,9 @@ namespace auth const auto is_connect_sequence = len >= 7 && strncmp("connect", data, 7) == 0; if (is_connect_sequence) { - std::vector connect_data{}; - connect_data.assign(data, data + len); - buffer.append("connect"); buffer.push_back(' '); - buffer.append(serialize_connect_data(connect_data)); + buffer.append(serialize_connect_data(data, len)); data = buffer.data(); len = static_cast(buffer.size()); @@ -126,10 +125,24 @@ namespace auth void handle_connect_packet(const game::netadr_t& target, const network::data_view& data) { - utils::byte_buffer buffer(data); + // TODO: SV running? - const auto text = buffer.read_vector(); - command::params_sv params(std::string(text.data(), text.size())); + utils::byte_buffer buffer(data); + profile_infos::profile_info info(buffer); + + const auto connect_data = buffer.read_string(); + const command::params_sv params(connect_data); + + if (params.size() != 2) + { + return; + } + + const utils::info_string info_string(params[1]); + const auto xuid = strtoull(info_string.get("xuid").data(), nullptr, 10); + + profile_infos::add_profile_info(xuid, std::move(info)); + profile_infos::distribute_profile_infos(); game::SV_DirectConnect(target); } diff --git a/src/client/component/profile_infos.cpp b/src/client/component/profile_infos.cpp index d03ccc49..10ea2ad9 100644 --- a/src/client/component/profile_infos.cpp +++ b/src/client/component/profile_infos.cpp @@ -3,6 +3,7 @@ #include "profile_infos.hpp" #include "network.hpp" +#include "party.hpp" #include #include @@ -29,7 +30,7 @@ namespace profile_infos profile_info info{}; constexpr auto version_size = sizeof(info.version); - if(data.size() < sizeof(version_size)) + if (data.size() < sizeof(version_size)) { return {}; } @@ -37,10 +38,40 @@ namespace profile_infos memcpy(&info.version, data.data(), version_size); info.ddl.assign(data.begin() + version_size, data.end()); - return { std::move(info) }; + return {std::move(info)}; } } + profile_info::profile_info(utils::byte_buffer& buffer) + { + this->version = buffer.read(); + this->ddl = buffer.read_string(); + } + + void profile_info::serialize(utils::byte_buffer& buffer) const + { + buffer.write(this->version); + buffer.write_string(this->ddl); + } + + void add_profile_info(const uint64_t user_id, profile_info info) + { + if (user_id == steam::SteamUser()->GetSteamID().bits) + { + return; + } + + profile_mapping.access([&](profile_map& profiles) + { + profiles[user_id] = std::move(info); + }); + } + + void distribute_profile_infos() + { + // TODO + } + std::optional get_profile_info(uint64_t user_id) { if (user_id == steam::SteamUser()->GetSteamID().bits) @@ -73,17 +104,23 @@ namespace profile_infos utils::io::write_file("players/user/profile_info", data); } - struct component final : generic_component + struct component final : client_component { - void post_load() override - { - } - void post_unpack() override { - /*network::on("profileInfo", [](const game::netadr_t& server, const network::data_view& data) + network::on("profileInfo", [](const game::netadr_t& server, const network::data_view& data) { - });*/ + if (party::get_connected_server() != server) + { + return; + } + + utils::byte_buffer buffer(data); + const auto user_id = buffer.read(); + const profile_info info(buffer); + + add_profile_info(user_id, info); + }); } }; } diff --git a/src/client/component/profile_infos.hpp b/src/client/component/profile_infos.hpp index e0f8cf5d..f875bf67 100644 --- a/src/client/component/profile_infos.hpp +++ b/src/client/component/profile_infos.hpp @@ -1,13 +1,23 @@ #pragma once +#include + namespace profile_infos { struct profile_info { - int32_t version; - std::string ddl; + int32_t version{3}; + std::string ddl{}; + + profile_info() = default; + profile_info(utils::byte_buffer& buffer); + void serialize(utils::byte_buffer& buffer) const; }; + void add_profile_info(uint64_t user_id, profile_info info); + + void distribute_profile_infos(); + std::optional get_profile_info(uint64_t user_id); void update_profile_info(const profile_info& info); } diff --git a/src/common/utils/byte_buffer.cpp b/src/common/utils/byte_buffer.cpp index 76e02a00..7a3d5b94 100644 --- a/src/common/utils/byte_buffer.cpp +++ b/src/common/utils/byte_buffer.cpp @@ -41,37 +41,6 @@ namespace utils this->offset_ += length; } - std::string byte_buffer::read_string() - { - std::string result{}; - - while (true) - { - const auto b = this->read(); - if (!b) - { - break; - } - - result.push_back(b); - } - - return result; - } - - std::string byte_buffer::read_string(const size_t length) - { - std::string result{}; - result.reserve(length); - - for (size_t i = 0; i < length; ++i) - { - result.push_back(this->read()); - } - - return result; - } - std::vector byte_buffer::read_data(const size_t length) { std::vector result{}; diff --git a/src/common/utils/byte_buffer.hpp b/src/common/utils/byte_buffer.hpp index 8989cbbd..c4c33ec7 100644 --- a/src/common/utils/byte_buffer.hpp +++ b/src/common/utils/byte_buffer.hpp @@ -20,15 +20,20 @@ namespace utils void write(const void* buffer, size_t length); - void write(const std::string& string, const bool null_terminate = false) + void write_string(const char* str, const size_t length) { - const size_t addend = null_terminate ? 1 : 0; - this->write(string.data(), string.size() + addend); + this->write(static_cast(length)); + this->write(str, length); } - void write_string(const std::string& string) + void write_string(const std::string& str) { - this->write(string, true); + this->write_string(str.data(), str.size()); + } + + void write_string(const char* str) + { + this->write_string(str, strlen(str)); } template @@ -46,7 +51,7 @@ namespace utils template void write_vector(const std::vector& vec) { - this->write(static_cast(vec.size())); + this->write(static_cast(vec.size())); this->write(vec); } @@ -74,7 +79,7 @@ namespace utils std::vector read_vector() { std::vector result{}; - const auto size = read(); + const auto size = this->read(); const auto totalSize = size * sizeof(T); if (this->offset_ + totalSize > this->buffer_.size()) @@ -88,8 +93,22 @@ namespace utils return result; } - std::string read_string(); - std::string read_string(size_t length); + std::string read_string() + { + std::string result{}; + const auto size = this->read(); + + if (this->offset_ + size > this->buffer_.size()) + { + throw std::runtime_error("Out of bounds read from byte buffer"); + } + + result.resize(size); + this->read(result.data(), size); + + return result; + } + std::vector read_data(size_t length); private: diff --git a/src/common/utils/info_string.cpp b/src/common/utils/info_string.cpp index bdb3ad1f..d6f401ea 100644 --- a/src/common/utils/info_string.cpp +++ b/src/common/utils/info_string.cpp @@ -8,6 +8,11 @@ namespace utils this->parse(buffer); } + info_string::info_string(const char* buffer) + : info_string(std::string{buffer}) + { + } + info_string::info_string(const std::string_view& buffer) : info_string(std::string{buffer}) { diff --git a/src/common/utils/info_string.hpp b/src/common/utils/info_string.hpp index 776739ab..4e3e4bc9 100644 --- a/src/common/utils/info_string.hpp +++ b/src/common/utils/info_string.hpp @@ -9,8 +9,9 @@ namespace utils { public: info_string() = default; - info_string(const std::string& buffer); - info_string(const std::string_view& buffer); + explicit info_string(const std::string& buffer); + explicit info_string(const char* buffer); + explicit info_string(const std::string_view& buffer); info_string(const std::basic_string_view& buffer); void set(const std::string& key, const std::string& value); From 26a56b0602114a5d787329be65311c78cd11982d Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 7 Apr 2023 09:01:36 +0200 Subject: [PATCH 17/23] More profile info progress --- src/client/component/auth.cpp | 3 +- src/client/component/party.cpp | 7 ++ src/client/component/party.hpp | 2 + src/client/component/profile_infos.cpp | 94 ++++++++++++++++++++++++-- src/client/component/profile_infos.hpp | 7 +- 5 files changed, 101 insertions(+), 12 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 22086bce..cc909f66 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -141,8 +141,7 @@ namespace auth const utils::info_string info_string(params[1]); const auto xuid = strtoull(info_string.get("xuid").data(), nullptr, 10); - profile_infos::add_profile_info(xuid, std::move(info)); - profile_infos::distribute_profile_infos(); + profile_infos::add_and_distribute_profile_info(target, xuid, info); game::SV_DirectConnect(target); } diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index be598d14..7a80a301 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -6,6 +6,7 @@ #include "network.hpp" #include "scheduler.hpp" #include "workshop.hpp" +#include "profile_infos.hpp" #include #include @@ -211,6 +212,7 @@ namespace party connect_host = target; } + profile_infos::clear_profile_infos(); query_server(connect_host, handle_connect_query_response); } @@ -314,6 +316,11 @@ namespace party return *reinterpret_cast(address); } + bool is_host(const game::netadr_t& addr) + { + return get_connected_server() == addr || connect_host == addr; + } + struct component final : client_component { void post_unpack() override diff --git a/src/client/component/party.hpp b/src/client/component/party.hpp index 4bca8966..f682a14e 100644 --- a/src/client/component/party.hpp +++ b/src/client/component/party.hpp @@ -9,4 +9,6 @@ namespace party void query_server(const game::netadr_t& host, query_callback callback); game::netadr_t get_connected_server(); + + bool is_host(const game::netadr_t& addr); } diff --git a/src/client/component/profile_infos.cpp b/src/client/component/profile_infos.cpp index 10ea2ad9..576217b1 100644 --- a/src/client/component/profile_infos.cpp +++ b/src/client/component/profile_infos.cpp @@ -12,12 +12,14 @@ #include "../steam/steam.hpp" #include +#include "game/utils.hpp" + namespace profile_infos { namespace { using profile_map = std::unordered_map; - utils::concurrency::container profile_mapping; + utils::concurrency::container profile_mapping{}; std::optional load_profile_info() { @@ -40,6 +42,49 @@ namespace profile_infos 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) + { + network::send(address, "profileInfo", buffer); + } + + template + 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) + { + utils::byte_buffer buffer{}; + buffer.write(user_id); + info.serialize(buffer); + + if (game::is_server()) + { + distribute_profile_info(*game::svs_clients, buffer.get_buffer()); + } + else + { + distribute_profile_info(*game::svs_clients_cl, buffer.get_buffer()); + } + } } profile_info::profile_info(utils::byte_buffer& buffer) @@ -54,26 +99,61 @@ namespace profile_infos buffer.write_string(this->ddl); } - void add_profile_info(const uint64_t user_id, profile_info info) + void add_profile_info(const uint64_t user_id, const profile_info& info) { if (user_id == steam::SteamUser()->GetSteamID().bits) { return; } + printf("Adding profile info: %llX\n", user_id); + profile_mapping.access([&](profile_map& profiles) { - profiles[user_id] = std::move(info); + profiles[user_id] = info; }); } - void distribute_profile_infos() + void distribute_profile_info_to_user(const game::netadr_t& addr, const uint64_t user_id, const profile_info& info) { - // TODO + utils::byte_buffer buffer{}; + buffer.write(user_id); + info.serialize(buffer); + + send_profile_info(addr, buffer.get_buffer()); } - std::optional get_profile_info(uint64_t user_id) + void distribute_profile_infos_to_user(const game::netadr_t& addr) { + profile_mapping.access([&](const profile_map& profiles) + { + for (const auto& entry : profiles) + { + distribute_profile_info_to_user(addr, entry.first, entry.second); + } + }); + } + + void add_and_distribute_profile_info(const game::netadr_t& addr, const uint64_t user_id, const profile_info& info) + { + distribute_profile_infos_to_user(addr); + + add_profile_info(user_id, info); + distribute_profile_info(user_id, info); + } + + void clear_profile_infos() + { + profile_mapping.access([&](profile_map& profiles) + { + profiles = {}; + }); + } + + std::optional get_profile_info(const uint64_t user_id) + { + printf("Requesting profile info: %llX\n", user_id); + if (user_id == steam::SteamUser()->GetSteamID().bits) { return load_profile_info(); @@ -110,7 +190,7 @@ namespace profile_infos { network::on("profileInfo", [](const game::netadr_t& server, const network::data_view& data) { - if (party::get_connected_server() != server) + if (!party::is_host(server)) { return; } diff --git a/src/client/component/profile_infos.hpp b/src/client/component/profile_infos.hpp index f875bf67..a417a545 100644 --- a/src/client/component/profile_infos.hpp +++ b/src/client/component/profile_infos.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include namespace profile_infos @@ -14,9 +15,9 @@ namespace profile_infos void serialize(utils::byte_buffer& buffer) const; }; - void add_profile_info(uint64_t user_id, profile_info info); - - void distribute_profile_infos(); + void add_profile_info(uint64_t user_id, const profile_info& info); + void add_and_distribute_profile_info(const game::netadr_t& addr, uint64_t user_id, const profile_info& info); + void clear_profile_infos(); std::optional get_profile_info(uint64_t user_id); void update_profile_info(const profile_info& info); From bee66b1e910cfa75b43f8ec129779d7ff49cc909 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 7 Apr 2023 10:46:09 +0200 Subject: [PATCH 18/23] Finish profile infos --- src/client/component/auth.cpp | 8 +++++--- src/client/component/profile_infos.cpp | 21 ++++++++++++++++++++- src/client/component/profile_infos.hpp | 2 ++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index cc909f66..a8bfd8eb 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -100,6 +100,8 @@ namespace auth std::string serialize_connect_data(const char* data, const int length) { utils::byte_buffer buffer{}; + profile_infos::get_profile_info().value_or(profile_infos::profile_info{}).serialize(buffer); + buffer.write_string(data, static_cast(length)); return buffer.move_buffer(); @@ -128,18 +130,18 @@ namespace auth // TODO: SV running? utils::byte_buffer buffer(data); - profile_infos::profile_info info(buffer); + const profile_infos::profile_info info(buffer); const auto connect_data = buffer.read_string(); const command::params_sv params(connect_data); - if (params.size() != 2) + if (params.size() < 2) { return; } const utils::info_string info_string(params[1]); - const auto xuid = strtoull(info_string.get("xuid").data(), nullptr, 10); + const auto xuid = strtoull(info_string.get("xuid").data(), nullptr, 16); profile_infos::add_and_distribute_profile_info(target, xuid, info); diff --git a/src/client/component/profile_infos.cpp b/src/client/component/profile_infos.cpp index 576217b1..24c9ba68 100644 --- a/src/client/component/profile_infos.cpp +++ b/src/client/component/profile_infos.cpp @@ -72,6 +72,11 @@ namespace profile_infos void distribute_profile_info(const uint64_t user_id, const profile_info& info) { + if (user_id == steam::SteamUser()->GetSteamID().bits) + { + return; + } + utils::byte_buffer buffer{}; buffer.write(user_id); info.serialize(buffer); @@ -132,6 +137,15 @@ namespace profile_infos distribute_profile_info_to_user(addr, entry.first, entry.second); } }); + + if (!game::is_server()) + { + const auto info = get_profile_info(); + if (info) + { + distribute_profile_info_to_user(addr, steam::SteamUser()->GetSteamID().bits, *info); + } + } } void add_and_distribute_profile_info(const game::netadr_t& addr, const uint64_t user_id, const profile_info& info) @@ -150,13 +164,18 @@ namespace profile_infos }); } + std::optional get_profile_info() + { + return load_profile_info(); + } + std::optional get_profile_info(const uint64_t user_id) { printf("Requesting profile info: %llX\n", user_id); if (user_id == steam::SteamUser()->GetSteamID().bits) { - return load_profile_info(); + return get_profile_info(); } return profile_mapping.access>([user_id](const profile_map& profiles) diff --git a/src/client/component/profile_infos.hpp b/src/client/component/profile_infos.hpp index a417a545..c1cfd1f8 100644 --- a/src/client/component/profile_infos.hpp +++ b/src/client/component/profile_infos.hpp @@ -19,6 +19,8 @@ namespace profile_infos void add_and_distribute_profile_info(const game::netadr_t& addr, uint64_t user_id, const profile_info& info); void clear_profile_infos(); + + std::optional get_profile_info(); std::optional get_profile_info(uint64_t user_id); void update_profile_info(const profile_info& info); } From 363f8cb01a070795101ac07fdae43e26aec9d885 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 7 Apr 2023 12:12:19 +0200 Subject: [PATCH 19/23] Trigger pcache updates --- src/client/component/auth.cpp | 7 +++- src/client/component/profile_infos.cpp | 55 ++++++++++++++++++++------ src/client/game/symbols.hpp | 3 ++ 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index a8bfd8eb..7385be95 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -7,6 +7,7 @@ #include "profile_infos.hpp" #include +#include #include #include @@ -16,7 +17,6 @@ #include #include - namespace auth { namespace @@ -127,7 +127,10 @@ namespace auth void handle_connect_packet(const game::netadr_t& target, const network::data_view& data) { - // TODO: SV running? + if (!game::get_dvar_bool("sv_running")) + { + return; + } utils::byte_buffer buffer(data); const profile_infos::profile_info info(buffer); diff --git a/src/client/component/profile_infos.cpp b/src/client/component/profile_infos.cpp index 24c9ba68..46fa2c6d 100644 --- a/src/client/component/profile_infos.cpp +++ b/src/client/component/profile_infos.cpp @@ -4,6 +4,7 @@ #include "profile_infos.hpp" #include "network.hpp" #include "party.hpp" +#include "scheduler.hpp" #include #include @@ -90,6 +91,31 @@ namespace profile_infos distribute_profile_info(*game::svs_clients_cl, buffer.get_buffer()); } } + + void schedule_pcache_update() + { + static std::atomic_bool update_triggered{false}; + if (game::is_server() || update_triggered.exchange(true)) + { + return; + } + + scheduler::once([] + { + game::PCache_DeleteEntries(game::CONTROLLER_INDEX_FIRST); + update_triggered = false; + }, scheduler::main, 5s); + } + + void clean_cached_profile_infos() + { + if (!game::get_dvar_bool("sv_running")) + { + return; + } + + // TODO + } } profile_info::profile_info(utils::byte_buffer& buffer) @@ -111,12 +137,12 @@ namespace profile_infos return; } - printf("Adding profile info: %llX\n", user_id); - profile_mapping.access([&](profile_map& profiles) { profiles[user_id] = info; }); + + schedule_pcache_update(); } void distribute_profile_info_to_user(const game::netadr_t& addr, const uint64_t user_id, const profile_info& info) @@ -203,23 +229,28 @@ namespace profile_infos utils::io::write_file("players/user/profile_info", data); } - struct component final : client_component + struct component final : generic_component { void post_unpack() override { - network::on("profileInfo", [](const game::netadr_t& server, const network::data_view& data) + scheduler::loop(clean_cached_profile_infos, scheduler::main, 5s); + + if (game::is_client()) { - if (!party::is_host(server)) + network::on("profileInfo", [](const game::netadr_t& server, const network::data_view& data) { - return; - } + if (!party::is_host(server)) + { + return; + } - utils::byte_buffer buffer(data); - const auto user_id = buffer.read(); - const profile_info info(buffer); + utils::byte_buffer buffer(data); + const auto user_id = buffer.read(); + const profile_info info(buffer); - add_profile_info(user_id, info); - }); + add_profile_info(user_id, info); + }); + } } }; } diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 6abf5b32..4f666024 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -157,6 +157,9 @@ namespace game 0x141CD98D0 }; + // PCache + WEAK symbol PCache_DeleteEntries{0x141E8D710}; + // SV WEAK symbol SV_Loaded{0x142252250, 0x140535460}; WEAK symbol SV_AddTestClient{0x142248F40, 0x14052E3E0}; From 9e7a567acb123ba6c1e6f1abbc70a8f2bcce005d Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 7 Apr 2023 13:55:43 +0200 Subject: [PATCH 20/23] Fix xuid offset --- src/client/component/bots.cpp | 2 -- src/client/component/dedicated_patches.cpp | 2 +- src/client/game/structs.hpp | 16 ++++++++-------- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/client/component/bots.cpp b/src/client/component/bots.cpp index 0d06afd0..2f334f62 100644 --- a/src/client/component/bots.cpp +++ b/src/client/component/bots.cpp @@ -115,8 +115,6 @@ namespace bots struct component final : generic_component { - static_assert(offsetof(game::client_s, bIsTestClient) == 0xBB360); - void post_unpack() override { utils::hook::jump(game::select(0x141653B70, 0x1402732E0), get_bot_name); diff --git a/src/client/component/dedicated_patches.cpp b/src/client/component/dedicated_patches.cpp index 48ed8326..6e7f249e 100644 --- a/src/client/component/dedicated_patches.cpp +++ b/src/client/component/dedicated_patches.cpp @@ -76,7 +76,7 @@ namespace dedicated_patches return 0; } - return static_cast(clients[client_num].guid); + return clients[client_num].xuid; } } diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 9e35f729..1e852b6c 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1547,21 +1547,21 @@ namespace game int client_state; char __pad0[0x28]; netadr_t address; - char __pad1[0xBB318]; - int guid; - char __pad2[0x8]; - bool bIsTestClient; - char __pad3[0x25818]; + char __pad1[0x5588]; uint64_t xuid; - char __pad4[0x4588]; + char __pad2[0xB5D84]; + int guid; + char __pad3[0x8]; + bool bIsTestClient; + char __pad4[0x29DAC]; }; - static_assert(sizeof(client_s) == 0xE5110); + static_assert(sizeof(client_s) <= 0xE5110); static_assert(offsetof(game::client_s, address) == 0x2C); + static_assert(offsetof(game::client_s, xuid) == 0x55C8); 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 { From fd8460349f61d3698fe7759b5d1b34feb1c56f38 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 7 Apr 2023 14:25:56 +0200 Subject: [PATCH 21/23] Cleanup cached profile infos --- src/client/component/auth.cpp | 2 +- src/client/component/chat.cpp | 4 +- src/client/component/dedicated_info.cpp | 4 +- src/client/component/getinfo.cpp | 33 +++++------- src/client/component/getinfo.hpp | 5 +- src/client/component/profile_infos.cpp | 66 ++++++++++++----------- src/client/game/utils.cpp | 69 ++++++++++++++++++++++++- src/client/game/utils.hpp | 10 ++++ 8 files changed, 133 insertions(+), 60 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 7385be95..d5e2d4f6 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -127,7 +127,7 @@ namespace auth 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; } diff --git a/src/client/component/chat.cpp b/src/client/component/chat.cpp index 7bb8a52e..41b1b44a 100644 --- a/src/client/component/chat.cpp +++ b/src/client/component/chat.cpp @@ -122,7 +122,7 @@ namespace chat // Overwrite say command utils::hook::jump(0x14052A6C0_g, +[] { - if (!game::get_dvar_bool("sv_running")) + if (!game::is_server_running()) { printf("Server is not running\n"); return; @@ -138,7 +138,7 @@ namespace chat // Overwrite tell command utils::hook::jump(0x14052A7E0_g, +[] { - if (!game::get_dvar_bool("sv_running")) + if (!game::is_server_running()) { printf("Server is not running\n"); return; diff --git a/src/client/component/dedicated_info.cpp b/src/client/component/dedicated_info.cpp index c950a247..95089a2d 100644 --- a/src/client/component/dedicated_info.cpp +++ b/src/client/component/dedicated_info.cpp @@ -27,11 +27,11 @@ namespace dedicated_info 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, mapname.data(), getinfo::get_client_count(), - getinfo::get_max_client_count(), + game::get_max_client_count(), getinfo::get_bot_count()); console::set_title(window_text); diff --git a/src/client/component/getinfo.cpp b/src/client/component/getinfo.cpp index 9e770266..17901992 100644 --- a/src/client/component/getinfo.cpp +++ b/src/client/component/getinfo.cpp @@ -41,33 +41,28 @@ namespace getinfo 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 get_client_count(*game::svs_clients_cl); + return count; } - int get_bot_count() + size_t get_bot_count() { - const auto client_states = game::is_server() ? *game::svs_clients : *game::svs_clients_cl; - if (!client_states) - { - return 0; - } + size_t count = 0; - int count = 0; - - for (int i = 0; i < get_max_client_count(); ++i) + game::foreach_connected_client([&count](const game::client_s&, const size_t index) { - if (game::SV_IsTestClient(i)) + if (game::SV_IsTestClient(static_cast(index))) { ++count; } - } + }); return count; } @@ -110,9 +105,9 @@ namespace getinfo info.set("xuid", utils::string::va("%llX", steam::SteamUser()->GetSteamID().bits)); info.set("mapname", game::get_dvar_string("mapname")); info.set("isPrivate", game::get_dvar_string("g_password").empty() ? "0" : "1"); - info.set("clients", utils::string::va("%i", get_client_count())); - info.set("bots", utils::string::va("%i", get_bot_count())); - info.set("sv_maxclients", utils::string::va("%i", get_max_client_count())); + info.set("clients", utils::string::va("%zu", get_client_count())); + info.set("bots", utils::string::va("%zu", get_bot_count())); + info.set("sv_maxclients", utils::string::va("%zu", get_max_client_count())); info.set("protocol", utils::string::va("%i", PROTOCOL)); info.set("playmode", utils::string::va("%i", game::Com_SessionMode_GetMode())); info.set("gamemode", utils::string::va("%i", Com_SessionMode_GetGameMode())); diff --git a/src/client/component/getinfo.hpp b/src/client/component/getinfo.hpp index 5d9d14be..0bf43b4d 100644 --- a/src/client/component/getinfo.hpp +++ b/src/client/component/getinfo.hpp @@ -2,8 +2,7 @@ namespace getinfo { - int get_max_client_count(); - int get_client_count(); - int get_bot_count(); + size_t get_client_count(); + size_t get_bot_count(); bool is_host(); } diff --git a/src/client/component/profile_infos.cpp b/src/client/component/profile_infos.cpp index 46fa2c6d..b72d192f 100644 --- a/src/client/component/profile_infos.cpp +++ b/src/client/component/profile_infos.cpp @@ -44,33 +44,11 @@ namespace profile_infos 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) { network::send(address, "profileInfo", buffer); } - template - 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) { if (user_id == steam::SteamUser()->GetSteamID().bits) @@ -82,14 +60,12 @@ namespace profile_infos buffer.write(user_id); 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()); - } - else - { - distribute_profile_info(*game::svs_clients_cl, buffer.get_buffer()); - } + send_profile_info(client.address, data); + }); } void schedule_pcache_update() @@ -107,14 +83,42 @@ namespace profile_infos }, scheduler::main, 5s); } + std::unordered_set get_connected_client_xuids() + { + std::unordered_set 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() { - if (!game::get_dvar_bool("sv_running")) + if (!game::is_server_running()) { 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); + } + } + }); } } diff --git a/src/client/game/utils.cpp b/src/client/game/utils.cpp index b33c08ef..051b3352 100644 --- a/src/client/game/utils.cpp +++ b/src/client/game/utils.cpp @@ -45,7 +45,8 @@ namespace game 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); auto* registered_dvar = Dvar_SessionModeRegisterBool(hash, dvar_name, value, flags, description); @@ -83,7 +84,8 @@ namespace game 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); auto* registered_dvar = Dvar_RegisterString(hash, dvar_name, value, flags, description); @@ -135,4 +137,67 @@ namespace game dvar_to_change->flags = flags; } + + bool is_server_running() + { + return get_dvar_bool("sv_running"); + } + + size_t get_max_client_count() + { + return static_cast(get_dvar_int("com_maxclients")); + } + + template + static void foreach_client(T* client_states, const std::function& 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& callback) + { + if (is_server()) + { + foreach_client(*svs_clients, callback); + } + else + { + foreach_client(*svs_clients_cl, callback); + } + } + + void foreach_client(const std::function& callback) + { + foreach_client([&](client_s& client, size_t) + { + callback(client); + }); + } + + void foreach_connected_client(const std::function& 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& callback) + { + foreach_connected_client([&](client_s& client, size_t) + { + callback(client); + }); + } } diff --git a/src/client/game/utils.hpp b/src/client/game/utils.hpp index c59bbfc7..a4e4de16 100644 --- a/src/client/game/utils.hpp +++ b/src/client/game/utils.hpp @@ -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_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); + void dvar_add_flags(const char* dvar, 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& callback); + void foreach_client(const std::function& callback); + + void foreach_connected_client(const std::function& callback); + void foreach_connected_client(const std::function& callback); } From 5ed2a1355eff8649588a67ba6078bd8856ec06ba Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 7 Apr 2023 14:33:23 +0200 Subject: [PATCH 22/23] Use new util --- src/client/component/getinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/component/getinfo.cpp b/src/client/component/getinfo.cpp index e0d8a6a7..ee848f15 100644 --- a/src/client/component/getinfo.cpp +++ b/src/client/component/getinfo.cpp @@ -111,7 +111,7 @@ namespace getinfo info.set("protocol", utils::string::va("%i", PROTOCOL)); info.set("playmode", utils::string::va("%i", game::Com_SessionMode_GetMode())); info.set("gamemode", utils::string::va("%i", Com_SessionMode_GetGameMode())); - info.set("sv_running", utils::string::va("%i", game::get_dvar_bool("sv_running"))); + info.set("sv_running", utils::string::va("%i", game::is_server_running())); info.set("dedicated", utils::string::va("%i", game::is_server() ? 1 : 0)); info.set("shortversion", SHORTVERSION); From a28235df267f7c379129344e5b8a6d413750237f Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 7 Apr 2023 14:37:34 +0200 Subject: [PATCH 23/23] Temporarily diable new protocol to merge changes --- src/client/component/auth.cpp | 8 +++++--- src/client/game/structs.hpp | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index d5e2d4f6..45405af4 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -172,8 +172,9 @@ namespace auth void post_unpack() override { // Skip connect handler - utils::hook::set(game::select(0x142253EFA, 0x14053714A), 0xEB); - network::on("connect", handle_connect_packet); + //utils::hook::set(game::select(0x142253EFA, 0x14053714A), 0xEB); + //network::on("connect", handle_connect_packet); + (void)&handle_connect_packet; // Patch steam id bit check std::vector> patches{}; @@ -220,7 +221,8 @@ namespace auth p(0x141EB5992_g, 0x141EB59D5_g); p(0x141EB74D2_g, 0x141EB7515_g); // ? - utils::hook::call(0x14134BF7D_g, send_connect_data_stub); + //utils::hook::call(0x14134BF7D_g, send_connect_data_stub); + (void)&send_connect_data_stub; } for (const auto& patch : patches) diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 1e852b6c..a54fddbf 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1,6 +1,6 @@ #pragma once -#define PROTOCOL 2 +#define PROTOCOL 1 #ifdef __cplusplus namespace game