153 lines
4.1 KiB
Lua
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
|