ee99c24d52
Instead of caching privs only for the current tick, and only for NodeCore itself, change the base API to use caching universally, including for naive mod code. Privs are cached until invalidated by a change; it's assumed here that the "auth_reload" command exists in the first place because this kind of caching is allowed and accounted for, even if it's not actually done by the engine or builtin.
183 lines
5.2 KiB
Lua
183 lines
5.2 KiB
Lua
-- LUALOCALS < ---------------------------------------------------------
|
|
local ipairs, minetest, nodecore, pairs, table, type
|
|
= ipairs, minetest, nodecore, pairs, table, type
|
|
local table_concat, table_insert, table_sort
|
|
= table.concat, table.insert, table.sort
|
|
-- LUALOCALS > ---------------------------------------------------------
|
|
|
|
local modname = minetest.get_current_modname()
|
|
|
|
local tabs = {}
|
|
nodecore.registered_inventory_tabs = tabs
|
|
function nodecore.register_inventory_tab(def)
|
|
tabs[#tabs + 1] = def
|
|
nodecore.translate_inform(def.title)
|
|
if type(def.content) == "table" then
|
|
for i = 1, #def.content do
|
|
nodecore.translate_inform(def.content[i])
|
|
end
|
|
end
|
|
end
|
|
|
|
local nct = nodecore.translate
|
|
local fse = minetest.formspec_escape
|
|
|
|
local formwidth = 15
|
|
local formheight = formwidth / 2
|
|
|
|
local alltabswidth = formwidth - 0.25
|
|
local maxtabs = 7
|
|
local tabheight = 0.5
|
|
local tabmarginx = 0.2
|
|
local tabmarginy = 0.25
|
|
local tabmax = formwidth - 0.5
|
|
|
|
local textmarginx = 0.25
|
|
local textmarginy = 0.1
|
|
local textheight = formheight + 0.8
|
|
|
|
local metakey = modname .. "_inventory_key"
|
|
function nodecore.inventory_tab_get(player)
|
|
local n = player:get_meta():get_int(metakey)
|
|
return nodecore.registered_inventory_tabs[n] and n or 1
|
|
end
|
|
function nodecore.inventory_tab_set(player, tab)
|
|
player:get_meta():set_int(metakey,
|
|
tab and nodecore.registered_inventory_tabs[tab] and tab or 0)
|
|
end
|
|
|
|
function nodecore.inventory_formspec(player)
|
|
local t = {
|
|
"bgcolor[#000000C0;true]",
|
|
"listcolors[#00000000;#00000000;#00000000;#000000FF;#FFFFFFFF]"
|
|
}
|
|
|
|
local tablist = {}
|
|
for i, v in ipairs(nodecore.registered_inventory_tabs) do
|
|
local vis = v.visible
|
|
if type(vis) == "function" then vis = vis(v, player) end
|
|
if vis == nil or vis then
|
|
tablist[#tablist + 1] = {idx = i, tab = v}
|
|
end
|
|
end
|
|
local tabqty = #tablist
|
|
if tabqty > maxtabs then tabqty = maxtabs end
|
|
local tabwidth = alltabswidth / tabqty
|
|
local x = 0
|
|
local y = 0
|
|
local tabdata
|
|
local curtab = nodecore.inventory_tab_get(player)
|
|
for i, v in ipairs(tablist) do
|
|
if curtab == v.idx then
|
|
tabdata = v.tab
|
|
t[#t + 1] = "box[" .. x .. "," .. (y + tabheight) .. ";"
|
|
.. (tabwidth - 0.04) .. ",0.1;#ffffff]"
|
|
end
|
|
t[#t + 1] = "button[" .. x .. "," .. y .. ";"
|
|
.. (tabwidth + tabmarginx) .. "," .. tabheight .. ";tab" .. i
|
|
.. ";" .. fse(nct(v.tab.title)) .. "]"
|
|
x = x + tabwidth
|
|
if x >= tabmax then
|
|
x = 0
|
|
y = y + tabheight + tabmarginy
|
|
end
|
|
end
|
|
if x > 0 then y = y + tabheight + tabmarginy end
|
|
|
|
table_insert(t, 1, "size[" .. formwidth .. "," .. formheight + y .. "]")
|
|
|
|
if tabdata then
|
|
local content = tabdata.content
|
|
if type(content) == "function" then
|
|
content = content(player, {
|
|
w = formwidth,
|
|
h = textheight,
|
|
x = textmarginx,
|
|
y = y + textmarginy
|
|
}, t)
|
|
end
|
|
if not content then return end
|
|
if tabdata.raw then
|
|
if type(content) == "table" then
|
|
for _, v in ipairs(content) do t[#t + 1] = v end
|
|
end
|
|
else
|
|
t[#t + 1] = "textarea[" .. textmarginx .. "," .. (y + textmarginy)
|
|
.. ";" .. formwidth .. "," .. textheight .. ";;;"
|
|
for _, v in ipairs(content) do t[#t + 1] = fse(nct(v) .. "\n") end
|
|
t[#t + 1] = "]"
|
|
end
|
|
end
|
|
|
|
return table_concat(t)
|
|
end
|
|
|
|
local invspeccache = {}
|
|
minetest.register_on_leaveplayer(function(player)
|
|
invspeccache[player:get_player_name()] = nil
|
|
end)
|
|
function nodecore.inventory_formspec_update(player)
|
|
local str = nodecore.inventory_formspec(player)
|
|
local pname = player:get_player_name()
|
|
if invspeccache[pname] == str then return str end
|
|
player:set_inventory_formspec(str)
|
|
invspeccache[pname] = str
|
|
return str
|
|
end
|
|
|
|
nodecore.register_on_joinplayer("join set inv formspec", nodecore.inventory_formspec_update)
|
|
|
|
nodecore.register_on_player_receive_fields("player inv formspec returned",
|
|
function(player, formname, fields)
|
|
if formname == "" then
|
|
local tab
|
|
for i = 1, #nodecore.registered_inventory_tabs do
|
|
if fields["tab" .. i] then
|
|
tab = i
|
|
break
|
|
end
|
|
end
|
|
if tab then
|
|
nodecore.inventory_tab_set(player, tab)
|
|
return minetest.show_formspec(player:get_player_name(),
|
|
formname, nodecore.inventory_formspec_update(player))
|
|
end
|
|
nodecore.inventory_formspec_update(player)
|
|
end
|
|
end)
|
|
|
|
local pending = {}
|
|
function nodecore.inventory_notify(pname, event)
|
|
pname = type(pname) == "string" and pname or pname:get_player_name()
|
|
local key = pname .. "|" .. event
|
|
if pending[key] then return end
|
|
pending[key] = true
|
|
minetest.after(0, function()
|
|
pending[key] = nil
|
|
|
|
local player = minetest.get_player_by_name(pname)
|
|
if not player then return end
|
|
|
|
local tab = nodecore.inventory_tab_get(player)
|
|
tab = tab and nodecore.registered_inventory_tabs[tab]
|
|
local evt = tab and tab["on_" .. event]
|
|
if type(evt) == "function" then evt = evt(player, pname) end
|
|
if evt then return nodecore.inventory_formspec_update(player) end
|
|
end)
|
|
end
|
|
|
|
nodecore.register_playerstep({
|
|
label = "hint tab watch interact",
|
|
action = function(player, data)
|
|
local privs = {}
|
|
for k, v in pairs(minetest.get_player_privs(data.pname)) do
|
|
if v then privs[#privs + 1] = k end
|
|
end
|
|
table_sort(privs)
|
|
privs = table_concat(privs, ",")
|
|
if privs == data.privstring then return end
|
|
data.privstring = privs
|
|
return nodecore.inventory_notify(player, "privchange")
|
|
end
|
|
})
|