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;