diff --git a/src/com/massivecraft/factions/Conf.java b/src/com/massivecraft/factions/Conf.java index 0e67bfa7..b1c8a6bf 100644 --- a/src/com/massivecraft/factions/Conf.java +++ b/src/com/massivecraft/factions/Conf.java @@ -105,6 +105,7 @@ public class Conf // prevent some potential exploits public static boolean handleExploitObsidianGenerators = true; public static boolean handleExploitEnderPearlClipping = true; + public static boolean handleExploitInteractionSpam = true; public static boolean homesEnabled = true; public static boolean homesMustBeInClaimedTerritory = true; diff --git a/src/com/massivecraft/factions/listeners/FactionsPlayerListener.java b/src/com/massivecraft/factions/listeners/FactionsPlayerListener.java index acc64ae3..4b10c03a 100644 --- a/src/com/massivecraft/factions/listeners/FactionsPlayerListener.java +++ b/src/com/massivecraft/factions/listeners/FactionsPlayerListener.java @@ -1,11 +1,12 @@ package com.massivecraft.factions.listeners; +import java.util.HashMap; import java.util.Iterator; +import java.util.Map; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -20,6 +21,7 @@ import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerPreLoginEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.util.NumberConversions; import com.massivecraft.factions.Board; import com.massivecraft.factions.Conf; @@ -129,6 +131,23 @@ public class FactionsPlayerListener implements Listener if ( ! canPlayerUseBlock(player, block, false)) { event.setCancelled(true); + if (Conf.handleExploitInteractionSpam) + { + String name = player.getName(); + InteractAttemptSpam attempt = interactSpammers.get(name); + if (attempt == null) + { + attempt = new InteractAttemptSpam(); + interactSpammers.put(name, attempt); + } + int count = attempt.increment(); + if (count >= 10) + { + FPlayer me = FPlayers.i.get(name); + me.msg("Ouch, that is starting to hurt. You should give it a rest."); + player.damage(NumberConversions.floor((double)count / 10)); + } + } return; } @@ -137,25 +156,6 @@ public class FactionsPlayerListener implements Listener return; // only interested on right-clicks for below } - // workaround fix for new CraftBukkit 1.1-R1 bug where half-step on half-step placement doesn't trigger BlockPlaceEvent - if ( - event.hasItem() - && - event.getItem().getType() == Material.STEP - && - block.getType() == Material.STEP - && - event.getBlockFace() == BlockFace.UP - && - event.getItem().getData().getData() == block.getData() - && - ! FactionsBlockListener.playerCanBuildDestroyBlock(player, block, "build", false) - ) - { - event.setCancelled(true); - return; - } - if ( ! playerCanUseItemHere(player, block.getLocation(), event.getMaterial(), false)) { event.setCancelled(true); @@ -163,6 +163,28 @@ public class FactionsPlayerListener implements Listener } } + + // for handling people who repeatedly spam attempts to open a door (or similar) in another faction's territory + private Map interactSpammers = new HashMap(); + private static class InteractAttemptSpam + { + private int attempts = 0; + private long lastAttempt = System.currentTimeMillis(); + + // returns the current attempt count + public int increment() + { + long Now = System.currentTimeMillis(); + if (Now > lastAttempt + 2000) + attempts = 1; + else + attempts++; + lastAttempt = Now; + return attempts; + } + } + + // TODO: Refactor ! justCheck -> to informIfNot // TODO: Possibly incorporate pain build... public static boolean playerCanUseItemHere(Player player, Location loc, Material material, boolean justCheck)