From 9534a72d44e66e8d77a9bd6a1b5c9498a8a9ead9 Mon Sep 17 00:00:00 2001 From: Brettflan Date: Tue, 17 Jan 2012 01:57:25 -0600 Subject: [PATCH] improved TNT exploit prevention Now, canceled exploit attempts don't injure players or mobs as if the TNT had successfully exploded, and if it's the case of an existing TNT block which a redstone torch is attempted to be placed next to, it no longer drops a free TNT item. In that case, the existing TNT block is still destroyed itself, but... oh well, it's close enough to perfect. --- src/com/massivecraft/factions/P.java | 1 + .../listeners/FactionsEntityListener.java | 140 +++++++++--------- 2 files changed, 74 insertions(+), 67 deletions(-) diff --git a/src/com/massivecraft/factions/P.java b/src/com/massivecraft/factions/P.java index 552742bc..a92ddb69 100644 --- a/src/com/massivecraft/factions/P.java +++ b/src/com/massivecraft/factions/P.java @@ -127,6 +127,7 @@ public class P extends MPlugin this.registerEvent(Event.Type.ENTITY_TARGET, this.entityListener, Event.Priority.Normal); this.registerEvent(Event.Type.PAINTING_BREAK, this.entityListener, Event.Priority.Normal); this.registerEvent(Event.Type.PAINTING_PLACE, this.entityListener, Event.Priority.Normal); + this.registerEvent(Event.Type.EXPLOSION_PRIME, this.entityListener, Event.Priority.Normal); // Block Events this.registerEvent(Event.Type.BLOCK_BREAK, this.blockListener, Event.Priority.Normal); diff --git a/src/com/massivecraft/factions/listeners/FactionsEntityListener.java b/src/com/massivecraft/factions/listeners/FactionsEntityListener.java index ccb3ad87..ea20ed63 100644 --- a/src/com/massivecraft/factions/listeners/FactionsEntityListener.java +++ b/src/com/massivecraft/factions/listeners/FactionsEntityListener.java @@ -11,6 +11,7 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Fireball; import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; +import org.bukkit.entity.TNTPrimed; import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.EndermanPickupEvent; import org.bukkit.event.entity.EndermanPlaceEvent; @@ -20,6 +21,7 @@ import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.EntityListener; 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; @@ -114,7 +116,48 @@ public class FactionsEntityListener extends EntityListener event.setCancelled(true); } } - + + @Override + 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 10 seconds (TNT takes 4 seconds to trigger; provide some leeway) + if (ex.timeMillis + 10000 < 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 "+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; + } + } + } + @Override public void onEntityExplode(EntityExplodeEvent event) { @@ -169,76 +212,39 @@ public class FactionsEntityListener extends EntityListener // ghast fireball which needs prevention event.setCancelled(true); } - else - { // TNT - if (exploitExplosions.size() > 0) - { // make sure this isn't a TNT explosion exploit attempt - int locX = event.getLocation().getBlockX(); - int locZ = event.getLocation().getBlockZ(); - - for (int i = exploitExplosions.size() - 1; i >= 0; i--) - { - PotentialExplosionExploit ex = exploitExplosions.get(i); - - // remove anything from the list older than 10 seconds (TNT takes 4 seconds to trigger; provide some leeway) - if (ex.timeMillis + 10000 < 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 "+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; - } - } - } - - if + else if + ( ( + faction.isNone() + && + Conf.wildernessBlockTNT + && + ! Conf.worldsNoWildernessProtection.contains(loc.getWorld().getName()) + ) + || + ( + faction.isNormal() + && ( - faction.isNone() - && - Conf.wildernessBlockTNT - && - ! Conf.worldsNoWildernessProtection.contains(loc.getWorld().getName()) - ) - || - ( - faction.isNormal() - && - ( - online ? Conf.territoryBlockTNT : Conf.territoryBlockTNTWhenOffline - ) - ) - || - ( - faction.isWarZone() - && - Conf.warZoneBlockTNT - ) - || - ( - faction.isSafeZone() - && - Conf.safeZoneBlockTNT + online ? Conf.territoryBlockTNT : Conf.territoryBlockTNTWhenOffline ) ) - { - // we'll assume it's TNT, which needs prevention - event.setCancelled(true); - } + || + ( + faction.isWarZone() + && + Conf.warZoneBlockTNT + ) + || + ( + faction.isSafeZone() + && + Conf.safeZoneBlockTNT + ) + ) + { + // we'll assume it's TNT, which needs prevention + event.setCancelled(true); } }