diff --git a/.github/workflows/announce-release-on-discord.yml b/.github/workflows/announce-release-on-discord.yml new file mode 100644 index 000000000..4e0eeef84 --- /dev/null +++ b/.github/workflows/announce-release-on-discord.yml @@ -0,0 +1,25 @@ +name: Announce release on discord +on: + release: + types: [published] + +jobs: + send_announcement: + runs-on: ubuntu-latest + steps: + - name: send custom message with args + env: + DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} + DISCORD_USERNAME: PlotSquared Release + DISCORD_AVATAR: https://raw.githubusercontent.com/IntellectualSites/Assets/main/plugins/PlotSquared/PlotSquared.png + uses: Ilshidur/action-discord@0.3.2 + with: + args: | + "<@&525015541815967744> <@&679322738552471574> <@&699293353862496266>" + "" + "<:plotsquared:730750385886593039> **PlotSquared ${{ github.event.release.tag_name }} has been released!**" + "" + "Click here to view changelog: https://github.com/IntellectualSites/PlotSquared/releases/tag/${{ github.event.release.tag_name }}" + "" + "The download is available at:" + "- Spigot: " diff --git a/Bukkit/build.gradle.kts b/Bukkit/build.gradle.kts index 5b9bcbf21..d56c2d74d 100644 --- a/Bukkit/build.gradle.kts +++ b/Bukkit/build.gradle.kts @@ -24,7 +24,7 @@ dependencies { implementation("org.bstats:bstats-bukkit") // Paper - compileOnly(libs.paper) + compileOnly("io.papermc.paper:paper-api") implementation("io.papermc:paperlib") // Plugins diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java b/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java index b19130c1c..4355e9418 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java @@ -849,11 +849,11 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl // managed elsewhere continue; case "SHULKER": - if (Settings.Enabled_Components.KILL_ROAD_MOBS) { + if (Settings.Enabled_Components.KILL_ROAD_MOBS && (Settings.Enabled_Components.KILL_NAMED_ROAD_MOBS || entity.getCustomName() == null)) { LivingEntity livingEntity = (LivingEntity) entity; List meta = entity.getMetadata("shulkerPlot"); if (!meta.isEmpty()) { - if (livingEntity.isLeashed()) { + if (livingEntity.isLeashed() && !Settings.Enabled_Components.KILL_OWNED_ROAD_MOBS) { continue; } List keep = entity.getMetadata("keep"); @@ -866,10 +866,8 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl com.plotsquared.core.location.Location pLoc = BukkitUtil.adapt(entity.getLocation()); PlotArea area = pLoc.getPlotArea(); if (area != null) { - PlotId currentPlotId = area.getPlotAbs(pLoc).getId(); - if (!originalPlotId.equals(currentPlotId) && (currentPlotId == null || !area.getPlot( - originalPlotId) - .equals(area.getPlot(currentPlotId)))) { + Plot currentPlot = area.getPlotAbs(pLoc); + if (currentPlot == null || !originalPlotId.equals(currentPlot.getId())) { if (entity.hasMetadata("ps-tmp-teleport")) { continue; } @@ -883,11 +881,11 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl com.plotsquared.core.location.Location pLoc = BukkitUtil.adapt(entity.getLocation()); PlotArea area = pLoc.getPlotArea(); if (area != null) { - PlotId currentPlotId = area.getPlotAbs(pLoc).getId(); - if (currentPlotId != null) { + Plot currentPlot = area.getPlotAbs(pLoc); + if (currentPlot != null) { entity.setMetadata( "shulkerPlot", - new FixedMetadataValue((Plugin) PlotSquared.platform(), currentPlotId) + new FixedMetadataValue((Plugin) PlotSquared.platform(), currentPlot.getId()) ); } } @@ -973,7 +971,9 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl || !entity.hasMetadata("keep")) { Entity passenger = entity.getPassenger(); if ((Settings.Enabled_Components.KILL_OWNED_ROAD_MOBS - || !(passenger instanceof Player)) && entity.getMetadata("keep").isEmpty()) { + || !((passenger instanceof Player) || livingEntity.isLeashed())) + && (Settings.Enabled_Components.KILL_NAMED_ROAD_MOBS || entity.getCustomName() == null) + && entity.getMetadata("keep").isEmpty()) { if (entity.hasMetadata("ps-tmp-teleport")) { continue; } @@ -983,8 +983,9 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl } } else { Entity passenger = entity.getPassenger(); - if ((Settings.Enabled_Components.KILL_OWNED_ROAD_MOBS - || !(passenger instanceof Player)) && entity.getMetadata("keep").isEmpty()) { + if ((Settings.Enabled_Components.KILL_OWNED_ROAD_MOBS || !(passenger instanceof Player)) + && (Settings.Enabled_Components.KILL_NAMED_ROAD_MOBS && entity.getCustomName() != null) + && entity.getMetadata("keep").isEmpty()) { if (entity.hasMetadata("ps-tmp-teleport")) { continue; } diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/generator/LegacyBlockStatePopulator.java b/Bukkit/src/main/java/com/plotsquared/bukkit/generator/LegacyBlockStatePopulator.java index eb8ad0201..d9482c5f2 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/generator/LegacyBlockStatePopulator.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/generator/LegacyBlockStatePopulator.java @@ -33,7 +33,6 @@ import org.bukkit.Chunk; import org.bukkit.World; import org.bukkit.generator.BlockPopulator; import org.checkerframework.checker.nullness.qual.NonNull; -import org.jetbrains.annotations.NotNull; import java.util.Random; @@ -51,7 +50,7 @@ final class LegacyBlockStatePopulator extends BlockPopulator { } @Override - public void populate(@NotNull final World world, @NotNull final Random random, @NotNull final Chunk source) { + public void populate(@NonNull final World world, @NonNull final Random random, @NonNull final Chunk source) { int chunkMinX = source.getX() << 4; int chunkMinZ = source.getZ() << 4; PlotArea area = Location.at(world.getName(), chunkMinX, 0, chunkMinZ).getPlotArea(); 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 a08097100..61365db8c 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener.java @@ -56,6 +56,7 @@ import com.plotsquared.core.plot.flag.types.BlockTypeWrapper; import com.plotsquared.core.plot.flag.types.BooleanFlag; import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.util.Permissions; +import com.plotsquared.core.util.PlotFlagUtil; import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskTime; import com.sk89q.worldedit.WorldEdit; @@ -166,7 +167,7 @@ public class BlockEventListener implements Listener { } Plot plot = location.getOwnedPlot(); if (plot == null) { - if (area.isRoadFlags() && !area.getRoadFlag(RedstoneFlag.class)) { + if (PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, RedstoneFlag.class, false)) { event.setNewCurrent(0); } return; @@ -1084,7 +1085,10 @@ public class BlockEventListener implements Listener { return; } if (plot == null) { - if (!Permissions.hasPermission(pp, Permission.PERMISSION_ADMIN_BUILD_ROAD)) { + if (!PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, BlockIgnitionFlag.class, true) && !Permissions.hasPermission( + pp, + Permission.PERMISSION_ADMIN_BUILD_ROAD + )) { pp.sendMessage( TranslatableCaption.of("permission.no_permission_event"), Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BUILD_ROAD)) @@ -1092,7 +1096,10 @@ public class BlockEventListener implements Listener { event.setCancelled(true); } } else if (!plot.hasOwner()) { - if (!Permissions.hasPermission(pp, Permission.PERMISSION_ADMIN_BUILD_UNOWNED)) { + if (!PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, BlockIgnitionFlag.class, true) && !Permissions.hasPermission( + pp, + Permission.PERMISSION_ADMIN_BUILD_UNOWNED + )) { pp.sendMessage( TranslatableCaption.of("permission.no_permission_event"), Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BUILD_UNOWNED)) 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 2d23515ad..d4b71a7b2 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener117.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener117.java @@ -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 com.plotsquared.core.util.PlotFlagUtil; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Entity; @@ -91,7 +92,8 @@ public class BlockEventListener117 implements Listener { } Plot plot = location.getOwnedPlot(); - if (plot == null || !plot.getFlag(MiscInteractFlag.class)) { + if (plot == null && !PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, MiscInteractFlag.class, true) || plot != null && !plot.getFlag( + MiscInteractFlag.class)) { if (plotPlayer != null) { if (plot != null) { if (!plot.isAdded(plotPlayer.getUUID())) { @@ -104,6 +106,12 @@ public class BlockEventListener117 implements Listener { if (entity instanceof Item item) { UUID itemThrower = item.getThrower(); if (plot != null) { + if (itemThrower == null && (itemThrower = item.getOwner()) == null) { + plot.debug( + "A thrown item couldn't trigger sculk sensors because misc-interact = false and the item's owner could not be resolved."); + event.setCancelled(true); + return; + } if (!plot.isAdded(itemThrower)) { if (!plot.isAdded(itemThrower)) { plot.debug("A thrown item couldn't trigger sculk sensors because misc-interact = false"); diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/EntityEventListener.java b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/EntityEventListener.java index bc28460e2..3e32a9816 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/EntityEventListener.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/EntityEventListener.java @@ -38,6 +38,7 @@ import com.plotsquared.core.plot.flag.implementations.InvincibleFlag; import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.util.EventDispatcher; import com.plotsquared.core.util.Permissions; +import com.plotsquared.core.util.PlotFlagUtil; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.world.block.BlockType; import org.bukkit.Material; @@ -261,7 +262,7 @@ public class EntityEventListener implements Listener { } Plot plot = location.getOwnedPlot(); if (plot == null) { - if (area.isRoadFlags() && area.getRoadFlag(InvincibleFlag.class)) { + if (PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, InvincibleFlag.class, true)) { event.setCancelled(true); } return; diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PaperListener.java b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PaperListener.java index 54cc21a41..3ad3a6227 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PaperListener.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PaperListener.java @@ -44,6 +44,7 @@ import com.plotsquared.core.plot.flag.implementations.ProjectilesFlag; import com.plotsquared.core.plot.flag.types.BooleanFlag; import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.util.Permissions; +import com.plotsquared.core.util.PlotFlagUtil; import net.kyori.adventure.text.minimessage.Template; import org.bukkit.Chunk; import org.bukkit.block.Block; @@ -326,14 +327,18 @@ public class PaperListener implements Listener { return; } Location location = BukkitUtil.adapt(entity.getLocation()); - if (!this.plotAreaManager.hasPlotArea(location.getWorldName())) { + PlotArea area = location.getPlotArea(); + if (area == null) { return; } PlotPlayer pp = BukkitUtil.adapt((Player) shooter); Plot plot = location.getOwnedPlot(); if (plot == null) { - if (!Permissions.hasPermission(pp, Permission.PERMISSION_ADMIN_PROJECTILE_ROAD)) { + if (!PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, ProjectilesFlag.class, true) && !Permissions.hasPermission( + pp, + Permission.PERMISSION_ADMIN_PROJECTILE_ROAD + )) { pp.sendMessage( TranslatableCaption.of("permission.no_permission_event"), Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_PROJECTILE_ROAD)) diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PaperListener113.java b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PaperListener113.java index 722e58347..635f736e7 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PaperListener113.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PaperListener113.java @@ -48,6 +48,10 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.block.BlockPlaceEvent; import org.checkerframework.checker.nullness.qual.NonNull; +/** + * @deprecated P2 effectively no longer supports 1.13 + */ +@Deprecated(forRemoval = true, since = "6.10.4") public class PaperListener113 extends PaperListener { @Inject 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 ca7130deb..fbe26e676 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEventListener.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEventListener.java @@ -68,6 +68,7 @@ import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.util.EventDispatcher; import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.Permissions; +import com.plotsquared.core.util.PlotFlagUtil; import com.plotsquared.core.util.PremiumVerification; import com.plotsquared.core.util.entity.EntityCategories; import com.plotsquared.core.util.task.TaskManager; @@ -889,8 +890,7 @@ public class PlayerEventListener implements Listener { } } else { PlotArea area = pp.getPlotAreaAbs(); - if (area != null && area.isRoadFlags() && area - .getRoadFlag(PreventCreativeCopyFlag.class)) { + if (area != null && PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, PreventCreativeCopyFlag.class, true)) { final ItemStack newStack = new ItemStack(newItem.getType(), newItem.getAmount()); event.setCursor(newStack); @@ -998,8 +998,10 @@ public class PlayerEventListener implements Listener { Plot plot = location.getPlotAbs(); BukkitPlayer pp = BukkitUtil.adapt(e.getPlayer()); if (plot == null) { - if (!area.isRoadFlags() && !area.getRoadFlag(MiscInteractFlag.class) && !Permissions - .hasPermission(pp, Permission.PERMISSION_ADMIN_INTERACT_ROAD)) { + if (!PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, MiscInteractFlag.class, true) && !Permissions.hasPermission( + pp, + Permission.PERMISSION_ADMIN_INTERACT_ROAD + )) { pp.sendMessage( TranslatableCaption.of("permission.no_permission_event"), Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_INTERACT_ROAD)) @@ -1009,9 +1011,7 @@ public class PlayerEventListener implements Listener { } else { if (Settings.Done.RESTRICT_BUILDING && DoneFlag.isDone(plot)) { if (!Permissions.hasPermission(pp, Permission.PERMISSION_ADMIN_BUILD_OTHER)) { - pp.sendMessage( - TranslatableCaption.of("done.building_restricted") - ); + pp.sendMessage(TranslatableCaption.of("done.building_restricted")); e.setCancelled(true); return; } @@ -1594,7 +1594,10 @@ public class PlayerEventListener implements Listener { BukkitPlayer pp = BukkitUtil.adapt(p); Plot plot = area.getPlot(location); if (plot == null) { - if (!Permissions.hasPermission(pp, Permission.PERMISSION_ADMIN_DESTROY_VEHICLE_ROAD)) { + if (!PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, VehicleBreakFlag.class, true) && !Permissions.hasPermission( + pp, + Permission.PERMISSION_ADMIN_DESTROY_VEHICLE_ROAD + )) { pp.sendMessage( TranslatableCaption.of("permission.no_permission_event"), Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_DESTROY_VEHICLE_ROAD)) @@ -1642,7 +1645,7 @@ public class PlayerEventListener implements Listener { } Plot plot = location.getOwnedPlot(); if (plot == null) { - if (area.isRoadFlags() && !area.getRoadFlag(ItemDropFlag.class)) { + if (PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, ItemDropFlag.class, false)) { event.setCancelled(true); } return; @@ -1668,7 +1671,7 @@ public class PlayerEventListener implements Listener { } Plot plot = location.getOwnedPlot(); if (plot == null) { - if (area.isRoadFlags() && area.getRoadFlag(DropProtectionFlag.class)) { + if (PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, DropProtectionFlag.class, true)) { event.setCancelled(true); } return; @@ -1690,17 +1693,15 @@ public class PlayerEventListener implements Listener { } Plot plot = location.getOwnedPlot(); if (plot == null) { - if (area.isRoadFlags() && area.getRoadFlag(KeepInventoryFlag.class)) { + if (PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, KeepInventoryFlag.class, true)) { event.setCancelled(true); } return; } if (plot.getFlag(KeepInventoryFlag.class)) { - if (plot.getFlag(KeepInventoryFlag.class)) { - plot.debug(event.getEntity().getName() + " kept their inventory because of keep-inventory = true"); - event.getDrops().clear(); - event.setKeepInventory(true); - } + plot.debug(event.getEntity().getName() + " kept their inventory because of keep-inventory = true"); + event.getDrops().clear(); + event.setKeepInventory(true); } } @@ -1725,16 +1726,14 @@ public class PlayerEventListener implements Listener { } Plot plot = location.getOwnedPlot(); if (plot == null) { - if (area.isRoadFlags() && area.getRoadFlag(DenyPortalTravelFlag.class)) { + if (PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, DenyPortalTravelFlag.class, true)) { event.setCancelled(true); } return; } if (plot.getFlag(DenyPortalTravelFlag.class)) { - if (plot.getFlag(DenyPortalTravelFlag.class)) { - plot.debug(event.getPlayer().getName() + " did not travel thru a portal because of deny-portal-travel = true"); - event.setCancelled(true); - } + plot.debug(event.getPlayer().getName() + " did not travel thru a portal because of deny-portal-travel = true"); + event.setCancelled(true); } } @@ -1772,7 +1771,7 @@ public class PlayerEventListener implements Listener { } Plot plot = location.getOwnedPlot(); if (plot == null) { - if (area.isRoadFlags() && area.getRoadFlag(DenyPortalsFlag.class)) { + if (PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, DenyPortalsFlag.class, true)) { event.setCancelled(true); return; } @@ -1801,16 +1800,14 @@ public class PlayerEventListener implements Listener { } Plot plot = location.getOwnedPlot(); if (plot == null) { - if (area.isRoadFlags() && area.getRoadFlag(LecternReadBookFlag.class)) { + if (PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, LecternReadBookFlag.class, true)) { event.setCancelled(true); } return; } if (plot.getFlag(LecternReadBookFlag.class)) { - if (plot.getFlag(LecternReadBookFlag.class)) { - plot.debug(event.getPlayer().getName() + " could not take the book because of lectern-read-book = true"); - event.setCancelled(true); - } + plot.debug(event.getPlayer().getName() + " could not take the book because of lectern-read-book = true"); + event.setCancelled(true); } } diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/ProjectileEventListener.java b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/ProjectileEventListener.java index 743649a80..2703c8cd9 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/ProjectileEventListener.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/ProjectileEventListener.java @@ -31,6 +31,7 @@ import com.plotsquared.core.plot.PlotHandler; import com.plotsquared.core.plot.flag.implementations.ProjectilesFlag; import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.util.Permissions; +import com.plotsquared.core.util.PlotFlagUtil; import net.kyori.adventure.text.minimessage.Template; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; @@ -97,14 +98,18 @@ public class ProjectileEventListener implements Listener { return; } Location location = BukkitUtil.adapt(entity.getLocation()); - if (!this.plotAreaManager.hasPlotArea(location.getWorldName())) { + PlotArea area = location.getPlotArea(); + if (area == null) { return; } PlotPlayer pp = BukkitUtil.adapt((Player) shooter); Plot plot = location.getOwnedPlot(); if (plot == null) { - if (!Permissions.hasPermission(pp, Permission.PERMISSION_ADMIN_PROJECTILE_ROAD)) { + if (!PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, ProjectilesFlag.class, true) && !Permissions.hasPermission( + pp, + Permission.PERMISSION_ADMIN_PROJECTILE_ROAD + )) { pp.sendMessage( TranslatableCaption.of("permission.no_permission_event"), Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_PROJECTILE_ROAD)) @@ -154,6 +159,8 @@ public class ProjectileEventListener implements Listener { if (plot.isAdded(((Player) shooter).getUniqueId()) || plot.getFlag(ProjectilesFlag.class)) { return; } + } else if (PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, ProjectilesFlag.class, true)) { + return; } entity.remove(); @@ -163,7 +170,10 @@ public class ProjectileEventListener implements Listener { PlotPlayer pp = BukkitUtil.adapt((Player) shooter); if (plot == null) { - if (!Permissions.hasPermission(pp, Permission.PERMISSION_ADMIN_PROJECTILE_UNOWNED)) { + if (!PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, ProjectilesFlag.class, true) && !Permissions.hasPermission( + pp, + Permission.PERMISSION_ADMIN_PROJECTILE_UNOWNED + )) { entity.remove(); event.setCancelled(true); } @@ -194,7 +204,6 @@ public class ProjectileEventListener implements Listener { if (sPlot == null || !PlotHandler.sameOwners(plot, sPlot)) { entity.remove(); event.setCancelled(true); - return; } } } diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/queue/GenChunk.java b/Bukkit/src/main/java/com/plotsquared/bukkit/queue/GenChunk.java index 44ec39545..558a86f51 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/queue/GenChunk.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/queue/GenChunk.java @@ -183,7 +183,11 @@ public class GenChunk extends ScopedQueueCoordinator { @Override public boolean setBlock(int x, int y, int z, @NonNull Pattern pattern) { - return setBlock(x, y, z, PatternUtil.apply(Preconditions.checkNotNull(pattern, "Pattern may not be null"), x, y, z)); + final BaseBlock block = PatternUtil.apply(Preconditions.checkNotNull( + pattern, + "Pattern may not be null" + ), x + (chunkX << 4), y, z + (chunkZ << 4)); + return setBlock(x, y, z, block); } @Override diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/queue/LimitedRegionWrapperQueue.java b/Bukkit/src/main/java/com/plotsquared/bukkit/queue/LimitedRegionWrapperQueue.java index d61372536..46161d4c4 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/queue/LimitedRegionWrapperQueue.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/queue/LimitedRegionWrapperQueue.java @@ -44,6 +44,7 @@ public class LimitedRegionWrapperQueue extends DelegateQueueCoordinator { private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + LimitedRegionWrapperQueue.class.getSimpleName()); private final LimitedRegion limitedRegion; + private boolean useOtherRestoreTagMethod = false; /** * @since 6.9.0 @@ -65,10 +66,18 @@ public class LimitedRegionWrapperQueue extends DelegateQueueCoordinator { CompoundTag tag = id.getNbtData(); StateWrapper sw = new StateWrapper(tag); try { - sw.restoreTag(limitedRegion.getBlockState(x, y, z).getBlock()); + if (useOtherRestoreTagMethod && getWorld() != null) { + sw.restoreTag(getWorld().getName(), x, y, z); + } else { + sw.restoreTag(limitedRegion.getBlockState(x, y, z).getBlock()); + } } catch (IllegalArgumentException e) { LOGGER.error("Error attempting to populate tile entity into the world at location {},{},{}", x, y, z, e); return false; + } catch (IllegalStateException e) { + useOtherRestoreTagMethod = true; + LOGGER.warn("IllegalStateException attempting to populate tile entity into the world at location {},{},{}. " + + "Possibly on <=1.17.1, switching to secondary method.", x, y, z, e); } } return result; diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/fawe/FaweRegionManager.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/fawe/FaweRegionManager.java index 1751710bb..0272a49e4 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/fawe/FaweRegionManager.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/fawe/FaweRegionManager.java @@ -36,8 +36,7 @@ import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.world.biome.BiomeType; import org.checkerframework.checker.nullness.qual.NonNull; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import org.checkerframework.checker.nullness.qual.Nullable; import java.util.Set; @@ -46,10 +45,7 @@ public class FaweRegionManager extends BukkitRegionManager { private final FaweDelegateRegionManager delegate = new FaweDelegateRegionManager(); @Inject - public FaweRegionManager( - @NonNull WorldUtil worldUtil, @NonNull GlobalBlockQueue blockQueue, @NonNull - ProgressSubscriberFactory subscriberFactory - ) { + public FaweRegionManager(WorldUtil worldUtil, GlobalBlockQueue blockQueue, ProgressSubscriberFactory subscriberFactory) { super(worldUtil, blockQueue, subscriberFactory); } @@ -76,9 +72,9 @@ public class FaweRegionManager extends BukkitRegionManager { @Override public boolean handleClear( - @NotNull Plot plot, + @NonNull Plot plot, @Nullable Runnable whenDone, - @NotNull PlotManager manager, + @NonNull PlotManager manager, final @Nullable PlotPlayer player ) { if (!Settings.FAWE_Components.CLEAR || !(manager instanceof HybridPlotManager)) { diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/fawe/FaweSchematicHandler.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/fawe/FaweSchematicHandler.java index 9b909439a..c1b2bbd7e 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/fawe/FaweSchematicHandler.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/fawe/FaweSchematicHandler.java @@ -29,7 +29,7 @@ import com.plotsquared.core.util.SchematicHandler; import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.task.RunnableVal; import com.sk89q.jnbt.CompoundTag; -import org.jetbrains.annotations.NotNull; +import org.checkerframework.checker.nullness.qual.NonNull; import java.io.InputStream; import java.net.URL; @@ -40,7 +40,7 @@ public class FaweSchematicHandler extends SchematicHandler { private final FaweDelegateSchematicHandler delegate = new FaweDelegateSchematicHandler(); @Inject - public FaweSchematicHandler(@NotNull WorldUtil worldUtil, @NotNull ProgressSubscriberFactory subscriberFactory) { + public FaweSchematicHandler(WorldUtil worldUtil, ProgressSubscriberFactory subscriberFactory) { super(worldUtil, subscriberFactory); } @@ -75,7 +75,7 @@ public class FaweSchematicHandler extends SchematicHandler { } @Override - public Schematic getSchematic(@NotNull InputStream is) { + public Schematic getSchematic(@NonNull InputStream is) { return delegate.getSchematic(is); } diff --git a/Core/src/main/java/com/plotsquared/core/PlotPlatform.java b/Core/src/main/java/com/plotsquared/core/PlotPlatform.java index 020c3c740..958468098 100644 --- a/Core/src/main/java/com/plotsquared/core/PlotPlatform.java +++ b/Core/src/main/java/com/plotsquared/core/PlotPlatform.java @@ -32,6 +32,7 @@ import com.plotsquared.core.inject.annotations.DefaultGenerator; import com.plotsquared.core.location.World; import com.plotsquared.core.permissions.PermissionHandler; import com.plotsquared.core.player.PlotPlayer; +import com.plotsquared.core.plot.expiration.ExpireManager; import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.queue.GlobalBlockQueue; import com.plotsquared.core.util.ChunkManager; @@ -284,6 +285,16 @@ public interface PlotPlatform

