diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java index c2b60d85..365d55a5 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java @@ -30,6 +30,7 @@ import com.sk89q.minecraft.util.commands.MissingNestedCommandException; import com.sk89q.minecraft.util.commands.SimpleInjector; import com.sk89q.minecraft.util.commands.WrappedCommandException; +import com.sk89q.worldguard.bukkit.listener.RegionFlagsListener; import com.sk89q.worldguard.util.concurrent.EvenMoreExecutors; import com.sk89q.worldguard.util.task.SimpleSupervisor; import com.sk89q.worldguard.util.task.Supervisor; @@ -227,6 +228,7 @@ public void run() { (new BlacklistListener(this)).registerEvents(); (new ChestProtectionListener(this)).registerEvents(); (new RegionProtectionListener(this)).registerEvents(); + (new RegionFlagsListener(this)).registerEvents(); (new BlockedPotionsListener(this)).registerEvents(); (new EventAbstractionListener(this)).registerEvents(); if ("true".equalsIgnoreCase(System.getProperty("worldguard.debug.listener"))) { diff --git a/src/main/java/com/sk89q/worldguard/bukkit/cause/Cause.java b/src/main/java/com/sk89q/worldguard/bukkit/cause/Cause.java index af931c40..d5bf8dcf 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/cause/Cause.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/cause/Cause.java @@ -93,7 +93,7 @@ public Player getPlayerRootCause() { } @Nullable - public Entity getEntityRootCause() { + public Entity getFirstEntity() { for (Object object : causes) { if (object instanceof Entity) { return (Entity) object; diff --git a/src/main/java/com/sk89q/worldguard/bukkit/event/block/AbstractBlockEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/block/AbstractBlockEvent.java index bbd013af..e9d4a7ec 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/event/block/AbstractBlockEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/block/AbstractBlockEvent.java @@ -103,7 +103,7 @@ public List getBlocks() { * list once the predicate returns {@code false} * @return true if one or more blocks were filtered out */ - public boolean filterBlocks(Predicate predicate, boolean cancelEventOnFalse) { + public boolean filter(Predicate predicate, boolean cancelEventOnFalse) { boolean hasRemoval = false; Iterator it = blocks.iterator(); @@ -130,14 +130,14 @@ public boolean filterBlocks(Predicate predicate, boolean cancelEventOn * *

This method will not fail fast and * cancel the event the first instance that the predicate returns - * {@code false}. See {@link #filterBlocks(Predicate, boolean)} to adjust + * {@code false}. See {@link #filter(Predicate, boolean)} to adjust * this behavior.

* * @param predicate the predicate * @return true if one or more blocks were filtered out */ - public boolean filterBlocks(Predicate predicate) { - return filterBlocks(predicate, false); + public boolean filter(Predicate predicate) { + return filter(predicate, false); } /** diff --git a/src/main/java/com/sk89q/worldguard/bukkit/event/entity/AbstractEntityEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/entity/AbstractEntityEvent.java index 83743552..8044d9ed 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/event/entity/AbstractEntityEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/entity/AbstractEntityEvent.java @@ -19,9 +19,11 @@ package com.sk89q.worldguard.bukkit.event.entity; +import com.google.common.base.Predicate; import com.sk89q.worldguard.bukkit.cause.Cause; import com.sk89q.worldguard.bukkit.event.AbstractDelegateEvent; import org.bukkit.Location; +import org.bukkit.World; import org.bukkit.entity.Entity; import org.bukkit.event.Event; @@ -49,6 +51,15 @@ protected AbstractEntityEvent(@Nullable Event originalEvent, Cause cause, Locati this.entity = null; } + /** + * Get the world. + * + * @return the world + */ + public World getWorld() { + return target.getWorld(); + } + /** * Get the target location being affected. * @@ -69,4 +80,23 @@ public Entity getEntity() { return entity; } + /** + * Filter the list of affected entities with the given predicate. If the + * predicate returns {@code false}, then the entity is not affected. + * + * @param predicate the predicate + * @param cancelEventOnFalse true to cancel the event and clear the entity + * list once the predicate returns {@code false} + * @return true if one or more entities were filtered out + */ + public boolean filter(Predicate predicate, boolean cancelEventOnFalse) { + if (!isCancelled()) { + if (!predicate.apply(getTarget())) { + setCancelled(true); + } + } + + return isCancelled(); + } + } diff --git a/src/main/java/com/sk89q/worldguard/bukkit/listener/BlacklistListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/BlacklistListener.java index 3149071e..c95d9852 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/listener/BlacklistListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/BlacklistListener.java @@ -84,7 +84,7 @@ public void onBreakBlock(final BreakBlockEvent event) { return; } - event.filterBlocks(new Predicate() { + event.filter(new Predicate() { @Override public boolean apply(Location target) { if (!wcfg.getBlacklist().check( @@ -116,7 +116,7 @@ public void onPlaceBlock(final PlaceBlockEvent event) { return; } - event.filterBlocks(new Predicate() { + event.filter(new Predicate() { @Override public boolean apply(Location target) { return wcfg.getBlacklist().check(new BlockPlaceBlacklistEvent( @@ -142,7 +142,7 @@ public void onUseBlock(final UseBlockEvent event) { return; } - event.filterBlocks(new Predicate() { + event.filter(new Predicate() { @Override public boolean apply(Location target) { return wcfg.getBlacklist().check(new BlockInteractBlacklistEvent( diff --git a/src/main/java/com/sk89q/worldguard/bukkit/listener/ChestProtectionListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/ChestProtectionListener.java index a2abeb54..35101a57 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/listener/ChestProtectionListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/ChestProtectionListener.java @@ -58,7 +58,7 @@ public void onPlaceBlock(final PlaceBlockEvent event) { return; } - event.filterBlocks(new Predicate() { + event.filter(new Predicate() { @Override public boolean apply(Location target) { if (wcfg.getChestProtection().isChest(event.getEffectiveMaterial().getId()) && wcfg.isChestProtected(target.getBlock(), player)) { @@ -84,7 +84,7 @@ public void onBreakBlock(final BreakBlockEvent event) { } if (player != null) { - event.filterBlocks(new Predicate() { + event.filter(new Predicate() { @Override public boolean apply(Location target) { if (wcfg.isChestProtected(target.getBlock(), player)) { @@ -96,7 +96,7 @@ public boolean apply(Location target) { } }, true); } else { - event.filterBlocks(new Predicate() { + event.filter(new Predicate() { @Override public boolean apply(Location target) { return !wcfg.isChestProtected(target.getBlock()); @@ -118,7 +118,7 @@ public void onUseBlock(final UseBlockEvent event) { } if (player != null) { - event.filterBlocks(new Predicate() { + event.filter(new Predicate() { @Override public boolean apply(Location target) { if (wcfg.isChestProtected(target.getBlock(), player)) { @@ -130,7 +130,7 @@ public boolean apply(Location target) { } }, true); } else { - event.filterBlocks(new Predicate() { + event.filter(new Predicate() { @Override public boolean apply(Location target) { return !wcfg.isChestProtected(target.getBlock()); diff --git a/src/main/java/com/sk89q/worldguard/bukkit/listener/RegionFlagsListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/RegionFlagsListener.java new file mode 100644 index 00000000..ad4608e3 --- /dev/null +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/RegionFlagsListener.java @@ -0,0 +1,98 @@ +/* + * WorldGuard, a suite of tools for Minecraft + * Copyright (C) sk89q + * Copyright (C) WorldGuard team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldguard.bukkit.listener; + +import com.google.common.base.Predicate; +import com.sk89q.worldguard.bukkit.RegionQuery; +import com.sk89q.worldguard.bukkit.WorldConfiguration; +import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import com.sk89q.worldguard.bukkit.event.block.BreakBlockEvent; +import com.sk89q.worldguard.bukkit.event.entity.SpawnEntityEvent; +import com.sk89q.worldguard.bukkit.util.Entities; +import com.sk89q.worldguard.protection.flags.DefaultFlag; +import com.sk89q.worldguard.protection.flags.StateFlag; +import org.bukkit.Location; +import org.bukkit.entity.Creeper; +import org.bukkit.entity.EnderDragon; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; + +import javax.annotation.Nullable; + +public class RegionFlagsListener extends AbstractListener { + + /** + * Construct the listener. + * + * @param plugin an instance of WorldGuardPlugin + */ + public RegionFlagsListener(WorldGuardPlugin plugin) { + super(plugin); + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onBreakBlock(final BreakBlockEvent event) { + WorldConfiguration config = getWorldConfig(event.getWorld()); + RegionQuery query = getPlugin().getRegionContainer().createQuery(); + + Entity entity; + if ((entity = event.getCause().getFirstEntity()) != null) { + if (entity instanceof Creeper) { // Creeper + event.filter(testState(query, DefaultFlag.CREEPER_EXPLOSION), config.explosionFlagCancellation); + + } else if (entity instanceof EnderDragon) { // Enderdragon + event.filter(testState(query, DefaultFlag.ENDERDRAGON_BLOCK_DAMAGE), config.explosionFlagCancellation); + + } else if (Entities.isTNTBased(entity)) { // TNT + explosive TNT carts + event.filter(testState(query, DefaultFlag.TNT), config.explosionFlagCancellation); + + } + } + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onSpawnEntity(final SpawnEntityEvent event) { + RegionQuery query = getPlugin().getRegionContainer().createQuery(); + + if (event.getEffectiveType() == EntityType.EXPERIENCE_ORB) { + event.filter(testState(query, DefaultFlag.EXP_DROPS), false); + } + } + + /** + * Create a new predicate to test a state flag for each location. + * + * @param query the query + * @param flag the flag + * @return a predicate + */ + private Predicate testState(final RegionQuery query, final StateFlag flag) { + return new Predicate() { + @Override + public boolean apply(@Nullable Location location) { + return query.testState(location, null, flag); + } + }; + } + + +} diff --git a/src/main/java/com/sk89q/worldguard/bukkit/listener/RegionProtectionListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/RegionProtectionListener.java index 76260805..bdf996b6 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/listener/RegionProtectionListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/RegionProtectionListener.java @@ -20,9 +20,7 @@ package com.sk89q.worldguard.bukkit.listener; import com.google.common.base.Predicate; -import com.sk89q.worldguard.bukkit.ConfigurationManager; import com.sk89q.worldguard.bukkit.RegionQuery; -import com.sk89q.worldguard.bukkit.WorldConfiguration; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.bukkit.cause.Cause; import com.sk89q.worldguard.bukkit.event.block.BreakBlockEvent; @@ -35,25 +33,18 @@ import com.sk89q.worldguard.bukkit.util.Entities; import com.sk89q.worldguard.bukkit.util.Materials; import com.sk89q.worldguard.domains.Association; -import com.sk89q.worldguard.protection.ApplicableRegionSet; import com.sk89q.worldguard.protection.association.Associables; import com.sk89q.worldguard.protection.association.RegionAssociable; -import com.sk89q.worldguard.protection.association.RegionOverlapAssociation; import com.sk89q.worldguard.protection.flags.DefaultFlag; -import com.sk89q.worldguard.protection.flags.StateFlag; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; -import org.bukkit.entity.Creeper; -import org.bukkit.entity.EnderDragon; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; -import javax.annotation.Nullable; - /** * Handle events that need to be processed by region protection. */ @@ -92,22 +83,6 @@ private boolean isWhitelisted(Cause cause) { return false; } - /** - * Create a new predicate to test a state flag for each location. - * - * @param query the query - * @param flag the flag - * @return a predicate - */ - private Predicate createStateTest(final RegionQuery query, final StateFlag flag) { - return new Predicate() { - @Override - public boolean apply(@Nullable Location location) { - return query.testState(location, null, flag); - } - }; - } - private RegionAssociable createRegionAssociable(Cause cause) { Object rootCause = cause.getRootCause(); @@ -134,7 +109,7 @@ public void onPlaceBlock(final PlaceBlockEvent event) { final RegionQuery query = getPlugin().getRegionContainer().createQuery(); final RegionAssociable associable = createRegionAssociable(event.getCause()); - event.filterBlocks(new Predicate() { + event.filter(new Predicate() { @Override public boolean apply(Location target) { boolean canPlace; @@ -163,32 +138,12 @@ public void onBreakBlock(final BreakBlockEvent event) { return; // Whitelisted cause } - ConfigurationManager globalConfig = getPlugin().getGlobalStateManager(); - WorldConfiguration config = globalConfig.get(event.getWorld()); final RegionQuery query = getPlugin().getRegionContainer().createQuery(); - // TODO: Move this to another event handler - Entity entity; - if ((entity = event.getCause().getEntityRootCause()) != null) { - // Creeper - if (entity instanceof Creeper) { - event.filterBlocks(createStateTest(query, DefaultFlag.CREEPER_EXPLOSION), config.explosionFlagCancellation); - - // Enderdragon - } else if (entity instanceof EnderDragon) { - event.filterBlocks(createStateTest(query, DefaultFlag.ENDERDRAGON_BLOCK_DAMAGE), config.explosionFlagCancellation); - - // TNT + explosive TNT carts - } else if (Entities.isTNTBased(entity)) { - event.filterBlocks(createStateTest(query, DefaultFlag.TNT), config.explosionFlagCancellation); - - } - } - if (!event.isCancelled()) { final RegionAssociable associable = createRegionAssociable(event.getCause()); - event.filterBlocks(new Predicate() { + event.filter(new Predicate() { @Override public boolean apply(Location target) { boolean canBreak = query.testBuild(target, associable); @@ -214,7 +169,7 @@ public void onUseBlock(final UseBlockEvent event) { final RegionQuery query = getPlugin().getRegionContainer().createQuery(); final RegionAssociable associable = createRegionAssociable(event.getCause()); - event.filterBlocks(new Predicate() { + event.filter(new Predicate() { @Override public boolean apply(Location target) { boolean canUse; @@ -223,15 +178,15 @@ public boolean apply(Location target) { if (Materials.isInventoryBlock(type)) { canUse = query.testBuild(target, associable, DefaultFlag.USE, DefaultFlag.CHEST_ACCESS); - // Beds (SLEEP) + // Beds (SLEEP) } else if (type == Material.BED) { canUse = query.testBuild(target, associable, DefaultFlag.USE, DefaultFlag.SLEEP); - // TNT (TNT) + // TNT (TNT) } else if (type == Material.TNT) { canUse = query.testBuild(target, associable, DefaultFlag.TNT); - // Everything else + // Everything else } else { canUse = query.testBuild(target, associable, DefaultFlag.USE); } diff --git a/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardBlockListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardBlockListener.java index c5fb85b4..d8667a86 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardBlockListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardBlockListener.java @@ -37,7 +37,6 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBurnEvent; -import org.bukkit.event.block.BlockExpEvent; import org.bukkit.event.block.BlockFadeEvent; import org.bukkit.event.block.BlockFormEvent; import org.bukkit.event.block.BlockFromToEvent; @@ -706,17 +705,4 @@ public void onBlockPistonRetract(BlockPistonRetractEvent event) { } } - /* - * Called when a block yields exp - */ - @EventHandler(priority = EventPriority.HIGH) - public void onBlockExp(BlockExpEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); - if (wcfg.disableExpDrops || !plugin.getGlobalRegionManager().allows(DefaultFlag.EXP_DROPS, - event.getBlock().getLocation())) { - event.setExpToDrop(0); - } - } - }