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