#include "plugin.h"
#include "game_sa\RenderWare.h"
#include "game_sa\common.h"
#include "game_sa\CFont.h"
#include "game_sa\CPed.h"
#include <Psapi.h>
#pragma comment( lib, "psapi.lib" )
#define E_ADDR_GAMEPROCESS 0x53E981
using namespace plugin;
#pragma pack(push, 1)
typedef struct stOpcodeRelCall
{
BYTE bOpcode;
DWORD dwRelAddr;
} OpcodeRelCall;
#pragma pack(pop)
class GPS {
private:
HANDLE hThread = NULL;
public:
GPS() {
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)GPS::init, (LPVOID)this, 0, (LPDWORD)NULL);
}
~GPS() {
// Check if thread still running on process
if (hThread != NULL)
TerminateThread(hThread, 0);
}
static LPVOID WINAPI init(LPVOID *lpParam) {
MODULEINFO miSampDll;
DWORD dwSampDllBaseAddr, dwSampDllEndAddr, dwCallAddr;
GPS *sender = (GPS *)lpParam;
stOpcodeRelCall *fnGameProc = (stOpcodeRelCall *)E_ADDR_GAMEPROCESS;
// Check if E_ADDR_GAMEPROCESS opcode is a relative call (0xE8)
while (fnGameProc->bOpcode != 0xE8)
Sleep(100);
while (true) {
Sleep(100);
// Get samp.dll module information to get base address and end address
if (!GetModuleInformation(GetCurrentProcess(), GetModuleHandle("samp.dll"), &miSampDll, sizeof(MODULEINFO))) {
continue;
}
// Some stupid calculation
dwSampDllBaseAddr = (DWORD)miSampDll.lpBaseOfDll;
dwSampDllEndAddr = dwSampDllBaseAddr + miSampDll.SizeOfImage;
// Calculate destination address by offset and relative call opcode size
dwCallAddr = fnGameProc->dwRelAddr + E_ADDR_GAMEPROCESS + 5;
// Check if dwCallAddr is a samp.dll's hook address,
// to make sure this plugin hook (Events::gameProcessEvent) not replaced by samp.dll
if (dwCallAddr >= dwSampDllBaseAddr && dwCallAddr <= dwSampDllEndAddr)
break;
}
// Just wait a few secs for the game loaded fully to avoid any conflicts and crashes
// I don't know what the elegant way is :)
while (!FindPlayerPed(0))
Sleep(5000);
// Run the plugin
sender->run();
// Reset the thread handle
sender->hThread = NULL;
return NULL;
}
void run() {
Events::drawHudEvent += [] {
CPed *player = FindPlayerPed(0);
if (player)
{
printf("%f\n", player->m_fCurrentRotation);
}
};
}
} gps;
{"html5":"htmlmixed","css":"css","javascript":"javascript","php":"php","python":"python","ruby":"ruby","lua":"text\/x-lua","bash":"text\/x-sh","go":"go","c":"text\/x-csrc","cpp":"text\/x-c++src","diff":"diff","latex":"stex","sql":"sql","xml":"xml","apl":"apl","asterisk":"asterisk","c_loadrunner":"text\/x-csrc","c_mac":"text\/x-csrc","coffeescript":"text\/x-coffeescript","csharp":"text\/x-csharp","d":"d","ecmascript":"javascript","erlang":"erlang","groovy":"text\/x-groovy","haskell":"text\/x-haskell","haxe":"text\/x-haxe","html4strict":"htmlmixed","java":"text\/x-java","java5":"text\/x-java","jquery":"javascript","mirc":"mirc","mysql":"sql","ocaml":"text\/x-ocaml","pascal":"text\/x-pascal","perl":"perl","perl6":"perl","plsql":"sql","properties":"text\/x-properties","q":"text\/x-q","scala":"scala","scheme":"text\/x-scheme","tcl":"text\/x-tcl","vb":"text\/x-vb","verilog":"text\/x-verilog","yaml":"text\/x-yaml","z80":"text\/x-z80"}