Create RegionFlagsListener and rename some methods.

This commit is contained in:
sk89q 2014-08-18 19:15:40 -07:00
parent bb64079d17
commit 985629c196
9 changed files with 149 additions and 78 deletions

View File

@ -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"))) {

View File

@ -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;

View File

@ -103,7 +103,7 @@ public List<Block> getBlocks() {
* list once the predicate returns {@code false}
* @return true if one or more blocks were filtered out
*/
public boolean filterBlocks(Predicate<Location> predicate, boolean cancelEventOnFalse) {
public boolean filter(Predicate<Location> predicate, boolean cancelEventOnFalse) {
boolean hasRemoval = false;
Iterator<Block> it = blocks.iterator();
@ -130,14 +130,14 @@ public boolean filterBlocks(Predicate<Location> predicate, boolean cancelEventOn
*
* <p>This method will <strong>not</strong> 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.</p>
*
* @param predicate the predicate
* @return true if one or more blocks were filtered out
*/
public boolean filterBlocks(Predicate<Location> predicate) {
return filterBlocks(predicate, false);
public boolean filter(Predicate<Location> predicate) {
return filter(predicate, false);
}
/**

View File

@ -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<Location> predicate, boolean cancelEventOnFalse) {
if (!isCancelled()) {
if (!predicate.apply(getTarget())) {
setCancelled(true);
}
}
return isCancelled();
}
}

View File

@ -84,7 +84,7 @@ public void onBreakBlock(final BreakBlockEvent event) {
return;
}
event.filterBlocks(new Predicate<Location>() {
event.filter(new Predicate<Location>() {
@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<Location>() {
event.filter(new Predicate<Location>() {
@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<Location>() {
event.filter(new Predicate<Location>() {
@Override
public boolean apply(Location target) {
return wcfg.getBlacklist().check(new BlockInteractBlacklistEvent(

View File

@ -58,7 +58,7 @@ public void onPlaceBlock(final PlaceBlockEvent event) {
return;
}
event.filterBlocks(new Predicate<Location>() {
event.filter(new Predicate<Location>() {
@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<Location>() {
event.filter(new Predicate<Location>() {
@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<Location>() {
event.filter(new Predicate<Location>() {
@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<Location>() {
event.filter(new Predicate<Location>() {
@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<Location>() {
event.filter(new Predicate<Location>() {
@Override
public boolean apply(Location target) {
return !wcfg.isChestProtected(target.getBlock());

View File

@ -0,0 +1,98 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
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<Location> testState(final RegionQuery query, final StateFlag flag) {
return new Predicate<Location>() {
@Override
public boolean apply(@Nullable Location location) {
return query.testState(location, null, flag);
}
};
}
}

View File

@ -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<Location> createStateTest(final RegionQuery query, final StateFlag flag) {
return new Predicate<Location>() {
@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<Location>() {
event.filter(new Predicate<Location>() {
@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<Location>() {
event.filter(new Predicate<Location>() {
@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<Location>() {
event.filter(new Predicate<Location>() {
@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);
}

View File

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