From 314a3424ea891e86b13c234cb3ae04566b7510ac Mon Sep 17 00:00:00 2001 From: Diavolo Date: Sat, 27 Aug 2022 20:25:31 +0200 Subject: [PATCH] fix hook compatability with plutonium --- .gitmodules | 3 - deps/premake/rapidjson.lua | 19 ------ deps/rapidjson | 1 - src/client/component/ban.cpp | 46 ------------- src/client/component/bots.cpp | 98 ---------------------------- src/client/component/chat.cpp | 59 +++++++++-------- src/client/component/command.cpp | 25 +++---- src/client/component/command.hpp | 16 +++-- src/client/component/gameplay.cpp | 2 +- src/client/component/gsc_patches.cpp | 21 ------ src/client/game/symbols.hpp | 6 +- src/client/std_include.hpp | 4 -- 12 files changed, 57 insertions(+), 243 deletions(-) delete mode 100644 deps/premake/rapidjson.lua delete mode 160000 deps/rapidjson delete mode 100644 src/client/component/ban.cpp delete mode 100644 src/client/component/bots.cpp delete mode 100644 src/client/component/gsc_patches.cpp diff --git a/.gitmodules b/.gitmodules index 592affd..7c912de 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,9 +4,6 @@ [submodule "deps/minhook"] path = deps/minhook url = https://github.com/TsudaKageyu/minhook.git -[submodule "deps/rapidjson"] - path = deps/rapidjson - url = https://github.com/Tencent/rapidjson.git [submodule "deps/asmjit"] path = deps/asmjit url = https://github.com/asmjit/asmjit.git diff --git a/deps/premake/rapidjson.lua b/deps/premake/rapidjson.lua deleted file mode 100644 index d108512..0000000 --- a/deps/premake/rapidjson.lua +++ /dev/null @@ -1,19 +0,0 @@ -rapidjson = { - source = path.join(dependencies.basePath, "rapidjson"), -} - -function rapidjson.import() - rapidjson.includes() -end - -function rapidjson.includes() - includedirs { - path.join(rapidjson.source, "include"), - } -end - -function rapidjson.project() - -end - -table.insert(dependencies, rapidjson) diff --git a/deps/rapidjson b/deps/rapidjson deleted file mode 160000 index 27c3a8d..0000000 --- a/deps/rapidjson +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 27c3a8dc0e2c9218fe94986d249a12b5ed838f1d diff --git a/src/client/component/ban.cpp b/src/client/component/ban.cpp deleted file mode 100644 index a4ea238..0000000 --- a/src/client/component/ban.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include - -#include "../loader/component_loader.hpp" - -#include - -namespace ban { -namespace { -const game::dvar_t* sv_discord = nullptr; -const game::dvar_t* sv_clanWebsite = nullptr; - -bool out_of_band_print_hk(game::netsrc_t src, game::netadr_s to, - const char* msg) { - // Proof of concept patch. Please ignore - if (msg != "error\nPATCH_BANNED_FROM_SERVER"s) { - return game::NET_OutOfBandPrint(src, to, msg); - } - - const auto error_msg = - std::format("error\nPermanently banned\nDiscord: {}\nWebsite: {}", - sv_discord->current.string, sv_clanWebsite->current.string); - - return game::NET_OutOfBandPrint(src, to, error_msg.data()); -} -} // namespace - -class component final : public component_interface { -public: - void post_unpack() override { - if (game::current == game::gamemode::zombies) - return; - - sv_discord = game::Dvar_RegisterString( - "sv_discord", "https://www.discord.gg/", game::DVAR_ARCHIVE, - "Discord invitation link"); - - sv_clanWebsite = - game::Dvar_RegisterString("sv_clanWebsite", "https://www.google.com/", - game::DVAR_ARCHIVE, "Website link"); - - utils::hook::call(0x48B7E2, out_of_band_print_hk); - } -}; -} // namespace ban - -REGISTER_COMPONENT(ban::component) diff --git a/src/client/component/bots.cpp b/src/client/component/bots.cpp deleted file mode 100644 index 1ed0fd7..0000000 --- a/src/client/component/bots.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include - -#include "../loader/component_loader.hpp" - -#include -#include - -namespace bots { -namespace { -using bot_entry = std::pair; -std::vector bot_names; -utils::hook::detour sv_bot_name_random_hook; - -// Json file is expected to contain a key for the bot's name. Value should be a -// string for the clantag -void load_bot_data() { - if (!utils::io::file_exists("bots/bots.json")) { - game::Com_Printf(game::CON_CHANNEL_SERVER, "bots.json was not found\n"); - return; - } - - rapidjson::Document obj; - const rapidjson::ParseResult result = - obj.Parse(utils::io::read_file("bots/bots.json").data()); - - if (!result || !obj.IsObject()) { - game::Com_Printf(game::CON_CHANNEL_SERVER, - "Failed to parse ban file. Empty?\n"); - return; - } - - for (rapidjson::Value::ConstMemberIterator itr = obj.MemberBegin(); - itr != obj.MemberEnd(); ++itr) { - if (itr->value.GetType() == rapidjson::Type::kStringType) { - bot_names.emplace_back( - std::make_pair(itr->name.GetString(), itr->value.GetString())); - } - } -} - -const char* sv_bot_name_random_stub() { - static auto loaded = false; - - if (bot_names.empty() && !loaded) { - load_bot_data(); - loaded = true; - } - - if (!bot_names.empty()) { - static std::size_t bot_id = 0; - bot_id %= bot_names.size(); - const auto& entry = bot_names.at(bot_id++); - return entry.first.data(); - } - - return sv_bot_name_random_hook.invoke(); -} - -int build_connect_string(char* buf, const char* connect_string, - const char* name, const char* bd_online_user_id, - int protocol, int qport) { - // Default - auto clan_tag = "3arc"s; - for (const auto& [bot_name, tag] : bot_names) { - if (bot_name == name) { - // Found their clantag - clan_tag = tag; - break; - } - } - - return _snprintf_s(buf, 0x400, _TRUNCATE, connect_string, name, - clan_tag.data(), bd_online_user_id, protocol, qport); -} -} // namespace - -class component final : public component_interface { -public: - void post_unpack() override { - if (game::current == game::gamemode::zombies) - return; - - // Add custom clantag - utils::hook::set( - 0x6B6294, - "connect " - "\"\\cg_predictItems\\1\\cl_punkbuster\\0\\cl_" - "anonymous\\0\\color\\4\\head\\default\\" - " model\\multi\\snaps\\20\\rate\\5000\\name\\%s\\clanAbbrev\\%" - "s\\bdOnlineUserID\\%s\\protocol\\%d\\qport\\%d\""); - - sv_bot_name_random_hook.create(0x49ED80, &sv_bot_name_random_stub); - utils::hook::call(0x6B6299, build_connect_string); - } -}; -} // namespace bots - -REGISTER_COMPONENT(bots::component) diff --git a/src/client/component/chat.cpp b/src/client/component/chat.cpp index 19911a2..f5628b7 100644 --- a/src/client/component/chat.cpp +++ b/src/client/component/chat.cpp @@ -1,41 +1,36 @@ #include - #include "../loader/component_loader.hpp" + #include #include +#include #include "command.hpp" namespace chat { namespace { -std::mutex chat_mutex; -std::unordered_set mute_list{}; +utils::hook::detour client_command_hook; + +using client_list = std::unordered_set; +utils::concurrency::container mute_list; void mute_player(const game::client_s* client) { - std::unique_lock _(chat_mutex); - - if (mute_list.contains(client->xuid)) { - game::SV_GameSendServerCommand( - -1, game::SV_CMD_CAN_IGNORE, - utils::string::va("%c \"%s is already muted\"", 0x65, client->name)); - return; - } - - mute_list.insert(client->xuid); + const auto xuid = client->xuid; + mute_list.access([&](client_list& clients) { clients.insert(xuid); }); } void unmute_player(const game::client_s* client) { - std::unique_lock _(chat_mutex); - mute_list.erase(client->xuid); + const auto xuid = client->xuid; + mute_list.access([&](client_list& clients) { clients.erase(xuid); }); game::SV_GameSendServerCommand( client->gentity->entnum, game::SV_CMD_CAN_IGNORE, utils::string::va("%c \"You were unmuted\"", 0x65)); } -void client_command(int client_number) { - char buf[1024] = {0}; +void client_command_stub(const int client_number) { + char buf[1024]{}; if (game::g_entities[client_number].client == nullptr) { // Not in game @@ -44,30 +39,36 @@ void client_command(int client_number) { game::SV_Cmd_ArgvBuffer(0, buf, sizeof(buf)); - std::unique_lock _(chat_mutex); - if (utils::string::starts_with(buf, "say") && - mute_list.contains(game::svs_clients[client_number].xuid)) { - game::SV_GameSendServerCommand( - client_number, game::SV_CMD_CAN_IGNORE, - utils::string::va("%c \"You are muted\"", 0x65)); - return; + if (utils::string::starts_with(buf, "say")) { + const auto is_muted = + mute_list.access([&](const client_list& clients) { + return clients.contains(game::svs_clients[client_number].xuid); + }); + + if (is_muted) { + game::SV_GameSendServerCommand( + client_number, game::SV_CMD_CAN_IGNORE, + utils::string::va("%c \"You are muted\"", 0x65)); + return; + } } - game::ClientCommand(client_number); + client_command_hook.invoke(client_number); } } // namespace class component final : public component_interface { public: void post_unpack() override { - utils::hook::call(SELECT_VALUE(0x58DA1C, 0x4FB3BD), client_command); + client_command_hook.create(SELECT_VALUE(0x63DB70, 0x4AF770), + client_command_stub); add_chat_commands(); } private: static void add_chat_commands() { - command::add("sayAs", [](const command::params& params) { + command::add("sayAs", [](const command::params_sv& params) { if (params.size() < 3) { game::Com_Printf(game::CON_CHANNEL_DONT_FILTER, "Usage: sayAs \n"); @@ -89,7 +90,7 @@ private: game::G_Say(gentity, nullptr, 0, message.data()); }); - command::add("mutePlayer", [](const command::params& params) { + command::add("mutePlayer", [](const command::params_sv& params) { if (params.size() < 2) { game::Com_Printf(game::CON_CHANNEL_DONT_FILTER, "Usage: mutePlayer \n"); @@ -109,7 +110,7 @@ private: mute_player(client); }); - command::add("unmutePlayer", [](const command::params& params) { + command::add("unmutePlayer", [](const command::params_sv& params) { if (params.size() < 2) { game::Com_Printf(game::CON_CHANNEL_DONT_FILTER, "Usage: unmutePlayer \n"); diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index c9e2280..3bd6dcd 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -1,5 +1,4 @@ #include - #include "../loader/component_loader.hpp" #include @@ -10,11 +9,11 @@ constexpr auto CMD_MAX_NESTING = 8; namespace command { -std::unordered_map> handlers; +std::unordered_map> handlers; namespace { void cmd_vstr_f() { - const params params; + const params_sv params; if (params.size() < 2) { game::Com_Printf(game::CON_CHANNEL_DONT_FILTER, @@ -43,7 +42,7 @@ void cmd_vstr_f() { } // namespace void main_handler() { - params params = {}; + params_sv params = {}; const auto command = utils::string::to_lower(params[0]); @@ -52,13 +51,13 @@ void main_handler() { } } -params::params() : nesting_(game::sv_cmd_args->nesting) { +params_sv::params_sv() : nesting_(game::sv_cmd_args->nesting) { assert(game::sv_cmd_args->nesting < CMD_MAX_NESTING); } -int params::size() const { return game::sv_cmd_args->argc[this->nesting_]; } +int params_sv::size() const { return game::sv_cmd_args->argc[this->nesting_]; } -const char* params::get(const int index) const { +const char* params_sv::get(const int index) const { if (index >= this->size()) { return ""; } @@ -66,10 +65,10 @@ const char* params::get(const int index) const { return game::sv_cmd_args->argv[this->nesting_][index]; } -std::string params::join(const int index) const { +std::string params_sv::join(const int index) const { std::string result = {}; - for (auto i = index; i < this->size(); i++) { + for (auto i = index; i < this->size(); ++i) { if (i > index) result.append(" "); result.append(this->get(i)); @@ -83,7 +82,8 @@ void add_raw(const char* name, void (*callback)()) { utils::memory::get_allocator()->allocate()); } -void add(const char* name, const std::function& callback) { +void add(const char* name, + const std::function& callback) { const auto command = utils::string::to_lower(name); if (!handlers.contains(command)) { @@ -109,9 +109,10 @@ public: private: static void add_commands_generic() { - add("properQuit", [](const params&) { utils::nt::raise_hard_exception(); }); + add("properQuit", + [](const params_sv&) { utils::nt::raise_hard_exception(); }); - add("echo", [](const params& params) { + add("echo", [](const params_sv& params) { for (auto i = 1; i < params.size(); i++) { game::Com_Printf(game::CON_CHANNEL_DONT_FILTER, "%s ", params.get(i)); } diff --git a/src/client/component/command.hpp b/src/client/component/command.hpp index 5aa2f92..13d5154 100644 --- a/src/client/component/command.hpp +++ b/src/client/component/command.hpp @@ -1,13 +1,14 @@ #pragma once namespace command { -class params { -public: - params(); - int size() const; - const char* get(int index) const; - std::string join(int index) const; +class params_sv { +public: + params_sv(); + + [[nodiscard]] int size() const; + [[nodiscard]] const char* get(int index) const; + [[nodiscard]] std::string join(int index) const; const char* operator[](const int index) const { return this->get(index); } @@ -16,7 +17,8 @@ private: }; void add_raw(const char* name, void (*callback)()); -void add(const char* name, const std::function& callback); +void add(const char* name, + const std::function& callback); void execute(std::string command, bool sync = false); } // namespace command diff --git a/src/client/component/gameplay.cpp b/src/client/component/gameplay.cpp index a89025d..5411a2c 100644 --- a/src/client/component/gameplay.cpp +++ b/src/client/component/gameplay.cpp @@ -1,6 +1,6 @@ #include - #include "../loader/component_loader.hpp" + #include namespace gameplay { diff --git a/src/client/component/gsc_patches.cpp b/src/client/component/gsc_patches.cpp deleted file mode 100644 index ae275a1..0000000 --- a/src/client/component/gsc_patches.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include - -#include "../loader/component_loader.hpp" -#include - -namespace gsc_patches { -namespace { -void g_log_printf(const char* fmt) { game::G_LogPrintf("%s", fmt); } -} // namespace - -class component final : public component_interface { -public: - void post_unpack() override { - if (game::environment::is_mp()) { - utils::hook::call(0x8426D3, g_log_printf); - } - } -}; -} // namespace gsc_patches - -REGISTER_COMPONENT(gsc_patches::component) diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index c43ba0b..e2d84d8 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -49,8 +49,9 @@ WEAK symbol Dvar_RegisterInt{0x58D900, 0x651910}; -WEAK symbol Cmd_AddCommandInternal{ - 0x6AD580, 0x661400}; +WEAK symbol + Cmd_AddCommandInternal{0x6AD580, 0x661400}; WEAK symbol Cmd_RemoveCommand{0x527EA0, 0x5F1A90}; WEAK symbol Cmd_FindCommand{0x445B60, 0x479DD0}; @@ -71,6 +72,7 @@ WEAK symbol Scr_AddVector{0x532EF0, 0x0}; WEAK symbol PM_GetEffectiveStance{0x659590, 0x0}; WEAK symbol sv_cmd_args{0x355BD88, 0x243D208}; + WEAK symbol dvarCount{0x385BE74, 0x261CBD4}; WEAK symbol sortedDvars{0x385BE88, 0x261CBE8}; WEAK symbol svs_clients{0x372D11C, 0x286D01C}; diff --git a/src/client/std_include.hpp b/src/client/std_include.hpp index ab36796..b11785f 100644 --- a/src/client/std_include.hpp +++ b/src/client/std_include.hpp @@ -18,10 +18,6 @@ #pragma warning(disable : 26812) -#include -#include -#include - #pragma comment(lib, "ntdll.lib") using namespace std::literals;