160 lines
3.8 KiB
Lua
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,
|
|
})
|