//Copyright Cheat Engine 2020 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.InteropServices; namespace CESDK { public class CESDKLua { private const int LUA_TNONE = -1; private const int LUA_TNIL = 0; private const int LUA_TBOOLEAN = 1; private const int LUA_TLIGHTUSERDATA = 2; private const int LUA_TNUMBER = 3; private const int LUA_TSTRING = 4; private const int LUA_TTABLE = 5; private const int LUA_TFUNCTION = 6; private const int LUA_TUSERDATA = 7; private const int LUA_TTHREAD = 8; [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Ansi)] static extern IntPtr LoadLibraryA([MarshalAs(UnmanagedType.LPStr)]string lpFileName); [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)] public static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)]string procedureName); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool FreeLibrary(IntPtr hModule); private CESDK sdk; [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int LuaCall(IntPtr lua_State); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int LuaCallSimplified(); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_gettop(IntPtr state); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_settop(IntPtr state, int idx); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_pushvalue(IntPtr state, int idx); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_rotate(IntPtr state, int idx, int n); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_copy(IntPtr state, int fromidx, int toidx); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_pushcclosure(IntPtr state, LuaCall func, int n); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_setglobal(IntPtr state, [MarshalAs(UnmanagedType.LPStr)]string str); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_getglobal(IntPtr state, [MarshalAs(UnmanagedType.LPStr)]string str); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_pushnil(IntPtr state); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_pushinteger(IntPtr state, [MarshalAs(UnmanagedType.I8)]Int64 i); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_pushnumber(IntPtr state, [MarshalAs(UnmanagedType.R8)]Double n); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_pushlstring(IntPtr state, [MarshalAs(UnmanagedType.LPStr)]string s, [MarshalAs(UnmanagedType.SysUInt)]IntPtr size); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_pushstring(IntPtr state, [MarshalAs(UnmanagedType.LPStr)]string s); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_pushboolean(IntPtr state, [MarshalAs(UnmanagedType.Bool)]bool b); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_type(IntPtr state, int idx); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate bool dlua_isnumber(IntPtr state, int idx); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate bool dlua_isinteger(IntPtr state, int idx); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate bool dlua_isstring(IntPtr state, int idx); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate bool dlua_iscfunction(IntPtr state, int idx); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate bool dlua_isuserdata(IntPtr state, int idx); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate double dlua_tonumberx(IntPtr state, int idx, [MarshalAs(UnmanagedType.I4)] ref int isnum); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate Int64 dlua_tointegerx(IntPtr state, int idx, [MarshalAs(UnmanagedType.I4)] ref int isnum); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate bool dlua_toboolean(IntPtr state, int idx); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate IntPtr dlua_tolstring(IntPtr state, int idx, IntPtr sizeptr); [UnmanagedFunctionPointer(CallingConvention.Cdecl)][return: MarshalAs(UnmanagedType.SysInt)] private delegate IntPtr dlua_touserdata(IntPtr state, int idx); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_rawlen(IntPtr state, int idx); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_gettable(IntPtr state, int idx); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_settable(IntPtr state, int idx); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_callk(IntPtr state, int nargs, int nresults, IntPtr context, IntPtr k); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dlua_pcallk(IntPtr state, int nargs, int nresults, IntPtr context, IntPtr k); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int dluaL_loadstring(IntPtr state, [MarshalAs(UnmanagedType.LPStr)]string script); //ce plugin: [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate IntPtr dGetLuaState(); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate IntPtr dLuaRegister(IntPtr state, [MarshalAs(UnmanagedType.LPStr)]string s, LuaCall func); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate void dLuaPushClassInstance(IntPtr state, IntPtr instance); //lua related sdk exports: private dGetLuaState _GetLuaState; private dLuaRegister LuaRegister; private dLuaPushClassInstance LuaPushClassInstance; //local native lua functions private dlua_gettop lua_gettop; private dlua_settop lua_settop; private dlua_pushvalue lua_pushvalue; private dlua_rotate lua_rotate; private dlua_copy lua_copy; private dlua_pushcclosure lua_pushcclosure; private dlua_setglobal lua_setglobal; private dlua_getglobal lua_getglobal; private dlua_pushnil lua_pushnil; private dlua_pushinteger lua_pushinteger; private dlua_pushnumber lua_pushnumber; private dlua_pushlstring lua_pushlstring; private dlua_pushstring lua_pushstring; private dlua_pushboolean lua_pushboolean; private dlua_type lua_type; private dlua_isnumber lua_isnumber; private dlua_isinteger lua_isinteger; private dlua_isstring lua_isstring; private dlua_iscfunction lua_iscfunction; private dlua_isuserdata lua_isuserdata; private dlua_tonumberx lua_tonumberx; private dlua_tointegerx lua_tointegerx; private dlua_toboolean lua_toboolean; private dlua_tolstring lua_tolstring; private dlua_touserdata lua_touserdata; private dlua_rawlen lua_rawlen; private dlua_gettable lua_gettable; private dlua_settable lua_settable; private dlua_callk lua_callk; private dlua_pcallk lua_pcallk; private dluaL_loadstring luaL_loadstring; public IntPtr State { get { return GetLuaState(); } } private static List luafunctions = new List(); //c# versions public int GetTop() { return lua_gettop(State); } public int GetTop(IntPtr L) { return lua_gettop(L); } public int SetTop(int idx) { return lua_settop(State, idx); } public int SetTop(IntPtr L, int idx) { return lua_settop(L, idx); } public int PushValue(int idx) { return lua_pushvalue(State, idx); } public int PushValue(IntPtr L, int idx) { return lua_pushvalue(L, idx); } public int Rotate(int idx, int n) { return lua_rotate(State, idx, n); } public int Rotate(IntPtr L, int idx, int n) { return lua_rotate(L, idx, n); } public int Copy(int idx, int fromidx, int toidx) { return lua_copy(State, fromidx, toidx); } public int Copy(IntPtr L, int fromidx, int toidx) { return lua_copy(L, fromidx, toidx); } public void Pop(IntPtr L, int n) { lua_settop(State, -n - 1); } public void Pop(int n) { Pop(State, n); } public void Remove(IntPtr L, int idx) { Rotate(L, idx, -1); Pop(L, 1); } public void Remove(int idx) { Remove(State, idx); } public void Insert(IntPtr L, int idx) { lua_rotate(L, idx, 1); } public void Insert(int idx) { Insert(State, idx); } public void Replace(IntPtr L, int idx) { lua_copy(State, -1, idx); Pop(State, 1); } public void Replace(int idx) { Replace(State, idx); } public int Type(int idx) { return lua_type(State, idx); } public int Type(IntPtr L, int idx) { return lua_type(L, idx); } public int PushClosure(LuaCall func, int n) { return lua_pushcclosure(State, func, n); } public int PushFunction(LuaCall func) { return PushClosure(func, 0); } public int SetGlobal(string str) { return lua_setglobal(State, str); } public int GetGlobal(string str) { return lua_getglobal(State, str); } /// /// Registers a new function with CE's lua environment /// /// new lua function name /// pointer to the method to be called when the function is executed public void Register(string FuncName, LuaCallSimplified func) { LuaCall z = delegate (IntPtr x) { int r; IntPtr oldOverride = lua_StateOverride; lua_StateOverride = x; r = func(); lua_StateOverride = oldOverride; return r; }; luafunctions.Add(z); //prevent it from getting garbage collected LuaRegister(State, FuncName, z); } public void Register(string FuncName, LuaCall func) { LuaCall z = delegate (IntPtr x) { int r; IntPtr oldOverride = lua_StateOverride; lua_StateOverride = x; r = func(x); lua_StateOverride = oldOverride; return r; }; luafunctions.Add(z); //prevent it from getting garbage collected LuaRegister(State, FuncName, z); } public void PushInteger(Int64 i) { lua_pushinteger(State, i); } public void PushInteger(IntPtr L, Int64 i) { lua_pushinteger(L, i); } public void PushNumber(Double n) { lua_pushnumber(State, n); } public void PushNumber(IntPtr L, Double n) { lua_pushnumber(L, n); } public void PushLString(string s, IntPtr size) { lua_pushlstring(State, s, size); } public void PushLString(IntPtr L, string s, IntPtr size) { lua_pushlstring(L, s, size); } public void PushString(string s) { lua_pushstring(State, s); } public void PushString(IntPtr L, string s) { lua_pushstring(L, s); } public void PushBoolean(bool b) { lua_pushboolean(State, b); } public void PushBoolean(IntPtr L, bool b) { lua_pushboolean(L, b); } public void PushCEObject(IntPtr L, IntPtr ceobject) { LuaPushClassInstance(L, ceobject); } public void PushCEObject(IntPtr ceobject) { LuaPushClassInstance(State, ceobject); } public Boolean IsFunction(IntPtr L, int idx) { return lua_type(L, idx) == LUA_TFUNCTION; } public Boolean IsFunction(int idx) { return lua_type(State, idx) == LUA_TFUNCTION; } public Boolean IsTable(IntPtr L, int idx) { return lua_type(L, idx) == LUA_TTABLE; } public Boolean IsTable(int idx) { return lua_type(State, idx) == LUA_TTABLE; } public Boolean IsLightUserdata(IntPtr L, int idx) { return lua_type(L, idx) == LUA_TLIGHTUSERDATA; } public Boolean IsLightUserdata(int idx) { return lua_type(State, idx) == LUA_TLIGHTUSERDATA; } public Boolean IsHeavyUserdata(IntPtr L, int idx) { return lua_type(L, idx) == LUA_TUSERDATA; } public Boolean IsHeavyUserdata(int idx) { return lua_type(State, idx) == LUA_TUSERDATA; } public Boolean IsNil(IntPtr L, int idx) { return lua_type(L, idx) == LUA_TNIL; } public Boolean IsNil(int idx) { return lua_type(State, idx) == LUA_TNIL; } public Boolean IsBoolean(IntPtr L, int idx) { return lua_type(L, idx) == LUA_TBOOLEAN; } public Boolean IsBoolean(int idx) { return lua_type(State, idx) == LUA_TBOOLEAN; } public Boolean IsThread(IntPtr L, int idx) { return lua_type(L, idx) == LUA_TTHREAD; } public Boolean IsThread(int idx) { return lua_type(State, idx) == LUA_TTHREAD; } public Boolean IsNone(IntPtr L, int idx) { return lua_type(L, idx) == LUA_TNONE; } public Boolean IsNone(int idx) { return lua_type(State, idx) == LUA_TNONE; } public Boolean IsNoneOrNil(IntPtr L, int idx) { return lua_type(L, idx) <=0; } public Boolean IsNoneOrNil(int idx) { return lua_type(State, idx) <= 0; } public Boolean IsNumber(IntPtr L, int idx) { return lua_isnumber(L, idx); } public Boolean IsNumber(int idx) { return lua_isnumber(State, idx); } public Boolean IsInteger(IntPtr L, int idx) { return lua_isinteger(L, idx); } public Boolean IsInteger(int idx) { return lua_isinteger(State, idx); } public Boolean IsString(IntPtr L, int idx) { return lua_isstring(L, idx); } public Boolean IsString(int idx) { return lua_isstring(State, idx); } public Boolean IsCFunction(IntPtr L, int idx) { return lua_iscfunction(L, idx); } public Boolean IsCFunction(int idx) { return lua_iscfunction(State, idx); } public Boolean IsUserData(IntPtr L, int idx) { return lua_isuserdata(L, idx); } public Boolean IsUserData(int idx) { return lua_isuserdata(State, idx); } public Boolean IsCEObject(IntPtr L, int idx) { return IsHeavyUserdata(L, idx); } public Boolean IsCEObject(int idx) { return IsHeavyUserdata(State, idx); } public double ToNumber(IntPtr L, int idx) { int isnumber = 0; return lua_tonumberx(L, idx, ref isnumber); } public double ToNumber(int idx) { return ToNumber(State, idx); } public Int64 ToInteger(IntPtr L, int idx) { int isnumber = 0; Int64 r =lua_tointegerx(L, idx, ref isnumber); if (isnumber==0) { r=(Int64)lua_tonumberx(L, idx, ref isnumber); if (isnumber == 0) return 0; } return r; } public Int64 ToInteger(int idx) { return ToInteger(State, idx); } public bool ToBoolean(IntPtr L, int idx) { return lua_toboolean(L, idx); } public bool ToBoolean(int idx) { return lua_toboolean(State, idx); } public string ToLString(IntPtr L, int idx, ref IntPtr count) { IntPtr ps=lua_tolstring(L, idx, IntPtr.Zero); string s=Marshal.PtrToStringAnsi(ps); return s; } public string ToLString(int idx, ref IntPtr count) { return ToLString(State, idx, ref count); } public IntPtr ToCEObject(IntPtr L, int idx) { IntPtr p = lua_touserdata(L, idx); p=Marshal.ReadIntPtr(p); return p; } public IntPtr ToCEObject(int idx) { return ToCEObject(State, idx); } public int ObjLen(IntPtr L, int idx) { return lua_rawlen(L, idx); } public int ObjLen(int idx) { return lua_rawlen(State, idx); } public int GetTable(IntPtr L, int idx) { return lua_gettable(L, idx); } public int GetTable(int idx) { return lua_gettable(State, idx); } public int SetTable(IntPtr L, int idx) { return lua_settable(L, idx); } public int SetTable(int idx) { return lua_settable(State, idx); } public string ToString(IntPtr L, int idx) { IntPtr len = (IntPtr)ObjLen(L, idx); return ToLString(L, idx, ref len); } public string ToString(int idx) { return ToString(State, idx); } public int PCall(IntPtr L, int nargs, int nresults) { int pcr=lua_pcallk(L, nargs, nresults, IntPtr.Zero, IntPtr.Zero); if (pcr!=0) throw new System.ApplicationException("PCall failed with error " + pcr.ToString() + " (" + ToString(-1) + ")"); return pcr; } public int PCall(int nargs, int nresults) { return PCall(State, nargs, nresults); } public int Call(IntPtr L, int nargs, int nresults) { return lua_callk(L, nargs, nresults, IntPtr.Zero, IntPtr.Zero); } public int Call(int nargs, int nresults) { return lua_callk(State, nargs, nresults, IntPtr.Zero, IntPtr.Zero); } public int LoadString(IntPtr L, string script) { return luaL_loadstring(L, script); } public int LoadString(string script) { return luaL_loadstring(State, script); } public int DoString(string x) { LoadString(x); return PCall(0, -1); } [ThreadStatic] static IntPtr lua_StateOverride = (IntPtr)0; private IntPtr GetLuaState() { if (lua_StateOverride != IntPtr.Zero) return lua_StateOverride; if (_GetLuaState == null) _GetLuaState = Marshal.GetDelegateForFunctionPointer(sdk.pluginexports.GetLuaState); /* if (lua_State==(IntPtr)0) { lua_State = _GetLuaState(); } */ return _GetLuaState(); } public CESDKLua(CESDK sdk) { //init lua IntPtr hLibLua=LoadLibraryA("lua53-32.dll"); if (hLibLua == IntPtr.Zero) hLibLua = LoadLibraryA("lua53-64.dll"); if (hLibLua != IntPtr.Zero) { //load the most commonly used functions lua_gettop = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_gettop")); lua_settop = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_settop")); lua_pushvalue = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_pushvalue")); lua_rotate = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_rotate")); lua_copy = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_copy")); lua_pushcclosure = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_pushcclosure")); lua_setglobal = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_setglobal")); lua_getglobal = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_getglobal")); lua_pushnil = Marshal.GetDelegateForFunctionPointer (GetProcAddress(hLibLua, "lua_pushnil")); lua_pushinteger = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_pushinteger")); lua_pushnumber = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_pushnumber")); lua_pushlstring = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_pushlstring")); lua_pushstring = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_pushstring")); lua_pushboolean = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_pushboolean")); lua_type = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_type")); lua_isnumber = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_isnumber")); lua_isinteger = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_isinteger")); lua_isstring = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_isstring")); lua_iscfunction = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_iscfunction")); lua_isuserdata = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_isuserdata")); lua_tonumberx = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_tonumberx")); lua_tointegerx = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_tointegerx")); lua_toboolean = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_toboolean")); lua_tolstring = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_tolstring")); lua_touserdata = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_touserdata")); lua_rawlen = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_rawlen")); lua_gettable = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_gettable")); lua_settable = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_settable")); lua_callk = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_callk")); lua_pcallk = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "lua_pcallk")); luaL_loadstring = Marshal.GetDelegateForFunctionPointer(GetProcAddress(hLibLua, "luaL_loadstring")); } LuaRegister = Marshal.GetDelegateForFunctionPointer(sdk.pluginexports.LuaRegister); LuaPushClassInstance = Marshal.GetDelegateForFunctionPointer(sdk.pluginexports.LuaPushClassInstance); this.sdk = sdk; } } }