allow calling namespaced torque functions

This commit is contained in:
Redo
2025-10-05 22:31:21 -05:00
parent 7da249cca1
commit edf31c178c
3 changed files with 34 additions and 13 deletions

Binary file not shown.

View File

@@ -12,12 +12,12 @@ Lua scripting for Blockland
## Quick Reference
### From TorqueScript
`'print('hello world')` - Execute Lua code in the console by prepending a `'` (single quote)
`luaeval("code");` - Eval Lua code
`luacall("funcName", %args);` - Call a Lua global function
`'print('hello world')` - Execute Lua in the console by prepending a `'` (single quote)
`luaeval("code");` - Execute Lua code
`luacall("funcName", %args...);` - Call a Lua global function
`luaexec("fileName");` - Execute a Lua file. Path rules are the same as executing .cs files.
`luaget("varName");` - Read a Lua global variable
`luaset("varName");` - Write a Lua global variable
`luaset("varName", %value);` - Write a Lua global variable
### From Lua
`bl.eval('code')` - Eval TorqueScript code
@@ -181,7 +181,7 @@ TorqueScript stores no type information; all values in TorqueScript are strings.
All Lua code is sandboxed, and file access is confined to the default directories in the same way TorqueScript is.
BlockLua also has access to any C libraries installed in the `modules/lualib` folder, so be careful throwing things in there.
### Unsafe Mode
BlockLua-Unsafe.dll can be built and used in place of BlockLua.dll (see compile.bat), to remove the sandboxing of Lua code. This allows Lua code to access any file and use any library, including ffi.
BlockLua can be built in Unsafe Mode by specifying the `-DBLLUA_UNSAFE` compiler flag. This removes the sandboxing of Lua code, allowing it to access any file and use any library, including ffi.
Please do not publish add-ons that require unsafe mode.
### List of Object Types

View File

@@ -479,6 +479,31 @@ toTsObject = function(idiS)
return obj
end
-- Allow bl['namespaced::function']()
local function safeNamespaceName(name)
return tostring(name:gsub(':', '_'))
end
local nscallArgStr = '%a,%b,%c,%d,%e,%f,%g,%h'
bl._cachedNamespaceCalls = {}
local function tsNamespacedCallTfname(name)
local tfname = bl._cachedNamespaceCalls[name]
if not tfname then
tfname = '_bllua_nscall_'..safeNamespaceName(name)
local tfcode = 'function '..tfname..'('..nscallArgStr..'){'..
name..'('..nscallArgStr..');}'
_bllua_ts.eval(tfcode)
bl._cachedNamespaceCalls[name] = tfname
end
return tfname
end
local function tsCallGen(name)
return function(...)
local args = {...}
local argsS = arglistToTs(args)
return valFromTs(_bllua_ts.call(name, unpack(argsS)), name)
end
end
-- Metatable for the global bl library
-- Allows accessing Torque objects, variables, and functions by indexing it
local tsMeta = {
@@ -499,16 +524,12 @@ local tsMeta = {
local ns, rest = name:match('^([^:]+)::(.+)$')
if not ns then error('ts index: invalid name \''..name..'\'', 2) end
if not rest:find('::') and tsIsFunctionNs(ns, rest) then
error('ts index: can\'t call a namespaced function from lua', 2)
return tsCallGen(tsNamespacedCallTfname(name))
else
return valFromTs(_bllua_ts.getvar(name), name)
end
elseif tsIsFunction(name) then
return function(...)
local args = {...}
local argsS = arglistToTs(args)
return valFromTs(_bllua_ts.call(name, unpack(argsS)), name)
end
return tsCallGen(name)
elseif tsIsObject(name) then
return toTsObject(name)
else
@@ -549,7 +570,7 @@ function bl.object(id)
elseif type(id)=='string' or type(id)=='number' then
return toTsObject(tostring(id))
else
error('bl.toobject: id must be a ts object, number, or string', 2)
error('bl.object: id must be a ts object, number, or string', 2)
end
end
function bl.array(name, ...)
@@ -557,7 +578,7 @@ function bl.array(name, ...)
return name..table.concat(rest, '_')
end
function _bllua_call(fnameS, ...)
local args = arglistFromTs('lua:'..fnameS:lower(), {...})
local args = arglistFromTs('lua:'..fnameS:lower(), {...}) -- todo: allow this though bl.type
if not _G[fnameS] then
error('luacall: no global lua function named \''..fnameS..'\'') end
-- todo: library fields and object methods