From 7ca0ab528e919a9eb3b66c0f14544fe5a6c4d721 Mon Sep 17 00:00:00 2001 From: Diavolo Date: Wed, 29 Dec 2021 23:17:03 +0100 Subject: [PATCH] mute/unmute chat --- src/component/chat.cpp | 97 ++++++++++++++++++++++++++++++++++++++++++ src/game/structs.hpp | 36 +++++++++------- src/game/symbols.hpp | 6 ++- 3 files changed, 123 insertions(+), 16 deletions(-) diff --git a/src/component/chat.cpp b/src/component/chat.cpp index 3f65d10..83c12a9 100644 --- a/src/component/chat.cpp +++ b/src/component/chat.cpp @@ -1,11 +1,60 @@ #include #include "loader/component_loader.hpp" +#include "utils/string.hpp" #include "command.hpp" namespace chat { + namespace + { + std::unordered_set mute_list{}; + + void mute_player(const game::client_s* cl) + { + if (mute_list.contains(cl->xuid)) + { + game::SV_GameSendServerCommand(-1, game::SV_CMD_CAN_IGNORE, + utils::string::va("%c \"%s is already muted\"", 0x65, cl->name)); + return; + } + + mute_list.insert(cl->xuid); + } + + void unmute_player(const game::client_s* cl) + { + mute_list.erase(cl->xuid); + + game::SV_GameSendServerCommand(cl->gentity->entnum, game::SV_CMD_CAN_IGNORE, + utils::string::va("%c \"You were unmuted\"", 0x65)); + } + + void client_command(int clientNumber) + { + char buf[1024] = {0}; + + if (game::g_entities[clientNumber].client == nullptr) + { + // Not in game + return; + } + + game::SV_Cmd_ArgvBuffer(0, buf, sizeof(buf)); + + if (utils::string::starts_with(buf, "say") && + mute_list.contains(game::svs_clients[clientNumber].xuid)) + { + game::SV_GameSendServerCommand(clientNumber, game::SV_CMD_CAN_IGNORE, + utils::string::va("%c \"You are muted\"", 0x65)); + return; + } + + game::ClientCommand(clientNumber); + } + } + class component final : public component_interface { public: @@ -14,6 +63,10 @@ namespace chat add_chat_commands(); } + void pre_destroy() override + { + } + private: static void add_chat_commands() { @@ -40,6 +93,50 @@ namespace chat const auto message = params.join(2); game::G_Say(gentity, nullptr, 0, message.data()); }); + + command::add("mutePlayer", [](const command::params& params) + { + if (params.size() < 2) + { + game::Com_Printf(game::CON_CHANNEL_DONT_FILTER, + "Usage: mutePlayer \n"); + return; + } + + const auto* client = game::SV_GetPlayerByNum(); + + if (client == nullptr) + return; + + assert(client->gentity != nullptr); + + if (client->gentity->client == nullptr) + return; + + mute_player(client); + }); + + command::add("unmutePlayer", [](const command::params& params) + { + if (params.size() < 2) + { + game::Com_Printf(game::CON_CHANNEL_DONT_FILTER, + "Usage: unmutePlayer \n"); + return; + } + + const auto* client = game::SV_GetPlayerByNum(); + + if (client == nullptr) + return; + + assert(client->gentity != nullptr); + + if (client->gentity->client == nullptr) + return; + + unmute_player(client); + }); } }; } diff --git a/src/game/structs.hpp b/src/game/structs.hpp index 26e9c70..18dcef0 100644 --- a/src/game/structs.hpp +++ b/src/game/structs.hpp @@ -533,20 +533,26 @@ namespace game struct client_s { clientHeader_t header; - const char* dropReason; - char userinfo[1024]; - char reliableCommandBuffer[16384]; - int reliableCommandBufferNext; - svscmd_info_t reliableCommandInfo[128]; - int reliableSequence; - int reliableAcknowledge; - int reliableSent; - int messageAcknowledge; - int gamestateMessageNum; - int challenge; - usercmd_s lastUsercmd; - int lastClientCommand; - char lastClientCommandString[1024]; - gentity_s* gentity; + const char* dropReason; // 1812 + char userinfo[1024]; // 1816 + char reliableCommandBuffer[16384]; // 2840 + int reliableCommandBufferNext; // 19224 + svscmd_info_t reliableCommandInfo[128]; // 19228 + int reliableSequence; // 20764 + int reliableAcknowledge; // 20768 + int reliableSent; // 20772 + int messageAcknowledge; // 20776 + int gamestateMessageNum; // 20780 + int challenge; // 20784 + usercmd_s lastUsercmd; // 20788 + int lastClientCommand; // 20840 + char lastClientCommandString[1024]; // 20844 + gentity_s* gentity; // 21868 + char name[32]; // 21872 + char clanAbbrev[5]; // 21904 + unsigned __int64 xuid; // 21912 + unsigned char __pad0[0x76D48]; }; + + static_assert(sizeof(client_s) == 0x7C2E8); } diff --git a/src/game/symbols.hpp b/src/game/symbols.hpp index 1fbf842..335a6d2 100644 --- a/src/game/symbols.hpp +++ b/src/game/symbols.hpp @@ -13,6 +13,8 @@ namespace game WEAK symbol Cmd_ExecuteSingleCommand{0x50B470, 0x0}; WEAK symbol SV_SendServerCommand{0x588B10, 0x0}; + WEAK symbol SV_GameSendServerCommand{0x6B8730, 0x0}; + WEAK symbol SV_Cmd_ArgvBuffer{0x462CB0, 0x0}; WEAK symbol SV_DelayDropClient{0x4A8DC0, 0x0}; WEAK symbol SV_GetPlayerByName{0x875180, 0x0}; WEAK symbol SV_GetPlayerByNum{0x875260, 0x0}; @@ -33,6 +35,7 @@ namespace game WEAK symbol I_CleanStr{0x4B0700, 0x0}; WEAK symbol ConcatArgs{0x5D5F10, 0x0}; + WEAK symbol ClientCommand{0x63DB70, 0x0}; WEAK symbol G_Say{0x51BBD0, 0x0}; WEAK symbol Scr_Notify{0x458D30, 0x0}; @@ -44,6 +47,7 @@ namespace game WEAK symbol cmd_args{0x355BD88, 0x0}; WEAK symbol dvarCount{0x385BE74, 0x0}; WEAK symbol sortedDvars{0x385BE88, 0x0}; - WEAK symbol g_entities{0x32E5784, 0x0}; + WEAK symbol svs_clients{0x372D11C, 0x0}; + WEAK symbol g_entities{0x32E5640, 0x0}; WEAK symbol level_time{0x3443F4C, 0x0}; }