diff --git a/BlockLua.dll b/BlockLua.dll index 57a349a..6d9a7bf 100644 Binary files a/BlockLua.dll and b/BlockLua.dll differ diff --git a/readme.md b/readme.md index 767d7ab..b06faf4 100644 --- a/readme.md +++ b/readme.md @@ -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 diff --git a/src/util/libbl.lua b/src/util/libbl.lua index 459ac25..34c6357 100644 --- a/src/util/libbl.lua +++ b/src/util/libbl.lua @@ -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