forked from MineClone5/MineClone5
Remove too idle players
This commit is contained in:
parent
869154f86d
commit
1e8f5ffc74
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue