update spectator mod

master
Juraj Vajda 2018-01-02 00:26:20 -05:00
parent bd9a224269
commit a710669117
1 changed files with 80 additions and 152 deletions

232
init.lua
View File

@ -522,180 +522,108 @@ minetest.register_chatcommand("cdebug", { -- toggle cdebug= display of stats on/
------------------------------------------------------
-- [Mod] Spectator Mode [git] [spectator_mode]
-- https://github.com/minetest-mods/spectator_mode
-- by jp » Tue Dec 08, 2015 15:34
-- modified/bugfixes by rnd
------------------------------------------------------
local original_pos = {}
minetest.register_privilege("watch", "Player can watch other players")
local function toggle_hud_flags(player, bool)
local flags = player:hud_get_flags()
local new_hud_flags = {}
for flag in pairs(flags) do
new_hud_flags[flag] = bool
end
player:hud_set_flags(new_hud_flags)
end
local function unwatching(name)
local watcher = minetest.get_player_by_name(name)
local privs = minetest.get_player_privs(name)
local watcher = minetest.get_player_by_name(name)
local privs = minetest.get_player_privs(name)
if watcher and default.player_attached[name] == true then
watcher:set_detach()
local pos = original_pos[watcher]
if pos then
-- setpos seems to be very unreliable
-- this workaround helps though
minetest.after(0.1, function()
watcher:setpos(pos)
end)
original_pos[watcher] = nil
end
cheat.watcher[name]=nil;
minetest.after(5,
function()
default.player_attached[name] = false
watcher:set_eye_offset({x=0, y=0, z=0}, {x=0, y=0, z=0})
watcher:set_nametag_attributes({color = {a=255, r=255, g=255, b=255}})
if watcher and default.player_attached[name] == true then
watcher:set_detach()
default.player_attached[name] = false
watcher:set_eye_offset(vector.new(), vector.new())
watcher:set_nametag_attributes({color = {a = 255, r = 255, g = 255, b = 255}})
watcher:hud_set_flags({
healthbar = true,
minimap = true,
breathbar = true,
hotbar = true,
wielditem = true,
crosshair = true
})
toggle_hud_flags(watcher, true)
watcher:set_properties({
visual_size = {x=1, y=1},
makes_footstep_sound = true,
collisionbox = {-0.3, -1, -0.3, 0.3, 1, 0.3}
})
end
)
-- if not privs.interact and cheat.moderators[name] == true then
-- privs.interact = true
-- minetest.set_player_privs(name, privs)
-- end
end
watcher:set_properties({
visual_size = {x = 1, y = 1},
makes_footstep_sound = true,
collisionbox = {-0.3, -1, -0.3, 0.3, 1, 0.3}
})
if not privs.interact and privs.watch == true then
privs.interact = true
minetest.set_player_privs(name, privs)
end
local pos = original_pos[watcher]
if pos then
-- setpos seems to be very unreliable
-- this workaround helps though
minetest.after(0.1, function()
watcher:setpos(pos)
end)
original_pos[watcher] = nil
end
end
end
minetest.register_chatcommand("watch", {
params = "<to_name>",
description = " - spectate what player is doing, stop with /unwatch",
privs = {interact=true},
func = function(name, param)
local privs = minetest.get_player_privs(name)
if not cheat.moderators[name] and not privs.kick then return end
local watcher = minetest.get_player_by_name(name)
if param == "" then -- no name given - select a suspect automatically
local players = minetest.get_connected_players();
for _,player in pairs(players) do
local pname = player:get_player_name();
if cheat.players[pname].count>0 then
param = pname;
cheat.suspect = param;
break;
end
end
if param == "" and cheat.suspect~="" then param = cheat.suspect end -- if none found watch last suspect
end
local target = minetest.get_player_by_name(param);
if not target then return end
if not cheat.players[param] then return end
params = "<to_name>",
description = "watch a given player",
privs = {watch = true},
func = function(name, param)
local watcher = minetest.get_player_by_name(name)
local target = minetest.get_player_by_name(param)
local privs = minetest.get_player_privs(name)
local canwatch = false;
for ip,v in pairs(anticheatdb) do
if v.name == param then
canwatch = true;
break;
end
end
local ip = tostring(minetest.get_player_ip(param));
if anticheatdb[ip] then canwatch = true end -- can watch since this ip was detected before
if canwatch or cheat.players[param].count>0 or param == cheat.suspect or privs.kick then
else
minetest.chat_send_player(name, "ordinary watchers can only watch cheat suspects of detected cheaters");
return
end
if target and watcher ~= target then
if default.player_attached[name] == true then
unwatching(param)
else
original_pos[watcher] = watcher:getpos()
end
-- show inventory
local tinv = target:get_inventory():get_list("main");
for i,v in pairs(tinv) do tinv[i] = v:to_string(); end
tinv = dump(tinv);
local form = "size [6,7] textarea[0,0;6.5,8.5;creport;INVENTORY LIST;".. minetest.formspec_escape(tinv).."]"
minetest.show_formspec(name, "watch_inventory", form)
default.player_attached[name] = true
watcher:set_attach(target, "", {x=0, y=-5, z=-20}, {x=0, y=0, z=0})
watcher:set_eye_offset({x=0, y=-5, z=-20}, {x=0, y=0, z=0})
watcher:set_nametag_attributes({color = {a=0}})
if target and watcher ~= target then
if default.player_attached[name] == true then
unwatching(param)
else
original_pos[watcher] = watcher:getpos()
end
watcher:hud_set_flags({
healthbar = false,
minimap = false,
breathbar = false,
hotbar = false,
wielditem = false,
crosshair = false
})
default.player_attached[name] = true
watcher:set_attach(target, "", vector.new(0, -5, -20), vector.new())
watcher:set_eye_offset(vector.new(0, -5, -20), vector.new())
watcher:set_nametag_attributes({color = {a = 0}})
watcher:set_properties({
visual_size = {x=0, y=0},
makes_footstep_sound = false,
collisionbox = {0}
})
toggle_hud_flags(watcher, true)
-- privs.interact = nil
-- minetest.set_player_privs(name, privs)
watcher:set_properties({
visual_size = {x = 0, y = 0},
makes_footstep_sound = false,
collisionbox = {0}
})
cheat.watcher[name]=true;
watchers[param][name] = true; -- register name as watcher of param
return true, "Watching '"..param.."' at "..minetest.pos_to_string(vector.round(target:getpos()))
end
privs.interact = nil
minetest.set_player_privs(name, privs)
return false, "Invalid parameter ('"..param.."')."
end
return true, "Watching '" .. param .. "' at "..
minetest.pos_to_string(vector.round(target:getpos()))
end
return false, "Invalid parameter ('" .. param .. "')."
end
})
minetest.register_chatcommand("unwatch", {
description = "",
privs = {interact=true},
func = function(name, param)
unwatching(name)
-- unregister name as watcher
for pname,val in pairs (watchers) do
if val[name] then watchers[pname][name] = nil; end
end
end
description = "unwatch a player",
privs = {watch=true},
func = function(name, param)
unwatching(name)
end
})
minetest.register_on_leaveplayer(function(player)
local name = player:get_player_name()
if watchers[name] then
for pname,_ in pairs (watchers[name]) do --xxx
unwatching(pname); -- all watchers do /unwatch
end
end
watchers[name] = nil;
local name = player:get_player_name()
unwatching(name)
end)