From 8f2e587eb99954a97f5da224f83c91be8fed4808 Mon Sep 17 00:00:00 2001 From: Brettflan Date: Mon, 19 Mar 2012 06:55:00 -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 | 16 ---- .../listeners/FactionsEntityListener.java | 85 +------------------ .../listeners/FactionsExploitListener.java | 42 +++++++++ 5 files changed, 52 insertions(+), 101 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 9c42faa7..0e67bfa7 100644 --- a/src/com/massivecraft/factions/Conf.java +++ b/src/com/massivecraft/factions/Conf.java @@ -101,7 +101,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 8c473561..ae95ec9e 100644 --- a/src/com/massivecraft/factions/P.java +++ b/src/com/massivecraft/factions/P.java @@ -30,6 +30,7 @@ import com.massivecraft.factions.integration.Worldguard; 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; @@ -54,6 +55,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; @@ -73,6 +75,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); } @@ -113,6 +116,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 aa2174b6..19caf19f 100644 --- a/src/com/massivecraft/factions/listeners/FactionsBlockListener.java +++ b/src/com/massivecraft/factions/listeners/FactionsBlockListener.java @@ -87,25 +87,9 @@ public class FactionsBlockListener implements Listener { if (event.isCancelled()) return; if ( ! event.canBuild()) return; - - // TODO: Test if this old stuff is still an issue. - // special case for flint&steel, which should only be prevented by DenyUsage list - /*if (event.getBlockPlaced().getType() == Material.FIRE) - { - return; - }*/ if ( ! playerCanBuildDestroyBlock(event.getPlayer(), event.getBlock(), "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 4bab89fd..83d702ec 100644 --- a/src/com/massivecraft/factions/listeners/FactionsEntityListener.java +++ b/src/com/massivecraft/factions/listeners/FactionsEntityListener.java @@ -1,22 +1,18 @@ 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.block.Block; import org.bukkit.entity.Enderman; import org.bukkit.entity.Entity; 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; @@ -28,7 +24,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; @@ -154,9 +149,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(); @@ -386,80 +379,4 @@ 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()+"\""; - 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); + } +}