Add helper ProtectionQuery class for other plugins.

This commit is contained in:
sk89q 2014-08-24 17:01:52 -07:00
parent fa422bef32
commit 8e320b6dbe
10 changed files with 281 additions and 24 deletions

View File

@ -34,8 +34,13 @@ public class BukkitPlayer extends LocalPlayer {
private final WorldGuardPlugin plugin;
private final Player player;
private final String name;
private final boolean silenced;
public BukkitPlayer(WorldGuardPlugin plugin, Player player) {
this(plugin, player, false);
}
BukkitPlayer(WorldGuardPlugin plugin, Player player, boolean silenced) {
checkNotNull(plugin);
checkNotNull(player);
@ -43,6 +48,7 @@ public BukkitPlayer(WorldGuardPlugin plugin, Player player) {
this.player = player;
// getName() takes longer than before in newer versions of Minecraft
this.name = player.getName();
this.silenced = silenced;
}
@Override
@ -68,13 +74,17 @@ public Vector getPosition() {
@Override
public void kick(String msg) {
player.kickPlayer(msg);
if (!silenced) {
player.kickPlayer(msg);
}
}
@Override
public void ban(String msg) {
player.setBanned(true);
player.kickPlayer(msg);
if (!silenced) {
player.setBanned(true);
player.kickPlayer(msg);
}
}
@Override
@ -84,7 +94,9 @@ public String[] getGroups() {
@Override
public void printRaw(String msg) {
player.sendMessage(msg);
if (!silenced) {
player.sendMessage(msg);
}
}
@Override

View File

@ -0,0 +1,153 @@
/*
* 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.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.DamageEntityEvent;
import com.sk89q.worldguard.bukkit.event.entity.SpawnEntityEvent;
import com.sk89q.worldguard.bukkit.event.entity.UseEntityEvent;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import javax.annotation.Nullable;
import static com.sk89q.worldguard.bukkit.event.DelegateEvents.setSilent;
import static com.sk89q.worldguard.bukkit.util.Events.fireAndTestCancel;
/**
* A helper class to query whether a block or entity is protected by
* WorldGuard.
*/
public class ProtectionQuery {
/**
* Test whether a block can be placed at a given location.
*
* <p>The cause does not have to be a player. It can be {@code null}
* if the cause is not known, although the checks will executed
* assuming that the actor is a non-member of all regions.</p>
*
* @param cause the cause, which can be a block, an entity, or a player, or {@code null} if unknown
* @param location the location of the block
* @param newMaterial the new material
* @return true if the action is permitted
*/
public boolean testBlockPlace(@Nullable Object cause, Location location, Material newMaterial) {
return !fireAndTestCancel(setSilent(new PlaceBlockEvent(null, Cause.create(cause), location, newMaterial)));
}
/**
* Test whether a block can be broken.
*
* <p>The cause does not have to be a player. It can be {@code null}
* if the cause is not known, although the checks will executed
* assuming that the actor is a non-member of all regions.</p>
*
* @param cause the cause, which can be a block, an entity, or a player, or {@code null} if unknown
* @param block the block broken
* @return true if the action is permitted
*/
public boolean testBlockBreak(@Nullable Object cause, Block block) {
return !fireAndTestCancel(setSilent(new BreakBlockEvent(null, Cause.create(cause), block)));
}
/**
* Test whether a block can be interacted with.
*
* <p>The cause does not have to be a player. It can be {@code null}
* if the cause is not known, although the checks will executed
* assuming that the actor is a non-member of all regions.</p>
*
* @param cause the cause, which can be a block, an entity, or a player, or {@code null} if unknown
* @param block the block that is interacted with
* @return true if the action is permitted
*/
public boolean testBlockInteract(@Nullable Object cause, Block block) {
return !fireAndTestCancel(setSilent(new UseBlockEvent(null, Cause.create(cause), block)));
}
/**
* Test whether an entity can be placed.
*
* <p>The cause does not have to be a player. It can be {@code null}
* if the cause is not known, although the checks will executed
* assuming that the actor is a non-member of all regions.</p>
*
* @param cause the cause, which can be a block, an entity, or a player, or {@code null} if unknown
* @param location the location that the entity will be spawned at
* @param type the type that is to be spawned
* @return true if the action is permitted
*/
public boolean testEntityPlace(@Nullable Object cause, Location location, EntityType type) {
return !fireAndTestCancel(setSilent(new SpawnEntityEvent(null, Cause.create(cause), location, type)));
}
/**
* Test whether an entity can be destroyed.
*
* <p>The cause does not have to be a player. It can be {@code null}
* if the cause is not known, although the checks will executed
* assuming that the actor is a non-member of all regions.</p>
*
* @param cause the cause, which can be a block, an entity, or a player, or {@code null} if unknown
* @param entity the entity broken
* @return true if the action is permitted
*/
public boolean testEntityDestroy(@Nullable Object cause, Entity entity) {
return !fireAndTestCancel(setSilent(new SpawnEntityEvent(null, Cause.create(cause), entity)));
}
/**
* Test whether an entity can be interacted with.
*
* <p>The cause does not have to be a player. It can be {@code null}
* if the cause is not known, although the checks will executed
* assuming that the actor is a non-member of all regions.</p>
*
* @param cause the cause, which can be a block, an entity, or a player, or {@code null} if unknown
* @param entity the entity interacted with
* @return true if the action is permitted
*/
public boolean testEntityInteract(@Nullable Object cause, Entity entity) {
return !fireAndTestCancel(setSilent(new UseEntityEvent(null, Cause.create(cause), entity)));
}
/**
* Test whether an entity can be damaged.
*
* <p>The cause does not have to be a player. It can be {@code null}
* if the cause is not known, although the checks will executed
* assuming that the actor is a non-member of all regions.</p>
*
* @param cause the cause, which can be a block, an entity, or a player, or {@code null} if unknown
* @param entity the entity damaged
* @return true if the action is permitted
*/
public boolean testEntityDamage(@Nullable Object cause, Entity entity) {
return !fireAndTestCancel(setSilent(new DamageEntityEvent(null, Cause.create(cause), entity)));
}
}

View File

@ -853,6 +853,17 @@ public LocalPlayer wrapPlayer(Player player) {
return new BukkitPlayer(this, player);
}
/**
* Wrap a player as a LocalPlayer.
*
* @param player The player to wrap
* @param silenced True to silence messages
* @return The wrapped player
*/
public LocalPlayer wrapPlayer(Player player, boolean silenced) {
return new BukkitPlayer(this, player, silenced);
}
/**
* Wrap a player as a LocalPlayer.
*
@ -865,6 +876,17 @@ public LocalPlayer wrapOfflinePlayer(OfflinePlayer player) {
return new BukkitOfflinePlayer(player);
}
/**
* Return a protection query helper object that can be used by another
* plugin to test whether WorldGuard permits an action at a particular
* place.
*
* @return an instance
*/
public ProtectionQuery createProtectionQuery() {
return new ProtectionQuery();
}
/**
* Configure WorldGuard's loggers.
*/

View File

@ -27,12 +27,13 @@
import static com.google.common.base.Preconditions.checkNotNull;
public abstract class AbstractDelegateEvent extends Event implements Cancellable {
public abstract class DelegateEvent extends Event implements Cancellable {
@Nullable
private final Event originalEvent;
private final Cause cause;
private boolean cancelled;
private boolean silent;
/**
* Create a new instance
@ -40,7 +41,7 @@ public abstract class AbstractDelegateEvent extends Event implements Cancellable
* @param originalEvent the original event
* @param cause the cause
*/
protected AbstractDelegateEvent(@Nullable Event originalEvent, Cause cause) {
protected DelegateEvent(@Nullable Event originalEvent, Cause cause) {
checkNotNull(cause);
this.originalEvent = originalEvent;
this.cause = cause;
@ -75,4 +76,22 @@ public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
/**
* Get whether this should be a silent check.
*
* @return true if a silent check
*/
public boolean isSilent() {
return silent;
}
/**
* Set whether this should be a silent check.
*
* @param silent true if silent
*/
void setSilent(boolean silent) {
this.silent = silent;
}
}

View File

@ -0,0 +1,39 @@
/*
* 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;
public final class DelegateEvents {
private DelegateEvents() {
}
/**
* Set an event to be silent.
*
* @param event the event
* @param <T> the type of event
* @return the same event
*/
public static <T extends DelegateEvent> T setSilent(T event) {
event.setSilent(true);
return event;
}
}

View File

@ -21,7 +21,7 @@
import com.google.common.base.Predicate;
import com.sk89q.worldguard.bukkit.cause.Cause;
import com.sk89q.worldguard.bukkit.event.AbstractDelegateEvent;
import com.sk89q.worldguard.bukkit.event.DelegateEvent;
import com.sk89q.worldguard.bukkit.event.BulkEvent;
import org.bukkit.Location;
import org.bukkit.Material;
@ -36,7 +36,7 @@
import static com.google.common.base.Preconditions.checkNotNull;
abstract class AbstractBlockEvent extends AbstractDelegateEvent implements BulkEvent {
abstract class AbstractBlockEvent extends DelegateEvent implements BulkEvent {
private final World world;
private final List<Block> blocks;
@ -149,5 +149,4 @@ public boolean filter(Predicate<Location> predicate) {
public Material getEffectiveMaterial() {
return effectiveMaterial;
}
}

View File

@ -21,7 +21,7 @@
import com.google.common.base.Predicate;
import com.sk89q.worldguard.bukkit.cause.Cause;
import com.sk89q.worldguard.bukkit.event.AbstractDelegateEvent;
import com.sk89q.worldguard.bukkit.event.DelegateEvent;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Entity;
@ -31,7 +31,7 @@
import static com.google.common.base.Preconditions.checkNotNull;
abstract class AbstractEntityEvent extends AbstractDelegateEvent {
abstract class AbstractEntityEvent extends DelegateEvent {
private final Location target;
@Nullable

View File

@ -20,7 +20,7 @@
package com.sk89q.worldguard.bukkit.event.inventory;
import com.sk89q.worldguard.bukkit.cause.Cause;
import com.sk89q.worldguard.bukkit.event.AbstractDelegateEvent;
import com.sk89q.worldguard.bukkit.event.DelegateEvent;
import org.bukkit.World;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
@ -33,7 +33,7 @@
/**
* Fired when an item is interacted with.
*/
public class UseItemEvent extends AbstractDelegateEvent {
public class UseItemEvent extends DelegateEvent {
private static final HandlerList handlers = new HandlerList();
private final World world;

View File

@ -23,6 +23,7 @@
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.event.DelegateEvent;
import com.sk89q.worldguard.bukkit.event.block.BreakBlockEvent;
import com.sk89q.worldguard.bukkit.event.block.PlaceBlockEvent;
import com.sk89q.worldguard.bukkit.event.block.UseBlockEvent;
@ -46,6 +47,12 @@ public ChestProtectionListener(WorldGuardPlugin plugin) {
super(plugin);
}
private void sendMessage(DelegateEvent event, Player player, String message) {
if (!event.isSilent()) {
player.sendMessage(message);
}
}
@EventHandler(ignoreCancelled = true)
public void onPlaceBlock(final PlaceBlockEvent event) {
final Player player = event.getCause().getFirstPlayer();
@ -62,7 +69,7 @@ public void onPlaceBlock(final PlaceBlockEvent event) {
@Override
public boolean apply(Location target) {
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.");
sendMessage(event, player, ChatColor.DARK_RED + "This spot is for a chest that you don't have permission for.");
return false;
}
@ -88,7 +95,7 @@ public void onBreakBlock(final BreakBlockEvent event) {
@Override
public boolean apply(Location target) {
if (wcfg.isChestProtected(target.getBlock(), player)) {
player.sendMessage(ChatColor.DARK_RED + "This chest is protected.");
sendMessage(event, player, ChatColor.DARK_RED + "This chest is protected.");
return false;
}
@ -122,7 +129,7 @@ public void onUseBlock(final UseBlockEvent event) {
@Override
public boolean apply(Location target) {
if (wcfg.isChestProtected(target.getBlock(), player)) {
player.sendMessage(ChatColor.DARK_RED + "This chest is protected.");
sendMessage(event, player, ChatColor.DARK_RED + "This chest is protected.");
return false;
}

View File

@ -24,6 +24,7 @@
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.cause.Cause;
import com.sk89q.worldguard.bukkit.event.DelegateEvent;
import com.sk89q.worldguard.bukkit.event.block.BreakBlockEvent;
import com.sk89q.worldguard.bukkit.event.block.PlaceBlockEvent;
import com.sk89q.worldguard.bukkit.event.block.UseBlockEvent;
@ -78,11 +79,16 @@ public RegionProtectionListener(WorldGuardPlugin plugin) {
/**
* Tell a sender that s/he cannot do something 'here'.
*
* @param event the event
* @param cause the cause
* @param location the location
* @param what what was done
*/
private void tellErrorMessage(Cause cause, Location location, String what) {
private void tellErrorMessage(DelegateEvent event, Cause cause, Location location, String what) {
if (event.isSilent()) {
return;
}
Object rootCause = cause.getRootCause();
if (rootCause instanceof Player) {
@ -178,7 +184,7 @@ public boolean apply(Location target) {
}
if (!canPlace) {
tellErrorMessage(event.getCause(), target, what);
tellErrorMessage(event, event.getCause(), target, what);
return false;
}
@ -215,7 +221,7 @@ public boolean apply(Location target) {
}
if (!canBreak) {
tellErrorMessage(event.getCause(), target, what);
tellErrorMessage(event, event.getCause(), target, what);
return false;
}
@ -262,7 +268,7 @@ public boolean apply(Location target) {
}
if (!canUse) {
tellErrorMessage(event.getCause(), target, what);
tellErrorMessage(event, event.getCause(), target, what);
return false;
}
@ -307,7 +313,7 @@ public void onSpawnEntity(SpawnEntityEvent event) {
}
if (!canSpawn) {
tellErrorMessage(event.getCause(), target, what);
tellErrorMessage(event, event.getCause(), target, what);
event.setCancelled(true);
}
}
@ -342,7 +348,7 @@ public void onDestroyEntity(DestroyEntityEvent event) {
}
if (!canDestroy) {
tellErrorMessage(event.getCause(), target, what);
tellErrorMessage(event, event.getCause(), target, what);
event.setCancelled(true);
}
}
@ -360,7 +366,7 @@ public void onUseEntity(UseEntityEvent event) {
String what = "use that";
if (!canUse) {
tellErrorMessage(event.getCause(), target, what);
tellErrorMessage(event, event.getCause(), target, what);
event.setCancelled(true);
}
}
@ -399,7 +405,7 @@ public void onDamageEntity(DamageEntityEvent event) {
}
if (!canDamage) {
tellErrorMessage(event.getCause(), target, what);
tellErrorMessage(event, event.getCause(), target, what);
event.setCancelled(true);
}
}