Better position memory

This commit is contained in:
Evert Prants 2019-11-11 18:52:54 +02:00
parent a3e43cc09a
commit 9993be4661
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
5 changed files with 75 additions and 41 deletions

6
ess/settingtypes.txt Normal file
View File

@ -0,0 +1,6 @@
# Save death position so that the player can return to it via /back
ess_save_death (Save death position) bool false
# /tpa request timeout in seconds
ess_tpa_timeout (tpask request timeout in seconds) int 120

View File

@ -1,8 +1,10 @@
local ess_save_death = minetest.settings:get_bool("ess_save_death", false)
local ess_tpa_timeout = tonumber(minetest.settings:get("ess_tpa_timeout")) or 120
local tpask = { local tpask = {
requests = {}, requests = {},
muted = {}, muted = {},
timeout = 120,
} }
local function cmd_top(name) local function cmd_top(name)
@ -29,7 +31,9 @@ local function cmd_back(name)
if not pos then if not pos then
return false, "Could not return to previous position." return false, "Could not return to previous position."
end end
minetest.get_player_by_name(name):set_pos(pos) local p = minetest.get_player_by_name(name)
ess.save_player_pos(p)
p:set_pos(pos)
return true, "Teleported back." return true, "Teleported back."
end end
@ -43,7 +47,7 @@ local function cmd_tpcommon(name,tname,direction)
return false, "Could not find player." return false, "Could not find player."
end end
if tpask.requests[tname] and tpask.requests[tname].when > minetest.get_us_time() - tpask.timeout * 100000 then if tpask.requests[tname] and tpask.requests[tname].when > minetest.get_us_time() - ess_tpa_timeout * 100000 then
return false, "There are currently pending requests regarding this player. Please wait." return false, "There are currently pending requests regarding this player. Please wait."
end end
@ -56,10 +60,10 @@ local function cmd_tpcommon(name,tname,direction)
minetest.chat_send_player(tname, name .. " has requested "..message..".") minetest.chat_send_player(tname, name .. " has requested "..message..".")
minetest.chat_send_player(tname, "Run /tpaccept to accept or /tpadeny to deny.") minetest.chat_send_player(tname, "Run /tpaccept to accept or /tpadeny to deny.")
if tpask.timeout > 0 then if ess_tpa_timeout > 0 then
minetest.chat_send_player(tname, "You have "..tpask.timeout.." seconds to respond.") minetest.chat_send_player(tname, "You have "..ess_tpa_timeout.." seconds to respond.")
end end
tpask.requests[tname] = {when = minetest.get_us_time()} tpask.requests[tname] = {when = minetest.get_gametime()}
if direction == 1 then if direction == 1 then
tpask.requests[tname].who = name tpask.requests[tname].who = name
else else
@ -81,7 +85,7 @@ end
local function cmd_tpaconfirm(name) local function cmd_tpaconfirm(name)
local reqs = tpask.requests[name] local reqs = tpask.requests[name]
local me = minetest.get_player_by_name(name) local me = minetest.get_player_by_name(name)
if not reqs or (tpask.timeout > 0 and tpask.requests[name].when < minetest.get_us_time() - tpask.timeout * 100000) then if not reqs or (tpask.timeout > 0 and tpask.requests[name].when < minetest.get_gametime() - ess_tpa_timeout) then
return false, "You have no pending teleport requests." return false, "You have no pending teleport requests."
end end
@ -94,9 +98,11 @@ local function cmd_tpaconfirm(name)
if reqs.to then if reqs.to then
minetest.chat_send_player(name, "Teleporting..") minetest.chat_send_player(name, "Teleporting..")
ess.save_player_pos(me)
me:set_pos(whoplayer:get_pos()) me:set_pos(whoplayer:get_pos())
else else
minetest.chat_send_player(who, "Teleporting..") minetest.chat_send_player(who, "Teleporting..")
ess.save_player_pos(whoplayer)
whoplayer:set_pos(me:get_pos()) whoplayer:set_pos(me:get_pos())
end end
@ -107,7 +113,7 @@ end
local function cmd_tpadeny(name) local function cmd_tpadeny(name)
local reqs = tpask.requests[name] local reqs = tpask.requests[name]
if not reqs or tpask.requests[name].when < minetest.get_us_time() - tpask.timeout * 1000 then if not reqs or tpask.requests[name].when < minetest.get_gametime() - tpask.timeout then
return false, "You have no pending teleport requests." return false, "You have no pending teleport requests."
end end
@ -137,7 +143,6 @@ local commands = {
privs = { privs = {
["ess.teleport.tpa"] = true, ["ess.teleport.tpa"] = true,
}, },
save_player_pos = true,
func = cmd_tpask, func = cmd_tpask,
}, },
["tpaskhere"] = { ["tpaskhere"] = {
@ -147,14 +152,12 @@ local commands = {
privs = { privs = {
["ess.teleport.tpahere"] = true, ["ess.teleport.tpahere"] = true,
}, },
save_player_pos = true,
func = cmd_tpaskhere, func = cmd_tpaskhere,
}, },
["tpaccept"] = { ["tpaccept"] = {
description = "Accept a teleport request.", description = "Accept a teleport request.",
aliases = {"tpayes"}, aliases = {"tpayes"},
func = cmd_tpaconfirm, func = cmd_tpaconfirm,
save_player_pos = true,
}, },
["tpdeny"] = { ["tpdeny"] = {
description = "Reject a teleport request.", description = "Reject a teleport request.",
@ -169,7 +172,6 @@ local commands = {
description = "Teleports you to your location prior to tp/spawn/warp.", description = "Teleports you to your location prior to tp/spawn/warp.",
aliases = {"return"}, aliases = {"return"},
privs = true, privs = true,
save_player_pos = true,
func = cmd_back, func = cmd_back,
}, },
["top"] = { ["top"] = {
@ -193,3 +195,10 @@ local commands = {
} }
ess.autoregister(commands, "teleport") ess.autoregister(commands, "teleport")
-- Save death point for use with /back
if ess_save_death then
minetest.register_on_dieplayer(function(player)
ess.save_player_pos(player)
end)
end

View File

@ -35,7 +35,6 @@ local function cmd_repair(name, params, splitparams)
commit = 1 commit = 1
end end
if commit == 1 and player then if commit == 1 and player then
local held = player:get_wielded_item() local held = player:get_wielded_item()
if held:get_wear() > 0 then if held:get_wear() > 0 then

View File

@ -67,6 +67,7 @@ local function cmd_warp(name,params,splitparams)
return false, "No such user." return false, "No such user."
end end
ess.save_player_pos(user)
user:set_pos(exists) user:set_pos(exists)
return true, "Warped to "..location.."." return true, "Warped to "..location.."."
end end
@ -98,7 +99,6 @@ local commands = {
["ess.warp.warp"] = true, ["ess.warp.warp"] = true,
["ess.warp.warp.other"] = true, ["ess.warp.warp.other"] = true,
}, },
save_player_pos = true,
func = cmd_warp, func = cmd_warp,
}, },
["setwarp"] = { ["setwarp"] = {

View File

@ -3,11 +3,11 @@
local storage = minetest.get_mod_storage() local storage = minetest.get_mod_storage()
ess = { ess = {
modules = {},
commands = {}, commands = {},
privileges = {}, privileges = {},
modules = {},
player_meta = {},
world_meta = nil, world_meta = nil,
player_meta = {},
} }
--------------------- ---------------------
@ -54,7 +54,7 @@ end
-- WORLD METADATA -- -- WORLD METADATA --
-------------------- --------------------
-- Load player metadata -- Load world metadata
local function worlddata_load() local function worlddata_load()
local decoded = minetest.deserialize(storage:get_string("_data")) local decoded = minetest.deserialize(storage:get_string("_data"))
if not decoded then if not decoded then
@ -66,21 +66,21 @@ local function worlddata_load()
return decoded return decoded
end end
-- Save player metadata -- Save world metadata
local function worlddata_save() local function worlddata_save()
if not ess.world_meta then return end if not ess.world_meta then return end
local encoded = minetest.serialize(ess.world_meta) local encoded = minetest.serialize(ess.world_meta)
storage:set_string("_data", encoded) storage:set_string("_data", encoded)
end end
-- Set a player metadata value -- Set a world metadata value
function ess.set_world_meta(flag, value) function ess.set_world_meta(flag, value)
if not ess.world_meta then worlddata_load() end if not ess.world_meta then worlddata_load() end
ess.world_meta[flag] = value ess.world_meta[flag] = value
worlddata_save() worlddata_save()
end end
-- Get a player's metadata value -- Get a world metadata value
function ess.get_world_meta(flag) function ess.get_world_meta(flag)
if not ess.world_meta then worlddata_load() end if not ess.world_meta then worlddata_load() end
return ess.world_meta[flag] return ess.world_meta[flag]
@ -95,31 +95,52 @@ function ess.reject_permission()
return false, "You don't have permission to run this command." return false, "You don't have permission to run this command."
end end
-- Match a single privilege, but also check ".all" privileges -- Match a single privilege, but also check ".all" privileges (optional)
function ess.priv_match(name, priv) function ess.priv_match(name, priv, skip_alls)
if not skip_alls then
local parts = string.split(priv, ".") local parts = string.split(priv, ".")
if #parts > 1 then if #parts > 1 then
if parts[1] ~= "ess" and minetest.check_player_privs(name, {["ess.all"] = true}) then
return true
end
if minetest.check_player_privs(name, {[parts[1] .. ".all"] = true}) then if minetest.check_player_privs(name, {[parts[1] .. ".all"] = true}) then
return true return true
end end
if #parts > 2 then if #parts > 2 then
if minetest.check_player_privs(name, {[parts[1] .. "." .. parts[2] .. ".all"] = true}) then if minetest.check_player_privs(name, {[parts[1] .. "." .. parts[2] .. ".all"] = true}) then
return true return true
end end
end end
end end
end
return minetest.check_player_privs(name, {[priv] = true}) return minetest.check_player_privs(name, {[priv] = true})
end end
-- Save a player's position for use with /back -- Save a player's position
local function save_player_pos(player, commit) -- If commit is not defined or true, we save current position
local pobj = minetest.get_player_by_name(player) -- If commit is false, just the player's position is returned
-- If commit is a position, we save that position
function ess.save_player_pos(player, commit)
local pobj
local name = player
if type(player) ~= "userdata" then
pobj = minetest.get_player_by_name(player)
if not pobj then return end if not pobj then return end
else
name = player:get_player_name()
pobj = player
end
local pos = pobj:get_pos() local pos = pobj:get_pos()
if commit == nil or commit == true then
commit = pos
end
if commit then if commit then
ess.set_player_meta(player, "position", minetest.pos_to_string(commit)) ess.set_player_meta(name, "position", minetest.pos_to_string(commit))
end end
return pos return pos
@ -142,6 +163,7 @@ local function handle_command_privileges(privileges, description, default)
end end
perms[perm] = true perms[perm] = true
-- Make sure .all privileges are registered
if #parts > 1 then if #parts > 1 then
for i,p in ipairs(parts) do for i,p in ipairs(parts) do
if i == 1 then if i == 1 then
@ -154,23 +176,20 @@ local function handle_command_privileges(privileges, description, default)
}) })
ess.privileges[a] = true ess.privileges[a] = true
end end
perms[a] = true
elseif i == 2 then elseif i == 2 then
local a = parts[1] .. "." .. p .. ".all" local a = parts[1] .. "." .. p .. ".all"
if not ess.privileges[a] then if not ess.privileges[a] then
minetest.register_privilege(a, { minetest.register_privilege(a, {
description = "icyess all commands in module " .. p .. " category "..p, description = "icyess all commands in module " .. parts[1] .. " category "..p,
give_to_singleplayer = false, give_to_singleplayer = false,
give_to_admin = false give_to_admin = false
}) })
ess.privileges[a] = true ess.privileges[a] = true
end end
perms[a] = true
end end
end end
end end
end end
perms["ess.all"] = true
return perms return perms
end end
@ -205,7 +224,7 @@ local function register_chatcommand(command, def)
-- If this command is a teleport, save the player position -- If this command is a teleport, save the player position
local player_pos local player_pos
if def.save_player_pos then if def.save_player_pos then
player_pos = save_player_pos(name) player_pos = ess.save_player_pos(name, false)
end end
local splitparams = string.split(params, " ") local splitparams = string.split(params, " ")
@ -215,7 +234,7 @@ local function register_chatcommand(command, def)
-- If we saved player position and the command succeeded, commit the last position save -- If we saved player position and the command succeeded, commit the last position save
if ret and player_pos then if ret and player_pos then
save_player_pos(name, player_pos) ess.save_player_pos(name, player_pos)
end end
return ret,mesg return ret,mesg
@ -295,7 +314,8 @@ end
default = false, default = false,
-- If this command modifies player's position in some way, -- If this command modifies player's position in some way,
-- save their current position before running the command -- save their current position before running the command.
-- Use this only when its is certain that the player will teleport.
save_player_pos = false save_player_pos = false
} }
]] ]]