Implement PVP flag through abstraction.

This commit is contained in:
sk89q 2014-08-22 12:47:06 -07:00
parent d8da89703b
commit ef56a32f00
9 changed files with 119 additions and 99 deletions

View File

@ -83,7 +83,7 @@ public Object getRootCause() {
}
@Nullable
public Player getPlayerRootCause() {
public Player getFirstPlayer() {
for (Object object : causes) {
if (object instanceof Player) {
return (Player) object;

View File

@ -0,0 +1,55 @@
/*
* 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 org.bukkit.entity.Entity;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
public class DamageEntityEvent extends AbstractEntityEvent {
private static final HandlerList handlers = new HandlerList();
public DamageEntityEvent(@Nullable Event originalEvent, Cause cause, Entity target) {
super(originalEvent, cause, checkNotNull(target));
}
@Override
@Nonnull
public Entity getEntity() {
return super.getEntity();
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@ -70,7 +70,7 @@ public BlacklistListener(WorldGuardPlugin plugin) {
@EventHandler(ignoreCancelled = true)
public void onBreakBlock(final BreakBlockEvent event) {
final Player player = event.getCause().getPlayerRootCause();
final Player player = event.getCause().getFirstPlayer();
if (player == null) {
return;
@ -102,7 +102,7 @@ public boolean apply(Location target) {
@EventHandler(ignoreCancelled = true)
public void onPlaceBlock(final PlaceBlockEvent event) {
Player player = event.getCause().getPlayerRootCause();
Player player = event.getCause().getFirstPlayer();
if (player == null) {
return;
@ -128,7 +128,7 @@ public boolean apply(Location target) {
@EventHandler(ignoreCancelled = true)
public void onUseBlock(final UseBlockEvent event) {
Player player = event.getCause().getPlayerRootCause();
Player player = event.getCause().getFirstPlayer();
if (player == null) {
return;
@ -153,7 +153,7 @@ public boolean apply(Location target) {
@EventHandler(ignoreCancelled = true)
public void onSpawnEntity(SpawnEntityEvent event) {
Player player = event.getCause().getPlayerRootCause();
Player player = event.getCause().getFirstPlayer();
if (player == null) {
return;
@ -177,7 +177,7 @@ public void onSpawnEntity(SpawnEntityEvent event) {
@EventHandler(ignoreCancelled = true)
public void onDestroyEntity(DestroyEntityEvent event) {
Player player = event.getCause().getPlayerRootCause();
Player player = event.getCause().getFirstPlayer();
if (player == null) {
return;
@ -203,7 +203,7 @@ public void onDestroyEntity(DestroyEntityEvent event) {
@EventHandler(ignoreCancelled = true)
public void onUseItem(UseItemEvent event) {
Player player = event.getCause().getPlayerRootCause();
Player player = event.getCause().getFirstPlayer();
if (player == null) {
return;

View File

@ -50,7 +50,7 @@ public BlockedPotionsListener(WorldGuardPlugin plugin) {
@EventHandler
public void onItemInteract(UseItemEvent event) {
// We only care about player caused events
if (event.getCause().getPlayerRootCause() == null) {
if (event.getCause().getFirstPlayer() == null) {
return;
}
@ -83,7 +83,7 @@ public void onItemInteract(UseItemEvent event) {
}
if (blockedEffect != null) {
Player player = event.getCause().getPlayerRootCause();
Player player = event.getCause().getFirstPlayer();
if (player != null) {
if (getPlugin().hasPermission(player, "worldguard.override.potions")) {

View File

@ -48,7 +48,7 @@ public ChestProtectionListener(WorldGuardPlugin plugin) {
@EventHandler(ignoreCancelled = true)
public void onPlaceBlock(final PlaceBlockEvent event) {
final Player player = event.getCause().getPlayerRootCause();
final Player player = event.getCause().getFirstPlayer();
if (player != null) {
final WorldConfiguration wcfg = getWorldConfig(player);
@ -74,7 +74,7 @@ public boolean apply(Location target) {
@EventHandler(ignoreCancelled = true)
public void onBreakBlock(final BreakBlockEvent event) {
final Player player = event.getCause().getPlayerRootCause();
final Player player = event.getCause().getFirstPlayer();
final WorldConfiguration wcfg = getWorldConfig(event.getWorld());
@ -108,7 +108,7 @@ public boolean apply(Location target) {
@EventHandler(ignoreCancelled = true)
public void onUseBlock(final UseBlockEvent event) {
final Player player = event.getCause().getPlayerRootCause();
final Player player = event.getCause().getFirstPlayer();
final WorldConfiguration wcfg = getWorldConfig(event.getWorld());

View File

@ -25,6 +25,7 @@
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.DestroyEntityEvent;
import com.sk89q.worldguard.bukkit.event.entity.SpawnEntityEvent;
import com.sk89q.worldguard.bukkit.event.entity.UseEntityEvent;
@ -487,12 +488,12 @@ public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
@EventHandler
public void onEntityDamage(EntityDamageEvent event) {
if (event instanceof EntityDamageByBlockEvent) {
Events.fireToCancel(event, new UseEntityEvent(event, create(((EntityDamageByBlockEvent) event).getDamager()), event.getEntity()));
Events.fireToCancel(event, new DamageEntityEvent(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()));
Events.fireToCancel(event, new DamageEntityEvent(event, create(damager), event.getEntity()));
// Item use event with the item in hand
// Older blacklist handler code used this, although it suffers from
@ -506,20 +507,20 @@ public void onEntityDamage(EntityDamageEvent event) {
}
} else {
Events.fireToCancel(event, new UseEntityEvent(event, Cause.unknown(), event.getEntity()));
Events.fireToCancel(event, new DamageEntityEvent(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()));
Events.fireToCancel(event, new DamageEntityEvent(event, create(((EntityCombustByBlockEvent) event).getCombuster()), event.getEntity()));
} else if (event instanceof EntityCombustByEntityEvent) {
Events.fireToCancel(event, new UseEntityEvent(event, create(((EntityCombustByEntityEvent) event).getCombuster()), event.getEntity()));
Events.fireToCancel(event, new DamageEntityEvent(event, create(((EntityCombustByEntityEvent) event).getCombuster()), event.getEntity()));
} else {
Events.fireToCancel(event, new UseEntityEvent(event, Cause.unknown(), event.getEntity()));
Events.fireToCancel(event, new DamageEntityEvent(event, Cause.unknown(), event.getEntity()));
}
}

View File

@ -26,16 +26,20 @@
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.DestroyEntityEvent;
import com.sk89q.worldguard.bukkit.event.entity.SpawnEntityEvent;
import com.sk89q.worldguard.bukkit.event.entity.UseEntityEvent;
import com.sk89q.worldguard.bukkit.util.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.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.State;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
@ -281,4 +285,39 @@ public void onUseEntity(UseEntityEvent event) {
}
}
@EventHandler(ignoreCancelled = true)
public void onDamageEntity(DamageEntityEvent event) {
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
if (isWhitelisted(event.getCause())) return; // Whitelisted cause
Location target = event.getTarget();
RegionAssociable associable = createRegionAssociable(event.getCause());
RegionQuery query = getPlugin().getRegionContainer().createQuery();
Player attacker;
boolean canDamage;
/* PVP */
if (event.getEntity() instanceof Player && (attacker = event.getCause().getFirstPlayer()) != null) {
Player defender = (Player) event.getEntity();
canDamage = query.testBuild(target, associable, DefaultFlag.PVP)
&& query.queryState(attacker.getLocation(), attacker, DefaultFlag.PVP) != State.DENY;
// Fire the disallow PVP event
if (!canDamage && Events.fireAndTestCancel(new DisallowedPVPEvent(attacker, defender, event.getOriginalEvent()))) {
canDamage = true;
}
/* Everything else */
} else {
canDamage = query.testBuild(target, associable, DefaultFlag.USE);
}
if (!canDamage) {
tellErrorMessage(event.getCause(), target);
event.setCancelled(true);
}
}
}

View File

@ -29,16 +29,13 @@
import com.sk89q.worldguard.bukkit.util.RegionQueryUtil;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.GlobalRegionManager;
import com.sk89q.worldguard.protection.events.DisallowedPVPEvent;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.EnderPearl;
import org.bukkit.entity.Enderman;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
@ -245,18 +242,6 @@ private void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
}
if (attacker != null) {
if (attacker instanceof Player) {
if (wcfg.useRegions) {
RegionQuery query = plugin.getRegionContainer().createQuery();
if (!query.testBuild(attacker.getLocation(), (Player) attacker, DefaultFlag.PVP)) {
tryCancelPVPEvent((Player) attacker, player, event, true);
} else if (!query.testBuild(defender.getLocation(), (Player) defender, DefaultFlag.PVP)) {
tryCancelPVPEvent((Player) attacker, player, event, false);
}
}
}
if (attacker instanceof TNTPrimed || attacker instanceof ExplosiveMinecart) {
// The check for explosion damage should be handled already... But... What ever...
@ -288,18 +273,9 @@ private void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
if (wcfg.useRegions) {
Fireball fireball = (Fireball) attacker;
RegionQuery query = plugin.getRegionContainer().createQuery();
if (fireball.getShooter() instanceof Player) {
Location pt2 = ((Player) fireball.getShooter()).getLocation();
if (!query.testBuild(pt2, (Player) fireball.getShooter(), DefaultFlag.PVP)) {
tryCancelPVPEvent((Player) fireball.getShooter(), player, event, true);
} else if (!query.testBuild(defender.getLocation(), (Player) defender, DefaultFlag.PVP)) {
tryCancelPVPEvent((Player) fireball.getShooter(), player, event, false);
}
} else {
if (!query.testBuild(defender.getLocation(), (Player) defender, DefaultFlag.GHAST_FIREBALL) && wcfg.explosionFlagCancellation) {
event.setCancelled(true);
return;
}
if (!query.testBuild(defender.getLocation(), (Player) defender, DefaultFlag.GHAST_FIREBALL) && wcfg.explosionFlagCancellation) {
event.setCancelled(true);
return;
}
}
@ -331,23 +307,6 @@ private void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
return;
}
}
if (attacker instanceof Tameable) {
if (((Tameable) attacker).getOwner() == null) {
if (!set.allows(DefaultFlag.MOB_DAMAGE, localPlayer)) {
event.setCancelled(true);
return;
}
}
if (!(((Tameable) attacker).getOwner() instanceof Player)) {
return;
}
Player beastMaster = (Player) ((Tameable) attacker).getOwner();
if (!plugin.getRegionContainer().createQuery().getApplicableRegions(attacker.getLocation()).allows(DefaultFlag.PVP, plugin.wrapPlayer(beastMaster))) {
tryCancelPVPEvent(beastMaster, player, event, true);
} else if (!set.allows(DefaultFlag.PVP, localPlayer)) {
tryCancelPVPEvent(beastMaster, player, event, false);
}
}
}
}
}
@ -390,19 +349,6 @@ private void onEntityDamageByProjectile(EntityDamageByEntityEvent event) {
}
}
}
// Check Player
// if (event.getDamager() instanceof EnderPearl || event.getDamager() instanceof Snowball) return;
if (attacker != null && attacker instanceof Player) {
if (event.getDamager() instanceof EnderPearl && attacker == player) return;
if (wcfg.useRegions) {
if (!plugin.getRegionContainer().createQuery().getApplicableRegions(attacker.getLocation()).allows(DefaultFlag.PVP, plugin.wrapPlayer((Player) attacker))) {
tryCancelPVPEvent((Player) attacker, player, event, true);
} else if (!plugin.getRegionContainer().createQuery().getApplicableRegions(defender.getLocation()).allows(DefaultFlag.PVP, localPlayer)) {
tryCancelPVPEvent((Player) attacker, player, event, false);
}
}
}
} else if (defender instanceof ItemFrame) {
if (checkItemFrameProtection(attacker, (ItemFrame) defender)) {
event.setCancelled(true);
@ -883,26 +829,6 @@ private boolean isInvincible(Player player) {
}
}
/**
* Using a DisallowedPVPEvent, notifies other plugins that WorldGuard
* wants to cancel a PvP damage event.<br />
* If this event is not cancelled, the attacking player is notified that
* PvP is disabled and WorldGuard cancels the damage event.
*
* @param attackingPlayer The attacker
* @param defendingPlayer The defender
* @param event The event that caused WorldGuard to act
*/
public void tryCancelPVPEvent(final Player attackingPlayer, final Player defendingPlayer, EntityDamageByEntityEvent event, boolean aggressorTriggered) {
final DisallowedPVPEvent disallowedPVPEvent = new DisallowedPVPEvent(attackingPlayer, defendingPlayer, event);
plugin.getServer().getPluginManager().callEvent(disallowedPVPEvent);
if (!disallowedPVPEvent.isCancelled()) {
if (aggressorTriggered) attackingPlayer.sendMessage(ChatColor.DARK_RED + "You are in a no-PvP area.");
else attackingPlayer.sendMessage(ChatColor.DARK_RED + "That player is in a no-PvP area.");
event.setCancelled(true);
}
}
/**
* Checks regions and config settings to protect items from being knocked
* out of item frames.

View File

@ -23,7 +23,6 @@
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
/**
* This event is fired when PVP is disallowed between players due to a "pvp deny" flag.
@ -37,9 +36,9 @@ public class DisallowedPVPEvent extends Event implements Cancellable {
private boolean cancelled = false;
private final Player attacker;
private final Player defender;
private final EntityDamageByEntityEvent event;
private final Event event;
public DisallowedPVPEvent(final Player attacker, final Player defender, EntityDamageByEntityEvent event) {
public DisallowedPVPEvent(final Player attacker, final Player defender, Event event) {
this.attacker = attacker;
this.defender = defender;
this.event = event;
@ -67,7 +66,7 @@ public Player getDefender() {
return defender;
}
public EntityDamageByEntityEvent getCause() {
public Event getCause() {
return event;
}