forked from MineClone5/MineClone5
#140 Fix anticheat (add settings)
This commit is contained in:
parent
03590d3730
commit
effe1a7ac5
|
@ -1,5 +1,6 @@
|
||||||
local flights_kick_threshold = 10
|
local enable_anticheat = true
|
||||||
local suffocations_kick_threshold = 1
|
local kick_cheaters = false
|
||||||
|
local kick_threshold = 10
|
||||||
|
|
||||||
local after = minetest.after
|
local after = minetest.after
|
||||||
local get_connected_players = minetest.get_connected_players
|
local get_connected_players = minetest.get_connected_players
|
||||||
|
@ -8,24 +9,34 @@ local get_objects_inside_radius = minetest.get_objects_inside_radius
|
||||||
local get_player_by_name = minetest.get_player_by_name
|
local get_player_by_name = minetest.get_player_by_name
|
||||||
local kick_player = minetest.kick_player
|
local kick_player = minetest.kick_player
|
||||||
local set_node = minetest.set_node
|
local set_node = minetest.set_node
|
||||||
|
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 distance = vector.distance
|
local distance = vector.distance
|
||||||
|
|
||||||
local window_size = 10
|
local window_size = 8
|
||||||
local detection_interval = 1.7
|
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 function update_settings()
|
||||||
|
enable_anticheat = minetest.settings:get_bool("enable_anticheat", true)
|
||||||
|
kick_cheaters = minetest.settings:get_bool("kick_cheaters", false)
|
||||||
|
kick_threshold = tonumber(minetest.settings:get("kick_threshold") or 10)
|
||||||
|
minetest.after(10, update_settings)
|
||||||
|
end
|
||||||
|
update_settings()
|
||||||
|
|
||||||
local function update_player(player_object)
|
local function update_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 pos = player_object:get_pos()
|
local pos = player_object:get_pos()
|
||||||
local x, y, z = floor(pos.x), floor(pos.y-0.1), floor(pos.z)
|
local x, z = floor(pos.x), floor(pos.z)
|
||||||
|
local feet_y, head_y = floor(pos.y-0.1), floor(pos.y + 1.49)
|
||||||
|
|
||||||
if mcl_playerplus.elytra then
|
if mcl_playerplus.elytra then
|
||||||
local elytra = mcl_playerplus.elytra[player_object]
|
local elytra = mcl_playerplus.elytra[player_object]
|
||||||
|
@ -34,19 +45,16 @@ local function update_player(player_object)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local air = get_node({x = x , y = y , z = z }).name == "air"
|
local air = #find_nodes_in_area({x = x, y = feet_y, z = z}, {x = x + 1, y = feet_y + 1, z = z + 1}, "air") == 8
|
||||||
and get_node({x = x , y = y , z = z + 1}).name == "air"
|
and #get_objects_inside_radius({x = pos.x, y = pos.y - 0.6, z = pos.z}, 1.3) > 1
|
||||||
and get_node({x = x , y = y + 1, z = z }).name == "air"
|
|
||||||
and get_node({x = x , y = y + 1, z = z + 1}).name == "air"
|
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
|
||||||
and get_node({x = x + 1, y = y , z = z }).name == "air"
|
|
||||||
and get_node({x = x + 1, y = y , z = z + 1}).name == "air"
|
|
||||||
and get_node({x = x + 1, y = y + 1, z = z }).name == "air"
|
|
||||||
and get_node({x = x + 1, y = y + 1, z = z + 1}).name == "air"
|
|
||||||
|
|
||||||
local player_data = {
|
local player_data = {
|
||||||
pos = pos,
|
pos = pos,
|
||||||
velocity = player_object:get_velocity(),
|
velocity = player_object:get_velocity(),
|
||||||
air = air
|
air = air,
|
||||||
|
noclip = noclip,
|
||||||
}
|
}
|
||||||
|
|
||||||
if joined_players[name] then
|
if joined_players[name] then
|
||||||
|
@ -68,6 +76,7 @@ local function check_player(name)
|
||||||
if not data[0] then return end
|
if not data[0] then return end
|
||||||
|
|
||||||
local always_air = true
|
local always_air = true
|
||||||
|
local always_noclip = true
|
||||||
local falling = data[0].velocity.y < 0
|
local falling = data[0].velocity.y < 0
|
||||||
for i = 0, window_size - 1 do
|
for i = 0, window_size - 1 do
|
||||||
local derivative = data[i]
|
local derivative = data[i]
|
||||||
|
@ -76,6 +85,7 @@ local function check_player(name)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
always_air = always_air and derivative.air
|
always_air = always_air and derivative.air
|
||||||
|
always_noclip = always_noclip and derivative.noclip
|
||||||
falling = falling or derivative.velocity.y < 0
|
falling = falling or derivative.velocity.y < 0
|
||||||
end
|
end
|
||||||
if always_air and not falling then
|
if always_air and not falling then
|
||||||
|
@ -84,26 +94,39 @@ local function check_player(name)
|
||||||
data.flights = 1
|
data.flights = 1
|
||||||
else
|
else
|
||||||
data.flights = data.flights + 1
|
data.flights = data.flights + 1
|
||||||
if data.flights >= flights_kick_threshold then
|
end
|
||||||
kick_player(name, "flights")
|
if kick_cheaters and kick_threshold and kick_threshold > 0 and data.flights >= kick_threshold then
|
||||||
end
|
kick_player(name, "flights")
|
||||||
|
return
|
||||||
end
|
end
|
||||||
local obj_player = minetest.get_player_by_name(name)
|
local obj_player = minetest.get_player_by_name(name)
|
||||||
if not obj_player then
|
if not obj_player then
|
||||||
kick_player(name, "flights")
|
return
|
||||||
end
|
end
|
||||||
local velocity = obj_player:get_velocity()
|
local velocity = obj_player:get_velocity()
|
||||||
local pos = obj_player:get_pos()
|
local pos = obj_player:get_pos()
|
||||||
local x, y, z = floor(pos.x), floor(pos.y), floor(pos.z)
|
local x, y, z = floor(pos.x), floor(pos.y), floor(pos.z)
|
||||||
while ( get_node({x = x , y = y, z = z }).name == "air"
|
while #find_nodes_in_area({x = x, y = y, z = z}, {x = x + 1, y = y, z = z + 1}, "air") == 4 do
|
||||||
and get_node({x = x , y = y, z = z + 1}).name == "air"
|
|
||||||
and get_node({x = x + 1, y = y, z = z }).name == "air"
|
|
||||||
and get_node({x = x + 1, y = y, z = z + 1}).name == "air"
|
|
||||||
) do
|
|
||||||
y = y - 1
|
y = y - 1
|
||||||
end
|
end
|
||||||
obj_player:set_velocity({x = velocity.x, y = -10, z = velocity.z})
|
|
||||||
obj_player:set_pos({x = x, y = y + 0.5, z = z})
|
obj_player:set_pos({x = x, y = y + 0.5, z = z})
|
||||||
|
obj_player:set_velocity({x = 0, y = 0, z = 0})
|
||||||
|
obj_player:set_acceleration({x = 0, y = 0, z = 0})
|
||||||
|
end
|
||||||
|
if always_noclip then
|
||||||
|
-- noclip detected
|
||||||
|
local obj_player = minetest.get_player_by_name(name)
|
||||||
|
if not obj_player then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local pos = obj_player:get_pos()
|
||||||
|
local x, y, z = floor(pos.x), floor(pos.y+1.49), floor(pos.z)
|
||||||
|
while #find_nodes_in_area({x = x, y = y, z = z}, {x = x + 1, y = y, z = z + 1}, "group:opaque") == 8 do
|
||||||
|
y = y + 1
|
||||||
|
end
|
||||||
|
obj_player:set_pos({x = x, y = y, z = z})
|
||||||
|
obj_player:set_velocity({x = 0, y = 0, z = 0})
|
||||||
|
obj_player:set_acceleration({x = 0, y = 0, z = 0})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -117,9 +140,11 @@ local function remove_player(player_object)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function step()
|
local function step()
|
||||||
for _, player in pairs(get_connected_players()) do
|
if enable_anticheat then
|
||||||
update_player(player)
|
for _, player in pairs(get_connected_players()) do
|
||||||
check_player(player:get_player_name())
|
update_player(player)
|
||||||
|
check_player(player:get_player_name())
|
||||||
|
end
|
||||||
end
|
end
|
||||||
after(step_seconds, step)
|
after(step_seconds, step)
|
||||||
end
|
end
|
||||||
|
@ -161,7 +186,7 @@ minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack
|
||||||
data.suffocations = data.suffocations + 1
|
data.suffocations = data.suffocations + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if data.suffocations >= suffocations_kick_threshold then
|
if data.suffocations >= kick_threshold then
|
||||||
kick_player(name, "choker")
|
kick_player(name, "choker")
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -157,6 +157,14 @@ fix_doubleplants (Mcimport double plant fixes) bool true
|
||||||
# Allow players to create Minecraft-like maps.
|
# Allow players to create Minecraft-like maps.
|
||||||
enable_real_maps (Enable Real Maps) bool true
|
enable_real_maps (Enable Real Maps) bool true
|
||||||
|
|
||||||
|
[Anticheat]
|
||||||
|
# Enable anticheats
|
||||||
|
enable_anticheat (Enable Anticheat) bool true
|
||||||
|
# Kick cheaters
|
||||||
|
kick_cheaters (Kick Cheaters) bool false
|
||||||
|
# Cheat kicking threshold
|
||||||
|
kick_threshold (Cheat Kicking Threshold) int 10
|
||||||
|
|
||||||
[Debugging]
|
[Debugging]
|
||||||
# If enabled, this will show the itemstring of an item in the description.
|
# If enabled, this will show the itemstring of an item in the description.
|
||||||
mcl_item_id_debug (Item ID Debug) bool false
|
mcl_item_id_debug (Item ID Debug) bool false
|
Loading…
Reference in New Issue