104 lines
3.3 KiB
C++
104 lines
3.3 KiB
C++
#include "lua_hook.h"
|
|
#include "functions/functions.h"
|
|
#include <MinHook.h>
|
|
#include <windows.h>
|
|
|
|
// Resolved function pointers
|
|
fn_lua_open real_lua_open = nullptr;
|
|
fn_lua_pushstring pfn_pushstring = nullptr;
|
|
fn_lua_pushcclosure pfn_pushcclosure = nullptr;
|
|
fn_lua_settable pfn_settable = nullptr;
|
|
fn_lua_tostring pfn_tostring = nullptr;
|
|
fn_lua_tonumber pfn_tonumber = nullptr;
|
|
fn_lua_newtable pfn_newtable = nullptr;
|
|
fn_lua_rawseti pfn_rawseti = nullptr;
|
|
fn_GetPlayerByIndex pfn_get_player_by_index = nullptr;
|
|
void* g_player_list = nullptr;
|
|
fn_PlayerWrapperCreate pfn_player_wrapper_create = nullptr;
|
|
fn_GetScriptFromState pfn_get_script_from_state = nullptr;
|
|
fn_MapVarToLua pfn_map_var_to_lua = nullptr;
|
|
fn_DebugPrint pfn_debug_print = nullptr;
|
|
|
|
void register_global(lua_State* L, const char* name, lua_CFunction fn) {
|
|
pfn_pushstring(L, name);
|
|
pfn_pushcclosure(L, fn, 0);
|
|
pfn_settable(L, LUA_GLOBALSINDEX);
|
|
}
|
|
|
|
// Fired every time the game creates a new Lua state
|
|
static lua_State* Hook_lua_open() {
|
|
lua_State* L = real_lua_open();
|
|
|
|
if (!L) {
|
|
return L;
|
|
}
|
|
|
|
Register_All(L);
|
|
|
|
return L;
|
|
}
|
|
|
|
bool LuaHook_Init() {
|
|
char exePath[MAX_PATH];
|
|
GetModuleFileNameA(nullptr, exePath, MAX_PATH);
|
|
|
|
const LuaRVAs* rvas = nullptr;
|
|
if (strstr(exePath, "StarWarsI.exe"))
|
|
rvas = &RVAs_StarWarsI;
|
|
else if (strstr(exePath, "StarWarsG.exe"))
|
|
rvas = &RVAs_StarWarsG;
|
|
else
|
|
return false;
|
|
|
|
if (!rvas->lua_open || !rvas->lua_pushstring || !rvas->lua_pushcclosure ||
|
|
!rvas->lua_settable || !rvas->lua_tostring)
|
|
return false;
|
|
|
|
uintptr_t base = (uintptr_t)GetModuleHandleA(nullptr);
|
|
|
|
pfn_pushstring = (fn_lua_pushstring)(base + rvas->lua_pushstring);
|
|
pfn_pushcclosure = (fn_lua_pushcclosure)(base + rvas->lua_pushcclosure);
|
|
pfn_settable = (fn_lua_settable)(base + rvas->lua_settable);
|
|
pfn_tostring = (fn_lua_tostring)(base + rvas->lua_tostring);
|
|
|
|
if (rvas->lua_tonumber && rvas->get_player_by_index && rvas->player_list &&
|
|
rvas->player_wrapper_create && rvas->get_script_from_state && rvas->map_var_to_lua)
|
|
{
|
|
pfn_tonumber = (fn_lua_tonumber)(base + rvas->lua_tonumber);
|
|
pfn_get_player_by_index = (fn_GetPlayerByIndex)(base + rvas->get_player_by_index);
|
|
g_player_list = (void*)(base + rvas->player_list);
|
|
pfn_player_wrapper_create = (fn_PlayerWrapperCreate)(base + rvas->player_wrapper_create);
|
|
pfn_get_script_from_state = (fn_GetScriptFromState)(base + rvas->get_script_from_state);
|
|
pfn_map_var_to_lua = (fn_MapVarToLua)(base + rvas->map_var_to_lua);
|
|
}
|
|
|
|
if (rvas->debug_print)
|
|
pfn_debug_print = (fn_DebugPrint)(base + rvas->debug_print);
|
|
|
|
if (rvas->lua_newtable && rvas->lua_rawseti) {
|
|
pfn_newtable = (fn_lua_newtable)(base + rvas->lua_newtable);
|
|
pfn_rawseti = (fn_lua_rawseti)(base + rvas->lua_rawseti);
|
|
}
|
|
|
|
void* const target = (void*)(base + rvas->lua_open);
|
|
|
|
if (MH_Initialize() != MH_OK) {
|
|
return false;
|
|
}
|
|
|
|
if (MH_CreateHook(target, &Hook_lua_open, (void**)&real_lua_open) != MH_OK) {
|
|
return false;
|
|
}
|
|
|
|
if (MH_EnableHook(target) != MH_OK) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void LuaHook_Shutdown() {
|
|
MH_DisableHook(MH_ALL_HOOKS);
|
|
MH_Uninitialize();
|
|
}
|