├── CMakeLists.txt ├── README.md ├── metahook.h ├── lualib.h ├── .github └── workflows │ └── cmake.yml ├── luametahook.cpp ├── .gitignore ├── lauxlib.h ├── vscript_patch.cpp ├── signatures.h ├── vscript_lua51.cpp ├── lua.h └── luaconf.h /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | set(CMAKE_CXX_STANDARD 17) 3 | add_library(lua5.1 SHARED vscript_lua51.cpp) 4 | 5 | add_library(vscript SHARED vscript_patch.cpp) 6 | target_link_libraries(vscript PUBLIC lua5.1) 7 | 8 | add_library(luametahook SHARED luametahook.cpp) 9 | target_link_libraries(luametahook PUBLIC lua5.1) 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vscript_lua51 2 | This extension enables Lua VScript from CS2 to load external lua module dll. Tested on Mar 24th (9640) and Mar 30th (9652) version. 3 | 4 | # Usage 5 | 1. Prepare build environment: VS2022 + CMake 6 | 2. Build lua51.dll and vscript.dll 7 | 3. Rename vscript.dll to vscript2.dll in CAGO\game\bin\win64 8 | 4. Copy lua51.dll and vscript.dll into CAGO\game\bin\win64 9 | 5. Put any other external lua module dll (like luasocket.dll) into CAGO\game\bin\win64 10 | 6. Load module by `local luasocket = require("luasocket")` \ 11 | Warning: This is a client-side hack, NEVER install it under VAC, or you may get banned. 12 | 13 | # Support 14 | PRs and issues are welcomed. -------------------------------------------------------------------------------- /metahook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | inline PVOID MH_GetModuleBase(HMODULE hModule) 4 | { 5 | MEMORY_BASIC_INFORMATION mem; 6 | 7 | if (!VirtualQuery(hModule, &mem, sizeof(MEMORY_BASIC_INFORMATION))) 8 | return 0; 9 | 10 | return (PVOID)mem.AllocationBase; 11 | } 12 | 13 | inline LONG_PTR MH_GetModuleSize(HMODULE hModule) 14 | { 15 | return ((IMAGE_NT_HEADERS*)((LONG_PTR)hModule + ((IMAGE_DOS_HEADER*)hModule)->e_lfanew))->OptionalHeader.SizeOfImage; 16 | } 17 | 18 | inline void* MH_SearchPattern(void* pStartSearch, LONG_PTR dwSearchLen, const char* pPattern, LONG_PTR dwPatternLen) 19 | { 20 | BYTE *dwStartAddr = (BYTE *)pStartSearch; 21 | BYTE *dwEndAddr = dwStartAddr + dwSearchLen - dwPatternLen; 22 | 23 | while (dwStartAddr < dwEndAddr) 24 | { 25 | bool found = true; 26 | 27 | for (LONG_PTR i = 0; i < dwPatternLen; i++) 28 | { 29 | if ((BYTE)pPattern[i] != 0x2A && (BYTE)pPattern[i] != dwStartAddr[i]) 30 | { 31 | found = false; 32 | break; 33 | } 34 | } 35 | 36 | if (found) 37 | return dwStartAddr; 38 | 39 | dwStartAddr++; 40 | } 41 | 42 | return 0; 43 | } -------------------------------------------------------------------------------- /lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Lua standard libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lualib_h 9 | #define lualib_h 10 | 11 | #include "lua.h" 12 | 13 | 14 | /* Key to file-handle type */ 15 | #define LUA_FILEHANDLE "FILE*" 16 | 17 | 18 | #define LUA_COLIBNAME "coroutine" 19 | LUALIB_API int (luaopen_base) (lua_State *L); 20 | 21 | #define LUA_TABLIBNAME "table" 22 | LUALIB_API int (luaopen_table) (lua_State *L); 23 | 24 | #define LUA_IOLIBNAME "io" 25 | LUALIB_API int (luaopen_io) (lua_State *L); 26 | 27 | #define LUA_OSLIBNAME "os" 28 | LUALIB_API int (luaopen_os) (lua_State *L); 29 | 30 | #define LUA_STRLIBNAME "string" 31 | LUALIB_API int (luaopen_string) (lua_State *L); 32 | 33 | #define LUA_MATHLIBNAME "math" 34 | LUALIB_API int (luaopen_math) (lua_State *L); 35 | 36 | #define LUA_DBLIBNAME "debug" 37 | LUALIB_API int (luaopen_debug) (lua_State *L); 38 | 39 | #define LUA_LOADLIBNAME "package" 40 | LUALIB_API int (luaopen_package) (lua_State *L); 41 | 42 | 43 | /* open all previous libraries */ 44 | LUALIB_API void (luaL_openlibs) (lua_State *L); 45 | 46 | 47 | 48 | #ifndef lua_assert 49 | #define lua_assert(x) ((void)0) 50 | #endif 51 | 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /.github/workflows/cmake.yml: -------------------------------------------------------------------------------- 1 | name: CMake 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | env: 10 | # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) 11 | BUILD_TYPE: Release 12 | 13 | jobs: 14 | build: 15 | # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. 16 | # You can convert this to a matrix build if you need cross-platform coverage. 17 | # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 18 | runs-on: windows-latest 19 | 20 | steps: 21 | - uses: actions/checkout@v3 22 | 23 | - name: Configure CMake 24 | # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. 25 | # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type 26 | run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} 27 | 28 | - name: Build 29 | # Build your program with the given configuration 30 | run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} 31 | 32 | -------------------------------------------------------------------------------- /luametahook.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | extern "C" { 4 | #include "lua.h" 5 | #include "lualib.h" 6 | #include "lauxlib.h" 7 | } 8 | 9 | #include "Windows.h" 10 | #include "metahook.h" 11 | 12 | // function SearchPattern(string ModuleName, string Pattern) 13 | int LuaMH_SearchPattern(lua_State* L) 14 | { 15 | const char* name = lua_tostring(L, 1); 16 | size_t pattern_len = 0; 17 | const char* pattern = lua_tolstring(L, 2, &pattern_len); 18 | HMODULE hModule = GetModuleHandleA(name); 19 | if (!hModule) 20 | return luaL_error(L, "invalid module"); 21 | 22 | BYTE* pBase = (BYTE*)MH_GetModuleBase(hModule); 23 | auto dwModuleSize = MH_GetModuleSize(hModule); 24 | VirtualProtect(pBase, dwModuleSize, PAGE_EXECUTE_READWRITE, NULL); 25 | auto addr = MH_SearchPattern(pBase, dwModuleSize, pattern, pattern_len); 26 | if (!addr) 27 | { 28 | return luaL_error(L, "signature not found"); 29 | } 30 | 31 | lua_pushlightuserdata(L, addr); 32 | return 1; 33 | } 34 | 35 | // function GetModuleRange(string ModuleName) => Base, Size 36 | int LuaMH_GetModuleRange(lua_State* L) 37 | { 38 | const char* name = lua_tostring(L, 1); 39 | HMODULE hModule = GetModuleHandleA(name); 40 | if (!hModule) 41 | return luaL_error(L, "invalid module"); 42 | BYTE* pBase = (BYTE*)MH_GetModuleBase(hModule); 43 | auto dwModuleSize = MH_GetModuleSize(hModule); 44 | 45 | lua_pushlightuserdata(L, pBase); 46 | lua_pushinteger(L, (lua_Integer)dwModuleSize); 47 | return 2; 48 | } 49 | 50 | const luaL_reg lib[] = { 51 | { "SearchPattern", LuaMH_SearchPattern}, 52 | { "GetModuleRange", LuaMH_GetModuleRange}, 53 | { nullptr, nullptr } 54 | }; 55 | 56 | extern "C" __declspec(dllexport) int luaopen_luametahook(lua_State* L) 57 | { 58 | luaL_register(L, "luametahook", lib); 59 | return 1; 60 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries 2 | *.o 3 | *.so 4 | *.a 5 | *.framework 6 | 7 | # Other 8 | *.save 9 | # Qt Creator for some reason creates *.user.$version files, so exclude it too 10 | *.user* 11 | *~ 12 | 13 | ### Xcode ### 14 | build/ 15 | *.pbxuser 16 | !default.pbxuser 17 | *.mode1v3 18 | !default.mode1v3 19 | *.mode2v3 20 | !default.mode2v3 21 | *.perspectivev3 22 | !default.perspectivev3 23 | xcuserdata 24 | *.xccheckout 25 | *.moved-aside 26 | DerivedData 27 | *.xcuserstate 28 | WorkspaceSettings.xcsettings 29 | 30 | 31 | ### OSX ### 32 | .DS_Store 33 | .AppleDouble 34 | .LSOverride 35 | 36 | 37 | # Thumbnails 38 | ._* 39 | 40 | # Files that might appear on external disk 41 | .Spotlight-V100 42 | .Trashes 43 | 44 | # Directories potentially created on remote AFP share 45 | .AppleDB 46 | .AppleDesktop 47 | Network Trash Folder 48 | Temporary Items 49 | .apdisk 50 | 51 | 52 | ### CMake ### 53 | CMakeCache.txt 54 | CMakeFiles 55 | Makefile 56 | cmake_install.cmake 57 | install_manifest.txt 58 | # makedepend 59 | Makefile.dep 60 | *.bak 61 | ALL_BUILD.* 62 | INSTALL.* 63 | ZERO_CHECK.* 64 | 65 | # Visual Studio 66 | *.obj 67 | *.exp 68 | *.suo 69 | *.sdf 70 | Debug/ 71 | Release/ 72 | ipch/ 73 | *.opensdf 74 | 75 | ## Ignore Visual Studio temporary files, build results, and 76 | ## files generated by popular Visual Studio add-ons. 77 | 78 | # User-specific files 79 | *.suo 80 | *.user 81 | *.userosscache 82 | *.sln.docstates 83 | 84 | # User-specific files (MonoDevelop/Xamarin Studio) 85 | *.userprefs 86 | 87 | # Build results 88 | [Dd]ebug/ 89 | [Dd]ebugPublic/ 90 | [Rr]elease/ 91 | [Rr]eleases/ 92 | build/ 93 | bld/ 94 | [Bb]in/ 95 | [Oo]bj/ 96 | 97 | # Visual Studio 2015 cache/options directory 98 | .vs/ 99 | 100 | # Visual Studio Code Preferences 101 | .vscode/ 102 | 103 | # Uncomment if you have tasks that create the project's static files in wwwroot 104 | #wwwroot/ 105 | 106 | # MSTest test Results 107 | [Tt]est[Rr]esult*/ 108 | [Bb]uild[Ll]og.* 109 | 110 | # NUNIT 111 | *.VisualState.xml 112 | TestResult.xml 113 | 114 | # Build Results of an ATL Project 115 | [Dd]ebugPS/ 116 | [Rr]eleasePS/ 117 | dlldata.c 118 | 119 | # DNX 120 | project.lock.json 121 | artifacts/ 122 | 123 | *_i.c 124 | *_p.c 125 | *_i.h 126 | *.ilk 127 | *.meta 128 | *.obj 129 | *.pch 130 | *.pdb 131 | *.pgc 132 | *.pgd 133 | *.rsp 134 | *.sbr 135 | *.tlb 136 | *.tli 137 | *.tlh 138 | *.tmp 139 | *.tmp_proj 140 | *.log 141 | *.vspscc 142 | *.vssscc 143 | .builds 144 | *.pidb 145 | *.svclog 146 | *.scc 147 | 148 | # Chutzpah Test files 149 | _Chutzpah* 150 | 151 | # Visual C++ cache files 152 | ipch/ 153 | *.aps 154 | *.ncb 155 | *.opensdf 156 | *.sdf 157 | *.cachefile 158 | 159 | # Visual Studio profiler 160 | *.psess 161 | *.vsp 162 | *.vspx 163 | *.sap 164 | 165 | # TFS 2012 Local Workspace 166 | $tf/ 167 | 168 | # Guidance Automation Toolkit 169 | *.gpState 170 | 171 | # ReSharper is a .NET coding add-in 172 | _ReSharper*/ 173 | *.[Rr]e[Ss]harper 174 | *.DotSettings.user 175 | 176 | # JustCode is a .NET coding add-in 177 | .JustCode 178 | 179 | # TeamCity is a build add-in 180 | _TeamCity* 181 | 182 | # DotCover is a Code Coverage Tool 183 | *.dotCover 184 | 185 | # NCrunch 186 | _NCrunch_* 187 | .*crunch*.local.xml 188 | nCrunchTemp_* 189 | 190 | # MightyMoose 191 | *.mm.* 192 | AutoTest.Net/ 193 | 194 | # Web workbench (sass) 195 | .sass-cache/ 196 | 197 | # Installshield output folder 198 | [Ee]xpress/ 199 | 200 | # DocProject is a documentation generator add-in 201 | DocProject/buildhelp/ 202 | DocProject/Help/*.HxT 203 | DocProject/Help/*.HxC 204 | DocProject/Help/*.hhc 205 | DocProject/Help/*.hhk 206 | DocProject/Help/*.hhp 207 | DocProject/Help/Html2 208 | DocProject/Help/html 209 | 210 | # Click-Once directory 211 | publish/ 212 | 213 | # Publish Web Output 214 | *.[Pp]ublish.xml 215 | *.azurePubxml 216 | # TODO: Comment the next line if you want to checkin your web deploy settings 217 | # but database connection strings (with potential passwords) will be unencrypted 218 | *.pubxml 219 | *.publishproj 220 | 221 | # NuGet Packages 222 | *.nupkg 223 | # The packages folder can be ignored because of Package Restore 224 | **/packages/* 225 | # except build/, which is used as an MSBuild target. 226 | !**/packages/build/ 227 | # Uncomment if necessary however generally it will be regenerated when needed 228 | #!**/packages/repositories.config 229 | 230 | # Windows Azure Build Output 231 | csx/ 232 | *.build.csdef 233 | 234 | # Windows Store app package directory 235 | AppPackages/ 236 | 237 | # Visual Studio cache files 238 | # files ending in .cache can be ignored 239 | *.[Cc]ache 240 | # but keep track of directories ending in .cache 241 | !*.[Cc]ache/ 242 | 243 | # Others 244 | ClientBin/ 245 | [Ss]tyle[Cc]op.* 246 | ~$* 247 | *~ 248 | *.dbmdl 249 | *.dbproj.schemaview 250 | *.pfx 251 | *.publishsettings 252 | node_modules/ 253 | orleans.codegen.cs 254 | 255 | # RIA/Silverlight projects 256 | Generated_Code/ 257 | 258 | # Backup & report files from converting an old project file 259 | # to a newer Visual Studio version. Backup files are not needed, 260 | # because we have git ;-) 261 | _UpgradeReport_Files/ 262 | Backup*/ 263 | UpgradeLog*.XML 264 | UpgradeLog*.htm 265 | 266 | # SQL Server files 267 | *.mdf 268 | *.ldf 269 | 270 | # Business Intelligence projects 271 | *.rdl.data 272 | *.bim.layout 273 | *.bim_*.settings 274 | 275 | # Microsoft Fakes 276 | FakesAssemblies/ 277 | 278 | # Node.js Tools for Visual Studio 279 | .ntvs_analysis.dat 280 | 281 | # Visual Studio 6 build log 282 | *.plg 283 | 284 | # Visual Studio 6 workspace options file 285 | *.opt 286 | 287 | # Visual Studio LightSwitch build output 288 | **/*.HTMLClient/GeneratedArtifacts 289 | **/*.DesktopClient/GeneratedArtifacts 290 | **/*.DesktopClient/ModelManifest.xml 291 | **/*.Server/GeneratedArtifacts 292 | **/*.Server/ModelManifest.xml 293 | _Pvt_Extensions 294 | 295 | # PVS Studio for Linux output 296 | *.cl.cfg 297 | 298 | # Kate 299 | *.kate-swp 300 | *.swp 301 | 302 | # QtCreator 303 | build-* 304 | 305 | # Android Build 306 | *.apk 307 | libs/armeabi* 308 | libs/x86 309 | obj 310 | bin 311 | gen 312 | 313 | # Android Studio 314 | local.properties 315 | build/ 316 | release/ 317 | debug/ 318 | .gradle/ 319 | .idea/ 320 | .cxx/ 321 | *.iml 322 | 323 | # Others 324 | .idea 325 | /cmake-build-* 326 | CMakeSettings.json 327 | /3rdparty/boost_* 328 | msvc/BundleArtifacts/ 329 | /enc_temp_folder 330 | /out 331 | /.git.7z 332 | -------------------------------------------------------------------------------- /lauxlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Auxiliary functions for building Lua libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lauxlib_h 9 | #define lauxlib_h 10 | 11 | 12 | #include 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | 18 | #if defined(LUA_COMPAT_GETN) 19 | LUALIB_API int (luaL_getn) (lua_State *L, int t); 20 | LUALIB_API void (luaL_setn) (lua_State *L, int t, int n); 21 | #else 22 | #define luaL_getn(L,i) ((int)lua_objlen(L, i)) 23 | #define luaL_setn(L,i,j) ((void)0) /* no op! */ 24 | #endif 25 | 26 | #if defined(LUA_COMPAT_OPENLIB) 27 | #define luaI_openlib luaL_openlib 28 | #endif 29 | 30 | 31 | /* extra error code for `luaL_load' */ 32 | #define LUA_ERRFILE (LUA_ERRERR+1) 33 | 34 | 35 | typedef struct luaL_Reg { 36 | const char *name; 37 | lua_CFunction func; 38 | } luaL_Reg; 39 | 40 | 41 | 42 | LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname, 43 | const luaL_Reg *l, int nup); 44 | LUALIB_API void (luaL_register) (lua_State *L, const char *libname, 45 | const luaL_Reg *l); 46 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); 47 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); 48 | LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); 49 | LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); 50 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, 51 | size_t *l); 52 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, 53 | const char *def, size_t *l); 54 | LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); 55 | LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); 56 | 57 | LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); 58 | LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, 59 | lua_Integer def); 60 | 61 | LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); 62 | LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); 63 | LUALIB_API void (luaL_checkany) (lua_State *L, int narg); 64 | 65 | LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); 66 | LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); 67 | 68 | LUALIB_API void (luaL_where) (lua_State *L, int lvl); 69 | LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); 70 | 71 | LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, 72 | const char *const lst[]); 73 | 74 | LUALIB_API int (luaL_ref) (lua_State *L, int t); 75 | LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); 76 | 77 | LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); 78 | LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, 79 | const char *name); 80 | LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); 81 | 82 | LUALIB_API lua_State *(luaL_newstate) (void); 83 | 84 | 85 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, 86 | const char *r); 87 | 88 | LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, 89 | const char *fname, int szhint); 90 | 91 | 92 | 93 | 94 | /* 95 | ** =============================================================== 96 | ** some useful macros 97 | ** =============================================================== 98 | */ 99 | 100 | #define luaL_argcheck(L, cond,numarg,extramsg) \ 101 | ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) 102 | #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) 103 | #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) 104 | #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) 105 | #define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) 106 | #define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) 107 | #define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) 108 | 109 | #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) 110 | 111 | #define luaL_dofile(L, fn) \ 112 | (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) 113 | 114 | #define luaL_dostring(L, s) \ 115 | (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) 116 | 117 | #define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) 118 | 119 | #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) 120 | 121 | /* 122 | ** {====================================================== 123 | ** Generic Buffer manipulation 124 | ** ======================================================= 125 | */ 126 | 127 | 128 | 129 | typedef struct luaL_Buffer { 130 | char *p; /* current position in buffer */ 131 | int lvl; /* number of strings in the stack (level) */ 132 | lua_State *L; 133 | char buffer[LUAL_BUFFERSIZE]; 134 | } luaL_Buffer; 135 | 136 | #define luaL_addchar(B,c) \ 137 | ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ 138 | (*(B)->p++ = (char)(c))) 139 | 140 | /* compatibility only */ 141 | #define luaL_putchar(B,c) luaL_addchar(B,c) 142 | 143 | #define luaL_addsize(B,n) ((B)->p += (n)) 144 | 145 | LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); 146 | LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); 147 | LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); 148 | LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); 149 | LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); 150 | LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); 151 | 152 | 153 | /* }====================================================== */ 154 | 155 | 156 | /* compatibility with ref system */ 157 | 158 | /* pre-defined references */ 159 | #define LUA_NOREF (-2) 160 | #define LUA_REFNIL (-1) 161 | 162 | #define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ 163 | (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) 164 | 165 | #define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) 166 | 167 | #define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) 168 | 169 | 170 | #define luaL_reg luaL_Reg 171 | 172 | #endif 173 | 174 | 175 | -------------------------------------------------------------------------------- /vscript_patch.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | extern "C" { 6 | #define LUA_BUILD_AS_DLL 7 | #include "lua.h" 8 | #include "lualib.h" 9 | #include "lauxlib.h" 10 | } 11 | 12 | extern "C" { 13 | LUALIB_API int luaopen_ffi(lua_State* L); 14 | LUA_API int luaJIT_setmode(lua_State* L, int idx, int mode); 15 | } 16 | 17 | typedef void* (*CreateInterfaceFn)(const char *pName, int *pReturnCode); 18 | 19 | struct AppSystemInfo_t 20 | { 21 | const char* m_pModuleName; 22 | const char* m_pInterfaceName; 23 | }; 24 | 25 | enum InitReturnVal_t 26 | { 27 | INIT_FAILED = 0, 28 | INIT_OK, 29 | 30 | INIT_LAST_VAL, 31 | }; 32 | 33 | enum AppSystemTier_t 34 | { 35 | APP_SYSTEM_TIER0 = 0, 36 | APP_SYSTEM_TIER1, 37 | APP_SYSTEM_TIER2, 38 | APP_SYSTEM_TIER3, 39 | 40 | APP_SYSTEM_TIER_OTHER, 41 | }; 42 | 43 | enum BuildType_t 44 | { 45 | kBuildTypeRelease = 2 46 | }; 47 | 48 | class IAppSystem 49 | { 50 | public: 51 | // Here's where the app systems get to learn about each other 52 | virtual bool Connect( CreateInterfaceFn factory ) = 0; 53 | virtual void Disconnect() = 0; 54 | 55 | // Here's where systems can access other interfaces implemented by this object 56 | // Returns NULL if it doesn't implement the requested interface 57 | virtual void *QueryInterface( const char *pInterfaceName ) = 0; 58 | 59 | // Init, shutdown 60 | virtual InitReturnVal_t Init() = 0; 61 | virtual void Shutdown() = 0; 62 | virtual void PreShutdown() = 0; 63 | 64 | // Returns all dependent libraries 65 | virtual const AppSystemInfo_t* GetDependencies() = 0; 66 | 67 | // Returns the tier 68 | virtual AppSystemTier_t GetTier() = 0; 69 | 70 | // Reconnect to a particular interface 71 | virtual void Reconnect(CreateInterfaceFn factory, const char* pInterfaceName) = 0; 72 | 73 | // Returns whether or not the app system is a singleton 74 | virtual bool IsSingleton() = 0; 75 | 76 | // Source 2 Added 77 | virtual BuildType_t GetBuildType() = 0; 78 | }; 79 | 80 | enum ScriptLanguage_t 81 | { 82 | SL_NONE, 83 | SL_LUA, 84 | 85 | SL_DEFAULT = SL_LUA 86 | }; 87 | 88 | class IScriptVMPartA 89 | { 90 | public: 91 | virtual void DeleteThis() = 0; // ? 92 | virtual bool Init() = 0; 93 | virtual bool ConnectDebugger() = 0; 94 | virtual void DisconnectDebugger() = 0; 95 | 96 | virtual ScriptLanguage_t GetLanguage() = 0; 97 | virtual const char* GetLanguageName() = 0; 98 | 99 | virtual void* GetInternalVM() = 0; 100 | 101 | // TODO : more 102 | }; 103 | 104 | class IScriptVM; 105 | class IScriptDebugger; 106 | 107 | class IScriptManager : public IAppSystem 108 | { 109 | public: 110 | virtual IScriptVM *CreateVM( ScriptLanguage_t language = SL_DEFAULT ) = 0; 111 | virtual void DestroyVM( IScriptVM * ) = 0; 112 | virtual IScriptDebugger* GetDebugger() = 0; 113 | }; 114 | #define VSCRIPT_INTERFACE_VERSION "VScriptManager010" 115 | 116 | CreateInterfaceFn GetOrigFactory() 117 | { 118 | auto dl = LoadLibrary("vscript2.dll"); 119 | return (CreateInterfaceFn)GetProcAddress(dl, "CreateInterface"); 120 | } 121 | 122 | IScriptManager *g_pScriptManager = nullptr; 123 | 124 | class CScriptManagerExt : public IScriptManager 125 | { 126 | public: 127 | bool Connect( CreateInterfaceFn factory ) override 128 | { 129 | return g_pScriptManager->Connect(factory); 130 | } 131 | 132 | void Disconnect() override 133 | { 134 | return g_pScriptManager->Disconnect(); 135 | } 136 | 137 | void *QueryInterface( const char *pInterfaceName ) override 138 | { 139 | return g_pScriptManager->QueryInterface(pInterfaceName); 140 | } 141 | 142 | InitReturnVal_t Init() override 143 | { 144 | return g_pScriptManager->Init(); 145 | } 146 | 147 | void Shutdown() override 148 | { 149 | return g_pScriptManager->Shutdown(); 150 | } 151 | 152 | void PreShutdown() override 153 | { 154 | return g_pScriptManager->PreShutdown(); 155 | } 156 | 157 | const AppSystemInfo_t* GetDependencies() override 158 | { 159 | return g_pScriptManager->GetDependencies(); 160 | } 161 | 162 | AppSystemTier_t GetTier() override 163 | { 164 | return g_pScriptManager->GetTier(); 165 | } 166 | 167 | void Reconnect(CreateInterfaceFn factory, const char* pInterfaceName) override 168 | { 169 | return g_pScriptManager->Reconnect(factory, pInterfaceName); 170 | } 171 | 172 | bool IsSingleton() override 173 | { 174 | return g_pScriptManager->IsSingleton(); 175 | } 176 | 177 | BuildType_t GetBuildType() override 178 | { 179 | return g_pScriptManager->GetBuildType(); 180 | } 181 | 182 | IScriptVM *CreateVM( ScriptLanguage_t language = SL_DEFAULT ) override 183 | { 184 | auto vm = g_pScriptManager->CreateVM(language); 185 | auto vm2 = (IScriptVMPartA*)vm; 186 | 187 | lua_State *L = (lua_State *)vm2->GetInternalVM(); 188 | 189 | // moemod : turn on jit again 190 | #define LUAJIT_MODE_OFF 0x0000 /* Turn feature off. */ 191 | #define LUAJIT_MODE_ON 0x0100 /* Turn feature on. */ 192 | #define LUAJIT_MODE_FLUSH 0x0200 /* Flush JIT-compiled code. */ 193 | luaJIT_setmode(L, 0, LUAJIT_MODE_ON); 194 | 195 | lua_getglobal(L, "print"); // #1 196 | lua_pushstring(L, "vscript patch: hello, world !!!"); // #2 197 | lua_call(L, 1, 0); // #0 198 | 199 | // moemod hack : restore package 200 | // valve sets package.loaders[*] and package.loadlib to nil 201 | // here we are going to restore them 202 | 203 | lua_getglobal(L, "package"); // #1 = package 204 | lua_getfield(L, -1, "loaders"); // #2 = package.loaders 205 | lua_pushinteger(L, 2); // #3 = 2 206 | lua_gettable(L, -2); // #3 = package.loaders[2] 207 | 208 | int valve_loader_ref = luaL_ref(L, LUA_REGISTRYINDEX); // #2 = package.loaders 209 | lua_pop(L, 2); // #0 210 | 211 | lua_pushcfunction(L, luaopen_package); // #1 212 | lua_call(L, 0, 0); // #0 213 | 214 | lua_getglobal(L, "table"); // #1 = table 215 | lua_getfield(L, -1, "insert"); // #2 = table.insert 216 | lua_remove(L, -2); // #1 = table.insert 217 | 218 | lua_getglobal(L, "package"); // #2 = package 219 | lua_getfield(L, -1, "loaders"); // #3 = package.loaders 220 | lua_remove(L, -2); // #2 = package.loaders 221 | 222 | lua_pushinteger(L, 2); // #3 = 2 223 | lua_rawgeti(L, LUA_REGISTRYINDEX, valve_loader_ref); // #4 = valve_loader 224 | lua_call(L, 3, 0); // #0 225 | 226 | luaL_unref(L, LUA_REGISTRYINDEX, valve_loader_ref); 227 | 228 | // moemod hack : restore io 229 | // not working, use local io = require("cio") 230 | //lua_pushcfunction(L, luaopen_io); 231 | //lua_pushstring(L, "io"); 232 | //lua_pcall(L, 1, 0, 0); 233 | 234 | // moemod hack : restore ffi 235 | // not working, use local io = require("cffi") 236 | //luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD", 1); 237 | //lua_pushcfunction(L, luaopen_ffi); 238 | //lua_setfield(L, -2, "ffi"); 239 | //lua_pop(L, 1); 240 | 241 | return vm; 242 | } 243 | 244 | void DestroyVM( IScriptVM *vm ) override 245 | { 246 | return g_pScriptManager->DestroyVM(vm); 247 | } 248 | 249 | IScriptDebugger* GetDebugger() override 250 | { 251 | return g_pScriptManager->GetDebugger(); 252 | } 253 | } g_ScriptManagerExt; 254 | 255 | #if defined( _WIN32 ) 256 | 257 | // Used for dll exporting and importing 258 | #define DLL_EXPORT extern "C" __declspec( dllexport ) 259 | #define DLL_IMPORT extern "C" __declspec( dllimport ) 260 | 261 | // Can't use extern "C" when DLL exporting a class 262 | #define DLL_CLASS_EXPORT __declspec( dllexport ) 263 | #define DLL_CLASS_IMPORT __declspec( dllimport ) 264 | 265 | // Can't use extern "C" when DLL exporting a global 266 | #define DLL_GLOBAL_EXPORT extern __declspec( dllexport ) 267 | #define DLL_GLOBAL_IMPORT extern __declspec( dllimport ) 268 | 269 | #elif defined(_LINUX) || defined(__APPLE__) 270 | // Used for dll exporting and importing 271 | #define DLL_EXPORT extern "C" __attribute__ ((visibility("default"))) 272 | #define DLL_IMPORT extern "C" 273 | 274 | // Can't use extern "C" when DLL exporting a class 275 | #define DLL_CLASS_EXPORT __attribute__ ((visibility("default"))) 276 | #define DLL_CLASS_IMPORT 277 | 278 | // Can't use extern "C" when DLL exporting a global 279 | #define DLL_GLOBAL_EXPORT extern __attribute ((visibility("default"))) 280 | #define DLL_GLOBAL_IMPORT extern 281 | 282 | #else 283 | #error "Unsupported Platform." 284 | #endif 285 | 286 | // EXPORT 287 | DLL_EXPORT void * CreateInterface(const char *pName, int *pReturnCode) 288 | { 289 | static CreateInterfaceFn vscript_factory = GetOrigFactory(); 290 | if(!strcmp(pName, VSCRIPT_INTERFACE_VERSION)) 291 | { 292 | g_pScriptManager = (IScriptManager *)vscript_factory(pName, pReturnCode); 293 | return &g_ScriptManagerExt; 294 | } 295 | return vscript_factory(pName, pReturnCode); 296 | } 297 | -------------------------------------------------------------------------------- /signatures.h: -------------------------------------------------------------------------------- 1 | F_DEF(index2adr, "\x4C\x8B\xC1\x85\xD2\x7E\x2A\x48\x8B\x41\x20\x48\x63\xD2") 2 | F_DEF(lj_obj_equal, "\x4C\x8B\x09\x4C\x8B\x12") 3 | F_DEF(lj_err_callermsg, "\x40\x53\x48\x83\xEC\x20\x48\x8B\x41\x10\x45\x33\xC9") 4 | F_DEF(luaL_loadbufferx, "\x4C\x8B\xDC\x49\x89\x5B\x08\x57\x48\x81\xEC\xF0\x00\x00\x00\x4D\x85\xC9\x48\x89\x54\x24\x20\x48\x8D\x05\x32\x06\x00\x00") 5 | F_DEF(lj_err_run, "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x4C\x8B\x51\x10") 6 | F_DEF(lj_err_argtype, "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x48\x63\xDA") 7 | F_DEF(err_argmsg, "\x48\x89\x5C\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xEC\x30\x8B\xDA") 8 | 9 | F_DEF(lua_newstate, "\x48\x89\x5C\x24\x20\x55\x56\x41\x56\x48\x83\xEC\x50") 10 | F_DEF(lua_close, "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xEC\x20\x48\x8B\x79\x10\x48\x8B\x9F\xC0\x00\x00\x00") 11 | F_DEF(lua_newthread, "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x48\x8B\x51\x10") 12 | F_DEF(lua_atpanic, "\x4C\x8B\x41\x10\x49\x8B\x80\x60\x01\x00\x00") 13 | 14 | F_DEF(lua_gettop, "\x48\x8B\x41\x28\x48\x2B\x41\x20") 15 | F_DEF(lua_settop, "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x48\x63\xFA") 16 | F_DEF(lua_pushvalue, "\x48\x83\xEC\x28\x4C\x8B\xD1\xE8\x2A\x2A\x2A\x2A\x49\x8B\x52\x28") 17 | F_DEF(lua_remove, "\x4C\x8B\xC1\x85\xD2\x7E\x2A\x48\x8B\x41\x20\x48\x8B\x49\x28") 18 | F_DEF(lua_insert, "\x4C\x8B\xC9\x85\xD2") 19 | //F_N(lua_replace, 2, ?) 20 | F_DEF(lua_checkstack, "\x48\x83\xEC\x28\x4C\x8B\xC9") 21 | F_DEF(lua_xmove, "\x48\x3B\xCA\x74\x2A\x48\x89\x5C\x24\x08") 22 | 23 | F_DEF(lua_isnumber, "\x48\x83\xEC\x28\xE8\x2A\x2A\x2A\x2A\x48\x8B\x08\x48\x8B\xC1\x48\xC1\xF8\x2F\x83\xF8\xF2") 24 | F_DEF(lua_isstring, "\x48\x83\xEC\x28\xE8\x2A\x2A\x2A\x2A\x48\x8B\x08\x48\xC1\xF9\x2F") 25 | F_DEF(lua_iscfunction, "\x48\x83\xEC\x28\xE8\x2A\x2A\x2A\x2A\x48\x8B\x08\x48\x8B\xC1\x48\xC1\xF8\x2F\x83\xF8\xF7") 26 | //F_N(lua_isuserdata, 2, ?) 27 | F_DEF(lua_type, "\x48\x83\xEC\x28\x4C\x8B\xD1\xE8\x2A\x2A\x2A\x2A\x4C\x8B\xD8") 28 | F_DEF(lua_typename, "\x48\x63\xC2\x48\x8D\x0D\x2A\x2A\x0B\x00") 29 | 30 | F_DEF(lua_equal, "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x45\x8B\xD0\x48\x8B\xD9") 31 | //F_N(lua_rawequal, 3, ?) 32 | F_DEF(lua_lessthan, "\x40\x53\x48\x83\xEC\x20\x45\x8B\xD0") 33 | 34 | F_DEF(lua_tonumber, "\x48\x83\xEC\x28\xE8\x2A\x2A\x2A\x2A\x48\x8B\x08\x48\x8B\xD1\x48\xC1\xFA\x2F\x83\xFA\xF2\x77\x2A") 35 | F_DEF(lua_tointeger, "\x48\x83\xEC\x28\xE8\x2A\x2A\x2A\x2A\x48\x8B\x08\x48\x8B\xD1\x48\xC1\xFA\x2F\x83\xFA\xF2\x73\x2A") 36 | F_DEF(lua_toboolean, "\x48\x83\xEC\x28\xE8\x2A\x2A\x2A\x2A\x48\x8B\x08\x33\xC0") 37 | F_DEF(lua_tolstring, "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x20\x49\x8B\xF8\x8B\xDA\x48\x8B\xF1\xE8\x2A\x2A\x2A\x2A") 38 | F_DEF(lua_objlen, "\x40\x53\x48\x83\xEC\x20\x4C\x8B\xD1\xE8\x2A\x2A\x2A\x2A") 39 | //F_N(lua_tocfunction, 2, ?) 40 | F_DEF(lua_touserdata, "\x48\x83\xEC\x28\x4C\x8B\xD1\xE8\x2A\x2A\x2A\x2A\x48\x8B\x10") 41 | //F_N(lua_tothread, 2, ?) 42 | //F_N(lua_topointer, 2, ?) 43 | 44 | F_DEF(lua_pushnil, "\x48\x8B\x41\x28\x48\xC7\x00\xFF\xFF\xFF\xFF\x48\x83\x41\x28\x08") 45 | F_DEF(lua_pushnumber, "\x48\x8B\x41\x28\xF2\x0F\x11\x08") 46 | F_DEF(lua_pushinteger, "\x48\x8B\x41\x28\x0F\x57\xC0") 47 | F_DEF(lua_pushlstring, "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x20\x4C\x8B\x49\x10\x49\x8B\xF8") 48 | F_DEF(lua_pushstring, "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x48\x8B\xFA\x48\x8B\xD9\x48\x85\xD2") 49 | F_DEF(lua_pushvfstring, "\x40\x53\x55\x48\x83\xEC\x48\x48\x8B\x59\x10") 50 | // F_N(lua_pushfstring, 2, "\x48\x89\x54\x24\x10\x4C\x89\x44\x24\x18\x4C\x89\x4C\x24\x20\x53\x48\x83\xEC\x20\x4C\x8B\x41\x10") 51 | F_DEF(lua_pushcclosure, "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x20\x48\x8B\xD9\x49\x63\xF8") 52 | F_DEF(lua_pushboolean, "\x48\x8B\x41\x28\x45\x33\xC0") 53 | F_DEF(lua_pushlightuserdata, "\x40\x53\x48\x83\xEC\x20\x48\x8B\xD9\xE8\x2A\x2A\x2A\x2A\x48\x8B\x53\x28") 54 | F_DEF(lua_pushthread, "\x40\x53\x48\x83\xEC\x20\x48\xB8\x00\x00\x00\x00\x00\x80\xFC\xFF") 55 | 56 | F_DEF(lua_gettable, "\x40\x53\x48\x83\xEC\x20\x48\x8B\xD9\xE8\x2A\x2A\x2A\x2A\x4C\x8B\x43\x28\x48\x8B\xD0\x49\x83\xE8\x08") 57 | F_DEF(lua_getfield, "\x48\x89\x5C\x24\x10\x57\x48\x83\xEC\x20\x4D\x8B\xD0") 58 | F_DEF(lua_rawget, "\x40\x53\x48\x83\xEC\x20\x48\x8B\xD9\xE8\x2A\x2A\x2A\x2A\x4C\x8B\x43\x28\x48\x8B\xCB") 59 | F_DEF(lua_rawgeti, "\x40\x53\x48\x83\xEC\x20\x4D\x63\xD0") 60 | F_DEF(lua_createtable, "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x20\x4C\x8B\x49\x10\x41\x8B\xF8") 61 | F_DEF(lua_newuserdata, "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x4C\x8B\x41\x10") 62 | F_DEF(lua_getmetatable, "\x48\x83\xEC\x28\x4C\x8B\xD1\xE8\x2A\x2A\x2A\x2A\x48\x8B\x08\x48\x8B\xC1\x48\xC1\xF8\x2F\x83\xF8\xF4") 63 | F_DEF(lua_getfenv, "\x48\x83\xEC\x28\x4C\x8B\xD1\xE8\x2A\x2A\x2A\x2A\x48\x8B\x08\x48\x8B\xC1\x48\xC1\xF8\x2F\x83\xF8\xF7") 64 | 65 | F_DEF(lua_settable, "\x40\x53\x48\x83\xEC\x20\x48\x8B\xD9\xE8\x2A\x2A\x2A\x2A\x4C\x8B\x43\x28\x48\x8B\xD0\x49\x83\xE8\x10") 66 | F_DEF(lua_setfield, "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x4D\x8B\xD0\x48\x8B\xD9") 67 | F_DEF(lua_rawset, "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x20\x48\x8B\xD9\xE8\x2A\x2A\x2A\x2A") 68 | F_DEF(lua_rawseti, "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x20\x4D\x63\xD0") 69 | F_DEF(lua_setmetatable, "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x48\x89\x7C\x24\x18\x41\x56\x48\x83\xEC\x20\x48\x8B\xF9\xE8\x2A\x2A\x2A\x2A") 70 | F_DEF(lua_setfenv, "\x40\x53\x48\x83\xEC\x20\x48\x8B\xD9\xE8\x2A\x2A\x2A\x2A\x4C\x8B\x4B\x28") 71 | 72 | F_DEF(lua_call, "\x48\x63\xC2\x4C\x8B\xD1") 73 | F_DEF(lua_pcall, "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x20\x48\x8B\x59\x10\x41\x8B\xF0") 74 | F_DEF(lua_cpcall, "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x48\x8B\x59\x10\x4C\x8D\x0D\xDB\xF4\xFF\xFF") 75 | F_DEF(lua_load, "\x4C\x8B\xDC\x49\x89\x5B\x08\x57\x48\x81\xEC\xF0\x00\x00\x00\x4D\x85\xC9\x48\x89\x54\x24\x20\x48\x8D\x05\xE2\x06\x00\x00") 76 | //F_N(lua_dump, 3, ?) 77 | 78 | //F_N(lua_yield, 2, ?) 79 | //F_N(lua_resume, 2, ?) 80 | //F_N(lua_status, 1, ?) 81 | 82 | F_DEF(lua_gc, "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x20\x48\x8B\x59\x10\x33\xFF") 83 | //F_DEF(lua_error, 0x58170) // "\x48\x83\xEC\x28\xE8\x2A\x2A\x2A\x2A\xCC" function is too short... 84 | F_DEF(lua_next, "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x48\x8B\xD9\xE8\x2A\x2A\x2A\x2A\x48\x8B\x53\x28") 85 | F_DEF(lua_concat, "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x8B\xFA\x48\x8B\xD9\x83\xFA\x02") 86 | //F_N(lua_getallocf, 2, ?) 87 | //F_N(lua_setallocf, 3, ? ) 88 | 89 | F_DEF(luaL_openlib, "\x48\x89\x5C\x24\x20\x55\x56\x41\x56\x48\x83\xEC\x20") 90 | //F_DEF(luaL_register, 0x5BDB0) // "\x45\x33\xC9\xE9\x2A\x2A\x2A\x2A\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC" function is too short... 91 | //F_N(luaL_getmetafield, 3, ?) 92 | F_DEF(luaL_callmeta, "\x48\x89\x5C\x24\x10\x48\x89\x6C\x24\x18\x56\x57\x41\x56\x48\x83\xEC\x20\x48\x8B\x59\x10\x48\x8B\xF1") 93 | //F_DEF(luaL_typerror, 0x58100) // "\x48\x83\x23\xEC\x28\xE8\x2A\x2A\x2A\x2A\xCC" function is too short... 94 | //F_DEF(luaL_argerror, 0x580C0) // "\x48\x83\xEC\x28\xE8\x2A\x2A\x2A\x2A\xCC" function is too short... 95 | F_DEF(luaL_checklstring, "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x20\x49\x8B\xF0") 96 | F_DEF(luaL_optlstring, "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x20\x49\x8B\xF1") 97 | F_DEF(luaL_checknumber, "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x8B\xDA\x48\x8B\xF9\xE8\x2A\x2A\x2A\x2A\x48\x8B\x08\x4C\x8B\xC1\x49\xC1\xF8\x2F\x41\x83\xF8\xF2\x77\x2A\xF2\x0F\x10\x00\x48\x8B\x5C\x24\x30\x48\x83\xC4\x20\x5F\xC3\x41\x83\xF8\xFB") 98 | F_DEF(luaL_optnumber, "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x8B\xDA\x48\x8B\xF9\xE8\x2A\x2A\x2A\x2A\x48\x8B\x08\x4C\x8B\xC1\x49\xC1\xF8\x2F\x41\x83\xF8\xF2\x77\x2A\xF2\x0F\x10\x00\x48\x8B\x5C\x24\x30\x48\x83\xC4\x20\x5F\xC3\x48\x83\xF9\xFF") 99 | //F_N(luaL_checkinteger, 2, ?) 100 | F_DEF(luaL_optinteger, "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x4D\x8B\xD0\x8B\xDA") 101 | 102 | F_DEF(luaL_checkstack, "\x48\x83\xEC\x28\x4C\x8B\xD1\x81\xFA\x40\x1F\x00\x00") 103 | F_DEF(luaL_checktype, "\x40\x53\x48\x83\xEC\x20\x45\x8B\xD8") 104 | //F_N(luaL_checkany, 3, ?) 105 | F_DEF(luaL_newmetatable, "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x20\x48\x8B\x41\x10\x48\x8B\xD9") 106 | F_DEF(luaL_checkudata, "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x41\x56\x48\x83\xEC\x20\x49\x8B\xD8") 107 | F_DEF(luaL_where, "\x40\x53\x48\x83\xEC\x20\x4C\x8D\x44\x24\x40") 108 | //F_N(luaL_error, 2, "\x40\x53\x48\x83\xEC\x20\x4C\x8D\x44\x24\x40") 109 | //F_N(luaL_checkoption, 4, ?) 110 | F_DEF(luaL_ref, "\x48\x89\x5C\x24\x10\x57\x48\x83\xEC\x20\x8D\x82\x0F\x27\x00\x00") 111 | F_DEF(luaL_unref, "\x45\x85\xC0\x78\x2A\x48\x89\x5C\x24\x08") 112 | F_DEF(luaL_loadfile, "\x40\x53\x56\x57\x48\x81\xEC\x00\x03\x00\x00") 113 | //F_N(luaL_loadbuffer, 4, ?) 114 | F_DEF(luaL_loadstring, "\x48\x89\x5C\x24\x08\x57\x48\x81\xEC\xF0\x00\x00\x00") 115 | F_DEF(luaL_newstate, "\x48\x83\xEC\x28\x33\xD2\xB9\x50\x4D\x00\x00") 116 | F_DEF(luaL_gsub, "\x40\x55\x53\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\xAC\x24\xA8\xFE\xFF\xFF") 117 | F_DEF(luaL_findtable, "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x41\x56\x41\x57\x48\x83\xEC\x20\x45\x8B\xF1") 118 | 119 | F_DEF(luaL_buffinit, "\x48\x8D\x42\x18\x48\x89\x4A\x10") 120 | F_DEF(luaL_prepbuffer, "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x4C\x8B\x01") 121 | F_DEF(luaL_addlstring, "\x40\x55\x57\x41\x57\x48\x83\xEC\x20\x48\x8B\xF9") 122 | //F_N(luaL_addstring, 2, ?) 123 | F_DEF(luaL_addvalue, "\x48\x89\x6C\x24\x20\x57\x48\x83\xEC\x20\x48\x8B\x69\x10") 124 | F_DEF(luaL_pushresult, "\x48\x89\x74\x24\x10\x48\x89\x7C\x24\x18\x41\x56\x48\x83\xEC\x20\x4C\x8B\x01") 125 | 126 | F_DEF(luaopen_base, "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xEC\x20\x48\x8B\x71\x48") 127 | F_DEF(luaopen_io, "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xEC\x20\x4C\x8D\x0D\x2A\x2A\x0A\x00") 128 | //F_N(luaopen_os, 1, ?) 129 | F_DEF(luaopen_string, "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xEC\x20\x4C\x8D\x0D\x2A\x2A\x0A\x00") 130 | F_DEF(luaopen_math, "\x40\x53\x48\x83\xEC\x20\xBA\x20\x00\x00\x00") 131 | F_DEF(luaopen_debug, "\x48\x83\xEC\x28\x4C\x8D\x0D\x2A\x2A\x0A\x00") 132 | F_DEF(luaopen_package, "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x48\x89\x7C\x24\x18\x41\x56\x48\x83\xEC\x30\x48\x8D\x15\x2A\x2A\x0A\x00") 133 | F_DEF(luaopen_bit, "\x48\x83\xEC\x28\x4C\x8D\x0D\x05\x35\x0A\x00") // find by "rshift" 134 | F_DEF(luaopen_ffi, "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x41\x56\x41\x57\x48\x83\xEC\x20\x48\x8B\xE9") // find by "Windows" & "x64" 135 | F_DEF(luaopen_string_buffer, "\x40\x53\x48\x83\xEC\x20\x4C\x8D\x0D\xD3\x11\x09\x00") // called in luaopen_string 136 | 137 | F_DEF(luaJIT_setmode, "\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xEC\x20\x48\x8B\x79\x10\x4C\x8B\xC9") 138 | 139 | F_DEF(lua_getstack, "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x48\x89\x7C\x24\x18\x4C\x8B\x59\x38") 140 | F_DEF(lua_getinfo, "\x48\x89\x5C\x24\x08\x44\x89\x4C\x24\x20\x55") 141 | F_DEF(lua_getlocal, "\x40\x53\x48\x83\xEC\x20\x48\xC7\x44\x24\x38\x00\x00\x00\x00") 142 | F_DEF(lua_setlocal, "\x40\x53\x48\x83\xEC\x20\x45\x8B\xC8") 143 | F_DEF(lua_getupvalue, "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x30\x48\x8B\xD9\x45\x8D\x50\xFF") 144 | F_DEF(lua_setupvalue, "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x30\x45\x8B\xD0") 145 | 146 | F_DEF(lua_sethook, "\x48\x83\xEC\x28\x48\x8B\x49\x10") 147 | F_DEF(lua_gethook, "\x48\x8B\x41\x10\x48\x8B\x80\x50\x01\x00\x00") 148 | F_DEF(lua_gethookmask, "\x48\x8B\x41\x10\x0F\xB6\x80\x91\x00\x00\x00") 149 | F_DEF(lua_gethookcount, "\x48\x8B\x41\x10\x8B\x80\x4C\x01\x00\x00") 150 | 151 | //F_N(luaL_openlibs, 1, ?) 152 | -------------------------------------------------------------------------------- /vscript_lua51.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | extern "C" { 5 | #define LUA_BUILD_AS_DLL 6 | #define LUA_CORE 7 | #include "lua.h" 8 | #include "lualib.h" 9 | #include "lauxlib.h" 10 | } 11 | 12 | #include "metahook.h" 13 | 14 | inline ptrdiff_t FindFunction(const char* funcname, ptrdiff_t offset) 15 | { 16 | auto hModule = LoadLibrary("vscript2.dll"); 17 | BYTE* pBase = (BYTE*)MH_GetModuleBase(hModule); 18 | auto dwModuleSize = MH_GetModuleSize(hModule); 19 | auto addr = pBase + offset; 20 | return (ptrdiff_t)addr; 21 | } 22 | 23 | template 24 | inline ptrdiff_t FindFunction(const char *funcname, const char(&pattern)[N]) 25 | { 26 | auto hModule = LoadLibrary("vscript2.dll"); 27 | BYTE* pBase = (BYTE*)MH_GetModuleBase(hModule); 28 | auto dwModuleSize = MH_GetModuleSize(hModule); 29 | VirtualProtect(pBase, dwModuleSize, PAGE_EXECUTE_READWRITE, NULL); 30 | auto addr = MH_SearchPattern(pBase, dwModuleSize, pattern, N - 1); 31 | if (!addr) 32 | { 33 | char buffer[256]; 34 | snprintf(buffer, sizeof(buffer), "Error: signature not found for %s", funcname); 35 | MessageBoxA(NULL, buffer, "vscript_lua51", MB_ICONINFORMATION); 36 | } 37 | return (ptrdiff_t)addr; 38 | } 39 | 40 | #define F_DEF(FUNCNAME, ...) ptrdiff_t g_addr_##FUNCNAME; 41 | #include "signatures.h" 42 | #undef F_DEF 43 | 44 | bool SearchSignatures() 45 | { 46 | bool failed = false; 47 | #define F_DEF(FUNCNAME, ...) \ 48 | if(g_addr_##FUNCNAME == 0) \ 49 | { \ 50 | g_addr_##FUNCNAME = FindFunction(#FUNCNAME, __VA_ARGS__); \ 51 | failed = failed || (g_addr_##FUNCNAME == 0); \ 52 | } 53 | 54 | #include "signatures.h" 55 | #undef F_DEF 56 | return !failed; 57 | } 58 | std::once_flag g_bSearchSignaturesCalled; 59 | 60 | typedef union TValue TValue; 61 | typedef const TValue cTValue; 62 | 63 | // declearation for internal methods 64 | static TValue* index2adr(lua_State* L, int idx); 65 | int lj_obj_equal(cTValue* o1, cTValue* o2); 66 | void lj_err_callermsg(lua_State* L, const char* msg); 67 | int luaL_loadbufferx(lua_State* L, const char* buff, size_t sz, const char* name, const char* mode); 68 | void lj_err_run(lua_State* L); 69 | void lj_err_argtype(lua_State* L, int narg, const char* xname); 70 | static void err_argmsg(lua_State* L, int narg, const char* msg); 71 | 72 | // take back luajit functions 73 | extern "C" { 74 | LUALIB_API int luaopen_bit(lua_State* L); 75 | //LUALIB_API int luaopen_jit(lua_State* L); 76 | LUALIB_API int luaopen_ffi(lua_State* L); 77 | LUALIB_API int luaopen_string_buffer(lua_State* L); 78 | 79 | LUA_API int luaJIT_setmode(lua_State* L, int idx, int mode); 80 | } 81 | 82 | // implementation for default functions 83 | 84 | LUA_API void (lua_replace)(lua_State* L, int idx) 85 | { 86 | // TODO : is this right? 87 | lua_remove(L, idx); 88 | lua_insert(L, idx); 89 | } 90 | 91 | LUA_API int (lua_isuserdata)(lua_State* L, int idx) 92 | { 93 | return lua_type(L, idx) == LUA_TLIGHTUSERDATA || lua_type(L, idx) == LUA_TUSERDATA; 94 | } 95 | 96 | LUA_API int (lua_rawequal)(lua_State* L, int idx1, int idx2) 97 | { 98 | TValue* ptr1 = index2adr(L, idx1); 99 | TValue* ptr2 = index2adr(L, idx2); 100 | 101 | BYTE* gState = *(BYTE**)((BYTE*)L + 0x10); 102 | void* luaNull = (void*)(gState + 0xf8); 103 | 104 | if (ptr1 != luaNull && ptr2 != luaNull) { 105 | return lj_obj_equal(ptr1, ptr2); 106 | } 107 | return false; 108 | } 109 | 110 | #define LJ_TFUNC (~8u) 111 | #define itype(o) ((uint32_t)(*(int64_t *)(o) >> 47)) 112 | #define tvisfunc(o) (itype(o) == LJ_TFUNC) 113 | #define LJ_GCVMASK 0x7FFFFFFFFFFFULL 114 | 115 | LUA_API lua_CFunction(lua_tocfunction) (lua_State* L, int idx) 116 | { 117 | TValue* o = index2adr(L, idx); 118 | uintptr_t gcptr = (*(int64_t *)o & LJ_GCVMASK); 119 | 120 | if (tvisfunc(o)) { 121 | BYTE op = **(BYTE**)(gcptr + 32); 122 | if (op == 95 || op == 96) 123 | return (lua_CFunction)(gcptr + 40); 124 | } 125 | return nullptr; 126 | } 127 | 128 | LUA_API lua_State* (lua_tothread)(lua_State* L, int idx) 129 | { 130 | // TODO : not yet implemented 131 | abort(); 132 | } 133 | 134 | LUA_API const void* (lua_topointer)(lua_State* L, int idx) 135 | { 136 | // TODO : not yet implemented 137 | abort(); 138 | } 139 | 140 | // implementation for other apis 141 | LUA_API const char* (lua_pushfstring)(lua_State* L, const char* fmt, ...) 142 | { 143 | const char* ret; 144 | va_list argp; 145 | va_start(argp, fmt); 146 | ret = lua_pushvfstring(L, fmt, argp); 147 | va_end(argp); 148 | return ret; 149 | } 150 | 151 | LUA_API int (lua_dump)(lua_State* L, lua_Writer writer, void* data) 152 | { 153 | // TODO : not yet implemented 154 | return luaL_error(L, "lua_dump : not yet implemented"); 155 | } 156 | 157 | LUA_API int (lua_yield)(lua_State* L, int nresults) 158 | { 159 | // TODO : not yet implemented 160 | abort(); 161 | } 162 | 163 | LUA_API int (lua_resume)(lua_State* L, int narg) 164 | { 165 | // TODO : not yet implemented 166 | abort(); 167 | } 168 | 169 | LUA_API int (lua_status)(lua_State* L) 170 | { 171 | // TODO : not yet implemented 172 | abort(); 173 | } 174 | 175 | LUA_API lua_Alloc(lua_getallocf) (lua_State* L, void** ud) 176 | { 177 | BYTE* gState = *(BYTE**)((BYTE*)L + 0x10); 178 | if (ud != nullptr) { 179 | *ud = *(void**)(gState + 0x18); 180 | } 181 | return *(lua_Alloc*)(gState + 0x10); 182 | } 183 | 184 | LUA_API void lua_setallocf(lua_State* L, lua_Alloc f, void* ud) 185 | { 186 | BYTE* gState = *(BYTE**)((BYTE*)L + 0x10); 187 | *(void**)(gState + 0x18) = ud; 188 | *(lua_Alloc*)(gState + 0x10) = f; 189 | } 190 | 191 | LUALIB_API int (luaL_getmetafield)(lua_State* L, int obj, const char* e) 192 | { 193 | if (!lua_getmetatable(L, obj)) /* no metatable? */ 194 | return 0; 195 | lua_pushstring(L, e); 196 | lua_rawget(L, -2); 197 | if (lua_isnil(L, -1)) { 198 | lua_pop(L, 2); /* remove metatable and metafield */ 199 | return 0; 200 | } 201 | else { 202 | lua_remove(L, -2); /* remove only metatable */ 203 | return 1; 204 | } 205 | } 206 | 207 | LUALIB_API lua_Integer(luaL_checkinteger) (lua_State* L, int numArg) 208 | { 209 | return luaL_optinteger(L, numArg, 0); 210 | } 211 | 212 | LUALIB_API void (luaL_checkany)(lua_State* L, int narg) 213 | { 214 | if (lua_type(L, narg) == LUA_TNONE) 215 | { 216 | luaL_argerror(L, narg, "value expected"); 217 | } 218 | } 219 | 220 | LUALIB_API int (luaL_error)(lua_State* L, const char* fmt, ...) // variadic 221 | { 222 | const char* msg; 223 | va_list argp; 224 | va_start(argp, fmt); 225 | msg = lua_pushvfstring(L, fmt, argp); 226 | va_end(argp); 227 | lj_err_callermsg(L, msg); 228 | return 0; /* unreachable */ 229 | } 230 | 231 | LUALIB_API int (luaL_checkoption)(lua_State* L, int narg, const char* def, const char* const lst[]) 232 | { 233 | ptrdiff_t i; 234 | const char* s = lua_tolstring(L, narg, NULL); 235 | if (s == NULL && (s = def) == NULL) 236 | luaL_typerror(L, narg, lua_typename(L, LUA_TSTRING)); 237 | for (i = 0; lst[i]; i++) 238 | if (strcmp(lst[i], s) == 0) 239 | return (int)i; 240 | return luaL_argerror(L, narg, lua_pushfstring(L, "invalid option %s", s)); 241 | } 242 | 243 | LUALIB_API int (luaL_loadbuffer)(lua_State* L, const char* buff, size_t sz, const char* name) // not found 244 | { 245 | return luaL_loadbufferx(L, buff, sz, name, NULL); 246 | } 247 | 248 | LUALIB_API int (luaopen_os)(lua_State* L) // not found 249 | { 250 | return luaL_error(L, "luaopen_os : not yet implemented"); 251 | } 252 | 253 | LUALIB_API int (luaopen_jit)(lua_State* L) // not found 254 | { 255 | return luaL_error(L, "luaopen_jit : not yet implemented"); 256 | } 257 | 258 | LUALIB_API void (luaL_openlibs)(lua_State* L) // inlined 259 | { 260 | luaL_error(L, "luaopen_os : not yet implemented"); 261 | } 262 | 263 | LUA_API int lua_error(lua_State* L) 264 | { 265 | lj_err_run(L); 266 | return 0; /* unreachable */ 267 | } 268 | 269 | LUALIB_API void luaL_register(lua_State* L, const char* libname, const luaL_Reg* l) 270 | { 271 | luaL_openlib(L, libname, l, 0); 272 | } 273 | 274 | LUALIB_API int luaL_argerror(lua_State* L, int narg, const char* msg) 275 | { 276 | err_argmsg(L, narg, msg); 277 | return 0; /* unreachable */ 278 | } 279 | 280 | LUALIB_API int luaL_typerror(lua_State* L, int narg, const char* xname) 281 | { 282 | lj_err_argtype(L, narg, xname); 283 | return 0; /* unreachable */ 284 | } 285 | 286 | // find signature 287 | 288 | template struct TypeIdentity { using type = T; }; 289 | template struct IntWrapper { static constexpr int value = N; }; 290 | struct Invalid {}; 291 | template struct Varadaic_GetN : TypeIdentity {}; 292 | template struct Varadaic_GetN<0, First, Rest...> : TypeIdentity {}; 293 | template struct Varadaic_GetN : Varadaic_GetN {}; 294 | template struct F_ReturnType; 295 | template struct F_ReturnType : TypeIdentity {}; 296 | template struct F_ArgType; 297 | template struct F_ArgType : Varadaic_GetN {}; 298 | template struct F_ArgNum; 299 | template struct F_ArgNum : IntWrapper {}; 300 | 301 | #define PP_TUPLE_FIRST(X, ...) X 302 | #define PP_TUPLE_REST(X, ...) __VA_ARGS__ 303 | #define PP_TUPLE_INVOKE(X, TUPLE) X TUPLE 304 | 305 | #define PP_CAT(a, b) PP_CAT_I(a, b) 306 | #define PP_CAT_I(a, b) PP_CAT_II(~, a ## b) 307 | #define PP_CAT_II(p, res) res 308 | #define PP_COMMA() , 309 | #define PP_EMPTY() 310 | #define PP_REPEAT_0(CTX, PATTERN, JOINER) 311 | #define PP_REPEAT_1(CTX, PATTERN, JOINER) PATTERN(CTX, 0) 312 | #define PP_REPEAT_2(CTX, PATTERN, JOINER) PP_REPEAT_1(CTX, PATTERN, JOINER) JOINER() PATTERN(CTX, 1) 313 | #define PP_REPEAT_3(CTX, PATTERN, JOINER) PP_REPEAT_2(CTX, PATTERN, JOINER) JOINER() PATTERN(CTX, 2) 314 | #define PP_REPEAT_4(CTX, PATTERN, JOINER) PP_REPEAT_3(CTX, PATTERN, JOINER) JOINER() PATTERN(CTX, 3) 315 | #define PP_REPEAT_5(CTX, PATTERN, JOINER) PP_REPEAT_4(CTX, PATTERN, JOINER) JOINER() PATTERN(CTX, 4) 316 | #define PP_REPEAT_6(CTX, PATTERN, JOINER) PP_REPEAT_5(CTX, PATTERN, JOINER) JOINER() PATTERN(CTX, 5) 317 | #define PP_REPEAT_N(CTX, PATTERN, JOINER, N) PP_TUPLE_INVOKE(PP_CAT(PP_REPEAT_,N),(CTX, PATTERN, JOINER)) 318 | #define PP_REPEAT_MAX 6 319 | 320 | #define ARG_N(FUNCTYPE, N) _##N 321 | #define ARG_DEF_N(FUNCTYPE, N) typename F_ArgType::type ARG_N(FUNCTYPE, N) 322 | #define F_N(FUNCNAME, N, ...) \ 323 | extern "C" LUA_API typename F_ReturnType::type (FUNCNAME)(PP_REPEAT_N(FUNCNAME, ARG_DEF_N, PP_COMMA, N)) \ 324 | { \ 325 | static const auto pfn = (decltype(FUNCNAME)*)FindFunction(#FUNCNAME, __VA_ARGS__); \ 326 | return pfn(PP_REPEAT_N(FUNCNAME, ARG_N, PP_COMMA, N)); \ 327 | } 328 | 329 | #define F_DEF_HELPER_N(FUNCNAME, N) \ 330 | template struct PP_CAT(FUNCNAME,_FuncDefHelper) \ 331 | { \ 332 | friend typename F_ReturnType::type \ 333 | (FUNCNAME)(PP_REPEAT_N(DependentFunctionType, ARG_DEF_N, PP_COMMA, N)) \ 334 | { \ 335 | return PP_CAT(FUNCNAME,_FindFunctionHelper)()(PP_REPEAT_N(DependentFunctionType, ARG_N, PP_COMMA, N)); \ 336 | } \ 337 | }; 338 | 339 | #define F_DEF(FUNCNAME, ...) \ 340 | static decltype(FUNCNAME) *PP_CAT(FUNCNAME,_FindFunctionHelper) () \ 341 | { \ 342 | std::call_once(g_bSearchSignaturesCalled, SearchSignatures); \ 343 | static auto pfn = reinterpret_cast(g_addr_##FUNCNAME); \ 344 | return pfn; \ 345 | } \ 346 | template struct PP_CAT(FUNCNAME,_FuncDefHelper); \ 347 | PP_REPEAT_N(FUNCNAME, F_DEF_HELPER_N, PP_EMPTY, PP_REPEAT_MAX) \ 348 | template struct PP_CAT(FUNCNAME,_FuncDefHelper)::value>; 349 | 350 | #include "signatures.h" 351 | #undef F_DEF -------------------------------------------------------------------------------- /lua.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lua.h,v 1.218.1.7 2012/01/13 20:36:20 roberto Exp $ 3 | ** Lua - An Extensible Extension Language 4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) 5 | ** See Copyright Notice at the end of this file 6 | */ 7 | 8 | 9 | #ifndef lua_h 10 | #define lua_h 11 | 12 | #include 13 | #include 14 | 15 | 16 | #include "luaconf.h" 17 | 18 | 19 | #define LUA_VERSION "Lua 5.1" 20 | #define LUA_RELEASE "Lua 5.1.5" 21 | #define LUA_VERSION_NUM 501 22 | #define LUA_COPYRIGHT "Copyright (C) 1994-2012 Lua.org, PUC-Rio" 23 | #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" 24 | 25 | 26 | /* mark for precompiled code (`Lua') */ 27 | #define LUA_SIGNATURE "\033Lua" 28 | 29 | /* option for multiple returns in `lua_pcall' and `lua_call' */ 30 | #define LUA_MULTRET (-1) 31 | 32 | 33 | /* 34 | ** pseudo-indices 35 | */ 36 | #define LUA_REGISTRYINDEX (-10000) 37 | #define LUA_ENVIRONINDEX (-10001) 38 | #define LUA_GLOBALSINDEX (-10002) 39 | #define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) 40 | 41 | 42 | /* thread status; 0 is OK */ 43 | #define LUA_YIELD 1 44 | #define LUA_ERRRUN 2 45 | #define LUA_ERRSYNTAX 3 46 | #define LUA_ERRMEM 4 47 | #define LUA_ERRERR 5 48 | 49 | 50 | typedef struct lua_State lua_State; 51 | 52 | typedef int (*lua_CFunction) (lua_State *L); 53 | 54 | 55 | /* 56 | ** functions that read/write blocks when loading/dumping Lua chunks 57 | */ 58 | typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); 59 | 60 | typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); 61 | 62 | 63 | /* 64 | ** prototype for memory-allocation functions 65 | */ 66 | typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); 67 | 68 | 69 | /* 70 | ** basic types 71 | */ 72 | #define LUA_TNONE (-1) 73 | 74 | #define LUA_TNIL 0 75 | #define LUA_TBOOLEAN 1 76 | #define LUA_TLIGHTUSERDATA 2 77 | #define LUA_TNUMBER 3 78 | #define LUA_TSTRING 4 79 | #define LUA_TTABLE 5 80 | #define LUA_TFUNCTION 6 81 | #define LUA_TUSERDATA 7 82 | #define LUA_TTHREAD 8 83 | 84 | 85 | 86 | /* minimum Lua stack available to a C function */ 87 | #define LUA_MINSTACK 20 88 | 89 | 90 | /* 91 | ** generic extra include file 92 | */ 93 | #if defined(LUA_USER_H) 94 | #include LUA_USER_H 95 | #endif 96 | 97 | 98 | /* type of numbers in Lua */ 99 | typedef LUA_NUMBER lua_Number; 100 | 101 | 102 | /* type for integer functions */ 103 | typedef LUA_INTEGER lua_Integer; 104 | 105 | 106 | 107 | /* 108 | ** state manipulation 109 | */ 110 | LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); 111 | LUA_API void (lua_close) (lua_State *L); 112 | LUA_API lua_State *(lua_newthread) (lua_State *L); 113 | 114 | LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); 115 | 116 | 117 | /* 118 | ** basic stack manipulation 119 | */ 120 | LUA_API int (lua_gettop) (lua_State *L); 121 | LUA_API void (lua_settop) (lua_State *L, int idx); 122 | LUA_API void (lua_pushvalue) (lua_State *L, int idx); 123 | LUA_API void (lua_remove) (lua_State *L, int idx); 124 | LUA_API void (lua_insert) (lua_State *L, int idx); 125 | LUA_API void (lua_replace) (lua_State *L, int idx); 126 | LUA_API int (lua_checkstack) (lua_State *L, int sz); 127 | 128 | LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); 129 | 130 | 131 | /* 132 | ** access functions (stack -> C) 133 | */ 134 | 135 | LUA_API int (lua_isnumber) (lua_State *L, int idx); 136 | LUA_API int (lua_isstring) (lua_State *L, int idx); 137 | LUA_API int (lua_iscfunction) (lua_State *L, int idx); 138 | LUA_API int (lua_isuserdata) (lua_State *L, int idx); 139 | LUA_API int (lua_type) (lua_State *L, int idx); 140 | LUA_API const char *(lua_typename) (lua_State *L, int tp); 141 | 142 | LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2); 143 | LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); 144 | LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2); 145 | 146 | LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx); 147 | LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx); 148 | LUA_API int (lua_toboolean) (lua_State *L, int idx); 149 | LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); 150 | LUA_API size_t (lua_objlen) (lua_State *L, int idx); 151 | LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); 152 | LUA_API void *(lua_touserdata) (lua_State *L, int idx); 153 | LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); 154 | LUA_API const void *(lua_topointer) (lua_State *L, int idx); 155 | 156 | 157 | /* 158 | ** push functions (C -> stack) 159 | */ 160 | LUA_API void (lua_pushnil) (lua_State *L); 161 | LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); 162 | LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); 163 | LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l); 164 | LUA_API void (lua_pushstring) (lua_State *L, const char *s); 165 | LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, 166 | va_list argp); 167 | LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); 168 | LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); 169 | LUA_API void (lua_pushboolean) (lua_State *L, int b); 170 | LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); 171 | LUA_API int (lua_pushthread) (lua_State *L); 172 | 173 | 174 | /* 175 | ** get functions (Lua -> stack) 176 | */ 177 | LUA_API void (lua_gettable) (lua_State *L, int idx); 178 | LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); 179 | LUA_API void (lua_rawget) (lua_State *L, int idx); 180 | LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); 181 | LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); 182 | LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); 183 | LUA_API int (lua_getmetatable) (lua_State *L, int objindex); 184 | LUA_API void (lua_getfenv) (lua_State *L, int idx); 185 | 186 | 187 | /* 188 | ** set functions (stack -> Lua) 189 | */ 190 | LUA_API void (lua_settable) (lua_State *L, int idx); 191 | LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); 192 | LUA_API void (lua_rawset) (lua_State *L, int idx); 193 | LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); 194 | LUA_API int (lua_setmetatable) (lua_State *L, int objindex); 195 | LUA_API int (lua_setfenv) (lua_State *L, int idx); 196 | 197 | 198 | /* 199 | ** `load' and `call' functions (load and run Lua code) 200 | */ 201 | LUA_API void (lua_call) (lua_State *L, int nargs, int nresults); 202 | LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); 203 | LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); 204 | LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, 205 | const char *chunkname); 206 | 207 | LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); 208 | 209 | 210 | /* 211 | ** coroutine functions 212 | */ 213 | LUA_API int (lua_yield) (lua_State *L, int nresults); 214 | LUA_API int (lua_resume) (lua_State *L, int narg); 215 | LUA_API int (lua_status) (lua_State *L); 216 | 217 | /* 218 | ** garbage-collection function and options 219 | */ 220 | 221 | #define LUA_GCSTOP 0 222 | #define LUA_GCRESTART 1 223 | #define LUA_GCCOLLECT 2 224 | #define LUA_GCCOUNT 3 225 | #define LUA_GCCOUNTB 4 226 | #define LUA_GCSTEP 5 227 | #define LUA_GCSETPAUSE 6 228 | #define LUA_GCSETSTEPMUL 7 229 | 230 | LUA_API int (lua_gc) (lua_State *L, int what, int data); 231 | 232 | 233 | /* 234 | ** miscellaneous functions 235 | */ 236 | 237 | LUA_API int (lua_error) (lua_State *L); 238 | 239 | LUA_API int (lua_next) (lua_State *L, int idx); 240 | 241 | LUA_API void (lua_concat) (lua_State *L, int n); 242 | 243 | LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); 244 | LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); 245 | 246 | 247 | 248 | /* 249 | ** =============================================================== 250 | ** some useful macros 251 | ** =============================================================== 252 | */ 253 | 254 | #define lua_pop(L,n) lua_settop(L, -(n)-1) 255 | 256 | #define lua_newtable(L) lua_createtable(L, 0, 0) 257 | 258 | #define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) 259 | 260 | #define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) 261 | 262 | #define lua_strlen(L,i) lua_objlen(L, (i)) 263 | 264 | #define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) 265 | #define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) 266 | #define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) 267 | #define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) 268 | #define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) 269 | #define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) 270 | #define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) 271 | #define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) 272 | 273 | #define lua_pushliteral(L, s) \ 274 | lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) 275 | 276 | #define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) 277 | #define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) 278 | 279 | #define lua_tostring(L,i) lua_tolstring(L, (i), NULL) 280 | 281 | 282 | 283 | /* 284 | ** compatibility macros and functions 285 | */ 286 | 287 | #define lua_open() luaL_newstate() 288 | 289 | #define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) 290 | 291 | #define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0) 292 | 293 | #define lua_Chunkreader lua_Reader 294 | #define lua_Chunkwriter lua_Writer 295 | 296 | 297 | /* hack */ 298 | LUA_API void lua_setlevel (lua_State *from, lua_State *to); 299 | 300 | 301 | /* 302 | ** {====================================================================== 303 | ** Debug API 304 | ** ======================================================================= 305 | */ 306 | 307 | 308 | /* 309 | ** Event codes 310 | */ 311 | #define LUA_HOOKCALL 0 312 | #define LUA_HOOKRET 1 313 | #define LUA_HOOKLINE 2 314 | #define LUA_HOOKCOUNT 3 315 | #define LUA_HOOKTAILRET 4 316 | 317 | 318 | /* 319 | ** Event masks 320 | */ 321 | #define LUA_MASKCALL (1 << LUA_HOOKCALL) 322 | #define LUA_MASKRET (1 << LUA_HOOKRET) 323 | #define LUA_MASKLINE (1 << LUA_HOOKLINE) 324 | #define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) 325 | 326 | typedef struct lua_Debug lua_Debug; /* activation record */ 327 | 328 | 329 | /* Functions to be called by the debuger in specific events */ 330 | typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); 331 | 332 | 333 | LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); 334 | LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); 335 | LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); 336 | LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); 337 | LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); 338 | LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n); 339 | 340 | LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); 341 | LUA_API lua_Hook lua_gethook (lua_State *L); 342 | LUA_API int lua_gethookmask (lua_State *L); 343 | LUA_API int lua_gethookcount (lua_State *L); 344 | 345 | 346 | struct lua_Debug { 347 | int event; 348 | const char *name; /* (n) */ 349 | const char *namewhat; /* (n) `global', `local', `field', `method' */ 350 | const char *what; /* (S) `Lua', `C', `main', `tail' */ 351 | const char *source; /* (S) */ 352 | int currentline; /* (l) */ 353 | int nups; /* (u) number of upvalues */ 354 | int linedefined; /* (S) */ 355 | int lastlinedefined; /* (S) */ 356 | char short_src[LUA_IDSIZE]; /* (S) */ 357 | /* private part */ 358 | int i_ci; /* active function */ 359 | }; 360 | 361 | /* }====================================================================== */ 362 | 363 | 364 | /****************************************************************************** 365 | * Copyright (C) 1994-2012 Lua.org, PUC-Rio. All rights reserved. 366 | * 367 | * Permission is hereby granted, free of charge, to any person obtaining 368 | * a copy of this software and associated documentation files (the 369 | * "Software"), to deal in the Software without restriction, including 370 | * without limitation the rights to use, copy, modify, merge, publish, 371 | * distribute, sublicense, and/or sell copies of the Software, and to 372 | * permit persons to whom the Software is furnished to do so, subject to 373 | * the following conditions: 374 | * 375 | * The above copyright notice and this permission notice shall be 376 | * included in all copies or substantial portions of the Software. 377 | * 378 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 379 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 380 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 381 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 382 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 383 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 384 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 385 | ******************************************************************************/ 386 | 387 | 388 | #endif 389 | -------------------------------------------------------------------------------- /luaconf.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: luaconf.h,v 1.82.1.7 2008/02/11 16:25:08 roberto Exp $ 3 | ** Configuration file for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lconfig_h 9 | #define lconfig_h 10 | 11 | #include 12 | #include 13 | 14 | 15 | /* 16 | ** ================================================================== 17 | ** Search for "@@" to find all configurable definitions. 18 | ** =================================================================== 19 | */ 20 | 21 | 22 | /* 23 | @@ LUA_ANSI controls the use of non-ansi features. 24 | ** CHANGE it (define it) if you want Lua to avoid the use of any 25 | ** non-ansi feature or library. 26 | */ 27 | #if defined(__STRICT_ANSI__) 28 | #define LUA_ANSI 29 | #endif 30 | 31 | 32 | #if !defined(LUA_ANSI) && defined(_WIN32) 33 | #define LUA_WIN 34 | #endif 35 | 36 | #if defined(LUA_USE_LINUX) 37 | #define LUA_USE_POSIX 38 | #define LUA_USE_DLOPEN /* needs an extra library: -ldl */ 39 | #define LUA_USE_READLINE /* needs some extra libraries */ 40 | #endif 41 | 42 | #if defined(LUA_USE_MACOSX) 43 | #define LUA_USE_POSIX 44 | #define LUA_DL_DYLD /* does not need extra library */ 45 | #endif 46 | 47 | 48 | 49 | /* 50 | @@ LUA_USE_POSIX includes all functionallity listed as X/Open System 51 | @* Interfaces Extension (XSI). 52 | ** CHANGE it (define it) if your system is XSI compatible. 53 | */ 54 | #if defined(LUA_USE_POSIX) 55 | #define LUA_USE_MKSTEMP 56 | #define LUA_USE_ISATTY 57 | #define LUA_USE_POPEN 58 | #define LUA_USE_ULONGJMP 59 | #endif 60 | 61 | 62 | /* 63 | @@ LUA_PATH and LUA_CPATH are the names of the environment variables that 64 | @* Lua check to set its paths. 65 | @@ LUA_INIT is the name of the environment variable that Lua 66 | @* checks for initialization code. 67 | ** CHANGE them if you want different names. 68 | */ 69 | #define LUA_PATH "LUA_PATH" 70 | #define LUA_CPATH "LUA_CPATH" 71 | #define LUA_INIT "LUA_INIT" 72 | 73 | 74 | /* 75 | @@ LUA_PATH_DEFAULT is the default path that Lua uses to look for 76 | @* Lua libraries. 77 | @@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for 78 | @* C libraries. 79 | ** CHANGE them if your machine has a non-conventional directory 80 | ** hierarchy or if you want to install your libraries in 81 | ** non-conventional directories. 82 | */ 83 | #if defined(_WIN32) 84 | /* 85 | ** In Windows, any exclamation mark ('!') in the path is replaced by the 86 | ** path of the directory of the executable file of the current process. 87 | */ 88 | #define LUA_LDIR "!\\lua\\" 89 | #define LUA_CDIR "!\\" 90 | #define LUA_PATH_DEFAULT \ 91 | ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ 92 | LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua" 93 | #define LUA_CPATH_DEFAULT \ 94 | ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" 95 | 96 | #else 97 | #define LUA_ROOT "/usr/local/" 98 | #define LUA_LDIR LUA_ROOT "share/lua/5.1/" 99 | #define LUA_CDIR LUA_ROOT "lib/lua/5.1/" 100 | #define LUA_PATH_DEFAULT \ 101 | "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ 102 | LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" 103 | #define LUA_CPATH_DEFAULT \ 104 | "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so" 105 | #endif 106 | 107 | 108 | /* 109 | @@ LUA_DIRSEP is the directory separator (for submodules). 110 | ** CHANGE it if your machine does not use "/" as the directory separator 111 | ** and is not Windows. (On Windows Lua automatically uses "\".) 112 | */ 113 | #if defined(_WIN32) 114 | #define LUA_DIRSEP "\\" 115 | #else 116 | #define LUA_DIRSEP "/" 117 | #endif 118 | 119 | 120 | /* 121 | @@ LUA_PATHSEP is the character that separates templates in a path. 122 | @@ LUA_PATH_MARK is the string that marks the substitution points in a 123 | @* template. 124 | @@ LUA_EXECDIR in a Windows path is replaced by the executable's 125 | @* directory. 126 | @@ LUA_IGMARK is a mark to ignore all before it when bulding the 127 | @* luaopen_ function name. 128 | ** CHANGE them if for some reason your system cannot use those 129 | ** characters. (E.g., if one of those characters is a common character 130 | ** in file/directory names.) Probably you do not need to change them. 131 | */ 132 | #define LUA_PATHSEP ";" 133 | #define LUA_PATH_MARK "?" 134 | #define LUA_EXECDIR "!" 135 | #define LUA_IGMARK "-" 136 | 137 | 138 | /* 139 | @@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. 140 | ** CHANGE that if ptrdiff_t is not adequate on your machine. (On most 141 | ** machines, ptrdiff_t gives a good choice between int or long.) 142 | */ 143 | #define LUA_INTEGER ptrdiff_t 144 | 145 | 146 | /* 147 | @@ LUA_API is a mark for all core API functions. 148 | @@ LUALIB_API is a mark for all standard library functions. 149 | ** CHANGE them if you need to define those functions in some special way. 150 | ** For instance, if you want to create one Windows DLL with the core and 151 | ** the libraries, you may want to use the following definition (define 152 | ** LUA_BUILD_AS_DLL to get it). 153 | */ 154 | #if defined(LUA_BUILD_AS_DLL) 155 | 156 | #if defined(LUA_CORE) || defined(LUA_LIB) 157 | #define LUA_API __declspec(dllexport) 158 | #else 159 | #define LUA_API __declspec(dllimport) 160 | #endif 161 | 162 | #else 163 | 164 | #define LUA_API extern 165 | 166 | #endif 167 | 168 | /* more often than not the libs go together with the core */ 169 | #define LUALIB_API LUA_API 170 | 171 | 172 | /* 173 | @@ LUAI_FUNC is a mark for all extern functions that are not to be 174 | @* exported to outside modules. 175 | @@ LUAI_DATA is a mark for all extern (const) variables that are not to 176 | @* be exported to outside modules. 177 | ** CHANGE them if you need to mark them in some special way. Elf/gcc 178 | ** (versions 3.2 and later) mark them as "hidden" to optimize access 179 | ** when Lua is compiled as a shared library. 180 | */ 181 | #if defined(luaall_c) 182 | #define LUAI_FUNC static 183 | #define LUAI_DATA /* empty */ 184 | 185 | #elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ 186 | defined(__ELF__) 187 | #define LUAI_FUNC __attribute__((visibility("hidden"))) extern 188 | #define LUAI_DATA LUAI_FUNC 189 | 190 | #else 191 | #define LUAI_FUNC extern 192 | #define LUAI_DATA extern 193 | #endif 194 | 195 | 196 | 197 | /* 198 | @@ LUA_QL describes how error messages quote program elements. 199 | ** CHANGE it if you want a different appearance. 200 | */ 201 | #define LUA_QL(x) "'" x "'" 202 | #define LUA_QS LUA_QL("%s") 203 | 204 | 205 | /* 206 | @@ LUA_IDSIZE gives the maximum size for the description of the source 207 | @* of a function in debug information. 208 | ** CHANGE it if you want a different size. 209 | */ 210 | #define LUA_IDSIZE 60 211 | 212 | 213 | /* 214 | ** {================================================================== 215 | ** Stand-alone configuration 216 | ** =================================================================== 217 | */ 218 | 219 | #if defined(lua_c) || defined(luaall_c) 220 | 221 | /* 222 | @@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that 223 | @* is, whether we're running lua interactively). 224 | ** CHANGE it if you have a better definition for non-POSIX/non-Windows 225 | ** systems. 226 | */ 227 | #if defined(LUA_USE_ISATTY) 228 | #include 229 | #define lua_stdin_is_tty() isatty(0) 230 | #elif defined(LUA_WIN) 231 | #include 232 | #include 233 | #define lua_stdin_is_tty() _isatty(_fileno(stdin)) 234 | #else 235 | #define lua_stdin_is_tty() 1 /* assume stdin is a tty */ 236 | #endif 237 | 238 | 239 | /* 240 | @@ LUA_PROMPT is the default prompt used by stand-alone Lua. 241 | @@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua. 242 | ** CHANGE them if you want different prompts. (You can also change the 243 | ** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.) 244 | */ 245 | #define LUA_PROMPT "> " 246 | #define LUA_PROMPT2 ">> " 247 | 248 | 249 | /* 250 | @@ LUA_PROGNAME is the default name for the stand-alone Lua program. 251 | ** CHANGE it if your stand-alone interpreter has a different name and 252 | ** your system is not able to detect that name automatically. 253 | */ 254 | #define LUA_PROGNAME "lua" 255 | 256 | 257 | /* 258 | @@ LUA_MAXINPUT is the maximum length for an input line in the 259 | @* stand-alone interpreter. 260 | ** CHANGE it if you need longer lines. 261 | */ 262 | #define LUA_MAXINPUT 512 263 | 264 | 265 | /* 266 | @@ lua_readline defines how to show a prompt and then read a line from 267 | @* the standard input. 268 | @@ lua_saveline defines how to "save" a read line in a "history". 269 | @@ lua_freeline defines how to free a line read by lua_readline. 270 | ** CHANGE them if you want to improve this functionality (e.g., by using 271 | ** GNU readline and history facilities). 272 | */ 273 | #if defined(LUA_USE_READLINE) 274 | #include 275 | #include 276 | #include 277 | #define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) 278 | #define lua_saveline(L,idx) \ 279 | if (lua_strlen(L,idx) > 0) /* non-empty line? */ \ 280 | add_history(lua_tostring(L, idx)); /* add it to history */ 281 | #define lua_freeline(L,b) ((void)L, free(b)) 282 | #else 283 | #define lua_readline(L,b,p) \ 284 | ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ 285 | fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ 286 | #define lua_saveline(L,idx) { (void)L; (void)idx; } 287 | #define lua_freeline(L,b) { (void)L; (void)b; } 288 | #endif 289 | 290 | #endif 291 | 292 | /* }================================================================== */ 293 | 294 | 295 | /* 296 | @@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles 297 | @* as a percentage. 298 | ** CHANGE it if you want the GC to run faster or slower (higher values 299 | ** mean larger pauses which mean slower collection.) You can also change 300 | ** this value dynamically. 301 | */ 302 | #define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ 303 | 304 | 305 | /* 306 | @@ LUAI_GCMUL defines the default speed of garbage collection relative to 307 | @* memory allocation as a percentage. 308 | ** CHANGE it if you want to change the granularity of the garbage 309 | ** collection. (Higher values mean coarser collections. 0 represents 310 | ** infinity, where each step performs a full collection.) You can also 311 | ** change this value dynamically. 312 | */ 313 | #define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ 314 | 315 | 316 | 317 | /* 318 | @@ LUA_COMPAT_GETN controls compatibility with old getn behavior. 319 | ** CHANGE it (define it) if you want exact compatibility with the 320 | ** behavior of setn/getn in Lua 5.0. 321 | */ 322 | #undef LUA_COMPAT_GETN 323 | 324 | /* 325 | @@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib. 326 | ** CHANGE it to undefined as soon as you do not need a global 'loadlib' 327 | ** function (the function is still available as 'package.loadlib'). 328 | */ 329 | #undef LUA_COMPAT_LOADLIB 330 | 331 | /* 332 | @@ LUA_COMPAT_VARARG controls compatibility with old vararg feature. 333 | ** CHANGE it to undefined as soon as your programs use only '...' to 334 | ** access vararg parameters (instead of the old 'arg' table). 335 | */ 336 | #define LUA_COMPAT_VARARG 337 | 338 | /* 339 | @@ LUA_COMPAT_MOD controls compatibility with old math.mod function. 340 | ** CHANGE it to undefined as soon as your programs use 'math.fmod' or 341 | ** the new '%' operator instead of 'math.mod'. 342 | */ 343 | #define LUA_COMPAT_MOD 344 | 345 | /* 346 | @@ LUA_COMPAT_LSTR controls compatibility with old long string nesting 347 | @* facility. 348 | ** CHANGE it to 2 if you want the old behaviour, or undefine it to turn 349 | ** off the advisory error when nesting [[...]]. 350 | */ 351 | #define LUA_COMPAT_LSTR 1 352 | 353 | /* 354 | @@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name. 355 | ** CHANGE it to undefined as soon as you rename 'string.gfind' to 356 | ** 'string.gmatch'. 357 | */ 358 | #define LUA_COMPAT_GFIND 359 | 360 | /* 361 | @@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib' 362 | @* behavior. 363 | ** CHANGE it to undefined as soon as you replace to 'luaL_register' 364 | ** your uses of 'luaL_openlib' 365 | */ 366 | #define LUA_COMPAT_OPENLIB 367 | 368 | 369 | 370 | /* 371 | @@ luai_apicheck is the assert macro used by the Lua-C API. 372 | ** CHANGE luai_apicheck if you want Lua to perform some checks in the 373 | ** parameters it gets from API calls. This may slow down the interpreter 374 | ** a bit, but may be quite useful when debugging C code that interfaces 375 | ** with Lua. A useful redefinition is to use assert.h. 376 | */ 377 | #if defined(LUA_USE_APICHECK) 378 | #include 379 | #define luai_apicheck(L,o) { (void)L; assert(o); } 380 | #else 381 | #define luai_apicheck(L,o) { (void)L; } 382 | #endif 383 | 384 | 385 | /* 386 | @@ LUAI_BITSINT defines the number of bits in an int. 387 | ** CHANGE here if Lua cannot automatically detect the number of bits of 388 | ** your machine. Probably you do not need to change this. 389 | */ 390 | /* avoid overflows in comparison */ 391 | #if INT_MAX-20 < 32760 392 | #define LUAI_BITSINT 16 393 | #elif INT_MAX > 2147483640L 394 | /* int has at least 32 bits */ 395 | #define LUAI_BITSINT 32 396 | #else 397 | #error "you must define LUA_BITSINT with number of bits in an integer" 398 | #endif 399 | 400 | 401 | /* 402 | @@ LUAI_UINT32 is an unsigned integer with at least 32 bits. 403 | @@ LUAI_INT32 is an signed integer with at least 32 bits. 404 | @@ LUAI_UMEM is an unsigned integer big enough to count the total 405 | @* memory used by Lua. 406 | @@ LUAI_MEM is a signed integer big enough to count the total memory 407 | @* used by Lua. 408 | ** CHANGE here if for some weird reason the default definitions are not 409 | ** good enough for your machine. (The definitions in the 'else' 410 | ** part always works, but may waste space on machines with 64-bit 411 | ** longs.) Probably you do not need to change this. 412 | */ 413 | #if LUAI_BITSINT >= 32 414 | #define LUAI_UINT32 unsigned int 415 | #define LUAI_INT32 int 416 | #define LUAI_MAXINT32 INT_MAX 417 | #define LUAI_UMEM size_t 418 | #define LUAI_MEM ptrdiff_t 419 | #else 420 | /* 16-bit ints */ 421 | #define LUAI_UINT32 unsigned long 422 | #define LUAI_INT32 long 423 | #define LUAI_MAXINT32 LONG_MAX 424 | #define LUAI_UMEM unsigned long 425 | #define LUAI_MEM long 426 | #endif 427 | 428 | 429 | /* 430 | @@ LUAI_MAXCALLS limits the number of nested calls. 431 | ** CHANGE it if you need really deep recursive calls. This limit is 432 | ** arbitrary; its only purpose is to stop infinite recursion before 433 | ** exhausting memory. 434 | */ 435 | #define LUAI_MAXCALLS 20000 436 | 437 | 438 | /* 439 | @@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function 440 | @* can use. 441 | ** CHANGE it if you need lots of (Lua) stack space for your C 442 | ** functions. This limit is arbitrary; its only purpose is to stop C 443 | ** functions to consume unlimited stack space. (must be smaller than 444 | ** -LUA_REGISTRYINDEX) 445 | */ 446 | #define LUAI_MAXCSTACK 8000 447 | 448 | 449 | 450 | /* 451 | ** {================================================================== 452 | ** CHANGE (to smaller values) the following definitions if your system 453 | ** has a small C stack. (Or you may want to change them to larger 454 | ** values if your system has a large C stack and these limits are 455 | ** too rigid for you.) Some of these constants control the size of 456 | ** stack-allocated arrays used by the compiler or the interpreter, while 457 | ** others limit the maximum number of recursive calls that the compiler 458 | ** or the interpreter can perform. Values too large may cause a C stack 459 | ** overflow for some forms of deep constructs. 460 | ** =================================================================== 461 | */ 462 | 463 | 464 | /* 465 | @@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and 466 | @* syntactical nested non-terminals in a program. 467 | */ 468 | #define LUAI_MAXCCALLS 200 469 | 470 | 471 | /* 472 | @@ LUAI_MAXVARS is the maximum number of local variables per function 473 | @* (must be smaller than 250). 474 | */ 475 | #define LUAI_MAXVARS 200 476 | 477 | 478 | /* 479 | @@ LUAI_MAXUPVALUES is the maximum number of upvalues per function 480 | @* (must be smaller than 250). 481 | */ 482 | #define LUAI_MAXUPVALUES 60 483 | 484 | 485 | /* 486 | @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. 487 | */ 488 | #define LUAL_BUFFERSIZE BUFSIZ 489 | 490 | /* }================================================================== */ 491 | 492 | 493 | 494 | 495 | /* 496 | ** {================================================================== 497 | @@ LUA_NUMBER is the type of numbers in Lua. 498 | ** CHANGE the following definitions only if you want to build Lua 499 | ** with a number type different from double. You may also need to 500 | ** change lua_number2int & lua_number2integer. 501 | ** =================================================================== 502 | */ 503 | 504 | #define LUA_NUMBER_DOUBLE 505 | #define LUA_NUMBER double 506 | 507 | /* 508 | @@ LUAI_UACNUMBER is the result of an 'usual argument conversion' 509 | @* over a number. 510 | */ 511 | #define LUAI_UACNUMBER double 512 | 513 | 514 | /* 515 | @@ LUA_NUMBER_SCAN is the format for reading numbers. 516 | @@ LUA_NUMBER_FMT is the format for writing numbers. 517 | @@ lua_number2str converts a number to a string. 518 | @@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. 519 | @@ lua_str2number converts a string to a number. 520 | */ 521 | #define LUA_NUMBER_SCAN "%lf" 522 | #define LUA_NUMBER_FMT "%.14g" 523 | #define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) 524 | #define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ 525 | #define lua_str2number(s,p) strtod((s), (p)) 526 | 527 | 528 | /* 529 | @@ The luai_num* macros define the primitive operations over numbers. 530 | */ 531 | #if defined(LUA_CORE) 532 | #include 533 | #define luai_numadd(a,b) ((a)+(b)) 534 | #define luai_numsub(a,b) ((a)-(b)) 535 | #define luai_nummul(a,b) ((a)*(b)) 536 | #define luai_numdiv(a,b) ((a)/(b)) 537 | #define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) 538 | #define luai_numpow(a,b) (pow(a,b)) 539 | #define luai_numunm(a) (-(a)) 540 | #define luai_numeq(a,b) ((a)==(b)) 541 | #define luai_numlt(a,b) ((a)<(b)) 542 | #define luai_numle(a,b) ((a)<=(b)) 543 | #define luai_numisnan(a) (!luai_numeq((a), (a))) 544 | #endif 545 | 546 | 547 | /* 548 | @@ lua_number2int is a macro to convert lua_Number to int. 549 | @@ lua_number2integer is a macro to convert lua_Number to lua_Integer. 550 | ** CHANGE them if you know a faster way to convert a lua_Number to 551 | ** int (with any rounding method and without throwing errors) in your 552 | ** system. In Pentium machines, a naive typecast from double to int 553 | ** in C is extremely slow, so any alternative is worth trying. 554 | */ 555 | 556 | /* On a Pentium, resort to a trick */ 557 | #if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ 558 | (defined(__i386) || defined (_M_IX86) || defined(__i386__)) 559 | 560 | /* On a Microsoft compiler, use assembler */ 561 | #if defined(_MSC_VER) 562 | 563 | #define lua_number2int(i,d) __asm fld d __asm fistp i 564 | #define lua_number2integer(i,n) lua_number2int(i, n) 565 | 566 | /* the next trick should work on any Pentium, but sometimes clashes 567 | with a DirectX idiosyncrasy */ 568 | #else 569 | 570 | union luai_Cast { double l_d; long l_l; }; 571 | #define lua_number2int(i,d) \ 572 | { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } 573 | #define lua_number2integer(i,n) lua_number2int(i, n) 574 | 575 | #endif 576 | 577 | 578 | /* this option always works, but may be slow */ 579 | #else 580 | #define lua_number2int(i,d) ((i)=(int)(d)) 581 | #define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) 582 | 583 | #endif 584 | 585 | /* }================================================================== */ 586 | 587 | 588 | /* 589 | @@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment. 590 | ** CHANGE it if your system requires alignments larger than double. (For 591 | ** instance, if your system supports long doubles and they must be 592 | ** aligned in 16-byte boundaries, then you should add long double in the 593 | ** union.) Probably you do not need to change this. 594 | */ 595 | #define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } 596 | 597 | 598 | /* 599 | @@ LUAI_THROW/LUAI_TRY define how Lua does exception handling. 600 | ** CHANGE them if you prefer to use longjmp/setjmp even with C++ 601 | ** or if want/don't to use _longjmp/_setjmp instead of regular 602 | ** longjmp/setjmp. By default, Lua handles errors with exceptions when 603 | ** compiling as C++ code, with _longjmp/_setjmp when asked to use them, 604 | ** and with longjmp/setjmp otherwise. 605 | */ 606 | #if defined(__cplusplus) 607 | /* C++ exceptions */ 608 | #define LUAI_THROW(L,c) throw(c) 609 | #define LUAI_TRY(L,c,a) try { a } catch(...) \ 610 | { if ((c)->status == 0) (c)->status = -1; } 611 | #define luai_jmpbuf int /* dummy variable */ 612 | 613 | #elif defined(LUA_USE_ULONGJMP) 614 | /* in Unix, try _longjmp/_setjmp (more efficient) */ 615 | #define LUAI_THROW(L,c) _longjmp((c)->b, 1) 616 | #define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } 617 | #define luai_jmpbuf jmp_buf 618 | 619 | #else 620 | /* default handling with long jumps */ 621 | #define LUAI_THROW(L,c) longjmp((c)->b, 1) 622 | #define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } 623 | #define luai_jmpbuf jmp_buf 624 | 625 | #endif 626 | 627 | 628 | /* 629 | @@ LUA_MAXCAPTURES is the maximum number of captures that a pattern 630 | @* can do during pattern-matching. 631 | ** CHANGE it if you need more captures. This limit is arbitrary. 632 | */ 633 | #define LUA_MAXCAPTURES 32 634 | 635 | 636 | /* 637 | @@ lua_tmpnam is the function that the OS library uses to create a 638 | @* temporary name. 639 | @@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam. 640 | ** CHANGE them if you have an alternative to tmpnam (which is considered 641 | ** insecure) or if you want the original tmpnam anyway. By default, Lua 642 | ** uses tmpnam except when POSIX is available, where it uses mkstemp. 643 | */ 644 | #if defined(loslib_c) || defined(luaall_c) 645 | 646 | #if defined(LUA_USE_MKSTEMP) 647 | #include 648 | #define LUA_TMPNAMBUFSIZE 32 649 | #define lua_tmpnam(b,e) { \ 650 | strcpy(b, "/tmp/lua_XXXXXX"); \ 651 | e = mkstemp(b); \ 652 | if (e != -1) close(e); \ 653 | e = (e == -1); } 654 | 655 | #else 656 | #define LUA_TMPNAMBUFSIZE L_tmpnam 657 | #define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } 658 | #endif 659 | 660 | #endif 661 | 662 | 663 | /* 664 | @@ lua_popen spawns a new process connected to the current one through 665 | @* the file streams. 666 | ** CHANGE it if you have a way to implement it in your system. 667 | */ 668 | #if defined(LUA_USE_POPEN) 669 | 670 | #define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) 671 | #define lua_pclose(L,file) ((void)L, (pclose(file) != -1)) 672 | 673 | #elif defined(LUA_WIN) 674 | 675 | #define lua_popen(L,c,m) ((void)L, _popen(c,m)) 676 | #define lua_pclose(L,file) ((void)L, (_pclose(file) != -1)) 677 | 678 | #else 679 | 680 | #define lua_popen(L,c,m) ((void)((void)c, m), \ 681 | luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) 682 | #define lua_pclose(L,file) ((void)((void)L, file), 0) 683 | 684 | #endif 685 | 686 | /* 687 | @@ LUA_DL_* define which dynamic-library system Lua should use. 688 | ** CHANGE here if Lua has problems choosing the appropriate 689 | ** dynamic-library system for your platform (either Windows' DLL, Mac's 690 | ** dyld, or Unix's dlopen). If your system is some kind of Unix, there 691 | ** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for 692 | ** it. To use dlopen you also need to adapt the src/Makefile (probably 693 | ** adding -ldl to the linker options), so Lua does not select it 694 | ** automatically. (When you change the makefile to add -ldl, you must 695 | ** also add -DLUA_USE_DLOPEN.) 696 | ** If you do not want any kind of dynamic library, undefine all these 697 | ** options. 698 | ** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD. 699 | */ 700 | #if defined(LUA_USE_DLOPEN) 701 | #define LUA_DL_DLOPEN 702 | #endif 703 | 704 | #if defined(LUA_WIN) 705 | #define LUA_DL_DLL 706 | #endif 707 | 708 | 709 | /* 710 | @@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State 711 | @* (the data goes just *before* the lua_State pointer). 712 | ** CHANGE (define) this if you really need that. This value must be 713 | ** a multiple of the maximum alignment required for your machine. 714 | */ 715 | #define LUAI_EXTRASPACE 0 716 | 717 | 718 | /* 719 | @@ luai_userstate* allow user-specific actions on threads. 720 | ** CHANGE them if you defined LUAI_EXTRASPACE and need to do something 721 | ** extra when a thread is created/deleted/resumed/yielded. 722 | */ 723 | #define luai_userstateopen(L) ((void)L) 724 | #define luai_userstateclose(L) ((void)L) 725 | #define luai_userstatethread(L,L1) ((void)L) 726 | #define luai_userstatefree(L) ((void)L) 727 | #define luai_userstateresume(L,n) ((void)L) 728 | #define luai_userstateyield(L,n) ((void)L) 729 | 730 | 731 | /* 732 | @@ LUA_INTFRMLEN is the length modifier for integer conversions 733 | @* in 'string.format'. 734 | @@ LUA_INTFRM_T is the integer type correspoding to the previous length 735 | @* modifier. 736 | ** CHANGE them if your system supports long long or does not support long. 737 | */ 738 | 739 | #if defined(LUA_USELONGLONG) 740 | 741 | #define LUA_INTFRMLEN "ll" 742 | #define LUA_INTFRM_T long long 743 | 744 | #else 745 | 746 | #define LUA_INTFRMLEN "l" 747 | #define LUA_INTFRM_T long 748 | 749 | #endif 750 | 751 | 752 | 753 | /* =================================================================== */ 754 | 755 | /* 756 | ** Local configuration. You can use this space to add your redefinitions 757 | ** without modifying the main part of the file. 758 | */ 759 | 760 | 761 | 762 | #endif 763 | 764 | --------------------------------------------------------------------------------