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 <mc.cache@web.de>
Co-authored-by: Jordan <dordsor21@gmail.com>
This commit is contained in:
Pierre Maurice Schwang 2022-01-23 10:44:11 +01:00 committed by GitHub
parent 5fc153d896
commit 59e0b4b67a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 62 additions and 29 deletions

View File

@ -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));

View File

@ -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;

View File

@ -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<String> WORLDS = new ArrayList<>(Collections.singletonList("*"));

View File

@ -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]++;

View File

@ -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 {

View File

@ -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<Plot> plots =
new ConcurrentLinkedDeque<>(PlotQuery.newQuery().allPlots().asList());
TaskManager.runTaskAsync(new Runnable() {
private ConcurrentLinkedDeque<Plot> 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;
}

View File

@ -80,7 +80,7 @@ public class ExpiryTask {
diff = settings.REQUIRED_PLOTS - plots.size();
}
List<Long> 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<Long> 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;
}
}

View File

@ -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