Remove too idle players

This commit is contained in:
kay27 2022-03-09 05:21:05 +04:00
parent 869154f86d
commit 1e8f5ffc74
1 changed files with 84 additions and 1 deletions

View File

@ -13,6 +13,7 @@ local find_nodes_in_area = minetest.find_nodes_in_area
local ceil = math.ceil local ceil = math.ceil
local floor = math.floor local floor = math.floor
local vector_length = vector.length
local distance = vector.distance local distance = vector.distance
@ -20,6 +21,10 @@ local window_size = 8
local detection_interval = 1.6 local detection_interval = 1.6
local step_seconds = detection_interval / window_size local step_seconds = detection_interval / window_size
local joined_players = {} local joined_players = {}
local ip_to_players = {}
local player_name_to_ip = {}
local player_doesnt_move = {}
local ban_next_time = {}
local function update_settings() local function update_settings()
enable_anticheat = minetest.settings:get_bool("enable_anticheat", true) enable_anticheat = minetest.settings:get_bool("enable_anticheat", true)
@ -58,9 +63,15 @@ local function update_player(player_object)
local noclip = #find_nodes_in_area({x = x, y = head_y, z = z}, {x = x + 1, y = head_y + 1, z = z + 1}, "group:opaque") == 8 local noclip = #find_nodes_in_area({x = x, y = head_y, z = z}, {x = x + 1, y = head_y + 1, z = z + 1}, "group:opaque") == 8
local velocity = player_object:get_velocity()
if vector_length(velocity) < 0.00000001 then
player_doesnt_move[name] = (player_doesnt_move[name] or 0) + 1
else
player_doesnt_move[name] = 0
end
local player_data = { local player_data = {
pos = pos, pos = pos,
velocity = player_object:get_velocity(), velocity = velocity,
air = air, air = air,
noclip = noclip, noclip = noclip,
} }
@ -142,7 +153,24 @@ local function remove_player(player_object)
if not player_object then return end if not player_object then return end
local name = player_object:get_player_name() local name = player_object:get_player_name()
if not name then return end if not name then return end
local ip = player_name_to_ip[name]
player_name_to_ip[name] = nil
if ip then
local players = ip_to_players[ip]
if players then
for k, v in pairs(players) do
if v == name then
if k < #players then
players[k] = players[#players]
end
players[#players] = nil
break
end
end
end
end
minetest.after(step_seconds, function() minetest.after(step_seconds, function()
player_doesnt_move[name] = nil
joined_players[name] = nil joined_players[name] = nil
end) end)
end end
@ -154,6 +182,50 @@ local function step()
check_player(player:get_player_name()) check_player(player:get_player_name())
end end
end end
for ip, players in pairs(ip_to_players) do
if #players > 2 then
local first = players[1]
local should_be_banned = ban_next_time[ip]
if #players < 6 then
for _, player_name in pairs(players) do
if (player_doesnt_move[player_name] or 0) > 1800/step_seconds then
minetest.kick_player(player_name, "Didn't move during 30 minutes, more than 2 connections from IP " .. ip)
end
end
elseif #players < 10 then
for _, player_name in pairs(players) do
if (player_doesnt_move[player_name] or 0) > 600/step_seconds then
minetest.kick_player(player_name, "Didn't move during 10 minutes, more than 5 connections from IP " .. ip)
end
end
elseif #players < 26 then
if should_be_banned then
minetest.chat_send_all("Player " .. first .. " has been banned for having more than 9 connections at once")
minetest.ban_player(first)
else
for _, player_name in pairs(players) do
if (player_doesnt_move[player_name] or 0) > 90/step_seconds then
minetest.kick_player(player_name, "Didn't move during 1.5 minutes being connected multiple times")
ban_next_time[ip] = 1
end
end
end
elseif #players <= 100 then
if should_be_banned then
minetest.ban_player(first)
minetest.chat_send_all("Player " .. first .. " has been banned for having more than 25 connections at once")
else
for _, player_name in pairs(players) do
minetest.kick_player(player_name, "More than 25 connections from IP address " .. ip)
end
ban_next_time[ip] = 1
end
else
minetest.ban_player(first)
minetest.chat_send_all("Player " .. first .. " has been banned for having more than 100 connections at once")
end
end
end
after(step_seconds, step) after(step_seconds, step)
end end
@ -203,4 +275,15 @@ minetest.register_on_joinplayer(update_player)
minetest.register_on_leaveplayer(remove_player) minetest.register_on_leaveplayer(remove_player)
minetest.register_on_authplayer(function(name, ip, is_success)
if not is_success then return end
local players = ip_to_players[ip]
if not players then
ip_to_players[ip] = {name}
else
players[#players + 1] = name
end
player_name_to_ip[name] = ip
end)
after(step_seconds, step) after(step_seconds, step)