# =============================================================================
# >> IMPORTS
# =============================================================================
import memory
from memory import Convention
from memory import DataType
from memory import Callback
from memory.manager import CustomType
from memory.manager import manager
# =============================================================================
# >> GLOBAL VARIABLES
# =============================================================================
server = memory.find_binary('server')
SPECIAL_GLOB = 0 # Global table
SPECIAL_ENV = 1 # Environment table
SPECIAL_REG = 2 # Registry table
# =============================================================================
# >> CLASSES
# =============================================================================
class CLuaInterface(CustomType, metaclass=manager):
_Pop = manager.virtual_function(2, [DataType.INT])
def Pop(self, iAmt=1):
self._Pop(iAmt)
GetField = manager.virtual_function(4, [DataType.INT, DataType.STRING])
SetField = manager.virtual_function(5, [DataType.INT, DataType.STRING])
Call = manager.virtual_function(10, [DataType.INT, DataType.INT])
_GetString = manager.virtual_function(
23,
[DataType.INT, DataType.POINTER],
DataType.STRING
)
def GetString(self, iStackPos=-1, iOutLen=None):
return self._GetString(iStackPos, iOutLen)
_PushString = manager.virtual_function(29, [DataType.STRING, DataType.UINT])
def PushString(self, val, iLen=0):
self._PushString(val, iLen)
PushNumber = manager.virtual_function(30, [DataType.DOUBLE])
PushCFunction = manager.virtual_function(32, [DataType.POINTER])
PushSpecial = manager.virtual_function(38, [DataType.INT])
RunString = manager.virtual_function(
88,
[DataType.STRING, DataType.STRING, DataType.STRING, DataType.BOOL, DataType.BOOL],
DataType.BOOL
)
def run_simple_string(self, string):
"""Run a simple Lua string.
Example:
print('Hello!')
"""
return self.RunString('lua_run', '', string, True, True)
# TODO: Add the Windows identifier. The virtual function indexes are the same on both
# platforms.
g_Lua = memory.make_object(CLuaInterface, server.find_pointer('g_Lua', level=1))
# =============================================================================
# >> EXAMPLE 1
# =============================================================================
# Print Hello!
g_Lua.PushSpecial(SPECIAL_GLOB)
g_Lua.GetField(-1, 'print')
g_Lua.PushString('Hello!')
g_Lua.Call(1, 0)
g_Lua.Pop()
# =============================================================================
# >> EXAMPLE 2
# =============================================================================
# Print name of team 0
g_Lua.PushSpecial(SPECIAL_GLOB)
g_Lua.GetField(-1, 'team') # Get the 'team' module
g_Lua.GetField(-1, 'GetName') # Get the 'GetName' function
g_Lua.PushNumber(0) # Team 0/Unassigned
g_Lua.Call(1, 1) # 1 arg and 1 return value
print('Team name:', g_Lua.GetString(-1))
g_Lua.Pop(3)
# =============================================================================
# >> EXAMPLE 3
# =============================================================================
# Create a new Lua function defined in Python!
@Callback(Convention.CDECL, [DataType.POINTER], DataType.INT)
def do_something(args):
# Print something
print('Do something')
# Return 1337
g_Lua.PushNumber(1337)
# Tell Lua that we are returning 1 value
return 1
# Add the function to the global Lua table
g_Lua.PushSpecial(SPECIAL_GLOB)
g_Lua.PushCFunction(do_something)
g_Lua.SetField(-2, 'do_something')
g_Lua.Pop()
# -- ../garrysmod/lua/test.lua
# -- Run the script with "lua_openscript test.lua"
# print(do_something())