commit 130d77a2d390512377f2258fdfd181f28368f345 Author: mykola2312 <49044616+mykola2312@users.noreply.github.com> Date: Wed Jul 19 23:36:28 2017 +0300 Initial commit diff --git a/Release/CL.read.1.tlog b/Release/CL.read.1.tlog new file mode 100644 index 0000000..2432116 Binary files /dev/null and b/Release/CL.read.1.tlog differ diff --git a/Release/CL.write.1.tlog b/Release/CL.write.1.tlog new file mode 100644 index 0000000..b967b6c Binary files /dev/null and b/Release/CL.write.1.tlog differ diff --git a/Release/cl.command.1.tlog b/Release/cl.command.1.tlog new file mode 100644 index 0000000..d55458d Binary files /dev/null and b/Release/cl.command.1.tlog differ diff --git a/Release/gmsv_usermessages_win32.Build.CppClean.log b/Release/gmsv_usermessages_win32.Build.CppClean.log new file mode 100644 index 0000000..e39c535 --- /dev/null +++ b/Release/gmsv_usermessages_win32.Build.CppClean.log @@ -0,0 +1,22 @@ +D:\GMHax\gmsv_usermessages_win32\Release\cl.command.1.tlog +D:\GMHax\gmsv_usermessages_win32\Release\CL.read.1.tlog +D:\GMHax\gmsv_usermessages_win32\Release\CL.write.1.tlog +D:\GMHAX\GMSV_USERMESSAGES_WIN32\RELEASE\GMSV_USERMESSAGES_WIN32.DLL.INTERMEDIATE.MANIFEST +D:\GMHax\gmsv_usermessages_win32\Release\gmsv_usermessages_win32.vcxprojResolveAssemblyReference.cache +D:\GMHax\gmsv_usermessages_win32\Release\gmsv_usermessages_win32.write.1.tlog +D:\GMHax\gmsv_usermessages_win32\Release\link.command.1.tlog +D:\GMHax\gmsv_usermessages_win32\Release\link.read.1.tlog +D:\GMHax\gmsv_usermessages_win32\Release\link.write.1.tlog +D:\GMHAX\GMSV_USERMESSAGES_WIN32\RELEASE\MAIN.OBJ +D:\GMHax\gmsv_usermessages_win32\Release\mt.command.1.tlog +D:\GMHax\gmsv_usermessages_win32\Release\mt.read.1.tlog +D:\GMHax\gmsv_usermessages_win32\Release\mt.write.1.tlog +D:\GMHAX\GMSV_USERMESSAGES_WIN32\RELEASE\NEKOBUF.OBJ +D:\GMHAX\GMSV_USERMESSAGES_WIN32\RELEASE\RECIPIENTFILTER.OBJ +D:\GMHAX\GMSV_USERMESSAGES_WIN32\RELEASE\SDK.OBJ +D:\GMHAX\GMSV_USERMESSAGES_WIN32\RELEASE\STATE.OBJ +D:\GMHAX\GMSV_USERMESSAGES_WIN32\RELEASE\VC100.PDB +D:\GMHAX\RELEASE\GMSV_USERMESSAGES_WIN32.DLL +D:\GMHax\Release\gmsv_usermessages_win32.exp +D:\GMHax\Release\gmsv_usermessages_win32.lib +D:\GMHAX\RELEASE\GMSV_USERMESSAGES_WIN32.PDB diff --git a/Release/gmsv_usermessages_win32.dll.intermediate.manifest b/Release/gmsv_usermessages_win32.dll.intermediate.manifest new file mode 100644 index 0000000..ecea6f7 --- /dev/null +++ b/Release/gmsv_usermessages_win32.dll.intermediate.manifest @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Release/gmsv_usermessages_win32.lastbuildstate b/Release/gmsv_usermessages_win32.lastbuildstate new file mode 100644 index 0000000..67b41d3 --- /dev/null +++ b/Release/gmsv_usermessages_win32.lastbuildstate @@ -0,0 +1,2 @@ +#v4.0:v100:false +Release|Win32|D:\GMHax\| diff --git a/Release/gmsv_usermessages_win32.log b/Release/gmsv_usermessages_win32.log new file mode 100644 index 0000000..836a520 --- /dev/null +++ b/Release/gmsv_usermessages_win32.log @@ -0,0 +1,38 @@ +Build started 19.07.2017 18:50:06. + 1>Project "D:\GMHax\gmsv_usermessages_win32\gmsv_usermessages_win32.vcxproj" on node 2 (rebuild target(s)). + 1>_PrepareForClean: + Deleting file "Release\gmsv_usermessages_win32.lastbuildstate". + InitializeBuildStatus: + Creating "Release\gmsv_usermessages_win32.unsuccessfulbuild" because "AlwaysCreate" was specified. + ClCompile: + C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\CL.exe /c /ID:\gmbase\sdk\game\shared /ID:\gmbase\sdk\game\server /ID:\gmbase\sdk\game /ID:\gmbase\sdk\tier1 /ID:\gmbase\sdk\public\tier1 /ID:\gmbase\sdk\public\tier0 /ID:\gmbase\sdk\public\ /ID:\gmbase\sdk\ /Zi /nologo /W3 /WX- /O2 /Oi /Oy- /GL /D _WINDLL /D _MBCS /Gm- /EHsc /MD /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Fo"Release\\" /Fd"Release\vc100.pdb" /Gd /TP /analyze- /errorReport:prompt main.cpp nekobuf.cpp recipientfilter.cpp sdk.cpp state.cpp + main.cpp + nekobuf.cpp + recipientfilter.cpp + sdk.cpp + state.cpp + 1>state.cpp(116): warning C4996: 'vsnprintf': This function or variable may be unsafe. Consider using vsnprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. + C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\stdio.h(354): см. объявление "vsnprintf" + 1>state.cpp(140): warning C4800: int: принудительно задано логическое значение "true" или "false" (предупреждение о производительности) + 1>state.cpp(330): warning C4996: '_snprintf': This function or variable may be unsafe. Consider using _snprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. + C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\stdio.h(363): см. объявление "_snprintf" + Link: + C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\link.exe /ERRORREPORT:PROMPT /OUT:"D:\GMHax\Release\gmsv_usermessages_win32.dll" /NOLOGO /LIBPATH:D:\gmbase\sdk\lib\public /LIBPATH:D:\gmbase\sdk\lib\common /LIBPATH:D:\gmbase\sdk\lib\ tier0.lib tier1.lib Psapi.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NODEFAULTLIB:LIBCMT.lib /MANIFEST /ManifestFile:"Release\gmsv_usermessages_win32.dll.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"D:\GMHax\Release\gmsv_usermessages_win32.pdb" /OPT:REF /OPT:ICF /LTCG /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"D:\GMHax\Release\gmsv_usermessages_win32.lib" /MACHINE:X86 /DLL Release\main.obj + Release\nekobuf.obj + Release\recipientfilter.obj + Release\sdk.obj + Release\state.obj + Создается библиотека D:\GMHax\Release\gmsv_usermessages_win32.lib и объект D:\GMHax\Release\gmsv_usermessages_win32.exp + Создание кода + Создание кода завершено + gmsv_usermessages_win32.vcxproj -> D:\GMHax\Release\gmsv_usermessages_win32.dll + Manifest: + C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\mt.exe /nologo /verbose /outputresource:"D:\GMHax\Release\gmsv_usermessages_win32.dll;#2" /manifest Release\gmsv_usermessages_win32.dll.intermediate.manifest + FinalizeBuildStatus: + Deleting file "Release\gmsv_usermessages_win32.unsuccessfulbuild". + Touching "Release\gmsv_usermessages_win32.lastbuildstate". + 1>Done Building Project "D:\GMHax\gmsv_usermessages_win32\gmsv_usermessages_win32.vcxproj" (rebuild target(s)). + +Построение успешно завершено. + +Time Elapsed 00:00:20.87 diff --git a/Release/gmsv_usermessages_win32.write.1.tlog b/Release/gmsv_usermessages_win32.write.1.tlog new file mode 100644 index 0000000..bc0e36b --- /dev/null +++ b/Release/gmsv_usermessages_win32.write.1.tlog @@ -0,0 +1,5 @@ +^D:\GMHax\gmsv_usermessages_win32\gmsv_usermessages_win32.vcxproj +D:\GMHax\Release\gmsv_usermessages_win32.lib +D:\GMHax\Release\gmsv_usermessages_win32.lib +D:\GMHax\Release\gmsv_usermessages_win32.exp +D:\GMHax\Release\gmsv_usermessages_win32.exp diff --git a/Release/link.command.1.tlog b/Release/link.command.1.tlog new file mode 100644 index 0000000..6b11d64 Binary files /dev/null and b/Release/link.command.1.tlog differ diff --git a/Release/link.read.1.tlog b/Release/link.read.1.tlog new file mode 100644 index 0000000..9c18521 Binary files /dev/null and b/Release/link.read.1.tlog differ diff --git a/Release/link.write.1.tlog b/Release/link.write.1.tlog new file mode 100644 index 0000000..cc3c7d3 Binary files /dev/null and b/Release/link.write.1.tlog differ diff --git a/Release/main.obj b/Release/main.obj new file mode 100644 index 0000000..51d0dc5 Binary files /dev/null and b/Release/main.obj differ diff --git a/Release/mt.command.1.tlog b/Release/mt.command.1.tlog new file mode 100644 index 0000000..7657e72 Binary files /dev/null and b/Release/mt.command.1.tlog differ diff --git a/Release/mt.read.1.tlog b/Release/mt.read.1.tlog new file mode 100644 index 0000000..3114032 Binary files /dev/null and b/Release/mt.read.1.tlog differ diff --git a/Release/mt.write.1.tlog b/Release/mt.write.1.tlog new file mode 100644 index 0000000..0f0b733 Binary files /dev/null and b/Release/mt.write.1.tlog differ diff --git a/Release/nekobuf.obj b/Release/nekobuf.obj new file mode 100644 index 0000000..f2a2940 Binary files /dev/null and b/Release/nekobuf.obj differ diff --git a/Release/recipientfilter.obj b/Release/recipientfilter.obj new file mode 100644 index 0000000..60060e0 Binary files /dev/null and b/Release/recipientfilter.obj differ diff --git a/Release/sdk.obj b/Release/sdk.obj new file mode 100644 index 0000000..f71dc07 Binary files /dev/null and b/Release/sdk.obj differ diff --git a/Release/state.obj b/Release/state.obj new file mode 100644 index 0000000..5bfac6c Binary files /dev/null and b/Release/state.obj differ diff --git a/Release/vc100.pdb b/Release/vc100.pdb new file mode 100644 index 0000000..26c275c Binary files /dev/null and b/Release/vc100.pdb differ diff --git a/gmsv_usermessages_win32.vcxproj b/gmsv_usermessages_win32.vcxproj new file mode 100644 index 0000000..1ead47f --- /dev/null +++ b/gmsv_usermessages_win32.vcxproj @@ -0,0 +1,84 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {95E2986B-FE2F-4CE2-8014-821A91E10E68} + gmsv_usermessages_win32 + + + + Application + true + MultiByte + + + DynamicLibrary + false + true + MultiByte + + + + + + + + + + + + + + + Level3 + Disabled + + + true + + + + + Level3 + MaxSpeed + true + true + D:\gmbase\sdk\game\shared;D:\gmbase\sdk\game\server;D:\gmbase\sdk\game;D:\gmbase\sdk\tier1;D:\gmbase\sdk\public\tier1;D:\gmbase\sdk\public\tier0;D:\gmbase\sdk\public\;D:\gmbase\sdk\;%(AdditionalIncludeDirectories) + + + true + true + true + D:\gmbase\sdk\lib\public;D:\gmbase\sdk\lib\common;D:\gmbase\sdk\lib\;%(AdditionalLibraryDirectories) + tier0.lib;tier1.lib;Psapi.lib;%(AdditionalDependencies) + LIBCMT.lib;%(IgnoreSpecificDefaultLibraries) + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gmsv_usermessages_win32.vcxproj.filters b/gmsv_usermessages_win32.vcxproj.filters new file mode 100644 index 0000000..0f0046d --- /dev/null +++ b/gmsv_usermessages_win32.vcxproj.filters @@ -0,0 +1,54 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Файлы исходного кода + + + Файлы исходного кода + + + Файлы исходного кода + + + Файлы исходного кода + + + Файлы исходного кода + + + + + Заголовочные файлы + + + Заголовочные файлы + + + Заголовочные файлы + + + Заголовочные файлы + + + Заголовочные файлы + + + Заголовочные файлы + + + \ No newline at end of file diff --git a/gmsv_usermessages_win32.vcxproj.user b/gmsv_usermessages_win32.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/gmsv_usermessages_win32.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/interface.h b/interface.h new file mode 100644 index 0000000..9b1b656 --- /dev/null +++ b/interface.h @@ -0,0 +1,37 @@ +#ifndef __INTERFACE_H +#define __INTERFACE_H + +#include "lua.h" +#include "state.h" + +class CLuaInterface; + +class CLuaShared +{ +public: + void** vtable; + char tmp[88]; + CLuaInterface* m_pClient; + CLuaInterface* m_pServer; + CLuaInterface* m_pMenu; +}; + +class CLuaInterface +{ +public: + void** vtable; + CLuaState* m_pState; +}; + +#ifndef DLL_EXPORT +#if defined(__GCC__) +#define DLL_EXPORT __attribute__((dllexport)) +#elif defined (_MSC_VER) +#define DLL_EXPORT __declspec(dllexport) +#endif +#endif + +#define GMOD_MODULE_OPEN() extern "C" DLL_EXPORT int gmod13_open(CLuaState* L) +#define GMOD_MODULE_CLOSE() extern "C" DLL_EXPORT int gmod13_close(CLuaState* L) + +#endif \ No newline at end of file diff --git a/lua.h b/lua.h new file mode 100644 index 0000000..fafb160 --- /dev/null +++ b/lua.h @@ -0,0 +1,87 @@ +#ifndef __LUA_H +#define __LUA_H + +#include +#include +#include + +#define LUA_REGISTRYINDEX (-10000) +#define LUA_ENVIRONINDEX (-10001) +#define LUA_GLOBALSINDEX (-10002) + +class CLuaState; +typedef int (*CLuaFunction)(CLuaState*); + +typedef int (*lua_type) (CLuaState *L, int idx); +typedef const char *(*lua_typename) (CLuaState *L, int tp); + +typedef int (*lua_gettop) (CLuaState *L); +typedef void (*lua_settop) (CLuaState *L, int idx); +typedef void (*lua_pushvalue) (CLuaState *L, int idx); + +typedef double (*lua_tonumber) (CLuaState *L, int idx); +typedef int (*lua_toboolean) (CLuaState *L, int idx); +typedef const char *(*lua_tolstring) (CLuaState *L, int idx, size_t *len); +typedef CLuaFunction (*lua_tocfunction) (CLuaState *L, int idx); +typedef void *(*lua_touserdata) (CLuaState *L, int idx); +typedef CLuaState *(*lua_tothread) (CLuaState *L, int idx); +typedef const void *(*lua_topointer) (CLuaState *L, int idx); + +typedef void (*lua_pushnil) (CLuaState *L); +typedef void (*lua_pushnumber) (CLuaState *L, double n); +typedef void (*lua_pushlstring) (CLuaState *L, const char *s, size_t l); +typedef void (*lua_pushcclosure) (CLuaState *L, CLuaFunction fn, int n); +typedef void (*lua_pushboolean) (CLuaState *L, int b); +typedef void (*lua_pushlightuserdata) (CLuaState *L, void *p); +typedef int (*lua_pushthread) (CLuaState *L); + +typedef void (*lua_gettable) (CLuaState *L, int idx); +typedef void (*lua_getfield) (CLuaState *L, int idx, const char *k); +typedef void (*lua_rawget) (CLuaState *L, int idx); +typedef void (*lua_rawgeti) (CLuaState *L, int idx, int n); +typedef void (*lua_createtable) (CLuaState *L, int narr, int nrec); +typedef void *(*lua_newuserdata) (CLuaState *L, size_t sz); +typedef int (*lua_getmetatable) (CLuaState *L, int objindex); +typedef void (*lua_getfenv) (CLuaState *L, int idx); + +typedef void (*lua_settable) (CLuaState *L, int idx); +typedef void (*lua_setfield) (CLuaState *L, int idx, const char *k); +typedef void (*lua_rawset) (CLuaState *L, int idx); +typedef void (*lua_rawseti) (CLuaState *L, int idx, int n); +typedef int (*lua_setmetatable) (CLuaState *L, int objindex); +typedef int (*lua_setfenv) (CLuaState *L, int idx); + +typedef void (*lua_call) (CLuaState *L, int nargs, int nresults); +typedef int (*lua_pcall) (CLuaState *L, int nargs, int nresults, int errfunc); + +typedef int (*luaL_loadbufferx)(CLuaState *L, const char *buff, + size_t sz,const char *name,const char* mode); +typedef int (*luaL_newmetatable) (CLuaState *L, const char *tname); +typedef void (*luaL_checktype) (CLuaState *L, int narg, int t); +typedef size_t (*lua_objlen) (CLuaState *L, int idx); +typedef void (*lua_pushinteger)(CLuaState *L, int n); +typedef int (*lua_tointeger)(CLuaState* L,int idx); + +typedef enum { + OK = 0, + YIELD, + ERRRUN, + ERRSYNTAX, + ERRMEM, + ERRERR +} ret_t; + +typedef enum { + NONE = -1, + NIL, + TBOOLEAN, + LIGHTUSERDATA, + NUMBER, + STRING, + TABLE, + FUNCTION, + USERDATA, + THREAD, +} luatype_t; + +#endif \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..7b1a9e1 --- /dev/null +++ b/main.cpp @@ -0,0 +1,136 @@ +#define GAME_DLL +#include +#include "cbase.h" +#include "interface.h" +#include "state.h" +#include "lua.h" +#include "sdk.h" +#include "recipientfilter.h" +#include "nekobuf.h" + +IVEngineServer* g_pEngine = NULL; +CLocalUserMessages* g_pLocalUserMessages; +DWORD dwRecipientVTable; + +int LookupUserMessage(CLuaState* L) +{ + L->CheckType(1,STRING); + L->PushInteger(g_pLocalUserMessages->LookupUserMessage(L->GetString(1))); + return 1; +} + +int GetUserMessages(CLuaState* L) +{ + usermessage_t* umsg; + + L->CreateTable(); + for(int i = 0; i < g_pLocalUserMessages->GetTotal(); i++) + { + umsg = g_pLocalUserMessages->GetUserMessage(i); + if(!umsg || !g_pLocalUserMessages->IsValidIndex(i)) + continue; + L->PushInteger(i); + L->CreateTable(); + + L->PushString(g_pLocalUserMessages->GetUserMessageName(i)); + L->SetField(-2,"name"); + + L->PushInteger(umsg->size); + L->SetField(-2,"size"); + + L->SetTable(-3); + } + return 1; +} + +int GetUserMessageName(CLuaState* L) +{ + L->CheckType(1,NUMBER); + L->PushString(g_pLocalUserMessages->GetUserMessageName(L->GetInteger(1))); + return 1; +} + +int GetTotal(CLuaState* L) +{ + L->PushInteger(g_pLocalUserMessages->GetTotal()); + return 1; +} + +int UserMessageBegin(CLuaState* L) +{ + CLocalRecipientFilter* filter = RecipientFilter_Check(L,1); + bf_write* buf; + L->CheckType(2,NUMBER); + if(!filter) L->PushNil(); + else + { + buf = g_pEngine->UserMessageBegin((IRecipientFilter*)filter,L->GetInteger(2)); + NekoBuf_Create(L,buf); + } + return 1; +} + +int MessageEnd(CLuaState* L) +{ + g_pEngine->MessageEnd(); + return 0; +} + +GMOD_MODULE_OPEN() +{ + HMODULE hServer,hEngine; + CreateInterfaceFn EngineFactory; + if(!(hServer = GetModuleHandle("server.dll")) + || !(hEngine = GetModuleHandle("engine.dll"))) + return 1; + if(!(EngineFactory = (CreateInterfaceFn)GetProcAddress(hEngine,"CreateInterface"))) + return 2; + if(!(g_pEngine = (IVEngineServer*)EngineFactory("VEngineServer021",NULL))) + return 3; + + DWORD dwAwardAchievement = FindPattern(hServer,AWARDACHIEVEMENT_SIG, + AWARDACHIEVEMENT_MASK); + dwRecipientVTable = *(PDWORD)((char*)dwAwardAchievement+AWARDACHIEVEMENT_OFFSET); + + Msg("dwAwardAchievement %p dwRecipientVTable %p\n",dwAwardAchievement,dwRecipientVTable); + + DWORD dwUserMessageBegin = FindPattern(hServer,USERMESSAGEBEGIN_SIG, + USERMESSAGEBEGIN_MASK); + g_pLocalUserMessages = *(CLocalUserMessages**)((char*)dwUserMessageBegin+USERMESSAGEBEGIN_OFFSET); + + Msg("dwUserMessageBegin %p g_pLocalUserMessages %p\n",dwUserMessageBegin,g_pLocalUserMessages); + + L->CreateTable(); + L->PushCFunction(LookupUserMessage); + L->SetField(-2,"LookupUserMessage"); + + L->PushCFunction(GetUserMessages); + L->SetField(-2,"GetUserMessages"); + + L->PushCFunction(GetUserMessageName); + L->SetField(-2,"GetUserMessageName"); + + L->PushCFunction(GetTotal); + L->SetField(-2,"GetTotal"); + + L->PushCFunction(UserMessageBegin); + L->SetField(-2,"UserMessageBegin"); + + L->PushCFunction(MessageEnd); + L->SetField(-2,"MessageEnd"); + + L->SetGlobal("usermessages"); + + RecipientFilter_Open(L); + NekoBuf_Open(L); + return 0; +} + +GMOD_MODULE_CLOSE() +{ + L->PushNil(); + L->SetGlobal("usermessages"); + RecipientFilter_Close(L); + NekoBuf_Close(L); + return 0; +} \ No newline at end of file diff --git a/nekobuf.cpp b/nekobuf.cpp new file mode 100644 index 0000000..79c6534 --- /dev/null +++ b/nekobuf.cpp @@ -0,0 +1,248 @@ +#include "nekobuf.h" + +static int ud_type = 253; +static char* ud_name = "NekoBuf"; + +void NekoBuf_Create(CLuaState* L,bf_write* buf) +{ + userdata_t* ud = L->NewUserData(); + + ud->data = buf; + ud->type = ud_type; + + L->GetMetaFromRegistry(ud_name); + L->SetMetaTable(-2); +} + +bf_write* NekoBuf_Check(CLuaState* L,int idx) +{ + userdata_t* ud = L->GetUserData(idx); + if(ud->type==ud_type) + return (bf_write*)ud->data; + return NULL; +} + +void* MetaCheck(CLuaState* L,int idx,int type) +{ + userdata_t* ud = L->GetUserData(idx); + if(ud->type==type) + return ud->data; + return NULL; +} + +int NekoBuf_tostring(CLuaState* L) +{ + L->PushFString("%s: %p",ud_name,NekoBuf_Check(L,1)); + return 1; +} + +int NekoBuf_eq(CLuaState* L) +{ + L->PushBool((NekoBuf_Check(L,1) == NekoBuf_Check(L,2))); + return 1; +} + +int NekoBuf_gc(CLuaState* L) +{ + return 0; +} + +int NekoBuf_WriteByte(CLuaState* L) +{ + bf_write* buf = NekoBuf_Check(L,1); + L->CheckType(2,NUMBER); + buf->WriteByte(L->GetInteger(2) & 0xFF); + return 0; +} + +int NekoBuf_WriteChar(CLuaState* L) +{ + bf_write* buf = NekoBuf_Check(L,1); + L->CheckType(2,NUMBER); + buf->WriteChar(L->GetInteger(2) & 0xFF); + return 0; +} + +int NekoBuf_WriteShort(CLuaState* L) +{ + bf_write* buf = NekoBuf_Check(L,1); + L->CheckType(2,NUMBER); + buf->WriteShort(L->GetInteger(2) & 0xFFFF); + return 0; +} + +int NekoBuf_WriteWord(CLuaState* L) +{ + bf_write* buf = NekoBuf_Check(L,1); + L->CheckType(2,NUMBER); + buf->WriteWord(L->GetInteger(2)); + return 0; +} + +int NekoBuf_WriteLong(CLuaState* L) +{ + bf_write* buf = NekoBuf_Check(L,1); + L->CheckType(2,NUMBER); + buf->WriteLong(L->GetInteger(2)); + return 0; +} + +int NekoBuf_WriteFloat(CLuaState* L) +{ + bf_write* buf = NekoBuf_Check(L,1); + L->CheckType(2,NUMBER); + buf->WriteFloat((float)L->GetNumber(2)); + return 0; +} + +int NekoBuf_WriteAngle(CLuaState* L) +{ + bf_write* buf = NekoBuf_Check(L,1); + L->CheckType(2,NUMBER); + L->CheckType(3,NUMBER); + buf->WriteBitAngle((float)L->GetNumber(2),L->GetInteger(3)); + return 0; +} + +int NekoBuf_WriteAngles(CLuaState* L) +{ + bf_write* buf = NekoBuf_Check(L,1); + QAngle* ang = (QAngle*)MetaCheck(L,2,11); //Angle + if(ang) + buf->WriteBitAngles((const QAngle&)ang); + return 0; +} + +int NekoBuf_WriteCoord(CLuaState* L) +{ + bf_write* buf = NekoBuf_Check(L,1); + L->CheckType(2,NUMBER); + buf->WriteBitCoord((float)L->GetNumber(2)); + return 0; +} + +int NekoBuf_WriteVec3Coord(CLuaState* L) +{ + bf_write* buf = NekoBuf_Check(L,1); + Vector* vec = (Vector*)MetaCheck(L,2,12); //Vector + if(vec) + buf->WriteBitVec3Coord((const Vector&)vec); + return 0; +} + +int NekoBuf_WriteVec3Normal(CLuaState* L) +{ + bf_write* buf = NekoBuf_Check(L,1); + Vector* vec = (Vector*)MetaCheck(L,2,12); //Vector + if(vec) + buf->WriteBitVec3Normal((const Vector&)vec); + return 0; +} + +int NekoBuf_WriteString(CLuaState* L) +{ + bf_write* buf = NekoBuf_Check(L,1); + L->CheckType(2,STRING); + buf->WriteString(L->GetString(2)); + return 0; +} + +int NekoBuf_WriteEHandle(CLuaState* L) +{ + bf_write* buf = NekoBuf_Check(L,1); + CBasePlayer* pEntity = GetEntityByLuaEntity(L,2); + CBaseHandle hEntity; + long EncodedEHandle; + + if(pEntity) + { + hEntity = pEntity->GetRefEHandle(); + int iSerialNum = (hEntity.m_Index >> NUM_ENT_ENTRY_BITS) + & ( (1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS) - 1 ); + EncodedEHandle = (hEntity.m_Index & ENT_ENTRY_MASK) | (iSerialNum << MAX_EDICT_BITS); + } + else EncodedEHandle = INVALID_NETWORKED_EHANDLE_VALUE; + + buf->WriteLong(EncodedEHandle); + return 0; +} + +int NekoBuf_WriteBool(CLuaState* L) +{ + bf_write* buf = NekoBuf_Check(L,1); + L->CheckType(2,TBOOLEAN); + buf->WriteOneBit(L->GetBool(2) ? 1 : 0); + return 0; +} + +int NekoBuf_WriteUBitLong(CLuaState* L) +{ + bf_write* buf = NekoBuf_Check(L,1); + L->CheckType(2,NUMBER); + L->CheckType(3,NUMBER); + buf->WriteUBitLong(L->GetInteger(2),L->GetInteger(3)); + return 0; +} + +int NekoBuf_WriteSBitLong(CLuaState* L) +{ + bf_write* buf = NekoBuf_Check(L,1); + L->CheckType(2,NUMBER); + L->CheckType(3,NUMBER); + buf->WriteSBitLong(L->GetInteger(2),L->GetInteger(3)); + return 0; +} + +int NekoBuf_WriteBits(CLuaState* L) +{ + bf_write* buf = NekoBuf_Check(L,1); + L->CheckType(2,STRING); + L->CheckType(3,NUMBER); + buf->WriteBits(L->GetString(2),L->GetInteger(3)); + return 0; +} + +#define REG_FUNC(n) \ + L->PushCFunction(NekoBuf_##n); \ + L->SetField(-2,#n) + +void NekoBuf_Open(CLuaState* L) +{ + L->CreateMetaTable(ud_name); + + L->PushCFunction(NekoBuf_tostring); + L->SetField(-2,"__tostring"); + + L->PushCFunction(NekoBuf_eq); + L->SetField(-2,"__eq"); + + L->PushCFunction(NekoBuf_gc); + L->SetField(-2,"__gc"); + + REG_FUNC(WriteByte); + REG_FUNC(WriteChar); + REG_FUNC(WriteShort); + REG_FUNC(WriteWord); + REG_FUNC(WriteLong); + REG_FUNC(WriteFloat); + REG_FUNC(WriteAngle); + REG_FUNC(WriteAngles); + REG_FUNC(WriteCoord); + REG_FUNC(WriteVec3Coord); + REG_FUNC(WriteVec3Normal); + REG_FUNC(WriteString); + L->PushCFunction(NekoBuf_WriteShort); + L->SetField(-2,"WriteEntity"); + REG_FUNC(WriteEHandle); + REG_FUNC(WriteBool); + REG_FUNC(WriteUBitLong); + REG_FUNC(WriteSBitLong); + REG_FUNC(WriteBits); + + L->Push(-1); + L->SetField(-2,"__index"); +} + +void NekoBuf_Close(CLuaState* L) +{ +} \ No newline at end of file diff --git a/nekobuf.h b/nekobuf.h new file mode 100644 index 0000000..ced6960 --- /dev/null +++ b/nekobuf.h @@ -0,0 +1,16 @@ +#ifndef __NEKOBUF_H +#define __NEKOBUF_H + +#define GAME_DLL +#include "lua.h" +#include "sdk.h" +#include "state.h" +#include "cbase.h" +#include "bitbuf.h" + +void NekoBuf_Open(CLuaState* L); +void NekoBuf_Close(CLuaState* L); + +void NekoBuf_Create(CLuaState* L,bf_write* buf); + +#endif \ No newline at end of file diff --git a/recipientfilter.cpp b/recipientfilter.cpp new file mode 100644 index 0000000..121845a --- /dev/null +++ b/recipientfilter.cpp @@ -0,0 +1,116 @@ +#include "recipientfilter.h" + +static int ud_type = 254; //RECIPIENTFILTER +static char* ud_name = "RecipientFilter"; + +int RecipientFilter_Create(CLuaState* L) +{ + userdata_t* ud = L->NewUserData(); + + ud->data = new CLocalRecipientFilter; + ud->type = ud_type; + + L->GetMetaFromRegistry(ud_name); + L->SetMetaTable(-2); + + return 1; +} + +CLocalRecipientFilter* RecipientFilter_Check(CLuaState* L,int idx) +{ + userdata_t* ud = L->GetUserData(idx); + if(ud->type==ud_type) + return (CLocalRecipientFilter*)ud->data; + return NULL; +} + +int RecipientFilter_tostring(CLuaState* L) +{ + L->PushFString("%s: %p",ud_name,RecipientFilter_Check(L,1)); + return 1; +} + +int RecipientFilter_eq(CLuaState* L) +{ + L->PushBool((RecipientFilter_Check(L,1) == RecipientFilter_Check(L,2))); + return 1; +} + +int RecipientFilter_gc(CLuaState* L) +{ + CLocalRecipientFilter* v1; + if((v1 = RecipientFilter_Check(L,1))) + delete v1; + return 0; +} + +int RecipientFilter_MakeReliable(CLuaState* L) +{ + RecipientFilter_Check(L,1)->MakeReliable(); + return 0; +} + +int RecipientFilter_AddRecipient(CLuaState* L) +{ + CBasePlayer* pPlayer = GetEntityByLuaEntity(L,2); + if(pPlayer) + RecipientFilter_Check(L,1)->AddRecipient(pPlayer); + return 0; +} + +int RecipientFilter_Reset(CLuaState* L) +{ + RecipientFilter_Check(L,1)->Reset(); + return 0; +} + +int RecipientFilter_Free(CLuaState* L) +{ + userdata_t* ud = L->GetUserData(1); + if(ud->data) + { + delete (CLocalRecipientFilter*)ud->data; + ud->data = NULL; + } + return 0; +} + +void RecipientFilter_Open(CLuaState* L) +{ + L->CreateTable(); + L->PushCFunction(RecipientFilter_Create); + L->SetField(-2,"Create"); + L->SetGlobal("recipientfilter"); + + L->CreateMetaTable(ud_name); + + L->PushCFunction(RecipientFilter_tostring); + L->SetField(-2,"__tostring"); + + L->PushCFunction(RecipientFilter_eq); + L->SetField(-2,"__eq"); + + L->PushCFunction(RecipientFilter_gc); + L->SetField(-2,"__gc"); + + L->PushCFunction(RecipientFilter_MakeReliable); + L->SetField(-2,"MakeReliable"); + + L->PushCFunction(RecipientFilter_AddRecipient); + L->SetField(-2,"AddRecipient"); + + L->PushCFunction(RecipientFilter_Reset); + L->SetField(-2,"Reset"); + + L->PushCFunction(RecipientFilter_Free); + L->SetField(-2,"Free"); + + L->Push(-1); + L->SetField(-2,"__index"); +} + +void RecipientFilter_Close(CLuaState* L) +{ + L->PushNil(); + L->SetGlobal("recipientfilter"); +} \ No newline at end of file diff --git a/recipientfilter.h b/recipientfilter.h new file mode 100644 index 0000000..9eccf45 --- /dev/null +++ b/recipientfilter.h @@ -0,0 +1,14 @@ +#ifndef __RECIPIENTFILTER_H +#define __RECIPIENTFILTER_H + +#include "state.h" +#include "lua.h" +#include "sdk.h" + +void RecipientFilter_Open(CLuaState* L); +void RecipientFilter_Close(CLuaState* L); + +int RecipientFilter_Create(CLuaState* L); +CLocalRecipientFilter* RecipientFilter_Check(CLuaState* L,int idx); + +#endif \ No newline at end of file diff --git a/sdk.cpp b/sdk.cpp new file mode 100644 index 0000000..c7d31c3 --- /dev/null +++ b/sdk.cpp @@ -0,0 +1,86 @@ +#include "sdk.h" + +extern DWORD dwRecipientVTable; +extern IVEngineServer* g_pEngine; + +DWORD FindPattern(HMODULE hDll, char* pattern, char* mask) +{ + MODULEINFO mInfo; + GetModuleInformation(GetCurrentProcess(),hDll,&mInfo,sizeof(MODULEINFO)); + + DWORD base = (DWORD)hDll; + DWORD size = (DWORD)mInfo.SizeOfImage; + + DWORD patternLength = (DWORD)strlen(mask); + for(DWORD i = 0; i < size - patternLength; i++) + { + bool found = true; + for(DWORD j = 0; j < patternLength; j++) + found &= mask[j] == '?' || pattern[j] == *(char*)(base+i+j); + if(found) + return base+i; + } + return NULL; +} + +CBasePlayer* GetEntityByLuaEntity(CLuaState* L,int idx) +{ + int ret; + edict_t* pEdict; + + L->Push(idx); + L->GetField(-1,"EntIndex"); + L->Push(-2); + L->Call(1,1); + ret = L->GetInteger(-1); + L->Pop(2); + + if(!(pEdict = g_pEngine->PEntityOfEntIndex(ret))) + return NULL; + else if(pEdict->IsFree()) + return NULL; + return (CBasePlayer*)(pEdict->GetUnknown()->GetBaseEntity()); +} + +CLocalRecipientFilter::CLocalRecipientFilter() +{ + dwVTable = dwRecipientVTable; + Reset(); +} + +CLocalRecipientFilter::~CLocalRecipientFilter() +{ +} + +void CLocalRecipientFilter::Reset() +{ + m_bReliable = false; + m_bInitMessage = false; + m_bUsingPredictionRules = false; + m_bIgnorePredictionCull = false; + m_Recipients.RemoveAll(); +} + +void CLocalRecipientFilter::AddRecipient(const CBasePlayer* pPlayer) +{ + int idx = pPlayer->entindex(); + if(m_Recipients.Find(idx)!=m_Recipients.InvalidIndex()) + return; + m_Recipients.AddToTail(idx); +} + +CLocalUserMessages::CLocalUserMessages() +{ +} + +CLocalUserMessages::~CLocalUserMessages() +{ +} + +int CLocalUserMessages::LookupUserMessage(const char* name) +{ + int idx; + if((idx = m_UserMessages.Find(name))!=m_UserMessages.InvalidIndex()) + return idx; + return -1; +} \ No newline at end of file diff --git a/sdk.h b/sdk.h new file mode 100644 index 0000000..3419150 --- /dev/null +++ b/sdk.h @@ -0,0 +1,99 @@ +#ifndef __SDK_H +#define __SDK_H + +#define GAME_DLL +#include +#include +#include "utlvector.h" +#include "utldict.h" +#include "cbase.h" + +//Used to retrieve recipient vtable +//#define AWARDACHIEVEMENT_SIG "\x55\x8B\xEC\x83\xEC\x20\x56\x8B\xF1\x8D\x4D\xE0\xE8\x00\x00\x00\x00\x56\x8D\x4D\xE0\xC7\x45\x00\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x8D\x45\xE0\x68\x00\x00\x00\x00\x50\xE8\x00\x00\x00\x00\x8B\x4D\x08\x51\xE8\x00\x00\x00\x00\x8B\x55\x0C\x52\xE8\x00\x00\x00\x00\x83\xC4\x10\xE8\x00\x00\x00\x00\x8D\x4D\xE0\xE8\x00\x00\x00\x00\x5E\x8B\xE5\x5D\xC2\x08\x00" +//#define AWARDACHIEVEMENT_MASK "xxxxxxxxxxxxx????xxxxxx?????x????xxxx????xx????xxxxx????xxxxx????xxxx????xxxx????xxxxxxx" +#define AWARDACHIEVEMENT_SIG "\x55\x8B\xEC\x83\xEC\x20\x56\x8B\xF1\x8D\x4D\xE0\xE8\x00\x00\x00\x00\x56\x8D\x4D\xE0\xC7\x45\x00\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x8D\x45\xE0\x68\x00\x00\x00\x00\x50\xE8\x00\x00\x00\x00\xFF\x75\x08\xE8\x00\x00\x00\x00\xFF\x75\x0C\xE8\x00\x00\x00\x00\x83\xC4\x10\xE8\x00\x00\x00\x00\x8D\x4D\xE0\xE8\x00\x00\x00\x00\x5E\x8B\xE5\x5D\xC2\x08\x00" +#define AWARDACHIEVEMENT_MASK "xxxxxxxxxxxxx????xxxxxx?????x????xxxx????xx????xxxx????xxxx????xxxx????xxxx????xxxxxxx" +#define AWARDACHIEVEMENT_OFFSET 0x18 + +//#define USERMESSAGEBEGIN_SIG "\x55\x8B\xEC\x8B\x0D\x00\x00\x00\x00\x56\x8B\x75\x0C\x56\xE8\x00\x00\x00\x00\x83\xF8\xFF\x75\x0C\x56\x68\x00\x00\x00\x00\xFF\x15\x00\x00\x00\x00\x8B\x0D\x00\x00\x00\x00\x8B\x11\x8B\x92\x00\x00\x00\x00\x50\x8B\x45\x08\x50\xFF\xD2\xA3\x00\x00\x00\x00\x5E\x5D\xC3" +//#define USERMESSAGEBEGIN_MASK "xxxxx????xxxxxx????xxxxxxx????xx????xx????xxxx????xxxxxxxx????xxx" +//#define USERMESSAGEBEGIN_OFFSET 0x5 +#define USERMESSAGEBEGIN_SIG "\x55\x8B\xEC\xFF\x75\x0C\x8B\x0D\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x8B\xD0\x83\xFA\xFF\x75\x0E\xFF\x75\x0C\x68\x00\x00\x00\x00\xFF\x15\x00\x00\x00\x00\x8B\x0D\x00\x00\x00\x00\x52\xFF\x75\x08\x8B\x01\xFF\x90\x00\x00\x00\x00\xA3\x00\x00\x00\x00\x5D\xC3" +#define USERMESSAGEBEGIN_MASK "xxxxxxxx????x????xxxxxxxxxxx????xx????xx????xxxxxxxx????x????xx" +#define USERMESSAGEBEGIN_OFFSET 0x8 + +class CLocalRecipientFilter +{ +public: + CLocalRecipientFilter(); + ~CLocalRecipientFilter(); + + void Reset(); + inline void MakeReliable(); + void AddRecipient(const CBasePlayer* pPlayer); +private: + DWORD dwVTable; + bool m_bReliable; + bool m_bInitMessage; + CUtlVector m_Recipients; + bool m_bUsingPredictionRules; + bool m_bIgnorePredictionCull; +}; + +void CLocalRecipientFilter::MakeReliable() +{ + m_bReliable = true; +} + +typedef void (*UserMsgCallback_t)(bf_read&); + +typedef struct { + int size; + const char* name; + CUtlVector clienthooks; +} usermessage_t; + +class CLocalUserMessages +{ +public: + CLocalUserMessages(); + ~CLocalUserMessages(); + + int LookupUserMessage(const char* name); + inline usermessage_t* GetUserMessage(int idx); + inline const char* GetUserMessageName(int idx); + inline int GetTotal(); + inline bool IsValidIndex(int idx); +private: + DWORD dwVTable; + CUtlDict m_UserMessages; +}; + +usermessage_t* CLocalUserMessages::GetUserMessage(int idx) +{ + if(idx>=0&&idx=0&&idx"; +} + +bool CLocalUserMessages::IsValidIndex(int idx) +{ + return m_UserMessages.IsValidIndex(idx); +} + +DWORD FindPattern(HMODULE hDll, char* pattern, char* mask); +CBasePlayer* GetEntityByLuaEntity(CLuaState* L,int idx); + +#endif \ No newline at end of file diff --git a/state.cpp b/state.cpp new file mode 100644 index 0000000..651dad8 --- /dev/null +++ b/state.cpp @@ -0,0 +1,343 @@ +#include "state.h" + +func_t lua_api[] = { + {"lua_gettop",NULL}, //0 + {"lua_settop",NULL}, //1 + {"lua_pushvalue",NULL}, //2 + {"lua_tonumber",NULL}, //3 + {"lua_toboolean",NULL}, //4 + {"lua_tolstring",NULL}, //5 + {"lua_tocfunction",NULL}, //6 + {"lua_touserdata",NULL}, //7 + {"lua_tothread",NULL}, //8 + {"lua_topointer",NULL}, //9 + {"lua_pushnil",NULL}, //10 + {"lua_pushnumber",NULL}, //11 + {"lua_pushlstring",NULL}, //12 + {"lua_pushcclosure",NULL}, //13 + {"lua_pushboolean",NULL}, //14 + {"lua_pushlightuserdata",NULL}, //15 + {"lua_pushthread",NULL}, //16 + {"lua_gettable",NULL}, //17 + {"lua_getfield",NULL}, //18 + {"lua_rawget",NULL}, //19 + {"lua_rawgeti",NULL}, //20 + {"lua_createtable",NULL}, //21 + {"lua_getmetatable",NULL}, //22 + {"lua_newuserdata",NULL}, //23 + {"lua_getfenv",NULL}, //24 + {"lua_settable",NULL}, //25 + {"lua_setfield",NULL}, //26 + {"lua_rawset",NULL}, //27 + {"lua_rawseti",NULL}, //28 + {"lua_setmetatable",NULL}, //29 + {"lua_setfenv",NULL}, //30 + {"lua_call",NULL}, //31 + {"lua_pcall",NULL}, //32 + {"luaL_loadbufferx",NULL}, //33 + {"luaL_newmetatable",NULL}, //34 + {"lua_type",NULL}, //35 + {"lua_typename",NULL}, //36 + {"luaL_checktype",NULL}, //37 + {"lua_objlen",NULL}, //38 + {"lua_pushinteger",NULL}, //39 + {"lua_tointeger",NULL}, //40 + {NULL,NULL} +}; + +CLuaState::CLuaState() +{ +} + +CLuaState::~CLuaState() +{ +} + +int CLuaState::GetTop() +{ + return (((lua_gettop)lua_api[0].ptr))(this); +} + +void CLuaState::SetTop(int n) +{ + (((lua_settop)lua_api[1].ptr))(this,n); +} + +void CLuaState::SetField(int idx,const char* name) +{ + (((lua_setfield)lua_api[26].ptr))(this,idx,name); +} + +void CLuaState::GetField(int idx,const char* name) +{ + (((lua_getfield)lua_api[18].ptr))(this,idx,name); +} + +void CLuaState::Push(int idx) +{ + (((lua_pushvalue)lua_api[2].ptr))(this,idx); +} + +void CLuaState::PushNil() +{ + (((lua_pushnil)lua_api[10].ptr))(this); +} + +void CLuaState::PushBool(bool val) +{ + (((lua_pushboolean)lua_api[14].ptr))(this,val); +} + +void CLuaState::PushNumber(double num) +{ + (((lua_pushnumber)lua_api[11].ptr))(this,num); +} + +void CLuaState::PushInteger(int n) +{ + (((lua_pushinteger)lua_api[39].ptr))(this,n); +} + +void CLuaState::PushCClosure(CLuaFunction fn,int n) +{ + (((lua_pushcclosure)lua_api[13].ptr))(this,fn,n); +} + +void CLuaState::PushString(const char* str,size_t len) +{ + if(!len) + len = strlen(str); + (((lua_pushlstring)lua_api[12].ptr))(this,str,len); +} + +void CLuaState::PushVString(const char* fmt,va_list ap) +{ + char buf[512]; + vsnprintf(buf,512,fmt,ap); + PushString(buf); +} + +void CLuaState::PushFString(const char* fmt,...) +{ + va_list ap; + va_start(ap,fmt); + PushVString(fmt,ap); + va_end(ap); +} + +void CLuaState::PushLightUserData(void* p) +{ + (((lua_pushlightuserdata)lua_api[15].ptr))(this,p); +} + +void CLuaState::PushThread(CLuaState* L) +{ + (((lua_pushthread)lua_api[16].ptr))(L); +} + +bool CLuaState::GetBool(int idx) +{ + return (((lua_toboolean)lua_api[4].ptr))(this,idx); +} + +double CLuaState::GetNumber(int idx) +{ + return (((lua_tonumber)lua_api[3].ptr))(this,idx); +} + +int CLuaState::GetInteger(int idx) +{ + return (((lua_tointeger)lua_api[40].ptr))(this,idx); +} + +const char* CLuaState::GetString(int idx,size_t* len) +{ + return (((lua_tolstring)lua_api[5].ptr))(this,idx,len); +} + +userdata_t* CLuaState::GetUserData(int idx) +{ + return (userdata_t*)(((lua_touserdata)lua_api[7].ptr))(this,idx); +} + +CLuaFunction CLuaState::GetCFunction(int idx) +{ + return (((lua_tocfunction)lua_api[6].ptr))(this,idx); +} + +CLuaState* CLuaState::GetThread(int idx) +{ + return (((lua_tothread)lua_api[8].ptr))(this,idx); +} + +const void* CLuaState::GetPointer(int idx) +{ + return (((lua_topointer)lua_api[9].ptr))(this,idx); +} + +void CLuaState::CreateTable() +{ + (((lua_createtable)lua_api[21].ptr))(this,0,0); +} + +void CLuaState::GetTable(int idx) +{ + (((lua_gettable)lua_api[17].ptr))(this,idx); +} + +void CLuaState::SetTable(int idx) +{ + (((lua_settable)lua_api[25].ptr))(this,idx); +} + +void CLuaState::RawGet(int idx) +{ + (((lua_rawget)lua_api[19].ptr))(this,idx); +} + +void CLuaState::RawGeti(int idx,int n) +{ + (((lua_rawgeti)lua_api[20].ptr))(this,idx,n); +} + +void CLuaState::RawSet(int idx) +{ + (((lua_rawset)lua_api[27].ptr))(this,idx); +} + +void CLuaState::RawSeti(int idx,int n) +{ + (((lua_rawseti)lua_api[28].ptr))(this,idx,n); +} + +void CLuaState::GetEnvironment(int idx) +{ + (((lua_getfenv)lua_api[24].ptr))(this,idx); +} + +void CLuaState::SetEnvironment(int idx) +{ + (((lua_setfenv)lua_api[30].ptr))(this,idx); +} + +userdata_t* CLuaState::NewUserData() +{ + return (userdata_t*)(((lua_newuserdata)lua_api[23].ptr))(this,sizeof(userdata_t)); +} + +void CLuaState::CreateMetaTable(const char* name) +{ + (((luaL_newmetatable)lua_api[34].ptr))(this,name); +} + +int CLuaState::GetMetaTable(int idx) +{ + return (((lua_getmetatable)lua_api[22].ptr))(this,idx); +} + +int CLuaState::SetMetaTable(int idx) +{ + return (((lua_setmetatable)lua_api[29].ptr))(this,idx); +} + +luatype_t CLuaState::Type(int idx) +{ + return (luatype_t)(((lua_type)lua_api[35].ptr))(this,idx); +} + +const char* CLuaState::TypeName(int idx) +{ + return (((lua_typename)lua_api[36].ptr))(this,Type(idx)); +} + +void CLuaState::CheckType(int idx,luatype_t tp) +{ + (((luaL_checktype)lua_api[37].ptr))(this,idx,tp); +} + +void CLuaState::Call(int nargs,int nret) +{ + (((lua_call)lua_api[31].ptr))(this,nargs,nret); +} + +int CLuaState::PCall(int nargs,int nret,int errfunc) +{ + return (((lua_pcall)lua_api[32].ptr))(this,nargs,nret,errfunc); +} + +void CLuaState::Print(const char* msg,...) +{ + GetGlobal("print"); + va_list ap; + va_start(ap,msg); + PushVString(msg,ap); + va_end(ap); + Call(1,0); +} + +int CLuaState::ObjLen(int idx) +{ + return (((lua_objlen)lua_api[38].ptr))(this,idx); +} + +int CLuaState::ReferenceCreate() +{ + int len = ObjLen(-1); + len++; + PushInteger(len); + Push(-2); + SetTable(LUA_REGISTRYINDEX); + Pop(); + return len; +} + +void CLuaState::ReferencePush(int refId) +{ + PushInteger(refId); + GetTable(LUA_REGISTRYINDEX); +} + +void CLuaState::ReferenceFree(int refId) +{ + PushInteger(refId); + PushNil(); + SetTable(LUA_REGISTRYINDEX); +} + +const char* CLuaState::RunString(const char* name,const char* buf,size_t len) +{ + const char* err = NULL; + if( (((luaL_loadbufferx)lua_api[33].ptr))(this,buf,len,name,NULL) != OK) + { + err = GetString(-1); + Pop(); + } + else + PCall(0,0,0); + return err; +} + +BOOL WINAPI ConnectLuaShared() +{ + HMODULE hLuaShared = NULL; + char szDebugInfo[128]; + if(!(hLuaShared = GetModuleHandle("lua_shared.dll"))) + return FALSE; + for(func_t* i = lua_api; i->name; i++) + { + if(!(i->ptr = (void*)GetProcAddress(hLuaShared,i->name))) + { + _snprintf(szDebugInfo,128,"GetProcAddress failed at %s",i->name); + MessageBoxA(NULL,szDebugInfo,"ConnectLuaShared",MB_ICONHAND); + return FALSE; + } + } + return TRUE; +} + +BOOL APIENTRY DllMain(HINSTANCE hDll,DWORD fdwReason,LPVOID lpReserved) +{ + if(fdwReason == DLL_PROCESS_ATTACH) + return ConnectLuaShared(); + return TRUE; +} \ No newline at end of file diff --git a/state.h b/state.h new file mode 100644 index 0000000..ffbc529 --- /dev/null +++ b/state.h @@ -0,0 +1,102 @@ +#ifndef __STATE_H +#define __STATE_H + +#include "lua.h" +#include +#include +#include + +typedef struct { + const char* name; + void* ptr; +} func_t; + +typedef struct { + void* data; + unsigned char type; +} userdata_t; + +class CLuaState +{ +public: + CLuaState(); + ~CLuaState(); + + int GetTop(); + void SetTop(int n); + + void SetField(int idx,const char* name); + void GetField(int idx,const char* name); + + inline void GetGlobal(const char* name){GetField(LUA_GLOBALSINDEX,name);} + inline void SetGlobal(const char* name){SetField(LUA_GLOBALSINDEX,name);} + inline void GetMetaFromRegistry(const char* name){GetField(LUA_REGISTRYINDEX,name);} + + void Push(int idx); + void Pop(int amt = 1){SetTop(-(amt)-1);} + + void PushNil(); + void PushBool(bool val); + void PushNumber(double num); + void PushInteger(int n); + void PushCClosure(CLuaFunction fn,int n); + inline void PushCFunction(CLuaFunction fn){PushCClosure(fn,0);} + void PushString(const char* str,size_t len = 0); + void PushVString(const char* fmt,va_list ap); + void PushFString(const char* fmt,...); + void PushLightUserData(void* p); + void PushThread(CLuaState* L); + + bool GetBool(int idx); + double GetNumber(int idx); + int GetInteger(int idx); + const char* GetString(int idx,size_t* len = NULL); + userdata_t* GetUserData(int idx); + CLuaFunction GetCFunction(int idx); + CLuaState* GetThread(int idx); + const void* GetPointer(int idx); + + void CreateTable(); + void GetTable(int idx); + void SetTable(int idx); + + void RawGet(int idx); + void RawGeti(int idx,int n); + void RawSet(int idx); + void RawSeti(int idx,int n); + + void GetEnvironment(int idx); + void SetEnvironment(int idx); + + userdata_t* NewUserData(); + void CreateMetaTable(const char* name); + int GetMetaTable(int idx); + int SetMetaTable(int idx); + + luatype_t Type(int idx); + const char* TypeName(int idx); + void CheckType(int idx,luatype_t tp); + + void Call(int nargs,int nret); + int PCall(int nargs,int nret,int errfunc); + + int ObjLen(int idx); + int ReferenceCreate(); + void ReferencePush(int refId); + void ReferenceFree(int refId); + + void Print(const char*,...); + const char* RunString(const char* name,const char* buf,size_t len); + + inline bool IsNil(int idx){return (Type(idx) == NIL);} + inline bool IsBool(int idx){return (Type(idx) == TBOOLEAN);} + inline bool IsLightUserData(int idx){return (Type(idx) == LIGHTUSERDATA);} + inline bool IsNumber(int idx){return (Type(idx) == NUMBER);} + inline bool IsString(int idx){return (Type(idx) == STRING);} + inline bool IsTable(int idx){return (Type(idx) == TABLE);} + inline bool IsFunction(int idx){return (Type(idx) == FUNCTION);} + inline bool IsUserData(int idx){return (Type(idx) == USERDATA);} + inline bool IsThread(int idx){return (Type(idx) == THREAD);} +}; + +#endif \ No newline at end of file