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); + } +}