2022-10-05 07:47:21 -04:00

98 lines
3.1 KiB
Lua

-- LUALOCALS < ---------------------------------------------------------
local minetest, pairs, string, tonumber
= minetest, pairs, string, tonumber
local string_format
= string.format
-- LUALOCALS > ---------------------------------------------------------
local modname = minetest.get_current_modname()
local invert = minetest.settings:get_bool(modname .. "_invert")
local timeout = tonumber(minetest.settings:get(modname .. "_timeout")) or 600
local reason = minetest.settings:get(modname .. "_reason") or "idle timeout"
minetest.register_privilege(modname, {
description = (invert and "Kick" or "Do not kick") .. " this player when idle",
give_to_singleplayer = false,
give_to_admin = false
})
local function now() return minetest.get_us_time() / 1000000 end
local times = {}
local actions = {}
minetest.register_chatcommand(modname, {
description = "Check player idle time and last action",
privs = {server = true},
func = function(_, param)
local time = times[param]
if not time then
return true, string_format("Player %q not found", param)
end
local active = (not minetest.check_player_privs(param, modname))
== (not invert)
return true, string_format(
"Player %q idle %0.2f/%s last action %q",
param,
now() - time,
active and string_format("%.2f", timeout) or "never",
actions[param] or "unknown")
end
})
local function bumpn(pname, action)
times[pname] = now()
actions[pname] = action
return pname
end
local function bump(player, action)
if not (player and player.get_player_name) then return end
local pname = player:get_player_name()
if not pname then return end
return bumpn(pname, action)
end
minetest.register_on_joinplayer(function(player) return bump(player, "join") end)
minetest.register_on_placenode(function(_, _, player)
--do not return
bump(player, "placenode")
end)
minetest.register_on_dignode(function(_, _, player) return bump(player, "dignode") end)
minetest.register_on_punchnode(function(_, _, player) return bump(player, "punchnode") end)
minetest.register_on_chat_message(function(pname) bumpn(pname, "chat") end)
minetest.register_on_player_receive_fields(function(player) return bump(player, "formspec") end)
minetest.register_on_craft(function(_, player) bump(player, "craft") end)
minetest.register_on_player_inventory_action(function(player)
return bump(player, "inventory")
end)
local looks = {}
local ctlbits = {}
local function checkplayer(player)
local pname = player:get_player_name()
local bits = player:get_player_control_bits()
local oldbits = ctlbits[pname]
ctlbits[pname] = bits
local look = player:get_look_dir()
local oldlook = looks[pname]
looks[pname] = look
if bits ~= oldbits then
return bumpn(pname, "control")
elseif not (oldlook and vector.distance(look, oldlook) < 0.001) then
return bumpn(pname, "lookdir")
end
return pname
end
minetest.register_globalstep(function()
for _, player in pairs(minetest.get_connected_players()) do
if (not minetest.check_player_privs(player, modname)) ~= (not invert) then return end
local pname = checkplayer(player)
if times[pname] < now() - timeout then
minetest.kick_player(pname, reason)
end
end
end)