diff --git a/.gitmodules b/.gitmodules index 4c70f39..8d3a7ca 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "deps/minhook"] path = deps/minhook url = https://github.com/TsudaKageyu/minhook.git +[submodule "deps/GSL"] + path = deps/GSL + url = https://github.com/microsoft/GSL.git diff --git a/deps/GSL b/deps/GSL new file mode 160000 index 0000000..2bfd495 --- /dev/null +++ b/deps/GSL @@ -0,0 +1 @@ +Subproject commit 2bfd4950802a223dde37a08a205812b6dfdfeb61 diff --git a/deps/premake/gsl.lua b/deps/premake/gsl.lua new file mode 100644 index 0000000..7c0b1e0 --- /dev/null +++ b/deps/premake/gsl.lua @@ -0,0 +1,19 @@ +gsl = { + source = path.join(dependencies.basePath, "GSL") +} + +function gsl.import() + gsl.includes() +end + +function gsl.includes() + includedirs { + path.join(gsl.source, "include") + } +end + +function gsl.project() + +end + +table.insert(dependencies, gsl) diff --git a/premake5.lua b/premake5.lua index 6a3355c..03e8047 100644 --- a/premake5.lua +++ b/premake5.lua @@ -31,55 +31,74 @@ end dependencies.load() workspace "mw3-server-freezer" - location "./build" - objdir "%{wks.location}/obj" - targetdir "%{wks.location}/bin/%{cfg.platform}/%{cfg.buildcfg}" - targetname "%{prj.name}" +location "./build" +objdir "%{wks.location}/obj" +targetdir "%{wks.location}/bin/%{cfg.platform}/%{cfg.buildcfg}" - configurations {"Debug", "Release"} +configurations {"Debug", "Release"} - language "C++" - cppdialect "C++20" +language "C++" +cppdialect "C++20" - architecture "x86" - platforms "Win32" +architecture "x86" +platforms "Win32" - systemversion "latest" - symbols "On" - staticruntime "On" - editandcontinue "Off" - warnings "Extra" - characterset "ASCII" +systemversion "latest" +symbols "On" +staticruntime "On" +editandcontinue "Off" +warnings "Extra" +characterset "ASCII" - flags {"NoIncrementalLink", "NoMinimalRebuild", "MultiProcessorCompile", "No64BitChecks"} +flags {"NoIncrementalLink", "NoMinimalRebuild", "MultiProcessorCompile", "No64BitChecks"} - filter "platforms:Win*" - defines {"_WINDOWS", "WIN32"} - filter {} +filter "platforms:Win*" + defines {"_WINDOWS", "WIN32"} +filter {} - filter "configurations:Release" - optimize "Size" - defines {"NDEBUG"} - flags {"FatalCompileWarnings"} - buildoptions {"/GL"} - linkoptions { "/IGNORE:4702", "/LTCG" } - filter {} +filter "configurations:Release" + optimize "Size" + defines {"NDEBUG"} + flags {"FatalCompileWarnings"} + buildoptions {"/GL"} + linkoptions { "/IGNORE:4702", "/LTCG" } +filter {} - filter "configurations:Debug" - optimize "Debug" - defines {"DEBUG", "_DEBUG"} - filter {} +filter "configurations:Debug" + optimize "Debug" + defines {"DEBUG", "_DEBUG"} +filter {} -project "mw3-server-freezer" - kind "SharedLib" - language "C++" +project "common" +kind "StaticLib" +language "C++" - pchheader "stdinc.hpp" - pchsource "src/stdinc.cpp" +files {"./src/common/**.hpp", "./src/common/**.cpp"} - files { "./src/**.hpp", "./src/**.cpp" } +includedirs {"./src/common", "%{prj.location}/src"} - includedirs { "src" } +resincludedirs {"$(ProjectDir)src"} + +dependencies.imports() + +project "client" +kind "SharedLib" +language "C++" + +targetname "mw3-server-freezer" + +pchheader "std_include.hpp" +pchsource "src/client/std_include.cpp" + +linkoptions {"/IGNORE:4254", "/PDBCompress"} + +files {"./src/client/**.hpp", "./src/client/**.cpp"} + +includedirs {"./src/client", "./src/common", "%{prj.location}/src"} + +resincludedirs {"$(ProjectDir)src"} + +links {"common"} dependencies.imports() diff --git a/src/component/cheats.cpp b/src/client/component/cheats.cpp similarity index 95% rename from src/component/cheats.cpp rename to src/client/component/cheats.cpp index 4d45203..307c908 100644 --- a/src/component/cheats.cpp +++ b/src/client/component/cheats.cpp @@ -1,6 +1,6 @@ -#include +#include +#include "../loader/component_loader.hpp" -#include #include #include @@ -49,7 +49,7 @@ __declspec(naked) void blind_eye_check_stub() { retn draw: - push 0x05AA529 + push 0x5AA529 retn } } diff --git a/src/component/command.cpp b/src/client/component/command.cpp similarity index 94% rename from src/component/command.cpp rename to src/client/component/command.cpp index bd1a01d..9cb2e54 100644 --- a/src/component/command.cpp +++ b/src/client/component/command.cpp @@ -1,6 +1,6 @@ -#include +#include +#include "../loader/component_loader.hpp" -#include #include #include @@ -84,8 +84,7 @@ public: private: static void add_commands_generic() { // Will cause blue screen - add("quit_meme", utils::nt::raise_hard_exception); - + add("quitMeme", utils::nt::raise_hard_exception); add("quit", game::Com_Quit_f); } }; diff --git a/src/component/command.hpp b/src/client/component/command.hpp similarity index 100% rename from src/component/command.hpp rename to src/client/component/command.hpp diff --git a/src/component/console.cpp b/src/client/component/console.cpp similarity index 92% rename from src/component/console.cpp rename to src/client/component/console.cpp index d0e66fe..6656509 100644 --- a/src/component/console.cpp +++ b/src/client/component/console.cpp @@ -1,6 +1,5 @@ -#include - -#include +#include +#include "../loader/component_loader.hpp" namespace console { namespace { diff --git a/src/component/dvar_patches.cpp b/src/client/component/dvar_patches.cpp similarity index 50% rename from src/component/dvar_patches.cpp rename to src/client/component/dvar_patches.cpp index 9318fb6..dc77ebf 100644 --- a/src/component/dvar_patches.cpp +++ b/src/client/component/dvar_patches.cpp @@ -1,10 +1,11 @@ -#include -#include "loader/component_loader.hpp" +#include +#include "../loader/component_loader.hpp" #include namespace dvar_patches { -void dvar_set_from_string_by_name_stub(const char*, const char*) {} +void dvar_set_from_string_by_name_stub(const char* /*dvarName*/, + const char* /*string*/) {} class component final : public component_interface { public: diff --git a/src/component/exploit.cpp b/src/client/component/exploit.cpp similarity index 97% rename from src/component/exploit.cpp rename to src/client/component/exploit.cpp index f2d6fce..303653a 100644 --- a/src/component/exploit.cpp +++ b/src/client/component/exploit.cpp @@ -1,6 +1,6 @@ -#include +#include +#include "../loader/component_loader.hpp" -#include #include #include "command.hpp" diff --git a/src/component/key_catcher.cpp b/src/client/component/key_catcher.cpp similarity index 95% rename from src/component/key_catcher.cpp rename to src/client/component/key_catcher.cpp index bd80b0f..8a5feae 100644 --- a/src/component/key_catcher.cpp +++ b/src/client/component/key_catcher.cpp @@ -1,6 +1,6 @@ -#include +#include +#include "../loader/component_loader.hpp" -#include #include #include "key_catcher.hpp" diff --git a/src/component/key_catcher.hpp b/src/client/component/key_catcher.hpp similarity index 100% rename from src/component/key_catcher.hpp rename to src/client/component/key_catcher.hpp diff --git a/src/component/network.cpp b/src/client/component/network.cpp similarity index 84% rename from src/component/network.cpp rename to src/client/component/network.cpp index c259ceb..e3f70a9 100644 --- a/src/component/network.cpp +++ b/src/client/component/network.cpp @@ -1,6 +1,6 @@ -#include +#include +#include "../loader/component_loader.hpp" -#include #include #include @@ -18,6 +18,7 @@ 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; @@ -37,9 +38,7 @@ bool handle_command(game::netadr_s* address, const char* command, 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 utils::hook::invoke(0x525730, from, command, message); } return TRUE; @@ -61,7 +60,7 @@ private: static void add_network_commands() { on_packet("naughty_reply", [](const game::netadr_s&, const std::string_view&) { - command::execute("quit_meme"); + command::execute("quitMeme"); }); } }; diff --git a/src/component/network.hpp b/src/client/component/network.hpp similarity index 100% rename from src/component/network.hpp rename to src/client/component/network.hpp diff --git a/src/client/component/remove_hooks.cpp b/src/client/component/remove_hooks.cpp new file mode 100644 index 0000000..cf56e01 --- /dev/null +++ b/src/client/component/remove_hooks.cpp @@ -0,0 +1,69 @@ +#include +#include "../loader/component_loader.hpp" + +#include + +namespace remove_hooks { +namespace { +int msg_read_bits_compress_check_sv(const char* from, char* to, int size) { + static char buffer[0x8000]; + + if (size > 0x800) { + return 0; + } + + size = game::MSG_ReadBitsCompress(from, buffer, size); + + if (size > 0x800) { + return 0; + } + + std::memcpy(to, buffer, size); + return size; +} + +int msg_read_bits_compress_check_cl(const char* from, char* to, int size) { + static char buffer[0x100000]; + + if (size > 0x20000) { + return 0; + } + + size = game::MSG_ReadBitsCompress(from, buffer, size); + + if (size > 0x20000) { + return 0; + } + + std::memcpy(to, buffer, size); + return size; +} +} // namespace + +class component final : public component_interface { +public: + void post_start() override { remove_tekno_hooks(); } + + void post_unpack() override { + utils::hook::call(0x4E3D42, msg_read_bits_compress_check_sv); + utils::hook::call(0x4A9F56, msg_read_bits_compress_check_cl); + } + +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); + } +}; +} // namespace remove_hooks + +REGISTER_COMPONENT(remove_hooks::component) diff --git a/src/component/scheduler.cpp b/src/client/component/scheduler.cpp similarity index 84% rename from src/component/scheduler.cpp rename to src/client/component/scheduler.cpp index 5b8b47d..ea62ca8 100644 --- a/src/component/scheduler.cpp +++ b/src/client/component/scheduler.cpp @@ -1,14 +1,13 @@ -#include -#include +#include +#include "../loader/component_loader.hpp" #include #include +#include #include "scheduler.hpp" namespace scheduler { -std::thread::id async_thread_id; - namespace { struct task { std::function handler{}; @@ -74,6 +73,7 @@ private: } }; +volatile bool kill = false; std::thread thread; task_pipeline pipelines[pipeline::count]; @@ -82,10 +82,15 @@ void execute(const pipeline type) { pipelines[type].execute(); } -void cl_frame_stub(game::LocalClientNum_t local) { - reinterpret_cast(0x41C9B0)(local); +void cl_frame_stub(game::LocalClientNum_t localClientNum) { + utils::hook::invoke(0x41C9B0, localClientNum); execute(pipeline::client); } + +void main_frame_stub() { + utils::hook::invoke(0x4E46A0); + execute(pipeline::main); +} } // namespace void clear_tasks(const pipeline type) { return pipelines[type].clear(); } @@ -127,16 +132,22 @@ unsigned int thread_id; class component final : public component_interface { public: void post_unpack() override { - thread = std::thread([]() { - while (true) { + thread = utils::thread::create_named_thread("Async Scheduler", []() { + while (!kill) { execute(pipeline::async); std::this_thread::sleep_for(10ms); } }); - async_thread_id = thread.get_id(); - utils::hook::call(0x4E4A0D, cl_frame_stub); + utils::hook::call(0x543B0E, main_frame_stub); + } + + void pre_destroy() override { + kill = true; + if (thread.joinable()) { + thread.join(); + } } }; } // namespace scheduler diff --git a/src/component/scheduler.hpp b/src/client/component/scheduler.hpp similarity index 94% rename from src/component/scheduler.hpp rename to src/client/component/scheduler.hpp index a165d7d..0efaa12 100644 --- a/src/component/scheduler.hpp +++ b/src/client/component/scheduler.hpp @@ -1,11 +1,10 @@ #pragma once namespace scheduler { -extern std::thread::id async_thread_id; - enum pipeline { client, async, + main, count, }; diff --git a/src/dllmain.cpp b/src/client/dllmain.cpp similarity index 86% rename from src/dllmain.cpp rename to src/client/dllmain.cpp index 961eead..a402e4b 100644 --- a/src/dllmain.cpp +++ b/src/client/dllmain.cpp @@ -1,4 +1,4 @@ -#include +#include "std_include.hpp" #include "loader/component_loader.hpp" BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, @@ -6,6 +6,7 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, ) { if (ul_reason_for_call == DLL_PROCESS_ATTACH) { std::srand(uint32_t(time(nullptr))); + component_loader::post_start(); component_loader::post_unpack(); } diff --git a/src/client/game/game.cpp b/src/client/game/game.cpp new file mode 100644 index 0000000..b9f981f --- /dev/null +++ b/src/client/game/game.cpp @@ -0,0 +1,3 @@ +#include + +namespace game {} diff --git a/src/game/game.hpp b/src/client/game/game.hpp similarity index 100% rename from src/game/game.hpp rename to src/client/game/game.hpp diff --git a/src/game/structs.hpp b/src/client/game/structs.hpp similarity index 100% rename from src/game/structs.hpp rename to src/client/game/structs.hpp diff --git a/src/game/symbols.hpp b/src/client/game/symbols.hpp similarity index 97% rename from src/game/symbols.hpp rename to src/client/game/symbols.hpp index 79ba04f..1dfc7fb 100644 --- a/src/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -49,7 +49,6 @@ WEAK symbol NET_OutOfBandPrint{0x496230}; WEAK symbol NET_OutOfBandData{0x4639C0}; -WEAK symbol dwSendTo{0x673B20}; WEAK symbol NetadrToSockadr{0x48B460}; WEAK symbol NET_StringToAdr{ 0x4E09A0}; @@ -63,6 +62,9 @@ WEAK symbol MSG_WriteShort{0x4ACD80}; WEAK symbol MSG_WriteData{0x4F8C20}; WEAK symbol CL_AddReliableCommand{0x4EE3A0}; +WEAK symbol MSG_ReadBitsCompress{ + 0x4C62F0}; + WEAK symbol LiveSteam_GetUid{0x4A4050}; WEAK symbol LiveSteam_Client_ConnectToSteamServer{0x4D6980}; @@ -75,5 +77,4 @@ WEAK symbol g_wv_hWnd{0x5A86AF0}; WEAK symbol s_wcd_hWnd{0x5A86330}; WEAK symbol serverId{0xFF5058}; WEAK symbol connectionState{0x1060214}; -WEAK symbol cl_paused{0x1CE6190}; } // namespace game diff --git a/src/loader/component_interface.hpp b/src/client/loader/component_interface.hpp similarity index 100% rename from src/loader/component_interface.hpp rename to src/client/loader/component_interface.hpp diff --git a/src/loader/component_loader.cpp b/src/client/loader/component_loader.cpp similarity index 98% rename from src/loader/component_loader.cpp rename to src/client/loader/component_loader.cpp index c6e3f18..aed344c 100644 --- a/src/loader/component_loader.cpp +++ b/src/client/loader/component_loader.cpp @@ -1,4 +1,4 @@ -#include +#include #include "component_loader.hpp" void component_loader::register_component( diff --git a/src/loader/component_loader.hpp b/src/client/loader/component_loader.hpp similarity index 100% rename from src/loader/component_loader.hpp rename to src/client/loader/component_loader.hpp diff --git a/src/client/std_include.cpp b/src/client/std_include.cpp new file mode 100644 index 0000000..e912508 --- /dev/null +++ b/src/client/std_include.cpp @@ -0,0 +1 @@ +#include "std_include.hpp" diff --git a/src/stdinc.hpp b/src/client/std_include.hpp similarity index 94% rename from src/stdinc.hpp rename to src/client/std_include.hpp index bb3cf05..3a06720 100644 --- a/src/stdinc.hpp +++ b/src/client/std_include.hpp @@ -5,7 +5,7 @@ #define WIN32_LEAN_AND_MEAN #include -#include +#include #include #include diff --git a/src/utils/concurrency.hpp b/src/common/utils/concurrency.hpp similarity index 100% rename from src/utils/concurrency.hpp rename to src/common/utils/concurrency.hpp diff --git a/src/utils/hook.cpp b/src/common/utils/hook.cpp similarity index 99% rename from src/utils/hook.cpp rename to src/common/utils/hook.cpp index 6fbac56..fffaeeb 100644 --- a/src/utils/hook.cpp +++ b/src/common/utils/hook.cpp @@ -1,5 +1,3 @@ -#include - #include "hook.hpp" #include "string.hpp" diff --git a/src/utils/hook.hpp b/src/common/utils/hook.hpp similarity index 100% rename from src/utils/hook.hpp rename to src/common/utils/hook.hpp diff --git a/src/utils/info_string.cpp b/src/common/utils/info_string.cpp similarity index 84% rename from src/utils/info_string.cpp rename to src/common/utils/info_string.cpp index b82ad7a..4bddcbf 100644 --- a/src/utils/info_string.cpp +++ b/src/common/utils/info_string.cpp @@ -1,5 +1,3 @@ -#include - #include "info_string.hpp" #include "string.hpp" @@ -38,13 +36,12 @@ void info_string::parse(std::string buffer) { std::string info_string::build() const { std::string info_string; - for (auto i = this->key_value_pairs_.begin(); - i != this->key_value_pairs_.end(); ++i) { + for (const auto& [key, val] : this->key_value_pairs_) { info_string.append("\\"); - info_string.append(i->first); // Key + info_string.append(key); info_string.append("\\"); - info_string.append(i->second); // Value + info_string.append(val); } return info_string; diff --git a/src/utils/info_string.hpp b/src/common/utils/info_string.hpp similarity index 100% rename from src/utils/info_string.hpp rename to src/common/utils/info_string.hpp diff --git a/src/utils/memory.cpp b/src/common/utils/memory.cpp similarity index 96% rename from src/utils/memory.cpp rename to src/common/utils/memory.cpp index 2fabec9..2babefb 100644 --- a/src/utils/memory.cpp +++ b/src/common/utils/memory.cpp @@ -1,5 +1,3 @@ -#include - #include "memory.hpp" #include "nt.hpp" @@ -50,7 +48,7 @@ char* memory::allocator::duplicate_string(const std::string& string) { return data; } -void* memory::allocate(const size_t length) { return calloc(length, 1); } +void* memory::allocate(const size_t length) { return std::calloc(length, 1); } char* memory::duplicate_string(const std::string& string) { const auto new_string = allocate_array(string.size() + 1); @@ -60,7 +58,7 @@ char* memory::duplicate_string(const std::string& string) { void memory::free(void* data) { if (data) { - ::free(data); + std::free(data); } } diff --git a/src/utils/memory.hpp b/src/common/utils/memory.hpp similarity index 100% rename from src/utils/memory.hpp rename to src/common/utils/memory.hpp diff --git a/src/utils/nt.cpp b/src/common/utils/nt.cpp similarity index 99% rename from src/utils/nt.cpp rename to src/common/utils/nt.cpp index fa5af71..da93ba8 100644 --- a/src/utils/nt.cpp +++ b/src/common/utils/nt.cpp @@ -1,5 +1,3 @@ -#include - #include "nt.hpp" namespace utils::nt { diff --git a/src/utils/nt.hpp b/src/common/utils/nt.hpp similarity index 100% rename from src/utils/nt.hpp rename to src/common/utils/nt.hpp diff --git a/src/utils/signature.cpp b/src/common/utils/signature.cpp similarity index 99% rename from src/utils/signature.cpp rename to src/common/utils/signature.cpp index 18b736e..601a723 100644 --- a/src/utils/signature.cpp +++ b/src/common/utils/signature.cpp @@ -1,7 +1,6 @@ -#include - #include "signature.hpp" #include +#include #include diff --git a/src/utils/signature.hpp b/src/common/utils/signature.hpp similarity index 100% rename from src/utils/signature.hpp rename to src/common/utils/signature.hpp diff --git a/src/utils/string.cpp b/src/common/utils/string.cpp similarity index 99% rename from src/utils/string.cpp rename to src/common/utils/string.cpp index 73fe42d..80e4610 100644 --- a/src/utils/string.cpp +++ b/src/common/utils/string.cpp @@ -1,9 +1,7 @@ -#include - #include "string.hpp" -#include -#include #include +#include +#include #include "nt.hpp" diff --git a/src/utils/string.hpp b/src/common/utils/string.hpp similarity index 92% rename from src/utils/string.hpp rename to src/common/utils/string.hpp index a113f2d..00426c3 100644 --- a/src/utils/string.hpp +++ b/src/common/utils/string.hpp @@ -1,6 +1,10 @@ #pragma once #include "memory.hpp" +#ifndef ARRAYSIZE +template size_t ARRAYSIZE(Type (&)[n]) { return n; } +#endif + namespace utils::string { template class va_provider final { public: @@ -19,7 +23,7 @@ public: while (true) { const int res = - vsnprintf_s(entry->buffer, entry->size, _TRUNCATE, format, ap); + _vsnprintf_s(entry->buffer, entry->size, _TRUNCATE, format, ap); if (res > 0) break; // Success if (res == 0) diff --git a/src/common/utils/thread.cpp b/src/common/utils/thread.cpp new file mode 100644 index 0000000..7d778ed --- /dev/null +++ b/src/common/utils/thread.cpp @@ -0,0 +1,105 @@ +#include +#include "nt.hpp" +#include "string.hpp" + +#include "thread.hpp" + +#include + +#include + +namespace utils::thread { +bool set_name(const HANDLE t, const std::string& name) { + const nt::library kernel32("kernel32.dll"); + if (!kernel32) { + return false; + } + + const auto set_description = + kernel32.get_proc( + "SetThreadDescription"); + if (!set_description) { + return false; + } + + return SUCCEEDED(set_description(t, string::convert(name).data())); +} + +bool set_name(const DWORD id, const std::string& name) { + auto* const t = OpenThread(THREAD_SET_LIMITED_INFORMATION, FALSE, id); + if (!t) + return false; + + const auto _ = gsl::finally([t]() { CloseHandle(t); }); + + return set_name(t, name); +} + +bool set_name(std::thread& t, const std::string& name) { + return set_name(t.native_handle(), name); +} + +bool set_name(const std::string& name) { + return set_name(GetCurrentThread(), name); +} + +std::vector get_thread_ids() { + auto* const h = + CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, GetCurrentProcessId()); + if (h == INVALID_HANDLE_VALUE) { + return {}; + } + + const auto _ = gsl::finally([h]() { CloseHandle(h); }); + + THREADENTRY32 entry{}; + entry.dwSize = sizeof(entry); + if (!Thread32First(h, &entry)) { + return {}; + } + + std::vector ids; + + do { + const auto check_size = + entry.dwSize < FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + + sizeof(entry.th32OwnerProcessID); + entry.dwSize = sizeof(entry); + + if (check_size && entry.th32OwnerProcessID == GetCurrentProcessId()) { + ids.emplace_back(entry.th32ThreadID); + } + } while (Thread32Next(h, &entry)); + + return ids; +} + +void for_each_thread(const std::function& callback) { + const auto ids = get_thread_ids(); + + for (const auto& id : ids) { + auto* const thread = OpenThread(THREAD_ALL_ACCESS, FALSE, id); + if (thread != nullptr) { + const auto _ = gsl::finally([thread]() { CloseHandle(thread); }); + + callback(thread); + } + } +} + +void suspend_other_threads() { + for_each_thread([](const HANDLE thread) { + if (GetThreadId(thread) != GetCurrentThreadId()) { + SuspendThread(thread); + } + }); +} + +void resume_other_threads() { + for_each_thread([](const HANDLE thread) { + if (GetThreadId(thread) != GetCurrentThreadId()) { + ResumeThread(thread); + } + }); +} +} // namespace utils::thread diff --git a/src/common/utils/thread.hpp b/src/common/utils/thread.hpp new file mode 100644 index 0000000..b9ee875 --- /dev/null +++ b/src/common/utils/thread.hpp @@ -0,0 +1,21 @@ +#pragma once + +namespace utils::thread { +bool set_name(HANDLE t, const std::string& name); +bool set_name(DWORD id, const std::string& name); +bool set_name(std::thread& t, const std::string& name); +bool set_name(const std::string& name); + +template +std::thread create_named_thread(const std::string& name, Args&&... args) { + auto t = std::thread(std::forward(args)...); + set_name(t, name); + return t; +} + +std::vector get_thread_ids(); +void for_each_thread(const std::function& callback); + +void suspend_other_threads(); +void resume_other_threads(); +} // namespace utils::thread diff --git a/src/component/remove_hooks.cpp b/src/component/remove_hooks.cpp deleted file mode 100644 index 74be176..0000000 --- a/src/component/remove_hooks.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include - -#include - -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); - - 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/user_info.cpp b/src/component/user_info.cpp deleted file mode 100644 index bb15de8..0000000 --- a/src/component/user_info.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include - -#include - -#include -#include -#include - -#include "scheduler.hpp" - -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[32]; - - const auto numbers = std::to_string(std::rand() % 10000); - _snprintf_s(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 - push esi - call cl_check_user_info - add esp, 8 - - popad - ret - } -} -} // namespace - -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); - } -}; -} // namespace user_info - -REGISTER_COMPONENT(user_info::component) diff --git a/src/game/game.cpp b/src/game/game.cpp deleted file mode 100644 index 7080bae..0000000 --- a/src/game/game.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include - -namespace game {} diff --git a/src/stdinc.cpp b/src/stdinc.cpp deleted file mode 100644 index c4d450f..0000000 --- a/src/stdinc.cpp +++ /dev/null @@ -1 +0,0 @@ -#include