9e9cd6ca48
Things like auto-forward or a taped down mining key also count as "idle" for this system's purposes as well, to avoid players trivially exploiting to avoid being kicked, or to prevent false positives caused by stuck controls.
64 lines
2.3 KiB
Lua
64 lines
2.3 KiB
Lua
-- LUALOCALS < ---------------------------------------------------------
|
|
local minetest, pairs, tonumber
|
|
= minetest, pairs, tonumber
|
|
-- 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 times = {}
|
|
|
|
local function now() return minetest.get_us_time() / 1000000 end
|
|
local function bumpn(pname) times[pname] = now() return pname end
|
|
local function bump(player)
|
|
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)
|
|
end
|
|
|
|
minetest.register_on_joinplayer(function(player) return bump(player) end)
|
|
minetest.register_on_placenode(function(_, _, player)
|
|
--do not return
|
|
bump(player)
|
|
end)
|
|
minetest.register_on_dignode(function(_, _, player) return bump(player) end)
|
|
minetest.register_on_punchnode(function(_, _, player) return bump(player) end)
|
|
minetest.register_on_chat_message(function(pname) bumpn(pname) end)
|
|
minetest.register_on_player_receive_fields(function(player) return bump(player) end)
|
|
minetest.register_on_craft(function(_, player) bump(player) end)
|
|
minetest.register_on_player_inventory_action(function(player) return bump(player) 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] = oldlook
|
|
if not (oldbits == bits and oldlook and vector.distance(look, oldlook) < 0.001)
|
|
then return bumpn(pname) 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)
|