commit 0348b4084dc3598f5b4ecc1c67a4a87eb01ddd92 Author: Beha Date: Sun Dec 6 18:11:38 2015 -0500 Initial Commit diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/depends.txt @@ -0,0 +1 @@ + diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..c966a55 --- /dev/null +++ b/init.lua @@ -0,0 +1,83 @@ +--Protection Lag Teleporter + +local check_speed = 0.2 --Teleport this quickly. +local check_time = 3 --Test this many times before finishing. + +protection_lagporter = {} +protection_lagporter.glitching = {} --Check if a player is being teleported with: if protection_lagporter.glitching[playername] then ... end + +local togo = {} --Target locations. +local times = {} --Test times. + +local function check_togo(name) + local player = minetest.get_player_by_name(name) + if player then + if togo[name] then + local p1 = player:getpos() + local p2 = togo[name] + --Calculate offset from y-axis velocity. + local ytest = math.max(math.min(math.abs(player:get_player_velocity().y), 1), 0.1) + --Is the player where he should be? + if math.abs(p1.x - p2.x) <= 0.1 and math.abs(p1.y - p2.y) <= ytest and math.abs(p1.z - p2.z) <= 0.1 then + times[name] = times[name] - 1 + end + --Yes, he is. + if times[name] <= 0 then + togo[name] = nil + times[name] = nil + protection_lagporter.glitching[name] = nil + return + end + --Teleport and retry. + player:setpos(togo[name]) + minetest.after(check_speed, check_togo, name) + end + end +end + +function protection_lagporter.check(pos, digger) + local player = minetest.get_player_by_name(digger) + if player then + if not togo[digger] then + --Target where the player was before. + togo[digger] = player:getpos() + protection_lagporter.glitching[digger] = true + end + if not times[digger] then + --Begin checks. + minetest.after(check_speed, check_togo, digger) + end + times[digger] = check_time + end +end + +minetest.register_on_leaveplayer(function(player) + --Ensure the player isn't still teleporting when he returns. + togo[player:get_player_name()] = nil + times[player:get_player_name()] = nil + protection_lagporter.glitching[player:get_player_name()] = nil +end) + +--Override node_dig to use + +local old_node_dig = minetest.node_dig + +function minetest.node_dig(pos, node, digger) + local def = ItemStack({name=node.name}):get_definition() + --Check if diggable, then check if is protected. + if not def.diggable or (def.can_dig and not def.can_dig(pos,digger)) then + --Cannot dig, but old_node_dig will handle this. + elseif minetest.is_protected(pos, digger:get_player_name(), def.walkable) then + minetest.log("action", digger:get_player_name() + .. " tried to dig " .. node.name + .. " at protected position " + .. minetest.pos_to_string(pos)) + minetest.record_protection_violation(pos, digger:get_player_name()) + return + end + + --Leave the rest to the proper function. + return old_node_dig(pos, node, digger) +end + +print("[MOD] protection_lagporter loaded") diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..5cf3b1e --- /dev/null +++ b/license.txt @@ -0,0 +1,22 @@ +Copyright (c) 2015 Beha + + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..4358b05 --- /dev/null +++ b/readme.md @@ -0,0 +1,36 @@ +This mod will teleport players back to where they started digging if they try to dig through protection. + +### Known Problems + +* It cannot handle very long lag. +* Occasionally players who try very hard to break through protection while in the air will jump up and down rapidly. This won't last very long though. + +### minetest.is_protected + +This mod overrides `minetest.node_dig` and calls a third argument in `minetest.is_protected`: `digger` +This argument can be safely ignored, so existing mods aren't broken by this. + +### Usage in other mods + +In a protection mod change the definition of minetest.is_protected and call `protection_lagporter.check(pos, name)` to support the digger option. + +A table of players being teleported is available with `protection_lagporter.glitching`, player names will either be `nil` if not teleporting or `true` if they are. +#### TenPlus1's Protection Redo + function minetest.is_protected(pos, digger, digging) + if not protector.can_dig(protector.radius, pos, digger, false, 1) then + if digging then protection_lagporter.check(pos, digger) end + return true + end + return protector.old_is_protected(pos, digger, digging) + end +#### ShadowNinja's Areas + function minetest.is_protected(pos, name, digging) + if not areas:canInteract(pos, name) then + if digging then protection_lagporter.check(pos, name) end + return true + end + return old_is_protected(pos, name, digging) + end + +#### Node Definitions +In node definitions you should use the digger argument, `minetest.is_protected(pos, name, digger)`, if you test for protection in `on_dig`. This is only needed if the node is walkable.