11// Types are in camelcase + C prefix
22#![ allow( non_snake_case) ]
3+ #![ allow( non_upper_case_globals) ]
34
45pub mod types;
56pub mod globals;
67pub mod helpers;
78
8- use types:: * ;
9- use globals:: Lua ;
10-
11- use std:: path:: PathBuf ;
12- extern crate dlopen;
13-
14- use dlopen:: wrapper:: { Container , WrapperApi } ;
15-
16- #[ derive( WrapperApi ) ]
17- pub struct LuaSharedInterface {
18- // GMOD
19- pub CreateInterface : extern fn ( name : CharBuf , ret_code : CInt ) -> * mut CVoid ,
20-
21- // Runners
22- pub luaL_loadbufferx : extern fn ( state : LuaState , code : CharBuf , size : SizeT , id : CharBuf , mode : CharBuf ) -> CInt ,
23- pub luaL_loadbuffer : extern fn ( state : LuaState , code : CharBuf , size : SizeT , id : CharBuf ) -> CInt ,
24- pub luaL_loadstring : extern fn ( state : LuaState , code : CharBuf ) -> CInt ,
25-
26- pub lua_pcall : extern fn ( state : LuaState , nargs : CInt , nresults : CInt , msgh : CInt ) -> CInt ,
27- pub lua_call : extern fn ( state : LuaState , nargs : CInt , nresults : CInt ) -> CInt ,
28- pub lua_cpcall : extern fn ( state : LuaState , func : LuaCFunction , userdata : * mut CVoid ) -> CInt ,
29- pub luaL_callmeta : extern fn ( state : LuaState , obj : CInt , name : CharBuf ) -> CInt ,
30-
31- // Setters
32- pub lua_setfield : extern fn ( state : LuaState , idx : CInt , name : CharBuf ) ,
33- pub lua_setmetatable : extern fn ( state : LuaState , idx : CInt ) ,
34- pub lua_settop : extern fn ( state : LuaState , ind : CInt ) ,
35- pub lua_setupvalue : extern fn ( state : LuaState , fidx : CInt , idx : CInt ) -> CharBuf ,
36- pub lua_setfenv : extern fn ( state : LuaState , idx : CInt ) -> CInt ,
37- pub lua_settable : extern fn ( state : LuaState , idx : CInt ) ,
38- pub lua_rawset : extern fn ( state : LuaState , idx : CInt ) , // lua_settable but no metamethods called
39- pub lua_rawseti : extern fn ( state : LuaState , idx : CInt , n : CInt ) , // t[n] = v
40-
41- // Getters
42- pub lua_gettable : extern fn ( state : LuaState , idx : CInt ) ,
43- pub lua_rawget : extern fn ( state : LuaState , idx : CInt ) , // lua_gettable but no metamethods called
44- pub lua_rawgeti : extern fn ( state : LuaState , idx : CInt , n : CInt ) , // lua_gettable but no metamethods called
45-
46- pub lua_getfield : extern fn ( state : LuaState , idx : CInt , key : CharBuf ) ,
47- pub lua_getupvalue : extern fn ( state : LuaState , fidx : CInt , idx : CInt ) -> CharBuf ,
48- pub lua_type : extern fn ( state : LuaState , idx : CInt ) -> CInt ,
49- pub lua_typename : extern fn ( state : LuaState , typeid : CInt ) -> CharBuf , // To be used with the return value of lua_type
50-
51- // Getters (with "to")
52- pub lua_tolstring : extern fn ( state : LuaState , ind : CInt , size : SizeT ) -> CharBuf ,
53- pub lua_toboolean : extern fn ( state : LuaState , idx : CInt ) -> CInt ,
54- pub lua_tocfunction : extern fn ( state : LuaState , idx : CInt ) -> LuaCFunction ,
55- pub lua_tointeger : extern fn ( state : LuaState , idx : CInt ) -> LuaInteger ,
56- pub lua_tonumber : extern fn ( state : LuaState , idx : CInt ) -> LuaNumber ,
57- pub lua_topointer : extern fn ( state : LuaState , idx : CInt ) -> * mut CVoid ,
58- pub lua_tothread : extern fn ( state : LuaState , idx : CInt ) -> LuaState ,
59- pub lua_touserdata : extern fn ( state : LuaState , idx : CInt ) -> * mut CVoid ,
60-
61- // Push functions
62- pub lua_pushstring : extern fn ( state : LuaState , s : CharBuf ) ,
63- pub lua_pushlstring : extern fn ( state : LuaState , s : CharBuf , sz : SizeT ) ,
64- pub lua_pushnil : extern fn ( state : LuaState ) ,
65- pub lua_pushnumber : extern fn ( state : LuaState , num : LuaNumber ) ,
66- pub lua_pushvalue : extern fn ( state : LuaState , idx : CInt ) ,
67- pub lua_pushcclosure : extern fn ( state : LuaState , fnc : LuaCFunction , idx : CInt ) ,
68-
69- // Type Checks
70- pub luaL_checkinteger : extern fn ( state : LuaState , narg : CInt ) -> LuaInteger ,
71- pub luaL_checknumber : extern fn ( state : LuaState , narg : CInt ) -> LuaNumber ,
72- pub luaL_checklstring : extern fn ( state : LuaState , narg : CInt ) -> CharBuf ,
73-
74- // Type Checks that return nothing
75- pub luaL_checkstack : extern fn ( state : LuaState , size : CInt , msg : CharBuf ) ,
76- pub luaL_checkany : extern fn ( state : LuaState , narg : CInt ) ,
77- pub luaL_checktype : extern fn ( state : LuaState , narg : CInt , typeid : CInt ) ,
78- pub luaL_checkudata : extern fn ( state : LuaState , narg : CInt , len : SizeT ) ,
79-
80- // Creation
81- pub luaL_newstate : extern fn ( ) -> LuaState ,
82- pub lua_createtable : extern fn ( state : LuaState , narr : CInt , nrec : CInt ) ,
83-
84- // Destruction
85- pub lua_close : extern fn ( state : LuaState ) , // Destroys the lua state
86-
87- // JIT
88- // Returns 1 for success, 0 for failure
89- pub luaJIT_setmode : extern fn ( state : LuaState , idx : CInt , jit_mode : CInt ) -> CInt ,
90-
91- // Coroutines
92- pub lua_yield : extern fn ( state : LuaState , nresults : CInt ) -> CInt ,
93- pub lua_status : extern fn ( state : LuaState ) -> CInt ,
94- pub lua_resume_real : extern fn ( state : LuaState , narg : CInt ) -> CInt ,
95-
96- // Comparison
97- pub lua_equal : extern fn ( state : LuaState , ind1 : CInt , ind2 : CInt ) -> CInt , // Returns 1 or 0 bool
98- pub lua_rawequal : extern fn ( state : LuaState , ind1 : CInt , ind2 : CInt ) -> CInt ,
99-
100- // Raising Errors
101- pub luaL_typerror : extern fn ( state : LuaState , narg : CInt , typename : CharBuf ) -> CInt ,
102- }
103-
104- // C++ Macros & Custom Functions
105- impl LuaSharedInterface {
106- pub fn lua_pop ( & self , state : LuaState , ind : CInt ) {
107- self . lua_settop ( state, -( ind) -1 ) ;
108- }
109-
110- pub fn lua_isboolean ( & self , state : LuaState , ind : CInt ) -> bool {
111- self . lua_type ( state, ind) == Lua :: Type :: Bool as i32
112- }
113-
114- pub fn lua_setglobal ( & self , state : LuaState , name : CharBuf ) {
115- self . lua_setfield ( state, Lua :: GLOBALSINDEX , name) ;
116- }
117-
118- pub fn lua_getglobal ( & self , state : LuaState , name : CharBuf ) {
119- self . lua_getfield ( state, Lua :: GLOBALSINDEX , name) ;
120- }
121-
122- pub fn lua_pushcfunction ( & self , state : LuaState , fnc : LuaCFunction ) {
123- self . lua_pushcclosure ( state, fnc, 0 ) ;
124- }
125-
126- pub fn lua_tostring ( & self , state : LuaState , idx : CInt ) -> CharBuf {
127- self . lua_tolstring ( state, idx, 0 )
128- }
129- pub fn lua_resume ( & self , state : LuaState , narg : CInt ) -> CInt {
130- self . lua_resume_real ( state, narg)
131- }
132- }
133-
134- // Global Static Stuff
135-
136- extern crate once_cell;
137- use once_cell:: sync:: Lazy ;
138-
139- // Keep separate in case needed by crates.
140- pub static GMOD_DIR : Lazy < PathBuf > = Lazy :: new ( || {
141- // Get the attached process. If you inject or run a binary module, will always GarrysMod directory.
142- std:: env:: current_dir ( ) . expect ( "Couldn't get current running directory." ) // D:\SteamLibrary\steamapps\common\GarrysMod for example.
143- } ) ;
144-
145- /// Where the lua_shared file binary is.
146- pub static BIN_DIR : Lazy < PathBuf > = Lazy :: new ( || {
147- let gm_dir = & * GMOD_DIR ;
148- match gm_dir. join ( "bin" ) {
149- bin if bin. exists ( ) && bin. join ( "lua_shared.dll" ) . exists ( ) => bin, // GarrysMod/bin
150- _ => {
151- let garrysmod_bin = gm_dir. join ( "garrysmod" ) . join ( "bin" ) ;
152- if !garrysmod_bin. exists ( ) {
153- panic ! ( "Couldn't find a bin folder in GarrysMod/bin or GarrysMod/garrysmod/bin." ) ;
154- }
155- garrysmod_bin // GarrysMod/garrysmod/bin
156- } ,
157- }
158- } ) ;
159-
160- // Let me know if there's a neater way to do this.
161- // Also if you need BIN_PATH back, try and re-implement it here.
162- // I don't know how i'd go about it without it being very messy and not checking whether lua_shared exists or not.
163- pub static LUA_SHARED_PATH : Lazy < Option < PathBuf > > = Lazy :: new ( || {
164- let game_bin = & * BIN_DIR ;
165-
166- if cfg ! ( target_arch = "x86_64" ) {
167- // x64 Platform. srcds is always 32 bit so we don't have to try and check that here.
168- let full = game_bin
169- . join ( "win64" )
170- . join ( "lua_shared.dll" ) ;
171-
172- return match full. exists ( ) {
173- true => Some ( full) ,
174- false => {
175- eprintln ! ( "x64, {}" , full. display( ) ) ;
176- None
177- }
178- }
179- } else {
180- // x86 Platform
181- let game_full = game_bin. join ( "lua_shared.dll" ) ;
182- return match game_full. exists ( ) {
183- true => Some ( game_full) ,
184- false => {
185- eprintln ! ( "game_full, {}" , game_full. display( ) ) ;
186- None
187- }
188- }
189- }
190- } ) ;
191-
192- type LuaSharedLibrary = Container < LuaSharedInterface > ;
193-
194- // Returns the underlying result of trying to create a luasharedinterface.
195- // Useful if you don't want your program to panic at all.
196- pub static LUA_SHAREDR : Lazy < Result < LuaSharedLibrary , dlopen:: Error > > = Lazy :: new ( || {
197- let dll_path = match & * LUA_SHARED_PATH {
198- Some ( path) => path,
199- None => panic ! ( "Couldn't get lua_shared location. Make sure it's at GarrysMod/bin/ or GarrysMod/garrysmod/bin/" )
200- } ;
201- unsafe { Container :: load ( dll_path) }
202- } ) ;
203-
204- pub static LUA_SHARED : Lazy < & LuaSharedLibrary > = Lazy :: new ( || {
205- match & * LUA_SHAREDR {
206- Ok ( lib) => lib, // We shouldn't need a mutable LuaSharedLibrary.
207- Err ( why) => panic ! ( "Couldn't load lua_shared.dll. Error Reason: {}. Report this on github." , why)
208- }
209- } ) ;
9+ #[ macro_use]
10+ pub mod lua_shared;
0 commit comments