Skip to content

Commit

Permalink
A somewhat working with() statement. Hacky, but works, seems to.
Browse files Browse the repository at this point in the history
  • Loading branch information
nkrapivin committed Apr 22, 2021
1 parent 61f9b5b commit 6716da7
Show file tree
Hide file tree
Showing 12 changed files with 182 additions and 41 deletions.
2 changes: 1 addition & 1 deletion libLassebq/GMAddresses.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

// What addresses to use?
#define DITTO_WIN_STEAM
#define KZ_105_STEAM

// Please please please, keep address format like this:
// #define Something_Addr (0xSOMETHINGu)
Expand Down
177 changes: 160 additions & 17 deletions libLassebq/GMLua.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -753,11 +753,13 @@ int lua_GMLua_setvar(lua_State* _pL)
return 0;
}

const lua_Integer GM_global = -5l;
const lua_Integer GM_noone = -4l;
const lua_Integer GM_all = -3l;
const lua_Integer GM_other = -2l;
const lua_Integer GM_self = -1l;
enum GM_instance_type : lua_Integer {
GM_global = -5l,
GM_noone = -4l,
GM_all = -3l,
GM_other = -2l,
GM_self = -1l
};

int lua_GMLua_inst(lua_State* _pL)
{
Expand Down Expand Up @@ -794,10 +796,7 @@ int lua_GMLua_inst(lua_State* _pL)
}
else
{
CInstance** luaSelf = reinterpret_cast<CInstance**>(lua_newuserdata(lS, sizeof(CInstance*)));
*luaSelf = inst;
luaL_getmetatable(lS, "__libLassebq_GMLInstance_metatable");
lua_setmetatable(lS, -2);
SH_pushCInstance(_pL, inst);
}

return 1;
Expand Down Expand Up @@ -841,6 +840,155 @@ int lua_DumpGMLVarids(lua_State* _pL)
return 0;
}

int lua_GMLua_setSelf(lua_State* _pL)
{
int Largc = lua_gettop(_pL); // get argument count.
if (Largc < 1)
{
return luaL_error(_pL, __FUNCTION__ " error: invalid argument count, expected 1, got %d.", Largc);
}

if (lua_isuserdata(_pL, 1))
{
CInstance** luaInst = reinterpret_cast<CInstance**>(luaL_checkudata(_pL, 1, "__libLassebq_GMLInstance_metatable"));
if (luaInst == nullptr)
{
return luaL_error(_pL, __FUNCTION__ " error: argument is userdata, but isn't GMLInstance.");
}

g_Self = *luaInst;
}
else
{
return luaL_error(_pL, __FUNCTION__ " error: argument is not userdata, it is %s.", lua_typename(_pL, lua_type(_pL, 1)));
}

return 0;
}

// please give hugs to cherryjam.
int cherry_with_wrapper(lua_State* _pL, CInstance* self, CInstance* other, int fIndex)
{
CInstance* oldOther = g_Other;
CInstance* oldSelf = g_Self;

g_Other = other;
g_Self = self;

int r = -1;
int oldtop = lua_gettop(_pL);
lua_pushvalue(_pL, fIndex);
SH_pushCInstance(_pL, self);
SH_pushCInstance(_pL, other);
RenewGlobal(_pL);

r = lua_pcall(_pL, 2, LUA_MULTRET, 0);
g_Self = oldSelf;
g_Other = oldOther;
if (r != LUA_OK)
{
const char* errmsg = lua_tostring(_pL, -1);
if (g_ThrowErrors)
{
YYError("Lua Error: lua_pcall failed with result %d in A WITH STATEMENT.\r\nDetails:\r\n%s\r\n", r, errmsg);
}
lua_pop(_pL, 1);
}
int newtop = lua_gettop(_pL);

if (oldtop == newtop)
{
return 0;
}
else
{
int diff = newtop - oldtop;
std::cout << "with, diff=" << diff << std::endl;
lua_pop(_pL, diff);
return diff;
}
}

