2019-12-04 18:54:54 -05:00

153 lines
4.1 KiB
Lua

-- LUALOCALS < ---------------------------------------------------------
local minetest, pairs, rawset, string
= minetest, pairs, rawset, string
local string_match
= string.match
-- LUALOCALS > ---------------------------------------------------------
local modstore = minetest.get_mod_storage()
local special = {
all = true,
none = true,
default = true
}
local function canwrite(role)
if special[role] then return end
local def = minetest.registered_privileges[role]
return (not def) or def.roleprivs
end
local function setrole(role, privstr)
rawset(minetest.registered_privileges, role, nil)
minetest.register_privilege(role, {
description = "=> " .. privstr,
give_to_singleplayer = false,
give_to_admin = false,
roleprivs = minetest.string_to_privs(privstr)
})
end
do
local loaded = modstore:to_table()
loaded = loaded and loaded.fields
if loaded then
for k, v in pairs(loaded) do
if canwrite(k) then setrole(k, v) end
end
end
end
minetest.register_chatcommand("role", {
params = "<role> (<priv> | <role>)[,...]",
description = "(Re)define a role",
privs = {privs = true},
func = function(_, param)
local role, privstr = string_match(param, "([^ ]+) (.+)")
if not role or not privstr then
return false, "Invalid parameters (see /help roledef)"
end
for k in pairs(minetest.string_to_privs(privstr)) do
if (not special[k]) and (not minetest.registered_privileges[k]) then
return false, "Invalid priv or role: " .. k
end
end
modstore:set_string(role, privstr)
setrole(role, privstr)
end
})
local function union(t, f) for k in pairs(f) do t[k] = true end return t end
local privexpand = minetest.string_to_privs
local getprivs = minetest.get_player_privs
local function expandroles(pname, privs, invert)
local seen = union({}, special)
local dirty = true
while dirty do
dirty = false
local newpriv = {}
for k in pairs(privs) do
if k == "all" then
privs = {}
for p, def in pairs(minetest.registered_privileges) do
if not def.roleprivs then privs[p] = true end
end
return privs
end
local def = minetest.registered_privileges[k]
if def and def.roleprivs then
if not seen[k] then
seen[k] = true
dirty = true
union(newpriv, def.roleprivs)
end
else
newpriv[k] = true
end
end
privs = newpriv
end
if invert or privs.none then
privs.none = nil
else
union(privs, getprivs(pname))
end
if privs.default then
union(privs, privexpand(minetest.settings:get("default_privs")))
privs.default = nil
end
return privs
end
local function cmdmod(cmd, paramfunc, invert)
local def = minetest.registered_chatcommands[cmd]
if def then
local oldfunc = def.func
rawset(def, "func", function(pname, param, ...)
local gname, privs = paramfunc(pname, param, ...)
if privs == "all" then param = param .. ",all" end
local oldstp = minetest.string_to_privs
function minetest.string_to_privs()
minetest.string_to_privs = oldstp
return expandroles(gname, privexpand(privs), invert)
end
local oldget = minetest.get_player_privs
if not invert then
local once
function minetest.get_player_privs(pn, ...)
if not once then
once = true
return oldget(pn, ...)
end
minetest.get_player_privs = oldget
return {}
end
end
local function helper(...)
minetest.string_to_privs = oldstp
minetest.get_player_privs = oldget
return ...
end
return helper(oldfunc(pname, param, ...))
end)
end
end
cmdmod("grant", function(_, param) return string_match(param, "([^ ]+) (.+)") end)
cmdmod("grantme", function(n, param) return n, param end)
cmdmod("revoke", function(_, param) return string_match(param, "([^ ]+) (.+)") end, true)
local revoke = minetest.registered_chatcommands.revoke
if revoke and not minetest.registered_chatcommands.revokeme then
minetest.register_chatcommand("revokeme", {
params = "<privilege> | all",
description = "Revoke privileges from yourself",
privs = revoke.privs,
func = function(pname, param)
return revoke.func(pname, pname .. " " .. param)
end
})
end