From a3769a4489face5fe4395e92e9a390355cc08b8d Mon Sep 17 00:00:00 2001 From: momo5502 Date: Mon, 13 Mar 2023 20:33:59 +0100 Subject: [PATCH] Rundimental ingame chat support Technically, this implements #168. However, it's very ugly, so it needs cleanup. --- src/client/component/chat.cpp | 47 ++++++++++++++++++++++--- src/client/component/chat.hpp | 6 ++++ src/client/game/symbols.hpp | 3 ++ src/client/steam/interfaces/friends.cpp | 3 +- 4 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 src/client/component/chat.hpp diff --git a/src/client/component/chat.cpp b/src/client/component/chat.cpp index ce3a92ad..c2ca88b3 100644 --- a/src/client/component/chat.cpp +++ b/src/client/component/chat.cpp @@ -1,8 +1,10 @@ #include #include "loader/component_loader.hpp" +#include "chat.hpp" #include "game/game.hpp" #include +#include #include "command.hpp" #include "client_command.hpp" @@ -41,17 +43,54 @@ namespace chat utils::hook::invoke(0x140298E70_g, ent, p.data()); } + + void get_chat_client_name_stub(uint64_t xuid, char* buffer, const size_t max_length) + { + utils::string::copy(buffer, max_length, utils::string::va("%llX-something", xuid)); + OutputDebugStringA(buffer); + } } - class component final : public server_component + const char* GetClientName(const uint64_t xuid) + { + if (xuid < 19 && !game::is_server()) + { + char buffer[256]; + game::CL_GetClientName(0, static_cast(xuid - 1), buffer, sizeof(buffer), true); + + return utils::string::va("%s\n", buffer); + } + + return "Unknown Soldier"; + } + + uint64_t* divert_xuid_to_client_num_stub(int, int client_num, int) + { + static thread_local uint64_t value; + // zero xuid is invalid, so increase the clientnum to prevent 0 values + value = static_cast(client_num) + 1; + return &value; + } + + class component final : public generic_component { public: void post_unpack() override { - client_command::add("say", cmd_say_f); - client_command::add("say_team", cmd_say_f); + utils::hook::call(game::select(0x141974B04, 0x14029908A), divert_xuid_to_client_num_stub); - client_command::add("chat", cmd_chat_f); + if (game::is_server()) + { + client_command::add("say", cmd_say_f); + client_command::add("say_team", cmd_say_f); + + client_command::add("chat", cmd_chat_f); + } + else + { + // Ignore some check that suppresses the chat + utils::hook::nop(0x141DEA9BD_g, 2); + } } }; } diff --git a/src/client/component/chat.hpp b/src/client/component/chat.hpp new file mode 100644 index 00000000..aae9201f --- /dev/null +++ b/src/client/component/chat.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace chat +{ + const char* GetClientName(const uint64_t xuid); +} diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index e242117e..cc06984b 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -13,6 +13,9 @@ namespace game int numPrivateSlots, const char* mapname, const char* gametype, const char* somethingWithUserMaps)> CL_ConnectFromLobby {0x14134C570}; + WEAK symbol CL_GetClientName{ + 0x1413E3140 + }; // Game WEAK symbol G_Say{0x0, 0x140299170}; diff --git a/src/client/steam/interfaces/friends.cpp b/src/client/steam/interfaces/friends.cpp index 0a9a7240..f72381c7 100644 --- a/src/client/steam/interfaces/friends.cpp +++ b/src/client/steam/interfaces/friends.cpp @@ -4,6 +4,7 @@ #include #include "component/name.hpp" +#include "component/chat.hpp" namespace steam { @@ -44,7 +45,7 @@ namespace steam const char* friends::GetFriendPersonaName(steam_id steamIDFriend) { - return ""; + return chat::GetClientName(steamIDFriend.bits); } bool friends::GetFriendGamePlayed(steam_id steamIDFriend, void* pFriendGameInfo)