mirror of
https://github.com/EngineHub/WorldGuard.git
synced 2024-12-24 18:19:03 +01:00
Fix the splash potion flag not working with the other flags.
Fixes WORLDGUARD-3274.
This commit is contained in:
parent
37a80338f5
commit
da032cb04e
@ -19,11 +19,14 @@
|
||||
|
||||
package com.sk89q.worldguard.bukkit.event;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.sk89q.worldguard.bukkit.cause.Cause;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
@ -36,6 +39,7 @@ public abstract class DelegateEvent extends Event implements Cancellable {
|
||||
@Nullable
|
||||
private final Event originalEvent;
|
||||
private final Cause cause;
|
||||
private final List<StateFlag> relevantFlags = Lists.newArrayList();
|
||||
private boolean cancelled;
|
||||
private boolean silent;
|
||||
|
||||
@ -70,6 +74,15 @@ public Cause getCause() {
|
||||
return cause;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of relevant flags to consider for this event.
|
||||
*
|
||||
* @return A list of relevant flags
|
||||
*/
|
||||
public List<StateFlag> getRelevantFlags() {
|
||||
return relevantFlags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
|
@ -28,7 +28,10 @@
|
||||
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.*;
|
||||
import com.sk89q.worldguard.bukkit.event.entity.DamageEntityEvent;
|
||||
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.listener.debounce.BlockPistonExtendKey;
|
||||
import com.sk89q.worldguard.bukkit.listener.debounce.BlockPistonRetractKey;
|
||||
@ -40,6 +43,7 @@
|
||||
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.protection.flags.DefaultFlag;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.*;
|
||||
import org.bukkit.entity.*;
|
||||
@ -731,7 +735,7 @@ public void onPotionSplash(PotionSplashEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
ThrownPotion potion = event.getPotion();
|
||||
World world = entity.getWorld();
|
||||
Cause cause = create(potion.getShooter());
|
||||
Cause cause = create(potion);
|
||||
|
||||
// Fire item interaction event
|
||||
Events.fireToCancel(event, new UseItemEvent(event, cause, world, potion.getItem()));
|
||||
@ -746,6 +750,9 @@ public void onPotionSplash(PotionSplashEvent event) {
|
||||
? new DamageEntityEvent(event, cause, affected) :
|
||||
new UseEntityEvent(event, cause, affected);
|
||||
|
||||
// Consider the potion splash flag
|
||||
delegate.getRelevantFlags().add(DefaultFlag.POTION_SPLASH);
|
||||
|
||||
if (Events.fireAndTestCancel(delegate)) {
|
||||
event.setIntensity(affected, 0);
|
||||
blocked++;
|
||||
|
@ -32,33 +32,28 @@
|
||||
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.internal.WGMetadata;
|
||||
import com.sk89q.worldguard.bukkit.permission.RegionPermissionModel;
|
||||
import com.sk89q.worldguard.bukkit.protection.DelayedRegionOverlapAssociation;
|
||||
import com.sk89q.worldguard.bukkit.util.Entities;
|
||||
import com.sk89q.worldguard.bukkit.util.Events;
|
||||
import com.sk89q.worldguard.bukkit.util.Materials;
|
||||
import com.sk89q.worldguard.bukkit.internal.WGMetadata;
|
||||
import com.sk89q.worldguard.domains.Association;
|
||||
import com.sk89q.worldguard.protection.association.Associables;
|
||||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
||||
import com.sk89q.worldguard.protection.events.DisallowedPVPEvent;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag.State;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.ExperienceOrb;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.vehicle.VehicleExitEvent;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Handle events that need to be processed by region protection.
|
||||
*/
|
||||
@ -112,6 +107,7 @@ private void tellErrorMessage(DelegateEvent event, Cause cause, Location locatio
|
||||
* Return whether the given cause is whitelist (should be ignored).
|
||||
*
|
||||
* @param cause the cause
|
||||
* @param world the world
|
||||
* @return true if whitelisted
|
||||
*/
|
||||
private boolean isWhitelisted(Cause cause, World world) {
|
||||
@ -178,12 +174,12 @@ public boolean apply(Location target) {
|
||||
|
||||
/* Flint and steel, fire charge, etc. */
|
||||
if (type == Material.FIRE) {
|
||||
canPlace = query.testBuild(target, associable, DefaultFlag.BLOCK_PLACE, DefaultFlag.LIGHTER);
|
||||
canPlace = query.testBuild(target, associable, combine(event, DefaultFlag.BLOCK_PLACE, DefaultFlag.LIGHTER));
|
||||
what = "place fire";
|
||||
|
||||
/* Everything else */
|
||||
} else {
|
||||
canPlace = query.testBuild(target, associable, DefaultFlag.BLOCK_PLACE);
|
||||
canPlace = query.testBuild(target, associable, combine(event, DefaultFlag.BLOCK_PLACE));
|
||||
what = "place that block";
|
||||
}
|
||||
|
||||
@ -215,12 +211,12 @@ public boolean apply(Location target) {
|
||||
|
||||
/* TNT */
|
||||
if (event.getCause().find(EntityType.PRIMED_TNT, EntityType.PRIMED_TNT) != null) {
|
||||
canBreak = query.testBuild(target, associable, DefaultFlag.BLOCK_BREAK, DefaultFlag.TNT);
|
||||
canBreak = query.testBuild(target, associable, combine(event, DefaultFlag.BLOCK_BREAK, DefaultFlag.TNT));
|
||||
what = "dynamite blocks";
|
||||
|
||||
/* Everything else */
|
||||
} else {
|
||||
canBreak = query.testBuild(target, associable, DefaultFlag.BLOCK_BREAK);
|
||||
canBreak = query.testBuild(target, associable, combine(event, DefaultFlag.BLOCK_BREAK));
|
||||
what = "break that block";
|
||||
}
|
||||
|
||||
@ -252,32 +248,32 @@ public boolean apply(Location target) {
|
||||
|
||||
/* Saplings, etc. */
|
||||
if (Materials.isConsideredBuildingIfUsed(type)) {
|
||||
canUse = query.testBuild(target, associable);
|
||||
canUse = query.testBuild(target, associable, combine(event));
|
||||
what = "use that";
|
||||
|
||||
/* Inventory */
|
||||
} else if (Materials.isInventoryBlock(type)) {
|
||||
canUse = query.testBuild(target, associable, DefaultFlag.INTERACT, DefaultFlag.CHEST_ACCESS);
|
||||
canUse = query.testBuild(target, associable, combine(event, DefaultFlag.INTERACT, DefaultFlag.CHEST_ACCESS));
|
||||
what = "open that";
|
||||
|
||||
/* Beds */
|
||||
} else if (type == Material.BED_BLOCK) {
|
||||
canUse = query.testBuild(target, associable, DefaultFlag.INTERACT, DefaultFlag.SLEEP);
|
||||
canUse = query.testBuild(target, associable, combine(event, DefaultFlag.INTERACT, DefaultFlag.SLEEP));
|
||||
what = "sleep";
|
||||
|
||||
/* TNT */
|
||||
} else if (type == Material.TNT) {
|
||||
canUse = query.testBuild(target, associable, DefaultFlag.INTERACT, DefaultFlag.TNT);
|
||||
canUse = query.testBuild(target, associable, combine(event, DefaultFlag.INTERACT, DefaultFlag.TNT));
|
||||
what = "use explosives";
|
||||
|
||||
/* Legacy USE flag */
|
||||
} else if (Materials.isUseFlagApplicable(type)) {
|
||||
canUse = query.testBuild(target, associable, DefaultFlag.INTERACT, DefaultFlag.USE);
|
||||
canUse = query.testBuild(target, associable, combine(event, DefaultFlag.INTERACT, DefaultFlag.USE));
|
||||
what = "use that";
|
||||
|
||||
/* Everything else */
|
||||
} else {
|
||||
canUse = query.testBuild(target, associable, DefaultFlag.INTERACT);
|
||||
canUse = query.testBuild(target, associable, combine(event, DefaultFlag.INTERACT));
|
||||
what = "use that";
|
||||
}
|
||||
|
||||
@ -307,22 +303,22 @@ public void onSpawnEntity(SpawnEntityEvent event) {
|
||||
|
||||
/* Vehicles */
|
||||
if (Entities.isVehicle(type)) {
|
||||
canSpawn = query.testBuild(target, associable, DefaultFlag.PLACE_VEHICLE);
|
||||
canSpawn = query.testBuild(target, associable, combine(event, DefaultFlag.PLACE_VEHICLE));
|
||||
what = "place vehicles";
|
||||
|
||||
/* Item pickup */
|
||||
} else if (event.getEntity() instanceof Item) {
|
||||
canSpawn = query.testBuild(target, associable, DefaultFlag.ITEM_DROP);
|
||||
canSpawn = query.testBuild(target, associable, combine(event, DefaultFlag.ITEM_DROP));
|
||||
what = "drop items";
|
||||
|
||||
/* XP drops */
|
||||
} else if (event.getEffectiveType() == EntityType.EXPERIENCE_ORB) {
|
||||
canSpawn = query.testBuild(target, associable, DefaultFlag.EXP_DROPS);
|
||||
canSpawn = query.testBuild(target, associable, combine(event, DefaultFlag.EXP_DROPS));
|
||||
what = "drop XP";
|
||||
|
||||
/* Everything else */
|
||||
} else {
|
||||
canSpawn = query.testBuild(target, associable);
|
||||
canSpawn = query.testBuild(target, associable, combine(event));
|
||||
|
||||
if (event.getEntity() instanceof Item) {
|
||||
what = "drop items";
|
||||
@ -352,17 +348,17 @@ public void onDestroyEntity(DestroyEntityEvent event) {
|
||||
|
||||
/* Vehicles */
|
||||
if (Entities.isVehicle(type)) {
|
||||
canDestroy = query.testBuild(target, associable, DefaultFlag.DESTROY_VEHICLE);
|
||||
canDestroy = query.testBuild(target, associable, combine(event, DefaultFlag.DESTROY_VEHICLE));
|
||||
what = "break vehicles";
|
||||
|
||||
/* Item pickup */
|
||||
} else if (event.getEntity() instanceof Item || event.getEntity() instanceof ExperienceOrb) {
|
||||
canDestroy = query.testBuild(target, associable, DefaultFlag.ITEM_PICKUP);
|
||||
canDestroy = query.testBuild(target, associable, combine(event, DefaultFlag.ITEM_PICKUP));
|
||||
what = "pick up items";
|
||||
|
||||
/* Everything else */
|
||||
} else {
|
||||
canDestroy = query.testBuild(target, associable);
|
||||
canDestroy = query.testBuild(target, associable, combine(event));
|
||||
what = "break things";
|
||||
}
|
||||
|
||||
@ -386,22 +382,22 @@ public void onUseEntity(UseEntityEvent event) {
|
||||
|
||||
/* Hostile / ambient mob override */
|
||||
if (Entities.isHostile(event.getEntity()) || Entities.isAmbient(event.getEntity()) || Entities.isNPC(event.getEntity())) {
|
||||
canUse = true;
|
||||
canUse = event.getRelevantFlags().isEmpty() || query.testState(target, associable, combine(event));
|
||||
what = "use that";
|
||||
|
||||
/* Paintings, item frames, etc. */
|
||||
} else if (Entities.isConsideredBuildingIfUsed(event.getEntity())) {
|
||||
canUse = query.testBuild(target, associable);
|
||||
canUse = query.testBuild(target, associable, combine(event));
|
||||
what = "change that";
|
||||
|
||||
/* Ridden on use */
|
||||
} else if (Entities.isRiddenOnUse(event.getEntity())) {
|
||||
canUse = query.testBuild(target, associable, DefaultFlag.RIDE, DefaultFlag.INTERACT);
|
||||
canUse = query.testBuild(target, associable, combine(event, DefaultFlag.RIDE, DefaultFlag.INTERACT));
|
||||
what = "ride that";
|
||||
|
||||
/* Everything else */
|
||||
} else {
|
||||
canUse = query.testBuild(target, associable, DefaultFlag.INTERACT);
|
||||
canUse = query.testBuild(target, associable, combine(event, DefaultFlag.INTERACT));
|
||||
what = "use that";
|
||||
}
|
||||
|
||||
@ -427,20 +423,20 @@ public void onDamageEntity(DamageEntityEvent event) {
|
||||
|
||||
/* Hostile / ambient mob override */
|
||||
if (isWhitelistedEntity(event.getEntity()) || (rootCause instanceof Entity && isWhitelistedEntity((Entity) rootCause))) {
|
||||
canDamage = true;
|
||||
canDamage = event.getRelevantFlags().isEmpty() || query.testState(target, associable, combine(event));
|
||||
what = "hit that";
|
||||
|
||||
/* Paintings, item frames, etc. */
|
||||
} else if (Entities.isConsideredBuildingIfUsed(event.getEntity())) {
|
||||
canDamage = query.testBuild(target, associable);
|
||||
canDamage = query.testBuild(target, associable, combine(event));
|
||||
what = "change that";
|
||||
|
||||
/* PVP */
|
||||
} else if (event.getEntity() instanceof Player && (attacker = event.getCause().getFirstPlayer()) != null && !attacker.equals(event.getEntity())) {
|
||||
Player defender = (Player) event.getEntity();
|
||||
|
||||
canDamage = query.testBuild(target, associable, DefaultFlag.PVP)
|
||||
&& query.queryState(attacker.getLocation(), attacker, DefaultFlag.PVP) != State.DENY;
|
||||
canDamage = query.testBuild(target, associable, combine(event, DefaultFlag.PVP))
|
||||
&& query.queryState(attacker.getLocation(), attacker, combine(event, DefaultFlag.PVP)) != State.DENY;
|
||||
|
||||
// Fire the disallow PVP event
|
||||
if (!canDamage && Events.fireAndTestCancel(new DisallowedPVPEvent(attacker, defender, event.getOriginalEvent()))) {
|
||||
@ -451,12 +447,12 @@ public void onDamageEntity(DamageEntityEvent event) {
|
||||
|
||||
/* Player damage not caused by another player */
|
||||
} else if (event.getEntity() instanceof Player) {
|
||||
canDamage = true;
|
||||
canDamage = event.getRelevantFlags().isEmpty() || query.testState(target, associable, combine(event));
|
||||
what = "damage that";
|
||||
|
||||
/* Everything else */
|
||||
} else {
|
||||
canDamage = query.testBuild(target, associable, DefaultFlag.INTERACT);
|
||||
canDamage = query.testBuild(target, associable, combine(event, DefaultFlag.INTERACT));
|
||||
what = "hit that";
|
||||
}
|
||||
|
||||
@ -494,4 +490,22 @@ private boolean isWhitelistedEntity(Entity entity) {
|
||||
return Entities.isNonPlayerCreature(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine the flags from a delegate event with an array of flags.
|
||||
*
|
||||
* <p>The delegate event's flags appear at the end.</p>
|
||||
*
|
||||
* @param event The event
|
||||
* @param flag An array of flags
|
||||
* @return An array of flags
|
||||
*/
|
||||
private static StateFlag[] combine(DelegateEvent event, StateFlag... flag) {
|
||||
List<StateFlag> extra = event.getRelevantFlags();
|
||||
StateFlag[] flags = Arrays.copyOf(flag, flag.length + extra.size());
|
||||
for (int i = 0; i < extra.size(); i++) {
|
||||
flags[flag.length + i] = extra.get(i);
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -768,30 +768,6 @@ public void onFoodLevelChange(FoodLevelChangeEvent event) {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPotionSplash(PotionSplashEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
ThrownPotion potion = event.getPotion();
|
||||
World world = entity.getWorld();
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
|
||||
GlobalRegionManager regionMan = plugin.getGlobalRegionManager();
|
||||
|
||||
int blockedEntities = 0;
|
||||
for (LivingEntity e : event.getAffectedEntities()) {
|
||||
if (!regionMan.allows(DefaultFlag.POTION_SPLASH, e.getLocation(),
|
||||
e instanceof Player ? plugin.wrapPlayer((Player) e) : null)) {
|
||||
event.setIntensity(e, 0);
|
||||
++blockedEntities;
|
||||
}
|
||||
}
|
||||
|
||||
if (blockedEntities == event.getAffectedEntities().size()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player is invincible, via either god mode or region flag. If
|
||||
* the region denies invincibility, the player must have an extra permission
|
||||
|
@ -56,6 +56,7 @@ public final class DefaultFlag {
|
||||
public static final StateFlag DESTROY_VEHICLE = new StateFlag("vehicle-destroy", false);
|
||||
public static final StateFlag LIGHTER = new StateFlag("lighter", false);
|
||||
public static final StateFlag RIDE = new StateFlag("ride", false);
|
||||
public static final StateFlag POTION_SPLASH = new StateFlag("potion-splash", false);
|
||||
|
||||
// These flags are similar to the ones above (used in tandem with BUILD),
|
||||
// but their defaults are set to TRUE because it is more user friendly.
|
||||
@ -99,7 +100,6 @@ public final class DefaultFlag {
|
||||
public static final StateFlag ENDERPEARL = new StateFlag("enderpearl", true);
|
||||
public static final StateFlag ENTITY_PAINTING_DESTROY = new StateFlag("entity-painting-destroy", true);
|
||||
public static final StateFlag ENTITY_ITEM_FRAME_DESTROY = new StateFlag("entity-item-frame-destroy", true);
|
||||
public static final StateFlag POTION_SPLASH = new StateFlag("potion-splash", true);
|
||||
|
||||
// Flags that adjust behaviors that aren't state flags
|
||||
public static final StringFlag DENY_MESSAGE = new StringFlag("deny-message",
|
||||
|
Loading…
Reference in New Issue
Block a user