summaryrefslogtreecommitdiff
path: root/builtin/game/chat.lua
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/game/chat.lua')
-rw-r--r--builtin/game/chat.lua119
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