diff --git a/src/com/massivecraft/factions/FPerm.java b/src/com/massivecraft/factions/FPerm.java index 97174afc..63a147aa 100644 --- a/src/com/massivecraft/factions/FPerm.java +++ b/src/com/massivecraft/factions/FPerm.java @@ -29,6 +29,7 @@ public enum FPerm BUTTON("button", "use stone buttons", Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY), LEVER("lever", "use levers", Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY), CONTAINER("container", "use containers", Rel.LEADER, Rel.OFFICER, Rel.MEMBER), + INVITE("invite", "invite players", Rel.LEADER, Rel.OFFICER), KICK("kick", "kick members", Rel.LEADER, Rel.OFFICER), SETHOME("sethome", "set the home", Rel.LEADER, Rel.OFFICER), @@ -141,6 +142,7 @@ public enum FPerm } // Perms which apply strictly to granting territory access + // TODO: This should be a boolean field within the class itself! private static final Set TerritoryPerms = EnumSet.of(BUILD, DOOR, BUTTON, LEVER, CONTAINER); public boolean isTerritoryPerm() { diff --git a/src/com/massivecraft/factions/Factions.java b/src/com/massivecraft/factions/Factions.java index a518849b..ab83cc1f 100644 --- a/src/com/massivecraft/factions/Factions.java +++ b/src/com/massivecraft/factions/Factions.java @@ -12,7 +12,6 @@ import com.massivecraft.factions.integration.Econ; import com.massivecraft.factions.integration.LWCFeatures; import com.massivecraft.factions.integration.SpoutFeatures; 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; @@ -47,7 +46,6 @@ public class Factions extends MPlugin public FactionsChatListener chatListener; public FactionsEntityListener entityListener; public FactionsExploitListener exploitListener; - public FactionsBlockListener blockListener; // Task Ids private Integer AutoLeaveTask = null; @@ -105,9 +103,6 @@ public class Factions extends MPlugin this.exploitListener = new FactionsExploitListener(); getServer().getPluginManager().registerEvents(this.exploitListener, this); - this.blockListener = new FactionsBlockListener(); - getServer().getPluginManager().registerEvents(this.blockListener, this); - postEnable(); } diff --git a/src/com/massivecraft/factions/MainListener.java b/src/com/massivecraft/factions/MainListener.java index cfa44687..54848f64 100644 --- a/src/com/massivecraft/factions/MainListener.java +++ b/src/com/massivecraft/factions/MainListener.java @@ -1,13 +1,29 @@ package com.massivecraft.factions; import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.block.BlockPistonExtendEvent; +import org.bukkit.event.block.BlockPistonRetractEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.block.BlockSpreadEvent; +import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityRegainHealthEvent; +import org.bukkit.event.hanging.HangingBreakByEntityEvent; +import org.bukkit.event.hanging.HangingBreakEvent; +import org.bukkit.event.hanging.HangingPlaceEvent; +import org.bukkit.event.hanging.HangingBreakEvent.RemoveCause; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.player.PlayerTeleportEvent; @@ -15,6 +31,7 @@ import org.bukkit.event.server.PluginDisableEvent; import org.bukkit.event.server.PluginEnableEvent; import com.massivecraft.factions.integration.SpoutFeatures; +import com.massivecraft.mcore.ps.PS; public class MainListener implements Listener { @@ -35,6 +52,201 @@ public class MainListener implements Listener Bukkit.getPluginManager().registerEvents(this, Factions.get()); } + // -------------------------------------------- // + // FLAG: EXPLOSIONS + // -------------------------------------------- // + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void blockExplosion(HangingBreakEvent event) + { + // If a hanging entity was broken by an explosion ... + if (event.getCause() != RemoveCause.EXPLOSION) return; + + // ... and the faction there has explosions disabled ... + Faction faction = BoardColl.get().getFactionAt(PS.valueOf(event.getEntity())); + if (faction.getFlag(FFlag.EXPLOSIONS)) return; + + // ... then cancel. + event.setCancelled(true); + } + + // -------------------------------------------- // + // FLAG: BUILD + // -------------------------------------------- // + + public static boolean canPlayerBuildAt(Player player, PS ps, boolean justCheck) + { + String name = player.getName(); + if (ConfServer.playersWhoBypassAllProtection.contains(name)) return true; + + FPlayer me = FPlayer.get(name); + if (me.isUsingAdminMode()) return true; + + Faction factionHere = BoardColl.get().getFactionAt(ps); + + if ( ! FPerm.BUILD.has(me, ps) && FPerm.PAINBUILD.has(me, ps)) + { + if (!justCheck) + { + me.msg("It is painful to build in the territory of %s.", factionHere.describeTo(me)); + player.damage(ConfServer.actionDeniedPainAmount); + } + return true; + } + + return FPerm.BUILD.has(me, ps, true); + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void blockBuild(HangingPlaceEvent event) + { + if (canPlayerBuildAt(event.getPlayer(), PS.valueOf(event.getEntity()), false)) return; + + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void blockBuild(HangingBreakEvent event) + { + if (! (event instanceof HangingBreakByEntityEvent)) return; + HangingBreakByEntityEvent entityEvent = (HangingBreakByEntityEvent)event; + + Entity breaker = entityEvent.getRemover(); + if (! (breaker instanceof Player)) return; + + if ( ! canPlayerBuildAt((Player)breaker, PS.valueOf(event.getEntity()), false)) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void blockBuild(BlockPlaceEvent event) + { + if (!event.canBuild()) return; + + if (canPlayerBuildAt(event.getPlayer(), PS.valueOf(event.getBlock()), false)) return; + + event.setBuild(false); + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void blockBuild(BlockBreakEvent event) + { + if (canPlayerBuildAt(event.getPlayer(), PS.valueOf(event.getBlock()), false)) return; + + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void blockBuild(BlockDamageEvent event) + { + if (!event.getInstaBreak()) return; + + if (canPlayerBuildAt(event.getPlayer(), PS.valueOf(event.getBlock()), false)) return; + + event.setCancelled(true); + } + + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void blockBuild(BlockPistonExtendEvent event) + { + if ( ! ConfServer.pistonProtectionThroughDenyBuild) return; + + Faction pistonFaction = BoardColl.get().getFactionAt(PS.valueOf(event.getBlock())); + + // target end-of-the-line empty (air) block which is being pushed into, including if piston itself would extend into air + Block targetBlock = event.getBlock().getRelative(event.getDirection(), event.getLength() + 1); + + // members of faction might not have build rights in their own territory, but pistons should still work regardless; so, address that corner case + Faction targetFaction = BoardColl.get().getFactionAt(PS.valueOf(targetBlock)); + if (targetFaction == pistonFaction) return; + + // if potentially pushing into air/water/lava in another territory, we need to check it out + if ((targetBlock.isEmpty() || targetBlock.isLiquid()) && ! FPerm.BUILD.has(pistonFaction, targetBlock.getLocation())) + { + event.setCancelled(true); + } + + /* + * note that I originally was testing the territory of each affected block, but since I found that pistons can only push + * up to 12 blocks and the width of any territory is 16 blocks, it should be safe (and much more lightweight) to test + * only the final target block as done above + */ + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void blockBuild(BlockPistonRetractEvent event) + { + if (!ConfServer.pistonProtectionThroughDenyBuild) return; + + // if not a sticky piston, retraction should be fine + if (!event.isSticky()) return; + + Location targetLoc = event.getRetractLocation(); + + // if potentially retracted block is just air/water/lava, no worries + if (targetLoc.getBlock().isEmpty() || targetLoc.getBlock().isLiquid()) return; + + Faction pistonFaction = BoardColl.get().getFactionAt(PS.valueOf(event.getBlock())); + + // members of faction might not have build rights in their own territory, but pistons should still work regardless; so, address that corner case + Faction targetFaction = BoardColl.get().getFactionAt(PS.valueOf(targetLoc)); + if (targetFaction == pistonFaction) return; + + if ( ! FPerm.BUILD.has(pistonFaction, targetLoc)) + { + event.setCancelled(true); + } + } + + // -------------------------------------------- // + // FLAG: FIRE SPREAD + // -------------------------------------------- // + + public void blockFireSpread(Block block, Cancellable cancellable) + { + // If the faction at the block has firespread disabled ... + PS ps = PS.valueOf(block); + Faction faction = BoardColl.get().getFactionAt(ps); + if (faction.getFlag(FFlag.FIRESPREAD)) return; + + // then cancel the event. + cancellable.setCancelled(true); + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void blockFireSpread(BlockIgniteEvent event) + { + // If fire is spreading ... + if (event.getCause() != IgniteCause.SPREAD && event.getCause() != IgniteCause.LAVA) return; + + // ... consider blocking it. + blockFireSpread(event.getBlock(), event); + } + + // TODO: Is use of this event deprecated? + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void blockFireSpread(BlockSpreadEvent event) + { + // If fire is spreading ... + if (event.getNewState().getTypeId() != 51) return; + + // ... consider blocking it. + blockFireSpread(event.getBlock(), event); + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void blockFireSpread(BlockBurnEvent event) + { + // If a block is burning ... + + // ... consider blocking it. + blockFireSpread(event.getBlock(), event); + } + // -------------------------------------------- // // SPOUT // -------------------------------------------- // diff --git a/src/com/massivecraft/factions/listeners/FactionsBlockListener.java b/src/com/massivecraft/factions/listeners/FactionsBlockListener.java deleted file mode 100644 index b49a2056..00000000 --- a/src/com/massivecraft/factions/listeners/FactionsBlockListener.java +++ /dev/null @@ -1,192 +0,0 @@ -package com.massivecraft.factions.listeners; - -import org.bukkit.Location; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockBurnEvent; -import org.bukkit.event.block.BlockDamageEvent; -import org.bukkit.event.block.BlockIgniteEvent; -import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.block.BlockPistonExtendEvent; -import org.bukkit.event.block.BlockPistonRetractEvent; -import org.bukkit.event.block.BlockSpreadEvent; -import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; - -import com.massivecraft.factions.BoardColl; -import com.massivecraft.factions.ConfServer; -import com.massivecraft.factions.FFlag; -import com.massivecraft.factions.FPerm; -import com.massivecraft.factions.FPlayer; -import com.massivecraft.factions.Faction; -import com.massivecraft.mcore.ps.PS; - - -public class FactionsBlockListener implements Listener -{ - // -------------------------------------------- // - // FLAG: FIRE SPREAD - // -------------------------------------------- // - - public void blockFireSpread(Block block, Cancellable cancellable) - { - // If the faction at the block has firespread disabled ... - PS ps = PS.valueOf(block); - Faction faction = BoardColl.get().getFactionAt(ps); - if (faction.getFlag(FFlag.FIRESPREAD)) return; - - // then cancel the event. - cancellable.setCancelled(true); - } - - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void blockFireSpread(BlockIgniteEvent event) - { - // If fire is spreading ... - if (event.getCause() != IgniteCause.SPREAD && event.getCause() != IgniteCause.LAVA) return; - - // ... consider blocking it. - blockFireSpread(event.getBlock(), event); - } - - // TODO: Is use of this event deprecated? - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void blockFireSpread(BlockSpreadEvent event) - { - // If fire is spreading ... - if (event.getNewState().getTypeId() != 51) return; - - // ... consider blocking it. - blockFireSpread(event.getBlock(), event); - } - - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void blockFireSpread(BlockBurnEvent event) - { - // If a block is burning ... - - // ... consider blocking it. - blockFireSpread(event.getBlock(), event); - } - - // -------------------------------------------- // - // ASSORTED - // -------------------------------------------- // - - public static boolean playerCanBuildDestroyBlock(Player player, Block block, String action, boolean justCheck) - { - return playerCanBuildDestroyBlock(player, block.getLocation(), action, justCheck); - } - - public static boolean playerCanBuildDestroyBlock(Player player, Location location, String action, boolean justCheck) - { - String name = player.getName(); - if (ConfServer.playersWhoBypassAllProtection.contains(name)) return true; - - FPlayer me = FPlayer.get(name); - if (me.isUsingAdminMode()) return true; - - PS ps = PS.valueOf(location); - Faction factionHere = BoardColl.get().getFactionAt(ps); - - if ( ! FPerm.BUILD.has(me, location) && FPerm.PAINBUILD.has(me, location)) - { - if (!justCheck) - { - me.msg("It is painful to %s in the territory of %s.", action, factionHere.describeTo(me)); - player.damage(ConfServer.actionDeniedPainAmount); - } - return true; - } - - return FPerm.BUILD.has(me, ps, true); - } - - @EventHandler(priority = EventPriority.NORMAL) - public void onBlockPlace(BlockPlaceEvent event) - { - if (event.isCancelled()) return; - if ( ! event.canBuild()) return; - - if ( ! playerCanBuildDestroyBlock(event.getPlayer(), event.getBlock(), "build", false)) - event.setCancelled(true); - } - - @EventHandler(priority = EventPriority.NORMAL) - public void onBlockBreak(BlockBreakEvent event) - { - if (event.isCancelled()) return; - - if ( ! playerCanBuildDestroyBlock(event.getPlayer(), event.getBlock(), "destroy", false)) - { - event.setCancelled(true); - } - } - - @EventHandler(priority = EventPriority.NORMAL) - public void onBlockDamage(BlockDamageEvent event) - { - if (event.isCancelled()) return; - if ( ! event.getInstaBreak()) return; - - if (! playerCanBuildDestroyBlock(event.getPlayer(), event.getBlock(), "destroy", false)) - { - event.setCancelled(true); - } - } - - @EventHandler(priority = EventPriority.NORMAL) - public void onBlockPistonExtend(BlockPistonExtendEvent event) - { - if (event.isCancelled()) return; - if ( ! ConfServer.pistonProtectionThroughDenyBuild) return; - - Faction pistonFaction = BoardColl.get().getFactionAt(PS.valueOf(event.getBlock())); - - // target end-of-the-line empty (air) block which is being pushed into, including if piston itself would extend into air - Block targetBlock = event.getBlock().getRelative(event.getDirection(), event.getLength() + 1); - - // members of faction might not have build rights in their own territory, but pistons should still work regardless; so, address that corner case - Faction targetFaction = BoardColl.get().getFactionAt(PS.valueOf(targetBlock)); - if (targetFaction == pistonFaction) return; - - // if potentially pushing into air/water/lava in another territory, we need to check it out - if ((targetBlock.isEmpty() || targetBlock.isLiquid()) && ! FPerm.BUILD.has(pistonFaction, targetBlock.getLocation())) - { - event.setCancelled(true); - } - - /* - * note that I originally was testing the territory of each affected block, but since I found that pistons can only push - * up to 12 blocks and the width of any territory is 16 blocks, it should be safe (and much more lightweight) to test - * only the final target block as done above - */ - } - - @EventHandler(priority = EventPriority.NORMAL) - public void onBlockPistonRetract(BlockPistonRetractEvent event) - { - // if not a sticky piston, retraction should be fine - if (event.isCancelled() || !event.isSticky() || !ConfServer.pistonProtectionThroughDenyBuild) return; - - Location targetLoc = event.getRetractLocation(); - - // if potentially retracted block is just air/water/lava, no worries - if (targetLoc.getBlock().isEmpty() || targetLoc.getBlock().isLiquid()) return; - - Faction pistonFaction = BoardColl.get().getFactionAt(PS.valueOf(event.getBlock())); - - // members of faction might not have build rights in their own territory, but pistons should still work regardless; so, address that corner case - Faction targetFaction = BoardColl.get().getFactionAt(PS.valueOf(targetLoc)); - if (targetFaction == pistonFaction) return; - - if ( ! FPerm.BUILD.has(pistonFaction, targetLoc)) - { - event.setCancelled(true); - } - } -} diff --git a/src/com/massivecraft/factions/listeners/FactionsEntityListener.java b/src/com/massivecraft/factions/listeners/FactionsEntityListener.java index 470ab6d8..53b4acdb 100644 --- a/src/com/massivecraft/factions/listeners/FactionsEntityListener.java +++ b/src/com/massivecraft/factions/listeners/FactionsEntityListener.java @@ -30,10 +30,6 @@ import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.EntityTargetEvent; import org.bukkit.event.entity.PotionSplashEvent; -import org.bukkit.event.hanging.HangingBreakByEntityEvent; -import org.bukkit.event.hanging.HangingBreakEvent; -import org.bukkit.event.hanging.HangingBreakEvent.RemoveCause; -import org.bukkit.event.hanging.HangingPlaceEvent; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; @@ -378,48 +374,13 @@ public class FactionsEntityListener implements Listener event.setCancelled(true); } - @EventHandler(priority = EventPriority.NORMAL) - public void onPaintingBreak(HangingBreakEvent event) - { - if (event.isCancelled()) return; + + + + + - if (event.getCause() == RemoveCause.EXPLOSION) - { - Faction faction = BoardColl.get().getFactionAt(PS.valueOf(event.getEntity())); - if (faction.getFlag(FFlag.EXPLOSIONS) == false) - { // faction has explosions disabled - event.setCancelled(true); - return; - } - } - - if (! (event instanceof HangingBreakByEntityEvent)) - { - return; - } - - Entity breaker = ((HangingBreakByEntityEvent)event).getRemover(); - if (! (breaker instanceof Player)) - { - return; - } - - if ( ! FactionsBlockListener.playerCanBuildDestroyBlock((Player)breaker, event.getEntity().getLocation().getBlock(), "remove paintings", false)) - { - event.setCancelled(true); - } - } - - @EventHandler(priority = EventPriority.NORMAL) - public void onPaintingPlace(HangingPlaceEvent event) - { - if (event.isCancelled()) return; - - if ( ! FactionsBlockListener.playerCanBuildDestroyBlock(event.getPlayer(), event.getBlock().getLocation().getBlock(), "place paintings", false) ) - { - event.setCancelled(true); - } - } + @EventHandler(priority = EventPriority.NORMAL) public void onEntityChangeBlock(EntityChangeBlockEvent event)