updated mod list
parent
8fd5ef65d9
commit
daef308f8c
178
init.lua
178
init.lua
|
@ -46,19 +46,19 @@ cheat.nodelist = {["default:stone"] = false, ["default:cobble"]= false, ["defaul
|
|||
|
||||
|
||||
local punish_cheat = function(name)
|
||||
|
||||
local player = minetest.get_player_by_name(name);
|
||||
|
||||
local player = minetest.get_player_by_name(name);
|
||||
local ip = tostring(minetest.get_player_ip(name));
|
||||
|
||||
|
||||
if not player then return end
|
||||
local text=""; local logtext = "";
|
||||
|
||||
|
||||
if cheat.players[name].cheattype == 1 then
|
||||
text = "#anticheat: ".. name .. " was caught walking inside wall";
|
||||
logtext = os.date("%H:%M.%S").." #anticheat: ".. name .. " was caught walking inside wall at " .. minetest.pos_to_string(cheat.players[name].cheatpos);
|
||||
player:set_hp(0);
|
||||
elseif cheat.players[name].cheattype == 2 then
|
||||
|
||||
|
||||
local gravity = player:get_physics_override().gravity; if gravity<1 then return end
|
||||
logtext= os.date("%H:%M.%S").." #anticheat: ".. name .. " was caught flying at " .. minetest.pos_to_string(cheat.players[name].cheatpos);
|
||||
if cheat.players[name].cheatpos.y>5 then -- only above height 5 it directly damages flyer
|
||||
|
@ -66,20 +66,20 @@ local punish_cheat = function(name)
|
|||
--player:set_hp(0);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if text~="" then
|
||||
minetest.chat_send_all(text);
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if logtext~="" then
|
||||
minetest.log("action", logtext);
|
||||
cheat.message = logtext;
|
||||
|
||||
|
||||
anticheatdb[ip] = {name = name, msg = logtext};
|
||||
|
||||
cheat.players[name].count=0; -- reset counter
|
||||
cheat.players[name].cheattype = 0;
|
||||
|
||||
|
||||
for name,_ in pairs(cheat.moderators) do -- display full message to moderators
|
||||
minetest.chat_send_player(name,logtext);
|
||||
end
|
||||
|
@ -90,14 +90,14 @@ end
|
|||
|
||||
|
||||
-- DETAILED NOCLIP CHECK
|
||||
local check_noclip = function(pos)
|
||||
local check_noclip = function(pos)
|
||||
local nodename = minetest.get_node(pos).name;
|
||||
local clear=true;
|
||||
if nodename ~= "air" then -- check if forbidden material!
|
||||
clear = cheat.nodelist[nodename]; -- test clip violation
|
||||
if clear == nil then clear = true end
|
||||
end
|
||||
|
||||
|
||||
if not clear then -- more detailed check
|
||||
local anodes = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+1, z=pos.z+1}, {"air"});
|
||||
if #anodes == 0 then return false end
|
||||
|
@ -110,21 +110,21 @@ end
|
|||
local check_fly = function(pos) -- return true if player not flying
|
||||
local fly = (minetest.get_node(pos).name=="air" and minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}).name=="air"); -- prerequisite for flying is this to be "air", but not sufficient condition
|
||||
if not fly then return true end;
|
||||
|
||||
|
||||
local anodes = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y, z=pos.z+1}, {"air"});
|
||||
if #anodes == 18 then -- player standing on air?
|
||||
return false
|
||||
else
|
||||
return true
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local round = function (x)
|
||||
if x > 0 then
|
||||
return math.floor(x+0.5)
|
||||
if x > 0 then
|
||||
return math.floor(x+0.5)
|
||||
else
|
||||
return -math.floor(-x+0.5)
|
||||
return -math.floor(-x+0.5)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -134,33 +134,33 @@ local check_player = function(player)
|
|||
local name = player:get_player_name();
|
||||
local privs = minetest.get_player_privs(name).kick;if privs then return end -- dont check moderators
|
||||
if cheat.watcher[name] then return end -- skip checking watchers while they watch
|
||||
|
||||
|
||||
local pos = player:getpos(); -- feet position
|
||||
pos.x = round(pos.x*10)/10;pos.z = round(pos.z*10)/10; -- less useless clutter
|
||||
pos.y = round(pos.y*10)/10; -- minetest buggy collision - need to do this or it returns wrong materials for feet position: aka magic number 0.498?????228
|
||||
if pos.y<0 then pos.y=pos.y+1 end -- weird, without this it fails to check feet block where y<0, it checks one below feet
|
||||
|
||||
|
||||
local nodename = minetest.get_node(pos).name;
|
||||
local clear=true;
|
||||
if nodename ~= "air" then -- check if forbidden material!
|
||||
clear = cheat.nodelist[nodename]; -- test clip violation
|
||||
if clear == nil then clear = true end
|
||||
end
|
||||
|
||||
|
||||
local fly = (nodename=="air" and minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}).name=="air"); -- prerequisite for flying, but not sufficient condition
|
||||
|
||||
if cheat.players[name].count == 0 then -- player hasnt "cheated" yet, remember last clear position
|
||||
cheat.players[name].clearpos = cheat.players[name].lastpos
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- manage noclip cheats
|
||||
if not clear then -- player caught inside walls
|
||||
local moved = (cheat.players[name].lastpos.x~=pos.x) or (cheat.players[name].lastpos.y~=pos.y) or (cheat.players[name].lastpos.z~=pos.z);
|
||||
if moved then -- if player stands still whole time do nothing
|
||||
if cheat.players[name].count == 0 then cheat.players[name].cheatpos = pos end -- remember first position where player found inside wall
|
||||
|
||||
|
||||
|
||||
|
||||
if cheat.players[name].count == 0 then
|
||||
minetest.after(CHECK_AGAIN+math.random(5),
|
||||
function()
|
||||
|
@ -174,40 +174,40 @@ local check_player = function(player)
|
|||
end
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
if cheat.players[name].count == 0 then -- mark as suspect
|
||||
cheat.players[name].count = 1;
|
||||
cheat.players[name].count = 1;
|
||||
cheat.players[name].cheattype = 1;
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- manage flyers
|
||||
if fly then
|
||||
|
||||
local fpos;
|
||||
fly,fpos = minetest.line_of_sight(pos, {x = pos.x, y = pos.y - 4, z = pos.z}, 1); --checking node maximal jump height below feet
|
||||
|
||||
|
||||
if fly then -- so we are in air, are we flying?
|
||||
|
||||
|
||||
if player:get_player_control().sneak then -- player sneaks, maybe on border?
|
||||
--search 18 nodes to find non air
|
||||
local anodes = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y, z=pos.z+1}, {"air"});
|
||||
if #anodes < 18 then fly = false end
|
||||
end -- if at this point fly = true means player is not standing on border
|
||||
|
||||
|
||||
if pos.y>=cheat.players[name].lastpos.y and fly then -- we actually didnt go down from last time and not on border
|
||||
|
||||
-- was lastpos in air too?
|
||||
local lastpos = cheat.players[name].lastpos;
|
||||
local anodes = minetest.find_nodes_in_area({x=lastpos.x-1, y=lastpos.y-1, z=lastpos.z-1}, {x=lastpos.x+1, y=lastpos.y, z=lastpos.z+1}, {"air"});
|
||||
if #anodes == 18 then fly = true else fly = false end
|
||||
|
||||
|
||||
if fly then -- so now in air above previous position, which was in air too?
|
||||
|
||||
|
||||
if cheat.players[name].count == 0 then cheat.players[name].cheatpos = pos end -- remember first position where player found "cheating"
|
||||
|
||||
|
||||
if cheat.players[name].count == 0 then
|
||||
minetest.after(CHECK_AGAIN,
|
||||
function()
|
||||
|
@ -215,38 +215,38 @@ local check_player = function(player)
|
|||
if not check_fly(pos) then
|
||||
punish_cheat(name)-- we got a cheater!
|
||||
else
|
||||
cheat.players[name].count = 0;
|
||||
cheat.players[name].count = 0;
|
||||
cheat.players[name].cheattype = 0;
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
if cheat.players[name].count == 0 then -- mark as suspect
|
||||
cheat.players[name].count = 1;
|
||||
cheat.players[name].count = 1;
|
||||
cheat.players[name].cheattype = 2;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
cheat.players[name].lastpos = pos
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
|
||||
|
||||
cheat.scan_timer = cheat.scan_timer + dtime
|
||||
local boneworld = false;
|
||||
|
||||
|
||||
-- GENERAL SCAN OF ALL PLAYERS
|
||||
if cheat.scan_timer>cheat.timestep then
|
||||
|
||||
cheat.stat_timer = cheat.stat_timer + cheat.timestep;
|
||||
if cheat.scan_timer>cheat.timestep then
|
||||
|
||||
cheat.stat_timer = cheat.stat_timer + cheat.timestep;
|
||||
-- dig xp stats every 2 minutes
|
||||
if boneworld and cheat.stat_timer>120 then
|
||||
cheat.stat_timer = 0;
|
||||
|
@ -259,33 +259,33 @@ minetest.register_globalstep(function(dtime)
|
|||
cheat.players[pname].stats.digxp = boneworld.digxp[pname];
|
||||
deltadig = boneworld.digxp[pname]-deltadig;
|
||||
cheat.players[pname].stats.deltadig = deltadig;
|
||||
|
||||
|
||||
if deltadig>cheat.players[pname].stats.maxdeltadig then
|
||||
cheat.players[pname].stats.maxdeltadig = deltadig;
|
||||
end
|
||||
|
||||
|
||||
if deltadig>2 then -- unnaturally high deltadig
|
||||
local ip = tostring(minetest.get_player_ip(pname));
|
||||
local logtext = os.date("%H:%M.%S") .. " #anticheat: " .. pname .. " (ip " .. ip .. ") is mining resources too fast, deltadig " .. deltadig;
|
||||
anticheatdb[ip] = {name = pname, msg = logtext};
|
||||
minetest.log("action", logtext);
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
cheat.timestep = CHEAT_TIMESTEP + (2*math.random()-1)*2; -- randomize step so its unpredictable
|
||||
cheat.scan_timer=0;
|
||||
--local t = minetest.get_gametime();
|
||||
local players = minetest.get_connected_players();
|
||||
|
||||
|
||||
for _,player in pairs(players) do
|
||||
check_player(player);
|
||||
end
|
||||
|
||||
|
||||
for name,_ in pairs(cheat.debuglist) do -- show suspects in debug
|
||||
for _,player in pairs(players) do
|
||||
local pname = player:get_player_name();
|
||||
|
@ -294,20 +294,20 @@ minetest.register_globalstep(function(dtime)
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
end
|
||||
end)
|
||||
|
||||
-- long range dig check
|
||||
|
||||
local check_can_dig = function(pos, digger)
|
||||
|
||||
local check_can_dig = function(pos, digger)
|
||||
|
||||
local p = digger:getpos();
|
||||
if p.y<0 then p.y=p.y+2 else p.y=p.y+1 end -- head position
|
||||
local dist = math.max(math.abs(p.x-pos.x),math.abs(p.y-pos.y),math.abs(p.z-pos.z));
|
||||
|
||||
|
||||
|
||||
if dist>6 then -- here 5
|
||||
dist = math.floor(dist*100)/100;
|
||||
local pname = digger:get_player_name();
|
||||
|
@ -320,7 +320,7 @@ local check_can_dig = function(pos, digger)
|
|||
anticheatdb[ip] = {name = pname, msg = logtext};
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
@ -332,8 +332,8 @@ local set_check_can_dig = function(name)
|
|||
--minetest.register_node(":"..name, tabl);
|
||||
end
|
||||
|
||||
minetest.after(0,
|
||||
function()
|
||||
minetest.after(0,
|
||||
function()
|
||||
set_check_can_dig("default:stone");
|
||||
set_check_can_dig("default:stone_with_iron");
|
||||
set_check_can_dig("default:stone_with_copper");
|
||||
|
@ -353,7 +353,7 @@ minetest.after(0,
|
|||
-- minetest.register_on_cheat(
|
||||
-- function(player, c)
|
||||
-- local name = player:get_player_name(); if name == nil then return end
|
||||
-- local stats = cheat.players[name].stats;
|
||||
-- local stats = cheat.players[name].stats;
|
||||
-- if not stats[c.type] then stats[c.type] = 0 end
|
||||
-- stats[c.type]=stats[c.type]+1;
|
||||
-- end
|
||||
|
@ -363,18 +363,18 @@ minetest.after(0,
|
|||
|
||||
local watchers = {}; -- for each player a list of watchers
|
||||
minetest.register_on_joinplayer(function(player) -- init stuff on player join
|
||||
local name = player:get_player_name(); if name == nil then return end
|
||||
local name = player:get_player_name(); if name == nil then return end
|
||||
local pos = player:getpos();
|
||||
|
||||
|
||||
if cheat.players[name] == nil then
|
||||
cheat.players[name]={count=0,cheatpos = pos, clearpos = pos, lastpos = pos, cheattype = 0}; -- type 0: none, 1 noclip, 2 fly
|
||||
end
|
||||
|
||||
|
||||
if cheat.players[name] and cheat.players[name].stats == nil then
|
||||
cheat.players[name].stats = {maxdeltadig=0,deltadig = 0,digxp = 0, state = 0}; -- various statistics about player: max dig xp increase in 2 minutes, current dig xp increase
|
||||
|
||||
|
||||
minetest.after(5, -- load digxp after boneworld loads it
|
||||
function()
|
||||
function()
|
||||
local boneworld = false;
|
||||
if boneworld and boneworld.xp then
|
||||
cheat.players[name].stats.digxp = boneworld.digxp[name] or 0;
|
||||
|
@ -382,38 +382,38 @@ minetest.register_on_joinplayer(function(player) -- init stuff on player join
|
|||
end
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
end
|
||||
--state 0 = stats not loaded yet
|
||||
|
||||
|
||||
|
||||
|
||||
watchers[name] = {}; -- for spectator mod
|
||||
|
||||
|
||||
local ip = tostring(minetest.get_player_ip(name));
|
||||
local msg = "";
|
||||
|
||||
|
||||
-- check anticheat db
|
||||
--check ip
|
||||
if anticheatdb[ip] then
|
||||
if anticheatdb[ip] then
|
||||
msg = "#anticheat: welcome back detected cheater, ip = " .. ip .. ", name " .. anticheatdb[ip].name .. ", new name = " .. name;
|
||||
end;
|
||||
--check names
|
||||
for ip,v in pairs(anticheatdb) do
|
||||
if v.name == name then
|
||||
if v.name == name then
|
||||
msg = "#anticheat: welcome back detected cheater, ip = " .. ip .. ", name = newname = " .. v.name;
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if msg~="" then
|
||||
for name,_ in pairs(cheat.moderators) do
|
||||
for name,_ in pairs(cheat.moderators) do
|
||||
minetest.chat_send_player(name,msg);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end)
|
||||
|
||||
minetest.register_chatcommand("cchk", {
|
||||
minetest.register_chatcommand("cchk", {
|
||||
privs = {
|
||||
interact = true
|
||||
},
|
||||
|
@ -425,9 +425,9 @@ minetest.register_chatcommand("cchk", {
|
|||
local player = minetest.get_player_by_name(param);
|
||||
if not player then return end
|
||||
check_player(player);
|
||||
|
||||
|
||||
local players = minetest.get_connected_players();
|
||||
|
||||
|
||||
local players = minetest.get_connected_players();
|
||||
for name,_ in pairs(cheat.debuglist) do -- show suspects in debug
|
||||
for _,player in pairs(players) do
|
||||
local pname = player:get_player_name();
|
||||
|
@ -436,8 +436,8 @@ minetest.register_chatcommand("cchk", {
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
end
|
||||
})
|
||||
|
||||
|
@ -450,13 +450,13 @@ minetest.register_chatcommand("crep", { -- see cheat report
|
|||
func = function(name, param)
|
||||
local privs = minetest.get_player_privs(name).privs;
|
||||
if not cheat.moderators[name] and not privs then return end
|
||||
|
||||
if param == "" then
|
||||
|
||||
if param == "" then
|
||||
minetest.chat_send_player(name,"use: crep type, types: 0(default) cheat report, 1 connected player stats (".. version ..")");
|
||||
end
|
||||
|
||||
|
||||
param = tonumber(param) or 0;
|
||||
|
||||
|
||||
if param == 0 then -- show cheat report
|
||||
local text = "";
|
||||
for ip,v in pairs(anticheatdb) do
|
||||
|
@ -474,8 +474,8 @@ minetest.register_chatcommand("crep", { -- see cheat report
|
|||
for _,player in pairs(players) do
|
||||
local pname = player:get_player_name();
|
||||
local ip = tostring(minetest.get_player_ip(pname));
|
||||
|
||||
|
||||
|
||||
|
||||
text = text .. "\nname " .. pname .. ", digxp " .. math.floor(1000*cheat.players[pname].stats.digxp)/1000 ..
|
||||
", deltadigxp(2min) " .. math.floor(1000*cheat.players[pname].stats.deltadig)/1000 .. ", maxdeltadigxp " .. math.floor(1000*cheat.players[pname].stats.maxdeltadig)/1000; -- .. " ".. string.gsub(dump(cheat.players[pname].stats), "\n", " ");
|
||||
if anticheatdb[ip] then text = text .. " (DETECTED) ip ".. ip .. ", name " .. anticheatdb[ip].name end
|
||||
|
@ -504,11 +504,11 @@ minetest.register_chatcommand("cdebug", { -- toggle cdebug= display of stats on/
|
|||
func = function(name, param)
|
||||
local privs = minetest.get_player_privs(name).privs;
|
||||
if not cheat.moderators[name] and not privs then return end
|
||||
|
||||
|
||||
if cheat.debuglist[name] == nil then cheat.debuglist[name] = true else cheat.debuglist[name] = nil end;
|
||||
|
||||
|
||||
minetest.chat_send_player(name,"#anticheat: " .. version);
|
||||
if cheat.debuglist[name]==true then
|
||||
if cheat.debuglist[name]==true then
|
||||
minetest.chat_send_player(name,"#anticheat: display of debug messages is ON");
|
||||
else
|
||||
minetest.chat_send_player(name,"#anticheat: display of debug messages is OFF");
|
||||
|
|
12
settings.lua
12
settings.lua
|
@ -24,11 +24,11 @@ anticheatsettings.CHECK_AGAIN = 15; -- after player found in bad position check
|
|||
|
||||
-- moderators list, those players can use cheat debug and will see full cheat message
|
||||
anticheatsettings.moderators = {
|
||||
["SaKeL"]=true,
|
||||
["SaKeL_Player"]=true,
|
||||
["SOUALYMANE"]=true,
|
||||
["ufa"]=true,
|
||||
["rnd"]=true,
|
||||
["MTZ"]=true
|
||||
["SaKeL"] = true,
|
||||
["SaKeL_Player"] = true,
|
||||
["SOUALYMANE"] = true,
|
||||
["ufa"] = true,
|
||||
["rnd"] = true,
|
||||
["JohnnyBravo"] = true
|
||||
}
|
||||
-- END OF SETTINGS --------------------------------------------------------
|
Loading…
Reference in New Issue