Skip to content

Commit

Permalink
Add library support to Luacontrollers
Browse files Browse the repository at this point in the history
This allows mods to provide their own libraries that can be accessed from within a Luacontroller, for example to make working with advanced digilines peripherals somewhat easier.
Libraries can be added to the mesecon.luacontroller_libraries table, and then the code running in the Luacontroller can use require() to request one. require() will return nil if the library is not present.
  • Loading branch information
cheapie committed Mar 21, 2021
1 parent 93aa24d commit 9904be9
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
19 changes: 19 additions & 0 deletions mesecons/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,25 @@ function mesecon.tablecopy(obj) -- deep copy
return obj
end

-- Performs a deep copy of a table, changing the environment of any functions.
-- Adapted from the builtin table.copy() function.
function mesecon.tablecopy_change_env(t, env, seen)
local n = {}
seen = seen or {}
seen[t] = n
for k, v in pairs(t) do
if type(v) == "function" then
local newfunc = v
setfenv(newfunc, env)
n[(type(k) == "table" and (seen[k] or mesecon.tablecopy_change_env(k, env, seen))) or k] = newfunc
else
n[(type(k) == "table" and (seen[k] or mesecon.tablecopy_change_env(k, env, seen))) or k] =
(type(v) == "table" and (seen[v] or mesecon.tablecopy_change_env(v, env, seen))) or v
end
end
return n
end

-- Returns whether two values are equal.
-- In tables, keys are compared for identity but values are compared recursively.
-- There is no protection from infinite recursion.
Expand Down
12 changes: 12 additions & 0 deletions mesecons_luacontroller/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,16 @@ local function get_digiline_send(pos, itbl, send_warning)
end
end

mesecon.luacontroller_libraries = {}

local function get_require(env)
return function(name)
if mesecon.luacontroller_libraries[name] then
return mesecon.tablecopy_change_env(mesecon.luacontroller_libraries[name],env)
end
end
end

local safe_globals = {
-- Don't add pcall/xpcall unless willing to deal with the consequences (unless very careful, incredibly likely to allow killing server indirectly)
"assert", "error", "ipairs", "next", "pairs", "select",
Expand Down Expand Up @@ -546,6 +556,8 @@ local function create_environment(pos, mem, event, itbl, send_warning)
for _, name in pairs(safe_globals) do
env[name] = _G[name]
end

env.require = get_require(env)

return env
end
Expand Down

0 comments on commit 9904be9

Please sign in to comment.