extends LocaleHolder { return injector().getInstance(ChunkManager.class); } + /** + * Get the {@link ExpireManager} implementation for the platform + * + * @return Expire manager + * @since 6.10.2 + */ + default @NonNull ExpireManager expireManager() { + return injector().getInstance(ExpireManager.class); + } + /** * Get the {@link PlotAreaManager} implementation. * diff --git a/Core/src/main/java/com/plotsquared/core/PlotSquared.java b/Core/src/main/java/com/plotsquared/core/PlotSquared.java index 5f89c69c1..76156fc21 100644 --- a/Core/src/main/java/com/plotsquared/core/PlotSquared.java +++ b/Core/src/main/java/com/plotsquared/core/PlotSquared.java @@ -290,11 +290,11 @@ public class PlotSquared { public void startExpiryTasks() { if (Settings.Enabled_Components.PLOT_EXPIRY) { - ExpireManager.IMP = new ExpireManager(this.eventDispatcher); - ExpireManager.IMP.runAutomatedTask(); + ExpireManager expireManager = PlotSquared.platform().expireManager(); + expireManager.runAutomatedTask(); for (Settings.Auto_Clear settings : Settings.AUTO_CLEAR.getInstances()) { ExpiryTask task = new ExpiryTask(settings, this.getPlotAreaManager()); - ExpireManager.IMP.addTask(task); + expireManager.addTask(task); } } } @@ -645,7 +645,8 @@ public class PlotSquared { } else { list = new ArrayList<>(input); } - list.sort(Comparator.comparingLong(a -> ExpireManager.IMP.getTimestamp(a.getOwnerAbs()))); + ExpireManager expireManager = PlotSquared.platform().expireManager(); + list.sort(Comparator.comparingLong(a -> expireManager.getTimestamp(a.getOwnerAbs()))); return list; } diff --git a/Core/src/main/java/com/plotsquared/core/command/DebugExec.java b/Core/src/main/java/com/plotsquared/core/command/DebugExec.java index 7290a544c..51e8ad8fe 100644 --- a/Core/src/main/java/com/plotsquared/core/command/DebugExec.java +++ b/Core/src/main/java/com/plotsquared/core/command/DebugExec.java @@ -19,6 +19,7 @@ package com.plotsquared.core.command; import com.google.inject.Inject; +import com.plotsquared.core.PlotSquared; import com.plotsquared.core.configuration.caption.StaticCaption; import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.events.PlotFlagRemoveEvent; @@ -139,10 +140,7 @@ public class DebugExec extends SubCommand { return true; } case "start-expire" -> { - if (ExpireManager.IMP == null) { - ExpireManager.IMP = new ExpireManager(this.eventDispatcher); - } - if (ExpireManager.IMP.runAutomatedTask()) { + if (PlotSquared.platform().expireManager().runAutomatedTask()) { player.sendMessage(TranslatableCaption.of("debugexec.expiry_started")); } else { player.sendMessage(TranslatableCaption.of("debugexec.expiry_already_started")); @@ -150,7 +148,7 @@ public class DebugExec extends SubCommand { return true; } case "stop-expire" -> { - if (ExpireManager.IMP == null || !ExpireManager.IMP.cancelTask()) { + if (!PlotSquared.platform().expireManager().cancelTask()) { player.sendMessage(TranslatableCaption.of("debugexec.task_halted")); } else { player.sendMessage(TranslatableCaption.of("debugexec.task_cancelled")); diff --git a/Core/src/main/java/com/plotsquared/core/command/Done.java b/Core/src/main/java/com/plotsquared/core/command/Done.java index 6537daeef..c50bdfce9 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Done.java +++ b/Core/src/main/java/com/plotsquared/core/command/Done.java @@ -19,6 +19,7 @@ package com.plotsquared.core.command; import com.google.inject.Inject; +import com.plotsquared.core.PlotSquared; import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.events.PlotDoneEvent; @@ -29,7 +30,6 @@ import com.plotsquared.core.location.Location; import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.Plot; -import com.plotsquared.core.plot.expiration.ExpireManager; import com.plotsquared.core.plot.expiration.PlotAnalysis; import com.plotsquared.core.plot.flag.PlotFlag; import com.plotsquared.core.plot.flag.implementations.DoneFlag; @@ -94,7 +94,7 @@ public class Done extends SubCommand { Template.of("plot", plot.getId().toString()) ); final Settings.Auto_Clear doneRequirements = Settings.AUTO_CLEAR.get("done"); - if (ExpireManager.IMP == null || doneRequirements == null) { + if (PlotSquared.platform().expireManager() == null || doneRequirements == null) { finish(plot, player, true); plot.removeRunning(); } else { diff --git a/Core/src/main/java/com/plotsquared/core/command/ListCmd.java b/Core/src/main/java/com/plotsquared/core/command/ListCmd.java index b47a99e25..fcb161926 100644 --- a/Core/src/main/java/com/plotsquared/core/command/ListCmd.java +++ b/Core/src/main/java/com/plotsquared/core/command/ListCmd.java @@ -30,7 +30,6 @@ import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.PlotArea; -import com.plotsquared.core.plot.expiration.ExpireManager; import com.plotsquared.core.plot.flag.implementations.DoneFlag; import com.plotsquared.core.plot.flag.implementations.PriceFlag; import com.plotsquared.core.plot.flag.implementations.ServerPlotFlag; @@ -240,7 +239,7 @@ public class ListCmd extends SubCommand { ); return false; } - if (ExpireManager.IMP == null) { + if (PlotSquared.platform().expireManager() == null) { plotConsumer.accept(PlotQuery.newQuery().noPlots()); } else { plotConsumer.accept(PlotQuery.newQuery().expiredPlots()); diff --git a/Core/src/main/java/com/plotsquared/core/command/Merge.java b/Core/src/main/java/com/plotsquared/core/command/Merge.java index 8c9976197..6da21063b 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Merge.java +++ b/Core/src/main/java/com/plotsquared/core/command/Merge.java @@ -282,7 +282,28 @@ public class Merge extends SubCommand { run.run(); } } - if (!force && !isOnline) { + if (force || !isOnline) { + if (force || Permissions.hasPermission(player, Permission.PERMISSION_ADMIN_COMMAND_MERGE_OTHER_OFFLINE)) { + if (plot.getPlotModificationManager().autoMerge(direction, maxSize - size, uuids.iterator().next(), player, terrain)) { + if (this.econHandler.isEnabled(plotArea) && price > 0d) { + if (!force && this.econHandler.getMoney(player) < price) { + player.sendMessage( + TranslatableCaption.of("economy.cannot_afford_merge"), + Template.of("money", this.econHandler.format(price)) + ); + return false; + } + this.econHandler.withdrawMoney(player, price); + player.sendMessage( + TranslatableCaption.of("economy.removed_balance"), + Template.of("money", this.econHandler.format(price)) + ); + } + player.sendMessage(TranslatableCaption.of("merge.success_merge")); + eventDispatcher.callPostMerge(player, plot); + return true; + } + } player.sendMessage(TranslatableCaption.of("merge.no_available_automerge")); return false; } diff --git a/Core/src/main/java/com/plotsquared/core/command/Trim.java b/Core/src/main/java/com/plotsquared/core/command/Trim.java index 09a5ff925..ca4603bd3 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Trim.java +++ b/Core/src/main/java/com/plotsquared/core/command/Trim.java @@ -25,7 +25,6 @@ import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.location.Location; import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.Plot; -import com.plotsquared.core.plot.expiration.ExpireManager; import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.queue.GlobalBlockQueue; import com.plotsquared.core.queue.QueueCoordinator; @@ -92,8 +91,8 @@ public class Trim extends SubCommand { } TranslatableCaption.of("trim.trim_starting"); final List plots = PlotQuery.newQuery().inWorld(world).asList(); - if (ExpireManager.IMP != null) { - plots.removeAll(ExpireManager.IMP.getPendingExpired()); + if (PlotSquared.platform().expireManager() != null) { + plots.removeAll(PlotSquared.platform().expireManager().getPendingExpired()); } result.value1 = new HashSet<>(PlotSquared.platform().worldUtil().getChunkChunks(world)); result.value2 = new HashSet<>(); diff --git a/Core/src/main/java/com/plotsquared/core/configuration/Settings.java b/Core/src/main/java/com/plotsquared/core/configuration/Settings.java index 4e5ac9bc5..025c779ee 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/Settings.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/Settings.java @@ -759,6 +759,8 @@ public class Settings extends Config { @Comment("Also kill any road mobs that are being ridden, or are leashed") public static boolean KILL_OWNED_ROAD_MOBS = false; + @Comment("Also kill any road mobs that are named") + public static boolean KILL_NAMED_ROAD_MOBS = false; @Comment("Kill items on roads (Stick, Paper, etc.)") public static boolean KILL_ROAD_ITEMS = false; @Comment("Kill vehicles on roads (Boat, Minecart, etc.)") diff --git a/Core/src/main/java/com/plotsquared/core/configuration/caption/ClickStripTransform.java b/Core/src/main/java/com/plotsquared/core/configuration/caption/ClickStripTransform.java index 470f1b914..2ebdf2c87 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/caption/ClickStripTransform.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/caption/ClickStripTransform.java @@ -21,16 +21,15 @@ package com.plotsquared.core.configuration.caption; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.event.ClickEvent; import org.checkerframework.checker.nullness.qual.NonNull; -import org.jetbrains.annotations.NotNull; import java.util.EnumSet; import java.util.Set; final class ClickStripTransform implements ComponentTransform { - private final Set actionsToStrip; + private final Set actionsToStrip; - public ClickStripTransform(final Set actionsToStrip) { + public ClickStripTransform(final Set actionsToStrip) { this.actionsToStrip = EnumSet.copyOf(actionsToStrip); } diff --git a/Core/src/main/java/com/plotsquared/core/configuration/caption/load/ClassLoaderCaptionProvider.java b/Core/src/main/java/com/plotsquared/core/configuration/caption/load/ClassLoaderCaptionProvider.java index 53fb35473..14b4cd624 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/caption/load/ClassLoaderCaptionProvider.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/caption/load/ClassLoaderCaptionProvider.java @@ -53,7 +53,10 @@ final class ClassLoaderCaptionProvider implements DefaultCaptionProvider { try { final InputStream stream = this.classLoader.getResourceAsStream(url); if (stream == null) { - LOGGER.warn("No resource for locale '{}' found", locale); + LOGGER.info("No resource for locale '{}' found in the plugin file." + + "Please ensure you have placed the latest version of the file messages_{}.json in the 'lang' folder." + + "You may be able to find completed translations at https://intellectualsites.crowdin.com/plotsquared", + locale, locale); return null; } try (final BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) { diff --git a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotManager.java b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotManager.java index af155b971..ffbfc5de2 100644 --- a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotManager.java +++ b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotManager.java @@ -174,8 +174,9 @@ public class HybridPlotManager extends ClassicPlotManager { for (int y = 0; y < blocks.length; y++) { if (blocks[y] != null) { queue.setBlock(x, minY + y, z, blocks[y]); - } else { + } else if (!isRoad) { // This is necessary, otherwise any blocks not specified in the schematic will remain after a clear + // Do not set air for road as this may cause cavernous roads when debugroadregen is used queue.setBlock(x, minY + y, z, airBlock); } } diff --git a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java index 5fb6ad868..532cc691a 100644 --- a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java +++ b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java @@ -21,7 +21,6 @@ package com.plotsquared.core.generator; import com.google.inject.Inject; import com.google.inject.assistedinject.Assisted; import com.intellectualsites.annotations.DoNotUse; -import com.intellectualsites.annotations.NotPublic; import com.plotsquared.core.PlotSquared; import com.plotsquared.core.configuration.ConfigurationSection; import com.plotsquared.core.configuration.Settings; @@ -75,6 +74,9 @@ public class HybridPlotWorld extends ClassicPlotWorld { public short PATH_WIDTH_UPPER; public HashMap G_SCH; public HashMap G_SCH_B; + /** + * The Y level at which schematic generation will start, lowest of either road or plot schematic generation. + */ public int SCHEM_Y; private Location SIGN_LOCATION; private File root = null; @@ -91,10 +93,10 @@ public class HybridPlotWorld extends ClassicPlotWorld { @Inject public HybridPlotWorld( @Assisted("world") final String worldName, - @Nullable @Assisted("id") final String id, + @javax.annotation.Nullable @Assisted("id") final String id, @Assisted final @NonNull IndependentPlotGenerator generator, - @Nullable @Assisted("min") final PlotId min, - @Nullable @Assisted("max") final PlotId max, + @javax.annotation.Nullable @Assisted("min") final PlotId min, + @javax.annotation.Nullable @Assisted("max") final PlotId max, @WorldConfig final @NonNull YamlConfiguration worldConfiguration, final @NonNull GlobalBlockQueue blockQueue ) { @@ -267,34 +269,67 @@ public class HybridPlotWorld extends ClassicPlotWorld { int oddshift = (this.ROAD_WIDTH & 1); SCHEM_Y = schematicStartHeight(); + + // plotY and roadY are important to allow plot and/or road schematic "overflow" into each other without causing AIOOB + // exceptions when attempting either to set blocks to, or get block from G_SCH + // Default plot schematic start height, normalized to the minimum height schematics are pasted from. int plotY = PLOT_HEIGHT - SCHEM_Y; int minRoadWall = Settings.Schematics.USE_WALL_IN_ROAD_SCHEM_HEIGHT ? Math.min(ROAD_HEIGHT, WALL_HEIGHT) : ROAD_HEIGHT; + // Default road schematic start height, normalized to the minimum height schematics are pasted from. int roadY = minRoadWall - SCHEM_Y; - int worldHeight = getMaxGenHeight() - getMinGenHeight() + 1; + int worldGenHeight = getMaxGenHeight() - getMinGenHeight() + 1; + + int maxSchematicHeight = 0; + int plotSchemHeight = 0; // SCHEM_Y should be normalised to the plot "start" height if (schematic3 != null) { - if (schematic3.getClipboard().getDimensions().getY() == worldHeight) { - SCHEM_Y = plotY = 0; + plotSchemHeight = maxSchematicHeight = schematic3.getClipboard().getDimensions().getY(); + if (maxSchematicHeight == worldGenHeight) { + SCHEM_Y = getMinGenHeight(); + plotY = 0; } else if (!Settings.Schematics.PASTE_ON_TOP) { - SCHEM_Y = plotY = getMinBuildHeight() - getMinGenHeight(); + SCHEM_Y = getMinBuildHeight(); + plotY = 0; } } + int roadSchemHeight; + if (schematic1 != null) { - if (schematic1.getClipboard().getDimensions().getY() == worldHeight) { - SCHEM_Y = roadY = getMinGenHeight(); - if (schematic3 != null && schematic3.getClipboard().getDimensions().getY() != worldHeight - && !Settings.Schematics.PASTE_ON_TOP) { - plotY = PLOT_HEIGHT; + roadSchemHeight = Math.max( + schematic1.getClipboard().getDimensions().getY(), + schematic2.getClipboard().getDimensions().getY() + ); + maxSchematicHeight = Math.max(roadSchemHeight, maxSchematicHeight); + if (maxSchematicHeight == worldGenHeight) { + SCHEM_Y = getMinGenHeight(); + roadY = 0; // Road is the lowest schematic + if (schematic3 != null && schematic3.getClipboard().getDimensions().getY() != worldGenHeight) { + // Road is the lowest schematic. Normalize plotY to it. + if (Settings.Schematics.PASTE_ON_TOP) { + plotY = PLOT_HEIGHT - getMinGenHeight(); + } else { + plotY = getMinBuildHeight() - getMinGenHeight(); + } } } else if (!Settings.Schematics.PASTE_ROAD_ON_TOP) { - SCHEM_Y = roadY = getMinBuildHeight(); - if (schematic3 != null && schematic3.getClipboard().getDimensions().getY() != worldHeight - && !Settings.Schematics.PASTE_ON_TOP) { - plotY = PLOT_HEIGHT; + if (SCHEM_Y == getMinGenHeight()) { // Only possible if plot schematic is enabled + // Plot is still the lowest schematic, normalize roadY to it + roadY = getMinBuildHeight() - getMinGenHeight(); + } else if (schematic3 != null) { + SCHEM_Y = getMinBuildHeight(); + roadY = 0;// Road is the lowest schematic + if (Settings.Schematics.PASTE_ON_TOP) { + // Road is the lowest schematic. Normalize plotY to it. + plotY = PLOT_HEIGHT - getMinBuildHeight(); + } + maxSchematicHeight = Math.max(maxSchematicHeight, plotY + plotSchemHeight); } + } else { + roadY = minRoadWall - SCHEM_Y; + maxSchematicHeight = Math.max(maxSchematicHeight, roadY + roadSchemHeight); } } @@ -331,17 +366,15 @@ public class HybridPlotWorld extends ClassicPlotWorld { y + min.getBlockY(), z + min.getBlockZ() )); - if (!id.getBlockType().getMaterial().isAir()) { - schem3PopulationNeeded |= id.hasNbtData(); - addOverlayBlock( - (short) (x + shift + oddshift + centerShiftX), - (short) (y + plotY), - (short) (z + shift + oddshift + centerShiftZ), - id, - false, - h3 - ); - } + schem3PopulationNeeded |= id.hasNbtData(); + addOverlayBlock( + (short) (x + shift + oddshift + centerShiftX), + (short) (y + plotY), + (short) (z + shift + oddshift + centerShiftZ), + id, + false, + maxSchematicHeight + ); } if (blockArrayClipboard3.hasBiomes()) { BiomeType biome = blockArrayClipboard3.getBiome(BlockVector2.at( @@ -391,18 +424,23 @@ public class HybridPlotWorld extends ClassicPlotWorld { y + min.getBlockY(), z + min.getBlockZ() )); - if (!id.getBlockType().getMaterial().isAir()) { - schem1PopulationNeeded |= id.hasNbtData(); - addOverlayBlock((short) (x - shift), (short) (y + roadY), (short) (z + shift + oddshift), id, false, h1); - addOverlayBlock( - (short) (z + shift + oddshift), - (short) (y + roadY), - (short) (shift - x + (oddshift - 1)), - id, - true, - h1 - ); - } + schem1PopulationNeeded |= id.hasNbtData(); + addOverlayBlock( + (short) (x - shift), + (short) (y + roadY), + (short) (z + shift + oddshift), + id, + false, + maxSchematicHeight + ); + addOverlayBlock( + (short) (z + shift + oddshift), + (short) (y + roadY), + (short) (shift - x + (oddshift - 1)), + id, + true, + maxSchematicHeight + ); } if (blockArrayClipboard1.hasBiomes()) { BiomeType biome = blockArrayClipboard1.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ())); @@ -430,10 +468,15 @@ public class HybridPlotWorld extends ClassicPlotWorld { y + min.getBlockY(), z + min.getBlockZ() )); - if (!id.getBlockType().getMaterial().isAir()) { - schem2PopulationNeeded |= id.hasNbtData(); - addOverlayBlock((short) (x - shift), (short) (y + roadY), (short) (z - shift), id, false, h2); - } + schem2PopulationNeeded |= id.hasNbtData(); + addOverlayBlock( + (short) (x - shift), + (short) (y + roadY), + (short) (z - shift), + id, + false, + maxSchematicHeight + ); } if (blockArrayClipboard2.hasBiomes()) { BiomeType biome = blockArrayClipboard2.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ())); @@ -443,6 +486,10 @@ public class HybridPlotWorld extends ClassicPlotWorld { } } + /** + * @deprecated This method should not be available for public API usage and will be made private. + */ + @Deprecated(forRemoval = true, since = "6.10.2") public void addOverlayBlock(short x, short y, short z, BaseBlock id, boolean rotate, int height) { if (z < 0) { z += this.SIZE; @@ -462,13 +509,22 @@ public class HybridPlotWorld extends ClassicPlotWorld { if (y >= height) { if (y > lastOverlayHeightError) { lastOverlayHeightError = y; - LOGGER.error(String.format("Error adding overlay block. `y > height`. y=%s, height=%s", y, height)); + LOGGER.error( + "Error adding overlay block in world {}. `y > height`. y={}, height={}", + getWorldName(), + y, + height + ); } return; } existing[y] = id; } + /** + * @deprecated This method should not be available for public API usage and will be made private. + */ + @Deprecated(forRemoval = true, since = "6.10.2") public void addOverlayBiome(short x, short z, BiomeType id) { if (z < 0) { z += this.SIZE; diff --git a/Core/src/main/java/com/plotsquared/core/generator/HybridUtils.java b/Core/src/main/java/com/plotsquared/core/generator/HybridUtils.java index cc00345bd..0def7d9cb 100644 --- a/Core/src/main/java/com/plotsquared/core/generator/HybridUtils.java +++ b/Core/src/main/java/com/plotsquared/core/generator/HybridUtils.java @@ -234,44 +234,52 @@ public class HybridUtils { Set types = new HashSet<>(); for (int yIndex = 0; yIndex < height; yIndex++) { BlockState old = oldBlocks[yIndex][x][z]; // Nullable - try { - BlockState now = newBlocks[yIndex][x][z]; // Not null - if (!now.equals(old) && !(old == null && now.getBlockType().equals(BlockTypes.AIR))) { - changes[i]++; - } - if (now.getBlockType().getMaterial().isAir()) { - air[i]++; - } else { - // check vertices - // modifications_adjacent - if (x > 0 && z > 0 && yIndex > 0 && x < width - 1 && z < length - 1 && yIndex < (height - 1)) { - if (newBlocks[yIndex - 1][x][z].getBlockType().getMaterial().isAir()) { - faces[i]++; - } - if (newBlocks[yIndex][x - 1][z].getBlockType().getMaterial().isAir()) { - faces[i]++; - } - if (newBlocks[yIndex][x][z - 1].getBlockType().getMaterial().isAir()) { - faces[i]++; - } - if (newBlocks[yIndex + 1][x][z].getBlockType().getMaterial().isAir()) { - faces[i]++; - } - if (newBlocks[yIndex][x + 1][z].getBlockType().getMaterial().isAir()) { - faces[i]++; - } - if (newBlocks[yIndex][x][z + 1].getBlockType().getMaterial().isAir()) { - faces[i]++; - } + BlockState now = newBlocks[yIndex][x][z]; // Not null + if (now == null) { + throw new NullPointerException(String.format( + "\"now\" block null attempting to perform plot analysis. Indexes: x=%d of %d, yIndex=%d" + + " of %d, z=%d of %d", + x, + width, + yIndex, + height, + z, + length + )); + } + if (!now.equals(old) && !(old == null && now.getBlockType().equals(BlockTypes.AIR))) { + changes[i]++; + } + if (now.getBlockType().getMaterial().isAir()) { + air[i]++; + } else { + // check vertices + // modifications_adjacent + if (x > 0 && z > 0 && yIndex > 0 && x < width - 1 && z < length - 1 && yIndex < (height - 1)) { + if (newBlocks[yIndex - 1][x][z].getBlockType().getMaterial().isAir()) { + faces[i]++; } + if (newBlocks[yIndex][x - 1][z].getBlockType().getMaterial().isAir()) { + faces[i]++; + } + if (newBlocks[yIndex][x][z - 1].getBlockType().getMaterial().isAir()) { + faces[i]++; + } + if (newBlocks[yIndex + 1][x][z].getBlockType().getMaterial().isAir()) { + faces[i]++; + } + if (newBlocks[yIndex][x + 1][z].getBlockType().getMaterial().isAir()) { + faces[i]++; + } + if (newBlocks[yIndex][x][z + 1].getBlockType().getMaterial().isAir()) { + faces[i]++; + } + } - if (!now.equals(now.getBlockType().getDefaultState())) { - data[i]++; - } - types.add(now.getBlockType()); + if (!now.equals(now.getBlockType().getDefaultState())) { + data[i]++; } - } catch (NullPointerException e) { - e.printStackTrace(); + types.add(now.getBlockType()); } } variety[i] = types.size(); diff --git a/Core/src/main/java/com/plotsquared/core/listener/PlotListener.java b/Core/src/main/java/com/plotsquared/core/listener/PlotListener.java index 6c837a2c6..0550d65eb 100644 --- a/Core/src/main/java/com/plotsquared/core/listener/PlotListener.java +++ b/Core/src/main/java/com/plotsquared/core/listener/PlotListener.java @@ -36,7 +36,6 @@ import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotTitle; import com.plotsquared.core.plot.PlotWeather; import com.plotsquared.core.plot.comment.CommentManager; -import com.plotsquared.core.plot.expiration.ExpireManager; import com.plotsquared.core.plot.flag.GlobalFlagContainer; import com.plotsquared.core.plot.flag.PlotFlag; import com.plotsquared.core.plot.flag.implementations.DenyExitFlag; @@ -163,8 +162,8 @@ public class PlotListener { if ((last != null) && !last.getId().equals(plot.getId())) { plotExit(player, last); } - if (ExpireManager.IMP != null) { - ExpireManager.IMP.handleEntry(player, plot); + if (PlotSquared.platform().expireManager() != null) { + PlotSquared.platform().expireManager().handleEntry(player, plot); } lastPlot.set(plot); } diff --git a/Core/src/main/java/com/plotsquared/core/permissions/Permission.java b/Core/src/main/java/com/plotsquared/core/permissions/Permission.java index ffd8f3d5a..8899f233d 100644 --- a/Core/src/main/java/com/plotsquared/core/permissions/Permission.java +++ b/Core/src/main/java/com/plotsquared/core/permissions/Permission.java @@ -162,6 +162,7 @@ public enum Permission { PERMISSION_LIST_AREA("plots.list.area"), PERMISSION_ADMIN_COMMAND_LOAD("plots.admin.command.load"), PERMISSION_ADMIN_COMMAND_MERGE("plots.admin.command.merge"), + PERMISSION_ADMIN_COMMAND_MERGE_OTHER_OFFLINE("plots.admin.command.merge.other.offline"), PERMISSION_ADMIN_COMMAND_SET_OWNER("plots.admin.command.setowner"), PERMISSION_COMMENT("plots.comment"), PERMISSION_INBOX("plots.inbox"), diff --git a/Core/src/main/java/com/plotsquared/core/player/PlotPlayer.java b/Core/src/main/java/com/plotsquared/core/player/PlotPlayer.java index 3594f5727..f0d5cdfc3 100644 --- a/Core/src/main/java/com/plotsquared/core/player/PlotPlayer.java +++ b/Core/src/main/java/com/plotsquared/core/player/PlotPlayer.java @@ -42,7 +42,6 @@ import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotCluster; import com.plotsquared.core.plot.PlotId; import com.plotsquared.core.plot.PlotWeather; -import com.plotsquared.core.plot.expiration.ExpireManager; import com.plotsquared.core.plot.flag.implementations.DoneFlag; import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.plot.world.SinglePlotArea; @@ -618,8 +617,8 @@ public abstract class PlotPlayer

implements CommandCaller, OfflinePlotPlayer, LOGGER.info("Plot {} was deleted + cleared due to {} getting banned", owned.getId(), getName()); } } - if (ExpireManager.IMP != null) { - ExpireManager.IMP.storeDate(getUUID(), System.currentTimeMillis()); + if (PlotSquared.platform().expireManager() != null) { + PlotSquared.platform().expireManager().storeDate(getUUID(), System.currentTimeMillis()); } PlotSquared.platform().playerManager().removePlayer(this); PlotSquared.platform().unregister(this); diff --git a/Core/src/main/java/com/plotsquared/core/plot/Plot.java b/Core/src/main/java/com/plotsquared/core/plot/Plot.java index 757f89012..098b95656 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/Plot.java +++ b/Core/src/main/java/com/plotsquared/core/plot/Plot.java @@ -40,7 +40,6 @@ import com.plotsquared.core.location.Location; import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.player.ConsolePlayer; import com.plotsquared.core.player.PlotPlayer; -import com.plotsquared.core.plot.expiration.ExpireManager; import com.plotsquared.core.plot.expiration.PlotAnalysis; import com.plotsquared.core.plot.flag.FlagContainer; import com.plotsquared.core.plot.flag.GlobalFlagContainer; @@ -1105,8 +1104,8 @@ public class Plot { * @return A boolean indicating whether or not the operation succeeded */ public boolean setFlag(final @NonNull PlotFlag flag) { - if (flag instanceof KeepFlag && ExpireManager.IMP != null) { - ExpireManager.IMP.updateExpired(this); + if (flag instanceof KeepFlag && PlotSquared.platform().expireManager() != null) { + PlotSquared.platform().expireManager().updateExpired(this); } for (final Plot plot : this.getConnectedPlots()) { plot.getFlagContainer().addFlag(flag); @@ -2831,11 +2830,11 @@ public class Plot { Component members = PlayerManager.getPlayerList(this.getMembers(), player); Component denied = PlayerManager.getPlayerList(this.getDenied(), player); String seen; - if (Settings.Enabled_Components.PLOT_EXPIRY && ExpireManager.IMP != null) { + if (Settings.Enabled_Components.PLOT_EXPIRY && PlotSquared.platform().expireManager() != null) { if (this.isOnline()) { seen = TranslatableCaption.of("info.now").getComponent(player); } else { - int time = (int) (ExpireManager.IMP.getAge(this, false) / 1000); + int time = (int) (PlotSquared.platform().expireManager().getAge(this, false) / 1000); if (time != 0) { seen = TimeUtil.secToTime(time); } else { diff --git a/Core/src/main/java/com/plotsquared/core/plot/PlotId.java b/Core/src/main/java/com/plotsquared/core/plot/PlotId.java index 4d0bb8fb7..62077ccb9 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/PlotId.java +++ b/Core/src/main/java/com/plotsquared/core/plot/PlotId.java @@ -112,7 +112,7 @@ public final class PlotId { * @return Plot ID copy * @deprecated PlotId is immutable, copy is not required. */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "6.10.2") public @NonNull PlotId copy() { return this; } diff --git a/Core/src/main/java/com/plotsquared/core/plot/PlotTitle.java b/Core/src/main/java/com/plotsquared/core/plot/PlotTitle.java index 58ec05999..fe4302d0b 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/PlotTitle.java +++ b/Core/src/main/java/com/plotsquared/core/plot/PlotTitle.java @@ -18,7 +18,8 @@ */ package com.plotsquared.core.plot; -import javax.annotation.Nullable; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.Objects; public class PlotTitle { diff --git a/Core/src/main/java/com/plotsquared/core/plot/expiration/ExpireManager.java b/Core/src/main/java/com/plotsquared/core/plot/expiration/ExpireManager.java index d8d565de9..0863112f8 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/expiration/ExpireManager.java +++ b/Core/src/main/java/com/plotsquared/core/plot/expiration/ExpireManager.java @@ -18,6 +18,8 @@ */ package com.plotsquared.core.plot.expiration; +import com.google.inject.Inject; +import com.plotsquared.core.PlotPlatform; import com.plotsquared.core.PlotSquared; import com.plotsquared.core.configuration.caption.Caption; import com.plotsquared.core.configuration.caption.Templates; @@ -60,6 +62,10 @@ import java.util.concurrent.ConcurrentLinkedDeque; public class ExpireManager { + /** + * @deprecated Use {@link PlotPlatform#expireManager()} instead + */ + @Deprecated(forRemoval = true, since = "6.10.2") public static ExpireManager IMP; private final ConcurrentHashMap dates_cache; private final ConcurrentHashMap account_age_cache; @@ -71,6 +77,7 @@ public class ExpireManager { */ private int running; + @Inject public ExpireManager(final @NonNull EventDispatcher eventDispatcher) { this.tasks = new ArrayDeque<>(); this.dates_cache = new ConcurrentHashMap<>(); diff --git a/Core/src/main/java/com/plotsquared/core/plot/expiration/ExpiryTask.java b/Core/src/main/java/com/plotsquared/core/plot/expiration/ExpiryTask.java index b1205d6da..e65ed1aaf 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/expiration/ExpiryTask.java +++ b/Core/src/main/java/com/plotsquared/core/plot/expiration/ExpiryTask.java @@ -18,6 +18,7 @@ */ package com.plotsquared.core.plot.expiration; +import com.plotsquared.core.PlotSquared; import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.PlotArea; @@ -72,8 +73,9 @@ public class ExpiryTask { min = false; diff = plots.size() - settings.REQUIRED_PLOTS; } + ExpireManager expireManager = PlotSquared.platform().expireManager(); List entireList = - plots.stream().map(plot -> ExpireManager.IMP.getAge(plot, settings.DELETE_IF_OWNER_IS_UNKNOWN)) + plots.stream().map(plot -> expireManager.getAge(plot, settings.DELETE_IF_OWNER_IS_UNKNOWN)) .collect(Collectors.toList()); List top = new ArrayList<>(diff + 1); if (diff > 1000) { diff --git a/Core/src/main/java/com/plotsquared/core/queue/BlockArrayCacheScopedQueueCoordinator.java b/Core/src/main/java/com/plotsquared/core/queue/BlockArrayCacheScopedQueueCoordinator.java index 243f5637f..c26d8ff16 100644 --- a/Core/src/main/java/com/plotsquared/core/queue/BlockArrayCacheScopedQueueCoordinator.java +++ b/Core/src/main/java/com/plotsquared/core/queue/BlockArrayCacheScopedQueueCoordinator.java @@ -116,7 +116,7 @@ public class BlockArrayCacheScopedQueueCoordinator extends ScopedQueueCoordinato x += offsetX; z += offsetZ; if (x >= scopeMinX && x < scopeMaxX && y >= minY && y <= maxY && z >= scopeMinZ && z < scopeMaxZ) { - blockStates[y - minY][x][z] = id.toImmutableState(); + blockStates[y - minY][x - scopeMinX][z - scopeMinZ] = id.toImmutableState(); } return false; } 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 e91c7b35b..b2d858b4d 100644 --- a/Core/src/main/java/com/plotsquared/core/util/EventDispatcher.java +++ b/Core/src/main/java/com/plotsquared/core/util/EventDispatcher.java @@ -20,6 +20,7 @@ package com.plotsquared.core.util; import com.google.common.eventbus.EventBus; import com.intellectualsites.annotations.DoNotUse; +import com.plotsquared.core.PlotSquared; import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.events.PlayerAutoPlotEvent; @@ -59,7 +60,6 @@ import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotId; import com.plotsquared.core.plot.Rating; -import com.plotsquared.core.plot.expiration.ExpireManager; import com.plotsquared.core.plot.flag.PlotFlag; import com.plotsquared.core.plot.flag.implementations.DeviceInteractFlag; import com.plotsquared.core.plot.flag.implementations.MiscPlaceFlag; @@ -300,8 +300,8 @@ public class EventDispatcher { if (player == null) { return; //possible future warning message to figure out where we are retrieving null } - if (ExpireManager.IMP != null) { - ExpireManager.IMP.handleJoin(player); + if (PlotSquared.platform().expireManager() != null) { + PlotSquared.platform().expireManager().handleJoin(player); } if (this.worldEdit != null) { if (player.getAttribute("worldedit")) { diff --git a/Core/src/main/java/com/plotsquared/core/util/PatternUtil.java b/Core/src/main/java/com/plotsquared/core/util/PatternUtil.java index 26100f811..e90ac3595 100644 --- a/Core/src/main/java/com/plotsquared/core/util/PatternUtil.java +++ b/Core/src/main/java/com/plotsquared/core/util/PatternUtil.java @@ -29,7 +29,6 @@ import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.function.pattern.BlockPattern; import com.sk89q.worldedit.function.pattern.Pattern; -import com.sk89q.worldedit.function.pattern.RandomPattern; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; @@ -44,7 +43,7 @@ public class PatternUtil { public static BaseBlock apply(@NonNull Pattern pattern, int x, int y, int z) { Preconditions.checkNotNull(pattern, "Pattern may not be null"); - if (pattern instanceof BlockPattern || pattern instanceof RandomPattern + if (pattern instanceof BlockPattern || pattern instanceof BlockState || pattern instanceof BlockType || pattern instanceof BaseBlock) { return pattern.applyBlock(BlockVector3.ZERO); diff --git a/Core/src/main/java/com/plotsquared/core/util/PlotFlagUtil.java b/Core/src/main/java/com/plotsquared/core/util/PlotFlagUtil.java new file mode 100644 index 000000000..d66339336 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/PlotFlagUtil.java @@ -0,0 +1,53 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * 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 . + */ +package com.plotsquared.core.util; + +import com.plotsquared.core.plot.PlotArea; +import com.plotsquared.core.plot.flag.PlotFlag; + +import java.util.Objects; + +/** + * Util class for generic methods relating to plot flags. + * + * @since 6.10.4 + */ +public final class PlotFlagUtil { + + private PlotFlagUtil() { + //No-op + } + + /** + * Check if the value of a {@link PlotFlag} matches the given value. If + * road flags are disabled for the given plot area, returns false. + * + * @param flagClass boolean flag to get value of + * @param value boolean value to check flag value against + * @param The flag value type + * @return true if road flag value matches with road flags enabled + * @since 6.10.4 + */ + public static boolean isAreaRoadFlagsAndFlagEquals( + PlotArea area, final Class> flagClass, T value + ) { + return area.isRoadFlags() && Objects.equals(area.getRoadFlag(flagClass), value); + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/util/StringMan.java b/Core/src/main/java/com/plotsquared/core/util/StringMan.java index 8fb2f2940..32a594ea2 100644 --- a/Core/src/main/java/com/plotsquared/core/util/StringMan.java +++ b/Core/src/main/java/com/plotsquared/core/util/StringMan.java @@ -36,7 +36,8 @@ import java.util.regex.Pattern; public class StringMan { - private static final Pattern STRING_SPLIT_PATTERN = Pattern.compile("(?\"[\\w ]+\")|(?\\w+)"); + // Stolen from https://stackoverflow.com/a/366532/12620913 | Debug: https://regex101.com/r/DudJLb/1 + private static final Pattern STRING_SPLIT_PATTERN = Pattern.compile("[^\\s\"]+|\"([^\"]*)\""); public static String replaceFromMap(String string, Map replacements) { StringBuilder sb = new StringBuilder(string); @@ -355,7 +356,7 @@ public class StringMan { var matcher = StringMan.STRING_SPLIT_PATTERN.matcher(message); List splitMessages = new ArrayList<>(); while (matcher.find()) { - splitMessages.add(matcher.group(0).replaceAll("\"", "")); + splitMessages.add(matcher.group(matcher.groupCount() - 1).replaceAll("\"", "")); } return splitMessages; } diff --git a/Core/src/main/java/com/plotsquared/core/util/query/ExpiredPlotProvider.java b/Core/src/main/java/com/plotsquared/core/util/query/ExpiredPlotProvider.java index 622983e13..1fac18f2c 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/ExpiredPlotProvider.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/ExpiredPlotProvider.java @@ -18,8 +18,8 @@ */ package com.plotsquared.core.util.query; +import com.plotsquared.core.PlotSquared; import com.plotsquared.core.plot.Plot; -import com.plotsquared.core.plot.expiration.ExpireManager; import java.util.Collection; @@ -27,7 +27,7 @@ class ExpiredPlotProvider implements PlotProvider { @Override public Collection getPlots() { - return ExpireManager.IMP.getPendingExpired(); + return PlotSquared.platform().expireManager().getPendingExpired(); } } diff --git a/Core/src/test/java/com/plotsquared/core/plot/FlagTest.java b/Core/src/test/java/com/plotsquared/core/plot/FlagTest.java index d1a7b2797..9b02f34da 100644 --- a/Core/src/test/java/com/plotsquared/core/plot/FlagTest.java +++ b/Core/src/test/java/com/plotsquared/core/plot/FlagTest.java @@ -101,7 +101,7 @@ public class FlagTest { public void shouldSuccessfullyParseTitleFlagWithTitleEmptyAndSubTitleSingleWord() { Assertions.assertDoesNotThrow(() -> { var title = PlotTitleFlag.TITLE_FLAG_DEFAULT.parse("\"\" \"single\"").getValue(); - Assertions.assertEquals(" ", title.title()); + Assertions.assertEquals("", title.title()); Assertions.assertEquals("single", title.subtitle()); }, "Should not throw a FlagParseException"); } diff --git a/Core/src/test/java/com/plotsquared/core/util/StringManTest.java b/Core/src/test/java/com/plotsquared/core/util/StringManTest.java index 8c1eb2aa1..14927ce42 100644 --- a/Core/src/test/java/com/plotsquared/core/util/StringManTest.java +++ b/Core/src/test/java/com/plotsquared/core/util/StringManTest.java @@ -32,7 +32,9 @@ public class StringManTest { new Message("title", List.of("title")), new Message("title \"sub title\"", List.of("title", "sub title")), new Message("\"a title\" subtitle", List.of("a title", "subtitle")), - new Message("\"title\" \"subtitle\"", List.of("title", "subtitle")) + new Message("\"title\" \"subtitle\"", List.of("title", "subtitle")), + new Message("\"How bold of you\" \"to assume I like rainbows\"", + List.of("How bold of you", "to assume I like rainbows")) ); for (Message message : messages) { diff --git a/build.gradle.kts b/build.gradle.kts index fca26f9b1..810e2be6e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -19,7 +19,7 @@ plugins { } group = "com.plotsquared" -version = "6.10.2-SNAPSHOT" +version = "6.10.6-SNAPSHOT" subprojects { group = rootProject.group @@ -65,7 +65,7 @@ subprojects { } dependencies { - implementation(platform("com.intellectualsites.bom:bom-1.18.x:1.16")) + implementation(platform("com.intellectualsites.bom:bom-1.18.x:1.21")) } dependencies { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 83a136062..652758547 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,11 +1,10 @@ [versions] # Platform expectations -paper = "1.18.1-R0.1-SNAPSHOT" guice = "5.1.0" -spotbugs = "4.7.2" +spotbugs = "4.7.3" # Plugins -worldedit = "7.2.12" +worldedit = "7.2.13" placeholderapi = "2.11.2" luckperms = "5.4" essentialsx = "2.19.7" @@ -14,7 +13,7 @@ mvdwapi = "3.1.1" # Third party prtree = "2.0.0" aopalliance = "1.0" -cloud-services = "1.7.1" +cloud-services = "1.8.0" arkitektonika = "2.1.1" squirrelid = "0.3.1" http4j = "1.3" @@ -26,9 +25,6 @@ licenser = "0.6.1" nexus = "1.1.0" [libraries] -# Platform expectations -paper = { group = "io.papermc.paper", name = "paper-api", version.ref = "paper" } - # Platform expectations guice = { group = "com.google.inject", name = "guice", version.ref = "guice" } guiceassistedinject = { group = "com.google.inject.extensions", name = "guice-assistedinject", version.ref = "guice" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 249e5832f..943f0cbfa 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ae04661ee..f398c33c4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index a69d9cb6c..65dcd68d6 100755 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,10 +80,10 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' @@ -143,12 +143,16 @@ fi if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac diff --git a/gradlew.bat b/gradlew.bat index 53a6b238d..6689b85be 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME%