From 6c07d84e23cfc097ba3acd70320d542027786c54 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Mon, 17 Apr 2023 18:42:52 +0200 Subject: [PATCH] Prepare colored name support --- src/client/component/auth.cpp | 80 ++++++++++++++++++++++++++++++++- src/client/component/auth.hpp | 1 + src/client/component/colors.cpp | 65 +++++++++++++++++++++------ src/client/component/party.hpp | 2 + src/client/game/utils.cpp | 34 ++++++++++++++ src/client/game/utils.hpp | 2 + src/client/std_include.hpp | 1 + 7 files changed, 170 insertions(+), 15 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 78a6b460..7c679aa8 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -2,6 +2,7 @@ #include "loader/component_loader.hpp" #include "auth.hpp" +#include "party.hpp" #include "command.hpp" #include "network.hpp" #include "scheduler.hpp" @@ -24,6 +25,8 @@ namespace auth { namespace { + std::array client_xuids{}; + std::string get_hdd_serial() { DWORD serial{}; @@ -151,6 +154,32 @@ namespace auth return 0; } + void distribute_player_xuid(const game::netadr_t& target, const size_t player_index, const uint64_t xuid) + { + if (player_index >= 18) + { + return; + } + + utils::byte_buffer buffer{}; + buffer.write(static_cast(player_index)); + buffer.write(xuid); + + game::foreach_connected_client([&](const game::client_s& client, size_t index) + { + network::send(client.address, "playerXuid", buffer.get_buffer()); + + if (index != player_index) + { + utils::byte_buffer current_buffer{}; + current_buffer.write(static_cast(index)); + current_buffer.write(client.xuid); + + network::send(target, "playerXuid", current_buffer.get_buffer()); + } + }); + } + void dispatch_connect_packet(const game::netadr_t& target, const std::string& data) { utils::byte_buffer buffer(data); @@ -173,13 +202,17 @@ namespace auth game::SV_DirectConnect(target); - game::foreach_connected_client([&](game::client_s& client) + size_t player_index = 18; + game::foreach_connected_client([&](game::client_s& client, size_t index) { if (client.address == target) { client.xuid = xuid; + player_index = index; } }); + + distribute_player_xuid(target, player_index, xuid); } void handle_connect_packet_fragment(const game::netadr_t& target, const network::data_view& data) @@ -200,6 +233,24 @@ namespace auth }, scheduler::server); } } + + void handle_player_xuid_packet(const game::netadr_t& target, const network::data_view& data) + { + if (game::is_server_running() || !party::is_host(target)) + { + return; + } + + utils::byte_buffer buffer(data); + + const auto player_id = buffer.read(); + const auto xuid = buffer.read(); + + if (player_id < client_xuids.size()) + { + client_xuids[player_id] = xuid; + } + } } uint64_t get_guid() @@ -217,6 +268,32 @@ namespace auth return guid; } + uint64_t get_guid(const size_t client_num) + { + if (client_num >= 18) + { + return 0; + } + + if (!game::is_server_running()) + { + return client_xuids[client_num]; + } + + uint64_t xuid = 0; + const auto callback = [&xuid](const game::client_s& client) + { + xuid = client.xuid; + }; + + if (!game::access_connected_client(client_num, callback)) + { + return 0; + } + + return xuid; + } + struct component final : generic_component { void post_unpack() override @@ -224,6 +301,7 @@ namespace auth // Skip connect handler utils::hook::set(game::select(0x142253EFA, 0x14053714A), 0xEB); network::on("connect", handle_connect_packet_fragment); + network::on("playerXuid", handle_player_xuid_packet); // Patch steam id bit check std::vector> patches{}; diff --git a/src/client/component/auth.hpp b/src/client/component/auth.hpp index 3ee0c53a..87c07f5e 100644 --- a/src/client/component/auth.hpp +++ b/src/client/component/auth.hpp @@ -3,4 +3,5 @@ namespace auth { uint64_t get_guid(); + uint64_t get_guid(size_t client_num); } diff --git a/src/client/component/colors.cpp b/src/client/component/colors.cpp index 306c44b6..5c7f7b4e 100644 --- a/src/client/component/colors.cpp +++ b/src/client/component/colors.cpp @@ -3,6 +3,10 @@ #include "game/game.hpp" +#include "auth.hpp" + +#include "steam/steam.hpp" + #include #include @@ -10,8 +14,25 @@ namespace colors { namespace { - utils::hook::detour get_player_name_hook; - utils::hook::detour get_gamer_tag_hook; + utils::hook::detour cl_get_client_name_hook; + + std::optional get_color_for_xuid(const uint64_t xuid) + { + if (xuid == 0xCD02AF6448291209 + || xuid == 0x10F0C433E08E1357 + || xuid == 0x60E0FEFE42341715) + { + return 2; + } + + return {}; + } + + std::optional get_color_for_client(const int client_num) + { + const auto xuid = auth::get_guid(static_cast(client_num)); + return get_color_for_xuid(xuid); + } template void patch_color(const uint8_t r, const uint8_t g, const uint8_t b, const uint8_t a = 255) @@ -36,23 +57,39 @@ namespace colors utils::hook::copy(g_color_table + index * 4, color_float, sizeof(color_float)); } - /*uint64_t get_player_name_stub(const uint64_t client, int client_num, char* buffer, const int size, - const bool has_clan_tag) + bool cl_get_client_name_stub(const int local_client_num, const int index, char* buf, const int size, + const bool add_clan_name) { - const auto res = get_player_name_hook.invoke(client, client_num, buffer, size, has_clan_tag); + const auto res = cl_get_client_name_hook.invoke(local_client_num, index, buf, size, add_clan_name); - if (_ReturnAddress() != reinterpret_cast(0x1406A7B56_g)) + if (_ReturnAddress() == reinterpret_cast(0x1406A7B56_g)) { - const auto val = utils::string::va("^%d%s", rand() % 7, buffer); - strncpy_s(buffer, size, val, size); + return res; } - return res; - }*/ + const auto color = get_color_for_client(index); + if (!color) + { + return res; + } - /*const char* get_gamer_tag_stub(const uint64_t num) + const auto val = utils::string::va("^%d%s", *color, buf); + utils::string::copy(buf, size, val); + + return res; + } + + /*const char* get_gamer_tag_stub(const uint32_t num) { - return utils::string::va("^3%s", get_gamer_tag_hook.invoke(num)); + const auto color = get_color_for_xuid(steam::SteamUser()->GetSteamID().bits); + const auto name = reinterpret_cast(0x141EC6E80)(num) + 8; + + if (!color || num) + { + return name; + } + + return utils::string::va("^1%s", *color, name); }*/ } @@ -68,8 +105,8 @@ namespace colors patch_color<6>(151, 80, 221); // 6 - Pink // Old addresses - //get_player_name_hook.create(0x1413E3140_g, get_player_name_stub); - //get_gamer_tag_hook.create(0x141EC7370_g, get_gamer_tag_stub); + cl_get_client_name_hook.create(game::CL_GetClientName, cl_get_client_name_stub); + //utils::hook::jump(0x141EC72E0_g, get_gamer_tag_stub); } }; } diff --git a/src/client/component/party.hpp b/src/client/component/party.hpp index f682a14e..b10ee95c 100644 --- a/src/client/component/party.hpp +++ b/src/client/component/party.hpp @@ -1,6 +1,8 @@ #pragma once #include +#include "game/game.hpp" + namespace party { using query_callback_func = void(bool success, const game::netadr_t& host, const ::utils::info_string& info, uint32_t ping); diff --git a/src/client/game/utils.cpp b/src/client/game/utils.cpp index e374a73a..c61a4350 100644 --- a/src/client/game/utils.cpp +++ b/src/client/game/utils.cpp @@ -176,6 +176,30 @@ namespace game } } + + template + static bool access_client(T* client_states, const size_t index, const std::function& callback) + { + if (!client_states || !callback) + { + return false; + } + + if (index >= get_max_client_count()) + { + return false; + } + + auto& client = client_states[index]; + if (client.client_state <= 0) + { + return false; + } + + callback(client); + return true; + } + void foreach_client(const std::function& callback) { if (is_server()) @@ -214,4 +238,14 @@ namespace game callback(client); }); } + + bool access_connected_client(const size_t index, const std::function& callback) + { + if (is_server()) + { + return access_client(*svs_clients, index, callback); + } + + return access_client(*svs_clients_cl, index, callback); + } } diff --git a/src/client/game/utils.hpp b/src/client/game/utils.hpp index 09abd8e7..5bbc78c0 100644 --- a/src/client/game/utils.hpp +++ b/src/client/game/utils.hpp @@ -24,4 +24,6 @@ namespace game void foreach_connected_client(const std::function& callback); void foreach_connected_client(const std::function& callback); + + bool access_connected_client(size_t index, const std::function& callback); } diff --git a/src/client/std_include.hpp b/src/client/std_include.hpp index 59b83a41..422c5ed9 100644 --- a/src/client/std_include.hpp +++ b/src/client/std_include.hpp @@ -65,6 +65,7 @@ #endif #include +#include #include #include #include