int cherry_with_gmobject(lua_State* _pL, int objIndex, int fIndex)
{
// any instances of this object exist in the first place.
CInstance* first = (*g_RunRoom)->m_Active.m_pFirst;
for (int i = 0; first != nullptr; i++)
{
if ((objIndex < 0) || (first->i_object_index == objIndex || first->m_pObject->m_parent == objIndex))
{
int diff = cherry_with_wrapper(_pL, first, g_Self, fIndex);
if (diff != 0)
{
// there was more than 0 elements returned, break!
break;
}
}

first = first->m_pNext;
}

return 0;
}

int lua_GMLua_with(lua_State* _pL)
{
int Largc = lua_gettop(_pL); // argument count
if (Largc < 2)
{
return luaL_error(_pL, __FUNCTION__ " error: invalid argument count, expected 2, got %d.", Largc);
}

// GMLua_inst(noone) will return nil.
if (lua_isnil(_pL, 1)) return 0;

// *sigh*
if (!lua_isfunction(_pL, 2))
{
return luaL_error(_pL, __FUNCTION__ " error: invalid argument 2, expected a function.");
}

// all?
if (lua_isinteger(_pL, 1))
{
lua_Integer wtf = lua_tointeger(_pL, 1);
std::cout << __FUNCTION__ << " wtf=" << wtf << std::endl;
if (wtf == GM_noone) return 0;
if (wtf >= 0 && wtf < 100000) // an object index, loop through all instances of that object.
{
cherry_with_gmobject(_pL, static_cast<int>(wtf), 2);
}
else if (wtf >= 100000) // instance id, auto cast to GMLInstance
{
CInstance* inst = lass_find_CInstance_QUICK(static_cast<int>(wtf));
if (inst == nullptr)
{
return luaL_error(_pL, __FUNCTION__ " error, passed instance id %lld is invalid, do you need sleep?", wtf);
}
cherry_with_wrapper(_pL, inst, g_Self, 2);
}
else if (wtf == GM_all)
{
cherry_with_gmobject(_pL, -1, 2); // -1 - doesn't matter which object, if it exists, do.
}
else
{
return luaL_error(_pL, __FUNCTION__ " error, dude go to sleep seriously, hug a pillow and have rest. %lld", wtf);
}
}
else // directly passed GMLInstance 'class'
{
CInstance** luaInst = reinterpret_cast<CInstance**>(luaL_checkudata(_pL, 1, "__libLassebq_GMLInstance_metatable"));
if (luaInst == nullptr)
{
return luaL_error(_pL, __FUNCTION__ " error, passed CInstance is not actually a GMLInstance, are you tired?");
}
cherry_with_wrapper(_pL, *luaInst, g_Self, 2);
}

return 0;
}

void RegisterFunctions(lua_State* _pL)
{
std::cout << "Registering functions... ";
Expand Down Expand Up @@ -873,6 +1021,8 @@ void RegisterFunctions(lua_State* _pL)
lua_register(_pL, "GMLua_getcallbacks", lua_GMLua_getcallbacks);
lua_register(_pL, "GMLua_dumpvarids", lua_DumpGMLVarids);
lua_register(_pL, "GMLua_detour_debug_mode_var", lua_GMLua_detour_debug_mode_var);
lua_register(_pL, "GMLua_setSelf", lua_GMLua_setSelf);
lua_register(_pL, "GMLua_with", lua_GMLua_with);
std::cout << "Done!" << std::endl;
}

Expand Down Expand Up @@ -1242,14 +1392,7 @@ void RenewGlobal(lua_State* _pL)
{
// global object may be relocated from time to time...
// gotta renew it sometimes.

CInstance** luaGlobal = reinterpret_cast<CInstance**>(lua_newuserdata(_pL, sizeof(CInstance*)));

// this is wrong, will likely break stuff, but who cares.
*luaGlobal = reinterpret_cast<CInstance*>(*g_pGlobal);

luaL_getmetatable(_pL, "__libLassebq_GMLInstance_metatable");
lua_setmetatable(_pL, -2);
SH_pushCInstance(_pL, reinterpret_cast<CInstance*>(*g_pGlobal));
lua_setglobal(_pL, "_pGlobal");
}

Expand Down
2 changes: 1 addition & 1 deletion libLassebq/Room.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ CRoom** g_RunRoom = nullptr; // this variable was only used to find instances, i
CHash<CInstance>* g_CInstanceHashList = nullptr;
int* g_New_Room = nullptr;

