TheWild 724f9f41de
2018-07-31 14:15:07 +02:00

160 lines
3.8 KiB
Lua

local common = ...
local global = _G
local io = io
local math = math
local minetest = minetest
local string = string
local table = table
local chat_send_player = minetest.chat_send_player
local get_player_by_name = minetest.get_player_by_name
local error = error
local find = string.find
local format = string.format
local insert = table.insert
local ipairs = ipairs
local loadfile = loadfile
local log = minetest.log
local pairs = pairs
local setfenv = setfenv -- TODO: polyfill for Lua >= 5.1
local setmetatable = setmetatable
local sort = table.sort
local type = type
local path = minetest.get_modpath(minetest.get_current_modname())
-- for clearing chat window
local bunch_of_lfs = string.rep('\n', 500)
return setmetatable({}, {
__index = function(envs, name)
local player = get_player_by_name(name)
if player == nil then
-- no idea how we could get there, but whatever
log('warning', format('Console attempted to access environment of %s, but there is no such player.', name))
return {}
end
-- variables available for player which cannot be erased
local own = {
me = player,
name = name,
}
--[[
-- disabled because it conflicts with at least one method (get_meta)
local methods = setmetatable({}, {
__index = function(t, k)
if player[k] then
local f = function(...)
return player[k](player, ...)
end
t[k] = f
return f
end
end
})
--]]
-- imports to allow using set_node, sin, write etc.
-- without the need to reference table directly.
-- TODO: optimize access?
local imports = {
own, -- me, name
-- methods, -- getpos(, get_wielded_item(...
common, -- extend(, count(, filter(...
global, -- standard global stuff
string, -- find(, rep(, gmatch(, lower(...
table, -- insert(, remove(, sort(, concat(...
io, -- open(, input(...
math, -- sin(, max(, pi...
minetest, -- set_node(, registered_items, CONTENT_AIR...
}
-- player environment
local env = setmetatable({}, {
-- function for import resolution
__index = function(table, index)
local result
for i, import in ipairs(imports) do
local result = import[index]
if result ~= nil then
return result
end
end
end
})
envs[name] = env
-- Those functions are defined here because more or less
-- they depend on variables in current scope.
-- Returns a table with all keys of given table
-- matching the given pattern. If no table provided,
-- it searches for keys in all imports.
function own.hint(table, pattern)
local result = {}
if pattern == nil then
pattern = table
table = {}
for i, import in ipairs(imports) do
for key, value in pairs(import) do
if find(key, pattern) then
table[key] = value
end
end
end
for key, value in pairs(table) do
insert(result, key)
end
else
if type(table) ~= 'table' then
error('Table expected')
end
for key, value in pairs(table) do
if find(key, pattern) then
insert(result, key)
end
end
end
sort(result)
return result
end
-- Clears the chat window.
function own.clear()
chat_send_player(name, bunch_of_lfs)
end
-- Sends message to player who called it.
function own.echo(s)
chat_send_player(name, s)
end
-- Loads a script into the function with env being the player env
local function load(name)
local result, err = loadfile(path .. '/scripts/' .. name .. '.lua')
if err then
error(err)
end
return setfenv(result, env)
end
own.load = load
-- Runs a script from scripts directory, using load function above
function own.run(name, ...)
return load(name)(...)
end
return env
end,
})