From 2ed98145daeb71098758a6d587d3bad8b91c1b11 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Tue, 22 Mar 2022 23:44:31 +0000 Subject: [PATCH] Fix format or so I hope --- src/component/cheats.cpp | 104 ++++++------ src/component/command.cpp | 164 ++++++++----------- src/component/command.hpp | 36 ++--- src/component/console.cpp | 72 ++++----- src/component/dvar_patches.cpp | 19 +-- src/component/exploit.cpp | 175 ++++++++++----------- src/component/key_catcher.cpp | 86 +++++----- src/component/key_catcher.hpp | 7 +- src/component/network.cpp | 113 ++++++------- src/component/network.hpp | 9 +- src/component/remove_hooks.cpp | 42 +++-- src/component/scheduler.cpp | 280 ++++++++++++++------------------- src/component/scheduler.hpp | 40 +++-- src/component/user_info.cpp | 105 ++++++------- 14 files changed, 541 insertions(+), 711 deletions(-) diff --git a/src/component/cheats.cpp b/src/component/cheats.cpp index 652736d..4d6c5fd 100644 --- a/src/component/cheats.cpp +++ b/src/component/cheats.cpp @@ -7,13 +7,11 @@ #include "key_catcher.hpp" #include "command.hpp" -namespace cheats -{ - game::dvar_t* cl_EnableCheats; +namespace cheats { +game::dvar_t* cl_EnableCheats; - __declspec(naked) void draw_red_box_stub() - { - __asm { +__declspec(naked) void draw_red_box_stub() { + __asm { push eax mov eax, cl_EnableCheats cmp byte ptr [eax + 12], 1 @@ -29,12 +27,11 @@ namespace cheats draw: push 0x43056A retn - } } +} - __declspec(naked) void blind_eye_check_stub() - { - __asm { +__declspec(naked) void blind_eye_check_stub() { + __asm { push eax mov eax, cl_EnableCheats cmp byte ptr [eax + 12], 1 @@ -54,60 +51,49 @@ namespace cheats draw: push 0x05AA529 retn - } + } +} + +class component final : public component_interface { +public: + void post_unpack() override { + cl_EnableCheats = game::Dvar_RegisterBool( + "cl_EnableCheats", false, game::DVAR_NONE, "Enable FoF wallhack"); + + utils::hook::jump(0x430561, draw_red_box_stub); + utils::hook::nop(0x430566, 2); + + utils::hook::jump(0x5AA524, blind_eye_check_stub); + + add_cheat_commands(); } - class component final : public component_interface - { - public: - void post_unpack() override - { - cl_EnableCheats = game::Dvar_RegisterBool( - "cl_EnableCheats", false, game::DVAR_NONE, "Enable FoF wallhack"); +private: + static void add_cheat_commands() { + key_catcher::on_key_press( + "Z", []([[maybe_unused]] const game::LocalClientNum_t& local_client) { + game::Dvar_SetBool(cl_EnableCheats, true); + }); - utils::hook::jump(0x430561, draw_red_box_stub); - utils::hook::nop(0x430566, 2); + key_catcher::on_key_press( + "X", []([[maybe_unused]] const game::LocalClientNum_t& local_client) { + game::Dvar_SetBool(cl_EnableCheats, false); + }); - utils::hook::jump(0x5AA524, blind_eye_check_stub); + key_catcher::on_key_press( + "Y", []([[maybe_unused]] const game::LocalClientNum_t& local_client) { + command::execute( + utils::string::va("cmd mr %i 2 allies", *game::serverId), true); + }); - add_cheat_commands(); - } - - private: - static void add_cheat_commands() - { - key_catcher::on_key_press( - "Z", - []([[maybe_unused]] const game::LocalClientNum_t& local_client) - { - game::Dvar_SetBool(cl_EnableCheats, true); - }); - - key_catcher::on_key_press( - "X", - []([[maybe_unused]] const game::LocalClientNum_t& local_client) - { - game::Dvar_SetBool(cl_EnableCheats, false); - }); - - key_catcher::on_key_press( - "Y", - []([[maybe_unused]] const game::LocalClientNum_t& local_client) - { - command::execute( - utils::string::va("cmd mr %i 2 allies", *game::serverId), true); - }); - - key_catcher::on_key_press( - "8", - []([[maybe_unused]] const game::LocalClientNum_t& local_client) - { - command::execute( - utils::string::va("cmd mr %i -1 endround", *game::serverId), - true); - }); - } - }; + key_catcher::on_key_press( + "8", []([[maybe_unused]] const game::LocalClientNum_t& local_client) { + command::execute( + utils::string::va("cmd mr %i -1 endround", *game::serverId), + true); + }); + } +}; } // namespace cheats REGISTER_COMPONENT(cheats::component) diff --git a/src/component/command.cpp b/src/component/command.cpp index 8b1507a..bd1a01d 100644 --- a/src/component/command.cpp +++ b/src/component/command.cpp @@ -8,117 +8,87 @@ constexpr auto CMD_MAX_NESTING = 8; -namespace command -{ - std::unordered_map> handlers; +namespace command { +std::unordered_map> handlers; - void main_handler() - { - params params = {}; +void main_handler() { + params params = {}; - const auto command = utils::string::to_lower(params[0]); - if (!handlers.contains(command)) - { - handlers[command](params); - } + const auto command = utils::string::to_lower(params[0]); + if (!handlers.contains(command)) { + handlers[command](params); + } +} + +params::params() : nesting_(game::cmd_args->nesting) { + assert(game::cmd_args->nesting < CMD_MAX_NESTING); +} + +int params::size() const { return game::cmd_args->argc[this->nesting_]; } + +const char* params::get(const int index) const { + if (index >= this->size()) { + return ""; } - params::params() - : nesting_(game::cmd_args->nesting) - { - assert(game::cmd_args->nesting < CMD_MAX_NESTING); + return game::cmd_args->argv[this->nesting_][index]; +} + +std::string params::join(const int index) const { + std::string result = {}; + + for (auto i = index; i < this->size(); i++) { + if (i > index) + result.append(" "); + result.append(this->get(i)); } - int params::size() const - { - return game::cmd_args->argc[this->nesting_]; + return result; +} + +void add_raw(const char* name, void (*callback)()) { + game::Cmd_AddCommandInternal( + name, callback, + utils::memory::get_allocator()->allocate()); +} + +void add(const char* name, const std::function& callback) { + const auto command = utils::string::to_lower(name); + + if (!handlers.contains(command)) { + add_raw(name, main_handler); } - const char* params::get(const int index) const - { - if (index >= this->size()) - { - return ""; - } + handlers[command] = callback; +} - return game::cmd_args->argv[this->nesting_][index]; +void add(const char* name, const std::function& callback) { + add(name, [callback](const params&) { callback(); }); +} + +void execute(std::string command, const bool sync) { + command += "\n"; + + if (sync) { + game::Cmd_ExecuteSingleCommand(game::LocalClientNum_t::LOCAL_CLIENT_0, 0, + command.data()); + } else { + game::Cbuf_AddText(game::LocalClientNum_t::LOCAL_CLIENT_0, command.data()); } +} - std::string params::join(const int index) const - { - std::string result = {}; +class component final : public component_interface { +public: + void post_unpack() override { add_commands_generic(); } - for (auto i = index; i < this->size(); i++) - { - if (i > index) result.append(" "); - result.append(this->get(i)); - } +private: + static void add_commands_generic() { + // Will cause blue screen + add("quit_meme", utils::nt::raise_hard_exception); - return result; + add("quit", game::Com_Quit_f); } - - void add_raw(const char* name, void (*callback)()) - { - game::Cmd_AddCommandInternal( - name, - callback, - utils::memory::get_allocator()->allocate()); - } - - void add(const char* name, const std::function& callback) - { - const auto command = utils::string::to_lower(name); - - if (!handlers.contains(command)) - { - add_raw(name, main_handler); - } - - handlers[command] = callback; - } - - void add(const char* name, const std::function& callback) - { - add(name, - [callback](const params&) - { - callback(); - }); - } - - void execute(std::string command, const bool sync) - { - command += "\n"; - - if (sync) - { - game::Cmd_ExecuteSingleCommand( - game::LocalClientNum_t::LOCAL_CLIENT_0, 0, command.data()); - } - else - { - game::Cbuf_AddText(game::LocalClientNum_t::LOCAL_CLIENT_0, - command.data()); - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - add_commands_generic(); - } - - private: - static void add_commands_generic() - { - // Will cause blue screen - add("quit_meme", utils::nt::raise_hard_exception); - - add("quit", game::Com_Quit_f); - } - }; +}; } // namespace command REGISTER_COMPONENT(command::component) diff --git a/src/component/command.hpp b/src/component/command.hpp index fc04b53..8996ad2 100644 --- a/src/component/command.hpp +++ b/src/component/command.hpp @@ -1,29 +1,23 @@ #pragma once -namespace command -{ - class params - { - public: - params(); +namespace command { +class params { +public: + params(); - [[nodiscard]] int size() const; - [[nodiscard]] const char* get(int index) const; - [[nodiscard]] std::string join(int index) const; + [[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); - } + const char* operator[](const int index) const { return this->get(index); } - private: - int nesting_; - }; +private: + int nesting_; +}; - 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 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); +void execute(std::string command, bool sync = false); } // namespace command diff --git a/src/component/console.cpp b/src/component/console.cpp index 3c183bb..d0e66fe 100644 --- a/src/component/console.cpp +++ b/src/component/console.cpp @@ -2,54 +2,42 @@ #include -namespace console -{ - namespace - { - std::thread thread; - std::thread::id async_thread_id; +namespace console { +namespace { +std::thread thread; +std::thread::id async_thread_id; - LRESULT __stdcall sys_start_console(HWND, UINT, WPARAM, LPARAM) - { - game::Sys_ShowConsole(); - return 0; - } +LRESULT __stdcall sys_start_console(HWND, UINT, WPARAM, LPARAM) { + game::Sys_ShowConsole(); + return 0; +} - void console_unlock() - { - const auto callback = - SetWindowLongA(*game::g_wv_hWnd, - GWL_WNDPROC, - reinterpret_cast(sys_start_console)); +void console_unlock() { + const auto callback = SetWindowLongA( + *game::g_wv_hWnd, GWL_WNDPROC, reinterpret_cast(sys_start_console)); - SendMessageA(*game::g_wv_hWnd, WM_QUIT, 0, 0); - SetWindowLongA(*game::g_wv_hWnd, GWL_WNDPROC, callback); - } + SendMessageA(*game::g_wv_hWnd, WM_QUIT, 0, 0); + SetWindowLongA(*game::g_wv_hWnd, GWL_WNDPROC, callback); +} - void show_console() - { - if (*game::s_wcd_hWnd) - { - ShowWindow(*game::s_wcd_hWnd, SW_SHOW); - } - } - } // namespace +void show_console() { + if (*game::s_wcd_hWnd) { + ShowWindow(*game::s_wcd_hWnd, SW_SHOW); + } +} +} // namespace - class component final : public component_interface - { - public: - void post_unpack() override - { - thread = std::thread( - []() - { - console_unlock(); - show_console(); - }); +class component final : public component_interface { +public: + void post_unpack() override { + thread = std::thread([]() { + console_unlock(); + show_console(); + }); - async_thread_id = thread.get_id(); - } - }; + async_thread_id = thread.get_id(); + } +}; } // namespace console REGISTER_COMPONENT(console::component) diff --git a/src/component/dvar_patches.cpp b/src/component/dvar_patches.cpp index afbdbfe..9318fb6 100644 --- a/src/component/dvar_patches.cpp +++ b/src/component/dvar_patches.cpp @@ -3,18 +3,15 @@ #include -namespace dvar_patches -{ - void dvar_set_from_string_by_name_stub(const char*, const char*) {} +namespace dvar_patches { +void dvar_set_from_string_by_name_stub(const char*, const char*) {} - class component final : public component_interface - { - public: - void post_unpack() override - { - utils::hook::call(0x59C0EF, dvar_set_from_string_by_name_stub); - } - }; +class component final : public component_interface { +public: + void post_unpack() override { + utils::hook::call(0x59C0EF, dvar_set_from_string_by_name_stub); + } +}; } // namespace dvar_patches REGISTER_COMPONENT(dvar_patches::component) \ No newline at end of file diff --git a/src/component/exploit.cpp b/src/component/exploit.cpp index 2bc28ff..f2d6fce 100644 --- a/src/component/exploit.cpp +++ b/src/component/exploit.cpp @@ -6,120 +6,103 @@ #include "command.hpp" #include "key_catcher.hpp" -namespace exploit -{ - game::dvar_t* cl_exploit; +namespace exploit { +game::dvar_t* cl_exploit; - /* - * void CL_Netchan_Transmit(netchan_t* chan, unsigned char* data, int a3) - * A brief description of data: the first few bytes contain information from - * clientConnection_t structure Offset 0: ServerID Size : 1 Offset 1: - * serverMessageSequence Size: 4 Offset 5: serverCommandSequence Size: 4 One - * clean way of sending invalid data to the server is to hook the functions - * that write the info to the packet Credit: - * https://stackoverflow.com/questions/58981714/how-do-i-change-the-value-of-a-single-byte-in-a-uint32-t-variable - */ +/* + * void CL_Netchan_Transmit(netchan_t* chan, unsigned char* data, int a3) + * A brief description of data: the first few bytes contain information from + * clientConnection_t structure Offset 0: ServerID Size : 1 Offset 1: + * serverMessageSequence Size: 4 Offset 5: serverCommandSequence Size: 4 One + * clean way of sending invalid data to the server is to hook the functions + * that write the info to the packet Credit: + * https://stackoverflow.com/questions/58981714/how-do-i-change-the-value-of-a-single-byte-in-a-uint32-t-variable + */ - void write_message_sequence(game::msg_t* msg, int data) - { - if (msg->maxsize - static_cast(msg->cursize) < sizeof(int)) - { - msg->overflowed = TRUE; - return; - } - - if (cl_exploit->current.enabled) data = (data & 0xFFFFFF00) | 0xAAu; - - auto* dest = reinterpret_cast(&msg->data[msg->cursize]); - *dest = data; - msg->cursize += sizeof(int); +void write_message_sequence(game::msg_t* msg, int data) { + if (msg->maxsize - static_cast(msg->cursize) < sizeof(int)) { + msg->overflowed = TRUE; + return; } - void write_command_sequence(game::msg_t* msg, int data) - { - if (msg->maxsize - static_cast(msg->cursize) < sizeof(int)) - { - msg->overflowed = TRUE; - return; - } + if (cl_exploit->current.enabled) + data = (data & 0xFFFFFF00) | 0xAAu; - if (cl_exploit->current.enabled) data = (data & 0x00FFFFFF) | (0x80u << 24); + auto* dest = reinterpret_cast(&msg->data[msg->cursize]); + *dest = data; + msg->cursize += sizeof(int); +} - auto* dest = reinterpret_cast(&msg->data[msg->cursize]); - *dest = data; - msg->cursize += sizeof(int); +void write_command_sequence(game::msg_t* msg, int data) { + if (msg->maxsize - static_cast(msg->cursize) < sizeof(int)) { + msg->overflowed = TRUE; + return; } - class component final : public component_interface - { - public: - void post_unpack() override - { - cl_exploit = game::Dvar_RegisterBool( - "cl_exploit", false, game::DVAR_NONE, "Enable server freezer"); + if (cl_exploit->current.enabled) + data = (data & 0x00FFFFFF) | (0x80u << 24); - add_exploit_commands(); - add_key_hooks(); + auto* dest = reinterpret_cast(&msg->data[msg->cursize]); + *dest = data; + msg->cursize += sizeof(int); +} - utils::hook::call(0x420B76, write_message_sequence); - utils::hook::call(0x420B86, write_command_sequence); - } +class component final : public component_interface { +public: + void post_unpack() override { + cl_exploit = game::Dvar_RegisterBool("cl_exploit", false, game::DVAR_NONE, + "Enable server freezer"); - private: - static void add_key_hooks() - { - key_catcher::on_key_press( - "O", - []([[maybe_unused]] const game::LocalClientNum_t& local_client) - { - command::execute("exploit"); - }); + add_exploit_commands(); + add_key_hooks(); - key_catcher::on_key_press( - "L", - []([[maybe_unused]] const game::LocalClientNum_t& local_client) - { - command::execute("undo_exploit"); - }); + utils::hook::call(0x420B76, write_message_sequence); + utils::hook::call(0x420B86, write_command_sequence); + } - key_catcher::on_key_press( - "K", - []([[maybe_unused]] const game::LocalClientNum_t& local_client) - { - command::execute("disconnect"); - }); - } +private: + static void add_key_hooks() { + key_catcher::on_key_press( + "O", []([[maybe_unused]] const game::LocalClientNum_t& local_client) { + command::execute("exploit"); + }); - static void add_exploit_commands() - { - command::add("exploit", - []([[maybe_unused]] const command::params& params) - { - game::Dvar_SetBool(cl_exploit, true); - }); + key_catcher::on_key_press( + "L", []([[maybe_unused]] const game::LocalClientNum_t& local_client) { + command::execute("undo_exploit"); + }); - command::add("undo_exploit", - []([[maybe_unused]] const command::params& params) - { - game::Dvar_SetBool(cl_exploit, false); - }); + key_catcher::on_key_press( + "K", []([[maybe_unused]] const game::LocalClientNum_t& local_client) { + command::execute("disconnect"); + }); + } - command::add( - "send_command", - []([[maybe_unused]] const command::params& params) - { - if (params.size() < 2) return; + static void add_exploit_commands() { + command::add("exploit", []([[maybe_unused]] const command::params& params) { + game::Dvar_SetBool(cl_exploit, true); + }); - if (*game::connectionState <= game::connstate_t::CA_CHALLENGING) - return; + command::add("undo_exploit", + []([[maybe_unused]] const command::params& params) { + game::Dvar_SetBool(cl_exploit, false); + }); - const auto cmd = std::format("queryserverinfo ;{}", params.join(1)); - game::NET_OutOfBandPrint(game::NS_SERVER, - game::localClientConnection->serverAddress, - cmd.data()); - }); - } - }; + command::add( + "send_command", []([[maybe_unused]] const command::params& params) { + if (params.size() < 2) + return; + + if (*game::connectionState <= game::connstate_t::CA_CHALLENGING) + return; + + const auto cmd = std::format("queryserverinfo ;{}", params.join(1)); + game::NET_OutOfBandPrint(game::NS_SERVER, + game::localClientConnection->serverAddress, + cmd.data()); + }); + } +}; } // namespace exploit REGISTER_COMPONENT(exploit::component) diff --git a/src/component/key_catcher.cpp b/src/component/key_catcher.cpp index 040a14e..bd80b0f 100644 --- a/src/component/key_catcher.cpp +++ b/src/component/key_catcher.cpp @@ -5,63 +5,49 @@ #include "key_catcher.hpp" -namespace key_catcher -{ - utils::hook::detour cl_key_event_hook; +namespace key_catcher { +utils::hook::detour cl_key_event_hook; - namespace - { - std::unordered_map& get_key_callbacks() - { - static std::unordered_map - key_callbacks{}; - return key_callbacks; +namespace { +std::unordered_map& get_key_callbacks() { + static std::unordered_map key_callbacks{}; + return key_callbacks; +} + +void handle_key_event(game::LocalClientNum_t local_client, int key_id) { + const auto result = VkKeyScanA(static_cast(key_id)); + const auto vk_key = LOBYTE(result); + const auto& callbacks = get_key_callbacks(); + + for (auto const& [key, value] : callbacks) { + const auto game_vk_key = game::Key_StringToKeynum(key.data()); + if (static_cast(game_vk_key) == vk_key) { + value(local_client); + return; } + } +} +} // namespace - void handle_key_event(game::LocalClientNum_t local_client, int key_id) - { - const auto result = VkKeyScanA(static_cast(key_id)); - const auto vk_key = LOBYTE(result); - const auto& callbacks = get_key_callbacks(); +void on_key_press(const std::string& command, const callback& callback) { + get_key_callbacks()[command] = callback; +} - for (auto const& [key, value] : callbacks) - { - const auto game_vk_key = game::Key_StringToKeynum(key.data()); - if (static_cast(game_vk_key) == vk_key) - { - value(local_client); - return; - } - } - } - } // namespace +void cl_key_event_stub(game::LocalClientNum_t local_client, int key_id, + int a3) { + handle_key_event(local_client, key_id); - void on_key_press(const std::string& command, const callback& callback) - { - get_key_callbacks()[command] = callback; + cl_key_event_hook.invoke(local_client, key_id, a3); +} + +class component final : public component_interface { +public: + void post_unpack() override { + cl_key_event_hook.create(0x4CD840, &cl_key_event_stub); } - void cl_key_event_stub(game::LocalClientNum_t local_client, int key_id, - int a3) - { - handle_key_event(local_client, key_id); - - cl_key_event_hook.invoke(local_client, key_id, a3); - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - cl_key_event_hook.create(0x4CD840, &cl_key_event_stub); - } - - void pre_destroy() override - { - cl_key_event_hook.clear(); - } - }; + void pre_destroy() override { cl_key_event_hook.clear(); } +}; } // namespace key_catcher REGISTER_COMPONENT(key_catcher::component) diff --git a/src/component/key_catcher.hpp b/src/component/key_catcher.hpp index d79c98c..db2e0e3 100644 --- a/src/component/key_catcher.hpp +++ b/src/component/key_catcher.hpp @@ -1,8 +1,7 @@ #pragma once -namespace key_catcher -{ - using callback = std::function; +namespace key_catcher { +using callback = std::function; - void on_key_press(const std::string& command, const callback& callback); +void on_key_press(const std::string& command, const callback& callback); } // namespace key_catcher diff --git a/src/component/network.cpp b/src/component/network.cpp index df4e9c0..c259ceb 100644 --- a/src/component/network.cpp +++ b/src/component/network.cpp @@ -7,77 +7,64 @@ #include "network.hpp" #include "command.hpp" -namespace network -{ - namespace - { - std::unordered_map& get_callbacks() - { - static std::unordered_map - network_callbacks{}; - return network_callbacks; - } +namespace network { +namespace { +std::unordered_map& get_callbacks() { + static std::unordered_map network_callbacks{}; + return network_callbacks; +} - bool handle_command(game::netadr_s* address, const char* command, - game::msg_t* msg) - { - const auto cmd_string = utils::string::to_lower(command); - auto& callbacks = get_callbacks(); - const auto handler = callbacks.find(cmd_string); - const auto offset = cmd_string.size() + 5; +bool handle_command(game::netadr_s* address, const char* command, + game::msg_t* msg) { + const auto cmd_string = utils::string::to_lower(command); + auto& callbacks = get_callbacks(); + const auto handler = callbacks.find(cmd_string); + const auto offset = cmd_string.size() + 5; - if (static_cast(msg->cursize) < offset || - handler == callbacks.end()) - { - return false; - } - - const std::string_view data(reinterpret_cast(msg->data) + offset, - msg->cursize - offset); - - handler->second(*address, data); - return true; - } - } // namespace - - int packet_interception_handler(game::netadr_s* from, const char* command, - game::msg_t* message) - { - if (!handle_command(from, command, message)) - { - return reinterpret_cast(0x525730)( - from, command, message); - } - - return TRUE; + if (static_cast(msg->cursize) < offset || + handler == callbacks.end()) { + return false; } - void on_packet(const std::string& command, const callback& callback) - { - get_callbacks()[utils::string::to_lower(command)] = callback; + const std::string_view data(reinterpret_cast(msg->data) + offset, + msg->cursize - offset); + + handler->second(*address, data); + return true; +} +} // namespace + +int packet_interception_handler(game::netadr_s* from, const char* command, + game::msg_t* message) { + if (!handle_command(from, command, message)) { + return reinterpret_cast(0x525730)(from, command, + message); } - class component final : public component_interface - { - public: - void post_unpack() override - { - add_network_commands(); + return TRUE; +} - utils::hook::call(0x5B27E1, packet_interception_handler); - } +void on_packet(const std::string& command, const callback& callback) { + get_callbacks()[utils::string::to_lower(command)] = callback; +} - private: - static void add_network_commands() - { - on_packet("naughty_reply", - [](const game::netadr_s&, const std::string_view&) - { - command::execute("quit_meme"); - }); - } - }; +class component final : public component_interface { +public: + void post_unpack() override { + add_network_commands(); + + utils::hook::call(0x5B27E1, packet_interception_handler); + } + +private: + static void add_network_commands() { + on_packet("naughty_reply", + [](const game::netadr_s&, const std::string_view&) { + command::execute("quit_meme"); + }); + } +}; } // namespace network REGISTER_COMPONENT(network::component) diff --git a/src/component/network.hpp b/src/component/network.hpp index b2f87c1..b5e3fe2 100644 --- a/src/component/network.hpp +++ b/src/component/network.hpp @@ -1,9 +1,8 @@ #pragma once -namespace network -{ - using callback = - std::function; +namespace network { +using callback = + std::function; - void on_packet(const std::string& command, const callback& callback); +void on_packet(const std::string& command, const callback& callback); } // namespace network diff --git a/src/component/remove_hooks.cpp b/src/component/remove_hooks.cpp index cedcd66..74be176 100644 --- a/src/component/remove_hooks.cpp +++ b/src/component/remove_hooks.cpp @@ -3,32 +3,26 @@ #include -namespace remove_hooks -{ - class component final : public component_interface - { - public: - void post_unpack() override - { - remove_tekno_hooks(); - } +namespace remove_hooks { +class component final : public component_interface { +public: + void post_unpack() override { remove_tekno_hooks(); } - private: - static void remove_tekno_hooks() - { - utils::hook::set(0x4E3D42, 0xE8); - utils::hook::set(0x4E3D43, 0xA9); - utils::hook::set(0x4E3D44, 0x25); - utils::hook::set(0x4E3D45, 0xFE); - utils::hook::set(0x4E3D46, 0xFF); +private: + static void remove_tekno_hooks() { + utils::hook::set(0x4E3D42, 0xE8); + utils::hook::set(0x4E3D43, 0xA9); + utils::hook::set(0x4E3D44, 0x25); + utils::hook::set(0x4E3D45, 0xFE); + utils::hook::set(0x4E3D46, 0xFF); - utils::hook::set(0x6EA960, 0x55); - utils::hook::set(0x6EA961, 0x8B); - utils::hook::set(0x6EA962, 0xEC); - utils::hook::set(0x6EA963, 0x81); - utils::hook::set(0x6EA964, 0xEC); - } - }; + utils::hook::set(0x6EA960, 0x55); + utils::hook::set(0x6EA961, 0x8B); + utils::hook::set(0x6EA962, 0xEC); + utils::hook::set(0x6EA963, 0x81); + utils::hook::set(0x6EA964, 0xEC); + } +}; } // namespace remove_hooks REGISTER_COMPONENT(remove_hooks::component) diff --git a/src/component/scheduler.cpp b/src/component/scheduler.cpp index 21627b5..5b8b47d 100644 --- a/src/component/scheduler.cpp +++ b/src/component/scheduler.cpp @@ -6,181 +6,139 @@ #include "scheduler.hpp" -namespace scheduler -{ - std::thread::id async_thread_id; +namespace scheduler { +std::thread::id async_thread_id; - namespace - { - struct task - { - std::function handler{}; - std::chrono::milliseconds interval{}; - std::chrono::high_resolution_clock::time_point last_call{}; - }; +namespace { +struct task { + std::function handler{}; + std::chrono::milliseconds interval{}; + std::chrono::high_resolution_clock::time_point last_call{}; +}; - using task_list = std::vector; +using task_list = std::vector; - class task_pipeline - { - public: - void add(task&& task) - { - new_callbacks_.access( - [&task, this](task_list& tasks) - { - tasks.emplace_back(std::move(task)); - }); - } - - void clear() - { - callbacks_.access( - [&](task_list& tasks) - { - this->merge_callbacks(); - tasks.clear(); - }); - } - - void execute() - { - callbacks_.access( - [&](task_list& tasks) - { - this->merge_callbacks(); - - for (auto i = tasks.begin(); i != tasks.end();) - { - const auto now = std::chrono::high_resolution_clock::now(); - const auto diff = now - i->last_call; - - if (diff < i->interval) - { - ++i; - continue; - } - - i->last_call = now; - - const auto res = i->handler(); - if (res == cond_end) - { - i = tasks.erase(i); - } - else - { - ++i; - } - } - }); - } - - private: - utils::concurrency::container new_callbacks_; - utils::concurrency::container callbacks_; - - void merge_callbacks() - { - callbacks_.access( - [&](task_list& tasks) - { - new_callbacks_.access( - [&](task_list& new_tasks) - { - tasks.insert(tasks.end(), - std::move_iterator( - new_tasks.begin()), - std::move_iterator( - new_tasks.end())); - new_tasks = {}; - }); - }); - } - }; - - std::thread thread; - task_pipeline pipelines[pipeline::count]; - - void execute(const pipeline type) - { - assert(type >= 0 && type < pipeline::count); - pipelines[type].execute(); - } - - void cl_frame_stub(game::LocalClientNum_t local) - { - reinterpret_cast(0x41C9B0)(local); - execute(pipeline::client); - } - } // namespace - - void clear_tasks(const pipeline type) - { - return pipelines[type].clear(); +class task_pipeline { +public: + void add(task&& task) { + new_callbacks_.access([&task, this](task_list& tasks) { + tasks.emplace_back(std::move(task)); + }); } - void schedule(const std::function& callback, const pipeline type, - const std::chrono::milliseconds delay) - { - assert(type >= 0 && type < pipeline::count); - - task task; - task.handler = callback; - task.interval = delay; - task.last_call = std::chrono::high_resolution_clock::now(); - - pipelines[type].add(std::move(task)); + void clear() { + callbacks_.access([&](task_list& tasks) { + this->merge_callbacks(); + tasks.clear(); + }); } - void loop(const std::function& callback, const pipeline type, - const std::chrono::milliseconds delay) - { - schedule( - [callback]() - { - callback(); - return cond_continue; - }, - type, - delay); + void execute() { + callbacks_.access([&](task_list& tasks) { + this->merge_callbacks(); + + for (auto i = tasks.begin(); i != tasks.end();) { + const auto now = std::chrono::high_resolution_clock::now(); + const auto diff = now - i->last_call; + + if (diff < i->interval) { + ++i; + continue; + } + + i->last_call = now; + + const auto res = i->handler(); + if (res == cond_end) { + i = tasks.erase(i); + } else { + ++i; + } + } + }); } - void once(const std::function& callback, const pipeline type, - const std::chrono::milliseconds delay) - { - schedule( - [callback]() - { - callback(); - return cond_end; - }, - type, - delay); +private: + utils::concurrency::container new_callbacks_; + utils::concurrency::container callbacks_; + + void merge_callbacks() { + callbacks_.access([&](task_list& tasks) { + new_callbacks_.access([&](task_list& new_tasks) { + tasks.insert(tasks.end(), + std::move_iterator(new_tasks.begin()), + std::move_iterator(new_tasks.end())); + new_tasks = {}; + }); + }); } +}; - unsigned int thread_id; +std::thread thread; +task_pipeline pipelines[pipeline::count]; - class component final : public component_interface - { - public: - void post_unpack() override - { - thread = std::thread( - []() - { - while (true) - { - execute(pipeline::async); - std::this_thread::sleep_for(10ms); - } - }); +void execute(const pipeline type) { + assert(type >= 0 && type < pipeline::count); + pipelines[type].execute(); +} - async_thread_id = thread.get_id(); +void cl_frame_stub(game::LocalClientNum_t local) { + reinterpret_cast(0x41C9B0)(local); + execute(pipeline::client); +} +} // namespace - utils::hook::call(0x4E4A0D, cl_frame_stub); - } - }; +void clear_tasks(const pipeline type) { return pipelines[type].clear(); } + +void schedule(const std::function& callback, const pipeline type, + const std::chrono::milliseconds delay) { + assert(type >= 0 && type < pipeline::count); + + task task; + task.handler = callback; + task.interval = delay; + task.last_call = std::chrono::high_resolution_clock::now(); + + pipelines[type].add(std::move(task)); +} + +void loop(const std::function& callback, const pipeline type, + const std::chrono::milliseconds delay) { + schedule( + [callback]() { + callback(); + return cond_continue; + }, + type, delay); +} + +void once(const std::function& callback, const pipeline type, + const std::chrono::milliseconds delay) { + schedule( + [callback]() { + callback(); + return cond_end; + }, + type, delay); +} + +unsigned int thread_id; + +class component final : public component_interface { +public: + void post_unpack() override { + thread = std::thread([]() { + while (true) { + execute(pipeline::async); + std::this_thread::sleep_for(10ms); + } + }); + + async_thread_id = thread.get_id(); + + utils::hook::call(0x4E4A0D, cl_frame_stub); + } +}; } // namespace scheduler REGISTER_COMPONENT(scheduler::component) diff --git a/src/component/scheduler.hpp b/src/component/scheduler.hpp index 0a8bb50..a165d7d 100644 --- a/src/component/scheduler.hpp +++ b/src/component/scheduler.hpp @@ -1,28 +1,26 @@ #pragma once -namespace scheduler -{ - extern std::thread::id async_thread_id; +namespace scheduler { +extern std::thread::id async_thread_id; - enum pipeline - { - client, - async, - count, - }; +enum pipeline { + client, + async, + count, +}; - static const bool cond_continue = false; - static const bool cond_end = true; +static const bool cond_continue = false; +static const bool cond_end = true; - void clear_tasks(const pipeline type); +void clear_tasks(const pipeline type); - void schedule(const std::function& callback, - pipeline type = pipeline::client, - std::chrono::milliseconds delay = 0ms); - void loop(const std::function& callback, - pipeline type = pipeline::client, - std::chrono::milliseconds delay = 0ms); - void once(const std::function& callback, - pipeline type = pipeline::client, - std::chrono::milliseconds delay = 0ms); +void schedule(const std::function& callback, + pipeline type = pipeline::client, + std::chrono::milliseconds delay = 0ms); +void loop(const std::function& callback, + pipeline type = pipeline::client, + std::chrono::milliseconds delay = 0ms); +void once(const std::function& callback, + pipeline type = pipeline::client, + std::chrono::milliseconds delay = 0ms); } // namespace scheduler diff --git a/src/component/user_info.cpp b/src/component/user_info.cpp index c96a165..51696e1 100644 --- a/src/component/user_info.cpp +++ b/src/component/user_info.cpp @@ -8,46 +8,44 @@ #include "scheduler.hpp" -namespace user_info -{ - namespace +namespace user_info { +namespace { +int a1 = 0; +void cl_check_user_info(int _a1, const int force) { + a1 = _a1; + + if (*game::connectionState <= game::connstate_t::CA_CHALLENGING) + return; + + if (game::cl_paused->current.enabled && !force) + return; + + const std::string info_string = game::Dvar_InfoString(_a1, 0x200); + utils::info_string info(info_string); + + const auto color_code = std::rand() % 10; + + char name[16]; + + const auto numbers = std::to_string(std::rand() % 10000); + _snprintf_s(name, sizeof(name), _TRUNCATE, "^%d%s", color_code, + numbers.data()); + + info.set("name", name); + + info.set("ec_usingTag", "1"); + info.set("ec_TagText", utils::string::va("^%dGG", color_code)); + + const auto big_title = std::to_string(std::rand() % 512); + info.set("ec_TitleBg", big_title); + + game::CL_AddReliableCommand( + _a1, utils::string::va("userinfo \"%s\"", info.build().data())); +} + +__declspec(naked) void cl_check_user_info_stub() { + __asm { - int a1 = 0; - void cl_check_user_info(int _a1, const int force) - { - a1 = _a1; - - if (*game::connectionState <= game::connstate_t::CA_CHALLENGING) return; - - if (game::cl_paused->current.enabled && !force) return; - - const std::string info_string = game::Dvar_InfoString(_a1, 0x200); - utils::info_string info(info_string); - - const auto color_code = std::rand() % 10; - - char name[16]; - - const auto numbers = std::to_string(std::rand() % 10000); - _snprintf_s( - name, sizeof(name), _TRUNCATE, "^%d%s", color_code, numbers.data()); - - info.set("name", name); - - info.set("ec_usingTag", "1"); - info.set("ec_TagText", utils::string::va("^%dGG", color_code)); - - const auto big_title = std::to_string(std::rand() % 512); - info.set("ec_TitleBg", big_title); - - game::CL_AddReliableCommand( - _a1, utils::string::va("userinfo \"%s\"", info.build().data())); - } - - __declspec(naked) void cl_check_user_info_stub() - { - __asm - { pushad push 0 @@ -57,26 +55,19 @@ namespace user_info popad ret - } - } - } // namespace + } +} +} // namespace - class component final : public component_interface - { - public: - void post_unpack() override - { - utils::hook::call(0x41CA53, cl_check_user_info_stub); +class component final : public component_interface { +public: + void post_unpack() override { + utils::hook::call(0x41CA53, cl_check_user_info_stub); - scheduler::loop( - [] - { - cl_check_user_info(a1, TRUE); - }, - scheduler::pipeline::client, - 4s); - } - }; + scheduler::loop([] { cl_check_user_info(a1, TRUE); }, + scheduler::pipeline::client, 4s); + } +}; } // namespace user_info REGISTER_COMPONENT(user_info::component)