diff --git a/src/Components/Modules/AntiCheat.cpp b/src/Components/Modules/AntiCheat.cpp index 697912ac..8aacbd97 100644 --- a/src/Components/Modules/AntiCheat.cpp +++ b/src/Components/Modules/AntiCheat.cpp @@ -9,7 +9,7 @@ namespace Components // This function does nothing, it only adds the two passed variables and returns the value // The only important thing it does is to clean the first parameter, and then return // By returning, the crash procedure will be called, as it hasn't been cleaned from the stack - void __declspec(naked) AntiCheat::NullSub() + __declspec(naked) void AntiCheat::NullSub() { __asm { @@ -28,7 +28,8 @@ namespace Components } } - void __declspec(naked) AntiCheat::CrashClient() +#if 0 + __declspec(naked) void AntiCheat::CrashClient() { static uint8_t crashProcedure[] = { @@ -83,26 +84,20 @@ namespace Components jmp AntiCheat::NullSub } } +#endif - void AntiCheat::AssertLibraryCall(void* callee) + void AntiCheat::CrashClient() { - HMODULE hModuleSelf = nullptr; - GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast(AntiCheat::AssertLibraryCall), &hModuleSelf); - - AntiCheat::AssertModuleCall(hModuleSelf, callee); + Utils::Hook::Set(0x41BA2C, 0xEB); } - void AntiCheat::AssertProcessCall(void* callee) + void AntiCheat::AssertCalleeModule(void* callee) { - AntiCheat::AssertModuleCall(GetModuleHandle(NULL), callee); - } - - void AntiCheat::AssertModuleCall(HMODULE module, void* callee) - { - HMODULE hModuleTarget = nullptr; + HMODULE hModuleSelf = nullptr, hModuleTarget = nullptr, hModuleProcess = GetModuleHandleA(NULL); GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast(callee), &hModuleTarget); + GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast(AntiCheat::AssertCalleeModule), &hModuleSelf); - if (!module || !hModuleTarget || module != hModuleTarget) + if (!hModuleSelf || !hModuleTarget || !hModuleProcess || (hModuleTarget != hModuleSelf &&hModuleTarget != hModuleProcess)) { //AntiCheat::CrashClient(); AntiCheat::Hash.append("\0", 1); @@ -110,12 +105,12 @@ namespace Components } // This has to be called when doing .text changes during runtime - void AntiCheat::EmptyHash() + __declspec(noinline) void AntiCheat::EmptyHash() { AntiCheat::LastCheck = 0; AntiCheat::Hash.clear(); - AntiCheat::AssertLibraryCall(_ReturnAddress()); + AntiCheat::AssertCalleeModule(_ReturnAddress()); } void AntiCheat::InitLoadLibHook() @@ -255,7 +250,7 @@ namespace Components AntiCheat::InstallLibHook(); } - void __declspec(naked) AntiCheat::CinematicStub() + __declspec(naked) void AntiCheat::CinematicStub() { __asm { @@ -273,14 +268,34 @@ namespace Components } } - void __declspec(naked) AntiCheat::AimTargetGetTagPosStub() + __declspec(naked) void AntiCheat::DObjGetWorldTagPosStub() + { + __asm + { + pushad + push[esp + 20h] + + call AntiCheat::AssertCalleeModule + + pop esi + popad + + push ecx + mov ecx, [esp + 10h] + + push 426585h + retn + } + } + + __declspec(naked) void AntiCheat::AimTargetGetTagPosStub() { __asm { pushad push [esp + 20h] - call AntiCheat::AssertProcessCall + call AntiCheat::AssertCalleeModule pop esi popad @@ -311,8 +326,9 @@ namespace Components Utils::Hook(0x418204, AntiCheat::SoundInitDriverStub, HOOK_CALL).Install()->Quick(); QuickPatch::OnFrame(AntiCheat::Frame); - // Check AimTarget_GetTagPos - //Utils::Hook(0x56AC60, AntiCheat::AimTargetGetTagPosStub, HOOK_JUMP).Install()->Quick(); + // Detect aimbots + Utils::Hook(0x426580, AntiCheat::DObjGetWorldTagPosStub, HOOK_JUMP).Install()->Quick(); + Utils::Hook(0x56AC60, AntiCheat::AimTargetGetTagPosStub, HOOK_JUMP).Install()->Quick(); // TODO: Probably move that :P AntiCheat::InitLoadLibHook(); diff --git a/src/Components/Modules/AntiCheat.hpp b/src/Components/Modules/AntiCheat.hpp index cfa8469d..f9ed2e94 100644 --- a/src/Components/Modules/AntiCheat.hpp +++ b/src/Components/Modules/AntiCheat.hpp @@ -27,9 +27,7 @@ namespace Components static void NullSub(); - static void AssertLibraryCall(void* callee); - static void AssertProcessCall(void* callee); - static void AssertModuleCall(HMODULE module, void* callee); + static void AssertCalleeModule(void* callee); static void UninstallLibHook(); static void InstallLibHook(); @@ -44,6 +42,7 @@ namespace Components static void SoundInitStub(int a1, int a2, int a3); static void SoundInitDriverStub(); + static void DObjGetWorldTagPosStub(); static void AimTargetGetTagPosStub(); static Utils::Hook LoadLibHook[4]; diff --git a/src/Components/Modules/AssetHandler.cpp b/src/Components/Modules/AssetHandler.cpp index ea593182..753560a2 100644 --- a/src/Components/Modules/AssetHandler.cpp +++ b/src/Components/Modules/AssetHandler.cpp @@ -64,7 +64,7 @@ namespace Components return header; } - void __declspec(naked) AssetHandler::FindAssetStub() + __declspec(naked) void AssetHandler::FindAssetStub() { __asm { @@ -122,7 +122,7 @@ namespace Components return (!restrict); } - void __declspec(naked) AssetHandler::AddAssetStub() + __declspec(naked) void AssetHandler::AddAssetStub() { __asm { diff --git a/src/Components/Modules/Auth.cpp b/src/Components/Modules/Auth.cpp index 628238c4..0da1a830 100644 --- a/src/Components/Modules/Auth.cpp +++ b/src/Components/Modules/Auth.cpp @@ -152,7 +152,7 @@ namespace Components } } - void __declspec(naked) Auth::DirectConnectStub() + __declspec(naked) void Auth::DirectConnectStub() { __asm { diff --git a/src/Components/Modules/Colors.cpp b/src/Components/Modules/Colors.cpp index d7b61033..3987707a 100644 --- a/src/Components/Modules/Colors.cpp +++ b/src/Components/Modules/Colors.cpp @@ -86,7 +86,7 @@ namespace Components return std::string(buffer); } - void __declspec(naked) Colors::ClientUserinfoChanged() + __declspec(naked) void Colors::ClientUserinfoChanged() { __asm { @@ -190,7 +190,7 @@ namespace Components return string; } - void __declspec(naked) Colors::LookupColorStub() + __declspec(naked) void Colors::LookupColorStub() { __asm { diff --git a/src/Components/Modules/Console.cpp b/src/Components/Modules/Console.cpp index c88bfd53..f50d3f1e 100644 --- a/src/Components/Modules/Console.cpp +++ b/src/Components/Modules/Console.cpp @@ -433,7 +433,7 @@ namespace Components ExitProcess(1); } - void __declspec(naked) Console::DrawSolidConsoleStub() + __declspec(naked) void Console::DrawSolidConsoleStub() { __asm { diff --git a/src/Components/Modules/Dedicated.cpp b/src/Components/Modules/Dedicated.cpp index d57d86c9..329e13d3 100644 --- a/src/Components/Modules/Dedicated.cpp +++ b/src/Components/Modules/Dedicated.cpp @@ -48,7 +48,7 @@ namespace Components Utils::Hook::Call(0x60C3D0)(); } - void __declspec(naked) Dedicated::PostInitializationStub() + __declspec(naked) void Dedicated::PostInitializationStub() { __asm { @@ -74,7 +74,7 @@ namespace Components return text; } - void __declspec(naked) Dedicated::PreSayStub() + __declspec(naked) void Dedicated::PreSayStub() { __asm { @@ -90,7 +90,7 @@ namespace Components } } - void __declspec(naked) Dedicated::PostSayStub() + __declspec(naked) void Dedicated::PostSayStub() { __asm { diff --git a/src/Components/Modules/FileSystem.cpp b/src/Components/Modules/FileSystem.cpp index c1879f00..f67126bb 100644 --- a/src/Components/Modules/FileSystem.cpp +++ b/src/Components/Modules/FileSystem.cpp @@ -113,7 +113,7 @@ namespace Components FileSystem::RegisterFolder("userraw"); } - void __declspec(naked) FileSystem::StartupStub() + __declspec(naked) void FileSystem::StartupStub() { __asm { diff --git a/src/Components/Modules/Logger.cpp b/src/Components/Modules/Logger.cpp index 7a9f61a5..d72c34ab 100644 --- a/src/Components/Modules/Logger.cpp +++ b/src/Components/Modules/Logger.cpp @@ -108,7 +108,7 @@ namespace Components } } - void __declspec(naked) Logger::PrintMessageStub() + __declspec(naked) void Logger::PrintMessageStub() { __asm { diff --git a/src/Components/Modules/Materials.cpp b/src/Components/Modules/Materials.cpp index f4650c8f..dd9ca412 100644 --- a/src/Components/Modules/Materials.cpp +++ b/src/Components/Modules/Materials.cpp @@ -1,59 +1,59 @@ -#include "STDInclude.hpp" - -namespace Components -{ - Utils::Hook Materials::ImageVersionCheckHook; - - void __declspec(naked) Materials::ImageVersionCheck() - { - __asm - { - cmp eax, 9 - je returnSafely - - jmp Materials::ImageVersionCheckHook.Original - - returnSafely: - mov al, 1 - add esp, 18h - retn - } - } - - Game::Material* Materials::VerifyMaterial(Game::Material* material) - { - if (!IsBadReadPtr(material, 4) && !IsBadReadPtr(material->name, 1)) - { - return material; - } - - return Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, "default").material; - } - - void __declspec(naked) Materials::DrawMaterialStub() - { - __asm - { - push eax - call Materials::VerifyMaterial - add esp, 4h - - mov edx, 5310F0h - jmp edx - } - } - - Materials::Materials() - { - // Allow codo images - Materials::ImageVersionCheckHook.Initialize(0x53A456, Materials::ImageVersionCheck, HOOK_CALL)->Install(); - - // Fix material pointer exploit - Utils::Hook(0x534E0C, Materials::DrawMaterialStub, HOOK_CALL).Install()->Quick(); - } - - Materials::~Materials() - { - Materials::ImageVersionCheckHook.Uninstall(); - } -} +#include "STDInclude.hpp" + +namespace Components +{ + Utils::Hook Materials::ImageVersionCheckHook; + + __declspec(naked) void Materials::ImageVersionCheck() + { + __asm + { + cmp eax, 9 + je returnSafely + + jmp Materials::ImageVersionCheckHook.Original + + returnSafely: + mov al, 1 + add esp, 18h + retn + } + } + + Game::Material* Materials::VerifyMaterial(Game::Material* material) + { + if (!IsBadReadPtr(material, 4) && !IsBadReadPtr(material->name, 1)) + { + return material; + } + + return Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, "default").material; + } + + __declspec(naked) void Materials::DrawMaterialStub() + { + __asm + { + push eax + call Materials::VerifyMaterial + add esp, 4h + + mov edx, 5310F0h + jmp edx + } + } + + Materials::Materials() + { + // Allow codo images + Materials::ImageVersionCheckHook.Initialize(0x53A456, Materials::ImageVersionCheck, HOOK_CALL)->Install(); + + // Fix material pointer exploit + Utils::Hook(0x534E0C, Materials::DrawMaterialStub, HOOK_CALL).Install()->Quick(); + } + + Materials::~Materials() + { + Materials::ImageVersionCheckHook.Uninstall(); + } +} diff --git a/src/Components/Modules/Network.cpp b/src/Components/Modules/Network.cpp index 8ec561ab..6b298c52 100644 --- a/src/Components/Modules/Network.cpp +++ b/src/Components/Modules/Network.cpp @@ -278,7 +278,7 @@ namespace Components Network::StartupSignal(); } - void __declspec(naked) Network::NetworkStartStub() + __declspec(naked) void Network::NetworkStartStub() { __asm { @@ -288,7 +288,7 @@ namespace Components } } - void __declspec(naked) Network::DeployPacketStub() + __declspec(naked) void Network::DeployPacketStub() { __asm { diff --git a/src/Components/Modules/Renderer.cpp b/src/Components/Modules/Renderer.cpp index ea5cdc00..28439c72 100644 --- a/src/Components/Modules/Renderer.cpp +++ b/src/Components/Modules/Renderer.cpp @@ -7,7 +7,7 @@ namespace Components wink::signal> Renderer::FrameOnceSignal; wink::signal> Renderer::BackendFrameSignal; - void __declspec(naked) Renderer::FrameStub() + __declspec(naked) void Renderer::FrameStub() { __asm { @@ -23,7 +23,7 @@ namespace Components Renderer::FrameOnceSignal.clear(); } - void __declspec(naked) Renderer::BackendFrameStub() + __declspec(naked) void Renderer::BackendFrameStub() { __asm { diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index 8550c0de..151e5732 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -21,7 +21,7 @@ namespace Components Logger::Error(5, "script compile error\nunknown function %s\n%s\n\n", funcName.data(), Script::ScriptName.data()); } - void __declspec(naked) Script::StoreFunctionNameStub() + __declspec(naked) void Script::StoreFunctionNameStub() { __asm { @@ -48,7 +48,7 @@ namespace Components } } - void __declspec(naked) Script::StoreScriptNameStub() + __declspec(naked) void Script::StoreScriptNameStub() { __asm { @@ -71,7 +71,7 @@ namespace Components Script::ScriptNameStack.pop_back(); } - void __declspec(naked) Script::RestoreScriptNameStub() + __declspec(naked) void Script::RestoreScriptNameStub() { __asm { diff --git a/src/Components/Modules/ServerInfo.cpp b/src/Components/Modules/ServerInfo.cpp index c91e7b80..1ee3a8de 100644 --- a/src/Components/Modules/ServerInfo.cpp +++ b/src/Components/Modules/ServerInfo.cpp @@ -88,7 +88,7 @@ namespace Components Game::UI_DrawText(cxt, addressText.data(), 0x7FFFFFFF, font, x2 - Game::UI_TextWidth(addressText.data(), 0, font, fontSize), y, 0, 0, fontSize, reinterpret_cast(0x747F34), 3); } - void __declspec(naked) ServerInfo::DrawScoreboardStub() + __declspec(naked) void ServerInfo::DrawScoreboardStub() { __asm { diff --git a/src/Components/Modules/Theatre.cpp b/src/Components/Modules/Theatre.cpp index 1dca1c48..3937bfa8 100644 --- a/src/Components/Modules/Theatre.cpp +++ b/src/Components/Modules/Theatre.cpp @@ -30,7 +30,7 @@ namespace Components std::memcpy(Theatre::BaselineSnapshot, *reinterpret_cast(snapshotMsg + 8), *reinterpret_cast(snapshotMsg + 20)); } - void __declspec(naked) Theatre::BaselineStoreStub() + __declspec(naked) void Theatre::BaselineStoreStub() { _asm { @@ -79,7 +79,7 @@ namespace Components } } - void __declspec(naked) Theatre::BaselineToFileStub() + __declspec(naked) void Theatre::BaselineToFileStub() { __asm { @@ -95,7 +95,7 @@ namespace Components } } - void __declspec(naked) Theatre::AdjustTimeDeltaStub() + __declspec(naked) void Theatre::AdjustTimeDeltaStub() { __asm { @@ -113,7 +113,7 @@ namespace Components } } - void __declspec(naked) Theatre::ServerTimedOutStub() + __declspec(naked) void Theatre::ServerTimedOutStub() { __asm { @@ -132,7 +132,7 @@ namespace Components } } - void __declspec(naked) Theatre::UISetActiveMenuStub() + __declspec(naked) void Theatre::UISetActiveMenuStub() { __asm { diff --git a/src/Components/Modules/UIFeeder.cpp b/src/Components/Modules/UIFeeder.cpp index 68cdd758..78be183f 100644 --- a/src/Components/Modules/UIFeeder.cpp +++ b/src/Components/Modules/UIFeeder.cpp @@ -1,285 +1,285 @@ -#include "STDInclude.hpp" - -namespace Components -{ - UIFeeder::Container UIFeeder::Current; - std::map UIFeeder::Feeders; - - void UIFeeder::Add(float feeder, UIFeeder::GetItemCount_t itemCountCb, UIFeeder::GetItemText_t itemTextCb, UIFeeder::Select_t selectCb) - { - UIFeeder::Feeders[feeder] = { itemCountCb, itemTextCb, selectCb }; - } - - const char* UIFeeder::GetItemText() - { - if (UIFeeder::Feeders.find(UIFeeder::Current.Feeder) != UIFeeder::Feeders.end()) - { - return UIFeeder::Feeders[UIFeeder::Current.Feeder].GetItemText(UIFeeder::Current.Index, UIFeeder::Current.Column); - } - - return nullptr; - } - - unsigned int UIFeeder::GetItemCount() - { - if (UIFeeder::Feeders.find(UIFeeder::Current.Feeder) != UIFeeder::Feeders.end()) - { - return UIFeeder::Feeders[UIFeeder::Current.Feeder].GetItemCount(); - } - - return 0; - } - - bool UIFeeder::SetItemSelection() - { - if (UIFeeder::Feeders.find(UIFeeder::Current.Feeder) != UIFeeder::Feeders.end()) - { - UIFeeder::Feeders[UIFeeder::Current.Feeder].Select(UIFeeder::Current.Index); - return true; - } - - return false; - } - - bool UIFeeder::CheckFeeder() - { - if (UIFeeder::Current.Feeder == 15.0f) return false; - return (UIFeeder::Feeders.find(UIFeeder::Current.Feeder) != UIFeeder::Feeders.end()); - } - - void __declspec(naked) UIFeeder::SetItemSelectionStub() - { - __asm - { - mov eax, [esp + 08h] - mov UIFeeder::Current.Feeder, eax - - mov eax, [esp + 0Ch] - mov UIFeeder::Current.Index, eax - - call UIFeeder::SetItemSelection - - test al, al - jz continue - - retn - - continue: - fld ds:739FD0h - - mov eax, 4C25D6h - jmp eax - } - } - - void __declspec(naked) UIFeeder::GetItemTextStub() - { - __asm - { - mov eax, [esp + 0Ch] - mov UIFeeder::Current.Feeder, eax - - mov eax, [esp + 10h] - mov UIFeeder::Current.Index, eax - - mov eax, [esp + 14h] - mov UIFeeder::Current.Column, eax - - call UIFeeder::GetItemText - - test eax, eax - jz continue - - push ebx - mov ebx, [esp + 4 + 28h] - mov dword ptr[ebx], 0 - pop ebx - retn - - continue: - push ecx - fld ds:739FD0h - - mov eax, 4CE9E7h - jmp eax - } - } - - void __declspec(naked) UIFeeder::GetItemCountStub() - { - __asm - { - mov eax, [esp + 8h] - mov UIFeeder::Current.Feeder, eax - - call UIFeeder::GetItemCount - - test eax, eax - jz continue - - retn - - continue: - push ecx - fld ds:739FD0h - - mov eax, 41A0D7h - jmp eax; - } - } - - void __declspec(naked) UIFeeder::HandleKeyStub() - { - static int NextClickTime = 0; - - __asm - { - mov ebx, ebp - mov eax, [ebp + 12Ch] - mov UIFeeder::Current.Feeder, eax - - push ebx - call UIFeeder::CheckFeeder - pop ebx - - test al, al - jz continueOriginal - - // Get current milliseconds - call Game::Sys_Milliseconds - - // Check if allowed to click - cmp eax, NextClickTime - jl continueOriginal - - // Set next allowed click time to current time + 300ms - add eax, 300 - mov NextClickTime, eax - - // Get item cursor position ptr - mov ecx, ebx - add ecx, Game::itemDef_t::cursorPos - - // Get item listbox ptr - mov edx, ebx - add edx, Game::itemDef_t::typeData - - // Get listbox cursor pos - mov edx, [edx] - add edx, Game::listBoxDef_s::startPos - mov edx, [edx] - - // Resolve item cursor pos pointer - mov ebx, [ecx] - - // Check if item cursor pos equals listbox cursor pos - cmp ebx, edx - je returnSafe - - // Update indices if not - mov [ecx], edx - mov UIFeeder::Current.Index, edx - - call UIFeeder::SetItemSelection - - returnSafe: - retn - - continueOriginal: - mov eax, 635570h - jmp eax - } - } - - void __declspec(naked) UIFeeder::MouseEnterStub() - { - __asm - { - mov eax, [edi + 12Ch] - mov UIFeeder::Current.Feeder, eax - - call UIFeeder::CheckFeeder - - test al, al - jnz continue - - mov[edi + 130h], esi - - continue: - mov eax, 639D75h - jmp eax - } - } - - void __declspec(naked) UIFeeder::MouseSelectStub() - { - __asm - { - mov eax, [esp + 08h] - mov UIFeeder::Current.Feeder, eax - - call UIFeeder::CheckFeeder - - test al, al - jnz continue - - mov eax, 4C25D0h - jmp eax - - continue: - retn - } - } - - void __declspec(naked) UIFeeder::PlaySoundStub() - { - __asm - { - mov eax, [edi + 12Ch] - mov UIFeeder::Current.Feeder, eax - - call UIFeeder::CheckFeeder - - test al, al - jnz continue - - mov eax, 685E10h - jmp eax - - continue: - retn - } - } - - UIFeeder::UIFeeder() - { - // Get feeder item count - Utils::Hook(0x41A0D0, UIFeeder::GetItemCountStub, HOOK_JUMP).Install()->Quick(); - - // Get feeder item text - Utils::Hook(0x4CE9E0, UIFeeder::GetItemTextStub, HOOK_JUMP).Install()->Quick(); - - // Select feeder item - Utils::Hook(0x4C25D0, UIFeeder::SetItemSelectionStub, HOOK_JUMP).Install()->Quick(); - - // Mouse enter check - Utils::Hook(0x639D6E, UIFeeder::MouseEnterStub, HOOK_JUMP).Install()->Quick(); - - // Handle key event - Utils::Hook(0x63C5BC, UIFeeder::HandleKeyStub, HOOK_CALL).Install()->Quick(); - - // Mouse select check - Utils::Hook(0x639D31, UIFeeder::MouseSelectStub, HOOK_CALL).Install()->Quick(); - - // Play mouse over sound check - Utils::Hook(0x639D66, UIFeeder::PlaySoundStub, HOOK_CALL).Install()->Quick(); - - // some thing overwriting feeder 2's data - Utils::Hook::Set(0x4A06A9, 0xEB); - } - - UIFeeder::~UIFeeder() - { - UIFeeder::Feeders.clear(); - } -} +#include "STDInclude.hpp" + +namespace Components +{ + UIFeeder::Container UIFeeder::Current; + std::map UIFeeder::Feeders; + + void UIFeeder::Add(float feeder, UIFeeder::GetItemCount_t itemCountCb, UIFeeder::GetItemText_t itemTextCb, UIFeeder::Select_t selectCb) + { + UIFeeder::Feeders[feeder] = { itemCountCb, itemTextCb, selectCb }; + } + + const char* UIFeeder::GetItemText() + { + if (UIFeeder::Feeders.find(UIFeeder::Current.Feeder) != UIFeeder::Feeders.end()) + { + return UIFeeder::Feeders[UIFeeder::Current.Feeder].GetItemText(UIFeeder::Current.Index, UIFeeder::Current.Column); + } + + return nullptr; + } + + unsigned int UIFeeder::GetItemCount() + { + if (UIFeeder::Feeders.find(UIFeeder::Current.Feeder) != UIFeeder::Feeders.end()) + { + return UIFeeder::Feeders[UIFeeder::Current.Feeder].GetItemCount(); + } + + return 0; + } + + bool UIFeeder::SetItemSelection() + { + if (UIFeeder::Feeders.find(UIFeeder::Current.Feeder) != UIFeeder::Feeders.end()) + { + UIFeeder::Feeders[UIFeeder::Current.Feeder].Select(UIFeeder::Current.Index); + return true; + } + + return false; + } + + bool UIFeeder::CheckFeeder() + { + if (UIFeeder::Current.Feeder == 15.0f) return false; + return (UIFeeder::Feeders.find(UIFeeder::Current.Feeder) != UIFeeder::Feeders.end()); + } + + __declspec(naked) void UIFeeder::SetItemSelectionStub() + { + __asm + { + mov eax, [esp + 08h] + mov UIFeeder::Current.Feeder, eax + + mov eax, [esp + 0Ch] + mov UIFeeder::Current.Index, eax + + call UIFeeder::SetItemSelection + + test al, al + jz continue + + retn + + continue: + fld ds:739FD0h + + mov eax, 4C25D6h + jmp eax + } + } + + __declspec(naked) void UIFeeder::GetItemTextStub() + { + __asm + { + mov eax, [esp + 0Ch] + mov UIFeeder::Current.Feeder, eax + + mov eax, [esp + 10h] + mov UIFeeder::Current.Index, eax + + mov eax, [esp + 14h] + mov UIFeeder::Current.Column, eax + + call UIFeeder::GetItemText + + test eax, eax + jz continue + + push ebx + mov ebx, [esp + 4 + 28h] + mov dword ptr[ebx], 0 + pop ebx + retn + + continue: + push ecx + fld ds:739FD0h + + mov eax, 4CE9E7h + jmp eax + } + } + + __declspec(naked) void UIFeeder::GetItemCountStub() + { + __asm + { + mov eax, [esp + 8h] + mov UIFeeder::Current.Feeder, eax + + call UIFeeder::GetItemCount + + test eax, eax + jz continue + + retn + + continue: + push ecx + fld ds:739FD0h + + mov eax, 41A0D7h + jmp eax; + } + } + + __declspec(naked) void UIFeeder::HandleKeyStub() + { + static int NextClickTime = 0; + + __asm + { + mov ebx, ebp + mov eax, [ebp + 12Ch] + mov UIFeeder::Current.Feeder, eax + + push ebx + call UIFeeder::CheckFeeder + pop ebx + + test al, al + jz continueOriginal + + // Get current milliseconds + call Game::Sys_Milliseconds + + // Check if allowed to click + cmp eax, NextClickTime + jl continueOriginal + + // Set next allowed click time to current time + 300ms + add eax, 300 + mov NextClickTime, eax + + // Get item cursor position ptr + mov ecx, ebx + add ecx, Game::itemDef_t::cursorPos + + // Get item listbox ptr + mov edx, ebx + add edx, Game::itemDef_t::typeData + + // Get listbox cursor pos + mov edx, [edx] + add edx, Game::listBoxDef_s::startPos + mov edx, [edx] + + // Resolve item cursor pos pointer + mov ebx, [ecx] + + // Check if item cursor pos equals listbox cursor pos + cmp ebx, edx + je returnSafe + + // Update indices if not + mov [ecx], edx + mov UIFeeder::Current.Index, edx + + call UIFeeder::SetItemSelection + + returnSafe: + retn + + continueOriginal: + mov eax, 635570h + jmp eax + } + } + + __declspec(naked) void UIFeeder::MouseEnterStub() + { + __asm + { + mov eax, [edi + 12Ch] + mov UIFeeder::Current.Feeder, eax + + call UIFeeder::CheckFeeder + + test al, al + jnz continue + + mov[edi + 130h], esi + + continue: + mov eax, 639D75h + jmp eax + } + } + + __declspec(naked) void UIFeeder::MouseSelectStub() + { + __asm + { + mov eax, [esp + 08h] + mov UIFeeder::Current.Feeder, eax + + call UIFeeder::CheckFeeder + + test al, al + jnz continue + + mov eax, 4C25D0h + jmp eax + + continue: + retn + } + } + + __declspec(naked) void UIFeeder::PlaySoundStub() + { + __asm + { + mov eax, [edi + 12Ch] + mov UIFeeder::Current.Feeder, eax + + call UIFeeder::CheckFeeder + + test al, al + jnz continue + + mov eax, 685E10h + jmp eax + + continue: + retn + } + } + + UIFeeder::UIFeeder() + { + // Get feeder item count + Utils::Hook(0x41A0D0, UIFeeder::GetItemCountStub, HOOK_JUMP).Install()->Quick(); + + // Get feeder item text + Utils::Hook(0x4CE9E0, UIFeeder::GetItemTextStub, HOOK_JUMP).Install()->Quick(); + + // Select feeder item + Utils::Hook(0x4C25D0, UIFeeder::SetItemSelectionStub, HOOK_JUMP).Install()->Quick(); + + // Mouse enter check + Utils::Hook(0x639D6E, UIFeeder::MouseEnterStub, HOOK_JUMP).Install()->Quick(); + + // Handle key event + Utils::Hook(0x63C5BC, UIFeeder::HandleKeyStub, HOOK_CALL).Install()->Quick(); + + // Mouse select check + Utils::Hook(0x639D31, UIFeeder::MouseSelectStub, HOOK_CALL).Install()->Quick(); + + // Play mouse over sound check + Utils::Hook(0x639D66, UIFeeder::PlaySoundStub, HOOK_CALL).Install()->Quick(); + + // some thing overwriting feeder 2's data + Utils::Hook::Set(0x4A06A9, 0xEB); + } + + UIFeeder::~UIFeeder() + { + UIFeeder::Feeders.clear(); + } +} diff --git a/src/Components/Modules/UIScript.cpp b/src/Components/Modules/UIScript.cpp index b5c1d3d1..00ee9ee4 100644 --- a/src/Components/Modules/UIScript.cpp +++ b/src/Components/Modules/UIScript.cpp @@ -1,136 +1,136 @@ -#include "STDInclude.hpp" - -namespace Components -{ - std::map> UIScript::UIScripts; - std::map> UIScript::UIOwnerDraws; - - template<> int UIScript::Token::Get() - { - if (this->IsValid()) - { - return atoi(this->token); - } - - return 0; - } - - template<> char* UIScript::Token::Get() - { - if (this->IsValid()) - { - return this->token; - } - - return ""; - } - - template<> const char* UIScript::Token::Get() - { - return this->Get(); - } - - template<> std::string UIScript::Token::Get() - { - return this->Get(); - } - - bool UIScript::Token::IsValid() - { - return (token && token[0]); - } - - void UIScript::Token::Parse(const char** args) - { - if (args) - { - this->token = Game::Com_ParseExt(args); - } - } - - void UIScript::Add(std::string name, UIScript::Callback* callback) - { - UIScript::UIScripts[name] = callback; - } - - void UIScript::Add(std::string name, UIScript::CallbackRaw* callback) - { - UIScript::Add(name, reinterpret_cast(callback)); - } - - void UIScript::AddOwnerDraw(int ownerdraw, UIScript::CallbackRaw* callback) - { - UIScript::UIOwnerDraws[ownerdraw] = callback; - } - - bool UIScript::RunMenuScript(const char* name, const char** args) - { - if (UIScript::UIScripts.find(name) != UIScript::UIScripts.end()) - { - UIScript::UIScripts[name](UIScript::Token(args)); - return true; - } - - return false; - } - - void UIScript::OwnerDrawHandleKeyStub(int ownerDraw, int flags, float *special, int key) - { - if (key == 200 || key == 201) //mouse buttons - { - for (auto i = UIScript::UIOwnerDraws.begin(); i != UIScript::UIOwnerDraws.end(); ++i) - { - if (i->first == ownerDraw) - { - i->second(); - } - } - } - - Utils::Hook::Call(0x4F58A0)(ownerDraw, flags, special, key); - } - - void __declspec(naked) UIScript::RunMenuScriptStub() - { - __asm - { - mov eax, esp - add eax, 8h - mov edx, eax // UIScript name - mov eax, [esp + 0C10h] // UIScript args - - push eax - push edx - call UIScript::RunMenuScript - add esp, 8h - - test al, al - jz continue - - // if returned - pop edi - pop esi - add esp, 0C00h - retn - - continue: - mov eax, 45ED00h - jmp eax - } - } - - UIScript::UIScript() - { - // Install handler - Utils::Hook::RedirectJump(0x45EC59, UIScript::RunMenuScriptStub); - - // Install ownerdraw handler - Utils::Hook(0x63D233, UIScript::OwnerDrawHandleKeyStub, HOOK_CALL).Install()->Quick(); - } - - UIScript::~UIScript() - { - UIScript::UIScripts.clear(); - UIScript::UIOwnerDraws.clear(); - } -} +#include "STDInclude.hpp" + +namespace Components +{ + std::map> UIScript::UIScripts; + std::map> UIScript::UIOwnerDraws; + + template<> int UIScript::Token::Get() + { + if (this->IsValid()) + { + return atoi(this->token); + } + + return 0; + } + + template<> char* UIScript::Token::Get() + { + if (this->IsValid()) + { + return this->token; + } + + return ""; + } + + template<> const char* UIScript::Token::Get() + { + return this->Get(); + } + + template<> std::string UIScript::Token::Get() + { + return this->Get(); + } + + bool UIScript::Token::IsValid() + { + return (token && token[0]); + } + + void UIScript::Token::Parse(const char** args) + { + if (args) + { + this->token = Game::Com_ParseExt(args); + } + } + + void UIScript::Add(std::string name, UIScript::Callback* callback) + { + UIScript::UIScripts[name] = callback; + } + + void UIScript::Add(std::string name, UIScript::CallbackRaw* callback) + { + UIScript::Add(name, reinterpret_cast(callback)); + } + + void UIScript::AddOwnerDraw(int ownerdraw, UIScript::CallbackRaw* callback) + { + UIScript::UIOwnerDraws[ownerdraw] = callback; + } + + bool UIScript::RunMenuScript(const char* name, const char** args) + { + if (UIScript::UIScripts.find(name) != UIScript::UIScripts.end()) + { + UIScript::UIScripts[name](UIScript::Token(args)); + return true; + } + + return false; + } + + void UIScript::OwnerDrawHandleKeyStub(int ownerDraw, int flags, float *special, int key) + { + if (key == 200 || key == 201) //mouse buttons + { + for (auto i = UIScript::UIOwnerDraws.begin(); i != UIScript::UIOwnerDraws.end(); ++i) + { + if (i->first == ownerDraw) + { + i->second(); + } + } + } + + Utils::Hook::Call(0x4F58A0)(ownerDraw, flags, special, key); + } + + __declspec(naked) void UIScript::RunMenuScriptStub() + { + __asm + { + mov eax, esp + add eax, 8h + mov edx, eax // UIScript name + mov eax, [esp + 0C10h] // UIScript args + + push eax + push edx + call UIScript::RunMenuScript + add esp, 8h + + test al, al + jz continue + + // if returned + pop edi + pop esi + add esp, 0C00h + retn + + continue: + mov eax, 45ED00h + jmp eax + } + } + + UIScript::UIScript() + { + // Install handler + Utils::Hook::RedirectJump(0x45EC59, UIScript::RunMenuScriptStub); + + // Install ownerdraw handler + Utils::Hook(0x63D233, UIScript::OwnerDrawHandleKeyStub, HOOK_CALL).Install()->Quick(); + } + + UIScript::~UIScript() + { + UIScript::UIScripts.clear(); + UIScript::UIOwnerDraws.clear(); + } +} diff --git a/src/Components/Modules/Window.cpp b/src/Components/Modules/Window.cpp index ea6083ff..e1f30658 100644 --- a/src/Components/Modules/Window.cpp +++ b/src/Components/Modules/Window.cpp @@ -1,165 +1,165 @@ -#include "STDInclude.hpp" - -namespace Components -{ - Dvar::Var Window::NoBorder; - Dvar::Var Window::NativeCursor; - - HWND Window::MainWindow = 0; - BOOL Window::CursorVisible = TRUE; - - int Window::Width() - { - return Window::Width(Window::MainWindow); - } - - int Window::Height() - { - return Window::Height(Window::MainWindow); - } - - int Window::Width(HWND window) - { - RECT rect; - Window::Dimension(window, &rect); - return (rect.right - rect.left); - } - - int Window::Height(HWND window) - { - RECT rect; - Window::Dimension(window, &rect); - return (rect.bottom - rect.top); - } - - void Window::Dimension(RECT* rect) - { - Window::Dimension(Window::MainWindow, rect); - } - - void Window::Dimension(HWND window, RECT* rect) - { - if (rect) - { - ZeroMemory(rect, sizeof(RECT)); - - if (window && IsWindow(window)) - { - GetWindowRect(window, rect); - } - } - } - - bool Window::IsCursorWithin(HWND window) - { - RECT rect; - POINT point; - Window::Dimension(window, &rect); - - GetCursorPos(&point); - - return ((point.x - rect.left) > 0 && (point.y - rect.top) > 0 && (rect.right - point.x) > 0 && (rect.bottom - point.y) > 0); - } - - int Window::IsNoBorder() - { - return Window::NoBorder.Get(); - } - - void __declspec(naked) Window::StyleHookStub() - { - __asm - { - call Window::IsNoBorder - test al, al - jz setBorder - - mov ebp, WS_VISIBLE | WS_POPUP - retn - - setBorder: - mov ebp, WS_VISIBLE | WS_SYSMENU | WS_CAPTION - retn - } - } - - void Window::DrawCursorStub(void *scrPlace, float x, float y, float w, float h, int horzAlign, int vertAlign, const float *color, Game::Material *material) - { - if (Window::NativeCursor.Get()) - { - Window::CursorVisible = TRUE; - } - else - { - Game::UI_DrawHandlePic(scrPlace, x, y, w, h, horzAlign, vertAlign, color, material); - } - } - - int WINAPI Window::ShowCursorHook(BOOL show) - { - if (Window::NativeCursor.Get() && IsWindow(Window::MainWindow) && GetForegroundWindow() == Window::MainWindow && Window::IsCursorWithin(Window::MainWindow)) - { - static int count = 0; - (show ? ++count : --count); - - if (count >= 0) - { - Window::CursorVisible = TRUE; - } - - return count; - } - - return ShowCursor(show); - } - - HWND WINAPI Window::CreateMainWindow(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam) - { - Window::MainWindow = CreateWindowExA(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); - return Window::MainWindow; - } - - Window::Window() - { - // Borderless window - Window::NoBorder = Dvar::Register("r_noborder", true, Game::dvar_flag::DVAR_FLAG_SAVED, "Do not use a border in windowed mode"); - Window::NativeCursor = Dvar::Register("ui_nativeCursor", false, Game::dvar_flag::DVAR_FLAG_SAVED, "Display native cursor"); - - Utils::Hook(0x507643, Window::StyleHookStub, HOOK_CALL).Install()->Quick(); - - // Main window creation - Utils::Hook::Nop(0x5076AA, 1); - Utils::Hook(0x5076AB, Window::CreateMainWindow, HOOK_CALL).Install()->Quick(); - - // Mark the cursor as visible - Utils::Hook(0x48E5D3, Window::DrawCursorStub, HOOK_CALL).Install()->Quick(); - - // Draw the cursor if necessary - Renderer::OnFrame([] () - { - if (Window::NativeCursor.Get() && IsWindow(Window::MainWindow) && GetForegroundWindow() == Window::MainWindow && Window::IsCursorWithin(Window::MainWindow)) - { - int value = 0; - - if (Window::CursorVisible) - { - // TODO: Apply custom cursor - SetCursor(LoadCursor(NULL, IDC_ARROW)); - - while ((value = ShowCursor(TRUE)) < 0); - while (value > 0) { value = ShowCursor(FALSE); } // Set display counter to 0 - } - else - { - while ((value = ShowCursor(FALSE)) >= 0); - while (value < -1) { value = ShowCursor(TRUE); } // Set display counter to -1 - } - - Window::CursorVisible = FALSE; - } - }); - - // Don't let the game interact with the native cursor - Utils::Hook::Set(0x6D7348, Window::ShowCursorHook); - } -} +#include "STDInclude.hpp" + +namespace Components +{ + Dvar::Var Window::NoBorder; + Dvar::Var Window::NativeCursor; + + HWND Window::MainWindow = 0; + BOOL Window::CursorVisible = TRUE; + + int Window::Width() + { + return Window::Width(Window::MainWindow); + } + + int Window::Height() + { + return Window::Height(Window::MainWindow); + } + + int Window::Width(HWND window) + { + RECT rect; + Window::Dimension(window, &rect); + return (rect.right - rect.left); + } + + int Window::Height(HWND window) + { + RECT rect; + Window::Dimension(window, &rect); + return (rect.bottom - rect.top); + } + + void Window::Dimension(RECT* rect) + { + Window::Dimension(Window::MainWindow, rect); + } + + void Window::Dimension(HWND window, RECT* rect) + { + if (rect) + { + ZeroMemory(rect, sizeof(RECT)); + + if (window && IsWindow(window)) + { + GetWindowRect(window, rect); + } + } + } + + bool Window::IsCursorWithin(HWND window) + { + RECT rect; + POINT point; + Window::Dimension(window, &rect); + + GetCursorPos(&point); + + return ((point.x - rect.left) > 0 && (point.y - rect.top) > 0 && (rect.right - point.x) > 0 && (rect.bottom - point.y) > 0); + } + + int Window::IsNoBorder() + { + return Window::NoBorder.Get(); + } + + __declspec(naked) void Window::StyleHookStub() + { + __asm + { + call Window::IsNoBorder + test al, al + jz setBorder + + mov ebp, WS_VISIBLE | WS_POPUP + retn + + setBorder: + mov ebp, WS_VISIBLE | WS_SYSMENU | WS_CAPTION + retn + } + } + + void Window::DrawCursorStub(void *scrPlace, float x, float y, float w, float h, int horzAlign, int vertAlign, const float *color, Game::Material *material) + { + if (Window::NativeCursor.Get()) + { + Window::CursorVisible = TRUE; + } + else + { + Game::UI_DrawHandlePic(scrPlace, x, y, w, h, horzAlign, vertAlign, color, material); + } + } + + int WINAPI Window::ShowCursorHook(BOOL show) + { + if (Window::NativeCursor.Get() && IsWindow(Window::MainWindow) && GetForegroundWindow() == Window::MainWindow && Window::IsCursorWithin(Window::MainWindow)) + { + static int count = 0; + (show ? ++count : --count); + + if (count >= 0) + { + Window::CursorVisible = TRUE; + } + + return count; + } + + return ShowCursor(show); + } + + HWND WINAPI Window::CreateMainWindow(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam) + { + Window::MainWindow = CreateWindowExA(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); + return Window::MainWindow; + } + + Window::Window() + { + // Borderless window + Window::NoBorder = Dvar::Register("r_noborder", true, Game::dvar_flag::DVAR_FLAG_SAVED, "Do not use a border in windowed mode"); + Window::NativeCursor = Dvar::Register("ui_nativeCursor", false, Game::dvar_flag::DVAR_FLAG_SAVED, "Display native cursor"); + + Utils::Hook(0x507643, Window::StyleHookStub, HOOK_CALL).Install()->Quick(); + + // Main window creation + Utils::Hook::Nop(0x5076AA, 1); + Utils::Hook(0x5076AB, Window::CreateMainWindow, HOOK_CALL).Install()->Quick(); + + // Mark the cursor as visible + Utils::Hook(0x48E5D3, Window::DrawCursorStub, HOOK_CALL).Install()->Quick(); + + // Draw the cursor if necessary + Renderer::OnFrame([] () + { + if (Window::NativeCursor.Get() && IsWindow(Window::MainWindow) && GetForegroundWindow() == Window::MainWindow && Window::IsCursorWithin(Window::MainWindow)) + { + int value = 0; + + if (Window::CursorVisible) + { + // TODO: Apply custom cursor + SetCursor(LoadCursor(NULL, IDC_ARROW)); + + while ((value = ShowCursor(TRUE)) < 0); + while (value > 0) { value = ShowCursor(FALSE); } // Set display counter to 0 + } + else + { + while ((value = ShowCursor(FALSE)) >= 0); + while (value < -1) { value = ShowCursor(TRUE); } // Set display counter to -1 + } + + Window::CursorVisible = FALSE; + } + }); + + // Don't let the game interact with the native cursor + Utils::Hook::Set(0x6D7348, Window::ShowCursorHook); + } +} diff --git a/src/Utils/Hooking.cpp b/src/Utils/Hooking.cpp index 206300bf..d8928327 100644 --- a/src/Utils/Hooking.cpp +++ b/src/Utils/Hooking.cpp @@ -56,7 +56,7 @@ namespace Utils *place = Hook::Interceptor::InterceptionStub; } - void __declspec(naked) Hook::Interceptor::InterceptionStub() + __declspec(naked) void Hook::Interceptor::InterceptionStub() { __asm {