Start work on offline player pos mod.
Keep track of player last positions when offline, for admin access. Add ability to dump player coords, and show player location HUDs (which coincide nicely with nodecore name HUDs)
This commit is contained in:
parent
ed95de8310
commit
c85b888874
12
szutil_offlinepos/README
Normal file
12
szutil_offlinepos/README
Normal file
@ -0,0 +1,12 @@
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Keep track of player last position, even when players are offline.
|
||||
Add support for some commands utilizing player positions.
|
||||
|
||||
- Support /teleport to offline players.
|
||||
|
||||
- Add /pos to get player's current position.
|
||||
|
||||
- Add /postrack to enable/disable player position waypoints.
|
||||
|
||||
------------------------------------------------------------------------
|
147
szutil_offlinepos/init.lua
Normal file
147
szutil_offlinepos/init.lua
Normal file
@ -0,0 +1,147 @@
|
||||
-- LUALOCALS < ---------------------------------------------------------
|
||||
local minetest, pairs, string, table
|
||||
= minetest, pairs, string, table
|
||||
local string_gmatch, string_match, table_concat
|
||||
= string.gmatch, string.match, table.concat
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
local modstore = minetest.get_mod_storage()
|
||||
|
||||
minetest.register_privilege(modname, {
|
||||
description = "Can see position of other players",
|
||||
give_to_singleplayer = false,
|
||||
give_to_admin = true
|
||||
})
|
||||
|
||||
local function matchplayers(spec)
|
||||
local found = {}
|
||||
local fields = modstore:to_table().fields
|
||||
for k, v in pairs(fields) do
|
||||
local matched
|
||||
for p in string_gmatch(spec, "[^%s]+") do
|
||||
matched = matched or string_match(k, p)
|
||||
end
|
||||
if matched then
|
||||
local player = minetest.get_player_by_name(k)
|
||||
found[k] = {
|
||||
name = k,
|
||||
pos = player and player:get_pos() or minetest.string_to_pos(v),
|
||||
player = player
|
||||
}
|
||||
end
|
||||
end
|
||||
return found
|
||||
end
|
||||
|
||||
minetest.register_chatcommand("pos", {
|
||||
description = "Get current position of players",
|
||||
privs = {[modname] = true},
|
||||
func = function(_, param)
|
||||
local rpt = {}
|
||||
for k, v in pairs(matchplayers(param)) do
|
||||
rpt[#rpt + 1] = k .. " at "
|
||||
.. minetest.pos_to_string(vector.round(v.pos))
|
||||
.. (v.player and " [online]" or "")
|
||||
end
|
||||
if #rpt < 1 then rpt = {"no match found"} end
|
||||
return true, table_concat(rpt, "\n")
|
||||
end
|
||||
})
|
||||
|
||||
local trackcache = {}
|
||||
minetest.register_chatcommand("postrack", {
|
||||
description = "Track current position of players",
|
||||
privs = {[modname] = true},
|
||||
func = function(pname, param)
|
||||
local player = minetest.get_player_by_name(pname)
|
||||
if not player then return false, "Cannot track while offline" end
|
||||
|
||||
local tracking = matchplayers(param)
|
||||
local total = 0
|
||||
for k in pairs(tracking) do
|
||||
if k ~= pname then
|
||||
tracking[k] = true
|
||||
total = total + 1
|
||||
else
|
||||
tracking[k] = nil
|
||||
end
|
||||
end
|
||||
|
||||
trackcache[pname] = tracking
|
||||
player:get_meta():set_string(modname, minetest.serialize(tracking))
|
||||
return true, "now tracking " .. total .. " player(s)"
|
||||
end
|
||||
})
|
||||
|
||||
local huds = {}
|
||||
|
||||
minetest.register_globalstep(function()
|
||||
for _, player in pairs(minetest.get_connected_players()) do
|
||||
local pname = player:get_player_name()
|
||||
modstore:set_string(pname, minetest.pos_to_string(player:get_pos()))
|
||||
|
||||
local tracking = {}
|
||||
if minetest.check_player_privs(pname, modname) then
|
||||
tracking = trackcache[pname]
|
||||
if not tracking then
|
||||
local s = player:get_meta():get_string(modname)
|
||||
tracking = s and s ~= "" and minetest.deserialize(s) or {}
|
||||
end
|
||||
end
|
||||
|
||||
local phuds = huds[pname]
|
||||
if not phuds then
|
||||
phuds = {}
|
||||
huds[pname] = phuds
|
||||
end
|
||||
|
||||
local show = {}
|
||||
for k in pairs(tracking) do
|
||||
local peer = minetest.get_player_by_name(k)
|
||||
local ppos = peer and peer:get_pos()
|
||||
if not ppos then
|
||||
local s = modstore:get_string(k)
|
||||
ppos = s and s ~= "" and minetest.string_to_pos(s)
|
||||
end
|
||||
if ppos then
|
||||
ppos.y = ppos.y + 1.25
|
||||
ppos.on = not not peer
|
||||
show[k] = ppos
|
||||
end
|
||||
end
|
||||
|
||||
for k, v in pairs(show) do
|
||||
local old = phuds[k]
|
||||
if old then
|
||||
if not vector.equals(old.pos, v) then
|
||||
player:hud_change(old.id, "world_pos", v)
|
||||
old.pos = v
|
||||
end
|
||||
if old.on ~= v.on then
|
||||
player:hud_change(old.id, "name", v.on and k
|
||||
or ("[" .. k .. "]"))
|
||||
old.on = v.on
|
||||
end
|
||||
else
|
||||
phuds[k] = {
|
||||
pos = v,
|
||||
on = v.on,
|
||||
id = player:hud_add({
|
||||
hud_elem_type = "waypoint",
|
||||
world_pos = v,
|
||||
name = v.on and k or ("(" .. k .. ")"),
|
||||
number = 0xffff00
|
||||
})
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
for k, v in pairs(phuds) do
|
||||
if not show[k] then
|
||||
player:hud_remove(v.id)
|
||||
phuds[k] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
Loading…
x
Reference in New Issue
Block a user