From 59e0b4b67a34949b1b4e834cdc7f71ad9c638863 Mon Sep 17 00:00:00 2001 From: Pierre Maurice Schwang Date: Sun, 23 Jan 2022 10:44:11 +0100 Subject: [PATCH] feat: unknown owner(s) for plot expiry (#3452) * feat: unknown owner(s) for plot expiry * Sort plugins on `/plot debugpaste` alphabetically (#3447) * feat: Sort plugins on debugpaste alphabetically * Put (F[A])WE at the top * feat: Add 1.18's music disc additions to `/plot music` (#3446) * refactor: Prepare removal of our maven repository (#3451) * Allow restoration of road schematic height calculation behaviour from pre 6.1.4 (#3444) * refactor: Update SquirrelID GAV * build: Release 6.3.0 * build: Back to snapshot for development * fix: fallback method in BukkitQueueCoordinator uses world coordinates * mark since tags as TODO * fix: get the lowest diff for plot age * fix: initialize with high value and better readability * fix: no need for multiple age checks * fix: address exceptions in plot analysis * chore: address requested changes * chore: Fix introduced violations Co-authored-by: Alex Co-authored-by: Jordan --- .../plotsquared/bukkit/BukkitPlatform.java | 4 +-- .../bukkit/queue/BukkitQueueCoordinator.java | 6 ++-- .../core/configuration/Settings.java | 2 ++ .../core/generator/HybridUtils.java | 17 ++++++--- .../java/com/plotsquared/core/plot/Plot.java | 2 +- .../core/plot/expiration/ExpireManager.java | 35 ++++++++++++------- .../core/plot/expiration/ExpiryTask.java | 10 +++++- .../core/queue/ChunkQueueCoordinator.java | 15 +++++--- 8 files changed, 62 insertions(+), 29 deletions(-) diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java b/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java index 7a7569f78..61ba28413 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java @@ -324,8 +324,6 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl // Comments CommentManager.registerDefaultInboxes(); - plotSquared.startExpiryTasks(); - // Do stuff that was previously done in PlotSquared // Kill entities if (Settings.Enabled_Components.KILL_ROAD_MOBS || Settings.Enabled_Components.KILL_ROAD_VEHICLES) { @@ -422,6 +420,8 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl }, TaskTime.ticks(1L)); } + plotSquared.startExpiryTasks(); + // Once the server has loaded force updating all generators known to P2 TaskManager.runTaskLater(() -> PlotSquared.platform().setupUtils().updateGenerators(true), TaskTime.ticks(1L)); diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/queue/BukkitQueueCoordinator.java b/Bukkit/src/main/java/com/plotsquared/bukkit/queue/BukkitQueueCoordinator.java index 6973dc5d1..8c418ee88 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/queue/BukkitQueueCoordinator.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/queue/BukkitQueueCoordinator.java @@ -51,7 +51,6 @@ import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import org.bukkit.Bukkit; -import org.bukkit.Chunk; import org.bukkit.block.Block; import org.bukkit.block.Container; import org.bukkit.block.data.BlockData; @@ -238,6 +237,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator { /** * Set a block to the world. First tries WNA but defaults to normal block setting methods if that fails */ + @SuppressWarnings("unused") private void setWorldBlock(int x, int y, int z, @NonNull BaseBlock block, @NonNull BlockVector2 blockVector2, boolean edge) { try { BlockVector3 loc = BlockVector3.at(x, y, z); @@ -266,9 +266,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator { } catch (WorldEditException ignored) { // Fallback to not so nice method BlockData blockData = BukkitAdapter.adapt(block); - Chunk chunk = getBukkitWorld().getChunkAt(blockVector2.getX(), blockVector2.getZ()); - - Block existing = chunk.getBlock(x, y, z); + Block existing = getBukkitWorld().getBlockAt(x, y, z); final BlockState existingBaseBlock = BukkitAdapter.adapt(existing.getBlockData()); if (BukkitBlockUtil.get(existing).equals(existingBaseBlock) && existing.getBlockData().matches(blockData)) { return; 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 70be6ece6..1d8be621f 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/Settings.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/Settings.java @@ -196,6 +196,8 @@ public class Settings extends Config { public boolean CONFIRMATION = true; public int DAYS = 90; public int SKIP_ACCOUNT_AGE_DAYS = -1; + @Comment("True, if a plot should be deleted if the plot owner is unknown to the server") + public boolean DELETE_IF_OWNER_IS_UNKNOWN = false; public List WORLDS = new ArrayList<>(Collections.singletonList("*")); 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 686e4f97f..23513571f 100644 --- a/Core/src/main/java/com/plotsquared/core/generator/HybridUtils.java +++ b/Core/src/main/java/com/plotsquared/core/generator/HybridUtils.java @@ -148,12 +148,22 @@ public class HybridUtils { return; } - ChunkQueueCoordinator chunk = new ChunkQueueCoordinator(bot, top, false); + ChunkQueueCoordinator chunk = new ChunkQueueCoordinator(worldUtil.getWeWorld(world), bot, top, false); hpw.getGenerator().generateChunk(chunk, hpw); + final BlockState airBlock = BlockTypes.AIR.getDefaultState(); final BlockState[][][] oldBlocks = chunk.getBlocks(); final BlockState[][][] newBlocks = new BlockState[256][width][length]; - final BlockState airBlock = BlockTypes.AIR.getDefaultState(); + for (final BlockState[][] newBlock : newBlocks) { + for (final BlockState[] blockStates : newBlock) { + Arrays.fill(blockStates, airBlock); + } + } + for (final BlockState[][] oldBlock : oldBlocks) { + for (final BlockState[] blockStates : oldBlock) { + Arrays.fill(blockStates, airBlock); + } + } System.gc(); System.gc(); @@ -221,9 +231,6 @@ public class HybridUtils { for (int y = 0; y < 256; y++) { BlockState old = oldBlocks[y][x][z]; try { - if (old == null) { - old = airBlock; - } BlockState now = newBlocks[y][x][z]; if (!old.equals(now)) { changes[i]++; 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 b94bd889d..55481ea3f 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/Plot.java +++ b/Core/src/main/java/com/plotsquared/core/plot/Plot.java @@ -2834,7 +2834,7 @@ public class Plot { if (this.isOnline()) { seen = TranslatableCaption.of("info.now").getComponent(player); } else { - int time = (int) (ExpireManager.IMP.getAge(this) / 1000); + int time = (int) (ExpireManager.IMP.getAge(this, false) / 1000); if (time != 0) { seen = TimeUtil.secToTime(time); } else { 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 ac28cec7e..b86f7af6e 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 @@ -216,24 +216,20 @@ public class ExpireManager { applicable.add(et); } } - if (applicable.isEmpty()) { return new ArrayList<>(); } + // Don't delete server plots if (plot.getFlag(ServerPlotFlag.class)) { return new ArrayList<>(); } - long diff = getAge(plot); - if (diff == 0) { - return new ArrayList<>(); - } // Filter out non old plots boolean shouldCheckAccountAge = false; for (int i = 0; i < applicable.size(); i++) { ExpiryTask et = applicable.poll(); - if (et.applies(diff)) { + if (et.applies(getAge(plot, et.shouldDeleteForUnknownOwner()))) { applicable.add(et); shouldCheckAccountAge |= et.getSettings().SKIP_ACCOUNT_AGE_DAYS != -1; } @@ -243,9 +239,9 @@ public class ExpireManager { } // Check account age if (shouldCheckAccountAge) { - long accountAge = getAge(plot); for (int i = 0; i < applicable.size(); i++) { ExpiryTask et = applicable.poll(); + long accountAge = getAge(plot, et.shouldDeleteForUnknownOwner()); if (et.appliesAccountAge(accountAge)) { applicable.add(et); } @@ -309,9 +305,8 @@ public class ExpireManager { return false; } this.running = 2; - final ConcurrentLinkedDeque plots = - new ConcurrentLinkedDeque<>(PlotQuery.newQuery().allPlots().asList()); TaskManager.runTaskAsync(new Runnable() { + private ConcurrentLinkedDeque plots = null; @Override public void run() { final Runnable task = this; @@ -319,6 +314,9 @@ public class ExpireManager { ExpireManager.this.running = 0; return; } + if (plots == null) { + plots = new ConcurrentLinkedDeque<>(PlotQuery.newQuery().allPlots().asList()); + } while (!plots.isEmpty()) { if (ExpireManager.this.running != 2) { ExpireManager.this.running = 0; @@ -453,7 +451,20 @@ public class ExpireManager { plot.getPlotModificationManager().deletePlot(null, whenDone); } + @Deprecated(forRemoval = true, since = "TODO") public long getAge(UUID uuid) { + return getAge(uuid, false); + } + + /** + * Get the age (last play time) of the passed player + * + * @param uuid the uuid of the owner to check against + * @param shouldDeleteUnknownOwner {@code true} if an unknown player should be counted as never online + * @return the millis since the player was last online, or {@link Long#MAX_VALUE} if player was never online + * @since TODO + */ + public long getAge(UUID uuid, final boolean shouldDeleteUnknownOwner) { if (PlotSquared.platform().playerManager().getPlayerIfExists(uuid) != null) { return 0; } @@ -463,7 +474,7 @@ public class ExpireManager { if (opp != null && (last = opp.getLastPlayed()) != 0) { this.dates_cache.put(uuid, last); } else { - return 0; + return shouldDeleteUnknownOwner ? Long.MAX_VALUE : 0; } } if (last == 0) { @@ -472,7 +483,7 @@ public class ExpireManager { return System.currentTimeMillis() - last; } - public long getAge(Plot plot) { + public long getAge(Plot plot, final boolean shouldDeleteUnknownOwner) { if (!plot.hasOwner() || Objects.equals(DBFunc.EVERYONE, plot.getOwner()) || PlotSquared.platform().playerManager().getPlayerIfExists(plot.getOwner()) != null || plot.getRunning() > 0) { return 0; @@ -494,7 +505,7 @@ public class ExpireManager { } long min = Long.MAX_VALUE; for (UUID owner : plot.getOwners()) { - long age = getAge(owner); + long age = getAge(owner, shouldDeleteUnknownOwner); if (age < min) { min = age; } 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 d2ccb5877..4ec683682 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 @@ -80,7 +80,7 @@ public class ExpiryTask { diff = settings.REQUIRED_PLOTS - plots.size(); } List entireList = - plots.stream().map(plot -> ExpireManager.IMP.getAge(plot)) + plots.stream().map(plot -> ExpireManager.IMP.getAge(plot, settings.DELETE_IF_OWNER_IS_UNKNOWN)) .collect(Collectors.toList()); List top = new ArrayList<>(diff + 1); if (diff > 1000) { @@ -157,5 +157,13 @@ public class ExpiryTask { return settings.CONFIRMATION; } + /** + * Returns {@code true} if this task respects unknown owners + * @return {@code true} if unknown owners should be counted as never online + * @since TODO + */ + public boolean shouldDeleteForUnknownOwner() { + return settings.DELETE_IF_OWNER_IS_UNKNOWN; + } } diff --git a/Core/src/main/java/com/plotsquared/core/queue/ChunkQueueCoordinator.java b/Core/src/main/java/com/plotsquared/core/queue/ChunkQueueCoordinator.java index 91bf7531f..f7b351356 100644 --- a/Core/src/main/java/com/plotsquared/core/queue/ChunkQueueCoordinator.java +++ b/Core/src/main/java/com/plotsquared/core/queue/ChunkQueueCoordinator.java @@ -46,13 +46,20 @@ public class ChunkQueueCoordinator extends ScopedQueueCoordinator { private final int length; private final BlockVector3 bot; private final BlockVector3 top; + private final World weWorld; - public ChunkQueueCoordinator(@NonNull BlockVector3 bot, @NonNull BlockVector3 top, boolean biomes) { + public ChunkQueueCoordinator( + final @NonNull World weWorld, + @NonNull BlockVector3 bot, + @NonNull BlockVector3 top, + boolean biomes + ) { super(null, Location.at("", 0, 0, 0), Location.at("", 15, 255, 15)); + this.weWorld = weWorld; this.width = top.getX() - bot.getX() + 1; this.length = top.getZ() - bot.getZ() + 1; - this.result = new BlockState[256][][]; - this.biomeResult = biomes ? new BiomeType[256][][] : null; + this.result = new BlockState[256][width][length]; + this.biomeResult = biomes ? new BiomeType[256][width][length] : null; this.bot = bot; this.top = top; } @@ -137,7 +144,7 @@ public class ChunkQueueCoordinator extends ScopedQueueCoordinator { @Override public @Nullable World getWorld() { - return super.getWorld(); + return weWorld; } @Override