diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener.java b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener.java index 06c1f3e66..198710578 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener.java @@ -265,15 +265,9 @@ public class BlockEventListener implements Listener { BukkitPlayer pp = BukkitUtil.adapt(player); Plot plot = area.getPlot(location); if (plot != null) { - if ((location.getY() >= area.getMaxBuildHeight() || location.getY() < area - .getMinBuildHeight()) && !Permissions - .hasPermission(pp, Permission.PERMISSION_ADMIN_BUILD_HEIGHT_LIMIT)) { + if (area.notifyIfOutsideBuildArea(pp, location.getY())) { event.setCancelled(true); - pp.sendMessage( - TranslatableCaption.of("height.height_limit"), - Template.of("minHeight", String.valueOf(area.getMinBuildHeight())), - Template.of("maxHeight", String.valueOf(area.getMaxBuildHeight())) - ); + return; } if (!plot.hasOwner()) { if (!Permissions.hasPermission(pp, Permission.PERMISSION_ADMIN_BUILD_UNOWNED)) { @@ -351,15 +345,9 @@ public class BlockEventListener implements Listener { event.setCancelled(true); return; } - } else if ((location.getY() >= area.getMaxBuildHeight() || location.getY() < area - .getMinBuildHeight()) && !Permissions - .hasPermission(plotPlayer, Permission.PERMISSION_ADMIN_BUILD_HEIGHT_LIMIT)) { + } else if (area.notifyIfOutsideBuildArea(plotPlayer, location.getY())) { event.setCancelled(true); - plotPlayer.sendMessage( - TranslatableCaption.of("height.height_limit"), - Template.of("minHeight", String.valueOf(area.getMinBuildHeight())), - Template.of("maxHeight", String.valueOf(area.getMaxBuildHeight())) - ); + return; } if (!plot.hasOwner()) { if (!Permissions @@ -537,7 +525,7 @@ public class BlockEventListener implements Listener { if (plot == null) { return; } - if (location.getY() >= area.getMaxBuildHeight() || location.getY() < area.getMinBuildHeight()) { + if (!area.buildRangeContainsY(location.getY())) { event.setCancelled(true); return; } @@ -739,7 +727,7 @@ public class BlockEventListener implements Listener { } return; } - if (toLocation.getY() >= toArea.getMaxBuildHeight() || toLocation.getY() < toArea.getMinBuildHeight()) { + if (!toArea.buildRangeContainsY(toLocation.getY())) { event.setCancelled(true); return; } @@ -813,6 +801,11 @@ public class BlockEventListener implements Listener { return; } + if (!area.buildRangeContainsY(location.getY())) { + event.setCancelled(true); + return; + } + Plot plot = location.getOwnedPlot(); if (plot == null || !plot.getFlag(CropGrowFlag.class)) { if (plot != null) { @@ -856,15 +849,16 @@ public class BlockEventListener implements Listener { } for (Block block1 : event.getBlocks()) { Location bloc = BukkitUtil.adapt(block1.getLocation()); - if (!area.contains(bloc.getX(), bloc.getZ()) || !area.contains( - bloc.getX() + relative.getBlockX(), - bloc.getZ() + relative.getBlockZ() - )) { + Location newLoc = bloc.add(relative.getBlockX(), relative.getBlockY(), relative.getBlockZ()); + if (!area.contains(bloc.getX(), bloc.getZ()) || !area.contains(newLoc)) { event.setCancelled(true); return; } - if (!plot.equals(area.getOwnedPlot(bloc)) || !plot - .equals(area.getOwnedPlot(bloc.add(relative.getBlockX(), relative.getBlockY(), relative.getBlockZ())))) { + if (!plot.equals(area.getOwnedPlot(bloc)) || !plot.equals(area.getOwnedPlot(newLoc))) { + event.setCancelled(true); + return; + } + if (!area.buildRangeContainsY(bloc.getY()) || !area.buildRangeContainsY(newLoc.getY())) { event.setCancelled(true); return; } @@ -890,9 +884,8 @@ public class BlockEventListener implements Listener { } for (Block block1 : event.getBlocks()) { Location bloc = BukkitUtil.adapt(block1.getLocation()); - if (bloc.isPlotArea() || bloc - .add(relative.getBlockX(), relative.getBlockY(), relative.getBlockZ()) - .isPlotArea()) { + Location newLoc = bloc.add(relative.getBlockX(), relative.getBlockY(), relative.getBlockZ()); + if (bloc.isPlotArea() || newLoc.isPlotArea()) { event.setCancelled(true); return; } @@ -906,15 +899,16 @@ public class BlockEventListener implements Listener { } for (Block block1 : event.getBlocks()) { Location bloc = BukkitUtil.adapt(block1.getLocation()); - if (!area.contains(bloc.getX(), bloc.getZ()) || !area.contains( - bloc.getX() + relative.getBlockX(), - bloc.getZ() + relative.getBlockZ() - )) { + Location newLoc = bloc.add(relative.getBlockX(), relative.getBlockY(), relative.getBlockZ()); + if (!area.contains(bloc.getX(), bloc.getZ()) || !area.contains(newLoc)) { event.setCancelled(true); return; } - if (!plot.equals(area.getOwnedPlot(bloc)) || !plot - .equals(area.getOwnedPlot(bloc.add(relative.getBlockX(), relative.getBlockY(), relative.getBlockZ())))) { + if (!plot.equals(area.getOwnedPlot(bloc)) || !plot.equals(area.getOwnedPlot(newLoc))) { + event.setCancelled(true); + return; + } + if (!area.buildRangeContainsY(bloc.getY()) || !area.buildRangeContainsY(newLoc.getY())) { event.setCancelled(true); return; } @@ -938,6 +932,11 @@ public class BlockEventListener implements Listener { Location location = BukkitUtil.adapt(event.getBlock().getRelative(targetFace).getLocation()); if (location.isPlotRoad()) { event.setCancelled(true); + return; + } + PlotArea area = location.getPlotArea(); + if (area != null && !area.buildRangeContainsY(location.getY())) { + event.setCancelled(true); } } } @@ -977,6 +976,10 @@ public class BlockEventListener implements Listener { Plot plot = area.getOwnedPlot(location); if (!Objects.equals(plot, origin)) { event.getBlocks().remove(i); + continue; + } + if (!area.buildRangeContainsY(location.getY())) { + event.getBlocks().remove(i); } } } @@ -1068,6 +1071,10 @@ public class BlockEventListener implements Listener { Plot plot = area.getOwnedPlot(location1); if (player != null) { BukkitPlayer pp = BukkitUtil.adapt(player); + if (area.notifyIfOutsideBuildArea(pp, location1.getY())) { + event.setCancelled(true); + return; + } if (plot == null) { if (!Permissions.hasPermission(pp, Permission.PERMISSION_ADMIN_BUILD_ROAD)) { pp.sendMessage( @@ -1175,7 +1182,10 @@ public class BlockEventListener implements Listener { return true; } Plot plot = area.getOwnedPlot(blockLocation); - return !Objects.equals(plot, origin); + if (!Objects.equals(plot, origin)) { + return true; + } + return !area.buildRangeContainsY(location.getY()); }); } if (blocks.isEmpty()) { @@ -1217,15 +1227,7 @@ public class BlockEventListener implements Listener { event.setCancelled(true); break; } - if (Permissions.hasPermission(pp, Permission.PERMISSION_ADMIN_BUILD_HEIGHT_LIMIT)) { - continue; - } - if (currentLocation.getY() >= area.getMaxBuildHeight() || currentLocation.getY() < area.getMinBuildHeight()) { - pp.sendMessage( - TranslatableCaption.of("height.height_limit"), - Template.of("minHeight", String.valueOf(area.getMinBuildHeight())), - Template.of("maxHeight", String.valueOf(area.getMaxBuildHeight())) - ); + if (area.notifyIfOutsideBuildArea(pp, currentLocation.getY())) { event.setCancelled(true); break; } diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener117.java b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener117.java index ccefb86fa..2d23515ad 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener117.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener117.java @@ -80,10 +80,19 @@ public class BlockEventListener117 implements Listener { return; } + BukkitPlayer plotPlayer = null; + + if (entity instanceof Player player) { + plotPlayer = BukkitUtil.adapt(player); + if (area.notifyIfOutsideBuildArea(plotPlayer, location.getY())) { + event.setCancelled(true); + return; + } + } + Plot plot = location.getOwnedPlot(); if (plot == null || !plot.getFlag(MiscInteractFlag.class)) { - if (entity instanceof Player player) { - BukkitPlayer plotPlayer = BukkitUtil.adapt(player); + if (plotPlayer != null) { if (plot != null) { if (!plot.isAdded(plotPlayer.getUUID())) { plot.debug(plotPlayer.getName() + " couldn't trigger sculk sensors because misc-interact = false"); @@ -115,12 +124,12 @@ public class BlockEventListener117 implements Listener { PlotArea area = location.getPlotArea(); if (area == null) { for (int i = blocks.size() - 1; i >= 0; i--) { - location = BukkitUtil.adapt(blocks.get(i).getLocation()); - if (location.isPlotArea()) { + Location blockLocation = BukkitUtil.adapt(blocks.get(i).getLocation()); + blockLocation = BukkitUtil.adapt(blocks.get(i).getLocation()); + if (blockLocation.isPlotArea()) { blocks.remove(i); } } - return; } else { Plot origin = area.getOwnedPlot(location); if (origin == null) { @@ -128,27 +137,19 @@ public class BlockEventListener117 implements Listener { return; } for (int i = blocks.size() - 1; i >= 0; i--) { - location = BukkitUtil.adapt(blocks.get(i).getLocation()); - if (!area.contains(location.getX(), location.getZ())) { + Location blockLocation = BukkitUtil.adapt(blocks.get(i).getLocation()); + if (!area.contains(blockLocation.getX(), blockLocation.getZ())) { blocks.remove(i); continue; } - Plot plot = area.getOwnedPlot(location); + Plot plot = area.getOwnedPlot(blockLocation); if (!Objects.equals(plot, origin)) { event.getBlocks().remove(i); + continue; + } + if (!area.buildRangeContainsY(location.getY())) { + event.getBlocks().remove(i); } - } - } - Plot origin = area.getPlot(location); - if (origin == null) { - event.setCancelled(true); - return; - } - for (int i = blocks.size() - 1; i >= 0; i--) { - location = BukkitUtil.adapt(blocks.get(i).getLocation()); - Plot plot = area.getOwnedPlot(location); - if (!Objects.equals(plot, origin) && (!plot.isMerged() && !origin.isMerged())) { - event.getBlocks().remove(i); } } } diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEventListener.java b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEventListener.java index 1a09da355..842fbd66d 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEventListener.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEventListener.java @@ -146,13 +146,11 @@ import org.bukkit.util.Vector; import org.checkerframework.checker.nullness.qual.NonNull; import java.lang.reflect.Field; -import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; import java.util.UUID; -import java.util.regex.Pattern; /** * Player Events involving plots. @@ -1719,6 +1717,7 @@ public class PlayerEventListener extends PlotListener implements Listener { if (PlotSquared.get().getPlotAreaManager().getPlotAreasSet(world).size() == 0) { return; } + BukkitPlayer pp = (event.getEntity() instanceof Player player) ? BukkitUtil.adapt(player) : null; int minX = Integer.MAX_VALUE; int maxX = Integer.MIN_VALUE; int minZ = Integer.MAX_VALUE; @@ -1740,6 +1739,10 @@ public class PlayerEventListener extends PlotListener implements Listener { if (area == null) { continue; } + if (area.notifyIfOutsideBuildArea(pp, location.getY())) { + event.setCancelled(true); + return; + } Plot plot = location.getOwnedPlot(); if (plot == null) { if (area.isRoadFlags() && area.getRoadFlag(DenyPortalsFlag.class)) { diff --git a/Core/src/main/java/com/plotsquared/core/plot/PlotArea.java b/Core/src/main/java/com/plotsquared/core/plot/PlotArea.java index fb42e9881..352614832 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/PlotArea.java +++ b/Core/src/main/java/com/plotsquared/core/plot/PlotArea.java @@ -36,6 +36,7 @@ import com.plotsquared.core.location.BlockLoc; import com.plotsquared.core.location.Direction; import com.plotsquared.core.location.Location; import com.plotsquared.core.location.PlotLoc; +import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.player.ConsolePlayer; import com.plotsquared.core.player.MetaDataAccess; import com.plotsquared.core.player.PlayerMetaDataKeys; @@ -48,6 +49,7 @@ import com.plotsquared.core.plot.flag.implementations.DoneFlag; import com.plotsquared.core.queue.GlobalBlockQueue; import com.plotsquared.core.queue.QueueCoordinator; import com.plotsquared.core.util.MathMan; +import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.PlotExpression; import com.plotsquared.core.util.RegionUtil; import com.plotsquared.core.util.StringMan; @@ -624,6 +626,38 @@ public abstract class PlotArea { getRegionAbs() == null || this.region.contains(location.getBlockVector3())); } + /** + * Get if the {@code PlotArea}'s build range (min build height -> max build height) contains the given y value + * + * @param y y height + * @return if build height contains y + */ + public boolean buildRangeContainsY(int y) { + return y >= minBuildHeight && y < maxBuildHeight; + } + + /** + * Utility method to check if the player is attempting to place blocks outside the build area, and notify of this if the + * player does not have permissions. + * + * @param player Player to check + * @param y y height to check + * @return true if outside build area with no permissions + * @since TODO + */ + public boolean notifyIfOutsideBuildArea(PlotPlayer player, int y) { + if (!buildRangeContainsY(y) && !Permissions.hasPermission(player, Permission.PERMISSION_ADMIN_BUILD_HEIGHT_LIMIT)) { + player.sendMessage( + TranslatableCaption.of("height.height_limit"), + Template.of("minHeight", String.valueOf(minBuildHeight)), + Template.of("maxHeight", String.valueOf(maxBuildHeight)) + ); + // Return true if "failed" as the method will always be inverted otherwise + return true; + } + return false; + } + public @NonNull Set getPlotsAbs(final UUID uuid) { if (uuid == null) { return Collections.emptySet(); diff --git a/Core/src/main/java/com/plotsquared/core/util/EventDispatcher.java b/Core/src/main/java/com/plotsquared/core/util/EventDispatcher.java index d1ad9386c..e91c7b35b 100644 --- a/Core/src/main/java/com/plotsquared/core/util/EventDispatcher.java +++ b/Core/src/main/java/com/plotsquared/core/util/EventDispatcher.java @@ -332,6 +332,15 @@ public class EventDispatcher { ) { PlotArea area = location.getPlotArea(); assert area != null; + if (!area.buildRangeContainsY(location.getY()) && !Permissions + .hasPermission(player, Permission.PERMISSION_ADMIN_BUILD_HEIGHT_LIMIT)) { + player.sendMessage( + TranslatableCaption.of("height.height_limit"), + Template.of("minHeight", String.valueOf(area.getMinBuildHeight())), + Template.of("maxHeight", String.valueOf(area.getMaxBuildHeight())) + ); + return false; + } Plot plot = area.getPlot(location); if (plot != null) { if (plot.isAdded(player.getUUID())) {