First commit

master
Billy S 2018-11-02 17:07:51 -04:00
commit 170b903722
3 changed files with 332 additions and 0 deletions

1
depends.txt Normal file
View File

@ -0,0 +1 @@
lib_chatcmdbuilder

283
init.lua Normal file
View File

@ -0,0 +1,283 @@
local function load_data()
ms = priv_roles.storage
local data = {}
data.players = minetest.deserialize(ms:get_string("players")) or {} -- Table of what players have what roles
data.roles = minetest.deserialize(ms:get_string("roles")) or {} -- Table of roles and associated privs
return data
end
local function save_data()
local p = minetest.serialize(priv_roles.data.players)
priv_roles.storage:set_string("players", p)
end
local function save_roles()
local r = minetest.serialize(priv_roles.data.roles)
priv_roles.storage:set_string("roles", r)
end
-- This really ought to be standard
function table.shallow_copy(t)
local t2 = {}
for k,v in pairs(t) do
t2[k] = v
end
return t2
end
-- Global mod list
priv_roles = {}
local p = minetest.get_modpath(minetest.get_current_modname())
-- Get old set_privs function
priv_roles.set_player_privs = minetest.set_player_privs
-- Call this to make sure that a player's role will exist
priv_roles.check_for_player = function(name)
if priv_roles.data.players[name] == nil then
priv_roles.data.players[name] = table.shallow_copy(priv_roles.default_roles)
priv_roles.data.players[name]["_extra"] = {}
end
-- Make sure _extra is defined
if priv_roles.data.players[name]["_extra"] == nil then
priv_roles.data.players[name]["_extra"] = {}
end
end
priv_roles.calc_privs = function(player, only_role_based)
priv_roles.check_for_player(player)
local roles = priv_roles.data.players[player]
if roles then
local privs = {}
for r, _ in pairs(roles) do
-- It could be the _extra role; if so ignore it
if r == "_extra" then
-- It could be a role that was removed; if so remove it
elseif priv_roles.data.roles[r] == nil then
priv_roles.data.players[player][r] = nil
else
local r_privs = table.shallow_copy(priv_roles.data.roles[r])
-- If "_all" is in r_privs, expand it to be all privs excepts ones mentioned in the role
if r_privs["_all"] then
for p, _ in pairs(minetest.registered_privileges) do
if r_privs[p] == nil then
r_privs[p] = true
end
end
r_privs["_all"] = nil
end
-- If "_nothing" is in r_privs, give no privs
if r_privs["_nothing"] then return {} end
-- Calculate the privs table
for p, v in pairs(r_privs) do
if privs[v] ~= false then -- If the priv is removed by a role, other roles can't re-add it
privs[p] = v
end
end
end
end
if only_role_based ~= true then
-- Apply all the privs in the _extra role
for priv, value in pairs(roles["_extra"]) do
privs[priv] = value
end
end
-- Get rid of all the privs with a value of false
local privs_table = {}
for p, v in pairs(privs) do
if v then
privs_table[p] = v
end
end
return privs_table
else
return {}
end
end
-- Redefine minetest.set_player_privs
function minetest.set_player_privs(player, full_privs)
-- Make sure player is valid
if (player == nil) or (not minetest.player_exists(player)) then
return false
end
-- Make sure privs table is valid
if full_privs == nil or type(full_privs) ~= "table" then
return false
end
-- Make sure the player has a roles table
priv_roles.check_for_player(player)
-- Get all the role-based privs
local privs = priv_roles.calc_privs(player, true)
local extra_privs = {}
-- Figure out what extra priv need to be granted
for p, _ in pairs(full_privs) do
if privs[p] == nil then
extra_privs[p] = true
end
end
-- Figure out what extra privs need to be removed
for p, _ in pairs(privs) do
if full_privs[p] == nil then
extra_privs[p] = false
end
end
-- Update _extra
priv_roles.data.players[player]["_extra"] = extra_privs
-- Calculate
local privs_final = priv_roles.calc_privs(player)
-- Set privs
priv_roles.set_player_privs(player, privs_final)
-- Save data
save_data()
end
-- Set up roles on joinplayer
minetest.register_on_joinplayer(function(player)
local pName = player:get_player_name()
priv_roles.check_for_player(pName)
-- Update privs (necessary for new players or if privs of a role were changed)
priv_roles.set_player_privs(pName, priv_roles.calc_privs(pName))
end)
-- Define mod functions
priv_roles.grant = function(player, role)
-- Get the role
local r = priv_roles.data.roles[role]
if r then -- Does the role exist
if minetest.player_exists(player) then -- Does the player exist?
priv_roles.check_for_player(player)
-- Add role to player
local p_roles = priv_roles.data.players[player]
p_roles[role] = true
priv_roles.data.players[player] = p_roles
-- Override anything in _extra that conflicts with that role
for p, _ in pairs(r) do
if priv_roles.data.players[player]["_extra"][p] == false then
priv_roles.data.players[player]["_extra"][p] = nil
end
end
-- Cacluate privs
local p_privs = priv_roles.calc_privs(player)
-- Assign privs
priv_roles.set_player_privs(player, p_privs)
-- Save data
save_data()
return true, "Done!"
else
return false, "Player " .. player .. "does not exist."
end
else
return false, "Role " .. role .. " does not exist."
end
end
priv_roles.revoke = function(player, role)
-- Get the role
local r = priv_roles.data.roles[role]
if r then -- Does the role exist
if minetest.player_exists(player) then -- Does the player exist?
priv_roles.check_for_player(player)
if priv_roles.data.players[player][role] then -- Does the player have that role?
-- Remove role from player
priv_roles.data.players[player][role] = nil
-- Override anything in _extra that has a priv in this role
for p, _ in pairs(r) do
if priv_roles.data.players[player]["_extra"][p] == true then
priv_roles.data.players[player]["_extra"][p] = nil
end
end
-- Calc privs
p_privs = priv_roles.calc_privs(player)
priv_roles.set_player_privs(player, p_privs)
-- Save data
save_data()
return true, "Done!"
else
return false, "Player " .. player .. " does not have role " .. role
end
else
return false, "Player " .. player .. " does not exist."
end
else
return false, "Role " .. role .. " does not exist."
end
end
priv_roles.list = function(player)
if minetest.player_exists(player) then
priv_roles.check_for_player(player)
local roles = priv_roles.data.players[player]
local r_str = "Roles of " .. player .. ":"
for r, _ in pairs(roles) do
if r ~= "_extra" then
r_str = r_str .. " " .. r
end
end
return true, r_str
else
return false, "Player " .. player .. " does not exist."
end
end
-- Load mod data
priv_roles.storage = minetest.get_mod_storage()
priv_roles.data = load_data()
-- Add in roles
dofile(p .. "/settings.lua")
-- Roles chat command
ChatCmdBuilder.new("roles", function(cmd)
-- grant player a role
cmd:sub("grant :name :role", function(name, t, r)
if minetest.check_player_privs(name, {privs = true}) then
local worked, msg = priv_roles.grant(t, r)
if worked then
minetest.chat_send_player(t, name .. " granted you the " .. r .. " role!")
end
return worked, msg
else
return false, "You don't have permission to run this command"
end
end)
-- revoke player a role
cmd:sub("revoke :name :role", function(name, t, r)
if minetest.check_player_privs(name, {privs = true}) then
local worked, msg = priv_roles.revoke(t, r)
if worked then
minetest.chat_send_player(t, name .. " revoked from you the " .. r .. " role!")
end
return worked, msg
else
return false, "You don't have permission to run this command"
end
end)
-- List player roles
cmd:sub("of :name", function(name, t)
local worked, msg = priv_roles.list(t)
return worked, msg
end)
-- List all roles
cmd:sub("list", function(name)
local l_str = "Available roles:"
for r, _ in pairs(priv_roles.data.roles) do
l_str = l_str .. " " .. r
end
return true, l_str
end)
-- Help
cmd:sub("help", function(name)
return true, "/roles grant <name> <role>: Grants player named <name> the role <role>\n" ..
"/roles revoke <name> <role>: Revokes role <role> from player named <name>\n" ..
"/roles of <name>: Lists the roles of player named <name>\n" ..
"/roles list: Lists all roles\n" ..
"/roles help: Shows this help"
end)
end, {
description = "Manage/view player roles",
privs = {
interact = true
}
})

48
settings.lua Normal file
View File

@ -0,0 +1,48 @@
-- Default roles; these are the roles given to a player when they join
priv_roles.default_roles = {player = true}
--
-- Player "ranks"
--
priv_roles.data.roles["player"] = { interact = true,
shout = true,
home = true}
priv_roles.data.roles["trusted"] = { lava = true,
areas_high_limit = true}
priv_roles.data.roles["moderator"] = { kick = true,
ban = true,
basic_privs = true,
fly = true,
jail = true,
bring = true,
teleport = true,
fast = true,
lava = true}
priv_roles.data.roles["admin"] = { _all = true,
server = false,
privs = false}
priv_roles.data.roles["owner"] = { _all = true}
--
-- Server builders
--
priv_roles.data.roles["builder"] = { fast = true,
fly = true,
creative = true,
noclip = true,
teleport = true,
areas = true}
priv_roles.data.roles["expert_builder"] = { worldedit = true}
--
-- Punishments
--
priv_roles.data.roles["noprivs"] = { _nothing = true}