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