rtdhook_call* mainloop_hook = nullptr;
bool open_input = false;
enum SampVersion {
SAMP_NOT_LOADED,
SAMP_UNKNOWN,
SAMP_037_R1,
SAMP_037_R3_1,
SAMP_037_R4_2
};
uintptr_t samp_get_base()
{
return reinterpret_cast<uintptr_t>(GetModuleHandleA("samp.dll"));
}
SampVersion samp_get_version()
{
static SampVersion samp_ver = SampVersion::SAMP_NOT_LOADED;
if (samp_ver <= SampVersion::SAMP_UNKNOWN)
{
auto base = samp_get_base();
if (base == 0) return SampVersion::SAMP_NOT_LOADED;
auto* ntHeader = reinterpret_cast<IMAGE_NT_HEADERS*>(base + reinterpret_cast<IMAGE_DOS_HEADER*>(base)->e_lfanew);
auto ep = ntHeader->OptionalHeader.AddressOfEntryPoint;
switch (ep)
{
case 0x31DF13:
samp_ver = SampVersion::SAMP_037_R1;
break;
case 0xCC4D0:
samp_ver = SampVersion::SAMP_037_R3_1;
break;
case 0xCBCB0:
samp_ver = SampVersion::SAMP_037_R4_2;
break;
default:
samp_ver = SampVersion::SAMP_UNKNOWN;
#ifdef _DEBUG
assert(0);
#endif
}
}
return samp_ver;
}
LRESULT CALLBACK handle_wndproc(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if (Msg == WM_KEYDOWN && wParam == 0x54) // T key
{
open_input = true; // Lazy to lock CInput WM_CHAR
return 0;
}
return CallWindowProcA(lpPrevWndFunc, hWnd, Msg, wParam, lParam);
}
void mainloop()
{
static bool once = false;
static SampVersion version = SAMP_NOT_LOADED;
if (!once && *reinterpret_cast<uintptr_t*>(0x00C8D4C0) == 9 && samp_get_base() != 0)
{
once = true;
version = samp_get_version();
if (version >= SAMP_037_R1)
{
uintptr_t override_mem = 0;
uintptr_t hook_ptr = 0;
switch (version)
{
case SAMP_037_R3_1:
override_mem = 0x0613CB;
hook_ptr = 0x0613CB + 1;
break;
case SAMP_037_R4_2:
override_mem = 0x061B3B;
hook_ptr = 0x061B3B + 1;
break;
case SAMP_037_R1:
hook_ptr = 0x05E02B;
break;
}
if (override_mem)
{
DWORD old_protection;
VirtualProtect((LPVOID)(samp_get_base() + override_mem), 2, PAGE_EXECUTE_READWRITE, &old_protection);
*reinterpret_cast<uint16_t*>(samp_get_base() + override_mem) = 0xE890;
VirtualProtect((LPVOID)(samp_get_base() + override_mem), 2, old_protection, &old_protection);
}
if (hook_ptr)
{
auto* hook = new rtdhook_call(samp_get_base() + hook_ptr, &handle_wndproc);
hook->install();
}
}
}
if (open_input)
{
static uintptr_t func_ptr = 0;
if (!func_ptr)
{
switch (version)
{
case SAMP_037_R3_1:
func_ptr = 0x060E20;
break;
case SAMP_037_R4_2:
func_ptr = 0x61590;
break;
case SAMP_037_R1:
func_ptr = 0x5DA80;
break;
}
}
if (func_ptr)
reinterpret_cast<int(*)(WPARAM)>(samp_get_base() + func_ptr)('T');
open_input = false;
}
reinterpret_cast<void(*)()>(mainloop_hook->getHookedFunctionAddress())();
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD fdwReason,
LPVOID lpReserved
)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
mainloop_hook = new rtdhook_call(0x53E968, &mainloop);
mainloop_hook->install();
}
return TRUE;
}