Help with getting Client lua state when hooking from Menu State
What's up, guys. I'm having trouble getting Client Lua state when using a module from menu state. I am already hooking from CreateLuaInterfaceFn but I'm having trouble getting it all working. Any hooks you guys can recommend or headers I might be missing/not thinking about?
For reference, I'm trying to call lua hooks between menu and client for a bot I'm building. Due to the bot running in client and the management/'backend' running in menu I'd like to notify menu on completed tasks etc.
The codebase is from the loonix branch of 'gm_roc' (credits to LennyPenny and meepen) because it seemed the closest to my use case. So I hope that helps if you wanted to see the headers and structs I'm using
I've been a software engineer for a number of years but I've never really gone near C++ before. So sorry if any of this cringes you out. Simple modules seemed fluid but going into hooking and process level stuff, I'm lost. Appreciate any help!
For reference, I'm trying to call lua hooks between menu and client for a bot I'm building. Due to the bot running in client and the management/'backend' running in menu I'd like to notify menu on completed tasks etc.
The codebase is from the loonix branch of 'gm_roc' (credits to LennyPenny and meepen) because it seemed the closest to my use case. So I hope that helps if you wanted to see the headers and structs I'm using
I've been a software engineer for a number of years but I've never really gone near C++ before. So sorry if any of this cringes you out. Simple modules seemed fluid but going into hooking and process level stuff, I'm lost. Appreciate any help!
Code:
using namespace GarrysMod;
Lua::Shared* luaShared;
VTable *luashared_vt;
VTable *client_vt;
Lua::Interface *cState;
Lua::ILuaBase *MENU;
int CallOnClient(lua_State *state)
{
if (!cState)
LUA->ThrowError("Not in game");
//Lua::ILuaBase *CLIENT = cState->state->luabase;
//CLIENT->PushSpecial(Lua::SPECIAL_GLOB);
//CLIENT->GetField(-1, "hook");
//CLIENT->GetField(-1, "Call");
//CLIENT->PushString(LUA->GetString(1));
//CLIENT->PushNil();
//CLIENT->PushString(LUA->GetString(2));
//CLIENT->Call(3, 1);
//CLIENT->Pop(2);
return 0;
}
int CallOnMenu(lua_State *state)
{
const char *name = LUA->GetString(1);
const char *data = LUA->GetString(2);
if (!cState)
LUA->ThrowError("Not in game");
//MENU->PushSpecial(Lua::SPECIAL_GLOB);
//MENU->GetField(-1, "hook");
//MENU->GetField(-1, "Call");
//MENU->PushString(name, strlen(name));
//MENU->PushNil();
//MENU->PushString(data, strlen(data));
//MENU->Call(3, 1);
//MENU->Pop(2);
return 0;
}
typedef Lua::Interface *(__thiscall *hCreateLuaInterfaceFn)(Lua::Shared*, unsigned char, bool);
void *__hook hCreateLuaInterface(Lua::Shared *ths, HOOK_EDX(void *) uchar state, bool renew)
{
Lua::Interface* hState = hCreateLuaInterfaceFn(luashared_vt->getold(Lua::Shared::CREATELUAINTERFACE))(ths, state, renew);
if (state != Lua::Interface::CLIENT)
return hState;
cState = hState;
//Push CallOnMenu to Client state
client_vt = new VTable(cState);
return cState;
}
typedef void *(__thiscall *hCloseLuaInterfaceFn)(Lua::Shared *, Lua::Interface *);
void *__hook hCloseLuaInterface(Lua::Shared *ths, HOOK_EDX(void *) Lua::Interface *iface)
{
if (iface == cState)
cState = NULL;
return hCloseLuaInterfaceFn(luashared_vt->getold(Lua::Shared::CLOSELUAINTERFACE))(ths, iface);
}
GMOD_MODULE_OPEN()
{
MENU = LUA;
luaShared = GetInterface<Lua::Shared*>("lua_shared", "LUASHARED003");
LUA->PushSpecial(Lua::SPECIAL_GLOB);
LUA->PushString("CallOnClient");
LUA->PushCFunction(CallOnClient);
LUA->SetTable(-3);
LUA->Pop();
luashared_vt = new VTable(luaShared);
luashared_vt->hook(Lua::Shared::CREATELUAINTERFACE, (void *)&hCreateLuaInterface);
luashared_vt->hook(Lua::Shared::CLOSELUAINTERFACE, (void *)&hCloseLuaInterface);
return 0;
}
GMOD_MODULE_CLOSE()
{
return 0;
}