From 9eef2d13d6cb91e46e6b7d674f43439324f24abb Mon Sep 17 00:00:00 2001 From: Brettflan Date: Thu, 2 Feb 2012 15:13:56 -0600 Subject: [PATCH] Adding TNT exploit workaround fix back; they finally fixed the exploit in CraftBukkit 1.1-RC1, but broke it again in 1.1-RC3. :( --- .../listeners/FactionsBlockListener.java | 8 ++ .../listeners/FactionsEntityListener.java | 81 +++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/src/com/massivecraft/factions/listeners/FactionsBlockListener.java b/src/com/massivecraft/factions/listeners/FactionsBlockListener.java index 3ade74d7..92e95ccb 100644 --- a/src/com/massivecraft/factions/listeners/FactionsBlockListener.java +++ b/src/com/massivecraft/factions/listeners/FactionsBlockListener.java @@ -1,6 +1,7 @@ package com.massivecraft.factions.listeners; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -96,6 +97,13 @@ public class FactionsBlockListener implements Listener { event.setCancelled(true); } + + Material handItem = event.getPlayer().getItemInHand().getType(); + if (handItem == Material.TNT || handItem == Material.REDSTONE_TORCH_ON) + { + Faction targetFaction = Board.getFactionAt(new FLocation(event.getBlock())); + FactionsEntityListener.trackPotentialExplosionExploit(event.getPlayer().getName(), targetFaction, handItem, event.getBlock().getLocation()); + } } @EventHandler(priority = EventPriority.NORMAL) diff --git a/src/com/massivecraft/factions/listeners/FactionsEntityListener.java b/src/com/massivecraft/factions/listeners/FactionsEntityListener.java index 27cb9d41..640d4ce2 100644 --- a/src/com/massivecraft/factions/listeners/FactionsEntityListener.java +++ b/src/com/massivecraft/factions/listeners/FactionsEntityListener.java @@ -1,12 +1,16 @@ package com.massivecraft.factions.listeners; import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.logging.Level; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; +import org.bukkit.entity.TNTPrimed; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -18,6 +22,7 @@ import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.entity.ExplosionPrimeEvent; import org.bukkit.event.painting.PaintingBreakByEntityEvent; import org.bukkit.event.painting.PaintingBreakEvent; import org.bukkit.event.painting.PaintingPlaceEvent; @@ -316,4 +321,80 @@ public class FactionsEntityListener implements Listener event.setCancelled(true); } + + + + /** + * Canceled redstone torch placement next to existing TNT is still triggering an explosion, thus, our workaround here. + * related to this: + * https://bukkit.atlassian.net/browse/BUKKIT-89 + * though they do finally appear to have fixed the converse situation (existing redstone torch, TNT placement attempted but canceled) + */ + private static ArrayList exploitExplosions = new ArrayList(); + + @EventHandler(priority = EventPriority.NORMAL) + public void onExplosionPrime(ExplosionPrimeEvent event) + { + if (event.isCancelled()) return; + if (! (event.getEntity() instanceof TNTPrimed)) return; + if (exploitExplosions.isEmpty()) return; + + // make sure this isn't a TNT explosion exploit attempt + + int locX = event.getEntity().getLocation().getBlockX(); + int locZ = event.getEntity().getLocation().getBlockZ(); + + for (int i = exploitExplosions.size() - 1; i >= 0; i--) + { + PotentialExplosionExploit ex = exploitExplosions.get(i); + + // remove anything from the list older than 8 seconds + if (ex.timeMillis + 8000 < System.currentTimeMillis()) + { + exploitExplosions.remove(i); + continue; + } + + int absX = Math.abs(ex.X - locX); + int absZ = Math.abs(ex.Z - locZ); + if (absX < 5 && absZ < 5) + { // it sure looks like an exploit attempt + // let's tattle on him to everyone + String msg = "NOTICE: Player \""+ex.playerName+"\" attempted to exploit a TNT bug in the territory of \""+ex.faction.getTag()+"\" at "+ex.X+","+ex.Z+" (X,Z) using a "+ex.item.name(); + P.p.log(Level.WARNING, msg); + for (FPlayer fplayer : FPlayers.i.getOnline()) + { + fplayer.sendMessage(msg); + } + event.setCancelled(true); + exploitExplosions.remove(i); + return; + } + } + } + + public static void trackPotentialExplosionExploit(String playerName, Faction faction, Material item, Location location) + { + exploitExplosions.add(new PotentialExplosionExploit(playerName, faction, item, location)); + } + + public static class PotentialExplosionExploit + { + public String playerName; + public Faction faction; + public Material item; + public long timeMillis; + public int X; + public int Z; + + public PotentialExplosionExploit(String playerName, Faction faction, Material item, Location location) + { + this.playerName = playerName; + this.faction = faction; + this.item = item; + this.timeMillis = System.currentTimeMillis(); + this.X = location.getBlockX(); + this.Z = location.getBlockZ(); + } + } }