mirror of
				https://github.com/IntellectualSites/PlotSquared.git
				synced 2025-11-03 18:53:43 +01:00 
			
		
		
		
	Merge branch 'v6' into chore/v6/deprecate-static-permissions-class
This commit is contained in:
		@@ -50,6 +50,7 @@ dependencies {
 | 
			
		||||
    implementation(libs.arkitektonika)
 | 
			
		||||
    implementation(libs.http4j)
 | 
			
		||||
    implementation("com.intellectualsites.paster:Paster")
 | 
			
		||||
    implementation("com.intellectualsites.informative-annotations:informative-annotations")
 | 
			
		||||
 | 
			
		||||
    // Adventure
 | 
			
		||||
    implementation("net.kyori:adventure-platform-bukkit")
 | 
			
		||||
@@ -87,6 +88,7 @@ tasks.named<ShadowJar>("shadowJar") {
 | 
			
		||||
    relocate("javax.inject", "com.plotsquared.core.annotation.inject")
 | 
			
		||||
    relocate("net.jcip", "com.plotsquared.core.annotations.jcip")
 | 
			
		||||
    relocate("edu.umd.cs.findbugs", "com.plotsquared.core.annotations.findbugs")
 | 
			
		||||
    relocate("com.intellectualsites.informative-annotations", "com.plotsquared.core.annotation.informative")
 | 
			
		||||
 | 
			
		||||
    // Get rid of all the libs which are 100% unused.
 | 
			
		||||
    minimize()
 | 
			
		||||
 
 | 
			
		||||
@@ -65,6 +65,7 @@ import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.GameMode;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.Tag;
 | 
			
		||||
import org.bukkit.block.Block;
 | 
			
		||||
import org.bukkit.block.BlockFace;
 | 
			
		||||
import org.bukkit.block.BlockState;
 | 
			
		||||
@@ -106,11 +107,20 @@ import org.checkerframework.checker.nullness.qual.NonNull;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
@SuppressWarnings("unused")
 | 
			
		||||
public class BlockEventListener implements Listener {
 | 
			
		||||
 | 
			
		||||
    private static final Set<Material> PISTONS = Set.of(
 | 
			
		||||
            Material.PISTON,
 | 
			
		||||
            Material.STICKY_PISTON
 | 
			
		||||
    );
 | 
			
		||||
    private static final Set<Material> PHYSICS_BLOCKS = Set.of(
 | 
			
		||||
            Material.TURTLE_EGG,
 | 
			
		||||
            Material.TURTLE_SPAWN_EGG
 | 
			
		||||
    );
 | 
			
		||||
    private final PlotAreaManager plotAreaManager;
 | 
			
		||||
    private final WorldEdit worldEdit;
 | 
			
		||||
 | 
			
		||||
@@ -216,48 +226,31 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
            plot.debug("Prevented block physics and resent block change because disable-physics = true");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        switch (event.getChangedType()) {
 | 
			
		||||
            case COMPARATOR: {
 | 
			
		||||
                if (!plot.getFlag(RedstoneFlag.class)) {
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    plot.debug("Prevented comparator update because redstone = false");
 | 
			
		||||
                }
 | 
			
		||||
                return;
 | 
			
		||||
        if (event.getChangedType() == Material.COMPARATOR) {
 | 
			
		||||
            if (!plot.getFlag(RedstoneFlag.class)) {
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
                plot.debug("Prevented comparator update because redstone = false");
 | 
			
		||||
            }
 | 
			
		||||
            case ANVIL:
 | 
			
		||||
            case DRAGON_EGG:
 | 
			
		||||
            case GRAVEL:
 | 
			
		||||
            case SAND:
 | 
			
		||||
            case TURTLE_EGG:
 | 
			
		||||
            case TURTLE_HELMET:
 | 
			
		||||
            case TURTLE_SPAWN_EGG: {
 | 
			
		||||
                if (plot.getFlag(DisablePhysicsFlag.class)) {
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    plot.debug("Prevented block physics because disable-physics = true");
 | 
			
		||||
                }
 | 
			
		||||
                return;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (PHYSICS_BLOCKS.contains(event.getChangedType())) {
 | 
			
		||||
            if (plot.getFlag(DisablePhysicsFlag.class)) {
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
                plot.debug("Prevented block physics because disable-physics = true");
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                if (Settings.Redstone.DETECT_INVALID_EDGE_PISTONS) {
 | 
			
		||||
                    switch (block.getType()) {
 | 
			
		||||
                        case PISTON, STICKY_PISTON -> {
 | 
			
		||||
                            org.bukkit.block.data.Directional piston = (org.bukkit.block.data.Directional) block.getBlockData();
 | 
			
		||||
                            switch (piston.getFacing()) {
 | 
			
		||||
                                case EAST -> location = location.add(1, 0, 0);
 | 
			
		||||
                                case SOUTH -> location = location.add(-1, 0, 0);
 | 
			
		||||
                                case WEST -> location = location.add(0, 0, 1);
 | 
			
		||||
                                case NORTH -> location = location.add(0, 0, -1);
 | 
			
		||||
                            }
 | 
			
		||||
                            Plot newPlot = area.getOwnedPlotAbs(location);
 | 
			
		||||
                            if (!plot.equals(newPlot)) {
 | 
			
		||||
                                event.setCancelled(true);
 | 
			
		||||
                                plot.debug("Prevented piston update because of invalid edge piston detection");
 | 
			
		||||
                                return;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (Settings.Redstone.DETECT_INVALID_EDGE_PISTONS) {
 | 
			
		||||
            if (PISTONS.contains(block.getType())) {
 | 
			
		||||
                org.bukkit.block.data.Directional piston = (org.bukkit.block.data.Directional) block.getBlockData();
 | 
			
		||||
                final BlockFace facing = piston.getFacing();
 | 
			
		||||
                location = location.add(facing.getModX(), facing.getModY(), facing.getModZ());
 | 
			
		||||
                Plot newPlot = area.getOwnedPlotAbs(location);
 | 
			
		||||
                if (!plot.equals(newPlot)) {
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    plot.debug("Prevented piston update because of invalid edge piston detection");
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -272,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)) {
 | 
			
		||||
@@ -358,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
 | 
			
		||||
@@ -544,25 +525,22 @@ 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;
 | 
			
		||||
        }
 | 
			
		||||
        switch (event.getNewState().getType()) {
 | 
			
		||||
            case SNOW:
 | 
			
		||||
            case SNOW_BLOCK:
 | 
			
		||||
                if (!plot.getFlag(SnowFormFlag.class)) {
 | 
			
		||||
                    plot.debug("Snow could not form because snow-form = false");
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                }
 | 
			
		||||
                return;
 | 
			
		||||
            case ICE:
 | 
			
		||||
            case FROSTED_ICE:
 | 
			
		||||
            case PACKED_ICE:
 | 
			
		||||
                if (!plot.getFlag(IceFormFlag.class)) {
 | 
			
		||||
                    plot.debug("Ice could not form because ice-form = false");
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                }
 | 
			
		||||
        if (Tag.SNOW.isTagged(event.getNewState().getType())) {
 | 
			
		||||
            if (!plot.getFlag(SnowFormFlag.class)) {
 | 
			
		||||
                plot.debug("Snow could not form because snow-form = false");
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
            }
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (Tag.ICE.isTagged(event.getNewState().getType())) {
 | 
			
		||||
            if (!plot.getFlag(IceFormFlag.class)) {
 | 
			
		||||
                plot.debug("Ice could not form because ice-form = false");
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -583,18 +561,12 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        Class<? extends BooleanFlag<?>> flag;
 | 
			
		||||
        switch (event.getNewState().getType()) {
 | 
			
		||||
            case SNOW:
 | 
			
		||||
            case SNOW_BLOCK:
 | 
			
		||||
                flag = SnowFormFlag.class;
 | 
			
		||||
                break;
 | 
			
		||||
            case ICE:
 | 
			
		||||
            case FROSTED_ICE:
 | 
			
		||||
            case PACKED_ICE:
 | 
			
		||||
                flag = IceFormFlag.class;
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                return; // other blocks are ignored by this event
 | 
			
		||||
        if (Tag.SNOW.isTagged(event.getNewState().getType())) {
 | 
			
		||||
            flag = SnowFormFlag.class;
 | 
			
		||||
        } else if (Tag.ICE.isTagged(event.getNewState().getType())) {
 | 
			
		||||
            flag = IceFormFlag.class;
 | 
			
		||||
        } else {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        boolean allowed = plot.getFlag(flag);
 | 
			
		||||
        Entity entity = event.getEntity();
 | 
			
		||||
@@ -698,50 +670,33 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        switch (block.getType()) {
 | 
			
		||||
            case ICE:
 | 
			
		||||
                if (!plot.getFlag(IceMeltFlag.class)) {
 | 
			
		||||
                    plot.debug("Ice could not melt because ice-melt = false");
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case SNOW:
 | 
			
		||||
                if (!plot.getFlag(SnowMeltFlag.class)) {
 | 
			
		||||
                    plot.debug("Snow could not melt because snow-melt = false");
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case FARMLAND:
 | 
			
		||||
                if (!plot.getFlag(SoilDryFlag.class)) {
 | 
			
		||||
                    plot.debug("Soil could not dry because soil-dry = false");
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case TUBE_CORAL_BLOCK:
 | 
			
		||||
            case BRAIN_CORAL_BLOCK:
 | 
			
		||||
            case BUBBLE_CORAL_BLOCK:
 | 
			
		||||
            case FIRE_CORAL_BLOCK:
 | 
			
		||||
            case HORN_CORAL_BLOCK:
 | 
			
		||||
            case TUBE_CORAL:
 | 
			
		||||
            case BRAIN_CORAL:
 | 
			
		||||
            case BUBBLE_CORAL:
 | 
			
		||||
            case FIRE_CORAL:
 | 
			
		||||
            case HORN_CORAL:
 | 
			
		||||
            case TUBE_CORAL_FAN:
 | 
			
		||||
            case BRAIN_CORAL_FAN:
 | 
			
		||||
            case BUBBLE_CORAL_FAN:
 | 
			
		||||
            case FIRE_CORAL_FAN:
 | 
			
		||||
            case HORN_CORAL_FAN:
 | 
			
		||||
            case BRAIN_CORAL_WALL_FAN:
 | 
			
		||||
            case BUBBLE_CORAL_WALL_FAN:
 | 
			
		||||
            case FIRE_CORAL_WALL_FAN:
 | 
			
		||||
            case HORN_CORAL_WALL_FAN:
 | 
			
		||||
            case TUBE_CORAL_WALL_FAN:
 | 
			
		||||
                if (!plot.getFlag(CoralDryFlag.class)) {
 | 
			
		||||
                    plot.debug("Coral could not dry because coral-dry = false");
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
        Material blockType = block.getType();
 | 
			
		||||
        if (Tag.ICE.isTagged(blockType)) {
 | 
			
		||||
            if (!plot.getFlag(IceMeltFlag.class)) {
 | 
			
		||||
                plot.debug("Ice could not melt because ice-melt = false");
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
            }
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (Tag.SNOW.isTagged(blockType)) {
 | 
			
		||||
            if (!plot.getFlag(SnowMeltFlag.class)) {
 | 
			
		||||
                plot.debug("Snow could not melt because snow-melt = false");
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
            }
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (blockType == Material.FARMLAND) {
 | 
			
		||||
            if (!plot.getFlag(SoilDryFlag.class)) {
 | 
			
		||||
                plot.debug("Soil could not dry because soil-dry = false");
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
            }
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (Tag.CORAL_BLOCKS.isTagged(blockType) || Tag.CORALS.isTagged(blockType)) {
 | 
			
		||||
            if (!plot.getFlag(CoralDryFlag.class)) {
 | 
			
		||||
                plot.debug("Coral could not dry because coral-dry = false");
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -772,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;
 | 
			
		||||
        }
 | 
			
		||||
@@ -846,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) {
 | 
			
		||||
@@ -889,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;
 | 
			
		||||
            }
 | 
			
		||||
@@ -923,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;
 | 
			
		||||
                }
 | 
			
		||||
@@ -939,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;
 | 
			
		||||
            }
 | 
			
		||||
@@ -971,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);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -1010,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);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -1101,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(
 | 
			
		||||
@@ -1208,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()) {
 | 
			
		||||
@@ -1250,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;
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@ import com.plotsquared.core.plot.Plot;
 | 
			
		||||
import com.plotsquared.core.plot.PlotArea;
 | 
			
		||||
import com.plotsquared.core.plot.flag.implementations.CopperOxideFlag;
 | 
			
		||||
import com.plotsquared.core.plot.flag.implementations.MiscInteractFlag;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.block.Block;
 | 
			
		||||
import org.bukkit.entity.Entity;
 | 
			
		||||
import org.bukkit.entity.Item;
 | 
			
		||||
@@ -39,11 +40,31 @@ import org.bukkit.event.block.BlockReceiveGameEvent;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
@SuppressWarnings("unused")
 | 
			
		||||
public class BlockEventListener117 implements Listener {
 | 
			
		||||
 | 
			
		||||
    private static final Set<Material> COPPER_OXIDIZING = Set.of(
 | 
			
		||||
            Material.COPPER_BLOCK,
 | 
			
		||||
            Material.EXPOSED_COPPER,
 | 
			
		||||
            Material.WEATHERED_COPPER,
 | 
			
		||||
            Material.OXIDIZED_COPPER,
 | 
			
		||||
            Material.CUT_COPPER,
 | 
			
		||||
            Material.EXPOSED_CUT_COPPER,
 | 
			
		||||
            Material.WEATHERED_CUT_COPPER,
 | 
			
		||||
            Material.OXIDIZED_CUT_COPPER,
 | 
			
		||||
            Material.CUT_COPPER_STAIRS,
 | 
			
		||||
            Material.EXPOSED_CUT_COPPER_STAIRS,
 | 
			
		||||
            Material.WEATHERED_CUT_COPPER_STAIRS,
 | 
			
		||||
            Material.OXIDIZED_CUT_COPPER_STAIRS,
 | 
			
		||||
            Material.CUT_COPPER_SLAB,
 | 
			
		||||
            Material.EXPOSED_CUT_COPPER_SLAB,
 | 
			
		||||
            Material.WEATHERED_CUT_COPPER_SLAB,
 | 
			
		||||
            Material.OXIDIZED_CUT_COPPER_SLAB
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    @Inject
 | 
			
		||||
    public BlockEventListener117() {
 | 
			
		||||
    }
 | 
			
		||||
@@ -59,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");
 | 
			
		||||
@@ -94,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) {
 | 
			
		||||
@@ -107,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);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -148,27 +170,11 @@ public class BlockEventListener117 implements Listener {
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        switch (event.getNewState().getType()) {
 | 
			
		||||
            case COPPER_BLOCK:
 | 
			
		||||
            case EXPOSED_COPPER:
 | 
			
		||||
            case WEATHERED_COPPER:
 | 
			
		||||
            case OXIDIZED_COPPER:
 | 
			
		||||
            case CUT_COPPER:
 | 
			
		||||
            case EXPOSED_CUT_COPPER:
 | 
			
		||||
            case WEATHERED_CUT_COPPER:
 | 
			
		||||
            case OXIDIZED_CUT_COPPER:
 | 
			
		||||
            case CUT_COPPER_STAIRS:
 | 
			
		||||
            case EXPOSED_CUT_COPPER_STAIRS:
 | 
			
		||||
            case WEATHERED_CUT_COPPER_STAIRS:
 | 
			
		||||
            case OXIDIZED_CUT_COPPER_STAIRS:
 | 
			
		||||
            case CUT_COPPER_SLAB:
 | 
			
		||||
            case EXPOSED_CUT_COPPER_SLAB:
 | 
			
		||||
            case WEATHERED_CUT_COPPER_SLAB:
 | 
			
		||||
            case OXIDIZED_CUT_COPPER_SLAB:
 | 
			
		||||
                if (!plot.getFlag(CopperOxideFlag.class)) {
 | 
			
		||||
                    plot.debug("Copper could not oxide because copper-oxide = false");
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                }
 | 
			
		||||
        if (COPPER_OXIDIZING.contains(event.getNewState().getType())) {
 | 
			
		||||
            if (!plot.getFlag(CopperOxideFlag.class)) {
 | 
			
		||||
                plot.debug("Copper could not oxide because copper-oxide = false");
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -124,17 +124,17 @@ public class EntitySpawnListener implements Listener {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        Plot plot = location.getOwnedPlotAbs();
 | 
			
		||||
        EntityType type = entity.getType();
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
            EntityType type = entity.getType();
 | 
			
		||||
            if (!area.isMobSpawning()) {
 | 
			
		||||
                switch (type) {
 | 
			
		||||
                    case DROPPED_ITEM:
 | 
			
		||||
                        if (Settings.Enabled_Components.KILL_ROAD_ITEMS) {
 | 
			
		||||
                            event.setCancelled(true);
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                    case PLAYER:
 | 
			
		||||
                        return;
 | 
			
		||||
                if (type == EntityType.PLAYER) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                if (type == EntityType.DROPPED_ITEM) {
 | 
			
		||||
                    if (Settings.Enabled_Components.KILL_ROAD_ITEMS) {
 | 
			
		||||
                        event.setCancelled(true);
 | 
			
		||||
                    }
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                if (type.isAlive()) {
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
@@ -148,15 +148,16 @@ public class EntitySpawnListener implements Listener {
 | 
			
		||||
        if (Settings.Done.RESTRICT_BUILDING && DoneFlag.isDone(plot)) {
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
        }
 | 
			
		||||
        switch (entity.getType()) {
 | 
			
		||||
            case ENDER_CRYSTAL:
 | 
			
		||||
                if (BukkitEntityUtil.checkEntity(entity, plot)) {
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                }
 | 
			
		||||
            case SHULKER:
 | 
			
		||||
                if (!entity.hasMetadata("shulkerPlot")) {
 | 
			
		||||
                    entity.setMetadata("shulkerPlot", new FixedMetadataValue((Plugin) PlotSquared.platform(), plot.getId()));
 | 
			
		||||
                }
 | 
			
		||||
        if (type == EntityType.ENDER_CRYSTAL) {
 | 
			
		||||
            if (BukkitEntityUtil.checkEntity(entity, plot)) {
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
            }
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (type == EntityType.SHULKER) {
 | 
			
		||||
            if (!entity.hasMetadata("shulkerPlot")) {
 | 
			
		||||
                entity.setMetadata("shulkerPlot", new FixedMetadataValue((Plugin) PlotSquared.platform(), plot.getId()));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -230,15 +230,15 @@ public class PaperListener implements Listener {
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
            EntityType type = event.getType();
 | 
			
		||||
            if (!area.isMobSpawning()) {
 | 
			
		||||
                switch (type) {
 | 
			
		||||
                    case DROPPED_ITEM:
 | 
			
		||||
                        if (Settings.Enabled_Components.KILL_ROAD_ITEMS) {
 | 
			
		||||
                            event.setShouldAbortSpawn(true);
 | 
			
		||||
                            event.setCancelled(true);
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                    case PLAYER:
 | 
			
		||||
                        return;
 | 
			
		||||
                if (type == EntityType.PLAYER) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                if (type == EntityType.DROPPED_ITEM) {
 | 
			
		||||
                    if (Settings.Enabled_Components.KILL_ROAD_ITEMS) {
 | 
			
		||||
                        event.setShouldAbortSpawn(true);
 | 
			
		||||
                        event.setCancelled(true);
 | 
			
		||||
                    }
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                if (type.isAlive()) {
 | 
			
		||||
                    event.setShouldAbortSpawn(true);
 | 
			
		||||
 
 | 
			
		||||
@@ -82,6 +82,7 @@ import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.ChatColor;
 | 
			
		||||
import org.bukkit.FluidCollisionMode;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.Tag;
 | 
			
		||||
import org.bukkit.block.Block;
 | 
			
		||||
import org.bukkit.block.BlockFace;
 | 
			
		||||
import org.bukkit.block.BlockState;
 | 
			
		||||
@@ -145,23 +146,36 @@ 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.
 | 
			
		||||
 */
 | 
			
		||||
@SuppressWarnings("unused")
 | 
			
		||||
public class PlayerEventListener extends PlotListener implements Listener {
 | 
			
		||||
public class PlayerEventListener implements Listener {
 | 
			
		||||
 | 
			
		||||
    private static final Set<Material> MINECARTS = Set.of(
 | 
			
		||||
            Material.MINECART,
 | 
			
		||||
            Material.TNT_MINECART,
 | 
			
		||||
            Material.CHEST_MINECART,
 | 
			
		||||
            Material.COMMAND_BLOCK_MINECART,
 | 
			
		||||
            Material.FURNACE_MINECART,
 | 
			
		||||
            Material.HOPPER_MINECART
 | 
			
		||||
    );
 | 
			
		||||
    private static final Set<Material> BOOKS = Set.of(
 | 
			
		||||
            Material.BOOK,
 | 
			
		||||
            Material.KNOWLEDGE_BOOK,
 | 
			
		||||
            Material.WRITABLE_BOOK,
 | 
			
		||||
            Material.WRITTEN_BOOK
 | 
			
		||||
    );
 | 
			
		||||
    private final EventDispatcher eventDispatcher;
 | 
			
		||||
    private final WorldEdit worldEdit;
 | 
			
		||||
    private final PlotAreaManager plotAreaManager;
 | 
			
		||||
    private final PlotListener plotListener;
 | 
			
		||||
    // To prevent recursion
 | 
			
		||||
    private boolean tmpTeleport = true;
 | 
			
		||||
    private Field fieldPlayer;
 | 
			
		||||
@@ -181,12 +195,13 @@ public class PlayerEventListener extends PlotListener implements Listener {
 | 
			
		||||
    public PlayerEventListener(
 | 
			
		||||
            final @NonNull PlotAreaManager plotAreaManager,
 | 
			
		||||
            final @NonNull EventDispatcher eventDispatcher,
 | 
			
		||||
            final @NonNull WorldEdit worldEdit
 | 
			
		||||
            final @NonNull WorldEdit worldEdit,
 | 
			
		||||
            final @NonNull PlotListener plotListener
 | 
			
		||||
    ) {
 | 
			
		||||
        super(eventDispatcher);
 | 
			
		||||
        this.eventDispatcher = eventDispatcher;
 | 
			
		||||
        this.worldEdit = worldEdit;
 | 
			
		||||
        this.plotAreaManager = plotAreaManager;
 | 
			
		||||
        this.plotListener = plotListener;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler
 | 
			
		||||
@@ -339,7 +354,7 @@ public class PlayerEventListener extends PlotListener implements Listener {
 | 
			
		||||
        if (area != null) {
 | 
			
		||||
            Plot plot = area.getPlot(location);
 | 
			
		||||
            if (plot != null) {
 | 
			
		||||
                plotEntry(pp, plot);
 | 
			
		||||
                plotListener.plotEntry(pp, plot);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // Delayed
 | 
			
		||||
@@ -391,7 +406,7 @@ public class PlayerEventListener extends PlotListener implements Listener {
 | 
			
		||||
                PlotArea area = location.getPlotArea();
 | 
			
		||||
                if (area == null) {
 | 
			
		||||
                    if (lastPlot != null) {
 | 
			
		||||
                        plotExit(pp, lastPlot);
 | 
			
		||||
                        plotListener.plotExit(pp, lastPlot);
 | 
			
		||||
                        lastPlotAccess.remove();
 | 
			
		||||
                    }
 | 
			
		||||
                    try (final MetaDataAccess<Location> lastLocationAccess =
 | 
			
		||||
@@ -525,7 +540,7 @@ public class PlayerEventListener extends PlotListener implements Listener {
 | 
			
		||||
            if (now == null) {
 | 
			
		||||
                try (final MetaDataAccess<Boolean> kickAccess =
 | 
			
		||||
                             pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) {
 | 
			
		||||
                    if (lastPlot != null && !plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(false)) {
 | 
			
		||||
                    if (lastPlot != null && !plotListener.plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(false)) {
 | 
			
		||||
                        pp.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                                Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_EXIT_DENIED))
 | 
			
		||||
@@ -543,7 +558,7 @@ public class PlayerEventListener extends PlotListener implements Listener {
 | 
			
		||||
                }
 | 
			
		||||
            } else if (now.equals(lastPlot)) {
 | 
			
		||||
                ForceFieldListener.handleForcefield(player, pp, now);
 | 
			
		||||
            } else if (!plotEntry(pp, now) && this.tmpTeleport) {
 | 
			
		||||
            } else if (!plotListener.plotEntry(pp, now) && this.tmpTeleport) {
 | 
			
		||||
                pp.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("deny.no_enter"),
 | 
			
		||||
                        Template.of("plot", now.toString())
 | 
			
		||||
@@ -615,7 +630,7 @@ public class PlayerEventListener extends PlotListener implements Listener {
 | 
			
		||||
            if (plot == null) {
 | 
			
		||||
                try (final MetaDataAccess<Boolean> kickAccess =
 | 
			
		||||
                             pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) {
 | 
			
		||||
                    if (lastPlot != null && !plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(false)) {
 | 
			
		||||
                    if (lastPlot != null && !plotListener.plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(false)) {
 | 
			
		||||
                        pp.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                                Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_EXIT_DENIED))
 | 
			
		||||
@@ -633,7 +648,7 @@ public class PlayerEventListener extends PlotListener implements Listener {
 | 
			
		||||
                }
 | 
			
		||||
            } else if (plot.equals(lastPlot)) {
 | 
			
		||||
                ForceFieldListener.handleForcefield(player, pp, plot);
 | 
			
		||||
            } else if (!plotEntry(pp, plot) && this.tmpTeleport) {
 | 
			
		||||
            } else if (!plotListener.plotEntry(pp, plot) && this.tmpTeleport) {
 | 
			
		||||
                pp.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("deny.no_enter"),
 | 
			
		||||
                        Template.of("plot", plot.toString())
 | 
			
		||||
@@ -780,7 +795,7 @@ public class PlayerEventListener extends PlotListener implements Listener {
 | 
			
		||||
            lastLocationAccess.remove();
 | 
			
		||||
        }
 | 
			
		||||
        if (plot != null) {
 | 
			
		||||
            plotExit(pp, plot);
 | 
			
		||||
            plotListener.plotExit(pp, plot);
 | 
			
		||||
        }
 | 
			
		||||
        if (this.worldEdit != null) {
 | 
			
		||||
            if (!Permissions.hasPermission(pp, Permission.PERMISSION_WORLDEDIT_BYPASS)) {
 | 
			
		||||
@@ -794,7 +809,7 @@ public class PlayerEventListener extends PlotListener implements Listener {
 | 
			
		||||
        if (location.isPlotArea()) {
 | 
			
		||||
            plot = location.getPlot();
 | 
			
		||||
            if (plot != null) {
 | 
			
		||||
                plotEntry(pp, plot);
 | 
			
		||||
                plotListener.plotEntry(pp, plot);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -830,10 +845,10 @@ public class PlayerEventListener extends PlotListener implements Listener {
 | 
			
		||||
        if ((slot > 8) || !event.getEventName().equals("InventoryCreativeEvent")) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        ItemStack current = inv.getItemInHand();
 | 
			
		||||
        ItemStack oldItem = inv.getItemInHand();
 | 
			
		||||
        ItemMeta oldMeta = oldItem.getItemMeta();
 | 
			
		||||
        ItemStack newItem = event.getCursor();
 | 
			
		||||
        ItemMeta newMeta = newItem.getItemMeta();
 | 
			
		||||
        ItemMeta oldMeta = newItem.getItemMeta();
 | 
			
		||||
 | 
			
		||||
        if (event.getClick() == ClickType.CREATIVE) {
 | 
			
		||||
            final Plot plot = pp.getCurrentPlot();
 | 
			
		||||
@@ -873,34 +888,26 @@ public class PlayerEventListener extends PlotListener implements Listener {
 | 
			
		||||
                oldLore = lore.toString();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (!"[(+NBT)]".equals(newLore) || (current.equals(newItem) && newLore.equals(oldLore))) {
 | 
			
		||||
            switch (newItem.getType()) {
 | 
			
		||||
                case LEGACY_BANNER:
 | 
			
		||||
                case PLAYER_HEAD:
 | 
			
		||||
                    if (newMeta != null) {
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                default:
 | 
			
		||||
                    return;
 | 
			
		||||
        Material itemType = newItem.getType();
 | 
			
		||||
        if (!"[(+NBT)]".equals(newLore) || (oldItem.equals(newItem) && newLore.equals(oldLore))) {
 | 
			
		||||
            if (newMeta == null || (itemType != Material.LEGACY_BANNER && itemType != Material.PLAYER_HEAD)) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Block block = player.getTargetBlock(null, 7);
 | 
			
		||||
        org.bukkit.block.BlockState state = block.getState();
 | 
			
		||||
        Material stateType = state.getType();
 | 
			
		||||
        Material itemType = newItem.getType();
 | 
			
		||||
        if (stateType != itemType) {
 | 
			
		||||
            switch (stateType) {
 | 
			
		||||
                case LEGACY_STANDING_BANNER:
 | 
			
		||||
                case LEGACY_WALL_BANNER:
 | 
			
		||||
                    if (itemType == Material.LEGACY_BANNER) {
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                case LEGACY_SKULL:
 | 
			
		||||
                    if (itemType == Material.LEGACY_SKULL_ITEM) {
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                default:
 | 
			
		||||
            if (stateType == Material.LEGACY_WALL_BANNER || stateType == Material.LEGACY_STANDING_BANNER) {
 | 
			
		||||
                if (itemType != Material.LEGACY_BANNER) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            } else if (stateType == Material.LEGACY_SKULL) {
 | 
			
		||||
                if (itemType != Material.LEGACY_SKULL_ITEM) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Location location = BukkitUtil.adapt(state.getLocation());
 | 
			
		||||
@@ -939,7 +946,7 @@ public class PlayerEventListener extends PlotListener implements Listener {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (cancelled) {
 | 
			
		||||
            if ((current.getType() == newItem.getType()) && (current.getDurability() == newItem
 | 
			
		||||
            if ((oldItem.getType() == newItem.getType()) && (oldItem.getDurability() == newItem
 | 
			
		||||
                    .getDurability())) {
 | 
			
		||||
                event.setCursor(
 | 
			
		||||
                        new ItemStack(newItem.getType(), newItem.getAmount(), newItem.getDurability()));
 | 
			
		||||
@@ -1126,14 +1133,21 @@ public class PlayerEventListener extends PlotListener implements Listener {
 | 
			
		||||
                    //Allow all players to eat while also allowing the block place event ot be fired
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                switch (type) {
 | 
			
		||||
                    case ACACIA_BOAT, BIRCH_BOAT, CHEST_MINECART, COMMAND_BLOCK_MINECART, DARK_OAK_BOAT, FURNACE_MINECART, HOPPER_MINECART, JUNGLE_BOAT, MINECART, OAK_BOAT, SPRUCE_BOAT, TNT_MINECART -> eventType = PlayerBlockEventType.PLACE_VEHICLE;
 | 
			
		||||
                    case FIREWORK_ROCKET, FIREWORK_STAR -> eventType = PlayerBlockEventType.SPAWN_MOB;
 | 
			
		||||
                    case BOOK, KNOWLEDGE_BOOK, WRITABLE_BOOK, WRITTEN_BOOK -> eventType = PlayerBlockEventType.READ;
 | 
			
		||||
                    case ARMOR_STAND -> {
 | 
			
		||||
                        location = BukkitUtil.adapt(block.getRelative(event.getBlockFace()).getLocation());
 | 
			
		||||
                        eventType = PlayerBlockEventType.PLACE_MISC;
 | 
			
		||||
                    }
 | 
			
		||||
                if (type == Material.ARMOR_STAND) {
 | 
			
		||||
                    location = BukkitUtil.adapt(block.getRelative(event.getBlockFace()).getLocation());
 | 
			
		||||
                    eventType = PlayerBlockEventType.PLACE_MISC;
 | 
			
		||||
                }
 | 
			
		||||
                if (Tag.ITEMS_BOATS.isTagged(type) || MINECARTS.contains(type)) {
 | 
			
		||||
                    eventType = PlayerBlockEventType.PLACE_VEHICLE;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                if (type == Material.FIREWORK_ROCKET || type == Material.FIREWORK_STAR) {
 | 
			
		||||
                    eventType = PlayerBlockEventType.SPAWN_MOB;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                if (BOOKS.contains(type)) {
 | 
			
		||||
                    eventType = PlayerBlockEventType.READ;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
@@ -1268,7 +1282,7 @@ public class PlayerEventListener extends PlotListener implements Listener {
 | 
			
		||||
        TaskManager.removeFromTeleportQueue(event.getPlayer().getName());
 | 
			
		||||
        BukkitPlayer pp = BukkitUtil.adapt(event.getPlayer());
 | 
			
		||||
        pp.unregister();
 | 
			
		||||
        this.logout(pp.getUUID());
 | 
			
		||||
        plotListener.logout(pp.getUUID());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
 | 
			
		||||
@@ -1705,6 +1719,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;
 | 
			
		||||
@@ -1726,6 +1741,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)) {
 | 
			
		||||
 
 | 
			
		||||
@@ -149,6 +149,18 @@ public class ProjectileEventListener implements Listener {
 | 
			
		||||
        Plot plot = area.getPlot(location);
 | 
			
		||||
        ProjectileSource shooter = entity.getShooter();
 | 
			
		||||
        if (shooter instanceof Player) {
 | 
			
		||||
            if (!((Player) shooter).isOnline()) {
 | 
			
		||||
                if (plot != null) {
 | 
			
		||||
                    if (plot.isAdded(((Player) shooter).getUniqueId()) || plot.getFlag(ProjectilesFlag.class)) {
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                entity.remove();
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            PlotPlayer<?> pp = BukkitUtil.adapt((Player) shooter);
 | 
			
		||||
            if (plot == null) {
 | 
			
		||||
                if (!Permissions.hasPermission(pp, Permission.PERMISSION_ADMIN_PROJECTILE_UNOWNED)) {
 | 
			
		||||
 
 | 
			
		||||
@@ -19,12 +19,12 @@
 | 
			
		||||
package com.plotsquared.bukkit.queue;
 | 
			
		||||
 | 
			
		||||
import com.google.common.base.Preconditions;
 | 
			
		||||
import com.intellectualsites.annotations.DoNotUse;
 | 
			
		||||
import com.plotsquared.bukkit.util.BukkitBlockUtil;
 | 
			
		||||
import com.plotsquared.bukkit.util.BukkitUtil;
 | 
			
		||||
import com.plotsquared.core.location.ChunkWrapper;
 | 
			
		||||
import com.plotsquared.core.location.Location;
 | 
			
		||||
import com.plotsquared.core.queue.ScopedQueueCoordinator;
 | 
			
		||||
import com.plotsquared.core.util.AnnotationHelper;
 | 
			
		||||
import com.plotsquared.core.util.ChunkUtil;
 | 
			
		||||
import com.plotsquared.core.util.PatternUtil;
 | 
			
		||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
 | 
			
		||||
@@ -44,7 +44,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
@AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.")
 | 
			
		||||
@DoNotUse
 | 
			
		||||
public class GenChunk extends ScopedQueueCoordinator {
 | 
			
		||||
 | 
			
		||||
    public final Biome[] biomes;
 | 
			
		||||
 
 | 
			
		||||
@@ -43,6 +43,7 @@ dependencies {
 | 
			
		||||
    api(libs.cloudServices)
 | 
			
		||||
    api(libs.arkitektonika)
 | 
			
		||||
    api("com.intellectualsites.paster:Paster")
 | 
			
		||||
    api("com.intellectualsites.informative-annotations:informative-annotations")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
tasks.processResources {
 | 
			
		||||
@@ -62,5 +63,6 @@ tasks {
 | 
			
		||||
        opt.links("https://jd.adventure.kyori.net/api/4.9.3/")
 | 
			
		||||
        opt.links("https://google.github.io/guice/api-docs/" + libs.guice.get().versionConstraint.toString() + "/javadoc/")
 | 
			
		||||
        opt.links("https://checkerframework.org/api/")
 | 
			
		||||
        opt.links("https://javadoc.io/doc/com.intellectualsites.informative-annotations/informative-annotations/latest/")
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@ import cloud.commandframework.services.ServicePipeline;
 | 
			
		||||
import com.google.inject.Injector;
 | 
			
		||||
import com.google.inject.Key;
 | 
			
		||||
import com.google.inject.TypeLiteral;
 | 
			
		||||
import com.intellectualsites.annotations.DoNotUse;
 | 
			
		||||
import com.plotsquared.core.backup.BackupManager;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.LocaleHolder;
 | 
			
		||||
import com.plotsquared.core.generator.GeneratorWrapper;
 | 
			
		||||
@@ -33,7 +34,6 @@ import com.plotsquared.core.permissions.PermissionHandler;
 | 
			
		||||
import com.plotsquared.core.player.PlotPlayer;
 | 
			
		||||
import com.plotsquared.core.plot.world.PlotAreaManager;
 | 
			
		||||
import com.plotsquared.core.queue.GlobalBlockQueue;
 | 
			
		||||
import com.plotsquared.core.util.AnnotationHelper;
 | 
			
		||||
import com.plotsquared.core.util.ChunkManager;
 | 
			
		||||
import com.plotsquared.core.util.EconHandler;
 | 
			
		||||
import com.plotsquared.core.util.PlatformWorldManager;
 | 
			
		||||
@@ -308,7 +308,7 @@ public interface PlotPlatform<P> extends LocaleHolder {
 | 
			
		||||
     * @return worldedit implementations
 | 
			
		||||
     * @since 6.3.0
 | 
			
		||||
     */
 | 
			
		||||
    @AnnotationHelper.ApiDescription(info = "Internal use only")
 | 
			
		||||
    @DoNotUse
 | 
			
		||||
    @NonNull String worldEditImplementations();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ package com.plotsquared.core.generator;
 | 
			
		||||
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
import com.google.inject.assistedinject.Assisted;
 | 
			
		||||
import com.intellectualsites.annotations.DoNotUse;
 | 
			
		||||
import com.plotsquared.core.PlotSquared;
 | 
			
		||||
import com.plotsquared.core.configuration.ConfigurationSection;
 | 
			
		||||
import com.plotsquared.core.configuration.Settings;
 | 
			
		||||
@@ -33,7 +34,6 @@ import com.plotsquared.core.plot.PlotId;
 | 
			
		||||
import com.plotsquared.core.plot.PlotManager;
 | 
			
		||||
import com.plotsquared.core.plot.schematic.Schematic;
 | 
			
		||||
import com.plotsquared.core.queue.GlobalBlockQueue;
 | 
			
		||||
import com.plotsquared.core.util.AnnotationHelper;
 | 
			
		||||
import com.plotsquared.core.util.FileUtils;
 | 
			
		||||
import com.plotsquared.core.util.MathMan;
 | 
			
		||||
import com.plotsquared.core.util.SchematicHandler;
 | 
			
		||||
@@ -531,7 +531,7 @@ public class HybridPlotWorld extends ClassicPlotWorld {
 | 
			
		||||
     *
 | 
			
		||||
     * @since 6.9.0
 | 
			
		||||
     */
 | 
			
		||||
    @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.")
 | 
			
		||||
    @DoNotUse
 | 
			
		||||
    public @Nullable List<Entity> getPlotSchematicEntities() {
 | 
			
		||||
        return schem3Entities;
 | 
			
		||||
    }
 | 
			
		||||
@@ -541,7 +541,7 @@ public class HybridPlotWorld extends ClassicPlotWorld {
 | 
			
		||||
     *
 | 
			
		||||
     * @since 6.9.0
 | 
			
		||||
     */
 | 
			
		||||
    @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.")
 | 
			
		||||
    @DoNotUse
 | 
			
		||||
    public @Nullable BlockVector3 getPlotSchematicMinPoint() {
 | 
			
		||||
        return schem3MinPoint;
 | 
			
		||||
    }
 | 
			
		||||
@@ -551,7 +551,7 @@ public class HybridPlotWorld extends ClassicPlotWorld {
 | 
			
		||||
     *
 | 
			
		||||
     * @since 6.9.0
 | 
			
		||||
     */
 | 
			
		||||
    @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.")
 | 
			
		||||
    @DoNotUse
 | 
			
		||||
    public boolean populationNeeded() {
 | 
			
		||||
        return schem1PopulationNeeded || schem2PopulationNeeded || schem3PopulationNeeded;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -189,13 +189,13 @@ public class HybridUtils {
 | 
			
		||||
                if (X == ctx) {
 | 
			
		||||
                    maxX = tx & 15;
 | 
			
		||||
                } else {
 | 
			
		||||
                    maxX = 16;
 | 
			
		||||
                    maxX = 15;
 | 
			
		||||
                }
 | 
			
		||||
                int maxZ;
 | 
			
		||||
                if (Z == ctz) {
 | 
			
		||||
                    maxZ = tz & 15;
 | 
			
		||||
                } else {
 | 
			
		||||
                    maxZ = 16;
 | 
			
		||||
                    maxZ = 15;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                int chunkBlockX = X << 4;
 | 
			
		||||
@@ -221,7 +221,7 @@ public class HybridUtils {
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            final Runnable run = () -> TaskManager.runTaskAsync(() -> {
 | 
			
		||||
            final Runnable run = () -> {
 | 
			
		||||
                int size = width * length;
 | 
			
		||||
                int[] changes = new int[size];
 | 
			
		||||
                int[] faces = new int[size];
 | 
			
		||||
@@ -296,7 +296,7 @@ public class HybridUtils {
 | 
			
		||||
                analysis.variety_sd = (int) (MathMan.getSD(variety, analysis.variety) * 100);
 | 
			
		||||
                whenDone.value = analysis;
 | 
			
		||||
                whenDone.run();
 | 
			
		||||
            });
 | 
			
		||||
            };
 | 
			
		||||
            queue.setCompleteTask(run);
 | 
			
		||||
            queue.enqueue();
 | 
			
		||||
        });
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
 */
 | 
			
		||||
package com.plotsquared.core.location;
 | 
			
		||||
 | 
			
		||||
import com.plotsquared.core.util.AnnotationHelper;
 | 
			
		||||
import com.intellectualsites.annotations.DoNotUse;
 | 
			
		||||
import com.sk89q.worldedit.math.BlockVector3;
 | 
			
		||||
import org.checkerframework.checker.nullness.qual.NonNull;
 | 
			
		||||
 | 
			
		||||
@@ -28,7 +28,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
 | 
			
		||||
 *
 | 
			
		||||
 * @since 6.9.0
 | 
			
		||||
 */
 | 
			
		||||
@AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.")
 | 
			
		||||
@DoNotUse
 | 
			
		||||
public final class UncheckedWorldLocation extends Location {
 | 
			
		||||
 | 
			
		||||
    private final String worldName;
 | 
			
		||||
@@ -54,7 +54,7 @@ public final class UncheckedWorldLocation extends Location {
 | 
			
		||||
     *
 | 
			
		||||
     * @since 6.9.0
 | 
			
		||||
     */
 | 
			
		||||
    @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.")
 | 
			
		||||
    @DoNotUse
 | 
			
		||||
    public static @NonNull UncheckedWorldLocation at(
 | 
			
		||||
            final @NonNull String world, final int x, final int y, final int z
 | 
			
		||||
    ) {
 | 
			
		||||
@@ -62,7 +62,7 @@ public final class UncheckedWorldLocation extends Location {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.")
 | 
			
		||||
    @DoNotUse
 | 
			
		||||
    public @NonNull String getWorldName() {
 | 
			
		||||
        return this.worldName;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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<Plot> getPlotsAbs(final UUID uuid) {
 | 
			
		||||
        if (uuid == null) {
 | 
			
		||||
            return Collections.emptySet();
 | 
			
		||||
 
 | 
			
		||||
@@ -20,8 +20,8 @@ package com.plotsquared.core.plot.flag;
 | 
			
		||||
 | 
			
		||||
import com.google.common.base.Preconditions;
 | 
			
		||||
import com.google.common.collect.ImmutableMap;
 | 
			
		||||
import com.intellectualsites.annotations.NotPublic;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.CaptionUtility;
 | 
			
		||||
import com.plotsquared.core.util.AnnotationHelper;
 | 
			
		||||
import org.apache.logging.log4j.LogManager;
 | 
			
		||||
import org.apache.logging.log4j.Logger;
 | 
			
		||||
import org.checkerframework.checker.nullness.qual.NonNull;
 | 
			
		||||
@@ -32,7 +32,6 @@ import java.util.HashMap;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Container type for {@link PlotFlag plot flags}.
 | 
			
		||||
@@ -353,7 +352,7 @@ public class FlagContainer {
 | 
			
		||||
     * @return a new Runnable that cleans up once the FlagContainer isn't needed anymore.
 | 
			
		||||
     * @since 6.0.10
 | 
			
		||||
     */
 | 
			
		||||
    @AnnotationHelper.ApiDescription(info = "This method should not be considered as public or API.")
 | 
			
		||||
    @NotPublic
 | 
			
		||||
    public Runnable createCleanupHook() {
 | 
			
		||||
        return () -> GlobalFlagContainer.getInstance().unsubscribe(unknownsRef);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -18,8 +18,8 @@
 | 
			
		||||
 */
 | 
			
		||||
package com.plotsquared.core.queue;
 | 
			
		||||
 | 
			
		||||
import com.intellectualsites.annotations.DoNotUse;
 | 
			
		||||
import com.plotsquared.core.location.Location;
 | 
			
		||||
import com.plotsquared.core.util.AnnotationHelper;
 | 
			
		||||
import com.sk89q.jnbt.CompoundTag;
 | 
			
		||||
import com.sk89q.worldedit.function.pattern.Pattern;
 | 
			
		||||
import com.sk89q.worldedit.math.BlockVector3;
 | 
			
		||||
@@ -37,7 +37,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
 | 
			
		||||
 * in {@link BlockArrayCacheScopedQueueCoordinator#setOffsetX(int)} and
 | 
			
		||||
 * {@link BlockArrayCacheScopedQueueCoordinator#setOffsetZ(int)}
 | 
			
		||||
 */
 | 
			
		||||
@AnnotationHelper.ApiDescription(info = "Internal use only. Subject to change at any time and created for specific use cases.")
 | 
			
		||||
@DoNotUse
 | 
			
		||||
public class BlockArrayCacheScopedQueueCoordinator extends ScopedQueueCoordinator {
 | 
			
		||||
 | 
			
		||||
    private final BlockState[][][] blockStates;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,55 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * PlotSquared, a land and world management plugin for Minecraft.
 | 
			
		||||
 * Copyright (C) IntellectualSites <https://intellectualsites.com>
 | 
			
		||||
 * Copyright (C) IntellectualSites team and contributors
 | 
			
		||||
 *
 | 
			
		||||
 * 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 <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
package com.plotsquared.core.util;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.Documented;
 | 
			
		||||
import java.lang.annotation.Retention;
 | 
			
		||||
import java.lang.annotation.RetentionPolicy;
 | 
			
		||||
import java.lang.annotation.Target;
 | 
			
		||||
 | 
			
		||||
import static java.lang.annotation.ElementType.METHOD;
 | 
			
		||||
import static java.lang.annotation.ElementType.MODULE;
 | 
			
		||||
import static java.lang.annotation.ElementType.PACKAGE;
 | 
			
		||||
import static java.lang.annotation.ElementType.RECORD_COMPONENT;
 | 
			
		||||
import static java.lang.annotation.ElementType.TYPE;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @since 6.2.2
 | 
			
		||||
 */
 | 
			
		||||
@AnnotationHelper.ApiDescription(info = "An internal class for custom annotations." +
 | 
			
		||||
        "This is in no form part of the API and is subject to change at any time.")
 | 
			
		||||
public final class AnnotationHelper {
 | 
			
		||||
 | 
			
		||||
    private AnnotationHelper() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Documented
 | 
			
		||||
    @Retention(RetentionPolicy.CLASS)
 | 
			
		||||
    @Target(value = {METHOD, PACKAGE, MODULE, RECORD_COMPONENT, TYPE})
 | 
			
		||||
    public @interface ApiDescription {
 | 
			
		||||
        /**
 | 
			
		||||
         * Returns additional information how to use a class for the API
 | 
			
		||||
         *
 | 
			
		||||
         * @return the version string
 | 
			
		||||
         * @since 6.2.2
 | 
			
		||||
         */
 | 
			
		||||
        String info() default "";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -19,6 +19,7 @@
 | 
			
		||||
package com.plotsquared.core.util;
 | 
			
		||||
 | 
			
		||||
import com.google.common.eventbus.EventBus;
 | 
			
		||||
import com.intellectualsites.annotations.DoNotUse;
 | 
			
		||||
import com.plotsquared.core.configuration.Settings;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
 | 
			
		||||
import com.plotsquared.core.events.PlayerAutoPlotEvent;
 | 
			
		||||
@@ -81,8 +82,7 @@ import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
@AnnotationHelper.ApiDescription(info = "This is an internal class used by PlotSquared to dispatch events." +
 | 
			
		||||
        "This is in no form part of the API and is subject to change at any time.")
 | 
			
		||||
@DoNotUse
 | 
			
		||||
public class EventDispatcher {
 | 
			
		||||
 | 
			
		||||
    private final EventBus eventBus = new EventBus("PlotSquaredEvents");
 | 
			
		||||
@@ -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())) {
 | 
			
		||||
 
 | 
			
		||||
@@ -65,7 +65,7 @@ subprojects {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dependencies {
 | 
			
		||||
        implementation(platform("com.intellectualsites.bom:bom-1.18.x:1.5"))
 | 
			
		||||
        implementation(platform("com.intellectualsites.bom:bom-1.18.x:1.7"))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dependencies {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
[versions]
 | 
			
		||||
# Platform expectations
 | 
			
		||||
paper = "1.18.1-R0.1-SNAPSHOT"
 | 
			
		||||
checker-qual = "3.22.0"
 | 
			
		||||
guice = "5.1.0"
 | 
			
		||||
spotbugs = "4.7.0"
 | 
			
		||||
 | 
			
		||||
@@ -15,7 +14,7 @@ mvdwapi = "3.1.1"
 | 
			
		||||
# Third party
 | 
			
		||||
prtree = "2.0.0"
 | 
			
		||||
aopalliance = "1.0"
 | 
			
		||||
cloud-services = "1.6.2"
 | 
			
		||||
cloud-services = "1.7.0"
 | 
			
		||||
arkitektonika = "2.1.1"
 | 
			
		||||
squirrelid = "0.3.1"
 | 
			
		||||
http4j = "1.3"
 | 
			
		||||
@@ -29,7 +28,6 @@ nexus = "1.1.0"
 | 
			
		||||
[libraries]
 | 
			
		||||
# Platform expectations
 | 
			
		||||
paper = { group = "io.papermc.paper", name = "paper-api", version.ref = "paper" }
 | 
			
		||||
checkerqual = { group = "org.checkerframework", name = "checker-qual", version.ref = "checker-qual" }
 | 
			
		||||
 | 
			
		||||
# Platform expectations
 | 
			
		||||
guice = { group = "com.google.inject", name = "guice", version.ref = "guice" }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user