pp = BukkitUtil.getPlayer((Player) shooter);
+ Plot plot = location.getOwnedPlot();
+ if (plot != null && !plot.isAdded(pp.getUUID())) {
+ entity.remove();
+ event.setCancelled(true);
+ }
+ }
+
+ @SuppressWarnings({"BooleanMethodIsAlwaysInverted", "cos it's not... dum IntelliJ"}) @EventHandler
+ public boolean onProjectileHit(ProjectileHitEvent event) {
+ Projectile entity = event.getEntity();
+ Location location = BukkitUtil.getLocation(entity);
+ if (!PlotSquared.get().hasPlotArea(location.getWorld())) {
+ return true;
+ }
+ PlotArea area = location.getPlotArea();
+ if (area == null) {
+ return true;
+ }
+ Plot plot = area.getPlot(location);
+ ProjectileSource shooter = entity.getShooter();
+ if (shooter instanceof Player) {
+ PlotPlayer> pp = BukkitUtil.getPlayer((Player) shooter);
+ if (plot == null) {
+ if (!Permissions.hasPermission(pp, Captions.PERMISSION_PROJECTILE_UNOWNED)) {
+ entity.remove();
+ return false;
+ }
+ return true;
+ }
+ if (plot.isAdded(pp.getUUID()) || Permissions
+ .hasPermission(pp, Captions.PERMISSION_PROJECTILE_OTHER)) {
+ return true;
+ }
+ entity.remove();
+ return false;
+ }
+ if (!(shooter instanceof Entity) && shooter != null) {
+ if (plot == null) {
+ entity.remove();
+ return false;
+ }
+ Location sLoc =
+ BukkitUtil.getLocation(((BlockProjectileSource) shooter).getBlock().getLocation());
+ if (!area.contains(sLoc.getX(), sLoc.getZ())) {
+ entity.remove();
+ return false;
+ }
+ Plot sPlot = area.getOwnedPlotAbs(sLoc);
+ if (sPlot == null || !PlotHandler.sameOwners(plot, sPlot)) {
+ entity.remove();
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitEntityUtil.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitEntityUtil.java
new file mode 100644
index 000000000..d5ef32ba3
--- /dev/null
+++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitEntityUtil.java
@@ -0,0 +1,363 @@
+/*
+ * _____ _ _ _____ _
+ * | __ \| | | | / ____| | |
+ * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
+ * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
+ * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
+ * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
+ * | |
+ * |_|
+ * PlotSquared plot management system for Minecraft
+ * Copyright (C) 2020 IntellectualSites
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.plotsquared.bukkit.util;
+
+import com.plotsquared.bukkit.player.BukkitPlayer;
+import com.plotsquared.core.configuration.Captions;
+import com.plotsquared.core.configuration.Settings;
+import com.plotsquared.core.location.Location;
+import com.plotsquared.core.plot.Plot;
+import com.plotsquared.core.plot.PlotArea;
+import com.plotsquared.core.plot.flag.implementations.AnimalAttackFlag;
+import com.plotsquared.core.plot.flag.implementations.AnimalCapFlag;
+import com.plotsquared.core.plot.flag.implementations.DoneFlag;
+import com.plotsquared.core.plot.flag.implementations.EntityCapFlag;
+import com.plotsquared.core.plot.flag.implementations.HangingBreakFlag;
+import com.plotsquared.core.plot.flag.implementations.HostileAttackFlag;
+import com.plotsquared.core.plot.flag.implementations.HostileCapFlag;
+import com.plotsquared.core.plot.flag.implementations.MiscBreakFlag;
+import com.plotsquared.core.plot.flag.implementations.MiscCapFlag;
+import com.plotsquared.core.plot.flag.implementations.MobCapFlag;
+import com.plotsquared.core.plot.flag.implementations.PveFlag;
+import com.plotsquared.core.plot.flag.implementations.PvpFlag;
+import com.plotsquared.core.plot.flag.implementations.TamedAttackFlag;
+import com.plotsquared.core.plot.flag.implementations.VehicleCapFlag;
+import com.plotsquared.core.util.EntityUtil;
+import com.plotsquared.core.util.MainUtil;
+import com.plotsquared.core.util.Permissions;
+import com.plotsquared.core.util.entity.EntityCategories;
+import com.sk89q.worldedit.bukkit.BukkitAdapter;
+import org.bukkit.entity.Arrow;
+import org.bukkit.entity.Creature;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.Player;
+import org.bukkit.entity.Projectile;
+import org.bukkit.event.entity.EntityDamageEvent;
+import org.bukkit.projectiles.BlockProjectileSource;
+import org.bukkit.projectiles.ProjectileSource;
+
+import java.util.Objects;
+
+public class BukkitEntityUtil {
+
+ public static final com.sk89q.worldedit.world.entity.EntityType FAKE_ENTITY_TYPE =
+ new com.sk89q.worldedit.world.entity.EntityType("plotsquared:fake");
+
+ public static boolean entityDamage(Entity damager, Entity victim) {
+ return entityDamage(damager, victim, null);
+ }
+
+ public static boolean entityDamage(Entity damager, Entity victim,
+ EntityDamageEvent.DamageCause cause) {
+ Location dloc = BukkitUtil.getLocation(damager);
+ Location vloc = BukkitUtil.getLocation(victim);
+ PlotArea dArea = dloc.getPlotArea();
+ PlotArea vArea;
+ if (dArea != null && dArea.contains(vloc.getX(), vloc.getZ())) {
+ vArea = dArea;
+ } else {
+ vArea = vloc.getPlotArea();
+ }
+ if (dArea == null && vArea == null) {
+ return true;
+ }
+
+ Plot dplot;
+ if (dArea != null) {
+ dplot = dArea.getPlot(dloc);
+ } else {
+ dplot = null;
+ }
+ Plot vplot;
+ if (vArea != null) {
+ vplot = vArea.getPlot(vloc);
+ } else {
+ vplot = null;
+ }
+
+ Plot plot;
+ String stub;
+ boolean isPlot = true;
+ if (dplot == null && vplot == null) {
+ if (dArea == null) {
+ return true;
+ }
+ plot = null;
+ stub = "road";
+ isPlot = false;
+ } else {
+ // Prioritize plots for close to seamless pvp zones
+ if (victim.getTicksLived() > damager.getTicksLived()) {
+ if (dplot == null || !(victim instanceof Player)) {
+ if (vplot == null) {
+ plot = dplot;
+ } else {
+ plot = vplot;
+ }
+ } else {
+ plot = dplot;
+ }
+ } else if (dplot == null || !(victim instanceof Player)) {
+ if (vplot == null) {
+ plot = dplot;
+ } else {
+ plot = vplot;
+ }
+ } else if (vplot == null) {
+ plot = dplot;
+ } else {
+ plot = vplot;
+ }
+ if (plot.hasOwner()) {
+ stub = "other";
+ } else {
+ stub = "unowned";
+ }
+ }
+ boolean roadFlags = vArea != null ? vArea.isRoadFlags() : dArea.isRoadFlags();
+ PlotArea area = vArea != null ? vArea : dArea;
+
+ Player player;
+ if (damager instanceof Player) { // attacker is player
+ player = (Player) damager;
+ } else if (damager instanceof Projectile) {
+ Projectile projectile = (Projectile) damager;
+ ProjectileSource shooter = projectile.getShooter();
+ if (shooter instanceof Player) { // shooter is player
+ player = (Player) shooter;
+ } else { // shooter is not player
+ if (shooter instanceof BlockProjectileSource) {
+ Location sLoc = BukkitUtil
+ .getLocation(((BlockProjectileSource) shooter).getBlock().getLocation());
+ dplot = dArea.getPlot(sLoc);
+ }
+ player = null;
+ }
+ } else { // Attacker is not player
+ player = null;
+ }
+ if (player != null) {
+ BukkitPlayer plotPlayer = BukkitUtil.getPlayer(player);
+
+ final com.sk89q.worldedit.world.entity.EntityType entityType;
+
+ // Create a fake entity type if the type does not have a name
+ if (victim.getType().getName() == null) {
+ entityType = FAKE_ENTITY_TYPE;
+ } else {
+ entityType = BukkitAdapter.adapt(victim.getType());
+ }
+
+ if (EntityCategories.HANGING.contains(entityType)) { // hanging
+ if (plot != null && (plot.getFlag(HangingBreakFlag.class) || plot
+ .isAdded(plotPlayer.getUUID()))) {
+ if (Settings.Done.RESTRICT_BUILDING && DoneFlag.isDone(plot)) {
+ if (!Permissions
+ .hasPermission(plotPlayer, Captions.PERMISSION_ADMIN_BUILD_OTHER)) {
+ MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT,
+ Captions.PERMISSION_ADMIN_BUILD_OTHER);
+ return false;
+ }
+ }
+ return true;
+ }
+ if (!Permissions.hasPermission(plotPlayer, "plots.admin.destroy." + stub)) {
+ MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT,
+ "plots.admin.destroy." + stub);
+ return false;
+ }
+ } else if (victim.getType() == EntityType.ARMOR_STAND) {
+ if (plot != null && (plot.getFlag(MiscBreakFlag.class) || plot
+ .isAdded(plotPlayer.getUUID()))) {
+ return true;
+ }
+ if (!Permissions.hasPermission(plotPlayer, "plots.admin.destroy." + stub)) {
+ MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT,
+ "plots.admin.destroy." + stub);
+ if (plot != null) {
+ plot.debug(player.getName()
+ + " could not break armor stand because misc-break = false");
+ }
+ return false;
+ }
+ } else if (EntityCategories.HOSTILE.contains(entityType)) {
+ if (isPlot) {
+ if (plot.getFlag(HostileAttackFlag.class) || plot.getFlag(PveFlag.class) || plot
+ .isAdded(plotPlayer.getUUID())) {
+ return true;
+ }
+ } else if (roadFlags && (area.getRoadFlag(HostileAttackFlag.class) || area
+ .getFlag(PveFlag.class))) {
+ return true;
+ }
+ if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) {
+ MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT,
+ "plots.admin.pve." + stub);
+ if (plot != null) {
+ plot.debug(player.getName() + " could not attack " + entityType
+ + " because pve = false OR hostile-attack = false");
+ }
+ return false;
+ }
+ } else if (EntityCategories.TAMEABLE.contains(entityType)) { // victim is tameable
+ if (isPlot) {
+ if (plot.getFlag(TamedAttackFlag.class) || plot.getFlag(PveFlag.class) || plot
+ .isAdded(plotPlayer.getUUID())) {
+ return true;
+ }
+ } else if (roadFlags && (area.getRoadFlag(TamedAttackFlag.class) || area
+ .getFlag(PveFlag.class))) {
+ return true;
+ }
+ if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) {
+ MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT,
+ "plots.admin.pve." + stub);
+ if (plot != null) {
+ plot.debug(player.getName() + " could not attack " + entityType
+ + " because pve = false OR tamned-attack = false");
+ }
+ return false;
+ }
+ } else if (EntityCategories.PLAYER.contains(entityType)) {
+ if (isPlot) {
+ if (!plot.getFlag(PvpFlag.class) && !Permissions
+ .hasPermission(plotPlayer, "plots.admin.pvp." + stub)) {
+ MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT,
+ "plots.admin.pvp." + stub);
+ plot.debug(player.getName() + " could not attack " + entityType
+ + " because pve = false");
+ return false;
+ } else {
+ return true;
+ }
+ } else if (roadFlags && area.getRoadFlag(PvpFlag.class)) {
+ return true;
+ }
+ if (!Permissions.hasPermission(plotPlayer, "plots.admin.pvp." + stub)) {
+ MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT,
+ "plots.admin.pvp." + stub);
+ return false;
+ }
+ } else if (EntityCategories.ANIMAL.contains(entityType)) { // victim is animal
+ if (isPlot) {
+ if (plot.getFlag(AnimalAttackFlag.class) || plot.getFlag(PveFlag.class) || plot
+ .isAdded(plotPlayer.getUUID())) {
+ plot.debug(player.getName() + " could not attack " + entityType
+ + " because pve = false OR animal-attack = false");
+ return true;
+ }
+ } else if (roadFlags && (area.getRoadFlag(AnimalAttackFlag.class) || area
+ .getFlag(PveFlag.class))) {
+ if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) {
+ MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT,
+ "plots.admin.pve." + stub);
+ return false;
+ }
+ }
+ } else if (EntityCategories.VEHICLE
+ .contains(entityType)) { // Vehicles are managed in vehicle destroy event
+ return true;
+ } else { // victim is something else
+ if (isPlot) {
+ if (plot.getFlag(PveFlag.class) || plot.isAdded(plotPlayer.getUUID())) {
+ return true;
+ }
+ } else if (roadFlags && area.getRoadFlag(PveFlag.class)) {
+ return true;
+ }
+ if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) {
+ MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT,
+ "plots.admin.pve." + stub);
+ if (plot != null) {
+ plot.debug(player.getName() + " could not attack " + entityType
+ + " because pve = false");
+ }
+ return false;
+ }
+ }
+ return true;
+ } else if (dplot != null && (!dplot.equals(vplot) || Objects
+ .equals(dplot.getOwnerAbs(), vplot.getOwnerAbs()))) {
+ return vplot != null && vplot.getFlag(PveFlag.class);
+ }
+ //disable the firework damage. too much of a headache to support at the moment.
+ if (vplot != null) {
+ if (EntityDamageEvent.DamageCause.ENTITY_EXPLOSION == cause
+ && damager.getType() == EntityType.FIREWORK) {
+ return false;
+ }
+ }
+ if (vplot == null && roadFlags && area.getRoadFlag(PveFlag.class)) {
+ return true;
+ }
+ return ((vplot != null && vplot.getFlag(PveFlag.class)) || !(damager instanceof Arrow
+ && !(victim instanceof Creature)));
+ }
+
+ public static boolean checkEntity(Entity entity, Plot plot) {
+ if (plot == null || !plot.hasOwner() || plot.getFlags().isEmpty() && plot.getArea()
+ .getFlagContainer().getFlagMap().isEmpty()) {
+ return false;
+ }
+
+ final com.sk89q.worldedit.world.entity.EntityType entityType =
+ BukkitAdapter.adapt(entity.getType());
+
+ if (EntityCategories.PLAYER.contains(entityType)) {
+ return false;
+ }
+
+ if (EntityCategories.PROJECTILE.contains(entityType) || EntityCategories.OTHER
+ .contains(entityType) || EntityCategories.HANGING.contains(entityType)) {
+ return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED,
+ MiscCapFlag.MISC_CAP_UNLIMITED);
+ }
+
+ // Has to go go before vehicle as horses are both
+ // animals and vehicles
+ if (EntityCategories.ANIMAL.contains(entityType) || EntityCategories.VILLAGER
+ .contains(entityType) || EntityCategories.TAMEABLE.contains(entityType)) {
+ return EntityUtil
+ .checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED, MobCapFlag.MOB_CAP_UNLIMITED,
+ AnimalCapFlag.ANIMAL_CAP_UNLIMITED);
+ }
+
+ if (EntityCategories.HOSTILE.contains(entityType)) {
+ return EntityUtil
+ .checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED, MobCapFlag.MOB_CAP_UNLIMITED,
+ HostileCapFlag.HOSTILE_CAP_UNLIMITED);
+ }
+
+ if (EntityCategories.VEHICLE.contains(entityType)) {
+ return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED,
+ VehicleCapFlag.VEHICLE_CAP_UNLIMITED);
+ }
+
+ return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED);
+ }
+
+}
diff --git a/Core/src/main/java/com/plotsquared/core/IPlotMain.java b/Core/src/main/java/com/plotsquared/core/IPlotMain.java
index a38045acb..d88d7ccb9 100644
--- a/Core/src/main/java/com/plotsquared/core/IPlotMain.java
+++ b/Core/src/main/java/com/plotsquared/core/IPlotMain.java
@@ -162,7 +162,7 @@ public interface IPlotMain extends ILogger {
/**
* Register the protection system.
*/
- void registerPlayerEvents();
+ void registerEvents();
/**
* Register force field events.
diff --git a/Core/src/main/java/com/plotsquared/core/PlotSquared.java b/Core/src/main/java/com/plotsquared/core/PlotSquared.java
index e9048f726..3e0e0443b 100644
--- a/Core/src/main/java/com/plotsquared/core/PlotSquared.java
+++ b/Core/src/main/java/com/plotsquared/core/PlotSquared.java
@@ -252,7 +252,7 @@ public class PlotSquared {
this.IMP.runEntityTask();
}
if (Settings.Enabled_Components.EVENTS) {
- this.IMP.registerPlayerEvents();
+ this.IMP.registerEvents();
}
// Required
this.IMP.registerWorldEvents();
diff --git a/Core/src/main/java/com/plotsquared/core/util/EntityUtil.java b/Core/src/main/java/com/plotsquared/core/util/EntityUtil.java
index 9bbc4e1aa..de451de83 100644
--- a/Core/src/main/java/com/plotsquared/core/util/EntityUtil.java
+++ b/Core/src/main/java/com/plotsquared/core/util/EntityUtil.java
@@ -43,7 +43,7 @@ import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE;
* Entity related general utility methods
*/
@UtilityClass
-public final class EntityUtil {
+public class EntityUtil {
private static int capNumeral(@NonNull final String flagName) {
int i;