diff --git a/builtin/game/chat.lua b/builtin/game/chat.lua index 10da054fd..0bd12c25f 100644 --- a/builtin/game/chat.lua +++ b/builtin/game/chat.lua @@ -167,6 +167,18 @@ core.register_chatcommand("admin", { end, }) +local function privileges_of(name, privs) + if not privs then + privs = core.get_player_privs(name) + end + local privstr = core.privs_to_string(privs, ", ") + if privstr == "" then + return S("@1 does not have any privileges.", name) + else + return S("Privileges of @1: @2", name, privstr) + end +end + core.register_chatcommand("privs", { params = S("[]"), description = S("Show privileges of yourself or another player"), @@ -176,9 +188,7 @@ core.register_chatcommand("privs", { if not core.player_exists(name) then return false, S("Player @1 does not exist.", name) end - return true, S("Privileges of @1: @2", name, - core.privs_to_string( - core.get_player_privs(name), ", ")) + return true, privileges_of(name) end, }) @@ -227,7 +237,10 @@ local function handle_grant_command(caller, grantname, grantprivstr) core.string_to_privs(core.settings:get("basic_privs") or "interact,shout") for priv, _ in pairs(grantprivs) do if not basic_privs[priv] and not caller_privs.privs then - return false, S("Your privileges are insufficient.") + return false, S("Your privileges are insufficient. ".. + "'@1' only allows you to grant: @2", + "basic_privs", + core.privs_to_string(basic_privs, ', ')) end if not core.registered_privileges[priv] then privs_unknown = privs_unknown .. S("Unknown privilege: @1", priv) .. "\n" @@ -246,15 +259,13 @@ local function handle_grant_command(caller, grantname, grantprivstr) if grantname ~= caller then core.chat_send_player(grantname, S("@1 granted you privileges: @2", caller, - core.privs_to_string(grantprivs, ' '))) + core.privs_to_string(grantprivs, ', '))) end - return true, S("Privileges of @1: @2", grantname, - core.privs_to_string( - core.get_player_privs(grantname), ' ')) + return true, privileges_of(grantname) end core.register_chatcommand("grant", { - params = S(" ( | all)"), + params = S(" ( [, [<...>]] | all)"), description = S("Give privileges to player"), func = function(name, param) local grantname, grantprivstr = string.match(param, "([^ ]+) (.+)") @@ -266,7 +277,7 @@ core.register_chatcommand("grant", { }) core.register_chatcommand("grantme", { - params = S(" | all"), + params = S(" [, [<...>]] | all"), description = S("Grant privileges to yourself"), func = function(name, param) if param == "" then @@ -286,16 +297,13 @@ local function handle_revoke_command(caller, revokename, revokeprivstr) return false, S("Player @1 does not exist.", revokename) end - local revokeprivs = core.string_to_privs(revokeprivstr) local privs = core.get_player_privs(revokename) - local basic_privs = - core.string_to_privs(core.settings:get("basic_privs") or "interact,shout") - for priv, _ in pairs(revokeprivs) do - if not basic_privs[priv] and not caller_privs.privs then - return false, S("Your privileges are insufficient.") - end - end + local revokeprivs = core.string_to_privs(revokeprivstr) + local is_singleplayer = core.is_singleplayer() + local is_admin = not is_singleplayer + and revokename == core.settings:get("name") + and revokename ~= "" if revokeprivstr == "all" then revokeprivs = privs privs = {} @@ -305,27 +313,73 @@ local function handle_revoke_command(caller, revokename, revokeprivstr) end end + local privs_unknown = "" + local basic_privs = + core.string_to_privs(core.settings:get("basic_privs") or "interact,shout") + local irrevokable = {} + local has_irrevokable_priv = false + for priv, _ in pairs(revokeprivs) do + if not basic_privs[priv] and not caller_privs.privs then + return false, S("Your privileges are insufficient. ".. + "'@1' only allows you to revoke: @2", + "basic_privs", + core.privs_to_string(basic_privs, ', ')) + end + local def = core.registered_privileges[priv] + if not def then + privs_unknown = privs_unknown .. S("Unknown privilege: @1", priv) .. "\n" + elseif is_singleplayer and def.give_to_singleplayer then + irrevokable[priv] = true + elseif is_admin and def.give_to_admin then + irrevokable[priv] = true + end + end + for priv, _ in pairs(irrevokable) do + revokeprivs[priv] = nil + has_irrevokable_priv = true + end + if privs_unknown ~= "" then + return false, privs_unknown + end + if has_irrevokable_priv then + if is_singleplayer then + core.chat_send_player(caller, + S("Note: Cannot revoke in singleplayer: @1", + core.privs_to_string(irrevokable, ', '))) + elseif is_admin then + core.chat_send_player(caller, + S("Note: Cannot revoke from admin: @1", + core.privs_to_string(irrevokable, ', '))) + end + end + + local revokecount = 0 for priv, _ in pairs(revokeprivs) do -- call the on_revoke callbacks core.run_priv_callbacks(revokename, priv, caller, "revoke") + revokecount = revokecount + 1 end core.set_player_privs(revokename, privs) + local new_privs = core.get_player_privs(revokename) + + if revokecount == 0 then + return false, S("No privileges were revoked.") + end + core.log("action", caller..' revoked (' ..core.privs_to_string(revokeprivs, ', ') ..') privileges from '..revokename) if revokename ~= caller then core.chat_send_player(revokename, S("@1 revoked privileges from you: @2", caller, - core.privs_to_string(revokeprivs, ' '))) + core.privs_to_string(revokeprivs, ', '))) end - return true, S("Privileges of @1: @2", revokename, - core.privs_to_string( - core.get_player_privs(revokename), ' ')) + return true, privileges_of(revokename, new_privs) end core.register_chatcommand("revoke", { - params = S(" ( | all)"), + params = S(" ( [, [<...>]] | all)"), description = S("Remove privileges from player"), privs = {}, func = function(name, param) @@ -338,7 +392,7 @@ core.register_chatcommand("revoke", { }) core.register_chatcommand("revokeme", { - params = S(" | all"), + params = S(" [, [<...>]] | all"), description = S("Revoke privileges from yourself"), privs = {}, func = function(name, param) diff --git a/builtin/game/privileges.lua b/builtin/game/privileges.lua index aee32a34e..1d3efb525 100644 --- a/builtin/game/privileges.lua +++ b/builtin/game/privileges.lua @@ -32,7 +32,13 @@ end core.register_privilege("interact", S("Can interact with things and modify the world")) core.register_privilege("shout", S("Can speak in chat")) -core.register_privilege("basic_privs", S("Can modify 'shout' and 'interact' privileges")) + +local basic_privs = + core.string_to_privs((core.settings:get("basic_privs") or "shout,interact")) +local basic_privs_desc = S("Can modify basic privileges (@1)", + core.privs_to_string(basic_privs, ', ')) +core.register_privilege("basic_privs", basic_privs_desc) + core.register_privilege("privs", S("Can modify privileges")) core.register_privilege("teleport", {