mirror of
https://github.com/EngineHub/WorldGuard.git
synced 2024-12-25 02:27:42 +01:00
Funnel pre-allowed events too.
Fixes WORLDGUARD-3308.
This commit is contained in:
parent
a03aaa45b1
commit
2f3f76c8cf
@ -19,20 +19,21 @@
|
||||
|
||||
package com.sk89q.worldguard.bukkit.event;
|
||||
|
||||
import org.bukkit.event.Event.Result;
|
||||
|
||||
/**
|
||||
* A bulk event contains several affected objects in a list.
|
||||
*/
|
||||
public interface BulkEvent {
|
||||
|
||||
/**
|
||||
* Return whether the event is explicitly cancelled.
|
||||
* Get the actual result.
|
||||
*
|
||||
* <p>By default, bulk events will cancel itself if the number of affected
|
||||
* objects drops to zero. This method returns the true cancellation
|
||||
* status.</p>
|
||||
* <p>By default, bulk events will set the result to DENY if the number of
|
||||
* affected objects drops to zero. This method returns the true result.</p>
|
||||
*
|
||||
* @return true if really cancelled
|
||||
* @return the explicit result
|
||||
*/
|
||||
boolean isExplicitlyCancelled();
|
||||
Result getExplicitResult();
|
||||
|
||||
}
|
||||
|
@ -34,13 +34,13 @@
|
||||
* This event is an internal event. We do not recommend handling or throwing
|
||||
* this event or its subclasses as the interface is highly subject to change.
|
||||
*/
|
||||
public abstract class DelegateEvent extends Event implements Cancellable {
|
||||
public abstract class DelegateEvent extends Event implements Cancellable, Handleable {
|
||||
|
||||
@Nullable
|
||||
private final Event originalEvent;
|
||||
private final Cause cause;
|
||||
private final List<StateFlag> relevantFlags = Lists.newArrayList();
|
||||
private boolean cancelled;
|
||||
private Result result = Result.DEFAULT;
|
||||
private boolean silent;
|
||||
|
||||
/**
|
||||
@ -85,12 +85,24 @@ public List<StateFlag> getRelevantFlags() {
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
return getResult() == Result.DENY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancelled = cancel;
|
||||
if (cancel) {
|
||||
setResult(Result.DENY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResult(Result result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -106,9 +118,25 @@ public boolean isSilent() {
|
||||
* Set whether this should be a silent check.
|
||||
*
|
||||
* @param silent true if silent
|
||||
* @return the same event
|
||||
*/
|
||||
void setSilent(boolean silent) {
|
||||
public DelegateEvent setSilent(boolean silent) {
|
||||
this.silent = silent;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the event to {@link Result#ALLOW} if {@code allowed} is true.
|
||||
*
|
||||
* @param allowed true to set the result
|
||||
* @return the same event
|
||||
*/
|
||||
public DelegateEvent setAllowed(boolean allowed) {
|
||||
if (allowed) {
|
||||
setResult(Result.ALLOW);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
package com.sk89q.worldguard.bukkit.event;
|
||||
|
||||
import org.bukkit.event.Event.Result;
|
||||
|
||||
/**
|
||||
* Utility methods for dealing with delegate events.
|
||||
*/
|
||||
@ -52,4 +54,19 @@ public static <T extends DelegateEvent> T setSilent(T event, boolean silent) {
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an event as handled as {@link Result#ALLOW} if {@code allowed} is
|
||||
* true, otherwise do nothing.
|
||||
*
|
||||
* @param event the event
|
||||
* @param <T> the type of event
|
||||
* @return the same event
|
||||
*/
|
||||
public static <T extends Handleable> T setAllowed(T event, boolean allowed) {
|
||||
if (allowed) {
|
||||
event.setResult(Result.ALLOW);
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.bukkit.event.Event.Result;
|
||||
|
||||
public interface Handleable {
|
||||
|
||||
Result getResult();
|
||||
|
||||
void setResult(Result result);
|
||||
|
||||
}
|
@ -70,16 +70,6 @@ private static List<Block> createList(Block block) {
|
||||
return blocks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return super.isCancelled() || blocks.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExplicitlyCancelled() {
|
||||
return super.isCancelled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the world.
|
||||
*
|
||||
@ -153,4 +143,18 @@ public boolean filter(Predicate<Location> predicate) {
|
||||
public Material getEffectiveMaterial() {
|
||||
return effectiveMaterial;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result getResult() {
|
||||
if (blocks.isEmpty()) {
|
||||
return Result.DENY;
|
||||
}
|
||||
return super.getResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result getExplicitResult() {
|
||||
return super.getResult();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.Event.Result;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
|
||||
@ -67,8 +68,8 @@ public void onPlaceBlock(PlaceBlockEvent event) {
|
||||
builder.append("[").append(event.getCause()).append("]");
|
||||
builder.append(" ");
|
||||
builder.append(":").append(getEventName(event.getOriginalEvent()));
|
||||
if (event.isCancelled()) {
|
||||
builder.append(" [CANCELLED]");
|
||||
if (event.getResult() != Result.DEFAULT) {
|
||||
builder.append(" [").append(event.getResult()).append("]");
|
||||
}
|
||||
logger.info(builder.toString());
|
||||
}
|
||||
@ -85,8 +86,8 @@ public void onBreakBlock(BreakBlockEvent event) {
|
||||
builder.append("@").append(toBlockString(event.getBlocks()));
|
||||
builder.append(" ");
|
||||
builder.append(":").append(getEventName(event.getOriginalEvent()));
|
||||
if (event.isCancelled()) {
|
||||
builder.append(" [CANCELLED]");
|
||||
if (event.getResult() != Result.DEFAULT) {
|
||||
builder.append(" [").append(event.getResult()).append("]");
|
||||
}
|
||||
logger.info(builder.toString());
|
||||
}
|
||||
@ -103,8 +104,8 @@ public void onUseBlock(UseBlockEvent event) {
|
||||
builder.append("@").append(toBlockString(event.getBlocks()));
|
||||
builder.append(" ");
|
||||
builder.append(":").append(getEventName(event.getOriginalEvent()));
|
||||
if (event.isCancelled()) {
|
||||
builder.append(" [CANCELLED]");
|
||||
if (event.getResult() != Result.DEFAULT) {
|
||||
builder.append(" [").append(event.getResult()).append("]");
|
||||
}
|
||||
logger.info(builder.toString());
|
||||
}
|
||||
@ -121,8 +122,8 @@ public void onSpawnEntity(SpawnEntityEvent event) {
|
||||
builder.append("@").append(toBlockString(event.getTarget()));
|
||||
builder.append(" ");
|
||||
builder.append(":").append(getEventName(event.getOriginalEvent()));
|
||||
if (event.isCancelled()) {
|
||||
builder.append(" [CANCELLED]");
|
||||
if (event.getResult() != Result.DEFAULT) {
|
||||
builder.append(" [").append(event.getResult()).append("]");
|
||||
}
|
||||
logger.info(builder.toString());
|
||||
}
|
||||
@ -139,8 +140,8 @@ public void onDestroyEntity(DestroyEntityEvent event) {
|
||||
builder.append("@").append(toBlockString(event.getTarget()));
|
||||
builder.append(" ");
|
||||
builder.append(":").append(getEventName(event.getOriginalEvent()));
|
||||
if (event.isCancelled()) {
|
||||
builder.append(" [CANCELLED]");
|
||||
if (event.getResult() != Result.DEFAULT) {
|
||||
builder.append(" [").append(event.getResult()).append("]");
|
||||
}
|
||||
logger.info(builder.toString());
|
||||
}
|
||||
@ -157,8 +158,8 @@ public void onUseEntity(UseEntityEvent event) {
|
||||
builder.append("@").append(toBlockString(event.getTarget()));
|
||||
builder.append(" ");
|
||||
builder.append(":").append(getEventName(event.getOriginalEvent()));
|
||||
if (event.isCancelled()) {
|
||||
builder.append(" [CANCELLED]");
|
||||
if (event.getResult() != Result.DEFAULT) {
|
||||
builder.append(" [").append(event.getResult()).append("]");
|
||||
}
|
||||
logger.info(builder.toString());
|
||||
}
|
||||
@ -175,8 +176,8 @@ public void onUseItem(UseItemEvent event) {
|
||||
builder.append("@").append(event.getWorld().getName());
|
||||
builder.append(" ");
|
||||
builder.append(":").append(getEventName(event.getOriginalEvent()));
|
||||
if (event.isCancelled()) {
|
||||
builder.append(" [CANCELLED]");
|
||||
if (event.getResult() != Result.DEFAULT) {
|
||||
builder.append(" [").append(event.getResult()).append("]");
|
||||
}
|
||||
logger.info(builder.toString());
|
||||
}
|
||||
|
@ -24,7 +24,6 @@
|
||||
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.DelegateEvents;
|
||||
import com.sk89q.worldguard.bukkit.event.block.BreakBlockEvent;
|
||||
import com.sk89q.worldguard.bukkit.event.block.PlaceBlockEvent;
|
||||
import com.sk89q.worldguard.bukkit.event.block.UseBlockEvent;
|
||||
@ -304,6 +303,7 @@ public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
Block clicked = event.getClickedBlock();
|
||||
Block placed;
|
||||
boolean silent = false;
|
||||
boolean modifiesWorld;
|
||||
Cause cause = create(player);
|
||||
|
||||
switch (event.getAction()) {
|
||||
@ -313,9 +313,8 @@ public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
silent = true;
|
||||
}
|
||||
|
||||
if (!hasInteractBypass(clicked)) {
|
||||
interactDebounce.debounce(clicked, event.getPlayer(), event, DelegateEvents.setSilent(new UseBlockEvent(event, cause, clicked), silent));
|
||||
}
|
||||
interactDebounce.debounce(clicked, event.getPlayer(), event,
|
||||
new UseBlockEvent(event, cause, clicked).setSilent(silent).setAllowed(hasInteractBypass(clicked)));
|
||||
break;
|
||||
|
||||
case RIGHT_CLICK_BLOCK:
|
||||
@ -328,17 +327,17 @@ public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
placed = clicked.getRelative(event.getBlockFace());
|
||||
|
||||
// Only fire events for blocks that are modified when right clicked
|
||||
if (isBlockModifiedOnClick(clicked, event.getAction() == Action.RIGHT_CLICK_BLOCK) || (item != null && isItemAppliedToBlock(item, clicked))) {
|
||||
if (Events.fireAndTestCancel(new UseBlockEvent(event, cause, clicked))) {
|
||||
event.setUseInteractedBlock(Result.DENY);
|
||||
}
|
||||
modifiesWorld = isBlockModifiedOnClick(clicked, event.getAction() == Action.RIGHT_CLICK_BLOCK) || (item != null && isItemAppliedToBlock(item, clicked));
|
||||
|
||||
// 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;
|
||||
}
|
||||
if (Events.fireAndTestCancel(new UseBlockEvent(event, cause, clicked).setAllowed(!modifiesWorld))) {
|
||||
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).setAllowed(!modifiesWorld))) {
|
||||
event.setUseInteractedBlock(Result.DENY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -377,9 +376,8 @@ public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onEntityInteract(org.bukkit.event.entity.EntityInteractEvent event) {
|
||||
if (!hasInteractBypass(event.getBlock())) {
|
||||
interactDebounce.debounce(event.getBlock(), event.getEntity(), event, new UseBlockEvent(event, create(event.getEntity()), event.getBlock()));
|
||||
}
|
||||
interactDebounce.debounce(event.getBlock(), event.getEntity(), event,
|
||||
new UseBlockEvent(event, create(event.getEntity()), event.getBlock()).setAllowed(hasInteractBypass(event.getBlock())));
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
@ -420,15 +418,18 @@ public void onBedEnter(PlayerBedEnterEvent event) {
|
||||
public void onPlayerBucketEmpty(PlayerBucketEmptyEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
Block blockAffected = event.getBlockClicked().getRelative(event.getBlockFace());
|
||||
boolean allowed = false;
|
||||
|
||||
// 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));
|
||||
if (event.getBucket() == Material.MILK_BUCKET) {
|
||||
allowed = true;
|
||||
}
|
||||
|
||||
ItemStack item = new ItemStack(event.getBucket(), 1);
|
||||
Material blockMaterial = Materials.getBucketBlockMaterial(event.getBucket());
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, create(player), blockAffected.getLocation(), blockMaterial).setAllowed(allowed));
|
||||
Events.fireToCancel(event, new UseItemEvent(event, create(player), player.getWorld(), item).setAllowed(allowed));
|
||||
|
||||
playDenyEffect(event.getPlayer(), blockAffected.getLocation().add(0.5, 0.5, 0.5));
|
||||
}
|
||||
|
||||
@ -436,14 +437,17 @@ public void onPlayerBucketEmpty(PlayerBucketEmptyEvent event) {
|
||||
public void onPlayerBucketFill(PlayerBucketFillEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
Block blockAffected = event.getBlockClicked().getRelative(event.getBlockFace());
|
||||
boolean allowed = false;
|
||||
|
||||
// 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));
|
||||
// Milk buckets can't be emptied as of writing
|
||||
if (event.getBucket() == Material.MILK_BUCKET) {
|
||||
allowed = true;
|
||||
}
|
||||
|
||||
ItemStack item = new ItemStack(event.getBucket(), 1);
|
||||
Events.fireToCancel(event, new BreakBlockEvent(event, create(player), blockAffected).setAllowed(allowed));
|
||||
Events.fireToCancel(event, new UseItemEvent(event, create(player), player.getWorld(), item).setAllowed(allowed));
|
||||
|
||||
playDenyEffect(event.getPlayer(), blockAffected.getLocation().add(0.5, 1, 0.5));
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.Event.Result;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.vehicle.VehicleExitEvent;
|
||||
|
||||
@ -153,6 +154,7 @@ private RegionAssociable createRegionAssociable(Cause cause) {
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlaceBlock(final PlaceBlockEvent event) {
|
||||
if (event.getResult() == Result.ALLOW) return; // Don't care about events that have been pre-allowed
|
||||
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
|
||||
if (isWhitelisted(event.getCause(), event.getWorld(), false)) return; // Whitelisted cause
|
||||
|
||||
@ -196,6 +198,7 @@ public boolean apply(Location target) {
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBreakBlock(final BreakBlockEvent event) {
|
||||
if (event.getResult() == Result.ALLOW) return; // Don't care about events that have been pre-allowed
|
||||
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
|
||||
if (isWhitelisted(event.getCause(), event.getWorld(), false)) return; // Whitelisted cause
|
||||
|
||||
@ -234,6 +237,7 @@ public boolean apply(Location target) {
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onUseBlock(final UseBlockEvent event) {
|
||||
if (event.getResult() == Result.ALLOW) return; // Don't care about events that have been pre-allowed
|
||||
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
|
||||
if (isWhitelisted(event.getCause(), event.getWorld(), false)) return; // Whitelisted cause
|
||||
|
||||
@ -290,6 +294,7 @@ public boolean apply(Location target) {
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onSpawnEntity(SpawnEntityEvent event) {
|
||||
if (event.getResult() == Result.ALLOW) return; // Don't care about events that have been pre-allowed
|
||||
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
|
||||
if (isWhitelisted(event.getCause(), event.getWorld(), false)) return; // Whitelisted cause
|
||||
|
||||
@ -336,6 +341,7 @@ public void onSpawnEntity(SpawnEntityEvent event) {
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onDestroyEntity(DestroyEntityEvent event) {
|
||||
if (event.getResult() == Result.ALLOW) return; // Don't care about events that have been pre-allowed
|
||||
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
|
||||
if (isWhitelisted(event.getCause(), event.getWorld(), false)) return; // Whitelisted cause
|
||||
|
||||
@ -371,6 +377,7 @@ public void onDestroyEntity(DestroyEntityEvent event) {
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onUseEntity(UseEntityEvent event) {
|
||||
if (event.getResult() == Result.ALLOW) return; // Don't care about events that have been pre-allowed
|
||||
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
|
||||
if (isWhitelisted(event.getCause(), event.getWorld(), false)) return; // Whitelisted cause
|
||||
|
||||
@ -410,6 +417,7 @@ public void onUseEntity(UseEntityEvent event) {
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onDamageEntity(DamageEntityEvent event) {
|
||||
if (event.getResult() == Result.ALLOW) return; // Don't care about events that have been pre-allowed
|
||||
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
|
||||
// Whitelist check is below
|
||||
|
||||
|
@ -110,7 +110,7 @@ public static <T extends Event & Cancellable> boolean fireItemEventToCancel(Play
|
||||
*/
|
||||
public static <T extends Event & Cancellable & BulkEvent> boolean fireBulkEventToCancel(Cancellable original, T eventToFire) {
|
||||
Bukkit.getServer().getPluginManager().callEvent(eventToFire);
|
||||
if (eventToFire.isExplicitlyCancelled()) {
|
||||
if (eventToFire.getExplicitResult() == Result.DENY) {
|
||||
original.setCancelled(true);
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user