From 03b0a2bb5f6e57b8ee393d4dfc11b917f15b6ab2 Mon Sep 17 00:00:00 2001 From: Brettflan Date: Mon, 19 Mar 2012 06:54:59 -0500 Subject: [PATCH] Optional prevention of a couple of exploits. 1. Obsidian generator exploit, which converts redstone wire to obsidian. New setting "handleExploitObsidianGenerators" (enabled by default) to determine whether it's prevented or not. Some servers might want to disable this prevention, to keep it as a viable obsidian creation method. Thanks to ObGenBlocker and WorldGuard plugins for the prevention method. 2. Ender pearl exploit, which could be used to clip through doors, glass, and probably a few other things if just the right spot was targeted. New setting "handleExploitEnderPearlClipping" (enabled by default) to determine whether it's prevented or not. Also removed our TNT exploit prevention code, since they did get it fully fixed in 1.1-R4 and it doesn't look to be coming back from the dead again like it did when they released 1.1-R2. --- src/com/massivecraft/factions/Conf.java | 6 +- src/com/massivecraft/factions/P.java | 4 + .../listeners/FactionsBlockListener.java | 9 -- .../listeners/FactionsEntityListener.java | 84 +------------------ .../listeners/FactionsExploitListener.java | 42 ++++++++++ 5 files changed, 52 insertions(+), 93 deletions(-) create mode 100644 src/com/massivecraft/factions/listeners/FactionsExploitListener.java diff --git a/src/com/massivecraft/factions/Conf.java b/src/com/massivecraft/factions/Conf.java index f9bb713e..deace70b 100644 --- a/src/com/massivecraft/factions/Conf.java +++ b/src/com/massivecraft/factions/Conf.java @@ -90,7 +90,11 @@ public class Conf public static boolean logLandUnclaims = true; public static boolean logMoneyTransactions = true; public static boolean logPlayerCommands = true; - + + // prevent some potential exploits + public static boolean handleExploitObsidianGenerators = true; + public static boolean handleExploitEnderPearlClipping = true; + public static boolean homesEnabled = true; public static boolean homesMustBeInClaimedTerritory = true; public static boolean homesTeleportToOnDeath = true; diff --git a/src/com/massivecraft/factions/P.java b/src/com/massivecraft/factions/P.java index b01aefe4..3fff9600 100644 --- a/src/com/massivecraft/factions/P.java +++ b/src/com/massivecraft/factions/P.java @@ -26,6 +26,7 @@ import com.massivecraft.factions.integration.capi.CapiFeatures; import com.massivecraft.factions.listeners.FactionsBlockListener; import com.massivecraft.factions.listeners.FactionsChatListener; import com.massivecraft.factions.listeners.FactionsEntityListener; +import com.massivecraft.factions.listeners.FactionsExploitListener; import com.massivecraft.factions.listeners.FactionsPlayerListener; import com.massivecraft.factions.listeners.FactionsServerListener; import com.massivecraft.factions.struct.ChatMode; @@ -49,6 +50,7 @@ public class P extends MPlugin public final FactionsPlayerListener playerListener; public final FactionsChatListener chatListener; public final FactionsEntityListener entityListener; + public final FactionsExploitListener exploitListener; public final FactionsBlockListener blockListener; public final FactionsServerListener serverListener; @@ -68,6 +70,7 @@ public class P extends MPlugin this.playerListener = new FactionsPlayerListener(this); this.chatListener = new FactionsChatListener(this); this.entityListener = new FactionsEntityListener(this); + this.exploitListener = new FactionsExploitListener(); this.blockListener = new FactionsBlockListener(this); this.serverListener = new FactionsServerListener(this); } @@ -108,6 +111,7 @@ public class P extends MPlugin getServer().getPluginManager().registerEvents(playerListener, this); getServer().getPluginManager().registerEvents(chatListener, this); getServer().getPluginManager().registerEvents(entityListener, this); + getServer().getPluginManager().registerEvents(exploitListener, this); getServer().getPluginManager().registerEvents(blockListener, this); getServer().getPluginManager().registerEvents(serverListener, this); diff --git a/src/com/massivecraft/factions/listeners/FactionsBlockListener.java b/src/com/massivecraft/factions/listeners/FactionsBlockListener.java index 716e2497..def506ce 100644 --- a/src/com/massivecraft/factions/listeners/FactionsBlockListener.java +++ b/src/com/massivecraft/factions/listeners/FactionsBlockListener.java @@ -45,16 +45,7 @@ public class FactionsBlockListener implements Listener } if ( ! playerCanBuildDestroyBlock(event.getPlayer(), event.getBlock().getLocation(), "build", false)) - { 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 76f4b0aa..5c3ddfb9 100644 --- a/src/com/massivecraft/factions/listeners/FactionsEntityListener.java +++ b/src/com/massivecraft/factions/listeners/FactionsEntityListener.java @@ -1,15 +1,12 @@ package com.massivecraft.factions.listeners; -import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.LinkedHashSet; -import java.util.logging.Level; import java.text.MessageFormat; import java.util.Set; import org.bukkit.Location; -import org.bukkit.Material; import org.bukkit.entity.Creeper; import org.bukkit.entity.Enderman; import org.bukkit.entity.Entity; @@ -17,7 +14,6 @@ import org.bukkit.entity.Fireball; import org.bukkit.entity.LivingEntity; 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; @@ -29,7 +25,6 @@ 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.entity.PotionSplashEvent; import org.bukkit.event.painting.PaintingBreakByEntityEvent; import org.bukkit.event.painting.PaintingBreakEvent; @@ -250,9 +245,7 @@ public class FactionsEntityListener implements Listener } if ( ! badjuju) return; - Entity thrower = event.getEntity(); - if (thrower instanceof Projectile) - thrower = ((Projectile)thrower).getShooter(); + Entity thrower = event.getPotion().getShooter(); // scan through affected entities to make sure they're all valid targets Iterator iter = event.getAffectedEntities().iterator(); @@ -567,79 +560,4 @@ public class FactionsEntityListener implements Listener return false; } - - - /** - * 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()+"\""; - P.p.log(Level.WARNING, msg + " at "+ex.X+","+ex.Z+" (X,Z) using a "+ex.item.name()); - for (FPlayer fplayer : FPlayers.i.getOnline()) - { - fplayer.sendMessage(msg+". Coordinates logged."); - } - 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(); - } - } } diff --git a/src/com/massivecraft/factions/listeners/FactionsExploitListener.java b/src/com/massivecraft/factions/listeners/FactionsExploitListener.java new file mode 100644 index 00000000..133b6800 --- /dev/null +++ b/src/com/massivecraft/factions/listeners/FactionsExploitListener.java @@ -0,0 +1,42 @@ +package com.massivecraft.factions.listeners; + +import org.bukkit.block.Block; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.Location; + +import com.massivecraft.factions.Conf; + + +public class FactionsExploitListener implements Listener +{ + @EventHandler(priority = EventPriority.NORMAL) + public void obsidianGenerator(BlockFromToEvent event) + { + if (event.isCancelled() == true || ! Conf.handleExploitObsidianGenerators) return; + + // thanks to ObGenBlocker and WorldGuard for this method + int source = event.getBlock().getTypeId(); + Block block = event.getToBlock(); + if ((source == 0 || source == 10 || source == 11) && block.getTypeId() == 55) + block.setTypeId(0); + } + + + @EventHandler(priority = EventPriority.NORMAL) + public void enderPearlTeleport(PlayerTeleportEvent event) + { + if (event.isCancelled() == true || ! Conf.handleExploitEnderPearlClipping) return; + if (event.getCause() != PlayerTeleportEvent.TeleportCause.ENDER_PEARL) return; + + // this exploit works when the target location is within 0.31 blocks or so of a door or glass block or similar... + // simple fix: ender pearl target locations are standardized to be in the center (X/Z) of the target block, not at the edges + Location target = event.getTo(); + target.setX(target.getBlockX() + 0.5); + target.setZ(target.getBlockZ() + 0.5); + event.setTo(target); + } +}