diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java index e1112f71..0b205618 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java @@ -33,10 +33,19 @@ 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.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.bukkit.listener.BlacklistListener; +import com.sk89q.worldguard.bukkit.listener.BlockedPotionsListener; +import com.sk89q.worldguard.bukkit.listener.ChestProtectionListener; +import com.sk89q.worldguard.bukkit.listener.RegionProtectionListener; import com.sk89q.worldguard.protection.GlobalRegionManager; import com.sk89q.worldguard.protection.managers.RegionManager; import com.sk89q.worldguard.util.FatalConfigurationLoadingException; diff --git a/src/main/java/com/sk89q/worldguard/internal/event/AbstractInteractEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/AbstractInteractEvent.java similarity index 95% rename from src/main/java/com/sk89q/worldguard/internal/event/AbstractInteractEvent.java rename to src/main/java/com/sk89q/worldguard/bukkit/event/AbstractInteractEvent.java index ed528d80..a2a8d22e 100644 --- a/src/main/java/com/sk89q/worldguard/internal/event/AbstractInteractEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/AbstractInteractEvent.java @@ -17,9 +17,9 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.event; +package com.sk89q.worldguard.bukkit.event; -import com.sk89q.worldguard.internal.cause.Cause; +import com.sk89q.worldguard.util.cause.Cause; import org.bukkit.event.Cancellable; import org.bukkit.event.Event; diff --git a/src/main/java/com/sk89q/worldguard/internal/event/block/AbstractBlockEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/block/AbstractBlockEvent.java similarity index 93% rename from src/main/java/com/sk89q/worldguard/internal/event/block/AbstractBlockEvent.java rename to src/main/java/com/sk89q/worldguard/bukkit/event/block/AbstractBlockEvent.java index f856e27b..a9f423ef 100644 --- a/src/main/java/com/sk89q/worldguard/internal/event/block/AbstractBlockEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/block/AbstractBlockEvent.java @@ -17,10 +17,10 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.event.block; +package com.sk89q.worldguard.bukkit.event.block; -import com.sk89q.worldguard.internal.cause.Cause; -import com.sk89q.worldguard.internal.event.AbstractInteractEvent; +import com.sk89q.worldguard.util.cause.Cause; +import com.sk89q.worldguard.bukkit.event.AbstractInteractEvent; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; diff --git a/src/main/java/com/sk89q/worldguard/internal/event/block/BreakBlockEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/block/BreakBlockEvent.java similarity index 94% rename from src/main/java/com/sk89q/worldguard/internal/event/block/BreakBlockEvent.java rename to src/main/java/com/sk89q/worldguard/bukkit/event/block/BreakBlockEvent.java index ddd0c667..fb929316 100644 --- a/src/main/java/com/sk89q/worldguard/internal/event/block/BreakBlockEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/block/BreakBlockEvent.java @@ -17,9 +17,9 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.event.block; +package com.sk89q.worldguard.bukkit.event.block; -import com.sk89q.worldguard.internal.cause.Cause; +import com.sk89q.worldguard.util.cause.Cause; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; diff --git a/src/main/java/com/sk89q/worldguard/internal/event/block/PlaceBlockEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/block/PlaceBlockEvent.java similarity index 94% rename from src/main/java/com/sk89q/worldguard/internal/event/block/PlaceBlockEvent.java rename to src/main/java/com/sk89q/worldguard/bukkit/event/block/PlaceBlockEvent.java index 69874e14..68d0d7c9 100644 --- a/src/main/java/com/sk89q/worldguard/internal/event/block/PlaceBlockEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/block/PlaceBlockEvent.java @@ -17,9 +17,9 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.event.block; +package com.sk89q.worldguard.bukkit.event.block; -import com.sk89q.worldguard.internal.cause.Cause; +import com.sk89q.worldguard.util.cause.Cause; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; diff --git a/src/main/java/com/sk89q/worldguard/internal/event/block/UseBlockEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/block/UseBlockEvent.java similarity index 94% rename from src/main/java/com/sk89q/worldguard/internal/event/block/UseBlockEvent.java rename to src/main/java/com/sk89q/worldguard/bukkit/event/block/UseBlockEvent.java index 99705dc9..21ba32de 100644 --- a/src/main/java/com/sk89q/worldguard/internal/event/block/UseBlockEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/block/UseBlockEvent.java @@ -17,9 +17,9 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.event.block; +package com.sk89q.worldguard.bukkit.event.block; -import com.sk89q.worldguard.internal.cause.Cause; +import com.sk89q.worldguard.util.cause.Cause; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; diff --git a/src/main/java/com/sk89q/worldguard/internal/event/entity/AbstractEntityEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/entity/AbstractEntityEvent.java similarity index 93% rename from src/main/java/com/sk89q/worldguard/internal/event/entity/AbstractEntityEvent.java rename to src/main/java/com/sk89q/worldguard/bukkit/event/entity/AbstractEntityEvent.java index 3e33d8bb..bb723f4b 100644 --- a/src/main/java/com/sk89q/worldguard/internal/event/entity/AbstractEntityEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/entity/AbstractEntityEvent.java @@ -17,10 +17,10 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.event.entity; +package com.sk89q.worldguard.bukkit.event.entity; -import com.sk89q.worldguard.internal.cause.Cause; -import com.sk89q.worldguard.internal.event.AbstractInteractEvent; +import com.sk89q.worldguard.util.cause.Cause; +import com.sk89q.worldguard.bukkit.event.AbstractInteractEvent; import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.event.Event; diff --git a/src/main/java/com/sk89q/worldguard/internal/event/entity/DestroyEntityEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/entity/DestroyEntityEvent.java similarity index 94% rename from src/main/java/com/sk89q/worldguard/internal/event/entity/DestroyEntityEvent.java rename to src/main/java/com/sk89q/worldguard/bukkit/event/entity/DestroyEntityEvent.java index ed68ed8f..3b74ee09 100644 --- a/src/main/java/com/sk89q/worldguard/internal/event/entity/DestroyEntityEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/entity/DestroyEntityEvent.java @@ -17,9 +17,9 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.event.entity; +package com.sk89q.worldguard.bukkit.event.entity; -import com.sk89q.worldguard.internal.cause.Cause; +import com.sk89q.worldguard.util.cause.Cause; import org.bukkit.entity.Entity; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; diff --git a/src/main/java/com/sk89q/worldguard/internal/event/entity/SpawnEntityEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/entity/SpawnEntityEvent.java similarity index 95% rename from src/main/java/com/sk89q/worldguard/internal/event/entity/SpawnEntityEvent.java rename to src/main/java/com/sk89q/worldguard/bukkit/event/entity/SpawnEntityEvent.java index d51bc364..bfd41a9f 100644 --- a/src/main/java/com/sk89q/worldguard/internal/event/entity/SpawnEntityEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/entity/SpawnEntityEvent.java @@ -17,9 +17,9 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.event.entity; +package com.sk89q.worldguard.bukkit.event.entity; -import com.sk89q.worldguard.internal.cause.Cause; +import com.sk89q.worldguard.util.cause.Cause; import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; diff --git a/src/main/java/com/sk89q/worldguard/internal/event/entity/UseEntityEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/entity/UseEntityEvent.java similarity index 94% rename from src/main/java/com/sk89q/worldguard/internal/event/entity/UseEntityEvent.java rename to src/main/java/com/sk89q/worldguard/bukkit/event/entity/UseEntityEvent.java index e8002534..08933202 100644 --- a/src/main/java/com/sk89q/worldguard/internal/event/entity/UseEntityEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/entity/UseEntityEvent.java @@ -17,9 +17,9 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.event.entity; +package com.sk89q.worldguard.bukkit.event.entity; -import com.sk89q.worldguard.internal.cause.Cause; +import com.sk89q.worldguard.util.cause.Cause; import org.bukkit.entity.Entity; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; diff --git a/src/main/java/com/sk89q/worldguard/internal/event/inventory/UseItemEvent.java b/src/main/java/com/sk89q/worldguard/bukkit/event/inventory/UseItemEvent.java similarity index 93% rename from src/main/java/com/sk89q/worldguard/internal/event/inventory/UseItemEvent.java rename to src/main/java/com/sk89q/worldguard/bukkit/event/inventory/UseItemEvent.java index 83766e9e..2d35d804 100644 --- a/src/main/java/com/sk89q/worldguard/internal/event/inventory/UseItemEvent.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/event/inventory/UseItemEvent.java @@ -17,10 +17,10 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.event.inventory; +package com.sk89q.worldguard.bukkit.event.inventory; -import com.sk89q.worldguard.internal.cause.Cause; -import com.sk89q.worldguard.internal.event.AbstractInteractEvent; +import com.sk89q.worldguard.util.cause.Cause; +import com.sk89q.worldguard.bukkit.event.AbstractInteractEvent; import org.bukkit.World; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; diff --git a/src/main/java/com/sk89q/worldguard/internal/listener/AbstractListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/AbstractListener.java similarity index 98% rename from src/main/java/com/sk89q/worldguard/internal/listener/AbstractListener.java rename to src/main/java/com/sk89q/worldguard/bukkit/listener/AbstractListener.java index f8845c5b..bce1e6ac 100644 --- a/src/main/java/com/sk89q/worldguard/internal/listener/AbstractListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/AbstractListener.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.listener; +package com.sk89q.worldguard.bukkit.listener; import com.sk89q.worldguard.bukkit.WorldConfiguration; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; diff --git a/src/main/java/com/sk89q/worldguard/internal/listener/BlacklistListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/BlacklistListener.java similarity index 94% rename from src/main/java/com/sk89q/worldguard/internal/listener/BlacklistListener.java rename to src/main/java/com/sk89q/worldguard/bukkit/listener/BlacklistListener.java index 18fcde6b..7399d3ea 100644 --- a/src/main/java/com/sk89q/worldguard/internal/listener/BlacklistListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/BlacklistListener.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.listener; +package com.sk89q.worldguard.bukkit.listener; import com.sk89q.worldguard.LocalPlayer; import com.sk89q.worldguard.blacklist.event.BlockBreakBlacklistEvent; @@ -32,13 +32,13 @@ import com.sk89q.worldguard.bukkit.WorldConfiguration; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.bukkit.util.Materials; -import com.sk89q.worldguard.internal.cause.Causes; -import com.sk89q.worldguard.internal.event.block.BreakBlockEvent; -import com.sk89q.worldguard.internal.event.block.PlaceBlockEvent; -import com.sk89q.worldguard.internal.event.block.UseBlockEvent; -import com.sk89q.worldguard.internal.event.entity.DestroyEntityEvent; -import com.sk89q.worldguard.internal.event.entity.SpawnEntityEvent; -import com.sk89q.worldguard.internal.event.inventory.UseItemEvent; +import com.sk89q.worldguard.util.cause.Causes; +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 org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Entity; diff --git a/src/main/java/com/sk89q/worldguard/internal/listener/BlockedPotionsListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/BlockedPotionsListener.java similarity index 96% rename from src/main/java/com/sk89q/worldguard/internal/listener/BlockedPotionsListener.java rename to src/main/java/com/sk89q/worldguard/bukkit/listener/BlockedPotionsListener.java index 85f5c455..a02a979c 100644 --- a/src/main/java/com/sk89q/worldguard/internal/listener/BlockedPotionsListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/BlockedPotionsListener.java @@ -17,14 +17,14 @@ * along with this program. If not, see . */ -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.inventory.UseItemEvent; +import com.sk89q.worldguard.util.cause.Causes; +import com.sk89q.worldguard.bukkit.event.inventory.UseItemEvent; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; diff --git a/src/main/java/com/sk89q/worldguard/internal/listener/ChestProtectionListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/ChestProtectionListener.java similarity index 95% rename from src/main/java/com/sk89q/worldguard/internal/listener/ChestProtectionListener.java rename to src/main/java/com/sk89q/worldguard/bukkit/listener/ChestProtectionListener.java index 4b7daffd..3757ad98 100644 --- a/src/main/java/com/sk89q/worldguard/internal/listener/ChestProtectionListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/ChestProtectionListener.java @@ -17,15 +17,15 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.listener; +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.internal.cause.Causes; -import com.sk89q.worldguard.internal.event.block.BreakBlockEvent; -import com.sk89q.worldguard.internal.event.block.PlaceBlockEvent; -import com.sk89q.worldguard.internal.event.block.UseBlockEvent; +import com.sk89q.worldguard.util.cause.Causes; +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; diff --git a/src/main/java/com/sk89q/worldguard/bukkit/listener/CauseListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/EventAbstractionListener.java similarity index 96% rename from src/main/java/com/sk89q/worldguard/bukkit/listener/CauseListener.java rename to src/main/java/com/sk89q/worldguard/bukkit/listener/EventAbstractionListener.java index 485b0b31..7e25d31e 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/listener/CauseListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/EventAbstractionListener.java @@ -22,16 +22,16 @@ import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.bukkit.util.Blocks; import com.sk89q.worldguard.bukkit.util.Materials; -import com.sk89q.worldguard.internal.Events; -import com.sk89q.worldguard.internal.cause.Cause; -import com.sk89q.worldguard.internal.cause.Causes; -import com.sk89q.worldguard.internal.event.block.BreakBlockEvent; -import com.sk89q.worldguard.internal.event.block.PlaceBlockEvent; -import com.sk89q.worldguard.internal.event.block.UseBlockEvent; -import com.sk89q.worldguard.internal.event.entity.DestroyEntityEvent; -import com.sk89q.worldguard.internal.event.entity.SpawnEntityEvent; -import com.sk89q.worldguard.internal.event.entity.UseEntityEvent; -import com.sk89q.worldguard.internal.event.inventory.UseItemEvent; +import com.sk89q.worldguard.bukkit.util.Events; +import com.sk89q.worldguard.util.cause.Cause; +import com.sk89q.worldguard.util.cause.Causes; +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.DyeColor; import org.bukkit.Material; import org.bukkit.World; @@ -87,13 +87,13 @@ import static com.sk89q.worldguard.bukkit.util.Materials.isBlockModifiedOnClick; import static com.sk89q.worldguard.bukkit.util.Materials.isItemAppliedToBlock; -import static com.sk89q.worldguard.internal.cause.Causes.create; +import static com.sk89q.worldguard.util.cause.Causes.create; -public class CauseListener implements Listener { +public class EventAbstractionListener implements Listener { private final WorldGuardPlugin plugin; - public CauseListener(WorldGuardPlugin plugin) { + public EventAbstractionListener(WorldGuardPlugin plugin) { this.plugin = plugin; } diff --git a/src/main/java/com/sk89q/worldguard/internal/listener/RegionProtectionListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/RegionProtectionListener.java similarity index 93% rename from src/main/java/com/sk89q/worldguard/internal/listener/RegionProtectionListener.java rename to src/main/java/com/sk89q/worldguard/bukkit/listener/RegionProtectionListener.java index 3214d23a..4c9c1a4c 100644 --- a/src/main/java/com/sk89q/worldguard/internal/listener/RegionProtectionListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/RegionProtectionListener.java @@ -17,19 +17,19 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.listener; +package com.sk89q.worldguard.bukkit.listener; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; 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.internal.cause.Causes; -import com.sk89q.worldguard.internal.event.block.BreakBlockEvent; -import com.sk89q.worldguard.internal.event.block.PlaceBlockEvent; -import com.sk89q.worldguard.internal.event.block.UseBlockEvent; -import com.sk89q.worldguard.internal.event.entity.DestroyEntityEvent; -import com.sk89q.worldguard.internal.event.entity.SpawnEntityEvent; -import com.sk89q.worldguard.internal.event.entity.UseEntityEvent; +import com.sk89q.worldguard.util.cause.Causes; +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.protection.flags.DefaultFlag; import org.bukkit.ChatColor; import org.bukkit.Location; diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardBlockListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardBlockListener.java similarity index 97% rename from src/main/java/com/sk89q/worldguard/bukkit/WorldGuardBlockListener.java rename to src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardBlockListener.java index 4cab5fab..ef0c69cf 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardBlockListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardBlockListener.java @@ -1,728 +1,732 @@ -/* - * WorldGuard, a suite of tools for Minecraft - * Copyright (C) sk89q - * 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 . - */ - -package com.sk89q.worldguard.bukkit; - -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.protection.ApplicableRegionSet; -import com.sk89q.worldguard.protection.flags.DefaultFlag; -import com.sk89q.worldguard.protection.managers.RegionManager; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.entity.Snowman; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockBurnEvent; -import org.bukkit.event.block.BlockExpEvent; -import org.bukkit.event.block.BlockFadeEvent; -import org.bukkit.event.block.BlockFormEvent; -import org.bukkit.event.block.BlockFromToEvent; -import org.bukkit.event.block.BlockIgniteEvent; -import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; -import org.bukkit.event.block.BlockPhysicsEvent; -import org.bukkit.event.block.BlockPistonExtendEvent; -import org.bukkit.event.block.BlockPistonRetractEvent; -import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.block.BlockRedstoneEvent; -import org.bukkit.event.block.BlockSpreadEvent; -import org.bukkit.event.block.EntityBlockFormEvent; -import org.bukkit.event.block.LeavesDecayEvent; -import org.bukkit.inventory.ItemStack; - -import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector; - -/** - * The listener for block events. - * - * @author sk89q - */ -public class WorldGuardBlockListener implements Listener { - - private WorldGuardPlugin plugin; - - /** - * Construct the object. - * - * @param plugin The plugin instance - */ - public WorldGuardBlockListener(WorldGuardPlugin plugin) { - this.plugin = plugin; - } - - /** - * Register events. - */ - public void registerEvents() { - plugin.getServer().getPluginManager().registerEvents(this, plugin); - } - - /** - * Get the world configuration given a world. - * - * @param world The world to get the configuration for. - * @return The configuration for {@code world} - */ - protected WorldConfiguration getWorldConfig(World world) { - return plugin.getGlobalStateManager().get(world); - } - - /** - * Get the world configuration given a player. - * - * @param player The player to get the wold from - * @return The {@link WorldConfiguration} for the player's world - */ - protected WorldConfiguration getWorldConfig(Player player) { - return getWorldConfig(player.getWorld()); - } - - /* - * Called when a block is broken. - */ - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onBlockBreak(BlockBreakEvent event) { - Player player = event.getPlayer(); - Block target = event.getBlock(); - WorldConfiguration wcfg = getWorldConfig(player); - - if (!wcfg.itemDurability) { - ItemStack held = player.getItemInHand(); - if (held.getType() != Material.AIR && !(ItemType.usesDamageValue(held.getTypeId())|| BlockType.usesData(held.getTypeId()))) { - held.setDurability((short) 0); - player.setItemInHand(held); - } - } - } - - /* - * Called when fluids flow. - */ - @EventHandler(ignoreCancelled = true) - public void onBlockFromTo(BlockFromToEvent event) { - World world = event.getBlock().getWorld(); - Block blockFrom = event.getBlock(); - Block blockTo = event.getToBlock(); - - boolean isWater = blockFrom.getTypeId() == 8 || blockFrom.getTypeId() == 9; - boolean isLava = blockFrom.getTypeId() == 10 || blockFrom.getTypeId() == 11; - boolean isAir = blockFrom.getTypeId() == 0; - - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); - - if (cfg.activityHaltToggle) { - event.setCancelled(true); - return; - } - - if (wcfg.simulateSponge && isWater) { - int ox = blockTo.getX(); - int oy = blockTo.getY(); - int oz = blockTo.getZ(); - - for (int cx = -wcfg.spongeRadius; cx <= wcfg.spongeRadius; cx++) { - for (int cy = -wcfg.spongeRadius; cy <= wcfg.spongeRadius; cy++) { - for (int cz = -wcfg.spongeRadius; cz <= wcfg.spongeRadius; cz++) { - Block sponge = world.getBlockAt(ox + cx, oy + cy, oz + cz); - if (sponge.getTypeId() == 19 - && (!wcfg.redstoneSponges || !sponge.isBlockIndirectlyPowered())) { - event.setCancelled(true); - return; - } - } - } - } - } - - /*if (plugin.classicWater && isWater) { - int blockBelow = blockFrom.getRelative(0, -1, 0).getTypeId(); - if (blockBelow != 0 && blockBelow != 8 && blockBelow != 9) { - blockFrom.setTypeId(9); - if (blockTo.getTypeId() == 0) { - blockTo.setTypeId(9); - } - return; - } - }*/ - - // Check the fluid block (from) whether it is air. - // If so and the target block is protected, cancel the event - if (wcfg.preventWaterDamage.size() > 0) { - int targetId = blockTo.getTypeId(); - - if ((isAir || isWater) && - wcfg.preventWaterDamage.contains(targetId)) { - event.setCancelled(true); - return; - } - } - - if (wcfg.allowedLavaSpreadOver.size() > 0 && isLava) { - int targetId = blockTo.getRelative(0, -1, 0).getTypeId(); - - if (!wcfg.allowedLavaSpreadOver.contains(targetId)) { - event.setCancelled(true); - return; - } - } - - if (wcfg.highFreqFlags && isWater - && !plugin.getGlobalRegionManager().allows(DefaultFlag.WATER_FLOW, - blockFrom.getLocation())) { - event.setCancelled(true); - return; - } - - if (wcfg.highFreqFlags && isLava - && !plugin.getGlobalRegionManager().allows(DefaultFlag.LAVA_FLOW, - blockFrom.getLocation())) { - event.setCancelled(true); - return; - } - - if (wcfg.disableObsidianGenerators && (isAir || isLava) - && (blockTo.getTypeId() == BlockID.REDSTONE_WIRE - || blockTo.getTypeId() == BlockID.TRIPWIRE)) { - blockTo.setTypeId(BlockID.AIR); - return; - } - } - - /* - * Called when a block gets ignited. - */ - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onBlockIgnite(BlockIgniteEvent event) { - IgniteCause cause = event.getCause(); - Block block = event.getBlock(); - World world = block.getWorld(); - - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(world); - - if (cfg.activityHaltToggle) { - event.setCancelled(true); - return; - } - boolean isFireSpread = cause == IgniteCause.SPREAD; - - if (wcfg.preventLightningFire && cause == IgniteCause.LIGHTNING) { - event.setCancelled(true); - return; - } - - if (wcfg.preventLavaFire && cause == IgniteCause.LAVA) { - event.setCancelled(true); - return; - } - - if (wcfg.disableFireSpread && isFireSpread) { - event.setCancelled(true); - return; - } - - if (wcfg.blockLighter && (cause == IgniteCause.FLINT_AND_STEEL || cause == IgniteCause.FIREBALL) - && event.getPlayer() != null - && !plugin.hasPermission(event.getPlayer(), "worldguard.override.lighter")) { - event.setCancelled(true); - return; - } - - if (wcfg.fireSpreadDisableToggle && isFireSpread) { - event.setCancelled(true); - return; - } - - if (wcfg.disableFireSpreadBlocks.size() > 0 && isFireSpread) { - int x = block.getX(); - int y = block.getY(); - int z = block.getZ(); - - if (wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x, y - 1, z)) - || wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x + 1, y, z)) - || wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x - 1, y, z)) - || wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x, y, z - 1)) - || wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x, y, z + 1))) { - event.setCancelled(true); - return; - } - } - - if (wcfg.useRegions) { - Vector pt = toVector(block); - RegionManager mgr = plugin.getGlobalRegionManager().get(world); - ApplicableRegionSet set = mgr.getApplicableRegions(pt); - - if (wcfg.highFreqFlags && isFireSpread - && !set.allows(DefaultFlag.FIRE_SPREAD)) { - event.setCancelled(true); - return; - } - - if (wcfg.highFreqFlags && cause == IgniteCause.LAVA - && !set.allows(DefaultFlag.LAVA_FIRE)) { - event.setCancelled(true); - return; - } - - if (cause == IgniteCause.FIREBALL && event.getPlayer() == null) { - // wtf bukkit, FIREBALL is supposed to be reserved to players - if (!set.allows(DefaultFlag.GHAST_FIREBALL)) { - event.setCancelled(true); - return; - } - } - - if (cause == IgniteCause.LIGHTNING && !set.allows(DefaultFlag.LIGHTNING)) { - event.setCancelled(true); - return; - } - } - } - - /* - * Called when a block is destroyed from burning. - */ - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onBlockBurn(BlockBurnEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); - - if (cfg.activityHaltToggle) { - event.setCancelled(true); - return; - } - - if (wcfg.disableFireSpread) { - event.setCancelled(true); - return; - } - - if (wcfg.fireSpreadDisableToggle) { - Block block = event.getBlock(); - event.setCancelled(true); - checkAndDestroyAround(block.getWorld(), block.getX(), block.getY(), block.getZ(), BlockID.FIRE); - return; - } - - if (wcfg.disableFireSpreadBlocks.size() > 0) { - Block block = event.getBlock(); - - if (wcfg.disableFireSpreadBlocks.contains(block.getTypeId())) { - event.setCancelled(true); - checkAndDestroyAround(block.getWorld(), block.getX(), block.getY(), block.getZ(), BlockID.FIRE); - return; - } - } - - if (wcfg.isChestProtected(event.getBlock())) { - event.setCancelled(true); - return; - } - - if (wcfg.useRegions) { - Block block = event.getBlock(); - int x = block.getX(); - int y = block.getY(); - int z = block.getZ(); - Vector pt = toVector(block); - RegionManager mgr = plugin.getGlobalRegionManager().get(block.getWorld()); - ApplicableRegionSet set = mgr.getApplicableRegions(pt); - - if (!set.allows(DefaultFlag.FIRE_SPREAD)) { - checkAndDestroyAround(block.getWorld(), x, y, z, BlockID.FIRE); - event.setCancelled(true); - return; - } - - } - } - - private void checkAndDestroyAround(World world, int x, int y, int z, int required) { - checkAndDestroy(world, x, y, z + 1, required); - checkAndDestroy(world, x, y, z - 1, required); - checkAndDestroy(world, x, y + 1, z, required); - checkAndDestroy(world, x, y - 1, z, required); - checkAndDestroy(world, x + 1, y, z, required); - checkAndDestroy(world, x - 1, y, z, required); - } - - private void checkAndDestroy(World world, int x, int y, int z, int required) { - if (world.getBlockTypeIdAt(x, y, z) == required) { - world.getBlockAt(x, y, z).setTypeId(BlockID.AIR); - } - } - - /* - * Called when block physics occurs. - */ - @EventHandler(ignoreCancelled = true) - public void onBlockPhysics(BlockPhysicsEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); - - if (cfg.activityHaltToggle) { - event.setCancelled(true); - return; - } - - int id = event.getChangedTypeId(); - - if (id == 13 && wcfg.noPhysicsGravel) { - event.setCancelled(true); - return; - } - - if (id == 12 && wcfg.noPhysicsSand) { - event.setCancelled(true); - return; - } - - if (id == 90 && wcfg.allowPortalAnywhere) { - event.setCancelled(true); - return; - } - - if (wcfg.ropeLadders && event.getBlock().getType() == Material.LADDER) { - if (event.getBlock().getRelative(0, 1, 0).getType() == Material.LADDER) { - event.setCancelled(true); - return; - } - } - } - - /* - * Called when a player places a block. - */ - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onBlockPlace(BlockPlaceEvent event) { - Block target = event.getBlock(); - World world = target.getWorld(); - - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(world); - - if (wcfg.simulateSponge && target.getType() == Material.SPONGE) { - if (wcfg.redstoneSponges && target.isBlockIndirectlyPowered()) { - return; - } - - int ox = target.getX(); - int oy = target.getY(); - int oz = target.getZ(); - - SpongeUtil.clearSpongeWater(plugin, world, ox, oy, oz); - } - } - - /* - * Called when redstone changes. - */ - @EventHandler(priority = EventPriority.HIGH) - public void onBlockRedstoneChange(BlockRedstoneEvent event) { - Block blockTo = event.getBlock(); - World world = blockTo.getWorld(); - - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(world); - - if (wcfg.simulateSponge && wcfg.redstoneSponges) { - int ox = blockTo.getX(); - int oy = blockTo.getY(); - int oz = blockTo.getZ(); - - for (int cx = -1; cx <= 1; cx++) { - for (int cy = -1; cy <= 1; cy++) { - for (int cz = -1; cz <= 1; cz++) { - Block sponge = world.getBlockAt(ox + cx, oy + cy, oz + cz); - if (sponge.getTypeId() == 19 - && sponge.isBlockIndirectlyPowered()) { - SpongeUtil.clearSpongeWater(plugin, world, ox + cx, oy + cy, oz + cz); - } else if (sponge.getTypeId() == 19 - && !sponge.isBlockIndirectlyPowered()) { - SpongeUtil.addSpongeWater(plugin, world, ox + cx, oy + cy, oz + cz); - } - } - } - } - - return; - } - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onLeavesDecay(LeavesDecayEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); - - if (cfg.activityHaltToggle) { - event.setCancelled(true); - return; - } - - if (wcfg.disableLeafDecay) { - event.setCancelled(true); - return; - } - - if (wcfg.useRegions) { - if (!plugin.getGlobalRegionManager().allows(DefaultFlag.LEAF_DECAY, - event.getBlock().getLocation())) { - event.setCancelled(true); - } - } - } - - /* - * Called when a block is formed based on world conditions. - */ - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onBlockForm(BlockFormEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); - - if (cfg.activityHaltToggle) { - event.setCancelled(true); - return; - } - - int type = event.getNewState().getTypeId(); - - if (event instanceof EntityBlockFormEvent) { - if (((EntityBlockFormEvent) event).getEntity() instanceof Snowman) { - if (wcfg.disableSnowmanTrails) { - event.setCancelled(true); - return; - } - } - return; - } - - if (type == BlockID.ICE) { - if (wcfg.disableIceFormation) { - event.setCancelled(true); - return; - } - if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows( - DefaultFlag.ICE_FORM, event.getBlock().getLocation())) { - event.setCancelled(true); - return; - } - } - - if (type == BlockID.SNOW) { - if (wcfg.disableSnowFormation) { - event.setCancelled(true); - return; - } - if (wcfg.allowedSnowFallOver.size() > 0) { - int targetId = event.getBlock().getRelative(0, -1, 0).getTypeId(); - - if (!wcfg.allowedSnowFallOver.contains(targetId)) { - event.setCancelled(true); - return; - } - } - if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows( - DefaultFlag.SNOW_FALL, event.getBlock().getLocation())) { - event.setCancelled(true); - return; - } - } - } - - /* - * Called when a block spreads based on world conditions. - */ - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onBlockSpread(BlockSpreadEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); - - if (cfg.activityHaltToggle) { - event.setCancelled(true); - return; - } - - int fromType = event.getSource().getTypeId(); - - if (fromType == BlockID.RED_MUSHROOM || fromType == BlockID.BROWN_MUSHROOM) { - if (wcfg.disableMushroomSpread) { - event.setCancelled(true); - return; - } - if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows( - DefaultFlag.MUSHROOMS, event.getBlock().getLocation())) { - event.setCancelled(true); - return; - } - } - - if (fromType == BlockID.GRASS) { - if (wcfg.disableGrassGrowth) { - event.setCancelled(true); - return; - } - if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows( - DefaultFlag.GRASS_SPREAD, event.getBlock().getLocation())) { - event.setCancelled(true); - return; - } - } - - if (fromType == BlockID.MYCELIUM) { - if (wcfg.disableMyceliumSpread) { - event.setCancelled(true); - return; - } - - if (wcfg.useRegions - && !plugin.getGlobalRegionManager().allows( - DefaultFlag.MYCELIUM_SPREAD, event.getBlock().getLocation())) { - event.setCancelled(true); - return; - } - } - - if (fromType == BlockID.VINE) { - if (wcfg.disableVineGrowth) { - event.setCancelled(true); - return; - } - - if (wcfg.useRegions - && !plugin.getGlobalRegionManager().allows( - DefaultFlag.VINE_GROWTH, event.getBlock().getLocation())) { - event.setCancelled(true); - return; - } - } - } - - /* - * Called when a block fades. - */ - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onBlockFade(BlockFadeEvent event) { - - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); - - switch (event.getBlock().getTypeId()) { - case BlockID.ICE: - if (wcfg.disableIceMelting) { - event.setCancelled(true); - return; - } - - if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows( - DefaultFlag.ICE_MELT, event.getBlock().getLocation())) { - event.setCancelled(true); - return; - } - break; - - case BlockID.SNOW: - if (wcfg.disableSnowMelting) { - event.setCancelled(true); - return; - } - - if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows( - DefaultFlag.SNOW_MELT, event.getBlock().getLocation())) { - event.setCancelled(true); - return; - } - break; - - case BlockID.SOIL: - if (wcfg.disableSoilDehydration) { - event.setCancelled(true); - return; - } - if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows( - DefaultFlag.SOIL_DRY, event.getBlock().getLocation())) { - event.setCancelled(true); - return; - } - break; - } - - } - - /* - * Called when a piston extends - */ - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onBlockPistonExtend(BlockPistonExtendEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); - - if (wcfg.useRegions) { - if (!plugin.getGlobalRegionManager().allows(DefaultFlag.PISTONS, event.getBlock().getLocation())) { - event.setCancelled(true); - return; - } - for (Block block : event.getBlocks()) { - if (!plugin.getGlobalRegionManager().allows(DefaultFlag.PISTONS, block.getLocation())) { - event.setCancelled(true); - return; - } - } - } - } - - /* - * Called when a piston retracts - */ - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onBlockPistonRetract(BlockPistonRetractEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); - - if (wcfg.useRegions && event.isSticky()) { - if (!(plugin.getGlobalRegionManager().allows(DefaultFlag.PISTONS, event.getRetractLocation())) - || !(plugin.getGlobalRegionManager().allows(DefaultFlag.PISTONS, event.getBlock().getLocation()))) { - event.setCancelled(true); - return; - } - } - } - - /* - * Called when a block yields exp - */ - @EventHandler(priority = EventPriority.HIGH) - public void onBlockExp(BlockExpEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); - if (wcfg.disableExpDrops || !plugin.getGlobalRegionManager().allows(DefaultFlag.EXP_DROPS, - event.getBlock().getLocation())) { - event.setExpToDrop(0); - } - } - -} +/* + * WorldGuard, a suite of tools for Minecraft + * Copyright (C) sk89q + * 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 . + */ + +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.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.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.entity.Snowman; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockExpEvent; +import org.bukkit.event.block.BlockFadeEvent; +import org.bukkit.event.block.BlockFormEvent; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.block.BlockPistonExtendEvent; +import org.bukkit.event.block.BlockPistonRetractEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.block.BlockRedstoneEvent; +import org.bukkit.event.block.BlockSpreadEvent; +import org.bukkit.event.block.EntityBlockFormEvent; +import org.bukkit.event.block.LeavesDecayEvent; +import org.bukkit.inventory.ItemStack; + +import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector; + +/** + * The listener for block events. + * + * @author sk89q + */ +public class WorldGuardBlockListener implements Listener { + + private WorldGuardPlugin plugin; + + /** + * Construct the object. + * + * @param plugin The plugin instance + */ + public WorldGuardBlockListener(WorldGuardPlugin plugin) { + this.plugin = plugin; + } + + /** + * Register events. + */ + public void registerEvents() { + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + /** + * Get the world configuration given a world. + * + * @param world The world to get the configuration for. + * @return The configuration for {@code world} + */ + protected WorldConfiguration getWorldConfig(World world) { + return plugin.getGlobalStateManager().get(world); + } + + /** + * Get the world configuration given a player. + * + * @param player The player to get the wold from + * @return The {@link WorldConfiguration} for the player's world + */ + protected WorldConfiguration getWorldConfig(Player player) { + return getWorldConfig(player.getWorld()); + } + + /* + * Called when a block is broken. + */ + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) { + Player player = event.getPlayer(); + Block target = event.getBlock(); + WorldConfiguration wcfg = getWorldConfig(player); + + if (!wcfg.itemDurability) { + ItemStack held = player.getItemInHand(); + if (held.getType() != Material.AIR && !(ItemType.usesDamageValue(held.getTypeId())|| BlockType.usesData(held.getTypeId()))) { + held.setDurability((short) 0); + player.setItemInHand(held); + } + } + } + + /* + * Called when fluids flow. + */ + @EventHandler(ignoreCancelled = true) + public void onBlockFromTo(BlockFromToEvent event) { + World world = event.getBlock().getWorld(); + Block blockFrom = event.getBlock(); + Block blockTo = event.getToBlock(); + + boolean isWater = blockFrom.getTypeId() == 8 || blockFrom.getTypeId() == 9; + boolean isLava = blockFrom.getTypeId() == 10 || blockFrom.getTypeId() == 11; + boolean isAir = blockFrom.getTypeId() == 0; + + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); + + if (cfg.activityHaltToggle) { + event.setCancelled(true); + return; + } + + if (wcfg.simulateSponge && isWater) { + int ox = blockTo.getX(); + int oy = blockTo.getY(); + int oz = blockTo.getZ(); + + for (int cx = -wcfg.spongeRadius; cx <= wcfg.spongeRadius; cx++) { + for (int cy = -wcfg.spongeRadius; cy <= wcfg.spongeRadius; cy++) { + for (int cz = -wcfg.spongeRadius; cz <= wcfg.spongeRadius; cz++) { + Block sponge = world.getBlockAt(ox + cx, oy + cy, oz + cz); + if (sponge.getTypeId() == 19 + && (!wcfg.redstoneSponges || !sponge.isBlockIndirectlyPowered())) { + event.setCancelled(true); + return; + } + } + } + } + } + + /*if (plugin.classicWater && isWater) { + int blockBelow = blockFrom.getRelative(0, -1, 0).getTypeId(); + if (blockBelow != 0 && blockBelow != 8 && blockBelow != 9) { + blockFrom.setTypeId(9); + if (blockTo.getTypeId() == 0) { + blockTo.setTypeId(9); + } + return; + } + }*/ + + // Check the fluid block (from) whether it is air. + // If so and the target block is protected, cancel the event + if (wcfg.preventWaterDamage.size() > 0) { + int targetId = blockTo.getTypeId(); + + if ((isAir || isWater) && + wcfg.preventWaterDamage.contains(targetId)) { + event.setCancelled(true); + return; + } + } + + if (wcfg.allowedLavaSpreadOver.size() > 0 && isLava) { + int targetId = blockTo.getRelative(0, -1, 0).getTypeId(); + + if (!wcfg.allowedLavaSpreadOver.contains(targetId)) { + event.setCancelled(true); + return; + } + } + + if (wcfg.highFreqFlags && isWater + && !plugin.getGlobalRegionManager().allows(DefaultFlag.WATER_FLOW, + blockFrom.getLocation())) { + event.setCancelled(true); + return; + } + + if (wcfg.highFreqFlags && isLava + && !plugin.getGlobalRegionManager().allows(DefaultFlag.LAVA_FLOW, + blockFrom.getLocation())) { + event.setCancelled(true); + return; + } + + if (wcfg.disableObsidianGenerators && (isAir || isLava) + && (blockTo.getTypeId() == BlockID.REDSTONE_WIRE + || blockTo.getTypeId() == BlockID.TRIPWIRE)) { + blockTo.setTypeId(BlockID.AIR); + return; + } + } + + /* + * Called when a block gets ignited. + */ + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockIgnite(BlockIgniteEvent event) { + IgniteCause cause = event.getCause(); + Block block = event.getBlock(); + World world = block.getWorld(); + + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(world); + + if (cfg.activityHaltToggle) { + event.setCancelled(true); + return; + } + boolean isFireSpread = cause == IgniteCause.SPREAD; + + if (wcfg.preventLightningFire && cause == IgniteCause.LIGHTNING) { + event.setCancelled(true); + return; + } + + if (wcfg.preventLavaFire && cause == IgniteCause.LAVA) { + event.setCancelled(true); + return; + } + + if (wcfg.disableFireSpread && isFireSpread) { + event.setCancelled(true); + return; + } + + if (wcfg.blockLighter && (cause == IgniteCause.FLINT_AND_STEEL || cause == IgniteCause.FIREBALL) + && event.getPlayer() != null + && !plugin.hasPermission(event.getPlayer(), "worldguard.override.lighter")) { + event.setCancelled(true); + return; + } + + if (wcfg.fireSpreadDisableToggle && isFireSpread) { + event.setCancelled(true); + return; + } + + if (wcfg.disableFireSpreadBlocks.size() > 0 && isFireSpread) { + int x = block.getX(); + int y = block.getY(); + int z = block.getZ(); + + if (wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x, y - 1, z)) + || wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x + 1, y, z)) + || wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x - 1, y, z)) + || wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x, y, z - 1)) + || wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x, y, z + 1))) { + event.setCancelled(true); + return; + } + } + + if (wcfg.useRegions) { + Vector pt = toVector(block); + RegionManager mgr = plugin.getGlobalRegionManager().get(world); + ApplicableRegionSet set = mgr.getApplicableRegions(pt); + + if (wcfg.highFreqFlags && isFireSpread + && !set.allows(DefaultFlag.FIRE_SPREAD)) { + event.setCancelled(true); + return; + } + + if (wcfg.highFreqFlags && cause == IgniteCause.LAVA + && !set.allows(DefaultFlag.LAVA_FIRE)) { + event.setCancelled(true); + return; + } + + if (cause == IgniteCause.FIREBALL && event.getPlayer() == null) { + // wtf bukkit, FIREBALL is supposed to be reserved to players + if (!set.allows(DefaultFlag.GHAST_FIREBALL)) { + event.setCancelled(true); + return; + } + } + + if (cause == IgniteCause.LIGHTNING && !set.allows(DefaultFlag.LIGHTNING)) { + event.setCancelled(true); + return; + } + } + } + + /* + * Called when a block is destroyed from burning. + */ + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockBurn(BlockBurnEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); + + if (cfg.activityHaltToggle) { + event.setCancelled(true); + return; + } + + if (wcfg.disableFireSpread) { + event.setCancelled(true); + return; + } + + if (wcfg.fireSpreadDisableToggle) { + Block block = event.getBlock(); + event.setCancelled(true); + checkAndDestroyAround(block.getWorld(), block.getX(), block.getY(), block.getZ(), BlockID.FIRE); + return; + } + + if (wcfg.disableFireSpreadBlocks.size() > 0) { + Block block = event.getBlock(); + + if (wcfg.disableFireSpreadBlocks.contains(block.getTypeId())) { + event.setCancelled(true); + checkAndDestroyAround(block.getWorld(), block.getX(), block.getY(), block.getZ(), BlockID.FIRE); + return; + } + } + + if (wcfg.isChestProtected(event.getBlock())) { + event.setCancelled(true); + return; + } + + if (wcfg.useRegions) { + Block block = event.getBlock(); + int x = block.getX(); + int y = block.getY(); + int z = block.getZ(); + Vector pt = toVector(block); + RegionManager mgr = plugin.getGlobalRegionManager().get(block.getWorld()); + ApplicableRegionSet set = mgr.getApplicableRegions(pt); + + if (!set.allows(DefaultFlag.FIRE_SPREAD)) { + checkAndDestroyAround(block.getWorld(), x, y, z, BlockID.FIRE); + event.setCancelled(true); + return; + } + + } + } + + private void checkAndDestroyAround(World world, int x, int y, int z, int required) { + checkAndDestroy(world, x, y, z + 1, required); + checkAndDestroy(world, x, y, z - 1, required); + checkAndDestroy(world, x, y + 1, z, required); + checkAndDestroy(world, x, y - 1, z, required); + checkAndDestroy(world, x + 1, y, z, required); + checkAndDestroy(world, x - 1, y, z, required); + } + + private void checkAndDestroy(World world, int x, int y, int z, int required) { + if (world.getBlockTypeIdAt(x, y, z) == required) { + world.getBlockAt(x, y, z).setTypeId(BlockID.AIR); + } + } + + /* + * Called when block physics occurs. + */ + @EventHandler(ignoreCancelled = true) + public void onBlockPhysics(BlockPhysicsEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); + + if (cfg.activityHaltToggle) { + event.setCancelled(true); + return; + } + + int id = event.getChangedTypeId(); + + if (id == 13 && wcfg.noPhysicsGravel) { + event.setCancelled(true); + return; + } + + if (id == 12 && wcfg.noPhysicsSand) { + event.setCancelled(true); + return; + } + + if (id == 90 && wcfg.allowPortalAnywhere) { + event.setCancelled(true); + return; + } + + if (wcfg.ropeLadders && event.getBlock().getType() == Material.LADDER) { + if (event.getBlock().getRelative(0, 1, 0).getType() == Material.LADDER) { + event.setCancelled(true); + return; + } + } + } + + /* + * Called when a player places a block. + */ + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockPlace(BlockPlaceEvent event) { + Block target = event.getBlock(); + World world = target.getWorld(); + + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(world); + + if (wcfg.simulateSponge && target.getType() == Material.SPONGE) { + if (wcfg.redstoneSponges && target.isBlockIndirectlyPowered()) { + return; + } + + int ox = target.getX(); + int oy = target.getY(); + int oz = target.getZ(); + + SpongeUtil.clearSpongeWater(plugin, world, ox, oy, oz); + } + } + + /* + * Called when redstone changes. + */ + @EventHandler(priority = EventPriority.HIGH) + public void onBlockRedstoneChange(BlockRedstoneEvent event) { + Block blockTo = event.getBlock(); + World world = blockTo.getWorld(); + + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(world); + + if (wcfg.simulateSponge && wcfg.redstoneSponges) { + int ox = blockTo.getX(); + int oy = blockTo.getY(); + int oz = blockTo.getZ(); + + for (int cx = -1; cx <= 1; cx++) { + for (int cy = -1; cy <= 1; cy++) { + for (int cz = -1; cz <= 1; cz++) { + Block sponge = world.getBlockAt(ox + cx, oy + cy, oz + cz); + if (sponge.getTypeId() == 19 + && sponge.isBlockIndirectlyPowered()) { + SpongeUtil.clearSpongeWater(plugin, world, ox + cx, oy + cy, oz + cz); + } else if (sponge.getTypeId() == 19 + && !sponge.isBlockIndirectlyPowered()) { + SpongeUtil.addSpongeWater(plugin, world, ox + cx, oy + cy, oz + cz); + } + } + } + } + + return; + } + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onLeavesDecay(LeavesDecayEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); + + if (cfg.activityHaltToggle) { + event.setCancelled(true); + return; + } + + if (wcfg.disableLeafDecay) { + event.setCancelled(true); + return; + } + + if (wcfg.useRegions) { + if (!plugin.getGlobalRegionManager().allows(DefaultFlag.LEAF_DECAY, + event.getBlock().getLocation())) { + event.setCancelled(true); + } + } + } + + /* + * Called when a block is formed based on world conditions. + */ + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockForm(BlockFormEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); + + if (cfg.activityHaltToggle) { + event.setCancelled(true); + return; + } + + int type = event.getNewState().getTypeId(); + + if (event instanceof EntityBlockFormEvent) { + if (((EntityBlockFormEvent) event).getEntity() instanceof Snowman) { + if (wcfg.disableSnowmanTrails) { + event.setCancelled(true); + return; + } + } + return; + } + + if (type == BlockID.ICE) { + if (wcfg.disableIceFormation) { + event.setCancelled(true); + return; + } + if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows( + DefaultFlag.ICE_FORM, event.getBlock().getLocation())) { + event.setCancelled(true); + return; + } + } + + if (type == BlockID.SNOW) { + if (wcfg.disableSnowFormation) { + event.setCancelled(true); + return; + } + if (wcfg.allowedSnowFallOver.size() > 0) { + int targetId = event.getBlock().getRelative(0, -1, 0).getTypeId(); + + if (!wcfg.allowedSnowFallOver.contains(targetId)) { + event.setCancelled(true); + return; + } + } + if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows( + DefaultFlag.SNOW_FALL, event.getBlock().getLocation())) { + event.setCancelled(true); + return; + } + } + } + + /* + * Called when a block spreads based on world conditions. + */ + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockSpread(BlockSpreadEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); + + if (cfg.activityHaltToggle) { + event.setCancelled(true); + return; + } + + int fromType = event.getSource().getTypeId(); + + if (fromType == BlockID.RED_MUSHROOM || fromType == BlockID.BROWN_MUSHROOM) { + if (wcfg.disableMushroomSpread) { + event.setCancelled(true); + return; + } + if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows( + DefaultFlag.MUSHROOMS, event.getBlock().getLocation())) { + event.setCancelled(true); + return; + } + } + + if (fromType == BlockID.GRASS) { + if (wcfg.disableGrassGrowth) { + event.setCancelled(true); + return; + } + if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows( + DefaultFlag.GRASS_SPREAD, event.getBlock().getLocation())) { + event.setCancelled(true); + return; + } + } + + if (fromType == BlockID.MYCELIUM) { + if (wcfg.disableMyceliumSpread) { + event.setCancelled(true); + return; + } + + if (wcfg.useRegions + && !plugin.getGlobalRegionManager().allows( + DefaultFlag.MYCELIUM_SPREAD, event.getBlock().getLocation())) { + event.setCancelled(true); + return; + } + } + + if (fromType == BlockID.VINE) { + if (wcfg.disableVineGrowth) { + event.setCancelled(true); + return; + } + + if (wcfg.useRegions + && !plugin.getGlobalRegionManager().allows( + DefaultFlag.VINE_GROWTH, event.getBlock().getLocation())) { + event.setCancelled(true); + return; + } + } + } + + /* + * Called when a block fades. + */ + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockFade(BlockFadeEvent event) { + + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); + + switch (event.getBlock().getTypeId()) { + case BlockID.ICE: + if (wcfg.disableIceMelting) { + event.setCancelled(true); + return; + } + + if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows( + DefaultFlag.ICE_MELT, event.getBlock().getLocation())) { + event.setCancelled(true); + return; + } + break; + + case BlockID.SNOW: + if (wcfg.disableSnowMelting) { + event.setCancelled(true); + return; + } + + if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows( + DefaultFlag.SNOW_MELT, event.getBlock().getLocation())) { + event.setCancelled(true); + return; + } + break; + + case BlockID.SOIL: + if (wcfg.disableSoilDehydration) { + event.setCancelled(true); + return; + } + if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows( + DefaultFlag.SOIL_DRY, event.getBlock().getLocation())) { + event.setCancelled(true); + return; + } + break; + } + + } + + /* + * Called when a piston extends + */ + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockPistonExtend(BlockPistonExtendEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); + + if (wcfg.useRegions) { + if (!plugin.getGlobalRegionManager().allows(DefaultFlag.PISTONS, event.getBlock().getLocation())) { + event.setCancelled(true); + return; + } + for (Block block : event.getBlocks()) { + if (!plugin.getGlobalRegionManager().allows(DefaultFlag.PISTONS, block.getLocation())) { + event.setCancelled(true); + return; + } + } + } + } + + /* + * Called when a piston retracts + */ + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockPistonRetract(BlockPistonRetractEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); + + if (wcfg.useRegions && event.isSticky()) { + if (!(plugin.getGlobalRegionManager().allows(DefaultFlag.PISTONS, event.getRetractLocation())) + || !(plugin.getGlobalRegionManager().allows(DefaultFlag.PISTONS, event.getBlock().getLocation()))) { + event.setCancelled(true); + return; + } + } + } + + /* + * Called when a block yields exp + */ + @EventHandler(priority = EventPriority.HIGH) + public void onBlockExp(BlockExpEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); + if (wcfg.disableExpDrops || !plugin.getGlobalRegionManager().allows(DefaultFlag.EXP_DROPS, + event.getBlock().getLocation())) { + event.setExpToDrop(0); + } + } + +} diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardCommandBookListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardCommandBookListener.java similarity index 96% rename from src/main/java/com/sk89q/worldguard/bukkit/WorldGuardCommandBookListener.java rename to src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardCommandBookListener.java index 7727ba6d..40fa77eb 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardCommandBookListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardCommandBookListener.java @@ -17,10 +17,11 @@ * along with this program. If not, see . */ -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; diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardEntityListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardEntityListener.java similarity index 97% rename from src/main/java/com/sk89q/worldguard/bukkit/WorldGuardEntityListener.java rename to src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardEntityListener.java index ac5fb2ec..b052f72f 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardEntityListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardEntityListener.java @@ -1,1004 +1,1009 @@ -/* - * WorldGuard, a suite of tools for Minecraft - * Copyright (C) sk89q - * 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 . - */ - -package com.sk89q.worldguard.bukkit; - -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.blocks.BlockID; -import com.sk89q.worldguard.LocalPlayer; -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; -import org.bukkit.entity.Fireball; -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.entity.Projectile; -import org.bukkit.entity.TNTPrimed; -import org.bukkit.entity.Tameable; -import org.bukkit.entity.ThrownPotion; -import org.bukkit.entity.Wither; -import org.bukkit.entity.WitherSkull; -import org.bukkit.entity.Wolf; -import org.bukkit.entity.minecart.ExplosiveMinecart; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.CreatureSpawnEvent; -import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; -import org.bukkit.event.entity.CreeperPowerEvent; -import org.bukkit.event.entity.EntityBreakDoorEvent; -import org.bukkit.event.entity.EntityChangeBlockEvent; -import org.bukkit.event.entity.EntityCombustEvent; -import org.bukkit.event.entity.EntityCreatePortalEvent; -import org.bukkit.event.entity.EntityDamageByBlockEvent; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; -import org.bukkit.event.entity.EntityDeathEvent; -import org.bukkit.event.entity.EntityExplodeEvent; -import org.bukkit.event.entity.EntityInteractEvent; -import org.bukkit.event.entity.EntityRegainHealthEvent; -import org.bukkit.event.entity.ExpBottleEvent; -import org.bukkit.event.entity.ExplosionPrimeEvent; -import org.bukkit.event.entity.FoodLevelChangeEvent; -import org.bukkit.event.entity.PigZapEvent; -import org.bukkit.event.entity.PlayerDeathEvent; -import org.bukkit.event.entity.PotionSplashEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.projectiles.ProjectileSource; - -import java.util.Set; - -import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector; - -/** - * Listener for entity related events. - * - * @author sk89q - */ -public class WorldGuardEntityListener implements Listener { - - private WorldGuardPlugin plugin; - - /** - * Construct the object; - * - * @param plugin The plugin instance - */ - public WorldGuardEntityListener(WorldGuardPlugin plugin) { - this.plugin = plugin; - } - - /** - * Register events. - */ - public void registerEvents() { - plugin.getServer().getPluginManager().registerEvents(this, plugin); - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onEntityInteract(EntityInteractEvent event) { - Entity entity = event.getEntity(); - Block block = event.getBlock(); - - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(entity.getWorld()); - - if (block.getTypeId() == BlockID.SOIL) { - if (/* entity instanceof Creature && // catch for any entity (not thrown for players) */ - wcfg.disableCreatureCropTrampling) { - event.setCancelled(true); - } - } - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onExpBottle(ExpBottleEvent event) { - WorldConfiguration wcfg = plugin.getGlobalStateManager().get(event.getEntity().getWorld()); - - if (wcfg.disableExpDrops || !plugin.getGlobalRegionManager().allows(DefaultFlag.EXP_DROPS, - event.getEntity().getLocation())) { - event.setExperience(0); - // event.setShowEffect(false); // don't want to cancel the bottle entirely I suppose, just the exp - } - } - - @EventHandler(priority = EventPriority.HIGH) - public void onEntityDeath(EntityDeathEvent event) { - WorldConfiguration wcfg = plugin.getGlobalStateManager().get(event.getEntity().getWorld()); - - if (wcfg.disableExpDrops || !plugin.getGlobalRegionManager().allows(DefaultFlag.EXP_DROPS, - event.getEntity().getLocation())) { - event.setDroppedExp(0); - } - - if (event instanceof PlayerDeathEvent && wcfg.disableDeathMessages) { - ((PlayerDeathEvent) event).setDeathMessage(""); - } - } - - private void onEntityDamageByBlock(EntityDamageByBlockEvent event) { - Entity defender = event.getEntity(); - DamageCause type = event.getCause(); - - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(defender.getWorld()); - - if (defender instanceof Wolf && ((Wolf) defender).isTamed()) { - if (wcfg.antiWolfDumbness && !(type == DamageCause.VOID)) { - event.setCancelled(true); - return; - } - } else if (defender instanceof Player) { - Player player = (Player) defender; - - if (isInvincible(player)) { - event.setCancelled(true); - return; - } - - if (wcfg.disableLavaDamage && type == DamageCause.LAVA) { - event.setCancelled(true); - player.setFireTicks(0); - return; - } - - if (wcfg.disableContactDamage && type == DamageCause.CONTACT) { - event.setCancelled(true); - return; - } - - if (wcfg.teleportOnVoid && type == DamageCause.VOID) { - BukkitUtil.findFreePosition(player); - event.setCancelled(true); - return; - } - - if (wcfg.disableVoidDamage && type == DamageCause.VOID) { - event.setCancelled(true); - return; - } - - if (type == DamageCause.BLOCK_EXPLOSION - && (wcfg.disableExplosionDamage || wcfg.blockOtherExplosions - || (wcfg.explosionFlagCancellation - && !plugin.getGlobalRegionManager().allows(DefaultFlag.OTHER_EXPLOSION, player.getLocation())))) { - event.setCancelled(true); - return; - } - } else { - - // for whatever reason, plugin-caused explosions with a null entity count as block explosions and aren't - // handled anywhere else - if (type == DamageCause.BLOCK_EXPLOSION - && (wcfg.blockOtherExplosions - || (wcfg.explosionFlagCancellation - && !plugin.getGlobalRegionManager().allows(DefaultFlag.OTHER_EXPLOSION, defender.getLocation())))) { - event.setCancelled(true); - return; - } - } - } - - private void onEntityDamageByEntity(EntityDamageByEntityEvent event) { - - if (event.getDamager() instanceof Projectile) { - onEntityDamageByProjectile(event); - return; - } - - Entity attacker = event.getDamager(); - Entity defender = event.getEntity(); - - if (defender instanceof ItemFrame) { - if (checkItemFrameProtection(attacker, (ItemFrame) defender)) { - event.setCancelled(true); - return; - } - } - - if (defender instanceof Player) { - Player player = (Player) defender; - LocalPlayer localPlayer = plugin.wrapPlayer(player); - - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(player.getWorld()); - - if (isInvincible(player)) { - if (wcfg.regionInvinciblityRemovesMobs - && attacker instanceof LivingEntity && !(attacker instanceof Player) - && !(attacker instanceof Tameable && ((Tameable) attacker).isTamed())) { - attacker.remove(); - } - - event.setCancelled(true); - return; - } - - if (wcfg.disableLightningDamage && event.getCause() == DamageCause.LIGHTNING) { - event.setCancelled(true); - return; - } - - if (wcfg.disableExplosionDamage) { - switch (event.getCause()) { - case BLOCK_EXPLOSION: - case ENTITY_EXPLOSION: - event.setCancelled(true); - return; - } - } - - if (attacker != null) { - if (attacker instanceof Player) { - if (wcfg.useRegions) { - Vector pt = toVector(defender.getLocation()); - Vector pt2 = toVector(attacker.getLocation()); - RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld()); - - if (!mgr.getApplicableRegions(pt2).allows(DefaultFlag.PVP, plugin.wrapPlayer((Player) attacker))) { - tryCancelPVPEvent((Player) attacker, player, event, true); - } else if (!mgr.getApplicableRegions(pt).allows(DefaultFlag.PVP ,localPlayer)) { - 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... - if (wcfg.blockTNTExplosions) { - event.setCancelled(true); - return; - } - if (wcfg.useRegions && wcfg.explosionFlagCancellation) { - Vector pt = toVector(defender.getLocation()); - RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld()); - ApplicableRegionSet set = mgr.getApplicableRegions(pt); - if (!set.allows(DefaultFlag.TNT, localPlayer)) { - event.setCancelled(true); - return; - } - } - } - - if (attacker instanceof Fireball) { - if (attacker instanceof WitherSkull) { - if (wcfg.blockWitherSkullExplosions) { - event.setCancelled(true); - return; - } - } else { - if (wcfg.blockFireballExplosions) { - event.setCancelled(true); - return; - } - } - if (wcfg.useRegions) { - Fireball fireball = (Fireball) attacker; - Vector pt = toVector(defender.getLocation()); - RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld()); - ApplicableRegionSet set = mgr.getApplicableRegions(pt); - if (fireball.getShooter() instanceof Player) { - Vector pt2 = toVector(((Player) fireball.getShooter()).getLocation()); - if (!mgr.getApplicableRegions(pt2).allows(DefaultFlag.PVP, plugin.wrapPlayer((Player) fireball.getShooter()))) { - tryCancelPVPEvent((Player) fireball.getShooter(), player, event, true); - } else if (!set.allows(DefaultFlag.PVP, localPlayer)) { - tryCancelPVPEvent((Player) fireball.getShooter(), player, event, false); - } - } else { - if (!set.allows(DefaultFlag.GHAST_FIREBALL, localPlayer) && wcfg.explosionFlagCancellation) { - event.setCancelled(true); - return; - } - } - - } - } - - if (attacker instanceof LivingEntity && !(attacker instanceof Player)) { - if (attacker instanceof Creeper && wcfg.blockCreeperExplosions) { - event.setCancelled(true); - return; - } - - if (wcfg.disableMobDamage) { - event.setCancelled(true); - return; - } - - if (wcfg.useRegions) { - Vector pt = toVector(defender.getLocation()); - RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld()); - ApplicableRegionSet set = mgr.getApplicableRegions(pt); - - if (!set.allows(DefaultFlag.MOB_DAMAGE, localPlayer) && !(attacker instanceof Tameable)) { - event.setCancelled(true); - return; - } - - if (attacker instanceof Creeper) { - if (!set.allows(DefaultFlag.CREEPER_EXPLOSION, localPlayer) && wcfg.explosionFlagCancellation) { - event.setCancelled(true); - 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(); - Vector pt2 = toVector(attacker.getLocation()); - if (!mgr.getApplicableRegions(pt2).allows(DefaultFlag.PVP, plugin.wrapPlayer(beastMaster))) { - tryCancelPVPEvent(beastMaster, player, event, true); - } else if (!set.allows(DefaultFlag.PVP, localPlayer)) { - tryCancelPVPEvent(beastMaster, player, event, false); - } - } - } - } - } - } - } - - private void onEntityDamageByProjectile(EntityDamageByEntityEvent event) { - Entity defender = event.getEntity(); - Entity attacker; - ProjectileSource source = ((Projectile) event.getDamager()).getShooter(); - if (source instanceof LivingEntity) { - attacker = (LivingEntity) source; - } else { - return; - } - - if (defender instanceof Player) { - Player player = (Player) defender; - LocalPlayer localPlayer = plugin.wrapPlayer(player); - - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(player.getWorld()); - - // Check Invincible - if (isInvincible(player)) { - event.setCancelled(true); - return; - } - - // Check Mob - if (attacker != null && !(attacker instanceof Player)) { - if (wcfg.disableMobDamage) { - event.setCancelled(true); - return; - } - if (wcfg.useRegions) { - Vector pt = toVector(defender.getLocation()); - RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld()); - - if (!mgr.getApplicableRegions(pt).allows(DefaultFlag.MOB_DAMAGE, localPlayer)) { - event.setCancelled(true); - return; - } - } - } - - // 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) { - Vector pt = toVector(defender.getLocation()); - Vector pt2 = toVector(attacker.getLocation()); - RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld()); - - if (!mgr.getApplicableRegions(pt2).allows(DefaultFlag.PVP, plugin.wrapPlayer((Player) attacker))) { - tryCancelPVPEvent((Player) attacker, player, event, true); - } else if (!mgr.getApplicableRegions(pt).allows(DefaultFlag.PVP, localPlayer)) { - tryCancelPVPEvent((Player) attacker, player, event, false); - } - } - } - } else if (defender instanceof ItemFrame) { - if (checkItemFrameProtection(attacker, (ItemFrame) defender)) { - event.setCancelled(true); - return; - } - } - - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onEntityDamage(EntityDamageEvent event) { - - if (event instanceof EntityDamageByEntityEvent) { - this.onEntityDamageByEntity((EntityDamageByEntityEvent) event); - return; - } else if (event instanceof EntityDamageByBlockEvent) { - this.onEntityDamageByBlock((EntityDamageByBlockEvent) event); - return; - } - - Entity defender = event.getEntity(); - DamageCause type = event.getCause(); - - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(defender.getWorld()); - - if (defender instanceof Wolf && ((Wolf) defender).isTamed()) { - if (wcfg.antiWolfDumbness) { - event.setCancelled(true); - return; - } - } else if (defender instanceof Player) { - Player player = (Player) defender; - - if (isInvincible(player)) { - event.setCancelled(true); - player.setFireTicks(0); - return; - } - - if (type == DamageCause.WITHER) { - // wither boss DoT tick - if (wcfg.disableMobDamage) { - event.setCancelled(true); - return; - } - - if (wcfg.useRegions) { - Vector pt = toVector(defender.getLocation()); - RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld()); - ApplicableRegionSet set = mgr.getApplicableRegions(pt); - - if (!set.allows(DefaultFlag.MOB_DAMAGE, plugin.wrapPlayer(player))) { - event.setCancelled(true); - return; - } - } - } - - if (type == DamageCause.DROWNING && cfg.hasAmphibiousMode(player)) { - player.setRemainingAir(player.getMaximumAir()); - event.setCancelled(true); - return; - } - - ItemStack helmet = player.getInventory().getHelmet(); - - if (type == DamageCause.DROWNING && wcfg.pumpkinScuba - && helmet != null - && (helmet.getTypeId() == BlockID.PUMPKIN - || helmet.getTypeId() == BlockID.JACKOLANTERN)) { - player.setRemainingAir(player.getMaximumAir()); - event.setCancelled(true); - return; - } - - if (wcfg.disableFallDamage && type == DamageCause.FALL) { - event.setCancelled(true); - return; - } - - if (wcfg.disableFireDamage && (type == DamageCause.FIRE - || type == DamageCause.FIRE_TICK)) { - event.setCancelled(true); - return; - } - - if (wcfg.disableDrowningDamage && type == DamageCause.DROWNING) { - player.setRemainingAir(player.getMaximumAir()); - event.setCancelled(true); - return; - } - - if (wcfg.teleportOnSuffocation && type == DamageCause.SUFFOCATION) { - BukkitUtil.findFreePosition(player); - event.setCancelled(true); - return; - } - - if (wcfg.disableSuffocationDamage && type == DamageCause.SUFFOCATION) { - event.setCancelled(true); - return; - } - } - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onEntityCombust(EntityCombustEvent event) { - Entity entity = event.getEntity(); - - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(entity.getWorld()); - - if (entity instanceof Player) { - Player player = (Player) entity; - - if (cfg.hasGodMode(player) || (wcfg.useRegions && RegionQueryUtil.isInvincible(plugin, player))) { - event.setCancelled(true); - return; - } - } - } - - /* - * Called on entity explode. - */ - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onEntityExplode(EntityExplodeEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - Location l = event.getLocation(); - World world = l.getWorld(); - WorldConfiguration wcfg = cfg.get(world); - Entity ent = event.getEntity(); - - if (cfg.activityHaltToggle) { - if (ent != null) { - ent.remove(); - } - event.setCancelled(true); - return; - } - - if (ent instanceof Creeper) { - if (wcfg.blockCreeperExplosions) { - event.setCancelled(true); - return; - } - if (wcfg.blockCreeperBlockDamage) { - event.blockList().clear(); - return; - } - - if (wcfg.useRegions) { - RegionManager mgr = plugin.getGlobalRegionManager().get(world); - - for (Block block : event.blockList()) { - if (!mgr.getApplicableRegions(toVector(block)).allows(DefaultFlag.CREEPER_EXPLOSION)) { - event.blockList().clear(); - if (wcfg.explosionFlagCancellation) event.setCancelled(true); - return; - } - } - } - } else if (ent instanceof EnderDragon) { - if (wcfg.blockEnderDragonBlockDamage) { - event.blockList().clear(); - return; - } - - if (wcfg.useRegions) { - RegionManager mgr = plugin.getGlobalRegionManager().get(world); - - for (Block block : event.blockList()) { - if (!mgr.getApplicableRegions(toVector(block)).allows(DefaultFlag.ENDERDRAGON_BLOCK_DAMAGE)) { - event.blockList().clear(); - if (wcfg.explosionFlagCancellation) event.setCancelled(true); - return; - } - } - } - } else if (ent instanceof TNTPrimed || ent instanceof ExplosiveMinecart) { - if (wcfg.blockTNTExplosions) { - event.setCancelled(true); - return; - } - if (wcfg.blockTNTBlockDamage) { - event.blockList().clear(); - return; - } - - if (wcfg.useRegions) { - RegionManager mgr = plugin.getGlobalRegionManager().get(world); - - for (Block block : event.blockList()) { - if (!mgr.getApplicableRegions(toVector(block)).allows(DefaultFlag.TNT)) { - event.blockList().clear(); - if (wcfg.explosionFlagCancellation) event.setCancelled(true); - return; - } - } - } - } else if (ent instanceof Fireball) { - if (ent instanceof WitherSkull) { - if (wcfg.blockWitherSkullExplosions) { - event.setCancelled(true); - return; - } - if (wcfg.blockWitherSkullBlockDamage) { - event.blockList().clear(); - return; - } - } else { - if (wcfg.blockFireballExplosions) { - event.setCancelled(true); - return; - } - if (wcfg.blockFireballBlockDamage) { - event.blockList().clear(); - return; - } - } - // allow wither skull blocking since there is no dedicated flag atm - if (wcfg.useRegions) { - RegionManager mgr = plugin.getGlobalRegionManager().get(world); - - for (Block block : event.blockList()) { - if (!mgr.getApplicableRegions(toVector(block)).allows(DefaultFlag.GHAST_FIREBALL)) { - event.blockList().clear(); - if (wcfg.explosionFlagCancellation) event.setCancelled(true); - return; - } - } - } - } else if (ent instanceof Wither) { - if (wcfg.blockWitherExplosions) { - event.setCancelled(true); - return; - } - if (wcfg.blockWitherBlockDamage) { - event.blockList().clear(); - return; - } - } else { - // unhandled entity - if (wcfg.blockOtherExplosions) { - event.setCancelled(true); - return; - } - if (wcfg.useRegions) { - RegionManager mgr = plugin.getGlobalRegionManager().get(world); - for (Block block : event.blockList()) { - if (!mgr.getApplicableRegions(toVector(block)).allows(DefaultFlag.OTHER_EXPLOSION)) { - event.blockList().clear(); - if (wcfg.explosionFlagCancellation) event.setCancelled(true); - return; - } - } - } - } - - - if (wcfg.signChestProtection) { - for (Block block : event.blockList()) { - if (wcfg.isChestProtected(block)) { - event.blockList().clear(); - return; - } - } - } - - } - - /* - * Called on explosion prime - */ - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onExplosionPrime(ExplosionPrimeEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld()); - Entity ent = event.getEntity(); - - if (cfg.activityHaltToggle) { - ent.remove(); - event.setCancelled(true); - return; - } - - if (event.getEntityType() == EntityType.WITHER) { - if (wcfg.blockWitherExplosions) { - event.setCancelled(true); - return; - } - } else if (event.getEntityType() == EntityType.WITHER_SKULL) { - if (wcfg.blockWitherSkullExplosions) { - event.setCancelled(true); - return; - } - } else if (event.getEntityType() == EntityType.FIREBALL) { - if (wcfg.blockFireballExplosions) { - event.setCancelled(true); - return; - } - } else if (event.getEntityType() == EntityType.CREEPER) { - if (wcfg.blockCreeperExplosions) { - event.setCancelled(true); - return; - } - } else if (event.getEntityType() == EntityType.PRIMED_TNT - || event.getEntityType() == EntityType.MINECART_TNT) { - if (wcfg.blockTNTExplosions) { - event.setCancelled(true); - return; - } - } - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onCreatureSpawn(CreatureSpawnEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - - if (cfg.activityHaltToggle) { - event.setCancelled(true); - return; - } - - WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld()); - - // allow spawning of creatures from plugins - if (!wcfg.blockPluginSpawning && event.getSpawnReason() == CreatureSpawnEvent.SpawnReason.CUSTOM) { - return; - } - - if (wcfg.allowTamedSpawns - && event.getEntity() instanceof Tameable // nullsafe check - && ((Tameable) event.getEntity()).isTamed()) { - return; - } - - EntityType entityType = event.getEntityType(); - - if (wcfg.blockCreatureSpawn.contains(entityType)) { - event.setCancelled(true); - return; - } - - Location eventLoc = event.getLocation(); - - if (wcfg.useRegions && cfg.useRegionsCreatureSpawnEvent) { - Vector pt = toVector(eventLoc); - RegionManager mgr = plugin.getGlobalRegionManager().get(eventLoc.getWorld()); - // @TODO get victims' stacktraces and find out why it's null anyway - if (mgr == null) return; - ApplicableRegionSet set = mgr.getApplicableRegions(pt); - - if (!set.allows(DefaultFlag.MOB_SPAWNING)) { - event.setCancelled(true); - return; - } - - Set entityTypes = set.getFlag(DefaultFlag.DENY_SPAWN); - if (entityTypes != null && entityTypes.contains(entityType)) { - event.setCancelled(true); - return; - } - } - - if (wcfg.blockGroundSlimes && entityType == EntityType.SLIME - && eventLoc.getY() >= 60 - && event.getSpawnReason() == SpawnReason.NATURAL) { - event.setCancelled(true); - return; - } - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onCreatePortal(EntityCreatePortalEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld()); - - switch (event.getEntityType()) { - case ENDER_DRAGON: - if (wcfg.blockEnderDragonPortalCreation) event.setCancelled(true); - break; - } - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onPigZap(PigZapEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld()); - - if (wcfg.disablePigZap) { - event.setCancelled(true); - } - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onCreeperPower(CreeperPowerEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld()); - - if (wcfg.disableCreeperPower) { - event.setCancelled(true); - } - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onEntityRegainHealth(EntityRegainHealthEvent event) { - - Entity ent = event.getEntity(); - World world = ent.getWorld(); - - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(world); - - if (wcfg.disableHealthRegain) { - event.setCancelled(true); - return; - } - } - - /** - * Called when an entity changes a block somehow - * - * @param event Relevant event details - */ - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onEntityChangeBlock(EntityChangeBlockEvent event) { - Entity ent = event.getEntity(); - Block block = event.getBlock(); - Location location = block.getLocation(); - - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(ent.getWorld()); - if (ent instanceof Enderman) { - if (wcfg.disableEndermanGriefing) { - event.setCancelled(true); - return; - } - - if (wcfg.useRegions) { - if (!plugin.getGlobalRegionManager().allows(DefaultFlag.ENDER_BUILD, location)) { - event.setCancelled(true); - return; - } - } - } else if (ent.getType() == EntityType.WITHER) { - if (wcfg.blockWitherBlockDamage || wcfg.blockWitherExplosions) { - event.setCancelled(true); - return; - } - } else if (/*ent instanceof Zombie && */event instanceof EntityBreakDoorEvent) { - if (wcfg.blockZombieDoorDestruction) { - event.setCancelled(true); - return; - } - } - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onFoodLevelChange(FoodLevelChangeEvent event) { - if (event.getEntity() instanceof Player) { - Player player = (Player) event.getEntity(); - if (event.getFoodLevel() < player.getFoodLevel() && isInvincible(player)) { - event.setCancelled(true); - } - } - } - - @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 - * to override it. (worldguard.god.override-regions) - * - * @param player The player to check - * @return Whether {@code player} is invincible - */ - private boolean isInvincible(Player player) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(player.getWorld()); - - boolean god = cfg.hasGodMode(player); - if (wcfg.useRegions) { - Boolean flag = RegionQueryUtil.isAllowedInvinciblity(plugin, player); - boolean allowed = flag == null || flag; - boolean invincible = RegionQueryUtil.isInvincible(plugin, player); - - if (allowed) { - return god || invincible; - } else { - return (god && plugin.hasPermission(player, "worldguard.god.override-regions")) - || invincible; - } - } else { - return god; - } - } - - /** - * Using a DisallowedPVPEvent, notifies other plugins that WorldGuard - * wants to cancel a PvP damage event.
- * 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. - * @param attacker attacking entity - * @param defender item frame being damaged - * @return true if the event should be cancelled - */ - private boolean checkItemFrameProtection(Entity attacker, ItemFrame defender) { - World world = attacker.getWorld(); - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(world); - 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)) { - if (!plugin.getGlobalRegionManager().allows( - DefaultFlag.ENTITY_ITEM_FRAME_DESTROY, defender.getLocation())) { - return true; - } - } - } - if (wcfg.blockEntityItemFrameDestroy && !(attacker instanceof Player)) { - return true; - } - return false; - } - -} +/* + * WorldGuard, a suite of tools for Minecraft + * Copyright (C) sk89q + * 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 . + */ + +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.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; +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; +import org.bukkit.entity.Fireball; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.entity.Tameable; +import org.bukkit.entity.ThrownPotion; +import org.bukkit.entity.Wither; +import org.bukkit.entity.WitherSkull; +import org.bukkit.entity.Wolf; +import org.bukkit.entity.minecart.ExplosiveMinecart; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +import org.bukkit.event.entity.CreeperPowerEvent; +import org.bukkit.event.entity.EntityBreakDoorEvent; +import org.bukkit.event.entity.EntityChangeBlockEvent; +import org.bukkit.event.entity.EntityCombustEvent; +import org.bukkit.event.entity.EntityCreatePortalEvent; +import org.bukkit.event.entity.EntityDamageByBlockEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.EntityInteractEvent; +import org.bukkit.event.entity.EntityRegainHealthEvent; +import org.bukkit.event.entity.ExpBottleEvent; +import org.bukkit.event.entity.ExplosionPrimeEvent; +import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.event.entity.PigZapEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.entity.PotionSplashEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.projectiles.ProjectileSource; + +import java.util.Set; + +import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector; + +/** + * Listener for entity related events. + * + * @author sk89q + */ +public class WorldGuardEntityListener implements Listener { + + private WorldGuardPlugin plugin; + + /** + * Construct the object; + * + * @param plugin The plugin instance + */ + public WorldGuardEntityListener(WorldGuardPlugin plugin) { + this.plugin = plugin; + } + + /** + * Register events. + */ + public void registerEvents() { + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onEntityInteract(EntityInteractEvent event) { + Entity entity = event.getEntity(); + Block block = event.getBlock(); + + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(entity.getWorld()); + + if (block.getTypeId() == BlockID.SOIL) { + if (/* entity instanceof Creature && // catch for any entity (not thrown for players) */ + wcfg.disableCreatureCropTrampling) { + event.setCancelled(true); + } + } + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onExpBottle(ExpBottleEvent event) { + WorldConfiguration wcfg = plugin.getGlobalStateManager().get(event.getEntity().getWorld()); + + if (wcfg.disableExpDrops || !plugin.getGlobalRegionManager().allows(DefaultFlag.EXP_DROPS, + event.getEntity().getLocation())) { + event.setExperience(0); + // event.setShowEffect(false); // don't want to cancel the bottle entirely I suppose, just the exp + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onEntityDeath(EntityDeathEvent event) { + WorldConfiguration wcfg = plugin.getGlobalStateManager().get(event.getEntity().getWorld()); + + if (wcfg.disableExpDrops || !plugin.getGlobalRegionManager().allows(DefaultFlag.EXP_DROPS, + event.getEntity().getLocation())) { + event.setDroppedExp(0); + } + + if (event instanceof PlayerDeathEvent && wcfg.disableDeathMessages) { + ((PlayerDeathEvent) event).setDeathMessage(""); + } + } + + private void onEntityDamageByBlock(EntityDamageByBlockEvent event) { + Entity defender = event.getEntity(); + DamageCause type = event.getCause(); + + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(defender.getWorld()); + + if (defender instanceof Wolf && ((Wolf) defender).isTamed()) { + if (wcfg.antiWolfDumbness && !(type == DamageCause.VOID)) { + event.setCancelled(true); + return; + } + } else if (defender instanceof Player) { + Player player = (Player) defender; + + if (isInvincible(player)) { + event.setCancelled(true); + return; + } + + if (wcfg.disableLavaDamage && type == DamageCause.LAVA) { + event.setCancelled(true); + player.setFireTicks(0); + return; + } + + if (wcfg.disableContactDamage && type == DamageCause.CONTACT) { + event.setCancelled(true); + return; + } + + if (wcfg.teleportOnVoid && type == DamageCause.VOID) { + BukkitUtil.findFreePosition(player); + event.setCancelled(true); + return; + } + + if (wcfg.disableVoidDamage && type == DamageCause.VOID) { + event.setCancelled(true); + return; + } + + if (type == DamageCause.BLOCK_EXPLOSION + && (wcfg.disableExplosionDamage || wcfg.blockOtherExplosions + || (wcfg.explosionFlagCancellation + && !plugin.getGlobalRegionManager().allows(DefaultFlag.OTHER_EXPLOSION, player.getLocation())))) { + event.setCancelled(true); + return; + } + } else { + + // for whatever reason, plugin-caused explosions with a null entity count as block explosions and aren't + // handled anywhere else + if (type == DamageCause.BLOCK_EXPLOSION + && (wcfg.blockOtherExplosions + || (wcfg.explosionFlagCancellation + && !plugin.getGlobalRegionManager().allows(DefaultFlag.OTHER_EXPLOSION, defender.getLocation())))) { + event.setCancelled(true); + return; + } + } + } + + private void onEntityDamageByEntity(EntityDamageByEntityEvent event) { + + if (event.getDamager() instanceof Projectile) { + onEntityDamageByProjectile(event); + return; + } + + Entity attacker = event.getDamager(); + Entity defender = event.getEntity(); + + if (defender instanceof ItemFrame) { + if (checkItemFrameProtection(attacker, (ItemFrame) defender)) { + event.setCancelled(true); + return; + } + } + + if (defender instanceof Player) { + Player player = (Player) defender; + LocalPlayer localPlayer = plugin.wrapPlayer(player); + + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(player.getWorld()); + + if (isInvincible(player)) { + if (wcfg.regionInvinciblityRemovesMobs + && attacker instanceof LivingEntity && !(attacker instanceof Player) + && !(attacker instanceof Tameable && ((Tameable) attacker).isTamed())) { + attacker.remove(); + } + + event.setCancelled(true); + return; + } + + if (wcfg.disableLightningDamage && event.getCause() == DamageCause.LIGHTNING) { + event.setCancelled(true); + return; + } + + if (wcfg.disableExplosionDamage) { + switch (event.getCause()) { + case BLOCK_EXPLOSION: + case ENTITY_EXPLOSION: + event.setCancelled(true); + return; + } + } + + if (attacker != null) { + if (attacker instanceof Player) { + if (wcfg.useRegions) { + Vector pt = toVector(defender.getLocation()); + Vector pt2 = toVector(attacker.getLocation()); + RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld()); + + if (!mgr.getApplicableRegions(pt2).allows(DefaultFlag.PVP, plugin.wrapPlayer((Player) attacker))) { + tryCancelPVPEvent((Player) attacker, player, event, true); + } else if (!mgr.getApplicableRegions(pt).allows(DefaultFlag.PVP ,localPlayer)) { + 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... + if (wcfg.blockTNTExplosions) { + event.setCancelled(true); + return; + } + if (wcfg.useRegions && wcfg.explosionFlagCancellation) { + Vector pt = toVector(defender.getLocation()); + RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld()); + ApplicableRegionSet set = mgr.getApplicableRegions(pt); + if (!set.allows(DefaultFlag.TNT, localPlayer)) { + event.setCancelled(true); + return; + } + } + } + + if (attacker instanceof Fireball) { + if (attacker instanceof WitherSkull) { + if (wcfg.blockWitherSkullExplosions) { + event.setCancelled(true); + return; + } + } else { + if (wcfg.blockFireballExplosions) { + event.setCancelled(true); + return; + } + } + if (wcfg.useRegions) { + Fireball fireball = (Fireball) attacker; + Vector pt = toVector(defender.getLocation()); + RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld()); + ApplicableRegionSet set = mgr.getApplicableRegions(pt); + if (fireball.getShooter() instanceof Player) { + Vector pt2 = toVector(((Player) fireball.getShooter()).getLocation()); + if (!mgr.getApplicableRegions(pt2).allows(DefaultFlag.PVP, plugin.wrapPlayer((Player) fireball.getShooter()))) { + tryCancelPVPEvent((Player) fireball.getShooter(), player, event, true); + } else if (!set.allows(DefaultFlag.PVP, localPlayer)) { + tryCancelPVPEvent((Player) fireball.getShooter(), player, event, false); + } + } else { + if (!set.allows(DefaultFlag.GHAST_FIREBALL, localPlayer) && wcfg.explosionFlagCancellation) { + event.setCancelled(true); + return; + } + } + + } + } + + if (attacker instanceof LivingEntity && !(attacker instanceof Player)) { + if (attacker instanceof Creeper && wcfg.blockCreeperExplosions) { + event.setCancelled(true); + return; + } + + if (wcfg.disableMobDamage) { + event.setCancelled(true); + return; + } + + if (wcfg.useRegions) { + Vector pt = toVector(defender.getLocation()); + RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld()); + ApplicableRegionSet set = mgr.getApplicableRegions(pt); + + if (!set.allows(DefaultFlag.MOB_DAMAGE, localPlayer) && !(attacker instanceof Tameable)) { + event.setCancelled(true); + return; + } + + if (attacker instanceof Creeper) { + if (!set.allows(DefaultFlag.CREEPER_EXPLOSION, localPlayer) && wcfg.explosionFlagCancellation) { + event.setCancelled(true); + 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(); + Vector pt2 = toVector(attacker.getLocation()); + if (!mgr.getApplicableRegions(pt2).allows(DefaultFlag.PVP, plugin.wrapPlayer(beastMaster))) { + tryCancelPVPEvent(beastMaster, player, event, true); + } else if (!set.allows(DefaultFlag.PVP, localPlayer)) { + tryCancelPVPEvent(beastMaster, player, event, false); + } + } + } + } + } + } + } + + private void onEntityDamageByProjectile(EntityDamageByEntityEvent event) { + Entity defender = event.getEntity(); + Entity attacker; + ProjectileSource source = ((Projectile) event.getDamager()).getShooter(); + if (source instanceof LivingEntity) { + attacker = (LivingEntity) source; + } else { + return; + } + + if (defender instanceof Player) { + Player player = (Player) defender; + LocalPlayer localPlayer = plugin.wrapPlayer(player); + + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(player.getWorld()); + + // Check Invincible + if (isInvincible(player)) { + event.setCancelled(true); + return; + } + + // Check Mob + if (attacker != null && !(attacker instanceof Player)) { + if (wcfg.disableMobDamage) { + event.setCancelled(true); + return; + } + if (wcfg.useRegions) { + Vector pt = toVector(defender.getLocation()); + RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld()); + + if (!mgr.getApplicableRegions(pt).allows(DefaultFlag.MOB_DAMAGE, localPlayer)) { + event.setCancelled(true); + return; + } + } + } + + // 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) { + Vector pt = toVector(defender.getLocation()); + Vector pt2 = toVector(attacker.getLocation()); + RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld()); + + if (!mgr.getApplicableRegions(pt2).allows(DefaultFlag.PVP, plugin.wrapPlayer((Player) attacker))) { + tryCancelPVPEvent((Player) attacker, player, event, true); + } else if (!mgr.getApplicableRegions(pt).allows(DefaultFlag.PVP, localPlayer)) { + tryCancelPVPEvent((Player) attacker, player, event, false); + } + } + } + } else if (defender instanceof ItemFrame) { + if (checkItemFrameProtection(attacker, (ItemFrame) defender)) { + event.setCancelled(true); + return; + } + } + + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onEntityDamage(EntityDamageEvent event) { + + if (event instanceof EntityDamageByEntityEvent) { + this.onEntityDamageByEntity((EntityDamageByEntityEvent) event); + return; + } else if (event instanceof EntityDamageByBlockEvent) { + this.onEntityDamageByBlock((EntityDamageByBlockEvent) event); + return; + } + + Entity defender = event.getEntity(); + DamageCause type = event.getCause(); + + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(defender.getWorld()); + + if (defender instanceof Wolf && ((Wolf) defender).isTamed()) { + if (wcfg.antiWolfDumbness) { + event.setCancelled(true); + return; + } + } else if (defender instanceof Player) { + Player player = (Player) defender; + + if (isInvincible(player)) { + event.setCancelled(true); + player.setFireTicks(0); + return; + } + + if (type == DamageCause.WITHER) { + // wither boss DoT tick + if (wcfg.disableMobDamage) { + event.setCancelled(true); + return; + } + + if (wcfg.useRegions) { + Vector pt = toVector(defender.getLocation()); + RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld()); + ApplicableRegionSet set = mgr.getApplicableRegions(pt); + + if (!set.allows(DefaultFlag.MOB_DAMAGE, plugin.wrapPlayer(player))) { + event.setCancelled(true); + return; + } + } + } + + if (type == DamageCause.DROWNING && cfg.hasAmphibiousMode(player)) { + player.setRemainingAir(player.getMaximumAir()); + event.setCancelled(true); + return; + } + + ItemStack helmet = player.getInventory().getHelmet(); + + if (type == DamageCause.DROWNING && wcfg.pumpkinScuba + && helmet != null + && (helmet.getTypeId() == BlockID.PUMPKIN + || helmet.getTypeId() == BlockID.JACKOLANTERN)) { + player.setRemainingAir(player.getMaximumAir()); + event.setCancelled(true); + return; + } + + if (wcfg.disableFallDamage && type == DamageCause.FALL) { + event.setCancelled(true); + return; + } + + if (wcfg.disableFireDamage && (type == DamageCause.FIRE + || type == DamageCause.FIRE_TICK)) { + event.setCancelled(true); + return; + } + + if (wcfg.disableDrowningDamage && type == DamageCause.DROWNING) { + player.setRemainingAir(player.getMaximumAir()); + event.setCancelled(true); + return; + } + + if (wcfg.teleportOnSuffocation && type == DamageCause.SUFFOCATION) { + BukkitUtil.findFreePosition(player); + event.setCancelled(true); + return; + } + + if (wcfg.disableSuffocationDamage && type == DamageCause.SUFFOCATION) { + event.setCancelled(true); + return; + } + } + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onEntityCombust(EntityCombustEvent event) { + Entity entity = event.getEntity(); + + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(entity.getWorld()); + + if (entity instanceof Player) { + Player player = (Player) entity; + + if (cfg.hasGodMode(player) || (wcfg.useRegions && RegionQueryUtil.isInvincible(plugin, player))) { + event.setCancelled(true); + return; + } + } + } + + /* + * Called on entity explode. + */ + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onEntityExplode(EntityExplodeEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + Location l = event.getLocation(); + World world = l.getWorld(); + WorldConfiguration wcfg = cfg.get(world); + Entity ent = event.getEntity(); + + if (cfg.activityHaltToggle) { + if (ent != null) { + ent.remove(); + } + event.setCancelled(true); + return; + } + + if (ent instanceof Creeper) { + if (wcfg.blockCreeperExplosions) { + event.setCancelled(true); + return; + } + if (wcfg.blockCreeperBlockDamage) { + event.blockList().clear(); + return; + } + + if (wcfg.useRegions) { + RegionManager mgr = plugin.getGlobalRegionManager().get(world); + + for (Block block : event.blockList()) { + if (!mgr.getApplicableRegions(toVector(block)).allows(DefaultFlag.CREEPER_EXPLOSION)) { + event.blockList().clear(); + if (wcfg.explosionFlagCancellation) event.setCancelled(true); + return; + } + } + } + } else if (ent instanceof EnderDragon) { + if (wcfg.blockEnderDragonBlockDamage) { + event.blockList().clear(); + return; + } + + if (wcfg.useRegions) { + RegionManager mgr = plugin.getGlobalRegionManager().get(world); + + for (Block block : event.blockList()) { + if (!mgr.getApplicableRegions(toVector(block)).allows(DefaultFlag.ENDERDRAGON_BLOCK_DAMAGE)) { + event.blockList().clear(); + if (wcfg.explosionFlagCancellation) event.setCancelled(true); + return; + } + } + } + } else if (ent instanceof TNTPrimed || ent instanceof ExplosiveMinecart) { + if (wcfg.blockTNTExplosions) { + event.setCancelled(true); + return; + } + if (wcfg.blockTNTBlockDamage) { + event.blockList().clear(); + return; + } + + if (wcfg.useRegions) { + RegionManager mgr = plugin.getGlobalRegionManager().get(world); + + for (Block block : event.blockList()) { + if (!mgr.getApplicableRegions(toVector(block)).allows(DefaultFlag.TNT)) { + event.blockList().clear(); + if (wcfg.explosionFlagCancellation) event.setCancelled(true); + return; + } + } + } + } else if (ent instanceof Fireball) { + if (ent instanceof WitherSkull) { + if (wcfg.blockWitherSkullExplosions) { + event.setCancelled(true); + return; + } + if (wcfg.blockWitherSkullBlockDamage) { + event.blockList().clear(); + return; + } + } else { + if (wcfg.blockFireballExplosions) { + event.setCancelled(true); + return; + } + if (wcfg.blockFireballBlockDamage) { + event.blockList().clear(); + return; + } + } + // allow wither skull blocking since there is no dedicated flag atm + if (wcfg.useRegions) { + RegionManager mgr = plugin.getGlobalRegionManager().get(world); + + for (Block block : event.blockList()) { + if (!mgr.getApplicableRegions(toVector(block)).allows(DefaultFlag.GHAST_FIREBALL)) { + event.blockList().clear(); + if (wcfg.explosionFlagCancellation) event.setCancelled(true); + return; + } + } + } + } else if (ent instanceof Wither) { + if (wcfg.blockWitherExplosions) { + event.setCancelled(true); + return; + } + if (wcfg.blockWitherBlockDamage) { + event.blockList().clear(); + return; + } + } else { + // unhandled entity + if (wcfg.blockOtherExplosions) { + event.setCancelled(true); + return; + } + if (wcfg.useRegions) { + RegionManager mgr = plugin.getGlobalRegionManager().get(world); + for (Block block : event.blockList()) { + if (!mgr.getApplicableRegions(toVector(block)).allows(DefaultFlag.OTHER_EXPLOSION)) { + event.blockList().clear(); + if (wcfg.explosionFlagCancellation) event.setCancelled(true); + return; + } + } + } + } + + + if (wcfg.signChestProtection) { + for (Block block : event.blockList()) { + if (wcfg.isChestProtected(block)) { + event.blockList().clear(); + return; + } + } + } + + } + + /* + * Called on explosion prime + */ + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onExplosionPrime(ExplosionPrimeEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld()); + Entity ent = event.getEntity(); + + if (cfg.activityHaltToggle) { + ent.remove(); + event.setCancelled(true); + return; + } + + if (event.getEntityType() == EntityType.WITHER) { + if (wcfg.blockWitherExplosions) { + event.setCancelled(true); + return; + } + } else if (event.getEntityType() == EntityType.WITHER_SKULL) { + if (wcfg.blockWitherSkullExplosions) { + event.setCancelled(true); + return; + } + } else if (event.getEntityType() == EntityType.FIREBALL) { + if (wcfg.blockFireballExplosions) { + event.setCancelled(true); + return; + } + } else if (event.getEntityType() == EntityType.CREEPER) { + if (wcfg.blockCreeperExplosions) { + event.setCancelled(true); + return; + } + } else if (event.getEntityType() == EntityType.PRIMED_TNT + || event.getEntityType() == EntityType.MINECART_TNT) { + if (wcfg.blockTNTExplosions) { + event.setCancelled(true); + return; + } + } + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onCreatureSpawn(CreatureSpawnEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + + if (cfg.activityHaltToggle) { + event.setCancelled(true); + return; + } + + WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld()); + + // allow spawning of creatures from plugins + if (!wcfg.blockPluginSpawning && event.getSpawnReason() == CreatureSpawnEvent.SpawnReason.CUSTOM) { + return; + } + + if (wcfg.allowTamedSpawns + && event.getEntity() instanceof Tameable // nullsafe check + && ((Tameable) event.getEntity()).isTamed()) { + return; + } + + EntityType entityType = event.getEntityType(); + + if (wcfg.blockCreatureSpawn.contains(entityType)) { + event.setCancelled(true); + return; + } + + Location eventLoc = event.getLocation(); + + if (wcfg.useRegions && cfg.useRegionsCreatureSpawnEvent) { + Vector pt = toVector(eventLoc); + RegionManager mgr = plugin.getGlobalRegionManager().get(eventLoc.getWorld()); + // @TODO get victims' stacktraces and find out why it's null anyway + if (mgr == null) return; + ApplicableRegionSet set = mgr.getApplicableRegions(pt); + + if (!set.allows(DefaultFlag.MOB_SPAWNING)) { + event.setCancelled(true); + return; + } + + Set entityTypes = set.getFlag(DefaultFlag.DENY_SPAWN); + if (entityTypes != null && entityTypes.contains(entityType)) { + event.setCancelled(true); + return; + } + } + + if (wcfg.blockGroundSlimes && entityType == EntityType.SLIME + && eventLoc.getY() >= 60 + && event.getSpawnReason() == SpawnReason.NATURAL) { + event.setCancelled(true); + return; + } + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onCreatePortal(EntityCreatePortalEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld()); + + switch (event.getEntityType()) { + case ENDER_DRAGON: + if (wcfg.blockEnderDragonPortalCreation) event.setCancelled(true); + break; + } + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onPigZap(PigZapEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld()); + + if (wcfg.disablePigZap) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onCreeperPower(CreeperPowerEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld()); + + if (wcfg.disableCreeperPower) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onEntityRegainHealth(EntityRegainHealthEvent event) { + + Entity ent = event.getEntity(); + World world = ent.getWorld(); + + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(world); + + if (wcfg.disableHealthRegain) { + event.setCancelled(true); + return; + } + } + + /** + * Called when an entity changes a block somehow + * + * @param event Relevant event details + */ + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onEntityChangeBlock(EntityChangeBlockEvent event) { + Entity ent = event.getEntity(); + Block block = event.getBlock(); + Location location = block.getLocation(); + + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(ent.getWorld()); + if (ent instanceof Enderman) { + if (wcfg.disableEndermanGriefing) { + event.setCancelled(true); + return; + } + + if (wcfg.useRegions) { + if (!plugin.getGlobalRegionManager().allows(DefaultFlag.ENDER_BUILD, location)) { + event.setCancelled(true); + return; + } + } + } else if (ent.getType() == EntityType.WITHER) { + if (wcfg.blockWitherBlockDamage || wcfg.blockWitherExplosions) { + event.setCancelled(true); + return; + } + } else if (/*ent instanceof Zombie && */event instanceof EntityBreakDoorEvent) { + if (wcfg.blockZombieDoorDestruction) { + event.setCancelled(true); + return; + } + } + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onFoodLevelChange(FoodLevelChangeEvent event) { + if (event.getEntity() instanceof Player) { + Player player = (Player) event.getEntity(); + if (event.getFoodLevel() < player.getFoodLevel() && isInvincible(player)) { + event.setCancelled(true); + } + } + } + + @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 + * to override it. (worldguard.god.override-regions) + * + * @param player The player to check + * @return Whether {@code player} is invincible + */ + private boolean isInvincible(Player player) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(player.getWorld()); + + boolean god = cfg.hasGodMode(player); + if (wcfg.useRegions) { + Boolean flag = RegionQueryUtil.isAllowedInvinciblity(plugin, player); + boolean allowed = flag == null || flag; + boolean invincible = RegionQueryUtil.isInvincible(plugin, player); + + if (allowed) { + return god || invincible; + } else { + return (god && plugin.hasPermission(player, "worldguard.god.override-regions")) + || invincible; + } + } else { + return god; + } + } + + /** + * Using a DisallowedPVPEvent, notifies other plugins that WorldGuard + * wants to cancel a PvP damage event.
+ * 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. + * @param attacker attacking entity + * @param defender item frame being damaged + * @return true if the event should be cancelled + */ + private boolean checkItemFrameProtection(Entity attacker, ItemFrame defender) { + World world = attacker.getWorld(); + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(world); + 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)) { + if (!plugin.getGlobalRegionManager().allows( + DefaultFlag.ENTITY_ITEM_FRAME_DESTROY, defender.getLocation())) { + return true; + } + } + } + if (wcfg.blockEntityItemFrameDestroy && !(attacker instanceof Player)) { + return true; + } + return false; + } + +} diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardHangingListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardHangingListener.java similarity index 95% rename from src/main/java/com/sk89q/worldguard/bukkit/WorldGuardHangingListener.java rename to src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardHangingListener.java index 53a7f141..8a767f09 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardHangingListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardHangingListener.java @@ -1,119 +1,122 @@ -/* - * WorldGuard, a suite of tools for Minecraft - * Copyright (C) sk89q - * 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 . - */ - -package com.sk89q.worldguard.bukkit; - -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 - */ -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); - } - } - } - -} +/* + * WorldGuard, a suite of tools for Minecraft + * Copyright (C) sk89q + * 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 . + */ + +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 + */ +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); + } + } + } + +} diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardPlayerListener.java similarity index 97% rename from src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java rename to src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardPlayerListener.java index df660abc..6b4ce0eb 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardPlayerListener.java @@ -1,729 +1,733 @@ -/* - * WorldGuard, a suite of tools for Minecraft - * Copyright (C) sk89q - * 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 . - */ - -package com.sk89q.worldguard.bukkit; - -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.FlagStateManager.PlayerFlagState; -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 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 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 allowedCommands = set.getFlag(DefaultFlag.ALLOWED_CMDS, localPlayer); - Set 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; - } - } - } -} +/* + * WorldGuard, a suite of tools for Minecraft + * Copyright (C) sk89q + * 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 . + */ + +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 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 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 allowedCommands = set.getFlag(DefaultFlag.ALLOWED_CMDS, localPlayer); + Set 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; + } + } + } +} diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardServerListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardServerListener.java similarity index 95% rename from src/main/java/com/sk89q/worldguard/bukkit/WorldGuardServerListener.java rename to src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardServerListener.java index 6ab068bb..2d3b049b 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardServerListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardServerListener.java @@ -17,8 +17,9 @@ * along with this program. If not, see . */ -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; diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardVehicleListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardVehicleListener.java similarity index 92% rename from src/main/java/com/sk89q/worldguard/bukkit/WorldGuardVehicleListener.java rename to src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardVehicleListener.java index 6cc4c7ad..8d5b1b6a 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardVehicleListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardVehicleListener.java @@ -1,72 +1,75 @@ -/* - * WorldGuard, a suite of tools for Minecraft - * Copyright (C) sk89q - * 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 . - */ - -package com.sk89q.worldguard.bukkit; - -import org.bukkit.World; -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.VehicleMoveEvent; - -public class WorldGuardVehicleListener implements Listener { - - private WorldGuardPlugin plugin; - - /** - * Construct the object; - * - * @param plugin - */ - public WorldGuardVehicleListener(WorldGuardPlugin plugin) { - this.plugin = plugin; - } - - /** - * Register events. - */ - public void registerEvents() { - plugin.getServer().getPluginManager().registerEvents(this, plugin); - } - - @EventHandler - public void onVehicleMove(VehicleMoveEvent event) { - Vehicle vehicle = event.getVehicle(); - if (vehicle.getPassenger() == null - || !(vehicle.getPassenger() instanceof Player)) return; - Player player = (Player) vehicle.getPassenger(); - World world = vehicle.getWorld(); - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(world); - - 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 = WorldGuardPlayerListener.checkMove(plugin, player, event.getFrom(), event.getTo()); - if (result) { - vehicle.setVelocity(new org.bukkit.util.Vector(0,0,0)); - vehicle.teleport(event.getFrom()); - } - } - } - } -} +/* + * WorldGuard, a suite of tools for Minecraft + * Copyright (C) sk89q + * 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 . + */ + +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 org.bukkit.World; +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.VehicleMoveEvent; + +public class WorldGuardVehicleListener implements Listener { + + private WorldGuardPlugin plugin; + + /** + * Construct the object; + * + * @param plugin + */ + public WorldGuardVehicleListener(WorldGuardPlugin plugin) { + this.plugin = plugin; + } + + /** + * Register events. + */ + public void registerEvents() { + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @EventHandler + public void onVehicleMove(VehicleMoveEvent event) { + Vehicle vehicle = event.getVehicle(); + if (vehicle.getPassenger() == null + || !(vehicle.getPassenger() instanceof Player)) return; + Player player = (Player) vehicle.getPassenger(); + World world = vehicle.getWorld(); + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(world); + + 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 = WorldGuardPlayerListener.checkMove(plugin, player, event.getFrom(), event.getTo()); + if (result) { + vehicle.setVelocity(new org.bukkit.util.Vector(0,0,0)); + vehicle.teleport(event.getFrom()); + } + } + } + } +} diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardWeatherListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardWeatherListener.java similarity index 94% rename from src/main/java/com/sk89q/worldguard/bukkit/WorldGuardWeatherListener.java rename to src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardWeatherListener.java index a3019a96..7fc1578e 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardWeatherListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardWeatherListener.java @@ -1,111 +1,114 @@ -/* - * WorldGuard, a suite of tools for Minecraft - * Copyright (C) sk89q - * 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 . - */ - -package com.sk89q.worldguard.bukkit; - -import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector; - -import org.bukkit.Location; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.weather.LightningStrikeEvent; -import org.bukkit.event.weather.ThunderChangeEvent; -import org.bukkit.event.weather.WeatherChangeEvent; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldguard.protection.ApplicableRegionSet; -import com.sk89q.worldguard.protection.flags.DefaultFlag; -import com.sk89q.worldguard.protection.managers.RegionManager; - -public class WorldGuardWeatherListener implements Listener { - - /** - * Plugin. - */ - private WorldGuardPlugin plugin; - - /** - * Construct the object; - * - * @param plugin The plugin instance - */ - public WorldGuardWeatherListener(WorldGuardPlugin plugin) { - this.plugin = plugin; - } - - public void registerEvents() { - plugin.getServer().getPluginManager().registerEvents(this, plugin); - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onWeatherChange(WeatherChangeEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(event.getWorld()); - - if (event.toWeatherState()) { - if (wcfg.disableWeather) { - event.setCancelled(true); - } - } else { - if (!wcfg.disableWeather && wcfg.alwaysRaining) { - event.setCancelled(true); - } - } - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onThunderChange(ThunderChangeEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(event.getWorld()); - - if (event.toThunderState()) { - if (wcfg.disableThunder) { - event.setCancelled(true); - } - } else { - if (!wcfg.disableWeather && wcfg.alwaysThundering) { - event.setCancelled(true); - } - } - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onLightningStrike(LightningStrikeEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(event.getWorld()); - - if (wcfg.disallowedLightningBlocks.size() > 0) { - int targetId = event.getLightning().getLocation().getBlock().getTypeId(); - if (wcfg.disallowedLightningBlocks.contains(targetId)) { - event.setCancelled(true); - } - } - - Location loc = event.getLightning().getLocation(); - if (wcfg.useRegions) { - Vector pt = toVector(loc); - RegionManager mgr = plugin.getGlobalRegionManager().get(loc.getWorld()); - ApplicableRegionSet set = mgr.getApplicableRegions(pt); - - if (!set.allows(DefaultFlag.LIGHTNING)) { - event.setCancelled(true); - } - } - } -} +/* + * WorldGuard, a suite of tools for Minecraft + * Copyright (C) sk89q + * 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 . + */ + +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; +import org.bukkit.event.Listener; +import org.bukkit.event.weather.LightningStrikeEvent; +import org.bukkit.event.weather.ThunderChangeEvent; +import org.bukkit.event.weather.WeatherChangeEvent; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldguard.protection.ApplicableRegionSet; +import com.sk89q.worldguard.protection.flags.DefaultFlag; +import com.sk89q.worldguard.protection.managers.RegionManager; + +public class WorldGuardWeatherListener implements Listener { + + /** + * Plugin. + */ + private WorldGuardPlugin plugin; + + /** + * Construct the object; + * + * @param plugin The plugin instance + */ + public WorldGuardWeatherListener(WorldGuardPlugin plugin) { + this.plugin = plugin; + } + + public void registerEvents() { + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onWeatherChange(WeatherChangeEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(event.getWorld()); + + if (event.toWeatherState()) { + if (wcfg.disableWeather) { + event.setCancelled(true); + } + } else { + if (!wcfg.disableWeather && wcfg.alwaysRaining) { + event.setCancelled(true); + } + } + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onThunderChange(ThunderChangeEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(event.getWorld()); + + if (event.toThunderState()) { + if (wcfg.disableThunder) { + event.setCancelled(true); + } + } else { + if (!wcfg.disableWeather && wcfg.alwaysThundering) { + event.setCancelled(true); + } + } + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onLightningStrike(LightningStrikeEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(event.getWorld()); + + if (wcfg.disallowedLightningBlocks.size() > 0) { + int targetId = event.getLightning().getLocation().getBlock().getTypeId(); + if (wcfg.disallowedLightningBlocks.contains(targetId)) { + event.setCancelled(true); + } + } + + Location loc = event.getLightning().getLocation(); + if (wcfg.useRegions) { + Vector pt = toVector(loc); + RegionManager mgr = plugin.getGlobalRegionManager().get(loc.getWorld()); + ApplicableRegionSet set = mgr.getApplicableRegions(pt); + + if (!set.allows(DefaultFlag.LIGHTNING)) { + event.setCancelled(true); + } + } + } +} diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardWorldListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardWorldListener.java similarity index 92% rename from src/main/java/com/sk89q/worldguard/bukkit/WorldGuardWorldListener.java rename to src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardWorldListener.java index 9b94ede4..89a498c7 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardWorldListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardWorldListener.java @@ -1,97 +1,101 @@ -/* - * WorldGuard, a suite of tools for Minecraft - * Copyright (C) sk89q - * 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 . - */ - -package com.sk89q.worldguard.bukkit; - -import org.bukkit.World; -import org.bukkit.entity.Entity; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.world.ChunkLoadEvent; -import org.bukkit.event.world.WorldLoadEvent; - -public class WorldGuardWorldListener implements Listener { - - private WorldGuardPlugin plugin; - - /** - * Construct the object; - * - * @param plugin The plugin instance - */ - public WorldGuardWorldListener(WorldGuardPlugin plugin) { - this.plugin = plugin; - } - - /** - * Register events. - */ - public void registerEvents() { - plugin.getServer().getPluginManager().registerEvents(this, plugin); - } - - @EventHandler - public void onChunkLoad(ChunkLoadEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - - if (cfg.activityHaltToggle) { - int removed = 0; - - for (Entity entity : event.getChunk().getEntities()) { - if (BukkitUtil.isIntensiveEntity(entity)) { - entity.remove(); - removed++; - } - } - - if (removed > 50) { - plugin.getLogger().info("Halt-Act: " + removed + " entities (>50) auto-removed from " - + event.getChunk().toString()); - } - } - } - - @EventHandler - public void onWorldLoad(WorldLoadEvent event) { - initWorld(event.getWorld()); - } - - /** - * Initialize the settings for the specified world - * @see WorldConfiguration#alwaysRaining - * @see WorldConfiguration#disableWeather - * @see WorldConfiguration#alwaysThundering - * @see WorldConfiguration#disableThunder - * @param world The specified world - */ - public void initWorld(World world) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(world); - if (wcfg.alwaysRaining && !wcfg.disableWeather) { - world.setStorm(true); - } else if (wcfg.disableWeather && !wcfg.alwaysRaining) { - world.setStorm(false); - } - if (wcfg.alwaysThundering && !wcfg.disableThunder) { - world.setThundering(true); - } else if (wcfg.disableThunder && !wcfg.alwaysThundering) { - world.setStorm(false); - } - } -} +/* + * WorldGuard, a suite of tools for Minecraft + * Copyright (C) sk89q + * 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 . + */ + +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; +import org.bukkit.event.Listener; +import org.bukkit.event.world.ChunkLoadEvent; +import org.bukkit.event.world.WorldLoadEvent; + +public class WorldGuardWorldListener implements Listener { + + private WorldGuardPlugin plugin; + + /** + * Construct the object; + * + * @param plugin The plugin instance + */ + public WorldGuardWorldListener(WorldGuardPlugin plugin) { + this.plugin = plugin; + } + + /** + * Register events. + */ + public void registerEvents() { + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @EventHandler + public void onChunkLoad(ChunkLoadEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + + if (cfg.activityHaltToggle) { + int removed = 0; + + for (Entity entity : event.getChunk().getEntities()) { + if (BukkitUtil.isIntensiveEntity(entity)) { + entity.remove(); + removed++; + } + } + + if (removed > 50) { + plugin.getLogger().info("Halt-Act: " + removed + " entities (>50) auto-removed from " + + event.getChunk().toString()); + } + } + } + + @EventHandler + public void onWorldLoad(WorldLoadEvent event) { + initWorld(event.getWorld()); + } + + /** + * Initialize the settings for the specified world + * @see WorldConfiguration#alwaysRaining + * @see WorldConfiguration#disableWeather + * @see WorldConfiguration#alwaysThundering + * @see WorldConfiguration#disableThunder + * @param world The specified world + */ + public void initWorld(World world) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(world); + if (wcfg.alwaysRaining && !wcfg.disableWeather) { + world.setStorm(true); + } else if (wcfg.disableWeather && !wcfg.alwaysRaining) { + world.setStorm(false); + } + if (wcfg.alwaysThundering && !wcfg.disableThunder) { + world.setThundering(true); + } else if (wcfg.disableThunder && !wcfg.alwaysThundering) { + world.setStorm(false); + } + } +} diff --git a/src/main/java/com/sk89q/worldguard/internal/Events.java b/src/main/java/com/sk89q/worldguard/bukkit/util/Events.java similarity index 98% rename from src/main/java/com/sk89q/worldguard/internal/Events.java rename to src/main/java/com/sk89q/worldguard/bukkit/util/Events.java index 4394acef..baea5c6e 100644 --- a/src/main/java/com/sk89q/worldguard/internal/Events.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/util/Events.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal; +package com.sk89q.worldguard.bukkit.util; import org.bukkit.Bukkit; import org.bukkit.event.Cancellable; diff --git a/src/main/java/com/sk89q/worldguard/internal/Blocks.java b/src/main/java/com/sk89q/worldguard/internal/Blocks.java deleted file mode 100644 index 7d82b045..00000000 --- a/src/main/java/com/sk89q/worldguard/internal/Blocks.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * WorldGuard, a suite of tools for Minecraft - * Copyright (C) sk89q - * 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 . - */ - -package com.sk89q.worldguard.internal; - -import org.bukkit.block.Block; -import org.bukkit.block.Hopper; -import org.bukkit.material.Attachable; -import org.bukkit.material.MaterialData; - -import javax.annotation.Nullable; - -/** - * Block related utility methods. - */ -public final class Blocks { - - private Blocks() { - } - - /** - * Get the block that this block attaches to. - * - * @param block the block to check - * @return the block attached to or null - */ - @Nullable - public static Block getAttachesTo(Block block) { - MaterialData data = block.getState().getData(); - - if (data instanceof Attachable) { - Attachable attachable = (Attachable) data; - return block.getRelative(attachable.getAttachedFace()); - } - - return null; - } - -} diff --git a/src/main/java/com/sk89q/worldguard/internal/cause/BlockCause.java b/src/main/java/com/sk89q/worldguard/util/cause/BlockCause.java similarity index 96% rename from src/main/java/com/sk89q/worldguard/internal/cause/BlockCause.java rename to src/main/java/com/sk89q/worldguard/util/cause/BlockCause.java index d19d2fd0..76fea257 100644 --- a/src/main/java/com/sk89q/worldguard/internal/cause/BlockCause.java +++ b/src/main/java/com/sk89q/worldguard/util/cause/BlockCause.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.cause; +package com.sk89q.worldguard.util.cause; import org.bukkit.block.Block; diff --git a/src/main/java/com/sk89q/worldguard/internal/cause/Cause.java b/src/main/java/com/sk89q/worldguard/util/cause/Cause.java similarity index 96% rename from src/main/java/com/sk89q/worldguard/internal/cause/Cause.java rename to src/main/java/com/sk89q/worldguard/util/cause/Cause.java index 828f9db1..65a0a4b4 100644 --- a/src/main/java/com/sk89q/worldguard/internal/cause/Cause.java +++ b/src/main/java/com/sk89q/worldguard/util/cause/Cause.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.cause; +package com.sk89q.worldguard.util.cause; /** * Represents a possible cause of an event. diff --git a/src/main/java/com/sk89q/worldguard/internal/cause/Causes.java b/src/main/java/com/sk89q/worldguard/util/cause/Causes.java similarity index 98% rename from src/main/java/com/sk89q/worldguard/internal/cause/Causes.java rename to src/main/java/com/sk89q/worldguard/util/cause/Causes.java index e549319b..6cd9532f 100644 --- a/src/main/java/com/sk89q/worldguard/internal/cause/Causes.java +++ b/src/main/java/com/sk89q/worldguard/util/cause/Causes.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.cause; +package com.sk89q.worldguard.util.cause; import org.bukkit.block.Block; import org.bukkit.entity.Entity; diff --git a/src/main/java/com/sk89q/worldguard/internal/cause/EntityCause.java b/src/main/java/com/sk89q/worldguard/util/cause/EntityCause.java similarity index 96% rename from src/main/java/com/sk89q/worldguard/internal/cause/EntityCause.java rename to src/main/java/com/sk89q/worldguard/util/cause/EntityCause.java index f24774b7..893da290 100644 --- a/src/main/java/com/sk89q/worldguard/internal/cause/EntityCause.java +++ b/src/main/java/com/sk89q/worldguard/util/cause/EntityCause.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.cause; +package com.sk89q.worldguard.util.cause; import org.bukkit.entity.Entity; diff --git a/src/main/java/com/sk89q/worldguard/internal/cause/PlayerCause.java b/src/main/java/com/sk89q/worldguard/util/cause/PlayerCause.java similarity index 96% rename from src/main/java/com/sk89q/worldguard/internal/cause/PlayerCause.java rename to src/main/java/com/sk89q/worldguard/util/cause/PlayerCause.java index 2b4e63f5..f016b270 100644 --- a/src/main/java/com/sk89q/worldguard/internal/cause/PlayerCause.java +++ b/src/main/java/com/sk89q/worldguard/util/cause/PlayerCause.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.cause; +package com.sk89q.worldguard.util.cause; import org.bukkit.entity.Player; diff --git a/src/main/java/com/sk89q/worldguard/internal/cause/UnknownCause.java b/src/main/java/com/sk89q/worldguard/util/cause/UnknownCause.java similarity index 96% rename from src/main/java/com/sk89q/worldguard/internal/cause/UnknownCause.java rename to src/main/java/com/sk89q/worldguard/util/cause/UnknownCause.java index d811ac20..9216c409 100644 --- a/src/main/java/com/sk89q/worldguard/internal/cause/UnknownCause.java +++ b/src/main/java/com/sk89q/worldguard/util/cause/UnknownCause.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.internal.cause; +package com.sk89q.worldguard.util.cause; import static com.google.common.base.Preconditions.checkNotNull;