const int FLAG_deactivated = 1;


CInstance* lass_find_CInstance_QUICK(int obj_index) {

Expand Down
2 changes: 1 addition & 1 deletion libLassebq/Room.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once
#include "Data.h"

const int FLAG_deactivated = 1;
struct YYRoom
{
const char* pName;
Expand Down
16 changes: 9 additions & 7 deletions libLassebq/ScriptHooker.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
#include "ScriptHooker.h"
#include "SHAutogen.h"
void SH_pushCInstance(lua_State* _pL, CInstance* _pInst)
{
CInstance** luaSelf = reinterpret_cast<CInstance**>(lua_newuserdata(lS, sizeof(CInstance*)));
*luaSelf = _pInst;
luaL_getmetatable(lS, "__libLassebq_GMLInstance_metatable");
lua_setmetatable(lS, -2);
}

#if USE_DETOURS

int getAutogenTableSize()
Expand All @@ -13,13 +21,7 @@ int getAutogenTableSize()
}
}

void SH_pushCInstance(lua_State* _pL, CInstance* _pInst)
{
CInstance** luaSelf = reinterpret_cast<CInstance**>(lua_newuserdata(lS, sizeof(CInstance*)));
*luaSelf = _pInst;
luaL_getmetatable(lS, "__libLassebq_GMLInstance_metatable");
lua_setmetatable(lS, -2);
}


void SH_pushScriptArgs(lua_State* _pL, const int _count, const RValue** _args)
{
Expand Down
10 changes: 6 additions & 4 deletions libLassebq/ScriptHooker.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
#pragma once
#include "GMLFuncs.h"
#include "Utils.h"
#include "libLassebq.h"
#include "GMLua.h"
void SH_pushCInstance(lua_State* _pL, CInstance* _pInst);
#define USE_DETOURS 1 /* Do you happen to have the Detours v4.0.1 from Microsoft Research's github? */

#if USE_DETOURS
#include "targetver.h"
#include "stdafx.h"
#include "detours\detours.h"
#include "GMLFuncs.h"
#include "Utils.h"
#include "libLassebq.h"
#include "GMLua.h"


void SH_hookGMLScript(const YYGMLFunc& ref, const int index);
RValue& SH_hookerRoutine(const int _myIndex, CInstance* _pSelf, CInstance* _pOther, RValue& _result, int _count, const RValue** _args);
Expand Down
Binary file added libLassebq/detours/debug/detours.lib
Binary file not shown.
Binary file added libLassebq/detours/debug/detours.pdb
Binary file not shown.
Binary file modified libLassebq/libLassebq.aps
Binary file not shown.
10 changes: 2 additions & 8 deletions libLassebq/libLassebq.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,14 +157,8 @@ bool lassebq_doLua(CInstance* _pSelf, CInstance* _pOther, const char* _pLFName)
{
// push pSelf/pOther as arguments to the function call...
// TODO: wrappers?
CInstance** luaSelf = reinterpret_cast<CInstance**>(lua_newuserdata(lS, sizeof(CInstance*)));
*luaSelf = _pSelf;
luaL_getmetatable(lS, "__libLassebq_GMLInstance_metatable");
lua_setmetatable(lS, -2);
CInstance** luaOther = reinterpret_cast<CInstance**>(lua_newuserdata(lS, sizeof(CInstance*)));
*luaOther = _pOther;
luaL_getmetatable(lS, "__libLassebq_GMLInstance_metatable");
lua_setmetatable(lS, -2);
SH_pushCInstance(lS, _pSelf);
SH_pushCInstance(lS, _pOther);

// renew _pGlobal
RenewGlobal(lS);
Expand Down
Binary file modified libLassebq/libLassebq.rc
Binary file not shown.
4 changes: 2 additions & 2 deletions libLassebq/libLassebq.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,12 @@
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBLASSEBQ_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib;winmm.lib;detours\detours.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>user32.lib;winmm.lib;detours\debug\detours.lib;%(AdditionalDependencies)</AdditionalDependencies>
<FullProgramDatabaseFile>true</FullProgramDatabaseFile>
<GenerateMapFile>true</GenerateMapFile>
<MapExports>true</MapExports>
Expand Down

0 comments on commit 6716da7

Please sign in to comment.