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 extends PlotFlag> 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%