123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555 |
- if not minetest.global_exists("gdac") then gdac = {} end
- gdac.session_violations = gdac.session_violations or {}
- gdac.modpath = minetest.get_modpath("gdac")
- local vector_distance = vector.distance
- local vector_round = vector.round
- local math_random = math.random
- dofile(gdac.modpath .. "/position_logger.lua")
- dofile(gdac.modpath .. "/anti_servspam.lua")
- dofile(gdac.modpath .. "/autokick.lua")
- function gdac.player_is_admin(playerorname)
- if minetest.is_singleplayer() then
- return false
- end
-
- local pref = playerorname
- if type(pref) == "string" then
- pref = minetest.get_player_by_name(pref)
- end
- if pref then
- return minetest.check_player_privs(pref, {server=true})
- end
- end
- gdac.players = gdac.players or {}
- gdac.cheats_logfile = "cheats.txt"
- gdac.detect_mining_hacks = false
- gdac.block_mining_hacks = false
- gdac.detect_long_range_interact = false
- gdac.detect_fly = false
- gdac.detect_clip = false
- gdac.name_of_admin = "MustTest"
- gdac.interact_range_limit = 6.5
- gdac.fly_timeout_min = 8
- gdac.fly_timeout_max = 32
- gdac.clip_timeout_min = 8
- gdac.clip_timeout_max = 32
- gdac.log = function(message)
- if gdac.logfile then
- gdac.logfile:write(message .. "\r\n")
- gdac.logfile:flush()
- end
- local admin = minetest.get_player_by_name(gdac.name_of_admin)
- if admin and admin:is_player() then
- minetest.chat_send_player(gdac.name_of_admin, "# Server: " .. message)
- end
- end
- gdac.add_session_violation = function(name)
-
- if gdac.session_violations[name] == nil then gdac.session_violations[name] = 0 end
- gdac.session_violations[name] = gdac.session_violations[name] + 1
- end
- local floor = math.floor
- local round = function(num)
- local digits = 1
- local shift = 10 ^ digits
- return floor(num * shift + 0.5 ) / shift
- end
- gdac.check_mined_invisible = function(pos, nodename, digger)
-
- if not digger or not digger:is_player() then return false end
- local pt = {x=pos.x, y=pos.y+1, z=pos.z}
- local pb = {x=pos.x, y=pos.y-1, z=pos.z}
- local p1 = {x=pos.x+1, y=pos.y, z=pos.z}
- local p2 = {x=pos.x-1, y=pos.y, z=pos.z}
- local p3 = {x=pos.x, y=pos.y, z=pos.z+1}
- local p4 = {x=pos.x, y=pos.y, z=pos.z-1}
- if minetest.get_node(pt).name == 'air' or
- minetest.get_node(pb).name == 'air' or
- minetest.get_node(p1).name == 'air' or
- minetest.get_node(p2).name == 'air' or
- minetest.get_node(p3).name == 'air' or
- minetest.get_node(p4).name == 'air' then
- return true
- else
- local nodes = {
- minetest.get_node(pt).name,
- minetest.get_node(pb).name,
- minetest.get_node(p1).name,
- minetest.get_node(p2).name,
- minetest.get_node(p3).name,
- minetest.get_node(p4).name,
- }
-
-
- for k, v in pairs(nodes) do
- local vt = minetest.reg_ns_nodes[v]
- if not vt then
-
- return true
- end
- if vt then
- if not vt.walkable or vt.climbable then
- return true
- end
- if vt.drawtype and vt.drawtype ~= "normal" then
- return true
- end
- end
- end
-
- local pname = digger:get_player_name()
- gdac.add_session_violation(pname)
- gdac.log("Almost certainly a cheater: <" .. pname ..
- "> dug '" .. nodename .. "' at (" .. pos.x .. "," .. pos.y .. "," .. pos.z ..
- "), which was NOT EXPOSED. SV: " ..
- gdac.session_violations[pname] .. ".")
- return false
- end
- end
- local check_fly = function(pos)
- if minetest.get_node(vector.add(pos, {x=0, y=-1, z=0})).name ~= "air" then
- return false
- end
-
-
-
-
- local minp = {x=pos.x-1, y=pos.y-2, z=pos.z-1}
- local maxp = {x=pos.x+1, y=pos.y+0, z=pos.z+1}
- local tb = minetest.find_nodes_in_area(minp, maxp, "air")
- if #tb >= 27 then
-
- return true
- end
- return false
- end
- local check_fly_again
- check_fly_again = function(name, old_pos)
- local player = minetest.get_player_by_name(name)
- if player and player:is_player() then
- if player:get_hp() <= 0 then return end
- local new_pos = player:get_pos()
- local still_cheating = check_fly(new_pos)
- if still_cheating == true then
- local y1 = new_pos.y
- local y2 = old_pos.y
- local d = y2 - y1
- if d < 0.1 then
-
- if vector_distance(new_pos, old_pos) > 0.5 then
- gdac.add_session_violation(name)
- gdac.log("Possible flier? <" .. name ..
- "> caught flying at " .. minetest.pos_to_string(vector_round(new_pos)) .. ". SV: " ..
- gdac.session_violations[name] .. ".")
- end
-
- minetest.after(1, check_fly_again, name, new_pos)
- end
- end
- end
- end
- gdac.antifly_globalstep = function(dtime)
- local players = minetest.get_connected_players()
- for k, v in ipairs(players) do
- if not minetest.check_player_privs(v, {fly=true}) and
- v:get_hp() > 0 then
- local name = v:get_player_name()
- local data = gdac.players[name]
- assert(data ~= nil)
- local check = false
- local cheat = false
-
- local flytimer = data.flytimer
- local flytimeout = data.flytimeout
- flytimer = flytimer + dtime
- if flytimer > flytimeout then
- flytimer = 0
-
- flytimeout = math_random(gdac.fly_timeout_min, gdac.fly_timeout_max)
- check = true
- end
- data.flytimer = flytimer
- data.flytimeout = flytimeout
-
- if check == true then
- cheat = check_fly(v:get_pos())
- end
- if cheat == true then
-
- minetest.after(1, check_fly_again, name, v:get_pos())
- end
- end
- end
- end
- local check_drawtype = function(drawtype)
- if drawtype == "normal" then
- return true
- elseif drawtype == "glasslike" then
- return true
- elseif drawtype == "glasslike_framed" then
- return true
- elseif drawtype == "glasslike_framed_optional" then
- return true
- elseif drawtype == "allfaces" then
- return true
- elseif drawtype == "allfaces_optional" then
- return true
- end
- end
- local check_clip = function(pos)
- local p = vector_round(pos)
- local p1 = {x=p.x, y=p.y, z=p.z}
- local p2 = {x=p.x, y=p.y+1, z=p.z}
- local n1 = minetest.get_node(p1).name
- local n2 = minetest.get_node(p2).name
- if n1 ~= "air" and n2 ~= "air" then
- local d1 = minetest.registered_nodes[n1]
- local d2 = minetest.registered_nodes[n2]
- local b1 = (d1.walkable == true and check_drawtype(d1.drawtype))
- local b2 = (d2.walkable == true and check_drawtype(d2.drawtype))
- if b1 and b2 then
- return true
- end
- end
- return false
- end
- local check_clip_again
- check_clip_again = function(name, old_pos)
- local player = minetest.get_player_by_name(name)
- if player and player:is_player() then
- if player:get_hp() <= 0 then return end
- local new_pos = player:get_pos()
- local still_cheating = check_clip(new_pos)
- if still_cheating == true then
-
- if vector_distance(new_pos, old_pos) > 0.5 then
- gdac.add_session_violation(name)
- gdac.log("Possible noclipper? <" .. name ..
- "> caught inside \"" .. minetest.get_node(new_pos).name .. "\" at " .. minetest.pos_to_string(vector_round(new_pos)) .. ". SV: " ..
- gdac.session_violations[name] .. ".")
- end
-
- minetest.after(1, check_clip_again, name, new_pos)
- end
- end
- end
- gdac.anticlip_globalstep = function(dtime)
- local players = minetest.get_connected_players()
- for k, v in ipairs(players) do
- if not minetest.check_player_privs(v, {noclip=true}) and
- v:get_hp() > 0 then
- local name = v:get_player_name()
- local data = gdac.players[name]
- assert(data ~= nil)
- local check = false
- local cheat = false
-
- local cliptimer = data.cliptimer
- local cliptimeout = data.cliptimeout
- cliptimer = cliptimer + dtime
- if cliptimer > cliptimeout then
- cliptimer = 0
-
- cliptimeout = math_random(gdac.clip_timeout_min, gdac.clip_timeout_max)
- check = true
- end
- data.cliptimer = cliptimer
- data.cliptimeout = cliptimeout
-
- if check == true then
- cheat = check_clip(v:get_pos())
- end
- if cheat == true then
-
- minetest.after(1, check_clip_again, name, v:get_pos())
- end
- end
- end
- end
- gdac.check_long_range_interact = function(pos, node, digger, strpart)
- local ppos = digger:get_pos()
- local d = vector_distance(pos, ppos)
- if d > gdac.interact_range_limit then
- local pname = digger:get_player_name()
- local nodename = node.name
- gdac.add_session_violation(pname)
- gdac.log("Possible cheater? <" .. pname ..
- "> " .. strpart .. " '" .. nodename .. "' at " .. minetest.pos_to_string(vector_round(pos)) ..
- "; TOO FAR from player at " .. minetest.pos_to_string(vector_round(ppos)) ..
- ". D: " .. round(d) .. ". SV: " ..
- gdac.session_violations[pname] .. ".")
- end
- end
- if not gdac.registered then
-
- do
- local path = minetest.get_worldpath() .. "/" .. gdac.cheats_logfile
- gdac.logfile = io.open(path, "a+")
- minetest.register_on_shutdown(function()
- if gdac.logfile then
- gdac.logfile:flush()
- gdac.logfile:close()
- end
- end)
- end
- if gdac.detect_mining_hacks then
-
- local register_mining_hack = function(nodename)
- if gdac.block_mining_hacks then
-
- local def = minetest.registered_items[nodename]
- local old_can_dig = def.can_dig
- minetest.override_item(nodename, {
- can_dig = function(pos, digger)
- if old_can_dig then
- old_can_dig(pos, digger)
- end
- return gdac.check_mined_invisible(pos, nodename, digger)
- end,
- })
- else
-
- local def = minetest.registered_items[nodename]
- local old_after_dig_node = def.after_dig_node
- minetest.override_item(nodename, {
- after_dig_node = function(pos, oldnode, oldmeta, digger)
- if old_after_dig_node then
- old_after_dig_node(pos, oldnode, oldmeta, digger)
- end
- return gdac.check_mined_invisible(pos, nodename, digger)
- end,
- })
- end
- end
- if minetest.get_modpath("default") then
- register_mining_hack("default:stone_with_coal")
- register_mining_hack("default:stone_with_mese")
- register_mining_hack("default:stone_with_iron")
- register_mining_hack("default:stone_with_copper")
- register_mining_hack("default:stone_with_gold")
- register_mining_hack("default:mese")
- end
- if minetest.get_modpath("moreores") then
- register_mining_hack("moreores:mineral_mithril")
- register_mining_hack("moreores:mineral_tin")
- register_mining_hack("moreores:mineral_silver")
- end
- if minetest.get_modpath("morerocks") then
- register_mining_hack("morerocks:marble")
- register_mining_hack("morerocks:granite")
- register_mining_hack("morerocks:marble_pink")
- register_mining_hack("morerocks:marble_white")
- register_mining_hack("morerocks:serpentine")
- end
- if minetest.get_modpath("quartz") then
- register_mining_hack("quartz:quartz_ore")
- end
- register_mining_hack("chromium:ore")
- register_mining_hack("zinc:ore")
- register_mining_hack("sulfur:ore")
- register_mining_hack("uranium:ore")
- register_mining_hack("kalite:ore")
- register_mining_hack("akalin:ore")
- register_mining_hack("alatro:ore")
- register_mining_hack("arol:ore")
- register_mining_hack("talinite:ore")
- end
-
- local random = math_random
- minetest.register_on_dignode(function(pos, oldnode, digger)
- if not digger or not digger:is_player() then return end
-
-
-
-
-
- instability.check_unsupported_around(pos)
-
- if random(1, 5) == 1 then
- ambiance.particles_on_dig(pos, oldnode)
- end
- end)
- local function node_not_walkable(pos)
- local nn = minetest.get_node(pos).name
- if nn == "air" then return true end
- local def = minetest.registered_nodes[nn]
- if def and not def.walkable then return true end
- end
- minetest.register_on_placenode(function(pos, newnode, digger)
- if not digger or not digger:is_player() then return end
-
-
-
-
- local dropped = false
- local control = digger:get_player_control()
- if control.aux1 and node_not_walkable({x=pos.x, y=pos.y-1, z=pos.z}) then
- local ndef = minetest.registered_nodes[newnode.name]
- local groups = ndef.groups or {}
-
- if ndef.paramtype2 ~= "wallmounted" and (groups.attached_node or 0) == 0 and (groups.hanging_node or 0) == 0 then
- if sfn.drop_node(pos) then
- dropped = true
- end
- end
- end
- if not dropped then
- instability.check_tower(pos, newnode, digger)
- instability.check_single_node(pos)
-
- instability.check_unsupported_single(pos)
- end
- if random(1, 5) == 1 then
- ambiance.particles_on_place(pos, newnode)
- end
- end)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- minetest.register_on_joinplayer(function(player)
- if gdac.player_is_admin(player) then
- gdac_invis.toggle_invisibility(player:get_player_name(), "")
- end
- end)
-
- local name = "gdac:core"
- local file = gdac.modpath .. "/init.lua"
- reload.register_file(name, file, false)
- gdac.registered = true
- end
|