diff options
Diffstat (limited to 'builtin/game/chat.lua')
-rw-r--r-- | builtin/game/chat.lua | 119 |
1 files changed, 89 insertions, 30 deletions
diff --git a/builtin/game/chat.lua b/builtin/game/chat.lua index 493bb92c0..bbcdcf2d0 100644 --- a/builtin/game/chat.lua +++ b/builtin/game/chat.lua @@ -130,8 +130,13 @@ local function parse_range_str(player_name, str) return false, S("Unable to get position of player @1.", player_name) end else - p1, p2 = core.string_to_area(str) - if p1 == nil then + local player = core.get_player_by_name(player_name) + local relpos + if player then + relpos = player:get_pos() + end + p1, p2 = core.string_to_area(str, relpos) + if p1 == nil or p2 == nil then return false, S("Incorrect area format. " .. "Expected: (x1,y1,z1) (x2,y2,z2)") end @@ -310,12 +315,7 @@ local function handle_revoke_command(caller, revokename, revokeprivstr) and revokename == core.settings:get("name") and revokename ~= "" if revokeprivstr == "all" then - revokeprivs = privs - privs = {} - else - for priv, _ in pairs(revokeprivs) do - privs[priv] = nil - end + revokeprivs = table.copy(privs) end local privs_unknown = "" @@ -332,7 +332,10 @@ local function handle_revoke_command(caller, revokename, revokeprivstr) end local def = core.registered_privileges[priv] if not def then - privs_unknown = privs_unknown .. S("Unknown privilege: @1", priv) .. "\n" + -- Old/removed privileges might still be granted to certain players + if not privs[priv] then + privs_unknown = privs_unknown .. S("Unknown privilege: @1", priv) .. "\n" + end elseif is_singleplayer and def.give_to_singleplayer then irrevokable[priv] = true elseif is_admin and def.give_to_admin then @@ -359,19 +362,22 @@ local function handle_revoke_command(caller, revokename, revokeprivstr) end local revokecount = 0 - - core.set_player_privs(revokename, privs) for priv, _ in pairs(revokeprivs) do - -- call the on_revoke callbacks - core.run_priv_callbacks(revokename, priv, caller, "revoke") + privs[priv] = nil revokecount = revokecount + 1 end - local new_privs = core.get_player_privs(revokename) if revokecount == 0 then return false, S("No privileges were revoked.") end + core.set_player_privs(revokename, privs) + for priv, _ in pairs(revokeprivs) do + -- call the on_revoke callbacks + core.run_priv_callbacks(revokename, priv, caller, "revoke") + end + local new_privs = core.get_player_privs(revokename) + core.log("action", caller..' revoked (' ..core.privs_to_string(revokeprivs, ', ') ..') privileges from '..revokename) @@ -569,10 +575,15 @@ core.register_chatcommand("teleport", { description = S("Teleport to position or player"), privs = {teleport=true}, func = function(name, param) + local player = core.get_player_by_name(name) + local relpos + if player then + relpos = player:get_pos() + end local p = {} - p.x, p.y, p.z = param:match("^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$") - p = vector.apply(p, tonumber) - if p.x and p.y and p.z then + p.x, p.y, p.z = string.match(param, "^([%d.~-]+)[, ] *([%d.~-]+)[, ] *([%d.~-]+)$") + p = core.parse_coordinates(p.x, p.y, p.z, relpos) + if p and p.x and p.y and p.z then return teleport_to_pos(name, p) end @@ -586,9 +597,19 @@ core.register_chatcommand("teleport", { "other players (missing privilege: @1).", "bring") local teleportee_name + p = {} teleportee_name, p.x, p.y, p.z = param:match( - "^([^ ]+) +([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$") + "^([^ ]+) +([%d.~-]+)[, ] *([%d.~-]+)[, ] *([%d.~-]+)$") + if teleportee_name then + local teleportee = core.get_player_by_name(teleportee_name) + if not teleportee then + return + end + relpos = teleportee:get_pos() + p = core.parse_coordinates(p.x, p.y, p.z, relpos) + end p = vector.apply(p, tonumber) + if teleportee_name and p.x and p.y and p.z then if not has_bring_priv then return false, missing_bring_msg @@ -621,6 +642,10 @@ core.register_chatcommand("set", { setname, setvalue = string.match(param, "([^ ]+) (.+)") if setname and setvalue then + if setname:sub(1, 7) == "secure." then + return false, S("Failed. Cannot modify secure settings. " + .. "Edit the settings file manually.") + end if not core.settings:get(setname) then return false, S("Failed. Use '/set -n <name> <value>' " .. "to create a new setting.") @@ -837,7 +862,7 @@ core.register_chatcommand("spawnentity", { description = S("Spawn entity at given (or your) position"), privs = {give=true, interact=true}, func = function(name, param) - local entityname, p = string.match(param, "^([^ ]+) *(.*)$") + local entityname, pstr = string.match(param, "^([^ ]+) *(.*)$") if not entityname then return false, S("EntityName required.") end @@ -851,11 +876,15 @@ core.register_chatcommand("spawnentity", { if not core.registered_entities[entityname] then return false, S("Cannot spawn an unknown entity.") end - if p == "" then + local p + if pstr == "" then p = player:get_pos() else - p = core.string_to_pos(p) - if p == nil then + p = {} + p.x, p.y, p.z = string.match(pstr, "^([%d.~-]+)[, ] *([%d.~-]+)[, ] *([%d.~-]+)$") + local relpos = player:get_pos() + p = core.parse_coordinates(p.x, p.y, p.z, relpos) + if not (p and p.x and p.y and p.z) then return false, S("Invalid parameters (@1).", param) end end @@ -1014,6 +1043,13 @@ core.register_chatcommand("status", { end, }) +local function get_time(timeofday) + local time = math.floor(timeofday * 1440) + local minute = time % 60 + local hour = (time - minute) / 60 + return time, hour, minute +end + core.register_chatcommand("time", { params = S("[<0..23>:<0..59> | <0..24000>]"), description = S("Show or set time of day"), @@ -1032,9 +1068,14 @@ core.register_chatcommand("time", { return false, S("You don't have permission to run " .. "this command (missing privilege: @1).", "settime") end - local hour, minute = param:match("^(%d+):(%d+)$") - if not hour then - local new_time = tonumber(param) or -1 + local relative, negative, hour, minute = param:match("^(~?)(%-?)(%d+):(%d+)$") + if not relative then -- checking the first capture against nil suffices + local new_time = core.parse_relative_number(param, core.get_timeofday() * 24000) + if not new_time then + new_time = tonumber(param) or -1 + else + new_time = new_time % 24000 + end if new_time ~= new_time or new_time < 0 or new_time > 24000 then return false, S("Invalid time (must be between 0 and 24000).") end @@ -1042,14 +1083,29 @@ core.register_chatcommand("time", { core.log("action", name .. " sets time to " .. new_time) return true, S("Time of day changed.") end + local new_time hour = tonumber(hour) minute = tonumber(minute) - if hour < 0 or hour > 23 then - return false, S("Invalid hour (must be between 0 and 23 inclusive).") - elseif minute < 0 or minute > 59 then - return false, S("Invalid minute (must be between 0 and 59 inclusive).") + if relative == "" then + if hour < 0 or hour > 23 then + return false, S("Invalid hour (must be between 0 and 23 inclusive).") + elseif minute < 0 or minute > 59 then + return false, S("Invalid minute (must be between 0 and 59 inclusive).") + end + new_time = (hour * 60 + minute) / 1440 + else + if minute < 0 or minute > 59 then + return false, S("Invalid minute (must be between 0 and 59 inclusive).") + end + local current_time = core.get_timeofday() + if negative == "-" then -- negative time + hour, minute = -hour, -minute + end + new_time = (current_time + (hour * 60 + minute) / 1440) % 1 + local _ + _, hour, minute = get_time(new_time) end - core.set_timeofday((hour * 60 + minute) / 1440) + core.set_timeofday(new_time) core.log("action", ("%s sets time to %d:%02d"):format(name, hour, minute)) return true, S("Time of day changed.") end, @@ -1131,6 +1187,9 @@ core.register_chatcommand("ban", { return true, S("Ban list: @1", ban_list) end end + if core.is_singleplayer() then + return false, S("You cannot ban players in singleplayer!") + end if not core.get_player_by_name(param) then return false, S("Player is not online.") end |