Fix md formatting + remove trailing whitespace

This commit is contained in:
2025-12-08 03:30:54 -05:00
parent 4f42801da6
commit f6bf18efaa

347
readme.md
View File

@@ -1,219 +1,240 @@
# BlockLua # BlockLua
Lua scripting for Blockland Lua scripting for Blockland
## How to Install ## How to Install
- Install RedBlocklandLoader
- Copy `lua5.1.dll` into your Blockland install folder, next to `Blockland.exe`
- Copy `BlockLua.dll` into the `modules` folder within the Blockland folder
- Install RedBlocklandLoader
- Copy `lua5.1.dll` into your Blockland install folder, next to `Blockland.exe`
- Copy `BlockLua.dll` into the `modules` folder within the Blockland folder
## Quick Reference ## Quick Reference
### From TorqueScript ### From TorqueScript
`'print('hello world')` - Execute Lua in the console by prepending a `'` (single quote)
`luaeval("code");` - Execute Lua code `'print('hello world')` - Execute Lua in the console by prepending a `'` (single quote)
`luacall("funcName", %args...);` - Call a Lua function (supports indexing tables and object methods) `luaeval("code");` - Execute Lua code
`luaexec("fileName");` - Execute a Lua file. Path rules are the same as when executing .cs files, relative paths are allowed. `luacall("funcName", %args...);` - Call a Lua function (supports indexing tables and object methods)
`luaget("varName");` - Read a Lua global variable (supports indexing tables) `luaexec("fileName");` - Execute a Lua file. Path rules are the same as when executing .cs files, relative paths are allowed.
`luaset("varName", %value);` - Write a Lua global variable (supports indexing tables) `luaget("varName");` - Read a Lua global variable (supports indexing tables)
`luaset("varName", %value);` - Write a Lua global variable (supports indexing tables)
### From Lua ### From Lua
`bl.eval('code')` - Eval TorqueScript code
`bl.funcName(args)` - Call a TorqueScript function `bl.eval('code')` - Eval TorqueScript code
`bl.varName` - Read a TorqueScript global variable `bl.funcName(args)` - Call a TorqueScript function
`bl['varName']` - Read a TorqueScript global variable (i.e. with special characters in the name, or from an array) `bl.varName` - Read a TorqueScript global variable
`bl.set('varName', value)` - Write a TorqueScript global variable `bl['varName']` - Read a TorqueScript global variable (i.e. with special characters in the name, or from an array)
`bl.set('varName', value)` - Write a TorqueScript global variable
`bl['namespaceName::funcName'](args)` - Call a namespaced TorqueScript function `bl['namespaceName::funcName'](args)` - Call a namespaced TorqueScript function
### Accessing Torque Objects from Lua ### Accessing Torque Objects from Lua
`bl.objectName` - Access a Torque object by name
`bl[objectID]` - Access a Torque object by ID (or name) `bl.objectName` - Access a Torque object by name
`object.fieldOrKey` - Read a field or Lua key from a Torque object `bl[objectID]` - Access a Torque object by ID (or name)
`object:set('field', value)` - Write a field on a Torque object `object.fieldOrKey` - Read a field or Lua key from a Torque object
`object.key = value` - Associate Lua data with a Torque object `object:set('field', value)` - Write a field on a Torque object
`object:method(args)` - Call a Torque object method `object.key = value` - Associate Lua data with a Torque object
`object[index]` - Access a member of a Torque set or group `object:method(args)` - Call a Torque object method
`object[index]` - Access a member of a Torque set or group
`for child in object:members() do` - Iterate objects within of a Torque set or group. Indices start at 0 like in Torque. `for child in object:members() do` - Iterate objects within of a Torque set or group. Indices start at 0 like in Torque.
`bl.isObject(object, objectID, or 'objectName')` - Check if an object exists `bl.isObject(object, objectID, or 'objectName')` - Check if an object exists
`object:exists()` - Check if an object exists `object:exists()` - Check if an object exists
### Timing/Schedules ### Timing/Schedules
`sched = bl.schedule(timeMs, function, args...)` - Schedule a Lua function to be called later, similar to schedule in Torque
`sched:cancel()` - Cancel a previously scheduled timer `sched = bl.schedule(timeMs, function, args...)` - Schedule a Lua function to be called later, similar to schedule in Torque
`sched:cancel()` - Cancel a previously scheduled timer
### Raycasts and Searches ### Raycasts and Searches
`hitObject, hitPos, hitNormal = bl.raycast(vector{startPosX,y,z}, vector{endPosX,y,z}, 'objtype'/{'objtypes',...}, ignoreObjects...?)` - Cast a ray in the world over objects of the specified type(s) (possibly excluding some objects), and return the object hit, the position of the hit, and the normal vector to the surface hit. See the Types section for a list of valid object types.
`for object in bl.boxSearch(vector{centerX,y,z}, vector{sizeX,y,z}, 'objtype'/{'objtypes',...}) do` - Find all objects in the world of the specified type(s) whose bounding box overlaps with the specified box. See the Types section for a list of valid object types. `hitObject, hitPos, hitNormal = bl.raycast(vector{startPosX,y,z}, vector{endPosX,y,z}, 'objtype'/{'objtypes',...}, ignoreObjects...?)` - Cast a ray in the world over objects of the specified type(s) (possibly excluding some objects), and return the object hit, the position of the hit, and the normal vector to the surface hit. See the Types section for a list of valid object types.
`for object in bl.radiusSearch(vector{centerX,y,z}, radius, 'objtype'/{'objtypes',...}) do` - Find all objects of the specified type(s) whose bounding box overlaps with the specified sphere. See the Types section for a list of valid object types. `for object in bl.boxSearch(vector{centerX,y,z}, vector{sizeX,y,z}, 'objtype'/{'objtypes',...}) do` - Find all objects in the world of the specified type(s) whose bounding box overlaps with the specified box. See the Types section for a list of valid object types.
`for object in bl.radiusSearch(vector{centerX,y,z}, radius, 'objtype'/{'objtypes',...}) do` - Find all objects of the specified type(s) whose bounding box overlaps with the specified sphere. See the Types section for a list of valid object types.
### List of Object Classes (for raycasts and searches) ### List of Object Classes (for raycasts and searches)
`'all'` - Any object
`'player'` - Players or bots `'all'` - Any object
`'item'` - Items `'player'` - Players or bots
`'vehicle'` - Vehicles `'item'` - Items
`'projectile'` - Projectiles `'vehicle'` - Vehicles
`'brick'` - Bricks with raycasting enabled `'projectile'` - Projectiles
`'brickalways'` - All bricks including those with raycasting disabled `'brick'` - Bricks with raycasting enabled
Other types: `'static'`, `'environment'`, `'terrain'`, `'water'`, `'trigger'`, `'marker'`, `'gamebase'`, `'shapebase'`, `'camera'`, `'staticshape'`, `'vehicleblocker'`, `'explosion'`, `'corpse'`, `'debris'`, `'physicalzone'`, `'staticts'`, `'staticrendered'`, `'damagableitem'` `'brickalways'` - All bricks including those with raycasting disabled
Other types: `'static'`, `'environment'`, `'terrain'`, `'water'`, `'trigger'`, `'marker'`, `'gamebase'`, `'shapebase'`, `'camera'`, `'staticshape'`, `'vehicleblocker'`, `'explosion'`, `'corpse'`, `'debris'`, `'physicalzone'`, `'staticts'`, `'staticrendered'`, `'damagableitem'`
### Server-Client Communication ### Server-Client Communication
`bl.addServerCmd('commandName', function(client, args...) ... end)` - Register a /command on the server
`bl.addClientCmd('commandName', function(args...) ... end)` - Register a client command on the client `bl.addServerCmd('commandName', function(client, args...) ... end)` - Register a /command on the server
`bl.commandToServer('commandName', args...)` - As a client, execute a server command `bl.addClientCmd('commandName', function(args...) ... end)` - Register a client command on the client
`bl.commandToClient(client, 'commandName', args...)` - As the server, execute a client command on a specific client `bl.commandToServer('commandName', args...)` - As a client, execute a server command
`bl.commandToAll('commandName', args...)` - As the server, execute a client command on all clients `bl.commandToClient(client, 'commandName', args...)` - As the server, execute a client command on a specific client
`bl.commandToAll('commandName', args...)` - As the server, execute a client command on all clients
### Packages/Hooks ### Packages/Hooks
`bl.hook('packageName', 'functionName', 'before'/'after', function(args) ... end)` - Hook a Torque function with a Lua function.
`args` is an array containing the arguments provided to the function. If the hook is `before`, these can be modified before being passed to the parent function. `bl.hook('packageName', 'functionName', 'before'/'after', function(args) ... end)` - Hook a Torque function with a Lua function.
If `args._return` is set to anything other than nil by a `before` hook, the parent function will not be called, and the function will simply return that value. Also in this case, any `after` hook will not be executed. `args` is an array containing the arguments provided to the function. If the hook is `before`, these can be modified before being passed to the parent function.
In an `after` hook, `args._return` is set to the value returned by the parent function, and can be modified. If `args._return` is set to anything other than nil by a `before` hook, the parent function will not be called, and the function will simply return that value. Also in this case, any `after` hook will not be executed.
`bl.unhook('packageName', 'functionName', 'before'/'after')` - Remove a previously defined hook In an `after` hook, `args._return` is set to the value returned by the parent function, and can be modified.
`bl.unhook('packageName', 'functionName')` - Remove any previously defined hooks on the function within the package `bl.unhook('packageName', 'functionName', 'before'/'after')` - Remove a previously defined hook
`bl.unhook('packageName')` - Remove any previously defined hooks within the package `bl.unhook('packageName', 'functionName')` - Remove any previously defined hooks on the function within the package
`bl.unhook('packageName')` - Remove any previously defined hooks within the package
### Modules and Dependencies ### Modules and Dependencies
`dofile('Add-Ons/Path/file.lua')` - Execute a Lua file. Relative paths (`./file.lua`) are allowed. `..` is not allowed.
`dofile('Add-Ons/Path/file.lua')` - Execute a Lua file. Relative paths (`./file.lua`) are allowed. `..` is not allowed.
`require('modulePath.moduleName')` - Load a Lua file or external library.
`require` replaces `.` with `/` in the path, and then searches for files in the following order: `require('modulePath.moduleName')` - Load a Lua file or external library.
- `./modulePath/moduleName.lua` `require` replaces `.` with `/` in the path, and then searches for files in the following order:
- `./modulePath/moduleName/init.lua`
- `modulePath/moduleName.lua` (Relative to game directory) - `./modulePath/moduleName.lua`
- `modulePath/moduleName/init.lua` (Relative to game directory) - `./modulePath/moduleName/init.lua`
- `modules/lualib/modulePath/moduleName.lua` - `modulePath/moduleName.lua` (Relative to game directory)
- `modules/lualib/modulePath/moduleName/init.lua` - `modulePath/moduleName/init.lua` (Relative to game directory)
- `modules/lualib/modulePath/moduleName.dll` - C libraries for Lua can be loaded - `modules/lualib/modulePath/moduleName.lua`
- `modules/lualib/modulePath/moduleName/init.lua`
Like in standard Lua, modules loaded using `require` are only executed the first time `require` is called with that path (from anywhere). Subsequent calls simply return the result from the initial execution. To allow hot reloading, use `dofile`. - `modules/lualib/modulePath/moduleName.dll` - C libraries for Lua can be loaded
Like in standard Lua, modules loaded using `require` are only executed the first time `require` is called with that path (from anywhere). Subsequent calls simply return the result from the initial execution. To allow hot reloading, use `dofile`.
### File I/O ### File I/O
Lua's builtin file I/O is emulated, and is confined to the same directories as TorqueScript file I/O.
Relative paths (`./`) are allowed. `..` is not allowed. Lua's builtin file I/O is emulated, and is confined to the same directories as TorqueScript file I/O.
`file = io.open('./file.txt', 'r'/'w'/'a'/'rb'/'wb'/'ab')` - Open a file Relative paths (`./`) are allowed. `..` is not allowed.
`file:read(numberOfChars/'*a')` - Read an opened file (must be opened in 'r' (read) or 'rb' (read binary) mode) `file = io.open('./file.txt', 'r'/'w'/'a'/'rb'/'wb'/'ab')` - Open a file
`file:write(string)` - Write an opened file (must be opened in 'w' (write), 'a' (append), 'wb' or 'ab' mode) `file:read(numberOfChars/'*a')` - Read an opened file (must be opened in 'r' (read) or 'rb' (read binary) mode)
`file:close()` - Close an opened file `file:write(string)` - Write an opened file (must be opened in 'w' (write), 'a' (append), 'wb' or 'ab' mode)
Reading files from ZIPs is supported, with caveats. Null characters are not allowed, and \r\n becomes \n. Generally, text formats work, and binary formats don't. `file:close()` - Close an opened file
Reading files from ZIPs is supported, with caveats. Null characters are not allowed, and \r\n becomes \n. Generally, text formats work, and binary formats don't.
When reading from outside ZIPs, binary files are fully supported. When reading from outside ZIPs, binary files are fully supported.
### Object Creation ### Object Creation
`bl.new('className')` - Create a new Torque object
`bl.new('className', {fieldName = value, ...})` - Create a new Torque object with the given fields `bl.new('className')` - Create a new Torque object
`bl.new('className objectName', fields?)` - Create a new named Torque object `bl.new('className', {fieldName = value, ...})` - Create a new Torque object with the given fields
`bl.new('className objectName:parentName', fields?)` - Create a new named Torque object with inheritance `bl.new('className objectName', fields?)` - Create a new named Torque object
`bl.datablock('datablockClassName datablockName', fields?)` - Create a new datablock `bl.new('className objectName:parentName', fields?)` - Create a new named Torque object with inheritance
`bl.datablock('datablockClassName datablockName:parentDatablockName', fields?)` - Create a new datablock with inheritance `bl.datablock('datablockClassName datablockName', fields?)` - Create a new datablock
`bl.datablock('datablockClassName datablockName:parentDatablockName', fields?)` - Create a new datablock with inheritance
### Classes and Types ### Classes and Types
`bl.type('varName', 'type')` - Register the type of a Torque global variable, for conversion when accessing from Lua. Valid types are 'boolean', 'object', 'string' (prevents automatic conversion), and nil (default, applies automatic conversion).
`bl.type('funcName', 'type')` - Register the return type of a Torque function, for conversion when calling from Lua. Valid types are 'bool', 'object', and nil - all other conversion is automatic. Already done for all default functions. `bl.type('varName', 'type')` - Register the type of a Torque global variable, for conversion when accessing from Lua. Valid types are 'boolean', 'object', 'string' (prevents automatic conversion), and nil (default, applies automatic conversion).
`bl.type('className::funcName', 'type')` - Register the return type of a Torque object method. `bl.type('funcName', 'type')` - Register the return type of a Torque function, for conversion when calling from Lua. Valid types are 'bool', 'object', and nil - all other conversion is automatic. Already done for all default functions.
`bl.class('className')` - Register an existing Torque class to be used from Lua. Already done for all built-in classes. `bl.type('className::funcName', 'type')` - Register the return type of a Torque object method.
`bl.class('className', 'parentClassName')` - Same as above, with inheritance `bl.class('className')` - Register an existing Torque class to be used from Lua. Already done for all built-in classes.
`bl.boolean(arg)` - Manually convert a Torque boolean (0 or 1) into a Lua boolean. `bl.class('className', 'parentClassName')` - Same as above, with inheritance
`bl.object(arg)` - Manually convert a Torque object reference (object ID or name) into a Lua object. `bl.boolean(arg)` - Manually convert a Torque boolean (0 or 1) into a Lua boolean.
`bl.string(arg)` - Manually convert any automatically-converted Torque value back into a string. This is not as reliable as using `bl.type` to specify the type as a string beforehand. `bl.object(arg)` - Manually convert a Torque object reference (object ID or name) into a Lua object.
`bl.string(arg)` - Manually convert any automatically-converted Torque value back into a string. This is not as reliable as using `bl.type` to specify the type as a string beforehand.
### Vector ### Vector
`vec = vector{x,y,z}` - Create a vector. Can have any number of elements
`vec1 + vec2` - Add `vec = vector{x,y,z}` - Create a vector. Can have any number of elements
`vec1 - vec2` - Subtract `vec1 + vec2` - Add
`vec * number` - Scale (x\*n, y\*n, z\*n) `vec1 - vec2` - Subtract
`vec / number` - Scale (x/n, y/n, z/n) `vec * number` - Scale (x\*n, y\*n, z\*n)
`vec ^ number` - Exponentiate (x^n, y^n, z^n) `vec / number` - Scale (x/n, y/n, z/n)
`vec1 * vec2` - Multiply elements piecewise (x1\*x2, y1\*y2, z1\*z2) `vec ^ number` - Exponentiate (x^n, y^n, z^n)
`vec1 / vec2` - Divide elements piecewise (x1/x2, y1/y2, z1/z2) `vec1 * vec2` - Multiply elements piecewise (x1\*x2, y1\*y2, z1\*z2)
`vec1 ^ vec2` - Exponentiate elements piecewise (x1^x2, y1^y2, z1^z2) `vec1 / vec2` - Divide elements piecewise (x1/x2, y1/y2, z1/z2)
`-vec` - Negate/invert `vec1 ^ vec2` - Exponentiate elements piecewise (x1^x2, y1^y2, z1^z2)
`vec1 == vec2` - Compare by value `-vec` - Negate/invert
`vec:length()` - Length `vec1 == vec2` - Compare by value
`vec:normalize()` - Preserve direction but scale so magnitude is 1 `vec:length()` - Length
`vec:floor()` - Floor each element `vec:normalize()` - Preserve direction but scale so magnitude is 1
`vec:ceil()` - Ceil each element `vec:floor()` - Floor each element
`vec:abs()` - Absolute value each element `vec:ceil()` - Ceil each element
`vec1:dot(vec2)` - Dot product `vec:abs()` - Absolute value each element
`vec1:cross(vec2)` - Cross product (Only defined for two vectors of length 3) `vec1:dot(vec2)` - Dot product
`vec:rotateZ(radians)` - Rotate counterclockwise about the Z (vertical) axis `vec1:cross(vec2)` - Cross product (Only defined for two vectors of length 3)
`vec:rotateByAngleId(0/1/2/3)` - Rotate counterclockwise about the Z (vertical) axis in increments of 90 degrees `vec:rotateZ(radians)` - Rotate counterclockwise about the Z (vertical) axis
`vec:tsString()` - Convert to string usable by Torque. Done automatically when a vector is passed to Torque. `vec:rotateByAngleId(0/1/2/3)` - Rotate counterclockwise about the Z (vertical) axis in increments of 90 degrees
`vec1:distance(vec2)` - Distance between two points `vec:tsString()` - Convert to string usable by Torque. Done automatically when a vector is passed to Torque.
`vec1:distance(vec2)` - Distance between two points
`vec2 = vec:copy()` - Clone a vector so its elements can be modified without affecting the original. Usually not needed - the builtin vector functions never modify vectors in-place. `vec2 = vec:copy()` - Clone a vector so its elements can be modified without affecting the original. Usually not needed - the builtin vector functions never modify vectors in-place.
### Matrix ### Matrix
WIP WIP
### Extended Standard Lua Library ### Extended Standard Lua Library
`str[index]`
`str[{start,stop}]` `str[index]`
`string.split(str, separator='' (splits into chars), noregex=false)` `str[{start,stop}]`
`string.bytes(str)` `string.split(str, separator='' (splits into chars), noregex=false)`
`string.trim(str, charsToTrim=' \t\r\n')` `string.bytes(str)`
`table.empty` `string.trim(str, charsToTrim=' \t\r\n')`
`table.map(func, ...)` `table.empty`
`table.mapk(func, ...)` `table.map(func, ...)`
`table.map_list(func, ...)` `table.mapk(func, ...)`
`table.mapi_list(func, ...)` `table.map_list(func, ...)`
`table.swap(tbl)` `table.mapi_list(func, ...)`
`table.reverse(list)` `table.swap(tbl)`
`table.islist(list)` `table.reverse(list)`
`table.append(list, ...)` `table.islist(list)`
`table.join(...)` `table.append(list, ...)`
`table.contains(tbl, val)` `table.join(...)`
`table.contains_list(list, val)` `table.contains(tbl, val)`
`table.copy(tbl)` `table.contains_list(list, val)`
`table.copy_list(list)` `table.copy(tbl)`
`table.sortcopy(tbl, sortFunction?)` `table.copy_list(list)`
`table.removevalue(tbl, val)` `table.sortcopy(tbl, sortFunction?)`
`table.removevalue_list(tbl, val)` `table.removevalue(tbl, val)`
`table.tostring(tbl)` `table.removevalue_list(tbl, val)`
`for char in string.chars(str) do` `table.tostring(tbl)`
`string.escape(str, escapes={['\n']='\\n', etc. (C standard)})` `for char in string.chars(str) do`
`string.unescape(str, escapeChar='\\', unescapes={['\\n']='\n', etc.})` `string.escape(str, escapes={['\n']='\\n', etc. (C standard)})`
`io.readall(filename)` `string.unescape(str, escapeChar='\\', unescapes={['\\n']='\n', etc.})`
`io.writeall(filename, str)` `io.readall(filename)`
`math.round(num)` `io.writeall(filename, str)`
`math.mod(divisor, modulus)` `math.round(num)`
`math.clamp(num, min, max)` `math.mod(divisor, modulus)`
`math.clamp(num, min, max)`
## Type Conversion ## Type Conversion
When a TorqueScript function is called from Lua or vice-versa, the arguments and return value must be converted between the two languages' type systems.
TorqueScript stores no type information; all values in TorqueScript are strings. So it's necessary to make some inferences when converting values between the two languages. When a TorqueScript function is called from Lua or vice-versa, the arguments and return value must be converted between the two languages' type systems.
TorqueScript stores no type information; all values in TorqueScript are strings. So it's necessary to make some inferences when converting values between the two languages.
### From Lua to TorqueScript ### From Lua to TorqueScript
- `nil` becomes the empty string ""
- `true` and `false` become "1" and "0" respectively - `nil` becomes the empty string ""
- A Torque object container becomes its object ID - `true` and `false` become "1" and "0" respectively
- A `vector` becomes a string containing three numbers separated by spaces - A Torque object container becomes its object ID
- A table of two `vector`s becomes a string containing six numbers separated by spaces - A `vector` becomes a string containing three numbers separated by spaces
- (WIP) A `matrix` is converted into an axis-angle (a "transform"), a string containing seven numbers separated by spaces - A table of two `vector`s becomes a string containing six numbers separated by spaces
- Any `string` is passed directly as a string - (WIP) A `matrix` is converted into an axis-angle (a "transform"), a string containing seven numbers separated by spaces
- Tables cannot be passed and will throw an error - Any `string` is passed directly as a string
- Tables cannot be passed and will throw an error
### From TorqueScript to Lua ### From TorqueScript to Lua
- The empty string "" becomes `nil`
- Any numeric value becomes a Lua `number`, except as specified with `bl.type`, which may convert a value into a `boolean` or a Torque object container. - The empty string "" becomes `nil`
- A string containing two or three numbers separated by single spaces becomes a `vector` - Any numeric value becomes a Lua `number`, except as specified with `bl.type`, which may convert a value into a `boolean` or a Torque object container.
- A string containing six numbers separated by single spaces becomes a table of two vectors, usually defining the corners a bounding box - A string containing two or three numbers separated by single spaces becomes a `vector`
- (WIP) A string containing seven numbers separated by single spaces is treated as an axis-angle (a "transform"), and is converted into a `matrix` representing the translation and rotation - A string containing six numbers separated by single spaces becomes a table of two vectors, usually defining the corners a bounding box
- Any other string is passed directly as a `string` - (WIP) A string containing seven numbers separated by single spaces is treated as an axis-angle (a "transform"), and is converted into a `matrix` representing the translation and rotation
- Any other string is passed directly as a `string`
For scenarios where the automatic TorqueScript->Lua conversion rules are insufficient or incorrect, use `bl.type`.
For scenarios where the automatic TorqueScript->Lua conversion rules are insufficient or incorrect, use `bl.type`.
To convert things by hand, use `bl.object`, `bl.boolean`, or `bl.string`. To convert things by hand, use `bl.object`, `bl.boolean`, or `bl.string`.
## I/O and Safety ## I/O and Safety
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. 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 ### Unsafe Mode
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.
A more limited option is `-DBLLUA_ALLOWFFI`, which allows the use of the `ffi` library. This can still be exploited to grant all the same access as full unsafe mode. 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 either of these. A more limited option is `-DBLLUA_ALLOWFFI`, which allows the use of the `ffi` library. This can still be exploited to grant all the same access as full unsafe mode.
Please do not publish add-ons that require either of these.
## Compiling ## Compiling
With any *32-bit* variant of GCC installed (such as MinGW or MSYS2), run the following command in the repo directory: With any _32-bit_ variant of GCC installed (such as MinGW or MSYS2), run the following command in the repo directory:
`g++ src/bllua4.cpp -o BlockLua.dll -m32 -shared -static-libgcc -Isrc -Iinc/tsfuncs -Iinc/lua -lpsapi -L. -llua5.1` `g++ src/bllua4.cpp -o BlockLua.dll -m32 -shared -static-libgcc -Isrc -Iinc/tsfuncs -Iinc/lua -lpsapi -L. -llua5.1`
LuaJIT (lua5.1.dll) can be obtained from https://luajit.org/ LuaJIT (lua5.1.dll) can be obtained from https://luajit.org/