Merge branch 'feature/event-abstraction' into feature/region-api-update

This commit is contained in:
sk89q 2014-08-12 19:49:52 -07:00
commit 989ce82c5d
46 changed files with 5791 additions and 4538 deletions

View File

@ -42,6 +42,7 @@
import org.bukkit.entity.Tameable;
import org.bukkit.inventory.ItemStack;
import javax.annotation.Nullable;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
@ -312,6 +313,22 @@ public static Target createTarget(Block block) {
return new MaterialTarget(block.getTypeId(), block.getData());
}
/**
* Get a blacklist target for the given block.
*
* @param block the block
* @param material a fallback material
* @return a target
*/
public static Target createTarget(@Nullable Block block, Material material) {
checkNotNull(material);
if (block != null) {
return new MaterialTarget(block.getTypeId(), block.getData());
} else {
return new MaterialTarget(material.getId(), (short) 0);
}
}
/**
* Get a blacklist target for the given item.
*

View File

@ -1,216 +0,0 @@
/*
* 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;
import com.sk89q.worldedit.blocks.ItemID;
import com.sk89q.worldguard.blacklist.event.BlockBreakBlacklistEvent;
import com.sk89q.worldguard.blacklist.event.ItemUseBlacklistEvent;
import com.sk89q.worldguard.blacklist.target.MaterialTarget;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Hanging;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Painting;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
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.event.player.PlayerInteractEntityEvent;
import org.bukkit.projectiles.ProjectileSource;
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
/**
* Listener for painting related events.
*
* @author BangL <henno.rickowski@gmail.com>
*/
public class WorldGuardHangingListener implements Listener {
private WorldGuardPlugin plugin;
/**
* Construct the object;
*
* @param plugin The plugin instance
*/
public WorldGuardHangingListener(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
/**
* Register events.
*/
public void registerEvents() {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onHangingingBreak(HangingBreakEvent event) {
Hanging hanging = event.getEntity();
World world = hanging.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
if (event instanceof HangingBreakByEntityEvent) {
HangingBreakByEntityEvent entityEvent = (HangingBreakByEntityEvent) event;
Entity removerEntity = entityEvent.getRemover();
if (removerEntity instanceof Projectile) {
Projectile projectile = (Projectile) removerEntity;
ProjectileSource remover = projectile.getShooter();
removerEntity = (remover instanceof LivingEntity ? (LivingEntity) remover : null);
}
if (removerEntity instanceof Player) {
Player player = (Player) removerEntity;
if (wcfg.getBlacklist() != null) {
if (hanging instanceof Painting
&& !wcfg.getBlacklist().check(
new BlockBreakBlacklistEvent(plugin.wrapPlayer(player),
toVector(player.getLocation()), new MaterialTarget(ItemID.PAINTING, (short) 0)), false, false)) {
event.setCancelled(true);
return;
} else if (hanging instanceof ItemFrame
&& !wcfg.getBlacklist().check(
new BlockBreakBlacklistEvent(plugin.wrapPlayer(player),
toVector(player.getLocation()), new MaterialTarget(ItemID.ITEM_FRAME, (short) 0)), false, false)) {
event.setCancelled(true);
return;
}
}
if (wcfg.useRegions) {
if (!plugin.getGlobalRegionManager().canBuild(player, hanging.getLocation())) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
event.setCancelled(true);
return;
}
}
} else {
if (removerEntity instanceof Creeper) {
if (wcfg.blockCreeperBlockDamage || wcfg.blockCreeperExplosions) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows(DefaultFlag.CREEPER_EXPLOSION, hanging.getLocation())) {
event.setCancelled(true);
return;
}
}
// this now covers dispensers as well, if removerEntity is null above,
// due to a non-LivingEntity ProjectileSource
if (hanging instanceof Painting
&& (wcfg.blockEntityPaintingDestroy
|| (wcfg.useRegions
&& !plugin.getGlobalRegionManager().allows(DefaultFlag.ENTITY_PAINTING_DESTROY, hanging.getLocation())))) {
event.setCancelled(true);
} else if (hanging instanceof ItemFrame
&& (wcfg.blockEntityItemFrameDestroy
|| (wcfg.useRegions
&& !plugin.getGlobalRegionManager().allows(DefaultFlag.ENTITY_ITEM_FRAME_DESTROY, hanging.getLocation())))) {
event.setCancelled(true);
}
}
} else {
// Explosions from mobs are not covered by HangingBreakByEntity
if (hanging instanceof Painting && wcfg.blockEntityPaintingDestroy
&& event.getCause() == RemoveCause.EXPLOSION) {
event.setCancelled(true);
} else if (hanging instanceof ItemFrame && wcfg.blockEntityItemFrameDestroy
&& event.getCause() == RemoveCause.EXPLOSION) {
event.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onHangingPlace(HangingPlaceEvent event) {
Block placedOn = event.getBlock();
Player player = event.getPlayer();
World world = placedOn.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
if (wcfg.getBlacklist() != null) {
if (event.getEntity() instanceof Painting
&& !wcfg.getBlacklist().check(
new ItemUseBlacklistEvent(plugin.wrapPlayer(player),
toVector(player.getLocation()), new MaterialTarget(ItemID.PAINTING, (short) 0)), false, false)) {
event.setCancelled(true);
return;
} else if (event.getEntity() instanceof ItemFrame
&& !wcfg.getBlacklist().check(
new ItemUseBlacklistEvent(plugin.wrapPlayer(player),
toVector(player.getLocation()), new MaterialTarget(ItemID.ITEM_FRAME, (short) 0)), false, false)) {
event.setCancelled(true);
return;
}
}
if (wcfg.useRegions) {
if (!plugin.getGlobalRegionManager().canBuild(player, placedOn.getRelative(event.getBlockFace()))) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
event.setCancelled(true);
return;
}
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onEntityInteract(PlayerInteractEntityEvent event) {
Player player = event.getPlayer();
Entity entity = event.getRightClicked();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(entity.getWorld());
if (wcfg.useRegions && (entity instanceof ItemFrame || entity instanceof Painting)) {
if (!plugin.getGlobalRegionManager().canBuild(player, entity.getLocation())) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
event.setCancelled(true);
return;
}
// if (entity instanceof ItemFrame
// && ((!plugin.getGlobalRegionManager().allows(
// DefaultFlag.ENTITY_ITEM_FRAME_DESTROY, entity.getLocation())))) {
// event.setCancelled(true);
// } else if (entity instanceof Painting
// && ((!plugin.getGlobalRegionManager().allows(
// DefaultFlag.ENTITY_PAINTING_DESTROY, entity.getLocation())))) {
// event.setCancelled(true);
// }
}
}
}

View File

@ -48,10 +48,21 @@
import com.sk89q.worldguard.bukkit.commands.GeneralCommands;
import com.sk89q.worldguard.bukkit.commands.ProtectionCommands;
import com.sk89q.worldguard.bukkit.commands.ToggleCommands;
import com.sk89q.worldguard.internal.listener.BlacklistListener;
import com.sk89q.worldguard.internal.listener.BlockedPotionsListener;
import com.sk89q.worldguard.internal.listener.ChestProtectionListener;
import com.sk89q.worldguard.internal.listener.RegionProtectionListener;
import com.sk89q.worldguard.bukkit.listener.BlacklistListener;
import com.sk89q.worldguard.bukkit.listener.BlockedPotionsListener;
import com.sk89q.worldguard.bukkit.listener.ChestProtectionListener;
import com.sk89q.worldguard.bukkit.listener.DebuggingListener;
import com.sk89q.worldguard.bukkit.listener.EventAbstractionListener;
import com.sk89q.worldguard.bukkit.listener.RegionProtectionListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardBlockListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardCommandBookListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardEntityListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardHangingListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardPlayerListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardServerListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardVehicleListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardWeatherListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardWorldListener;
import com.sk89q.worldguard.protection.GlobalRegionManager;
import com.sk89q.worldguard.protection.util.migrator.MigrationException;
import com.sk89q.worldguard.protection.util.migrator.UUIDMigrator;
@ -218,6 +229,8 @@ public void run() {
(new ChestProtectionListener(this)).registerEvents();
(new RegionProtectionListener(this)).registerEvents();
(new BlockedPotionsListener(this)).registerEvents();
(new EventAbstractionListener(this)).registerEvents();
(new DebuggingListener(this, getLogger())).registerEvents();
configuration.updateCommandBookGodMode();

View File

@ -0,0 +1,132 @@
/*
* 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.cause;
import com.google.common.base.Joiner;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* An instance of this object describes the actors that played a role in
* causing an event, with the ability to describe a situation where one actor
* controls several other actors to create the event.
*
* <p>For example, if a player fires an arrow that hits an item frame, the player
* is the initiator, while the arrow is merely controlled by the player to
* hit the item frame.</p>
*/
public class Cause {
private static final Cause UNKNOWN = new Cause(Collections.emptyList());
private final List<Object> causes;
/**
* Create a new instance.
*
* @param causes a list of causes
*/
private Cause(List<Object> causes) {
checkNotNull(causes);
this.causes = causes;
}
/**
* Return whether a cause is known.
*
* @return true if known
*/
public boolean isKnown() {
return !causes.isEmpty();
}
@Nullable
public Player getPlayerRootCause() {
for (Object object : causes) {
if (object instanceof Player) {
return (Player) object;
}
}
return null;
}
@Override
public String toString() {
return Joiner.on(" | ").join(causes);
}
/**
* Expand an cause object.
*
* @param list the list to add elements to
* @param element an array of objects
*/
private static void expand(List<Object> list, @Nullable Object ... element) {
if (element != null) {
for (Object o : element) {
if (o == null) {
continue;
}
if (o instanceof Projectile) {
expand(list, ((Projectile) o).getShooter());
} else {
list.add(o);
}
}
}
}
/**
* Create a new instance with the given objects as the cause,
* where the first-most object is the initial initiator and those
* following it are controlled by the previous entry.
*
* @param cause an array of causing objects
* @return a cause
*/
public static Cause create(@Nullable Object ... cause) {
if (cause != null) {
List<Object> causes = new ArrayList<Object>(cause.length);
expand(causes, cause);
return new Cause(causes);
} else {
return UNKNOWN;
}
}
/**
* Create a new instance that indicates that the cause is not known.
*
* @return a cause
*/
public static Cause unknown() {
return UNKNOWN;
}
}

View File

@ -17,38 +17,31 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.internal.event;
package com.sk89q.worldguard.bukkit.event;
import com.sk89q.worldguard.internal.cause.Cause;
import com.sk89q.worldguard.bukkit.cause.Cause;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import java.util.Collections;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
abstract class AbstractInteractEvent extends Event implements Cancellable {
public abstract class AbstractInteractEvent extends Event implements Cancellable {
private final Event originalEvent;
private final List<? extends Cause<?>> causes;
private final Interaction interaction;
private final Cause cause;
private boolean cancelled;
/**
* Create a new instance
*
* @param originalEvent the original event
* @param causes a list of causes, where the originating causes are at the beginning
* @param interaction the action that is being taken
* @param cause the cause
*/
protected AbstractInteractEvent(Event originalEvent, List<? extends Cause<?>> causes, Interaction interaction) {
protected AbstractInteractEvent(Event originalEvent, Cause cause) {
checkNotNull(originalEvent);
checkNotNull(causes);
checkNotNull(interaction);
checkNotNull(cause);
this.originalEvent = originalEvent;
this.causes = causes;
this.interaction = interaction;
this.cause = cause;
}
/**
@ -61,22 +54,12 @@ public Event getOriginalEvent() {
}
/**
* Return an unmodifiable list of causes, where the originating causes are
* at the beginning of the list.
* Return the cause.
*
* @return a list of causes
* @return the cause
*/
public List<? extends Cause<?>> getCauses() {
return Collections.unmodifiableList(causes);
}
/**
* Get the action that is being taken.
*
* @return the action
*/
public Interaction getInteraction() {
return interaction;
public Cause getCause() {
return cause;
}
@Override

View File

@ -0,0 +1,84 @@
/*
* 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.event.block;
import com.sk89q.worldguard.bukkit.cause.Cause;
import com.sk89q.worldguard.bukkit.event.AbstractInteractEvent;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.Event;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
abstract class AbstractBlockEvent extends AbstractInteractEvent {
private final Location target;
@Nullable
private final Block block;
private final Material effectiveMaterial;
protected AbstractBlockEvent(Event originalEvent, Cause cause, Block block) {
super(originalEvent, cause);
checkNotNull(block);
this.target = block.getLocation();
this.block = block;
this.effectiveMaterial = block.getType();
}
protected AbstractBlockEvent(Event originalEvent, Cause cause, Location target, Material effectiveMaterial) {
super(originalEvent, cause);
this.target = target;
this.block = null;
this.effectiveMaterial = effectiveMaterial;
}
/**
* Get the target block being affected.
*
* @return a block
*/
public Location getTarget() {
return target;
}
/**
* Get the block.
*
* @return the block
*/
@Nullable
public Block getBlock() {
return block;
}
/**
* Get the effective material of the block, regardless of what the block
* currently is.
*
* @return the effective material
*/
public Material getEffectiveMaterial() {
return effectiveMaterial;
}
}

View File

@ -17,32 +17,34 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.internal.cause;
package com.sk89q.worldguard.bukkit.event.block;
import com.sk89q.worldguard.bukkit.cause.Cause;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* A cause that is a block.
*/
import static com.google.common.base.Preconditions.checkNotNull;
public class BreakBlockEvent extends AbstractBlockEvent {
public class BlockCause implements Cause<Block> {
private static final HandlerList handlers = new HandlerList();
private final Block block;
public BreakBlockEvent(Event originalEvent, Cause cause, Block block) {
super(originalEvent, cause, block);
}
/**
* Create a new instance.
*
* @param block the block
*/
public BlockCause(Block block) {
checkNotNull(block);
this.block = block;
public BreakBlockEvent(Event originalEvent, Cause cause, Location target, Material effectiveMaterial) {
super(originalEvent, cause, target, effectiveMaterial);
}
@Override
public Block get() {
return block;
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@ -0,0 +1,50 @@
/*
* 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.event.block;
import com.sk89q.worldguard.bukkit.cause.Cause;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class PlaceBlockEvent extends AbstractBlockEvent {
private static final HandlerList handlers = new HandlerList();
public PlaceBlockEvent(Event originalEvent, Cause cause, Block block) {
super(originalEvent, cause, block);
}
public PlaceBlockEvent(Event originalEvent, Cause cause, Location target, Material effectiveMaterial) {
super(originalEvent, cause, target, effectiveMaterial);
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@ -0,0 +1,53 @@
/*
* 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.event.block;
import com.sk89q.worldguard.bukkit.cause.Cause;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* Fired when a block is interacted with.
*/
public class UseBlockEvent extends AbstractBlockEvent {
private static final HandlerList handlers = new HandlerList();
public UseBlockEvent(Event originalEvent, Cause cause, Block block) {
super(originalEvent, cause, block);
}
public UseBlockEvent(Event originalEvent, Cause cause, Location target, Material effectiveMaterial) {
super(originalEvent, cause, target, effectiveMaterial);
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@ -0,0 +1,72 @@
/*
* 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.event.entity;
import com.sk89q.worldguard.bukkit.cause.Cause;
import com.sk89q.worldguard.bukkit.event.AbstractInteractEvent;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.event.Event;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
abstract class AbstractEntityEvent extends AbstractInteractEvent {
private final Location target;
@Nullable
private final Entity entity;
protected AbstractEntityEvent(Event originalEvent, Cause cause, Entity entity) {
super(originalEvent, cause);
checkNotNull(entity);
this.target = entity.getLocation();
this.entity = entity;
}
protected AbstractEntityEvent(Event originalEvent, Cause cause, Location target) {
super(originalEvent, cause);
checkNotNull(target);
this.target = target;
this.entity = null;
}
/**
* Get the target location being affected.
*
* @return a location
*/
public Location getTarget() {
return target;
}
/**
* Get the target entity being affected.
*
* @return a entity
*/
@Nullable
public Entity getEntity() {
return entity;
}
}

View File

@ -17,32 +17,38 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.internal.cause;
package com.sk89q.worldguard.bukkit.event.entity;
import com.sk89q.worldguard.bukkit.cause.Cause;
import org.bukkit.entity.Entity;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import javax.annotation.Nonnull;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A cause that is an entity.
*/
public class EntityCause implements Cause<Entity> {
public class DestroyEntityEvent extends AbstractEntityEvent {
private final Entity entity;
private static final HandlerList handlers = new HandlerList();
/**
* Create a new instance.
*
* @param entity the entity
*/
public EntityCause(Entity entity) {
checkNotNull(entity);
this.entity = entity;
public DestroyEntityEvent(Event originalEvent, Cause cause, Entity target) {
super(originalEvent, cause, checkNotNull(target));
}
@Override
public Entity get() {
return entity;
@Nonnull
public Entity getEntity() {
return super.getEntity();
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@ -17,46 +17,40 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.internal.event;
package com.sk89q.worldguard.bukkit.event.entity;
import com.sk89q.worldguard.internal.cause.Cause;
import org.bukkit.block.Block;
import com.sk89q.worldguard.bukkit.cause.Cause;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Fired when a block is interacted with.
*/
public class BlockInteractEvent extends AbstractInteractEvent {
public class SpawnEntityEvent extends AbstractEntityEvent {
private static final HandlerList handlers = new HandlerList();
private final Block target;
private final EntityType effectiveType;
/**
* Create a new instance.
*
* @param originalEvent the original event
* @param causes a list of causes, where the originating causes are at the beginning
* @param interaction the action that is being taken
* @param target the target block being affected
*/
public BlockInteractEvent(Event originalEvent, List<? extends Cause<?>> causes, Interaction interaction, Block target) {
super(originalEvent, causes, interaction);
checkNotNull(target);
this.target = target;
public SpawnEntityEvent(Event originalEvent, Cause cause, Entity target) {
super(originalEvent, cause, checkNotNull(target));
this.effectiveType = target.getType();
}
public SpawnEntityEvent(Event originalEvent, Cause cause, Location location, EntityType type) {
super(originalEvent, cause, location);
checkNotNull(type);
this.effectiveType = type;
}
/**
* Get the target block being affected.
* Get the effective entity type of the spawned entity.
*
* @return a block
* @return the effective type
*/
public Block getTarget() {
return target;
public EntityType getEffectiveType() {
return effectiveType;
}
@Override

View File

@ -17,46 +17,32 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.internal.event;
package com.sk89q.worldguard.bukkit.event.entity;
import com.sk89q.worldguard.internal.cause.Cause;
import com.sk89q.worldguard.bukkit.cause.Cause;
import org.bukkit.entity.Entity;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import java.util.List;
import javax.annotation.Nonnull;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Fired when an entity is interacted with.
*/
public class EntityInteractEvent extends AbstractInteractEvent {
public class UseEntityEvent extends AbstractEntityEvent {
private static final HandlerList handlers = new HandlerList();
private final Entity target;
/**
* Create a new instance.
*
* @param originalEvent the original event
* @param causes a list of causes, where the originating causes are at the beginning
* @param interaction the action that is being taken
* @param target the target entity being affected
*/
public EntityInteractEvent(Event originalEvent, List<? extends Cause<?>> causes, Interaction interaction, Entity target) {
super(originalEvent, causes, interaction);
checkNotNull(target);
this.target = target;
public UseEntityEvent(Event originalEvent, Cause cause, Entity target) {
super(originalEvent, cause, checkNotNull(target));
}
/**
* Get the target entity.
*
* @return the target entity
*/
public Entity getTarget() {
return target;
@Override
@Nonnull
public Entity getEntity() {
return super.getEntity();
}
@Override
@ -67,4 +53,5 @@ public HandlerList getHandlers() {
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@ -17,38 +17,28 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.internal.event;
package com.sk89q.worldguard.bukkit.event.inventory;
import com.sk89q.worldguard.internal.cause.Cause;
import com.sk89q.worldguard.bukkit.cause.Cause;
import com.sk89q.worldguard.bukkit.event.AbstractInteractEvent;
import org.bukkit.World;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Fired when an item is interacted with.
*/
public class ItemInteractEvent extends AbstractInteractEvent {
public class UseItemEvent extends AbstractInteractEvent {
private static final HandlerList handlers = new HandlerList();
private final World world;
private final ItemStack itemStack;
/**
* Create a new instance.
*
* @param originalEvent the original event
* @param causes a list of causes, where the originating causes are at the beginning
* @param interaction the action that is being taken
* @param world the world
* @param itemStack the item
*/
public ItemInteractEvent(Event originalEvent, List<? extends Cause<?>> causes, Interaction interaction, World world, ItemStack itemStack) {
super(originalEvent, causes, interaction);
public UseItemEvent(Event originalEvent, Cause cause, World world, ItemStack itemStack) {
super(originalEvent, cause);
checkNotNull(world);
checkNotNull(itemStack);
this.world = world;

View File

@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.internal.listener;
package com.sk89q.worldguard.bukkit.listener;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;

View File

@ -0,0 +1,258 @@
/*
* 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.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.blacklist.event.BlockBreakBlacklistEvent;
import com.sk89q.worldguard.blacklist.event.BlockDispenseBlacklistEvent;
import com.sk89q.worldguard.blacklist.event.BlockInteractBlacklistEvent;
import com.sk89q.worldguard.blacklist.event.BlockPlaceBlacklistEvent;
import com.sk89q.worldguard.blacklist.event.ItemAcquireBlacklistEvent;
import com.sk89q.worldguard.blacklist.event.ItemDestroyWithBlacklistEvent;
import com.sk89q.worldguard.blacklist.event.ItemDropBlacklistEvent;
import com.sk89q.worldguard.blacklist.event.ItemUseBlacklistEvent;
import com.sk89q.worldguard.bukkit.ConfigurationManager;
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.block.PlaceBlockEvent;
import com.sk89q.worldguard.bukkit.event.block.UseBlockEvent;
import com.sk89q.worldguard.bukkit.event.entity.DestroyEntityEvent;
import com.sk89q.worldguard.bukkit.event.entity.SpawnEntityEvent;
import com.sk89q.worldguard.bukkit.event.inventory.UseItemEvent;
import com.sk89q.worldguard.bukkit.util.Materials;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockDispenseEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.inventory.ItemStack;
import static com.sk89q.worldguard.bukkit.BukkitUtil.createTarget;
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
/**
* Handle events that need to be processed by the blacklist.
*/
public class BlacklistListener extends AbstractListener {
/**
* Construct the listener.
*
* @param plugin an instance of WorldGuardPlugin
*/
public BlacklistListener(WorldGuardPlugin plugin) {
super(plugin);
}
@EventHandler(ignoreCancelled = true)
public void onBreakBlock(BreakBlockEvent event) {
Player player = event.getCause().getPlayerRootCause();
if (player == null) {
return;
}
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
Block target = event.getBlock();
WorldConfiguration wcfg = getWorldConfig(player);
// Blacklist guard
if (wcfg.getBlacklist() == null) {
return;
}
if (!wcfg.getBlacklist().check(
new BlockBreakBlacklistEvent(localPlayer, toVector(event.getTarget()), createTarget(target, event.getEffectiveMaterial())), false, false)) {
event.setCancelled(true);
} else if (!wcfg.getBlacklist().check(
new ItemDestroyWithBlacklistEvent(localPlayer, toVector(event.getTarget()), createTarget(player.getItemInHand())), false, false)) {
event.setCancelled(true);
}
}
@EventHandler(ignoreCancelled = true)
public void onPlaceBlock(PlaceBlockEvent event) {
Player player = event.getCause().getPlayerRootCause();
if (player == null) {
return;
}
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
Block target = event.getBlock();
WorldConfiguration wcfg = getWorldConfig(player);
// Blacklist guard
if (wcfg.getBlacklist() == null) {
return;
}
if (!wcfg.getBlacklist().check(new BlockPlaceBlacklistEvent(
localPlayer, toVector(event.getTarget()), createTarget(target, event.getEffectiveMaterial())), false, false)) {
event.setCancelled(true);
}
}
@EventHandler(ignoreCancelled = true)
public void onUseBlock(UseBlockEvent event) {
Player player = event.getCause().getPlayerRootCause();
if (player == null) {
return;
}
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
Block target = event.getBlock();
WorldConfiguration wcfg = getWorldConfig(player);
// Blacklist guard
if (wcfg.getBlacklist() == null) {
return;
}
if (!wcfg.getBlacklist().check(new BlockInteractBlacklistEvent(
localPlayer, toVector(event.getTarget()), createTarget(target, event.getEffectiveMaterial())), false, false)) {
event.setCancelled(true);
}
}
@EventHandler(ignoreCancelled = true)
public void onSpawnEntity(SpawnEntityEvent event) {
Player player = event.getCause().getPlayerRootCause();
if (player == null) {
return;
}
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
WorldConfiguration wcfg = getWorldConfig(player);
// Blacklist guard
if (wcfg.getBlacklist() == null) {
return;
}
Material material = Materials.getRelatedMaterial(event.getEffectiveType());
if (material != null) {
if (!wcfg.getBlacklist().check(new ItemUseBlacklistEvent(localPlayer, toVector(event.getTarget()), createTarget(material)), false, false)) {
event.setCancelled(true);
}
}
}
@EventHandler(ignoreCancelled = true)
public void onDestroyEntity(DestroyEntityEvent event) {
Player player = event.getCause().getPlayerRootCause();
if (player == null) {
return;
}
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
Entity target = event.getEntity();
WorldConfiguration wcfg = getWorldConfig(player);
// Blacklist guard
if (wcfg.getBlacklist() == null) {
return;
}
Material material = Materials.getRelatedMaterial(target.getType());
if (material != null) {
// Not really a block but we only have one on-break blacklist event
if (!wcfg.getBlacklist().check(new BlockBreakBlacklistEvent(localPlayer, toVector(event.getTarget()), createTarget(material)), false, false)) {
event.setCancelled(true);
}
}
}
@EventHandler(ignoreCancelled = true)
public void onUseItem(UseItemEvent event) {
Player player = event.getCause().getPlayerRootCause();
if (player == null) {
return;
}
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
ItemStack target = event.getItemStack();
WorldConfiguration wcfg = getWorldConfig(player);
// Blacklist guard
if (wcfg.getBlacklist() == null) {
return;
}
if (!wcfg.getBlacklist().check(new ItemUseBlacklistEvent(localPlayer, toVector(player.getLocation()), createTarget(target)), false, false)) {
event.setCancelled(true);
}
}
@EventHandler(ignoreCancelled = true)
public void onPlayerDropItem(PlayerDropItemEvent event) {
ConfigurationManager cfg = getPlugin().getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getPlayer().getWorld());
if (wcfg.getBlacklist() != null) {
Item ci = event.getItemDrop();
if (!wcfg.getBlacklist().check(
new ItemDropBlacklistEvent(getPlugin().wrapPlayer(event.getPlayer()),
toVector(ci.getLocation()), createTarget(ci.getItemStack())), false, false)) {
event.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onPlayerPickupItem(PlayerPickupItemEvent event) {
ConfigurationManager cfg = getPlugin().getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getPlayer().getWorld());
if (wcfg.getBlacklist() != null) {
Item ci = event.getItem();
if (!wcfg.getBlacklist().check(
new ItemAcquireBlacklistEvent(getPlugin().wrapPlayer(event.getPlayer()),
toVector(ci.getLocation()), createTarget(ci.getItemStack())), false, true)) {
event.setCancelled(true);
}
}
}
@EventHandler(ignoreCancelled = true)
public void onBlockDispense(BlockDispenseEvent event) {
ConfigurationManager cfg = getPlugin().getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
if (wcfg.getBlacklist() != null) {
if (!wcfg.getBlacklist().check(new BlockDispenseBlacklistEvent(null, toVector(event.getBlock()), createTarget(event.getItem())), false, false)) {
event.setCancelled(true);
}
}
}
}

View File

@ -17,14 +17,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.internal.listener;
package com.sk89q.worldguard.bukkit.listener;
import com.sk89q.worldguard.bukkit.BukkitUtil;
import com.sk89q.worldguard.bukkit.ConfigurationManager;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.internal.cause.Causes;
import com.sk89q.worldguard.internal.event.ItemInteractEvent;
import com.sk89q.worldguard.bukkit.event.inventory.UseItemEvent;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@ -49,9 +48,9 @@ public BlockedPotionsListener(WorldGuardPlugin plugin) {
}
@EventHandler
public void onItemInteract(ItemInteractEvent event) {
public void onItemInteract(UseItemEvent event) {
// We only care about player caused events
if (!Causes.mayInvolvePlayer(event.getCauses())) {
if (event.getCause().getPlayerRootCause() == null) {
return;
}
@ -84,7 +83,7 @@ public void onItemInteract(ItemInteractEvent event) {
}
if (blockedEffect != null) {
Player player = Causes.getInvolvedPlayer(event.getCauses());
Player player = event.getCause().getPlayerRootCause();
if (player != null) {
if (getPlugin().hasPermission(player, "worldguard.override.potions")) {

View File

@ -0,0 +1,177 @@
/*
* 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.sk89q.worldedit.blocks.BlockID;
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.block.PlaceBlockEvent;
import com.sk89q.worldguard.bukkit.event.block.UseBlockEvent;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.SignChangeEvent;
/**
* Handle events that need to be processed by the chest protection.
*/
public class ChestProtectionListener extends AbstractListener {
/**
* Construct the listener.
*
* @param plugin an instance of WorldGuardPlugin
*/
public ChestProtectionListener(WorldGuardPlugin plugin) {
super(plugin);
}
@EventHandler(ignoreCancelled = true)
public void onPlaceBlock(PlaceBlockEvent event) {
Player player = event.getCause().getPlayerRootCause();
Location target = event.getTarget();
if (player != null) {
WorldConfiguration wcfg = getWorldConfig(player);
// Early guard
if (!wcfg.signChestProtection) {
return;
}
if (wcfg.getChestProtection().isChest(event.getEffectiveMaterial().getId()) && wcfg.isChestProtected(target.getBlock(), player)) {
player.sendMessage(ChatColor.DARK_RED + "This spot is for a chest that you don't have permission for.");
event.setCancelled(true);
}
}
}
@EventHandler(ignoreCancelled = true)
public void onBreakBlock(BreakBlockEvent event) {
Player player = event.getCause().getPlayerRootCause();
Location target = event.getTarget();
WorldConfiguration wcfg = getWorldConfig(target.getWorld());
// Early guard
if (!wcfg.signChestProtection) {
return;
}
if (player != null) {
if (wcfg.isChestProtected(target.getBlock(), player)) {
player.sendMessage(ChatColor.DARK_RED + "This chest is protected.");
event.setCancelled(true);
}
} else {
if (wcfg.isChestProtected(target.getBlock())) {
// No player? Deny anyway
event.setCancelled(true);
}
}
}
@EventHandler(ignoreCancelled = true)
public void onUseBlock(UseBlockEvent event) {
Player player = event.getCause().getPlayerRootCause();
Location target = event.getTarget();
WorldConfiguration wcfg = getWorldConfig(target.getWorld());
// Early guard
if (!wcfg.signChestProtection) {
return;
}
if (player != null) {
if (wcfg.isChestProtected(target.getBlock(), player)) {
player.sendMessage(ChatColor.DARK_RED + "This chest is protected.");
event.setCancelled(true);
}
} else {
if (wcfg.isChestProtected(target.getBlock())) {
// No player? Deny anyway
event.setCancelled(true);
}
}
}
@EventHandler(ignoreCancelled = true)
public void onSignChange(SignChangeEvent event) {
Player player = event.getPlayer();
WorldConfiguration wcfg = getWorldConfig(player);
if (wcfg.signChestProtection) {
if (event.getLine(0).equalsIgnoreCase("[Lock]")) {
if (wcfg.isChestProtectedPlacement(event.getBlock(), player)) {
player.sendMessage(ChatColor.DARK_RED + "You do not own the adjacent chest.");
event.getBlock().breakNaturally();
event.setCancelled(true);
return;
}
if (event.getBlock().getTypeId() != BlockID.SIGN_POST) {
player.sendMessage(ChatColor.RED
+ "The [Lock] sign must be a sign post, not a wall sign.");
event.getBlock().breakNaturally();
event.setCancelled(true);
return;
}
if (!event.getLine(1).equalsIgnoreCase(player.getName())) {
player.sendMessage(ChatColor.RED
+ "The first owner line must be your name.");
event.getBlock().breakNaturally();
event.setCancelled(true);
return;
}
int below = event.getBlock().getRelative(0, -1, 0).getTypeId();
if (below == BlockID.TNT || below == BlockID.SAND
|| below == BlockID.GRAVEL || below == BlockID.SIGN_POST) {
player.sendMessage(ChatColor.RED
+ "That is not a safe block that you're putting this sign on.");
event.getBlock().breakNaturally();
event.setCancelled(true);
return;
}
event.setLine(0, "[Lock]");
player.sendMessage(ChatColor.YELLOW
+ "A chest or double chest above is now protected.");
}
} else if (!wcfg.disableSignChestProtectionCheck) {
if (event.getLine(0).equalsIgnoreCase("[Lock]")) {
player.sendMessage(ChatColor.RED
+ "WorldGuard's sign chest protection is disabled.");
event.getBlock().breakNaturally();
event.setCancelled(true);
}
}
}
}

View File

@ -0,0 +1,162 @@
/*
* 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.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.event.block.BreakBlockEvent;
import com.sk89q.worldguard.bukkit.event.block.PlaceBlockEvent;
import com.sk89q.worldguard.bukkit.event.block.UseBlockEvent;
import com.sk89q.worldguard.bukkit.event.entity.DestroyEntityEvent;
import com.sk89q.worldguard.bukkit.event.entity.SpawnEntityEvent;
import com.sk89q.worldguard.bukkit.event.entity.UseEntityEvent;
import com.sk89q.worldguard.bukkit.event.inventory.UseItemEvent;
import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import java.util.logging.Logger;
import static com.google.common.base.Preconditions.checkNotNull;
public class DebuggingListener extends AbstractListener {
private final Logger logger;
/**
* Construct the listener.
*
* @param plugin an instance of WorldGuardPlugin
* @param logger the logger
*/
public DebuggingListener(WorldGuardPlugin plugin, Logger logger) {
super(plugin);
checkNotNull(logger);
this.logger = logger;
}
@EventHandler
public void onPlaceBlock(PlaceBlockEvent event) {
StringBuilder builder = new StringBuilder();
builder.append("PLACE");
builder.append(" ");
builder.append("").append(event.getEffectiveMaterial());
builder.append(" ");
builder.append("@").append(toBlockString(event.getTarget()));
builder.append(" ");
builder.append("[").append(event.getCause()).append("]");
builder.append(" ");
builder.append(":").append(event.getOriginalEvent().getEventName());
logger.info(builder.toString());
}
@EventHandler
public void onBreakBlock(BreakBlockEvent event) {
StringBuilder builder = new StringBuilder();
builder.append("DIG");
builder.append(" ");
builder.append("").append(event.getEffectiveMaterial());
builder.append(" ");
builder.append("[").append(event.getCause()).append("]");
builder.append(" ");
builder.append("@").append(toBlockString(event.getTarget()));
builder.append(" ");
builder.append(":").append(event.getOriginalEvent().getEventName());
logger.info(builder.toString());
}
@EventHandler
public void onUseBlock(UseBlockEvent event) {
StringBuilder builder = new StringBuilder();
builder.append("INTERACT");
builder.append(" ");
builder.append("").append(event.getEffectiveMaterial());
builder.append(" ");
builder.append("[").append(event.getCause()).append("]");
builder.append(" ");
builder.append("@").append(toBlockString(event.getTarget()));
builder.append(" ");
builder.append(":").append(event.getOriginalEvent().getEventName());
logger.info(builder.toString());
}
@EventHandler
public void onSpawnEntity(SpawnEntityEvent event) {
StringBuilder builder = new StringBuilder();
builder.append("SPAWN");
builder.append(" ");
builder.append("").append(event.getEffectiveType());
builder.append(" ");
builder.append("[").append(event.getCause()).append("]");
builder.append(" ");
builder.append("@").append(toBlockString(event.getTarget()));
builder.append(" ");
builder.append(":").append(event.getOriginalEvent().getEventName());
logger.info(builder.toString());
}
@EventHandler
public void onDestroyEntity(DestroyEntityEvent event) {
StringBuilder builder = new StringBuilder();
builder.append("DESTROY");
builder.append(" ");
builder.append("").append(event.getEntity().getType());
builder.append(" ");
builder.append("[").append(event.getCause()).append("]");
builder.append(" ");
builder.append("@").append(toBlockString(event.getTarget()));
builder.append(" ");
builder.append(":").append(event.getOriginalEvent().getEventName());
logger.info(builder.toString());
}
@EventHandler
public void onUseEntity(UseEntityEvent event) {
StringBuilder builder = new StringBuilder();
builder.append("INTERACT");
builder.append(" ");
builder.append("").append(event.getEntity().getType());
builder.append(" ");
builder.append("[").append(event.getCause()).append("]");
builder.append(" ");
builder.append("@").append(toBlockString(event.getTarget()));
builder.append(" ");
builder.append(":").append(event.getOriginalEvent().getEventName());
logger.info(builder.toString());
}
@EventHandler
public void onUseItem(UseItemEvent event) {
StringBuilder builder = new StringBuilder();
builder.append("USE");
builder.append(" ");
builder.append("").append(event.getItemStack().getType());
builder.append(" ");
builder.append("[").append(event.getCause()).append("]");
builder.append(" ");
builder.append("@").append(event.getWorld().getName());
builder.append(" ");
builder.append(":").append(event.getOriginalEvent().getEventName());
logger.info(builder.toString());
}
private static String toBlockString(Location location) {
return location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ();
}
}

View File

@ -0,0 +1,578 @@
/*
* 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.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.cause.Cause;
import com.sk89q.worldguard.bukkit.event.block.BreakBlockEvent;
import com.sk89q.worldguard.bukkit.event.block.PlaceBlockEvent;
import com.sk89q.worldguard.bukkit.event.block.UseBlockEvent;
import com.sk89q.worldguard.bukkit.event.entity.DestroyEntityEvent;
import com.sk89q.worldguard.bukkit.event.entity.SpawnEntityEvent;
import com.sk89q.worldguard.bukkit.event.entity.UseEntityEvent;
import com.sk89q.worldguard.bukkit.event.inventory.UseItemEvent;
import com.sk89q.worldguard.bukkit.util.Blocks;
import com.sk89q.worldguard.bukkit.util.Events;
import com.sk89q.worldguard.bukkit.util.Materials;
import com.sk89q.worldguard.bukkit.util.WGMetadata;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.ThrownPotion;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.Event.Result;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockBurnEvent;
import org.bukkit.event.block.BlockDamageEvent;
import org.bukkit.event.block.BlockDispenseEvent;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.block.BlockIgniteEvent;
import org.bukkit.event.block.BlockIgniteEvent.IgniteCause;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.EntityCombustByBlockEvent;
import org.bukkit.event.entity.EntityCombustByEntityEvent;
import org.bukkit.event.entity.EntityCombustEvent;
import org.bukkit.event.entity.EntityDamageByBlockEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityTameEvent;
import org.bukkit.event.entity.EntityUnleashEvent;
import org.bukkit.event.entity.PotionSplashEvent;
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.hanging.HangingBreakEvent;
import org.bukkit.event.hanging.HangingPlaceEvent;
import org.bukkit.event.player.PlayerBedEnterEvent;
import org.bukkit.event.player.PlayerBucketEmptyEvent;
import org.bukkit.event.player.PlayerBucketFillEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.player.PlayerShearEntityEvent;
import org.bukkit.event.player.PlayerUnleashEntityEvent;
import org.bukkit.event.vehicle.VehicleDamageEvent;
import org.bukkit.event.vehicle.VehicleDestroyEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.Dispenser;
import org.bukkit.material.MaterialData;
import javax.annotation.Nullable;
import static com.sk89q.worldguard.bukkit.cause.Cause.create;
import static com.sk89q.worldguard.bukkit.util.Materials.isBlockModifiedOnClick;
import static com.sk89q.worldguard.bukkit.util.Materials.isItemAppliedToBlock;
public class EventAbstractionListener implements Listener {
/**
* Abstract {@link BlockFromToEvent}s into break and place events.
* Currently disabled as it creates a lot of new events.
*/
public static final boolean ABSTRACT_FROM_TO_EVENTS = false;
private static final String FALLING_SOURCE_KEY = "worldguard.fallingSource";
private final WorldGuardPlugin plugin;
public EventAbstractionListener(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
public void registerEvents() {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
//-------------------------------------------------------------------------
// Block break / place
//-------------------------------------------------------------------------
@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
Events.fireToCancel(event, new BreakBlockEvent(event, create(event.getPlayer()), event.getBlock()));
}
@EventHandler
public void onBlockPlace(BlockPlaceEvent event) {
BlockState previousState = event.getBlockReplacedState();
// Some blocks, like tall grass and fire, get replaced
if (previousState.getType() != Material.AIR) {
Events.fireToCancel(event, new BreakBlockEvent(event, create(event.getPlayer()), previousState.getLocation(), previousState.getType()));
}
Events.fireToCancel(event, new PlaceBlockEvent(event, create(event.getPlayer()), event.getBlock()));
}
@EventHandler
public void onBlockBurn(BlockBurnEvent event) {
Events.fireToCancel(event, new UseBlockEvent(event, Cause.unknown(), event.getBlock()));
}
// TODO: Handle EntityCreatePortalEvent?
@EventHandler
public void onEntityChangeBlock(EntityChangeBlockEvent event) {
Block block = event.getBlock();
Entity entity = event.getEntity();
Material to = event.getTo();
// Fire two events: one as BREAK and one as PLACE
if (event.getTo() != Material.AIR && event.getBlock().getType() != Material.AIR) {
Events.fireToCancel(event, new BreakBlockEvent(event, create(entity), block));
Events.fireToCancel(event, new PlaceBlockEvent(event, create(entity), block.getLocation(), to));
} else {
if (event.getTo() == Material.AIR) {
// Track the source so later we can create a proper chain of causes
if (entity instanceof FallingBlock) {
WGMetadata.put(entity, FALLING_SOURCE_KEY, block);
// Switch around the event
Events.fireToCancel(event, new SpawnEntityEvent(event, create(block), entity));
} else {
Events.fireToCancel(event, new BreakBlockEvent(event, create(entity), event.getBlock()));
}
} else {
Cause cause;
// Return the source for falling blocks
if (entity instanceof FallingBlock) {
Block source = WGMetadata.getIfPresent(entity, FALLING_SOURCE_KEY, Block.class);
cause = create(source, entity);
} else {
cause = create(entity);
}
Events.fireToCancel(event, new PlaceBlockEvent(event, cause, event.getBlock().getLocation(), to));
}
}
}
// TODO: Handle pistons
// TODO: Handle EntityExplodeEvent
//-------------------------------------------------------------------------
// Block external interaction
//-------------------------------------------------------------------------
@EventHandler
public void onBlockDamage(BlockDamageEvent event) {
Block target = event.getBlock();
// Previously, and perhaps still, the only way to catch cake eating
// events was through here
if (target.getType() == Material.CAKE_BLOCK) {
Events.fireToCancel(event, new UseBlockEvent(event, create(event.getPlayer()), target));
}
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
@Nullable ItemStack item = player.getItemInHand();
Block clicked = event.getClickedBlock();
Block placed;
Cause cause = create(player);
switch (event.getAction()) {
case PHYSICAL:
if (Events.fireAndTestCancel(new UseBlockEvent(event, cause, clicked))) {
event.setUseInteractedBlock(Result.DENY);
event.setCancelled(true);
}
break;
case RIGHT_CLICK_BLOCK:
placed = clicked.getRelative(event.getBlockFace());
// Re-used for dispensers
handleBlockRightClick(event, create(event.getPlayer()), item, clicked, event.getBlockFace(), placed);
case LEFT_CLICK_BLOCK:
placed = clicked.getRelative(event.getBlockFace());
// As of MC ~1.6, sneaking blocks the use of blocks with right click
if (!player.isSneaking() || event.getAction() == Action.LEFT_CLICK_BLOCK) {
// Only fire events for blocks that are modified when right clicked
if (isBlockModifiedOnClick(clicked.getType()) || (item != null && isItemAppliedToBlock(item.getType(), clicked.getType()))) {
if (Events.fireAndTestCancel(new UseBlockEvent(event, cause, clicked))) {
event.setUseInteractedBlock(Result.DENY);
}
// Handle connected blocks (i.e. beds, chests)
for (Block connected : Blocks.getConnected(clicked)) {
if (Events.fireAndTestCancel(new UseBlockEvent(event, create(event.getPlayer()), connected))) {
event.setUseInteractedBlock(Result.DENY);
break;
}
}
}
// Special handling of flint and steel on TNT
if (clicked.getType() == Material.TNT && item != null && item.getType() == Material.FLINT_AND_STEEL) {
if (Events.fireAndTestCancel(new BreakBlockEvent(event, create(event.getPlayer()), clicked))) {
event.setUseInteractedBlock(Result.DENY);
break;
}
}
}
// Special handling of putting out fires
if (event.getAction() == Action.LEFT_CLICK_BLOCK && placed.getType() == Material.FIRE) {
if (Events.fireAndTestCancel(new BreakBlockEvent(event, create(event.getPlayer()), placed))) {
event.setUseInteractedBlock(Result.DENY);
break;
}
}
case LEFT_CLICK_AIR:
case RIGHT_CLICK_AIR:
if (item != null && !item.getType().isBlock() && Events.fireAndTestCancel(new UseItemEvent(event, cause, player.getWorld(), item))) {
event.setUseItemInHand(Result.DENY);
}
break;
}
}
@EventHandler
public void onEntityInteract(org.bukkit.event.entity.EntityInteractEvent event) {
Events.fireToCancel(event, new UseBlockEvent(event, create(event.getEntity()), event.getBlock()));
}
@EventHandler
public void onBlockIgnite(BlockIgniteEvent event) {
Block block = event.getBlock();
Cause cause;
// Find the cause
if (event.getPlayer() != null) {
cause = create(event.getPlayer());
} else if (event.getIgnitingEntity() != null) {
cause = create(event.getIgnitingEntity());
} else if (event.getIgnitingBlock() != null) {
cause = create(event.getIgnitingBlock());
} else {
cause = Cause.unknown();
}
if (block.getType() != Material.AIR) {
Events.fireToCancel(event, new BreakBlockEvent(event, cause, event.getBlock()));
}
// This is also handled in the PlayerInteractEvent listener
if (event.getCause() == IgniteCause.FLINT_AND_STEEL || event.getCause() == IgniteCause.FIREBALL) {
// TODO: Test location of block
Events.fireToCancel(event, new PlaceBlockEvent(event, cause, event.getBlock().getLocation(), Material.FIRE));
}
}
@EventHandler
public void onSignChange(SignChangeEvent event) {
Events.fireToCancel(event, new UseBlockEvent(event, create(event.getPlayer()), event.getBlock()));
}
@EventHandler
public void onBedEnter(PlayerBedEnterEvent event) {
Events.fireToCancel(event, new UseBlockEvent(event, create(event.getPlayer()), event.getBed()));
}
@EventHandler
public void onPlayerBucketEmpty(PlayerBucketEmptyEvent event) {
Player player = event.getPlayer();
Block blockAffected = event.getBlockClicked().getRelative(event.getBlockFace());
// Milk buckets can't be emptied as of writing
if (event.getBucket() != Material.MILK_BUCKET) {
ItemStack item = new ItemStack(event.getBucket(), 1);
Material blockMaterial = Materials.getBucketBlockMaterial(event.getBucket());
Events.fireToCancel(event, new PlaceBlockEvent(event, create(player), blockAffected.getLocation(), blockMaterial));
Events.fireToCancel(event, new UseItemEvent(event, create(player), player.getWorld(), item));
}
}
@EventHandler
public void onPlayerBucketFill(PlayerBucketFillEvent event) {
Player player = event.getPlayer();
Block blockAffected = event.getBlockClicked().getRelative(event.getBlockFace());
// Milk buckets can't be filled by right clicking the ground as of writing
if (event.getBucket() != Material.MILK_BUCKET) {
ItemStack item = new ItemStack(event.getBucket(), 1);
Events.fireToCancel(event, new BreakBlockEvent(event, create(player), blockAffected));
Events.fireToCancel(event, new UseItemEvent(event, create(player), player.getWorld(), item));
}
}
// TODO: Handle EntityPortalEnterEvent
//-------------------------------------------------------------------------
// Block self-interaction
//-------------------------------------------------------------------------
@EventHandler
public void onBlockFromTo(BlockFromToEvent event) {
if (ABSTRACT_FROM_TO_EVENTS) {
Block from = event.getBlock();
Block to = event.getToBlock();
// Liquids pass this event when flowing to solid blocks
if (to.getType().isSolid() && Materials.isLiquid(from.getType())) {
return;
}
Cause cause = create(from);
if (from.getType() != Material.AIR) {
Events.fireToCancel(event, new BreakBlockEvent(event, cause, to));
}
Events.fireToCancel(event, new PlaceBlockEvent(event, cause, to.getLocation(), from.getType()));
}
}
//-------------------------------------------------------------------------
// Entity break / place
//-------------------------------------------------------------------------
@EventHandler
public void onCreatureSpawn(CreatureSpawnEvent event) {
Events.fireToCancel(event, new SpawnEntityEvent(event, Cause.unknown(), event.getEntity()));
}
@EventHandler
public void onHangingPlace(HangingPlaceEvent event) {
Events.fireToCancel(event, new SpawnEntityEvent(event, create(event.getPlayer()), event.getEntity()));
}
@EventHandler
public void onHangingBreak(HangingBreakEvent event) {
if (event instanceof HangingBreakByEntityEvent) {
Events.fireToCancel(event, new DestroyEntityEvent(event, create(((HangingBreakByEntityEvent) event).getRemover()), event.getEntity()));
} else {
Events.fireToCancel(event, new DestroyEntityEvent(event, Cause.unknown(), event.getEntity()));
}
}
@EventHandler
public void onVehicleDestroy(VehicleDestroyEvent event) {
Events.fireToCancel(event, new DestroyEntityEvent(event, create(event.getAttacker()), event.getVehicle()));
}
// TODO: XP pickup is an entity destroy event
//-------------------------------------------------------------------------
// Entity external interaction
//-------------------------------------------------------------------------
@EventHandler
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
Player player = event.getPlayer();
World world = player.getWorld();
ItemStack item = player.getItemInHand();
Entity entity = event.getRightClicked();
Events.fireToCancel(event, new UseItemEvent(event, create(player), world, item));
Events.fireToCancel(event, new UseEntityEvent(event, create(player), entity));
}
@EventHandler
public void onEntityDamage(EntityDamageEvent event) {
if (event instanceof EntityDamageByBlockEvent) {
Events.fireToCancel(event, new UseEntityEvent(event, create(((EntityDamageByBlockEvent) event).getDamager()), event.getEntity()));
} else if (event instanceof EntityDamageByEntityEvent) {
EntityDamageByEntityEvent entityEvent = (EntityDamageByEntityEvent) event;
Entity damager = entityEvent.getDamager();
Events.fireToCancel(event, new UseEntityEvent(event, create(damager), event.getEntity()));
// Item use event with the item in hand
// Older blacklist handler code used this, although it suffers from
// race problems
if (damager instanceof Player) {
ItemStack item = ((Player) damager).getItemInHand();
if (item != null) {
Events.fireToCancel(event, new UseItemEvent(event, create(damager), event.getEntity().getWorld(), item));
}
}
} else {
Events.fireToCancel(event, new UseEntityEvent(event, Cause.unknown(), event.getEntity()));
}
}
@EventHandler
public void onEntityCombust(EntityCombustEvent event) {
if (event instanceof EntityCombustByBlockEvent) {
Events.fireToCancel(event, new UseEntityEvent(event, create(((EntityCombustByBlockEvent) event).getCombuster()), event.getEntity()));
} else if (event instanceof EntityCombustByEntityEvent) {
Events.fireToCancel(event, new UseEntityEvent(event, create(((EntityCombustByEntityEvent) event).getCombuster()), event.getEntity()));
} else {
Events.fireToCancel(event, new UseEntityEvent(event, Cause.unknown(), event.getEntity()));
}
}
@EventHandler
public void onEntityUnleash(EntityUnleashEvent event) {
if (event instanceof PlayerUnleashEntityEvent) {
PlayerUnleashEntityEvent playerEvent = (PlayerUnleashEntityEvent) event;
Events.fireToCancel(playerEvent, new UseEntityEvent(playerEvent, create(playerEvent.getPlayer()), event.getEntity()));
} else {
// TODO: Raise anyway?
}
}
@EventHandler
public void onEntityTame(EntityTameEvent event) {
Events.fireToCancel(event, new UseEntityEvent(event, create(event.getOwner()), event.getEntity()));
}
@EventHandler
public void onPlayerShearEntity(PlayerShearEntityEvent event) {
Events.fireToCancel(event, new UseEntityEvent(event, create(event.getPlayer()), event.getEntity()));
}
@EventHandler
public void onPlayerPickupItem(PlayerPickupItemEvent event) {
Events.fireToCancel(event, new DestroyEntityEvent(event, create(event.getPlayer()), event.getItem()));
}
@EventHandler
public void onPlayerDropItem(PlayerDropItemEvent event) {
Events.fireToCancel(event, new SpawnEntityEvent(event, create(event.getPlayer()), event.getItemDrop()));
}
@EventHandler
public void onVehicleDamage(VehicleDamageEvent event) {
Events.fireToCancel(event, new DestroyEntityEvent(event, create(event.getAttacker()), event.getVehicle()));
}
@EventHandler
public void onVehicleEnter(VehicleDamageEvent event) {
Events.fireToCancel(event, new UseEntityEvent(event, create(event.getAttacker()), event.getVehicle()));
}
//-------------------------------------------------------------------------
// Composite events
//-------------------------------------------------------------------------
@EventHandler
public void onPotionSplash(PotionSplashEvent event) {
Entity entity = event.getEntity();
ThrownPotion potion = event.getPotion();
World world = entity.getWorld();
Cause cause = create(potion.getShooter());
// Fire item interaction event
Events.fireToCancel(event, new UseItemEvent(event, cause, world, potion.getItem()));
// Fire entity interaction event
if (!event.isCancelled()) {
int blocked = 0;
for (LivingEntity affected : event.getAffectedEntities()) {
if (Events.fireAndTestCancel(new UseEntityEvent(event, cause, affected))) {
event.setIntensity(affected, 0);
blocked++;
}
}
if (blocked == event.getAffectedEntities().size()) {
event.setCancelled(true);
}
}
}
@EventHandler
public void onBlockDispense(BlockDispenseEvent event) {
Cause cause = create(event.getBlock());
Block dispenserBlock = event.getBlock();
ItemStack item = event.getItem();
MaterialData materialData = dispenserBlock.getState().getData();
Events.fireToCancel(event, new UseItemEvent(event, cause, dispenserBlock.getWorld(), item));
// Simulate right click event as players have it
if (materialData instanceof Dispenser) {
Dispenser dispenser = (Dispenser) materialData;
Block placed = dispenserBlock.getRelative(dispenser.getFacing());
Block clicked = placed.getRelative(dispenser.getFacing());
handleBlockRightClick(event, cause, item, clicked, dispenser.getFacing().getOppositeFace(), placed);
}
}
/**
* Handle the right click of a block while an item is held.
*
* @param event the original event
* @param cause the list of cause
* @param item the item
* @param clicked the clicked block
* @param faceClicked the face of the clicked block
* @param placed the placed block
* @param <T> the event type
*/
private static <T extends Event & Cancellable> void handleBlockRightClick(T event, Cause cause, @Nullable ItemStack item, Block clicked, BlockFace faceClicked, Block placed) {
if (item != null && item.getType() == Material.TNT) {
// Workaround for a bug that allowed TNT to trigger instantly if placed
// next to redstone, without plugins getting the clicked place event
// (not sure if this actually still happens)
Events.fireToCancel(event, new UseBlockEvent(event, cause, clicked.getLocation(), Material.TNT));
}
// Handle created Minecarts
if (item != null && Materials.isMinecart(item.getType())) {
// TODO: Give a more specific Minecart type
Events.fireToCancel(event, new SpawnEntityEvent(event, cause, placed.getLocation().add(0.5, 0, 0.5), EntityType.MINECART));
}
// Handle cocoa beans
if (item != null && item.getType() == Material.INK_SACK && Materials.isDyeColor(item.getData(), DyeColor.BROWN)) {
// CraftBukkit doesn't or didn't throw a clicked place for this
if (!(faceClicked == BlockFace.DOWN || faceClicked == BlockFace.UP)) {
Events.fireToCancel(event, new PlaceBlockEvent(event, cause, placed.getLocation(), Material.COCOA));
}
}
// Workaround for http://leaky.bukkit.org/issues/1034
if (item != null && item.getType() == Material.TNT) {
Events.fireToCancel(event, new PlaceBlockEvent(event, cause, placed.getLocation(), Material.TNT));
}
}
// TODO: Inventory events?
}

View File

@ -0,0 +1,202 @@
/*
* 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.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.event.block.BreakBlockEvent;
import com.sk89q.worldguard.bukkit.event.block.PlaceBlockEvent;
import com.sk89q.worldguard.bukkit.event.block.UseBlockEvent;
import com.sk89q.worldguard.bukkit.event.entity.DestroyEntityEvent;
import com.sk89q.worldguard.bukkit.event.entity.SpawnEntityEvent;
import com.sk89q.worldguard.bukkit.event.entity.UseEntityEvent;
import com.sk89q.worldguard.bukkit.util.Entities;
import com.sk89q.worldguard.bukkit.util.Materials;
import com.sk89q.worldguard.bukkit.util.RegionQuery;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
/**
* Handle events that need to be processed by region protection.
*/
public class RegionProtectionListener extends AbstractListener {
/**
* Construct the listener.
*
* @param plugin an instance of WorldGuardPlugin
*/
public RegionProtectionListener(WorldGuardPlugin plugin) {
super(plugin);
}
private void tellErrorMessage(CommandSender sender, Object subject) {
sender.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
}
@EventHandler(ignoreCancelled = true)
public void onPlaceBlock(PlaceBlockEvent event) {
Player player = event.getCause().getPlayerRootCause();
Location target = event.getTarget();
Material type = event.getEffectiveMaterial();
if (player != null) {
RegionQuery query = new RegionQuery(getPlugin(), player);
boolean canPlace;
// Flint and steel, fire charge
if (type == Material.FIRE) {
canPlace = query.allows(DefaultFlag.LIGHTER, target) || (query.canBuild(target) && query.canConstruct(target));
} else {
canPlace = query.canBuild(target) && query.canConstruct(target);
}
if (!canPlace) {
tellErrorMessage(player, target);
event.setCancelled(true);
}
}
}
@EventHandler(ignoreCancelled = true)
public void onBreakBlock(BreakBlockEvent event) {
Player player = event.getCause().getPlayerRootCause();
Location target = event.getTarget();
if (player != null) {
if (!getPlugin().getGlobalRegionManager().canBuild(player, target)) {
tellErrorMessage(player, target);
event.setCancelled(true);
} else if (!getPlugin().getGlobalRegionManager().canConstruct(player, target)) {
tellErrorMessage(player, target);
event.setCancelled(true);
}
}
}
@EventHandler(ignoreCancelled = true)
public void onUseBlock(UseBlockEvent event) {
Player player = event.getCause().getPlayerRootCause();
Location target = event.getTarget();
Material type = event.getEffectiveMaterial();
if (player != null) {
RegionQuery query = new RegionQuery(getPlugin(), player);
boolean canUse;
// Inventory blocks (CHEST_ACCESS)
if (Materials.isInventoryBlock(type)) {
canUse = query.canBuild( target)
|| query.allows(DefaultFlag.CHEST_ACCESS, target)
|| query.allows(DefaultFlag.USE, target);
// Beds (SLEEP)
} else if (type == Material.BED) {
canUse = query.canBuild(target)
|| query.allows(DefaultFlag.SLEEP, target)
|| query.allows(DefaultFlag.USE, target);
// TNT (TNT)
} else if (type == Material.TNT) {
canUse = query.canBuild(target)
|| query.allows(DefaultFlag.TNT, target);
// Everything else
} else {
canUse = query.canBuild(target)
|| query.allows(DefaultFlag.USE, target);
}
if (!canUse) {
tellErrorMessage(player, target);
event.setCancelled(true);
}
}
}
@EventHandler(ignoreCancelled = true)
public void onSpawnEntity(SpawnEntityEvent event) {
Player player = event.getCause().getPlayerRootCause();
Location target = event.getTarget();
EntityType type = event.getEffectiveType();
if (player != null) {
RegionQuery query = new RegionQuery(getPlugin(), player);
boolean canSpawn;
if (Entities.isVehicle(type)) {
canSpawn = query.canBuild(target) || query.allows(DefaultFlag.PLACE_VEHICLE, target);
} else {
canSpawn = query.canBuild(target);
}
if (!canSpawn) {
tellErrorMessage(player, target);
event.setCancelled(true);
}
}
}
@EventHandler(ignoreCancelled = true)
public void onDestroyEntity(DestroyEntityEvent event) {
Player player = event.getCause().getPlayerRootCause();
Location target = event.getTarget();
EntityType type = event.getEntity().getType();
if (player != null) {
RegionQuery query = new RegionQuery(getPlugin(), player);
boolean canDestroy;
if (Entities.isVehicle(type)) {
canDestroy = query.canBuild(target) || query.allows(DefaultFlag.DESTROY_VEHICLE, target);
} else {
canDestroy = query.canBuild(target);
}
if (!canDestroy) {
tellErrorMessage(player, target);
event.setCancelled(true);
}
}
}
@EventHandler(ignoreCancelled = true)
public void onUseEntity(UseEntityEvent event) {
Player player = event.getCause().getPlayerRootCause();
Location target = event.getTarget();
if (player != null) {
RegionQuery query = new RegionQuery(getPlugin(), player);
boolean canUse = query.canBuild(target) || query.allows(DefaultFlag.USE, target);
if (!canUse) {
tellErrorMessage(player, target);
event.setCancelled(true);
}
}
}
}

View File

@ -17,23 +17,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
package com.sk89q.worldguard.bukkit.listener;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.blocks.ItemType;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.blacklist.event.BlockDispenseBlacklistEvent;
import com.sk89q.worldguard.internal.Events;
import com.sk89q.worldguard.internal.cause.Causes;
import com.sk89q.worldguard.internal.event.BlockInteractEvent;
import com.sk89q.worldguard.internal.event.Interaction;
import com.sk89q.worldguard.internal.event.ItemInteractEvent;
import com.sk89q.worldguard.bukkit.ConfigurationManager;
import com.sk89q.worldguard.bukkit.SpongeUtil;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
@ -44,8 +40,6 @@
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.BlockDispenseEvent;
import org.bukkit.event.block.BlockExpEvent;
import org.bukkit.event.block.BlockFadeEvent;
import org.bukkit.event.block.BlockFormEvent;
@ -60,10 +54,8 @@
import org.bukkit.event.block.BlockSpreadEvent;
import org.bukkit.event.block.EntityBlockFormEvent;
import org.bukkit.event.block.LeavesDecayEvent;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.inventory.ItemStack;
import static com.sk89q.worldguard.bukkit.BukkitUtil.createTarget;
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
/**
@ -111,20 +103,6 @@ protected WorldConfiguration getWorldConfig(Player player) {
return getWorldConfig(player.getWorld());
}
/*
* Called when a block is damaged.
*/
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockDamage(BlockDamageEvent event) {
Block target = event.getBlock();
// Cake are damaged and not broken when they are eaten, so we must
// handle them a bit separately
if (target.getType() == Material.CAKE_BLOCK) {
Events.fireToCancel(event, new BlockInteractEvent(event, Causes.create(event.getPlayer()), Interaction.INTERACT, target));
}
}
/*
* Called when a block is broken.
*/
@ -141,8 +119,6 @@ public void onBlockBreak(BlockBreakEvent event) {
player.setItemInHand(held);
}
}
Events.fireToCancel(event, new BlockInteractEvent(event, Causes.create(event.getPlayer()), Interaction.BREAK, target));
}
/*
@ -301,25 +277,9 @@ public void onBlockIgnite(BlockIgniteEvent event) {
if (wcfg.useRegions) {
Vector pt = toVector(block);
Player player = event.getPlayer();
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
if (player != null && !plugin.getGlobalRegionManager().hasBypass(player, world)) {
LocalPlayer localPlayer = plugin.wrapPlayer(player);
// this is preliminarily handled in the player listener under handleBlockRightClick
// why it's handled here too, no one knows
if (cause == IgniteCause.FLINT_AND_STEEL || cause == IgniteCause.FIREBALL) {
if (!set.allows(DefaultFlag.LIGHTER)
&& !set.canBuild(localPlayer)
&& !plugin.hasPermission(player, "worldguard.override.lighter")) {
event.setCancelled(true);
return;
}
}
}
if (wcfg.highFreqFlags && isFireSpread
&& !set.allows(DefaultFlag.FIRE_SPREAD)) {
event.setCancelled(true);
@ -469,8 +429,6 @@ public void onBlockPlace(BlockPlaceEvent event) {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
Events.fireToCancel(event, new BlockInteractEvent(event, Causes.create(event.getPlayer()), Interaction.PLACE, target));
if (wcfg.simulateSponge && target.getType() == Material.SPONGE) {
if (wcfg.redstoneSponges && target.isBlockIndirectlyPowered()) {
return;
@ -519,75 +477,6 @@ public void onBlockRedstoneChange(BlockRedstoneEvent event) {
}
}
/*
* Called when a sign is changed.
*/
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onSignChange(SignChangeEvent event) {
Player player = event.getPlayer();
WorldConfiguration wcfg = getWorldConfig(player);
if (wcfg.signChestProtection) {
if (event.getLine(0).equalsIgnoreCase("[Lock]")) {
if (wcfg.isChestProtectedPlacement(event.getBlock(), player)) {
player.sendMessage(ChatColor.DARK_RED + "You do not own the adjacent chest.");
event.getBlock().breakNaturally();
event.setCancelled(true);
return;
}
if (event.getBlock().getTypeId() != BlockID.SIGN_POST) {
player.sendMessage(ChatColor.RED
+ "The [Lock] sign must be a sign post, not a wall sign.");
event.getBlock().breakNaturally();
event.setCancelled(true);
return;
}
if (!event.getLine(1).equalsIgnoreCase(player.getName())) {
player.sendMessage(ChatColor.RED
+ "The first owner line must be your name.");
event.getBlock().breakNaturally();
event.setCancelled(true);
return;
}
int below = event.getBlock().getRelative(0, -1, 0).getTypeId();
if (below == BlockID.TNT || below == BlockID.SAND
|| below == BlockID.GRAVEL || below == BlockID.SIGN_POST) {
player.sendMessage(ChatColor.RED
+ "That is not a safe block that you're putting this sign on.");
event.getBlock().breakNaturally();
event.setCancelled(true);
return;
}
event.setLine(0, "[Lock]");
player.sendMessage(ChatColor.YELLOW
+ "A chest or double chest above is now protected.");
}
} else if (!wcfg.disableSignChestProtectionCheck) {
if (event.getLine(0).equalsIgnoreCase("[Lock]")) {
player.sendMessage(ChatColor.RED
+ "WorldGuard's sign chest protection is disabled.");
event.getBlock().breakNaturally();
event.setCancelled(true);
return;
}
}
if (!plugin.getGlobalRegionManager().canBuild(player, event.getBlock())) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
event.setCancelled(true);
return;
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onLeavesDecay(LeavesDecayEvent event) {
ConfigurationManager cfg = plugin.getGlobalStateManager();
@ -827,21 +716,6 @@ public void onBlockPistonRetract(BlockPistonRetractEvent event) {
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockDispense(BlockDispenseEvent event) {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
if (wcfg.getBlacklist() != null) {
if (!wcfg.getBlacklist().check(new BlockDispenseBlacklistEvent(null, toVector(event.getBlock()), createTarget(event.getItem())), false, false)) {
event.setCancelled(true);
return;
}
}
Events.fireToCancel(event, new ItemInteractEvent(event, Causes.create(event.getBlock()), Interaction.INTERACT, event.getBlock().getWorld(), event.getItem()));
}
/*
* Called when a block yields exp
*/

View File

@ -17,10 +17,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
package com.sk89q.worldguard.bukkit.listener;
import com.sk89q.commandbook.InfoComponent;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import org.bukkit.entity.Player;

View File

@ -17,16 +17,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
package com.sk89q.worldguard.bukkit.listener;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.blacklist.event.ItemUseBlacklistEvent;
import com.sk89q.worldguard.internal.Events;
import com.sk89q.worldguard.internal.cause.Causes;
import com.sk89q.worldguard.internal.event.Interaction;
import com.sk89q.worldguard.internal.event.ItemInteractEvent;
import com.sk89q.worldguard.bukkit.BukkitUtil;
import com.sk89q.worldguard.bukkit.ConfigurationManager;
import com.sk89q.worldguard.bukkit.RegionQueryUtil;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.GlobalRegionManager;
import com.sk89q.worldguard.protection.events.DisallowedPVPEvent;
@ -83,7 +83,6 @@
import java.util.Set;
import static com.sk89q.worldguard.bukkit.BukkitUtil.createTarget;
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
/**
@ -225,26 +224,6 @@ private void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
Entity attacker = event.getDamager();
Entity defender = event.getEntity();
if (attacker instanceof Player) {
Player player = (Player) attacker;
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(player.getWorld());
ItemStack held = player.getInventory().getItemInHand();
if (held != null) {
if (wcfg.getBlacklist() != null) {
if (!wcfg.getBlacklist().check(
new ItemUseBlacklistEvent(plugin.wrapPlayer(player),
toVector(player.getLocation()), createTarget(held)), false, false)) {
event.setCancelled(true);
return;
}
}
}
}
if (defender instanceof ItemFrame) {
if (checkItemFrameProtection(attacker, (ItemFrame) defender)) {
event.setCancelled(true);
@ -934,9 +913,6 @@ public void onPotionSplash(PotionSplashEvent event) {
World world = entity.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
Events.fireToCancel(event, new ItemInteractEvent(event, Causes.create(potion.getShooter()), Interaction.INTERACT, world, potion.getItem()));
GlobalRegionManager regionMan = plugin.getGlobalRegionManager();
@ -1017,16 +993,7 @@ private boolean checkItemFrameProtection(Entity attacker, ItemFrame defender) {
if (wcfg.useRegions) {
// bukkit throws this event when a player attempts to remove an item from a frame
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
if (attacker instanceof Player) {
Player player = (Player) attacker;
LocalPlayer localPlayer = plugin.wrapPlayer(player);
if (!plugin.getGlobalRegionManager().hasBypass(player, world)
&& !mgr.getApplicableRegions(defender.getLocation())
.canBuild(localPlayer)) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
return true;
}
} else {
if (!(attacker instanceof Player)) {
if (!plugin.getGlobalRegionManager().allows(
DefaultFlag.ENTITY_ITEM_FRAME_DESTROY, defender.getLocation())) {
return true;

View File

@ -0,0 +1,122 @@
/*
* 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.sk89q.worldguard.bukkit.ConfigurationManager;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import org.bukkit.World;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Hanging;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Painting;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.hanging.HangingBreakEvent;
import org.bukkit.event.hanging.HangingBreakEvent.RemoveCause;
import org.bukkit.projectiles.ProjectileSource;
/**
* Listener for painting related events.
*
* @author BangL <henno.rickowski@gmail.com>
*/
public class WorldGuardHangingListener implements Listener {
private WorldGuardPlugin plugin;
/**
* Construct the object;
*
* @param plugin The plugin instance
*/
public WorldGuardHangingListener(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
/**
* Register events.
*/
public void registerEvents() {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onHangingBreak(HangingBreakEvent event) {
Hanging hanging = event.getEntity();
World world = hanging.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
if (event instanceof HangingBreakByEntityEvent) {
HangingBreakByEntityEvent entityEvent = (HangingBreakByEntityEvent) event;
Entity removerEntity = entityEvent.getRemover();
if (removerEntity instanceof Projectile) {
Projectile projectile = (Projectile) removerEntity;
ProjectileSource remover = projectile.getShooter();
removerEntity = (remover instanceof LivingEntity ? (LivingEntity) remover : null);
}
if (!(removerEntity instanceof Player)) {
if (removerEntity instanceof Creeper) {
if (wcfg.blockCreeperBlockDamage || wcfg.blockCreeperExplosions) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows(DefaultFlag.CREEPER_EXPLOSION, hanging.getLocation())) {
event.setCancelled(true);
return;
}
}
// this now covers dispensers as well, if removerEntity is null above,
// due to a non-LivingEntity ProjectileSource
if (hanging instanceof Painting
&& (wcfg.blockEntityPaintingDestroy
|| (wcfg.useRegions
&& !plugin.getGlobalRegionManager().allows(DefaultFlag.ENTITY_PAINTING_DESTROY, hanging.getLocation())))) {
event.setCancelled(true);
} else if (hanging instanceof ItemFrame
&& (wcfg.blockEntityItemFrameDestroy
|| (wcfg.useRegions
&& !plugin.getGlobalRegionManager().allows(DefaultFlag.ENTITY_ITEM_FRAME_DESTROY, hanging.getLocation())))) {
event.setCancelled(true);
}
}
} else {
// Explosions from mobs are not covered by HangingBreakByEntity
if (hanging instanceof Painting && wcfg.blockEntityPaintingDestroy
&& event.getCause() == RemoveCause.EXPLOSION) {
event.setCancelled(true);
} else if (hanging instanceof ItemFrame && wcfg.blockEntityItemFrameDestroy
&& event.getCause() == RemoveCause.EXPLOSION) {
event.setCancelled(true);
}
}
}
}

View File

@ -0,0 +1,733 @@
/*
* 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.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.blacklist.event.ItemUseBlacklistEvent;
import com.sk89q.worldguard.bukkit.BukkitUtil;
import com.sk89q.worldguard.bukkit.ConfigurationManager;
import com.sk89q.worldguard.bukkit.FlagStateManager.PlayerFlagState;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.util.command.CommandFilter;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerBedEnterEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerFishEvent;
import org.bukkit.event.player.PlayerGameModeChangeEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.PluginManager;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
import java.util.regex.Pattern;
import static com.sk89q.worldguard.bukkit.BukkitUtil.createTarget;
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
/**
* Handles all events thrown in relation to a player.
*/
public class WorldGuardPlayerListener implements Listener {
private Pattern opPattern = Pattern.compile("^/op(?:\\s.*)?$", Pattern.CASE_INSENSITIVE);
private WorldGuardPlugin plugin;
/**
* Construct the object;
*
* @param plugin
*/
public WorldGuardPlayerListener(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
/**
* Register events.
*/
public void registerEvents() {
final PluginManager pm = plugin.getServer().getPluginManager();
pm.registerEvents(this, plugin);
if (plugin.getGlobalStateManager().usePlayerMove) {
pm.registerEvents(new PlayerMoveHandler(), plugin);
}
}
// unsure if anyone actually started using this yet, but just in case...
@Deprecated
public static boolean checkMove(WorldGuardPlugin plugin, Player player, World world, Location from, Location to) {
return checkMove(plugin, player, from, to); // drop world since it used to be mishandled
}
/**
* Handles movement related events, including changing gamemode, sending
* greeting/farewell messages, etc.
* A reference to WorldGuardPlugin is required to keep this method static
* although WGBukkit.getPlugin() may be used.
* @return true if the movement should not be allowed
*/
public static boolean checkMove(WorldGuardPlugin plugin, Player player, Location from, Location to) {
PlayerFlagState state = plugin.getFlagStateManager().getState(player);
//Flush states in multiworld scenario
if (state.lastWorld != null && !state.lastWorld.equals(to.getWorld())) {
plugin.getFlagStateManager().forget(player);
state = plugin.getFlagStateManager().getState(player);
}
World world = from.getWorld();
World toWorld = to.getWorld();
LocalPlayer localPlayer = plugin.wrapPlayer(player);
boolean hasBypass = plugin.getGlobalRegionManager().hasBypass(player, world);
boolean hasRemoteBypass;
if (world.equals(toWorld)) {
hasRemoteBypass = hasBypass;
} else {
hasRemoteBypass = plugin.getGlobalRegionManager().hasBypass(player, toWorld);
}
RegionManager mgr = plugin.getGlobalRegionManager().get(toWorld);
Vector pt = new Vector(to.getBlockX(), to.getBlockY(), to.getBlockZ());
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
/*
// check if region is full
// get the lowest number of allowed members in any region
boolean regionFull = false;
String maxPlayerMessage = null;
if (!hasBypass) {
for (ProtectedRegion region : set) {
if (region instanceof GlobalProtectedRegion) {
continue; // global region can't have a max
}
// get the max for just this region
Integer maxPlayers = region.getFlag(DefaultFlag.MAX_PLAYERS);
if (maxPlayers == null) {
continue;
}
int occupantCount = 0;
for(Player occupant : world.getPlayers()) {
// each player in this region counts as one toward the max of just this region
// A person with bypass doesn't count as an occupant of the region
if (!occupant.equals(player) && !plugin.getGlobalRegionManager().hasBypass(occupant, world)) {
if (region.contains(BukkitUtil.toVector(occupant.getLocation()))) {
if (++occupantCount >= maxPlayers) {
regionFull = true;
maxPlayerMessage = region.getFlag(DefaultFlag.MAX_PLAYERS_MESSAGE);
// At least one region in the set is full, we are going to use this message because it
// was the first one we detected as full. In reality we should check them all and then
// resolve the message from full regions, but that is probably a lot laggier (and this
// is already pretty laggy. In practice, we can't really control which one we get first
// right here.
break;
}
}
}
}
}
}
*/
boolean entryAllowed = set.allows(DefaultFlag.ENTRY, localPlayer);
if (!hasRemoteBypass && (!entryAllowed /*|| regionFull*/)) {
String message = /*maxPlayerMessage != null ? maxPlayerMessage :*/ "You are not permitted to enter this area.";
player.sendMessage(ChatColor.DARK_RED + message);
return true;
}
// Have to set this state
if (state.lastExitAllowed == null) {
state.lastExitAllowed = plugin.getGlobalRegionManager().get(world)
.getApplicableRegions(toVector(from))
.allows(DefaultFlag.EXIT, localPlayer);
}
boolean exitAllowed = set.allows(DefaultFlag.EXIT, localPlayer);
if (!hasBypass && exitAllowed && !state.lastExitAllowed) {
player.sendMessage(ChatColor.DARK_RED + "You are not permitted to leave this area.");
return true;
}
// WorldGuardRegionMoveEvent event = new WorldGuardRegionMoveEvent(plugin, player, state, set, from, to);
// Bukkit.getPluginManager().callEvent(event);
String greeting = set.getFlag(DefaultFlag.GREET_MESSAGE);//, localPlayer);
String farewell = set.getFlag(DefaultFlag.FAREWELL_MESSAGE);//, localPlayer);
Boolean notifyEnter = set.getFlag(DefaultFlag.NOTIFY_ENTER);//, localPlayer);
Boolean notifyLeave = set.getFlag(DefaultFlag.NOTIFY_LEAVE);//, localPlayer);
GameMode gameMode = set.getFlag(DefaultFlag.GAME_MODE);
if (state.lastFarewell != null && (farewell == null
|| !state.lastFarewell.equals(farewell))) {
String replacedFarewell = plugin.replaceMacros(
player, BukkitUtil.replaceColorMacros(state.lastFarewell));
player.sendMessage(replacedFarewell.replaceAll("\\\\n", "\n").split("\\n"));
}
if (greeting != null && (state.lastGreeting == null
|| !state.lastGreeting.equals(greeting))) {
String replacedGreeting = plugin.replaceMacros(
player, BukkitUtil.replaceColorMacros(greeting));
player.sendMessage(replacedGreeting.replaceAll("\\\\n", "\n").split("\\n"));
}
if ((notifyLeave == null || !notifyLeave)
&& state.notifiedForLeave != null && state.notifiedForLeave) {
plugin.broadcastNotification(ChatColor.GRAY + "WG: "
+ ChatColor.LIGHT_PURPLE + player.getName()
+ ChatColor.GOLD + " left NOTIFY region");
}
if (notifyEnter != null && notifyEnter && (state.notifiedForEnter == null
|| !state.notifiedForEnter)) {
StringBuilder regionList = new StringBuilder();
for (ProtectedRegion region : set) {
if (regionList.length() != 0) {
regionList.append(", ");
}
regionList.append(region.getId());
}
plugin.broadcastNotification(ChatColor.GRAY + "WG: "
+ ChatColor.LIGHT_PURPLE + player.getName()
+ ChatColor.GOLD + " entered NOTIFY region: "
+ ChatColor.WHITE
+ regionList);
}
if (!hasBypass && gameMode != null) {
if (player.getGameMode() != gameMode) {
state.lastGameMode = player.getGameMode();
player.setGameMode(gameMode);
} else if (state.lastGameMode == null) {
state.lastGameMode = player.getServer().getDefaultGameMode();
}
} else {
if (state.lastGameMode != null) {
GameMode mode = state.lastGameMode;
state.lastGameMode = null;
player.setGameMode(mode);
}
}
state.lastGreeting = greeting;
state.lastFarewell = farewell;
state.notifiedForEnter = notifyEnter;
state.notifiedForLeave = notifyLeave;
state.lastExitAllowed = exitAllowed;
state.lastWorld = to.getWorld();
state.lastBlockX = to.getBlockX();
state.lastBlockY = to.getBlockY();
state.lastBlockZ = to.getBlockZ();
return false;
}
class PlayerMoveHandler implements Listener {
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
World world = player.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
if (player.getVehicle() != null) {
return; // handled in vehicle listener
}
if (wcfg.useRegions) {
// Did we move a block?
if (event.getFrom().getBlockX() != event.getTo().getBlockX()
|| event.getFrom().getBlockY() != event.getTo().getBlockY()
|| event.getFrom().getBlockZ() != event.getTo().getBlockZ()) {
boolean result = checkMove(plugin, player, event.getFrom(), event.getTo());
if (result) {
Location newLoc = event.getFrom();
newLoc.setX(newLoc.getBlockX() + 0.5);
newLoc.setY(newLoc.getBlockY());
newLoc.setZ(newLoc.getBlockZ() + 0.5);
event.setTo(newLoc);
}
}
}
}
}
@EventHandler
public void onPlayerGameModeChange(PlayerGameModeChangeEvent event) {
Player player = event.getPlayer();
WorldConfiguration wcfg = plugin.getGlobalStateManager().get(player.getWorld());
if (wcfg.useRegions && !plugin.getGlobalRegionManager().hasBypass(player, player.getWorld())) {
GameMode gameMode = plugin.getGlobalRegionManager().get(player.getWorld())
.getApplicableRegions(player.getLocation()).getFlag(DefaultFlag.GAME_MODE);
if (plugin.getFlagStateManager().getState(player).lastGameMode != null
&& gameMode != null && event.getNewGameMode() != gameMode) {
event.setCancelled(true);
}
}
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
World world = player.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
if (cfg.activityHaltToggle) {
player.sendMessage(ChatColor.YELLOW
+ "Intensive server activity has been HALTED.");
int removed = 0;
for (Entity entity : world.getEntities()) {
if (BukkitUtil.isIntensiveEntity(entity)) {
entity.remove();
removed++;
}
}
if (removed > 10) {
plugin.getLogger().info("Halt-Act: " + removed + " entities (>10) auto-removed from "
+ player.getWorld().toString());
}
}
if (wcfg.fireSpreadDisableToggle) {
player.sendMessage(ChatColor.YELLOW
+ "Fire spread is currently globally disabled for this world.");
}
if (!cfg.hasCommandBookGodMode() && cfg.autoGodMode && (plugin.inGroup(player, "wg-invincible")
|| plugin.hasPermission(player, "worldguard.auto-invincible"))) {
plugin.getLogger().log(Level.INFO, "Enabled auto-god mode for " + player.getName());
cfg.enableGodMode(player);
}
if (plugin.inGroup(player, "wg-amphibious")) {
plugin.getLogger().log(Level.INFO, "Enabled no-drowning mode for " + player.getName() + " (player is in group 'wg-amphibious')");
cfg.enableAmphibiousMode(player);
}
if (wcfg.useRegions) {
PlayerFlagState state = plugin.getFlagStateManager().getState(player);
Location loc = player.getLocation();
state.lastWorld = loc.getWorld();
state.lastBlockX = loc.getBlockX();
state.lastBlockY = loc.getBlockY();
state.lastBlockZ = loc.getBlockZ();
}
}
@EventHandler(ignoreCancelled = true)
public void onPlayerChat(AsyncPlayerChatEvent event) {
Player player = event.getPlayer();
WorldConfiguration wcfg = plugin.getGlobalStateManager().get(player.getWorld());
if (wcfg.useRegions) {
if (!plugin.getGlobalRegionManager().allows(DefaultFlag.SEND_CHAT, player.getLocation())) {
player.sendMessage(ChatColor.RED + "You don't have permission to chat in this region!");
event.setCancelled(true);
return;
}
for (Iterator<Player> i = event.getRecipients().iterator(); i.hasNext();) {
if (!plugin.getGlobalRegionManager().allows(DefaultFlag.RECEIVE_CHAT, i.next().getLocation())) {
i.remove();
}
}
if (event.getRecipients().size() == 0) {
event.setCancelled(true);
}
}
}
@EventHandler(ignoreCancelled = true)
public void onPlayerLogin(PlayerLoginEvent event) {
Player player = event.getPlayer();
ConfigurationManager cfg = plugin.getGlobalStateManager();
String hostKey = cfg.hostKeys.get(player.getName().toLowerCase());
if (hostKey != null) {
String hostname = event.getHostname();
int colonIndex = hostname.indexOf(':');
if (colonIndex != -1) {
hostname = hostname.substring(0, colonIndex);
}
if (!hostname.equals(hostKey)) {
event.disallow(PlayerLoginEvent.Result.KICK_OTHER,
"You did not join with the valid host key!");
plugin.getLogger().warning("WorldGuard host key check: " +
player.getName() + " joined with '" + hostname +
"' but '" + hostKey + "' was expected. Kicked!");
return;
}
}
if (cfg.deopOnJoin) {
player.setOp(false);
}
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
World world = player.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
// This is to make the enter/exit flags accurate -- move events are not
// sent constantly, so it is possible to move just a little enough to
// not trigger the event and then rejoin so that you are then considered
// outside the border. This should work around that.
if (wcfg.useRegions) {
boolean hasBypass = plugin.getGlobalRegionManager().hasBypass(player, world);
PlayerFlagState state = plugin.getFlagStateManager().getState(player);
if (state.lastWorld != null && !hasBypass) {
LocalPlayer localPlayer = plugin.wrapPlayer(player);
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
Location loc = player.getLocation();
Vector pt = new Vector(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
if (state.lastExitAllowed == null) {
state.lastExitAllowed = set.allows(DefaultFlag.EXIT, localPlayer);
}
if (!state.lastExitAllowed || !set.allows(DefaultFlag.ENTRY, localPlayer)) {
// Only if we have the last location cached
if (state.lastWorld.equals(world)) {
Location newLoc = new Location(world, state.lastBlockX + 0.5,
state.lastBlockY, state.lastBlockZ + 0.5);
player.teleport(newLoc);
}
}
}
}
cfg.forgetPlayer(plugin.wrapPlayer(player));
plugin.forgetPlayer(player);
}
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
World world = player.getWorld();
if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
handleBlockRightClick(event);
} else if (event.getAction() == Action.PHYSICAL) {
handlePhysicalInteract(event);
}
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
if (wcfg.removeInfiniteStacks
&& !plugin.hasPermission(player, "worldguard.override.infinite-stack")) {
int slot = player.getInventory().getHeldItemSlot();
ItemStack heldItem = player.getInventory().getItem(slot);
if (heldItem != null && heldItem.getAmount() < 0) {
player.getInventory().setItem(slot, null);
player.sendMessage(ChatColor.RED + "Infinite stack removed.");
}
}
}
/**
* Called when a player right clicks a block.
*
* @param event Thrown event
*/
private void handleBlockRightClick(PlayerInteractEvent event) {
if (event.isCancelled()) {
return;
}
Block block = event.getClickedBlock();
World world = block.getWorld();
int type = block.getTypeId();
Player player = event.getPlayer();
ItemStack item = player.getItemInHand();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
// Infinite stack removal
if ((type == BlockID.CHEST
|| type == BlockID.JUKEBOX
|| type == BlockID.DISPENSER
|| type == BlockID.FURNACE
|| type == BlockID.BURNING_FURNACE
|| type == BlockID.BREWING_STAND
|| type == BlockID.ENCHANTMENT_TABLE)
&& wcfg.removeInfiniteStacks
&& !plugin.hasPermission(player, "worldguard.override.infinite-stack")) {
for (int slot = 0; slot < 40; slot++) {
ItemStack heldItem = player.getInventory().getItem(slot);
if (heldItem != null && heldItem.getAmount() < 0) {
player.getInventory().setItem(slot, null);
player.sendMessage(ChatColor.RED + "Infinite stack in slot #" + slot + " removed.");
}
}
}
if (wcfg.useRegions) {
Vector pt = toVector(block);
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
Block placedIn = block.getRelative(event.getBlockFace());
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
ApplicableRegionSet placedInSet = mgr.getApplicableRegions(placedIn.getLocation());
LocalPlayer localPlayer = plugin.wrapPlayer(player);
if (item.getTypeId() == wcfg.regionWand && plugin.hasPermission(player, "worldguard.region.wand")) {
if (set.size() > 0) {
player.sendMessage(ChatColor.YELLOW + "Can you build? "
+ (set.canBuild(localPlayer) ? "Yes" : "No"));
StringBuilder str = new StringBuilder();
for (Iterator<ProtectedRegion> it = set.iterator(); it.hasNext();) {
str.append(it.next().getId());
if (it.hasNext()) {
str.append(", ");
}
}
player.sendMessage(ChatColor.YELLOW + "Applicable regions: " + str.toString());
} else {
player.sendMessage(ChatColor.YELLOW + "WorldGuard: No defined regions here!");
}
event.setCancelled(true);
}
}
}
/**
* Called when a player steps on a pressure plate or tramples crops.
*
* @param event Thrown event
*/
private void handlePhysicalInteract(PlayerInteractEvent event) {
if (event.isCancelled()) return;
Player player = event.getPlayer();
Block block = event.getClickedBlock(); //not actually clicked but whatever
int type = block.getTypeId();
World world = player.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
if (block.getTypeId() == BlockID.SOIL && wcfg.disablePlayerCropTrampling) {
event.setCancelled(true);
return;
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onPlayerDropItem(PlayerDropItemEvent event) {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getPlayer().getWorld());
Player player = event.getPlayer();
if (wcfg.useRegions) {
if (!plugin.getGlobalRegionManager().hasBypass(player, player.getWorld())
&& !plugin.getGlobalRegionManager().allows(DefaultFlag.ITEM_DROP, player.getLocation())) {
event.setCancelled(true);
player.sendMessage(ChatColor.RED + "You don't have permission to do that in this area.");
}
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onPlayerFish(PlayerFishEvent event) {
WorldConfiguration wcfg = plugin.getGlobalStateManager().get(event.getPlayer().getWorld());
if (wcfg.disableExpDrops || !plugin.getGlobalRegionManager().allows(DefaultFlag.EXP_DROPS,
event.getPlayer().getLocation())) {
event.setExpToDrop(0);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerRespawn(PlayerRespawnEvent event) {
Player player = event.getPlayer();
Location location = player.getLocation();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(player.getWorld());
if (wcfg.useRegions) {
Vector pt = toVector(location);
RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld());
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
LocalPlayer localPlayer = plugin.wrapPlayer(player);
com.sk89q.worldedit.Location spawn = set.getFlag(DefaultFlag.SPAWN_LOC, localPlayer);
if (spawn != null) {
event.setRespawnLocation(com.sk89q.worldedit.bukkit.BukkitUtil.toLocation(spawn));
}
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onItemHeldChange(PlayerItemHeldEvent event) {
Player player = event.getPlayer();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(player.getWorld());
if (wcfg.removeInfiniteStacks
&& !plugin.hasPermission(player, "worldguard.override.infinite-stack")) {
int newSlot = event.getNewSlot();
ItemStack heldItem = player.getInventory().getItem(newSlot);
if (heldItem != null && heldItem.getAmount() < 0) {
player.getInventory().setItem(newSlot, null);
player.sendMessage(ChatColor.RED + "Infinite stack removed.");
}
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onPlayerBedEnter(PlayerBedEnterEvent event) {
Player player = event.getPlayer();
Location location = player.getLocation();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(player.getWorld());
if (wcfg.useRegions) {
Vector pt = toVector(location);
RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld());
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
if (!plugin.getGlobalRegionManager().hasBypass(player, player.getWorld())
&& !set.allows(DefaultFlag.SLEEP, plugin.wrapPlayer(player))) {
event.setCancelled(true);
player.sendMessage("This bed doesn't belong to you!");
return;
}
}
}
@EventHandler(priority= EventPriority.LOW, ignoreCancelled = true)
public void onPlayerTeleport(PlayerTeleportEvent event) {
World world = event.getFrom().getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
if (wcfg.useRegions) {
RegionManager mgr = plugin.getGlobalRegionManager().get(event.getFrom().getWorld());
Vector pt = new Vector(event.getTo().getBlockX(), event.getTo().getBlockY(), event.getTo().getBlockZ());
Vector ptFrom = new Vector(event.getFrom().getBlockX(), event.getFrom().getBlockY(), event.getFrom().getBlockZ());
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
ApplicableRegionSet setFrom = mgr.getApplicableRegions(ptFrom);
LocalPlayer localPlayer = plugin.wrapPlayer(event.getPlayer());
if (cfg.usePlayerTeleports) {
boolean result = checkMove(plugin, event.getPlayer(), event.getFrom(), event.getTo());
if (result) {
event.setCancelled(true);
return;
}
}
if (event.getCause() == TeleportCause.ENDER_PEARL) {
if (!plugin.getGlobalRegionManager().hasBypass(localPlayer, world)
&& !(set.allows(DefaultFlag.ENDERPEARL, localPlayer)
&& setFrom.allows(DefaultFlag.ENDERPEARL, localPlayer))) {
event.getPlayer().sendMessage(ChatColor.DARK_RED + "You're not allowed to go there.");
event.setCancelled(true);
return;
}
}
}
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
Player player = event.getPlayer();
LocalPlayer localPlayer = plugin.wrapPlayer(player);
World world = player.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
if (wcfg.useRegions && !plugin.getGlobalRegionManager().hasBypass(player, world)) {
Vector pt = toVector(player.getLocation());
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
Set<String> allowedCommands = set.getFlag(DefaultFlag.ALLOWED_CMDS, localPlayer);
Set<String> blockedCommands = set.getFlag(DefaultFlag.BLOCKED_CMDS, localPlayer);
CommandFilter test = new CommandFilter(allowedCommands, blockedCommands);
if (!test.apply(event.getMessage())) {
player.sendMessage(ChatColor.RED + event.getMessage() + " is not allowed in this area.");
event.setCancelled(true);
return;
}
}
if (cfg.blockInGameOp) {
if (opPattern.matcher(event.getMessage()).matches()) {
player.sendMessage(ChatColor.RED + "/op can only be used in console (as set by a WG setting).");
event.setCancelled(true);
return;
}
}
}
}

View File

@ -17,8 +17,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
package com.sk89q.worldguard.bukkit.listener;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.server.PluginDisableEvent;

View File

@ -17,24 +17,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
package com.sk89q.worldguard.bukkit.listener;
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
import org.bukkit.ChatColor;
import com.sk89q.worldguard.bukkit.ConfigurationManager;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Vehicle;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.vehicle.VehicleDestroyEvent;
import org.bukkit.event.vehicle.VehicleMoveEvent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
public class WorldGuardVehicleListener implements Listener {
@ -56,34 +49,6 @@ public void registerEvents() {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void onVehicleDestroy(VehicleDestroyEvent event) {
Vehicle vehicle = event.getVehicle();
Entity destroyer = event.getAttacker();
if (!(destroyer instanceof Player)) return; // don't care
Player player = (Player) destroyer;
World world = vehicle.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
if (wcfg.useRegions) {
Vector pt = toVector(vehicle.getLocation());
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
LocalPlayer localPlayer = plugin.wrapPlayer(player);
if (!plugin.getGlobalRegionManager().hasBypass(player, world)
&& !set.canBuild(localPlayer)
&& !set.allows(DefaultFlag.DESTROY_VEHICLE, localPlayer)) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission to destroy vehicles here.");
event.setCancelled(true);
return;
}
}
}
@EventHandler
public void onVehicleMove(VehicleMoveEvent event) {
Vehicle vehicle = event.getVehicle();

View File

@ -17,10 +17,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
package com.sk89q.worldguard.bukkit.listener;
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
import com.sk89q.worldguard.bukkit.ConfigurationManager;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;

View File

@ -17,8 +17,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
package com.sk89q.worldguard.bukkit.listener;
import com.sk89q.worldguard.bukkit.BukkitUtil;
import com.sk89q.worldguard.bukkit.ConfigurationManager;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.event.EventHandler;

View File

@ -17,17 +17,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.internal;
package com.sk89q.worldguard.bukkit.util;
import org.bukkit.block.Block;
import org.bukkit.block.Hopper;
import org.bukkit.material.Attachable;
import org.bukkit.material.Bed;
import org.bukkit.material.MaterialData;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* Block related utility methods.
* Utility methods to deal with blocks.
*/
public final class Blocks {
@ -35,21 +36,25 @@ private Blocks() {
}
/**
* Get the block that this block attaches to.
* Get a list of connected blocks to the given block, not including
* the given block.
*
* @param block the block to check
* @return the block attached to or null
* @param block the block
* @return a list of connected blocks, not including the given block
*/
@Nullable
public static Block getAttachesTo(Block block) {
public static List<Block> getConnected(Block block) {
MaterialData data = block.getState().getData();
if (data instanceof Attachable) {
Attachable attachable = (Attachable) data;
return block.getRelative(attachable.getAttachedFace());
if (data instanceof Bed) {
Bed bed = (Bed) data;
if (bed.isHeadOfBed()) {
return Arrays.asList(block.getRelative(bed.getFacing().getOppositeFace()));
} else {
return Arrays.asList(block.getRelative(bed.getFacing()));
}
} else {
return Collections.emptyList();
}
return null;
}
}

View File

@ -0,0 +1,114 @@
/*
* 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.util;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.Tameable;
import org.bukkit.projectiles.ProjectileSource;
import javax.annotation.Nullable;
public final class Entities {
private Entities() {
}
/**
* Test whether the given entity is tameable and tamed.
*
* @param entity the entity, or null
* @return true if tamed
*/
public static boolean isTamed(@Nullable Entity entity) {
return entity instanceof Tameable && ((Tameable) entity).isTamed();
}
/**
* Return if the given entity type is TNT-based.
*
* @param type the type
* @return true if TNT based
*/
public static boolean isTNTBased(EntityType type) {
return type == EntityType.PRIMED_TNT || type == EntityType.MINECART_TNT;
}
/**
* Return if the given entity type is a fireball
* (not including wither skulls).
*
* @param type the type
* @return true if a fireball
*/
public static boolean isFireball(EntityType type) {
return type == EntityType.FIREBALL || type == EntityType.SMALL_FIREBALL;
}
/**
* Test whether the given entity type is a vehicle type.
*
* @param type the type
* @return true if the type is a vehicle type
*/
public static boolean isVehicle(EntityType type) {
return type == EntityType.BOAT
|| isMinecart(type);
}
/**
* Test whether the given entity type is a Minecart type.
*
* @param type the type
* @return true if the type is a Minecart type
*/
public static boolean isMinecart(EntityType type) {
return type == EntityType.MINECART
|| type == EntityType.MINECART_CHEST
|| type == EntityType.MINECART_COMMAND
|| type == EntityType.MINECART_FURNACE
|| type == EntityType.MINECART_HOPPER
|| type == EntityType.MINECART_MOB_SPAWNER
|| type == EntityType.MINECART_TNT;
}
/**
* Get the underlying shooter of a projectile if one exists.
*
* @param entity the entity
* @return the shooter
*/
public static Entity getShooter(Entity entity) {
while (entity instanceof Projectile) {
Projectile projectile = (Projectile) entity;
ProjectileSource remover = projectile.getShooter();
if (remover instanceof Entity && remover != entity) {
entity = (Entity) remover;
} else {
return entity;
}
}
return entity;
}
}

View File

@ -0,0 +1,77 @@
/*
* 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.util;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
/**
* Utility methods to deal with event-related enums in Bukkit.
*/
public final class EventEnums {
private EventEnums() {
}
/**
* Return whether the given damage cause is fire-reltaed.
*
* @param cause the cause
* @return true if fire related
*/
public static boolean isFireCause(DamageCause cause) {
return cause == DamageCause.FIRE || cause == DamageCause.FIRE_TICK;
}
/**
* Return whether the given cause is an explosion.
*
* @param cause the cause
* @return true if it is an explosion cuase
*/
public static boolean isExplosionCause(DamageCause cause) {
return cause == DamageCause.BLOCK_EXPLOSION || cause == DamageCause.ENTITY_EXPLOSION;
}
/**
* Restore the statistic associated with the given cause. For example,
* for the {@link DamageCause#DROWNING} cause, the entity would have its
* air level set to its maximum.
*
* @param entity the entity
* @param cause the cuase
*/
public static void restoreStatistic(Entity entity, DamageCause cause) {
if (cause == DamageCause.DROWNING && entity instanceof LivingEntity) {
LivingEntity living = (LivingEntity) entity;
living.setRemainingAir(living.getMaximumAir());
}
if (isFireCause(cause)) {
entity.setFireTicks(0);
}
if (cause == DamageCause.LAVA) {
entity.setFireTicks(0);
}
}
}

View File

@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.internal;
package com.sk89q.worldguard.bukkit.util;
import org.bukkit.Bukkit;
import org.bukkit.event.Cancellable;
@ -34,8 +34,20 @@ private Events() {
}
/**
* Fire the {@code eventToFire} if {@code original} has not been cancelled
* and cancel the original if the fired event is cancelled.
* Fire the {@code eventToFire} and return whether the event was cancelled.
*
* @param eventToFire the event to fire
* @param <T> an event that can be fired and is cancellable
* @return true if the event was cancelled
*/
public static <T extends Event & Cancellable> boolean fireAndTestCancel( T eventToFire) {
Bukkit.getServer().getPluginManager().callEvent(eventToFire);
return eventToFire.isCancelled();
}
/**
* Fire the {@code eventToFire} and cancel the original if the fired event
* is cancelled.
*
* @param original the original event to potentially cancel
* @param eventToFire the event to fire to consider cancelling the original event
@ -43,20 +55,18 @@ private Events() {
* @return true if the event was fired and it caused the original event to be cancelled
*/
public static <T extends Event & Cancellable> boolean fireToCancel(Cancellable original, T eventToFire) {
if (!original.isCancelled()) {
Bukkit.getServer().getPluginManager().callEvent(eventToFire);
if (eventToFire.isCancelled()) {
original.setCancelled(true);
return true;
}
Bukkit.getServer().getPluginManager().callEvent(eventToFire);
if (eventToFire.isCancelled()) {
original.setCancelled(true);
return true;
}
return false;
}
/**
* Fire the {@code eventToFire} if {@code original}
* and cancel the original if the fired event is cancelled.
* Fire the {@code eventToFire} and cancel the original if the fired event
* is cancelled.
*
* @param original the original event to potentially cancel
* @param eventToFire the event to fire to consider cancelling the original event

View File

@ -0,0 +1,597 @@
/*
* 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.util;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.material.Dye;
import org.bukkit.material.MaterialData;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
/**
* Material utility class.
*/
public final class Materials {
private static final int MODIFIED_ON_CLICK = 1;
private static final int MODIFIES_BLOCKS = 2;
private static final BiMap<EntityType, Material> ENTITY_ITEMS = HashBiMap.create();
private static final Map<Material, Integer> MATERIAL_FLAGS = new HashMap<Material, Integer>();
static {
ENTITY_ITEMS.put(EntityType.PAINTING, Material.PAINTING);
ENTITY_ITEMS.put(EntityType.ARROW, Material.ARROW);
ENTITY_ITEMS.put(EntityType.SNOWBALL, Material.SNOW_BALL);
ENTITY_ITEMS.put(EntityType.FIREBALL, Material.FIREBALL);
ENTITY_ITEMS.put(EntityType.SMALL_FIREBALL, Material.FIREWORK_CHARGE);
ENTITY_ITEMS.put(EntityType.ENDER_PEARL, Material.ENDER_PEARL);
ENTITY_ITEMS.put(EntityType.THROWN_EXP_BOTTLE, Material.EXP_BOTTLE);
ENTITY_ITEMS.put(EntityType.ITEM_FRAME, Material.ITEM_FRAME);
ENTITY_ITEMS.put(EntityType.PRIMED_TNT, Material.TNT);
ENTITY_ITEMS.put(EntityType.FIREWORK, Material.FIREWORK);
ENTITY_ITEMS.put(EntityType.MINECART_COMMAND, Material.COMMAND_MINECART);
ENTITY_ITEMS.put(EntityType.BOAT, Material.BOAT);
ENTITY_ITEMS.put(EntityType.MINECART, Material.MINECART);
ENTITY_ITEMS.put(EntityType.MINECART_CHEST, Material.STORAGE_MINECART);
ENTITY_ITEMS.put(EntityType.MINECART_FURNACE, Material.POWERED_MINECART);
ENTITY_ITEMS.put(EntityType.MINECART_TNT, Material.EXPLOSIVE_MINECART);
ENTITY_ITEMS.put(EntityType.MINECART_HOPPER, Material.HOPPER_MINECART);
ENTITY_ITEMS.put(EntityType.SPLASH_POTION, Material.POTION);
ENTITY_ITEMS.put(EntityType.EGG, Material.EGG);
MATERIAL_FLAGS.put(Material.AIR, 0);
MATERIAL_FLAGS.put(Material.STONE, 0);
MATERIAL_FLAGS.put(Material.GRASS, 0);
MATERIAL_FLAGS.put(Material.DIRT, 0);
MATERIAL_FLAGS.put(Material.COBBLESTONE, 0);
MATERIAL_FLAGS.put(Material.WOOD, 0);
MATERIAL_FLAGS.put(Material.SAPLING, 0);
MATERIAL_FLAGS.put(Material.BEDROCK, 0);
MATERIAL_FLAGS.put(Material.WATER, 0);
MATERIAL_FLAGS.put(Material.STATIONARY_WATER, 0);
MATERIAL_FLAGS.put(Material.LAVA, 0);
MATERIAL_FLAGS.put(Material.STATIONARY_LAVA, 0);
MATERIAL_FLAGS.put(Material.SAND, 0);
MATERIAL_FLAGS.put(Material.GRAVEL, 0);
MATERIAL_FLAGS.put(Material.GOLD_ORE, 0);
MATERIAL_FLAGS.put(Material.IRON_ORE, 0);
MATERIAL_FLAGS.put(Material.COAL_ORE, 0);
MATERIAL_FLAGS.put(Material.LOG, 0);
MATERIAL_FLAGS.put(Material.LEAVES, 0);
MATERIAL_FLAGS.put(Material.SPONGE, 0);
MATERIAL_FLAGS.put(Material.GLASS, 0);
MATERIAL_FLAGS.put(Material.LAPIS_ORE, 0);
MATERIAL_FLAGS.put(Material.LAPIS_BLOCK, 0);
MATERIAL_FLAGS.put(Material.DISPENSER, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.SANDSTONE, 0);
MATERIAL_FLAGS.put(Material.NOTE_BLOCK, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.BED_BLOCK, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.POWERED_RAIL, 0);
MATERIAL_FLAGS.put(Material.DETECTOR_RAIL, 0);
MATERIAL_FLAGS.put(Material.PISTON_STICKY_BASE, 0);
MATERIAL_FLAGS.put(Material.WEB, 0);
MATERIAL_FLAGS.put(Material.LONG_GRASS, 0);
MATERIAL_FLAGS.put(Material.DEAD_BUSH, 0);
MATERIAL_FLAGS.put(Material.PISTON_BASE, 0);
MATERIAL_FLAGS.put(Material.PISTON_EXTENSION, 0);
MATERIAL_FLAGS.put(Material.WOOL, 0);
MATERIAL_FLAGS.put(Material.PISTON_MOVING_PIECE, 0);
MATERIAL_FLAGS.put(Material.YELLOW_FLOWER, 0);
MATERIAL_FLAGS.put(Material.RED_ROSE, 0);
MATERIAL_FLAGS.put(Material.BROWN_MUSHROOM, 0);
MATERIAL_FLAGS.put(Material.RED_MUSHROOM, 0);
MATERIAL_FLAGS.put(Material.GOLD_BLOCK, 0);
MATERIAL_FLAGS.put(Material.IRON_BLOCK, 0);
MATERIAL_FLAGS.put(Material.DOUBLE_STEP, 0);
MATERIAL_FLAGS.put(Material.STEP, 0);
MATERIAL_FLAGS.put(Material.BRICK, 0);
MATERIAL_FLAGS.put(Material.TNT, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.BOOKSHELF, 0);
MATERIAL_FLAGS.put(Material.MOSSY_COBBLESTONE, 0);
MATERIAL_FLAGS.put(Material.OBSIDIAN, 0);
MATERIAL_FLAGS.put(Material.TORCH, 0);
MATERIAL_FLAGS.put(Material.FIRE, 0);
MATERIAL_FLAGS.put(Material.MOB_SPAWNER, 0);
MATERIAL_FLAGS.put(Material.WOOD_STAIRS, 0);
MATERIAL_FLAGS.put(Material.CHEST, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.REDSTONE_WIRE, 0);
MATERIAL_FLAGS.put(Material.DIAMOND_ORE, 0);
MATERIAL_FLAGS.put(Material.DIAMOND_BLOCK, 0);
MATERIAL_FLAGS.put(Material.WORKBENCH, 0);
MATERIAL_FLAGS.put(Material.CROPS, 0);
MATERIAL_FLAGS.put(Material.SOIL, 0);
MATERIAL_FLAGS.put(Material.FURNACE, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.BURNING_FURNACE, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.SIGN_POST, 0);
MATERIAL_FLAGS.put(Material.WOODEN_DOOR, 0);
MATERIAL_FLAGS.put(Material.LADDER, 0);
MATERIAL_FLAGS.put(Material.RAILS, 0);
MATERIAL_FLAGS.put(Material.COBBLESTONE_STAIRS, 0);
MATERIAL_FLAGS.put(Material.WALL_SIGN, 0);
MATERIAL_FLAGS.put(Material.LEVER, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.STONE_PLATE, 0);
MATERIAL_FLAGS.put(Material.IRON_DOOR_BLOCK, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.WOOD_PLATE, 0);
MATERIAL_FLAGS.put(Material.REDSTONE_ORE, 0);
MATERIAL_FLAGS.put(Material.GLOWING_REDSTONE_ORE, 0);
MATERIAL_FLAGS.put(Material.REDSTONE_TORCH_OFF, 0);
MATERIAL_FLAGS.put(Material.REDSTONE_TORCH_ON, 0);
MATERIAL_FLAGS.put(Material.STONE_BUTTON, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.SNOW, 0);
MATERIAL_FLAGS.put(Material.ICE, 0);
MATERIAL_FLAGS.put(Material.SNOW_BLOCK, 0);
MATERIAL_FLAGS.put(Material.CACTUS, 0);
MATERIAL_FLAGS.put(Material.CLAY, 0);
MATERIAL_FLAGS.put(Material.SUGAR_CANE_BLOCK, 0);
MATERIAL_FLAGS.put(Material.JUKEBOX, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.FENCE, 0);
MATERIAL_FLAGS.put(Material.PUMPKIN, 0);
MATERIAL_FLAGS.put(Material.NETHERRACK, 0);
MATERIAL_FLAGS.put(Material.SOUL_SAND, 0);
MATERIAL_FLAGS.put(Material.GLOWSTONE, 0);
MATERIAL_FLAGS.put(Material.PORTAL, 0);
MATERIAL_FLAGS.put(Material.JACK_O_LANTERN, 0);
MATERIAL_FLAGS.put(Material.CAKE_BLOCK, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.DIODE_BLOCK_OFF, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.DIODE_BLOCK_ON, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.STAINED_GLASS, 0);
MATERIAL_FLAGS.put(Material.TRAP_DOOR, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.MONSTER_EGGS, 0);
MATERIAL_FLAGS.put(Material.SMOOTH_BRICK, 0);
MATERIAL_FLAGS.put(Material.HUGE_MUSHROOM_1, 0);
MATERIAL_FLAGS.put(Material.HUGE_MUSHROOM_2, 0);
MATERIAL_FLAGS.put(Material.IRON_FENCE, 0);
MATERIAL_FLAGS.put(Material.THIN_GLASS, 0);
MATERIAL_FLAGS.put(Material.MELON_BLOCK, 0);
MATERIAL_FLAGS.put(Material.PUMPKIN_STEM, 0);
MATERIAL_FLAGS.put(Material.MELON_STEM, 0);
MATERIAL_FLAGS.put(Material.VINE, 0);
MATERIAL_FLAGS.put(Material.FENCE_GATE, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.BRICK_STAIRS, 0);
MATERIAL_FLAGS.put(Material.SMOOTH_STAIRS, 0);
MATERIAL_FLAGS.put(Material.MYCEL, 0);
MATERIAL_FLAGS.put(Material.WATER_LILY, 0);
MATERIAL_FLAGS.put(Material.NETHER_BRICK, 0);
MATERIAL_FLAGS.put(Material.NETHER_FENCE, 0);
MATERIAL_FLAGS.put(Material.NETHER_BRICK_STAIRS, 0);
MATERIAL_FLAGS.put(Material.NETHER_WARTS, 0);
MATERIAL_FLAGS.put(Material.ENCHANTMENT_TABLE, 0);
MATERIAL_FLAGS.put(Material.BREWING_STAND, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.CAULDRON, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.ENDER_PORTAL, 0);
MATERIAL_FLAGS.put(Material.ENDER_PORTAL_FRAME, 0);
MATERIAL_FLAGS.put(Material.ENDER_STONE, 0);
MATERIAL_FLAGS.put(Material.DRAGON_EGG, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.REDSTONE_LAMP_OFF, 0);
MATERIAL_FLAGS.put(Material.REDSTONE_LAMP_ON, 0);
MATERIAL_FLAGS.put(Material.WOOD_DOUBLE_STEP, 0);
MATERIAL_FLAGS.put(Material.WOOD_STEP, 0);
MATERIAL_FLAGS.put(Material.COCOA, 0);
MATERIAL_FLAGS.put(Material.SANDSTONE_STAIRS, 0);
MATERIAL_FLAGS.put(Material.EMERALD_ORE, 0);
MATERIAL_FLAGS.put(Material.ENDER_CHEST, 0);
MATERIAL_FLAGS.put(Material.TRIPWIRE_HOOK, 0);
MATERIAL_FLAGS.put(Material.TRIPWIRE, 0);
MATERIAL_FLAGS.put(Material.EMERALD_BLOCK, 0);
MATERIAL_FLAGS.put(Material.SPRUCE_WOOD_STAIRS, 0);
MATERIAL_FLAGS.put(Material.BIRCH_WOOD_STAIRS, 0);
MATERIAL_FLAGS.put(Material.JUNGLE_WOOD_STAIRS, 0);
MATERIAL_FLAGS.put(Material.COMMAND, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.BEACON, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.COBBLE_WALL, 0);
MATERIAL_FLAGS.put(Material.FLOWER_POT, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.CARROT, 0);
MATERIAL_FLAGS.put(Material.POTATO, 0);
MATERIAL_FLAGS.put(Material.WOOD_BUTTON, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.SKULL, 0);
MATERIAL_FLAGS.put(Material.ANVIL, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.TRAPPED_CHEST, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.GOLD_PLATE, 0);
MATERIAL_FLAGS.put(Material.IRON_PLATE, 0);
MATERIAL_FLAGS.put(Material.REDSTONE_COMPARATOR_OFF, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.REDSTONE_COMPARATOR_ON, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.DAYLIGHT_DETECTOR, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.REDSTONE_BLOCK, 0);
MATERIAL_FLAGS.put(Material.QUARTZ_ORE, 0);
MATERIAL_FLAGS.put(Material.HOPPER, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.QUARTZ_BLOCK, 0);
MATERIAL_FLAGS.put(Material.QUARTZ_STAIRS, 0);
MATERIAL_FLAGS.put(Material.ACTIVATOR_RAIL, 0);
MATERIAL_FLAGS.put(Material.DROPPER, MODIFIED_ON_CLICK);
MATERIAL_FLAGS.put(Material.STAINED_CLAY, 0);
MATERIAL_FLAGS.put(Material.STAINED_GLASS_PANE, 0);
MATERIAL_FLAGS.put(Material.LEAVES_2, 0);
MATERIAL_FLAGS.put(Material.LOG_2, 0);
MATERIAL_FLAGS.put(Material.ACACIA_STAIRS, 0);
MATERIAL_FLAGS.put(Material.DARK_OAK_STAIRS, 0);
MATERIAL_FLAGS.put(Material.HAY_BLOCK, 0);
MATERIAL_FLAGS.put(Material.CARPET, 0);
MATERIAL_FLAGS.put(Material.HARD_CLAY, 0);
MATERIAL_FLAGS.put(Material.COAL_BLOCK, 0);
MATERIAL_FLAGS.put(Material.PACKED_ICE, 0);
MATERIAL_FLAGS.put(Material.DOUBLE_PLANT, 0);
MATERIAL_FLAGS.put(Material.IRON_SPADE, 0);
MATERIAL_FLAGS.put(Material.IRON_PICKAXE, 0);
MATERIAL_FLAGS.put(Material.IRON_AXE, 0);
MATERIAL_FLAGS.put(Material.FLINT_AND_STEEL, 0);
MATERIAL_FLAGS.put(Material.APPLE, 0);
MATERIAL_FLAGS.put(Material.BOW, 0);
MATERIAL_FLAGS.put(Material.ARROW, 0);
MATERIAL_FLAGS.put(Material.COAL, 0);
MATERIAL_FLAGS.put(Material.DIAMOND, 0);
MATERIAL_FLAGS.put(Material.IRON_INGOT, 0);
MATERIAL_FLAGS.put(Material.GOLD_INGOT, 0);
MATERIAL_FLAGS.put(Material.IRON_SWORD, 0);
MATERIAL_FLAGS.put(Material.WOOD_SWORD, 0);
MATERIAL_FLAGS.put(Material.WOOD_SPADE, 0);
MATERIAL_FLAGS.put(Material.WOOD_PICKAXE, 0);
MATERIAL_FLAGS.put(Material.WOOD_AXE, 0);
MATERIAL_FLAGS.put(Material.STONE_SWORD, 0);
MATERIAL_FLAGS.put(Material.STONE_SPADE, 0);
MATERIAL_FLAGS.put(Material.STONE_PICKAXE, 0);
MATERIAL_FLAGS.put(Material.STONE_AXE, 0);
MATERIAL_FLAGS.put(Material.DIAMOND_SWORD, 0);
MATERIAL_FLAGS.put(Material.DIAMOND_SPADE, 0);
MATERIAL_FLAGS.put(Material.DIAMOND_PICKAXE, 0);
MATERIAL_FLAGS.put(Material.DIAMOND_AXE, 0);
MATERIAL_FLAGS.put(Material.STICK, 0);
MATERIAL_FLAGS.put(Material.BOWL, 0);
MATERIAL_FLAGS.put(Material.MUSHROOM_SOUP, 0);
MATERIAL_FLAGS.put(Material.GOLD_SWORD, 0);
MATERIAL_FLAGS.put(Material.GOLD_SPADE, 0);
MATERIAL_FLAGS.put(Material.GOLD_PICKAXE, 0);
MATERIAL_FLAGS.put(Material.GOLD_AXE, 0);
MATERIAL_FLAGS.put(Material.STRING, 0);
MATERIAL_FLAGS.put(Material.FEATHER, 0);
MATERIAL_FLAGS.put(Material.SULPHUR, 0);
MATERIAL_FLAGS.put(Material.WOOD_HOE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.STONE_HOE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.IRON_HOE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.DIAMOND_HOE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.GOLD_HOE, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.SEEDS, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.WHEAT, 0);
MATERIAL_FLAGS.put(Material.BREAD, 0);
MATERIAL_FLAGS.put(Material.LEATHER_HELMET, 0);
MATERIAL_FLAGS.put(Material.LEATHER_CHESTPLATE, 0);
MATERIAL_FLAGS.put(Material.LEATHER_LEGGINGS, 0);
MATERIAL_FLAGS.put(Material.LEATHER_BOOTS, 0);
MATERIAL_FLAGS.put(Material.CHAINMAIL_HELMET, 0);
MATERIAL_FLAGS.put(Material.CHAINMAIL_CHESTPLATE, 0);
MATERIAL_FLAGS.put(Material.CHAINMAIL_LEGGINGS, 0);
MATERIAL_FLAGS.put(Material.CHAINMAIL_BOOTS, 0);
MATERIAL_FLAGS.put(Material.IRON_HELMET, 0);
MATERIAL_FLAGS.put(Material.IRON_CHESTPLATE, 0);
MATERIAL_FLAGS.put(Material.IRON_LEGGINGS, 0);
MATERIAL_FLAGS.put(Material.IRON_BOOTS, 0);
MATERIAL_FLAGS.put(Material.DIAMOND_HELMET, 0);
MATERIAL_FLAGS.put(Material.DIAMOND_CHESTPLATE, 0);
MATERIAL_FLAGS.put(Material.DIAMOND_LEGGINGS, 0);
MATERIAL_FLAGS.put(Material.DIAMOND_BOOTS, 0);
MATERIAL_FLAGS.put(Material.GOLD_HELMET, 0);
MATERIAL_FLAGS.put(Material.GOLD_CHESTPLATE, 0);
MATERIAL_FLAGS.put(Material.GOLD_LEGGINGS, 0);
MATERIAL_FLAGS.put(Material.GOLD_BOOTS, 0);
MATERIAL_FLAGS.put(Material.FLINT, 0);
MATERIAL_FLAGS.put(Material.PORK, 0);
MATERIAL_FLAGS.put(Material.GRILLED_PORK, 0);
MATERIAL_FLAGS.put(Material.PAINTING, 0);
MATERIAL_FLAGS.put(Material.GOLDEN_APPLE, 0);
MATERIAL_FLAGS.put(Material.SIGN, 0);
MATERIAL_FLAGS.put(Material.WOOD_DOOR, 0);
MATERIAL_FLAGS.put(Material.BUCKET, 0);
MATERIAL_FLAGS.put(Material.WATER_BUCKET, 0);
MATERIAL_FLAGS.put(Material.LAVA_BUCKET, 0);
MATERIAL_FLAGS.put(Material.MINECART, 0);
MATERIAL_FLAGS.put(Material.SADDLE, 0);
MATERIAL_FLAGS.put(Material.IRON_DOOR, 0);
MATERIAL_FLAGS.put(Material.REDSTONE, 0);
MATERIAL_FLAGS.put(Material.SNOW_BALL, 0);
MATERIAL_FLAGS.put(Material.BOAT, 0);
MATERIAL_FLAGS.put(Material.LEATHER, 0);
MATERIAL_FLAGS.put(Material.MILK_BUCKET, 0);
MATERIAL_FLAGS.put(Material.CLAY_BRICK, 0);
MATERIAL_FLAGS.put(Material.CLAY_BALL, 0);
MATERIAL_FLAGS.put(Material.SUGAR_CANE, 0);
MATERIAL_FLAGS.put(Material.PAPER, 0);
MATERIAL_FLAGS.put(Material.BOOK, 0);
MATERIAL_FLAGS.put(Material.SLIME_BALL, 0);
MATERIAL_FLAGS.put(Material.STORAGE_MINECART, 0);
MATERIAL_FLAGS.put(Material.POWERED_MINECART, 0);
MATERIAL_FLAGS.put(Material.EGG, 0);
MATERIAL_FLAGS.put(Material.COMPASS, 0);
MATERIAL_FLAGS.put(Material.FISHING_ROD, 0);
MATERIAL_FLAGS.put(Material.WATCH, 0);
MATERIAL_FLAGS.put(Material.GLOWSTONE_DUST, 0);
MATERIAL_FLAGS.put(Material.RAW_FISH, 0);
MATERIAL_FLAGS.put(Material.COOKED_FISH, 0);
MATERIAL_FLAGS.put(Material.INK_SACK, 0);
MATERIAL_FLAGS.put(Material.BONE, 0);
MATERIAL_FLAGS.put(Material.SUGAR, 0);
MATERIAL_FLAGS.put(Material.CAKE, 0);
MATERIAL_FLAGS.put(Material.BED, 0);
MATERIAL_FLAGS.put(Material.DIODE, 0);
MATERIAL_FLAGS.put(Material.COOKIE, 0);
MATERIAL_FLAGS.put(Material.MAP, 0);
MATERIAL_FLAGS.put(Material.SHEARS, MODIFIES_BLOCKS);
MATERIAL_FLAGS.put(Material.MELON, 0);
MATERIAL_FLAGS.put(Material.PUMPKIN_SEEDS, 0);
MATERIAL_FLAGS.put(Material.MELON_SEEDS, 0);
MATERIAL_FLAGS.put(Material.RAW_BEEF, 0);
MATERIAL_FLAGS.put(Material.COOKED_BEEF, 0);
MATERIAL_FLAGS.put(Material.RAW_CHICKEN, 0);
MATERIAL_FLAGS.put(Material.COOKED_CHICKEN, 0);
MATERIAL_FLAGS.put(Material.ROTTEN_FLESH, 0);
MATERIAL_FLAGS.put(Material.ENDER_PEARL, 0);
MATERIAL_FLAGS.put(Material.BLAZE_ROD, 0);
MATERIAL_FLAGS.put(Material.GHAST_TEAR, 0);
MATERIAL_FLAGS.put(Material.GOLD_NUGGET, 0);
MATERIAL_FLAGS.put(Material.NETHER_STALK, 0);
MATERIAL_FLAGS.put(Material.POTION, 0);
MATERIAL_FLAGS.put(Material.GLASS_BOTTLE, 0);
MATERIAL_FLAGS.put(Material.SPIDER_EYE, 0);
MATERIAL_FLAGS.put(Material.FERMENTED_SPIDER_EYE, 0);
MATERIAL_FLAGS.put(Material.BLAZE_POWDER, 0);
MATERIAL_FLAGS.put(Material.MAGMA_CREAM, 0);
MATERIAL_FLAGS.put(Material.BREWING_STAND_ITEM, 0);
MATERIAL_FLAGS.put(Material.CAULDRON_ITEM, 0);
MATERIAL_FLAGS.put(Material.EYE_OF_ENDER, 0);
MATERIAL_FLAGS.put(Material.SPECKLED_MELON, 0);
MATERIAL_FLAGS.put(Material.MONSTER_EGG, 0);
MATERIAL_FLAGS.put(Material.EXP_BOTTLE, 0);
MATERIAL_FLAGS.put(Material.FIREBALL, 0);
MATERIAL_FLAGS.put(Material.BOOK_AND_QUILL, 0);
MATERIAL_FLAGS.put(Material.WRITTEN_BOOK, 0);
MATERIAL_FLAGS.put(Material.EMERALD, 0);
MATERIAL_FLAGS.put(Material.ITEM_FRAME, 0);
MATERIAL_FLAGS.put(Material.FLOWER_POT_ITEM, 0);
MATERIAL_FLAGS.put(Material.CARROT_ITEM, 0);
MATERIAL_FLAGS.put(Material.POTATO_ITEM, 0);
MATERIAL_FLAGS.put(Material.BAKED_POTATO, 0);
MATERIAL_FLAGS.put(Material.POISONOUS_POTATO, 0);
MATERIAL_FLAGS.put(Material.EMPTY_MAP, 0);
MATERIAL_FLAGS.put(Material.GOLDEN_CARROT, 0);
MATERIAL_FLAGS.put(Material.SKULL_ITEM, 0);
MATERIAL_FLAGS.put(Material.CARROT_STICK, 0);
MATERIAL_FLAGS.put(Material.NETHER_STAR, 0);
MATERIAL_FLAGS.put(Material.PUMPKIN_PIE, 0);
MATERIAL_FLAGS.put(Material.FIREWORK, 0);
MATERIAL_FLAGS.put(Material.FIREWORK_CHARGE, 0);
MATERIAL_FLAGS.put(Material.ENCHANTED_BOOK, 0);
MATERIAL_FLAGS.put(Material.REDSTONE_COMPARATOR, 0);
MATERIAL_FLAGS.put(Material.NETHER_BRICK_ITEM, 0);
MATERIAL_FLAGS.put(Material.QUARTZ, 0);
MATERIAL_FLAGS.put(Material.EXPLOSIVE_MINECART, 0);
MATERIAL_FLAGS.put(Material.HOPPER_MINECART, 0);
MATERIAL_FLAGS.put(Material.IRON_BARDING, 0);
MATERIAL_FLAGS.put(Material.GOLD_BARDING, 0);
MATERIAL_FLAGS.put(Material.DIAMOND_BARDING, 0);
MATERIAL_FLAGS.put(Material.LEASH, 0);
MATERIAL_FLAGS.put(Material.NAME_TAG, 0);
MATERIAL_FLAGS.put(Material.COMMAND_MINECART, 0);
MATERIAL_FLAGS.put(Material.GOLD_RECORD, 0);
MATERIAL_FLAGS.put(Material.GREEN_RECORD, 0);
MATERIAL_FLAGS.put(Material.RECORD_3, 0);
MATERIAL_FLAGS.put(Material.RECORD_4, 0);
MATERIAL_FLAGS.put(Material.RECORD_5, 0);
MATERIAL_FLAGS.put(Material.RECORD_6, 0);
MATERIAL_FLAGS.put(Material.RECORD_7, 0);
MATERIAL_FLAGS.put(Material.RECORD_8, 0);
MATERIAL_FLAGS.put(Material.RECORD_9, 0);
MATERIAL_FLAGS.put(Material.RECORD_10, 0);
MATERIAL_FLAGS.put(Material.RECORD_11, 0);
MATERIAL_FLAGS.put(Material.RECORD_12, 0);
}
private Materials() {
}
/**
* Get the related material for an entity type.
*
* @param type the entity type
* @return the related material or {@code null} if one is not known or exists
*/
@Nullable
public static Material getRelatedMaterial(EntityType type) {
return ENTITY_ITEMS.get(type);
}
/**
* Get the material of the block placed by the given bucket, defaulting
* to water if the bucket type is not known.
*
* <p>If a non-bucket material is given, it will be assumed to be
* an unknown bucket type. If the given bucket doesn't have a block form
* (it can't be placed), then water will be returned (i.e. for milk).
* Be aware that either the stationary or non-stationary material may be
* returned.</p>
*
* @param type the bucket material
* @return the block material
*/
public static Material getBucketBlockMaterial(Material type) {
switch (type) {
case LAVA_BUCKET:
return Material.LAVA;
case MILK_BUCKET:
return Material.WATER;
default:
return Material.WATER;
}
}
/**
* Test whether the given material is a mushroom.
*
* @param material the material
* @return true if a mushroom block
*/
public static boolean isMushroom(Material material) {
return material == Material.RED_MUSHROOM || material == Material.BROWN_MUSHROOM;
}
/**
* Test whether the given material is a leaf block.
*
* @param material the material
* @return true if a leaf block
*/
public static boolean isLeaf(Material material) {
return material == Material.LEAVES || material == Material.LEAVES_2;
}
/**
* Test whether the given material is a liquid block.
*
* @param material the material
* @return true if a liquid block
*/
public static boolean isLiquid(Material material) {
return isWater(material) || isLava(material);
}
/**
* Test whether the given material is water.
*
* @param material the material
* @return true if a water block
*/
public static boolean isWater(Material material) {
return material == Material.WATER || material == Material.STATIONARY_WATER;
}
/**
* Test whether the given material is lava.
*
* @param material the material
* @return true if a lava block
*/
public static boolean isLava(Material material) {
return material == Material.LAVA || material == Material.STATIONARY_LAVA;
}
/**
* Test whether the given material is a portal material.
*
* @param material the material
* @return true if a portal block
*/
public static boolean isPortal(Material material) {
return material == Material.PORTAL || material == Material.ENDER_PORTAL;
}
/**
* Test whether the given material data is of the given dye color.
*
* <p>Returns false for non-dyed items.</p>
*
* @param data the data
* @return true if it is the provided dye color
*/
public static boolean isDyeColor(MaterialData data, DyeColor color) {
return data instanceof Dye && ((Dye) data).getColor() == color;
}
/**
* Test whether the given material is a rail block.
*
* @param material the material
* @return true if a rail block
*/
public static boolean isRailBlock(Material material) {
return material == Material.RAILS
|| material == Material.ACTIVATOR_RAIL
|| material == Material.DETECTOR_RAIL
|| material == Material.POWERED_RAIL;
}
/**
* Test whether the given material is a Minecart.
*
* @param material the material
* @return true if a Minecart item
*/
public static boolean isMinecart(Material material) {
return material == Material.MINECART
|| material == Material.COMMAND_MINECART
|| material == Material.EXPLOSIVE_MINECART
|| material == Material.HOPPER_MINECART
|| material == Material.POWERED_MINECART
|| material == Material.STORAGE_MINECART;
}
/**
* Test whether the given material is an inventory block.
*
* @param material the material
* @return true if an inventory block
*/
public static boolean isInventoryBlock(Material material) {
return material == Material.CHEST
|| material == Material.JUKEBOX
|| material == Material.DISPENSER
|| material == Material.FURNACE
|| material == Material.BURNING_FURNACE
|| material == Material.BREWING_STAND
|| material == Material.TRAPPED_CHEST
|| material == Material.HOPPER
|| material == Material.DROPPER;
}
/**
* Test whether the given material is a block that is modified when it is
* left or right clicked.
*
* <p>This test is conservative, returning true for blocks that it is not
* aware of.</p>
*
* @param material the material
* @return true if the block is modified
*/
public static boolean isBlockModifiedOnClick(Material material) {
Integer flags = MATERIAL_FLAGS.get(material);
return flags == null || (flags & MODIFIED_ON_CLICK) == MODIFIED_ON_CLICK;
}
/**
* Test whether the given item modifies a given block when right clicked.
*
* <p>This test is conservative, returning true for items that it is not
* aware of or does not have the details for.</p>
*
* @param item the item
* @param block the block
* @return true if the item is applied to the block
*/
public static boolean isItemAppliedToBlock(Material item, Material block) {
Integer flags = MATERIAL_FLAGS.get(item);
return flags == null || (flags & MODIFIES_BLOCKS) == MODIFIES_BLOCKS;
}
}

View File

@ -0,0 +1,95 @@
/*
* 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.util;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.bukkit.BukkitUtil;
import com.sk89q.worldguard.bukkit.ConfigurationManager;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.GlobalRegionManager;
import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import javax.annotation.Nullable;
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
public class RegionQuery {
private final ConfigurationManager config;
private final GlobalRegionManager globalManager;
@Nullable
private final LocalPlayer localPlayer;
public RegionQuery(WorldGuardPlugin plugin, @Nullable Player player) {
this.config = plugin.getGlobalStateManager();
this.globalManager = plugin.getGlobalRegionManager();
this.localPlayer = player != null ? plugin.wrapPlayer(player) : null;
}
public boolean canBuild(Location location) {
World world = location.getWorld();
WorldConfiguration worldConfig = config.get(world);
if (!worldConfig.useRegions) {
return true;
}
if (localPlayer != null && globalManager.hasBypass(localPlayer, world)) {
return true;
} else {
RegionManager manager = globalManager.get(location.getWorld());
return manager.getApplicableRegions(BukkitUtil.toVector(location)).canBuild(localPlayer);
}
}
public boolean canConstruct(Location location) {
World world = location.getWorld();
WorldConfiguration worldConfig = config.get(world);
if (!worldConfig.useRegions) {
return true;
}
if (localPlayer != null && globalManager.hasBypass(localPlayer, world)) {
return true;
} else {
RegionManager manager = globalManager.get(location.getWorld());
return manager.getApplicableRegions(BukkitUtil.toVector(location)).canConstruct(localPlayer);
}
}
public boolean allows(StateFlag flag, Location location) {
World world = location.getWorld();
WorldConfiguration worldConfig = config.get(world);
if (!worldConfig.useRegions) {
return true;
}
RegionManager manager = globalManager.get(location.getWorld());
return manager.getApplicableRegions(toVector(location)).allows(flag, localPlayer);
}
}

View File

@ -0,0 +1,78 @@
/*
* 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.util;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.metadata.Metadatable;
import javax.annotation.Nullable;
import java.util.List;
/**
* Utility methods for dealing with metadata on entities.
*
* <p>WorldGuard is placed as the owner of all values.</p>
*/
public final class WGMetadata {
private WGMetadata() {
}
/**
* Add some metadata to a target.
*
* @param target the target
* @param key the key
* @param value the value
*/
public static void put(Metadatable target, String key, Object value) {
target.setMetadata(key, new FixedMetadataValue(WorldGuardPlugin.inst(), value));
}
/**
* Get the (first) metadata value on the given target that has the given
* key and is of the given class type.
*
* @param target the target
* @param key the key
* @param expected the type of the value
* @param <T> the type of the value
* @return a value, or {@code null} if one does not exists
*/
@Nullable
@SuppressWarnings("unchecked")
public static <T> T getIfPresent(Metadatable target, String key, Class<T> expected) {
List<MetadataValue> values = target.getMetadata(key);
WorldGuardPlugin owner = WorldGuardPlugin.inst();
for (MetadataValue value : values) {
if (value.getOwningPlugin() == owner) {
Object v = value.value();
if (expected.isInstance(v)) {
return (T) v;
}
}
}
return null;
}
}

View File

@ -1,38 +0,0 @@
/*
* 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.internal.cause;
/**
* Represents a possible cause of an event.
*
* <p>Example causes include players, blocks, entities, and many more.</p>
*
* @param <T> the wrapped object type
*/
public interface Cause<T> {
/**
* Get the underlying object.
*
* @return the underlying object
*/
T get();
}

View File

@ -1,100 +0,0 @@
/*
* 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.internal.cause;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* Utility methods to handle {@code Cause}s.
*/
public final class Causes {
private Causes() {
}
/**
* Get the first player that is in the list of causes.
*
* @param causes a list of causes, where the originating causes are at the beginning
* @return the player or null
*/
@Nullable
public static Player getInvolvedPlayer(List<? extends Cause<?>> causes) {
for (Cause cause : causes) {
if (cause instanceof PlayerCause) {
return ((PlayerCause) cause).get();
}
}
return null;
}
/**
* Test whether the list of causes may indicate that a player was part of
* the cause, directly or indirectly.
*
* <p>An indirect cause would be a dispenser, for example.</p>
*
* @param causes a list of cuases
* @return true if the event involved a player
*/
public static boolean mayInvolvePlayer(List<? extends Cause<?>> causes) {
for (Cause<?> cause : causes) {
if (cause instanceof PlayerCause || cause instanceof BlockCause) {
return true; // This needs to be made smarter later
}
}
return false;
}
/**
* Create a list of causes from a list of objects representing causes.
*
* @param cause an array of causes, where the originating causes are at the beginning
* @return a list of causes, where the originating causes are at the beginning
*/
public static List<? extends Cause<?>> create(Object ... cause) {
List<Cause<?>> causes = new ArrayList<Cause<?>>(cause.length);
for (Object o : cause) {
if (o == null) {
continue;
}
if (o instanceof Player) {
causes.add(new PlayerCause((Player) o));
} else if (o instanceof Block) {
causes.add(new BlockCause((Block) o));
} else if (o instanceof Entity) {
causes.add(new EntityCause((Entity) o));
} else {
causes.add(new UnknownCause(o));
}
}
return causes;
}
}

View File

@ -1,48 +0,0 @@
/*
* 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.internal.cause;
import org.bukkit.entity.Player;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A cause that is the player.
*/
public class PlayerCause implements Cause<Player> {
private final Player player;
/**
* Create a new instance.
*
* @param player the player
*/
public PlayerCause(Player player) {
checkNotNull(player);
this.player = player;
}
@Override
public Player get() {
return player;
}
}

View File

@ -1,46 +0,0 @@
/*
* 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.internal.cause;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A cause that is not known.
*/
public class UnknownCause implements Cause<Object> {
private final Object cause;
/**
* Create a new instance.
*
* @param cause the underlying object
*/
public UnknownCause(Object cause) {
checkNotNull(cause);
this.cause = cause;
}
@Override
public Object get() {
return cause;
}
}

View File

@ -1,31 +0,0 @@
/*
* 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.internal.event;
/**
* Represents a possible act upon an object.
*/
public enum Interaction {
PLACE,
BREAK,
INTERACT
}

View File

@ -1,90 +0,0 @@
/*
* 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.internal.listener;
import com.sk89q.worldguard.blacklist.event.BlockBreakBlacklistEvent;
import com.sk89q.worldguard.blacklist.event.BlockPlaceBlacklistEvent;
import com.sk89q.worldguard.blacklist.event.ItemDestroyWithBlacklistEvent;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.internal.cause.Causes;
import com.sk89q.worldguard.internal.event.BlockInteractEvent;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import static com.sk89q.worldguard.bukkit.BukkitUtil.createTarget;
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
/**
* Handle events that need to be processed by the blacklist.
*/
public class BlacklistListener extends AbstractListener {
/**
* Construct the listener.
*
* @param plugin an instance of WorldGuardPlugin
*/
public BlacklistListener(WorldGuardPlugin plugin) {
super(plugin);
}
@EventHandler(ignoreCancelled = true)
public void handleBlockInteract(BlockInteractEvent event) {
Player player = Causes.getInvolvedPlayer(event.getCauses());
Block target = event.getTarget();
WorldConfiguration wcfg = getWorldConfig(player);
// Blacklist guard
if (wcfg.getBlacklist() == null) {
return;
}
if (player != null) {
switch (event.getInteraction()) {
case BREAK:
if (!wcfg.getBlacklist().check(
new BlockBreakBlacklistEvent(getPlugin().wrapPlayer(player), toVector(target), createTarget(target)), false, false)) {
event.setCancelled(true);
return;
}
if (!wcfg.getBlacklist().check(
new ItemDestroyWithBlacklistEvent(getPlugin().wrapPlayer(player), toVector(target), createTarget(player.getItemInHand())), false, false)) {
event.setCancelled(true);
return;
}
break;
case PLACE:
if (!wcfg.getBlacklist().check(
new BlockPlaceBlacklistEvent(getPlugin().wrapPlayer(player), toVector(target), createTarget(target)), false, false)) {
event.setCancelled(true);
return;
}
break;
}
}
}
}

View File

@ -1,76 +0,0 @@
/*
* 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.internal.listener;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.internal.cause.Causes;
import com.sk89q.worldguard.internal.event.Interaction;
import com.sk89q.worldguard.internal.event.BlockInteractEvent;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
/**
* Handle events that need to be processed by the chest protection.
*/
public class ChestProtectionListener extends AbstractListener {
/**
* Construct the listener.
*
* @param plugin an instance of WorldGuardPlugin
*/
public ChestProtectionListener(WorldGuardPlugin plugin) {
super(plugin);
}
@EventHandler(ignoreCancelled = true)
public void handleBlockInteract(BlockInteractEvent event) {
Player player = Causes.getInvolvedPlayer(event.getCauses());
Block target = event.getTarget();
WorldConfiguration wcfg = getWorldConfig(player);
// Early guard
if (!wcfg.signChestProtection) {
return;
}
if (player != null) {
if (wcfg.isChestProtected(target, player)) {
player.sendMessage(ChatColor.DARK_RED + "This chest is protected.");
event.setCancelled(true);
return;
}
if (event.getInteraction() == Interaction.PLACE) {
if (wcfg.getChestProtection().isChest(target.getTypeId())) {
if (wcfg.isAdjacentChestProtected(target, player)) {
player.sendMessage(ChatColor.DARK_RED + "This spot is for a chest that you don't have permission for.");
event.setCancelled(true);
return;
}
}
}
}
}
}

View File

@ -1,72 +0,0 @@
/*
* 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.internal.listener;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.internal.cause.Causes;
import com.sk89q.worldguard.internal.event.Interaction;
import com.sk89q.worldguard.internal.event.BlockInteractEvent;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
/**
* Handle events that need to be processed by region protection.
*/
public class RegionProtectionListener extends AbstractListener {
/**
* Construct the listener.
*
* @param plugin an instance of WorldGuardPlugin
*/
public RegionProtectionListener(WorldGuardPlugin plugin) {
super(plugin);
}
private void tellErrorMessage(CommandSender sender, Object subject) {
sender.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
}
@EventHandler(ignoreCancelled = true)
public void handleBlockInteract(BlockInteractEvent event) {
Player player = Causes.getInvolvedPlayer(event.getCauses());
Block target = event.getTarget();
if (player != null) {
if (!getPlugin().getGlobalRegionManager().canBuild(player, target)) {
tellErrorMessage(player, target);
event.setCancelled(true);
return;
}
if (event.getInteraction() != Interaction.INTERACT) {
if (!getPlugin().getGlobalRegionManager().canConstruct(player, target)) {
tellErrorMessage(player, target);
event.setCancelled(true);
return;
}
}
}
}
}