diff --git a/adapters/modded-common/src/main/java/art/arcane/iris/modded/ModdedEngineBootstrap.java b/adapters/modded-common/src/main/java/art/arcane/iris/modded/ModdedEngineBootstrap.java index 06ecbee61..036b4d423 100644 --- a/adapters/modded-common/src/main/java/art/arcane/iris/modded/ModdedEngineBootstrap.java +++ b/adapters/modded-common/src/main/java/art/arcane/iris/modded/ModdedEngineBootstrap.java @@ -30,6 +30,7 @@ import art.arcane.iris.engine.object.TileData; import art.arcane.iris.modded.api.ModdedCustomContentRegistry; import art.arcane.iris.modded.command.ModdedGuiHost; import art.arcane.iris.modded.command.ModdedObjectUndo; +import art.arcane.iris.modded.command.ModdedPregenBossBar; import art.arcane.iris.modded.command.ModdedPregenJob; import art.arcane.iris.modded.command.ModdedStudioCommands; import art.arcane.iris.modded.command.ModdedWandService; @@ -79,6 +80,7 @@ public final class ModdedEngineBootstrap { ModdedStartup.runOnce(server); ModdedPrimaryWorldRouter.tick(server); SERVICE_MANAGER.tick(server); + ModdedPregenBossBar.tick(server); } public static void start(MinecraftServer server) { diff --git a/adapters/modded-common/src/main/java/art/arcane/iris/modded/api/IrisModdedAPI.java b/adapters/modded-common/src/main/java/art/arcane/iris/modded/api/IrisModdedAPI.java index b24abcb8d..2cb7d7ca2 100644 --- a/adapters/modded-common/src/main/java/art/arcane/iris/modded/api/IrisModdedAPI.java +++ b/adapters/modded-common/src/main/java/art/arcane/iris/modded/api/IrisModdedAPI.java @@ -18,7 +18,7 @@ package art.arcane.iris.modded.api; -import art.arcane.iris.core.tools.IrisToolbelt; +import art.arcane.iris.core.tools.WorldMaintenance; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.modded.IrisModdedChunkGenerator; import art.arcane.iris.modded.command.ModdedPregenJob; @@ -96,7 +96,7 @@ public final class IrisModdedAPI { if (sliceType == null) { return; } - IrisToolbelt.retainMantleDataForSlice(sliceType.getCanonicalName()); + WorldMaintenance.retainMantleDataForSlice(sliceType.getCanonicalName()); } public static void registerProvider(ModdedDataProvider provider) { diff --git a/adapters/modded-common/src/main/java/art/arcane/iris/modded/command/IrisModdedCommands.java b/adapters/modded-common/src/main/java/art/arcane/iris/modded/command/IrisModdedCommands.java index c8aba50e6..fad8d713e 100644 --- a/adapters/modded-common/src/main/java/art/arcane/iris/modded/command/IrisModdedCommands.java +++ b/adapters/modded-common/src/main/java/art/arcane/iris/modded/command/IrisModdedCommands.java @@ -557,6 +557,7 @@ public final class IrisModdedCommands { fail(source, "A pregeneration task is already running. Stop it first with /iris pregen stop."); return 0; } + ModdedPregenBossBar.begin(source.getPlayer()); String guiNote; if (!gui) { guiNote = ""; @@ -573,6 +574,7 @@ public final class IrisModdedCommands { private static int pregenStop(CommandSourceStack source) { if (ModdedPregenJob.stop()) { + ModdedPregenBossBar.clear(); ok(source, "Stopping pregeneration; finishing up the current region..."); return 1; } diff --git a/adapters/modded-common/src/main/java/art/arcane/iris/modded/command/ModdedPregenBossBar.java b/adapters/modded-common/src/main/java/art/arcane/iris/modded/command/ModdedPregenBossBar.java new file mode 100644 index 000000000..bc0261bcd --- /dev/null +++ b/adapters/modded-common/src/main/java/art/arcane/iris/modded/command/ModdedPregenBossBar.java @@ -0,0 +1,107 @@ +package art.arcane.iris.modded.command; + +import art.arcane.iris.core.gui.PregeneratorJob; +import art.arcane.volmlib.util.format.Form; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerBossEvent; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.BossEvent; + +import java.util.UUID; + +public final class ModdedPregenBossBar { + private static final UUID BAR_ID = UUID.fromString("14150000-1e15-4a2b-9c3d-1115e9a1cafe"); + private static final int UPDATE_INTERVAL_TICKS = 10; + + private static volatile ServerBossEvent bar; + private static volatile UUID viewer; + private static int sinceUpdate; + + private ModdedPregenBossBar() { + } + + public static synchronized void begin(ServerPlayer player) { + clear(); + if (player == null) { + return; + } + viewer = player.getUUID(); + bar = new ServerBossEvent(BAR_ID, Component.literal("Iris Pregen starting..."), BossEvent.BossBarColor.GREEN, BossEvent.BossBarOverlay.PROGRESS); + bar.setProgress(0.0F); + bar.addPlayer(player); + sinceUpdate = UPDATE_INTERVAL_TICKS; + } + + public static void tick(MinecraftServer server) { + ServerBossEvent active = bar; + if (active == null) { + return; + } + PregeneratorJob.PregenProgress progress = PregeneratorJob.progressSnapshot(); + if (progress == null) { + clear(); + return; + } + if (++sinceUpdate < UPDATE_INTERVAL_TICKS) { + return; + } + sinceUpdate = 0; + reattach(server, active); + active.setProgress((float) clamp01(progress.percent() / 100.0D)); + active.setColor(progress.paused() ? BossEvent.BossBarColor.YELLOW : BossEvent.BossBarColor.GREEN); + active.setName(nameFor(progress)); + } + + private static void reattach(MinecraftServer server, ServerBossEvent active) { + UUID id = viewer; + if (id == null || server == null) { + return; + } + ServerPlayer player = server.getPlayerList().getPlayer(id); + if (player != null && !active.getPlayers().contains(player)) { + active.addPlayer(player); + } + } + + private static Component nameFor(PregeneratorJob.PregenProgress progress) { + MutableComponent name = Component.empty(); + name.append(ModdedCommandFeedback.text("Iris Pregen ", ModdedCommandFeedback.DARK_GREEN)); + name.append(ModdedCommandFeedback.text(Form.f(progress.generated()) + "/" + Form.f(progress.totalChunks()), ModdedCommandFeedback.VALUE)); + name.append(ModdedCommandFeedback.text(" " + String.format("%.1f", progress.percent()) + "%", ModdedCommandFeedback.USAGE)); + if (progress.paused()) { + name.append(ModdedCommandFeedback.text(" PAUSED", ModdedCommandFeedback.REQUIRED)); + return name; + } + name.append(ModdedCommandFeedback.text(" " + Form.f((int) progress.chunksPerSecond()) + "/s", ModdedCommandFeedback.VALUE)); + if (progress.eta() > 0L) { + name.append(ModdedCommandFeedback.text(" ETA " + Form.duration(progress.eta(), 1), ModdedCommandFeedback.DARK_GREEN)); + } + if (progress.failed() > 0L) { + name.append(ModdedCommandFeedback.text(" failed " + Form.f(progress.failed()), ModdedCommandFeedback.REQUIRED)); + } + return name; + } + + private static double clamp01(double value) { + if (value < 0.0D) { + return 0.0D; + } + if (value > 1.0D) { + return 1.0D; + } + return value; + } + + public static synchronized void clear() { + ServerBossEvent existing = bar; + if (existing != null) { + existing.removeAllPlayers(); + existing.setVisible(false); + } + bar = null; + viewer = null; + sinceUpdate = 0; + } +} diff --git a/adapters/modded-common/src/main/java/art/arcane/iris/modded/command/ModdedRegen.java b/adapters/modded-common/src/main/java/art/arcane/iris/modded/command/ModdedRegen.java index 1ebd3992f..1fcf200d9 100644 --- a/adapters/modded-common/src/main/java/art/arcane/iris/modded/command/ModdedRegen.java +++ b/adapters/modded-common/src/main/java/art/arcane/iris/modded/command/ModdedRegen.java @@ -18,7 +18,7 @@ package art.arcane.iris.modded.command; -import art.arcane.iris.core.tools.IrisToolbelt; +import art.arcane.iris.core.tools.WorldMaintenance; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.mantle.EngineMantle; import art.arcane.iris.modded.IrisModdedChunkGenerator; @@ -107,7 +107,7 @@ public final class ModdedRegen { private void run() { long startedAt = M.ms(); String worldName = engine.getWorld() == null ? null : engine.getWorld().name(); - IrisToolbelt.beginWorldMaintenance(worldName, "regen"); + WorldMaintenance.beginWorldMaintenance(worldName, "regen"); try { resetMantleMargin(); List targets = ChunkSpiral.centerOut(centerX, centerZ, radius); @@ -120,7 +120,7 @@ public final class ModdedRegen { LOGGER.error("Iris regen failed", e); fail("Regen failed: " + e); } finally { - IrisToolbelt.endWorldMaintenance(worldName, "regen"); + WorldMaintenance.endWorldMaintenance(worldName, "regen"); ACTIVE.set(false); } } diff --git a/adapters/modded-common/src/main/java/art/arcane/iris/modded/service/ModdedEngineMaintenanceService.java b/adapters/modded-common/src/main/java/art/arcane/iris/modded/service/ModdedEngineMaintenanceService.java index 493bc4cbf..e9b345745 100644 --- a/adapters/modded-common/src/main/java/art/arcane/iris/modded/service/ModdedEngineMaintenanceService.java +++ b/adapters/modded-common/src/main/java/art/arcane/iris/modded/service/ModdedEngineMaintenanceService.java @@ -22,7 +22,7 @@ import art.arcane.iris.core.IrisSettings; import art.arcane.iris.core.gui.PregeneratorJob; import art.arcane.iris.core.pregenerator.MantleHeapPressure; import art.arcane.iris.core.runtime.GoldenHashEngine; -import art.arcane.iris.core.tools.IrisToolbelt; +import art.arcane.iris.core.tools.WorldMaintenance; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.modded.ModdedWorldEngines; import art.arcane.iris.spi.IrisLogging; @@ -166,7 +166,7 @@ public final class ModdedEngineMaintenanceService implements ModdedTickableServi } private boolean shouldSkipForMaintenance(Engine engine) { - if (engine.getWorld() == null || !IrisToolbelt.isWorldMaintenanceActive(engine.getWorld().name())) { + if (engine.getWorld() == null || !WorldMaintenance.isWorldMaintenanceActive(engine.getWorld().name())) { return false; } return !pregenTargets(engine); diff --git a/core/src/main/java/art/arcane/iris/core/IrisRuntimeSchedulerMode.java b/core/src/main/java/art/arcane/iris/core/IrisRuntimeSchedulerMode.java index 402c55148..21ca8ae7e 100644 --- a/core/src/main/java/art/arcane/iris/core/IrisRuntimeSchedulerMode.java +++ b/core/src/main/java/art/arcane/iris/core/IrisRuntimeSchedulerMode.java @@ -47,6 +47,9 @@ public enum IrisRuntimeSchedulerMode { || containsIgnoreCase(bukkitName, "pufferfish") || containsIgnoreCase(bukkitVersion, "pufferfish") || containsIgnoreCase(serverClassName, "pufferfish") + || containsIgnoreCase(bukkitName, "leaf") + || containsIgnoreCase(bukkitVersion, "leaf") + || containsIgnoreCase(serverClassName, "leaf") || containsIgnoreCase(bukkitName, "spigot") || containsIgnoreCase(bukkitVersion, "spigot") || containsIgnoreCase(serverClassName, "spigot") diff --git a/core/src/main/java/art/arcane/iris/core/runtime/WorldRuntimeControlService.java b/core/src/main/java/art/arcane/iris/core/runtime/WorldRuntimeControlService.java index 562827672..506173fee 100644 --- a/core/src/main/java/art/arcane/iris/core/runtime/WorldRuntimeControlService.java +++ b/core/src/main/java/art/arcane/iris/core/runtime/WorldRuntimeControlService.java @@ -140,28 +140,56 @@ public final class WorldRuntimeControlService { skipAmount += 24000L; } - TimeSkipEvent event = new TimeSkipEvent(world, TimeSkipEvent.SkipReason.CUSTOM, skipAmount); - PluginManager pluginManager = Bukkit.getPluginManager(); - if (pluginManager != null) { - pluginManager.callEvent(event); - } - if (event.isCancelled()) { - return false; + long effectiveSkip = skipAmount; + if (TIME_SKIP_EVENT_AVAILABLE) { + long fired = fireTimeSkipEvent(world, skipAmount); + if (fired == TIME_SKIP_CANCELLED) { + return false; + } + effectiveSkip = fired; } try { - boolean written = backend.writeDayTime(world, currentTime.getAsLong() + event.getSkipAmount()); + boolean written = backend.writeDayTime(world, currentTime.getAsLong() + effectiveSkip); if (!written) { return false; } backend.syncTime(world); return true; } catch (Throwable e) { - IrisLogging.reportError("Runtime time control failed for world \"" + world.getName() + "\".", e); + IrisLogging.debug("Runtime time lock skipped for world \"" + world.getName() + "\": " + e.getMessage()); return false; } } + private static final long TIME_SKIP_CANCELLED = Long.MIN_VALUE; + private static final boolean TIME_SKIP_EVENT_AVAILABLE = probeTimeSkipEvent(); + + private static boolean probeTimeSkipEvent() { + try { + Class.forName("org.bukkit.event.world.TimeSkipEvent$SkipReason"); + return true; + } catch (Throwable e) { + return false; + } + } + + private long fireTimeSkipEvent(World world, long skipAmount) { + try { + TimeSkipEvent event = new TimeSkipEvent(world, TimeSkipEvent.SkipReason.CUSTOM, skipAmount); + PluginManager pluginManager = Bukkit.getPluginManager(); + if (pluginManager != null) { + pluginManager.callEvent(event); + } + if (event.isCancelled()) { + return TIME_SKIP_CANCELLED; + } + return event.getSkipAmount(); + } catch (Throwable e) { + return skipAmount; + } + } + public CompletableFuture requestChunkAsync(World world, int chunkX, int chunkZ, boolean generate) { return backend.requestChunkAsync(world, chunkX, chunkZ, generate); } diff --git a/core/src/main/java/art/arcane/iris/core/safeguard/task/Tasks.java b/core/src/main/java/art/arcane/iris/core/safeguard/task/Tasks.java index bcf34fc4e..e41eceadb 100644 --- a/core/src/main/java/art/arcane/iris/core/safeguard/task/Tasks.java +++ b/core/src/main/java/art/arcane/iris/core/safeguard/task/Tasks.java @@ -63,7 +63,7 @@ public final class Tasks { }); private static final Task SOFTWARE = Task.of("software", () -> { - Set supported = Set.of("canvas", "folia", "purpur", "pufferfish", "paper", "spigot", "bukkit"); + Set supported = Set.of("canvas", "folia", "purpur", "pufferfish", "leaf", "paper", "spigot", "bukkit"); String serverName = server().getName().toLowerCase(Locale.ROOT); boolean supportedServer = isCanvasServer(); if (!supportedServer) { @@ -81,7 +81,7 @@ public final class Tasks { return withDiagnostics(Mode.WARNING, Diagnostic.Logger.WARN.create("Unsupported Server Software"), - Diagnostic.Logger.WARN.create("- Please consider using Canvas, Folia, Paper, or Purpur instead.")); + Diagnostic.Logger.WARN.create("- Please consider using Canvas, Folia, Leaf, Paper, or Purpur instead.")); }); private static final Task VERSION = Task.of("version", () -> { diff --git a/core/src/main/java/art/arcane/iris/core/tools/IrisReflectiveAPI.java b/core/src/main/java/art/arcane/iris/core/tools/IrisReflectiveAPI.java index 387bbe54d..3072fc9f6 100644 --- a/core/src/main/java/art/arcane/iris/core/tools/IrisReflectiveAPI.java +++ b/core/src/main/java/art/arcane/iris/core/tools/IrisReflectiveAPI.java @@ -24,7 +24,7 @@ public class IrisReflectiveAPI { } public static void retainMantleData(String classname) { - IrisToolbelt.retainMantleDataForSlice(classname); + WorldMaintenance.retainMantleDataForSlice(classname); } public static void setMantleData(World world, int x, int y, int z, Object data) { diff --git a/core/src/main/java/art/arcane/iris/core/tools/IrisToolbelt.java b/core/src/main/java/art/arcane/iris/core/tools/IrisToolbelt.java index 9c88d3ee7..987dfaeeb 100644 --- a/core/src/main/java/art/arcane/iris/core/tools/IrisToolbelt.java +++ b/core/src/main/java/art/arcane/iris/core/tools/IrisToolbelt.java @@ -55,8 +55,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicInteger; /** * Something you really want to wear if working on Iris. Shit gets pretty hectic down there. @@ -65,8 +63,6 @@ import java.util.concurrent.atomic.AtomicInteger; public class IrisToolbelt { @ApiStatus.Internal public static Map toolbeltConfiguration = new HashMap<>(); - private static final Map worldMaintenanceDepth = new ConcurrentHashMap<>(); - private static final Map worldMaintenanceMantleBypassDepth = new ConcurrentHashMap<>(); private static final Method BUKKIT_IS_STOPPING_METHOD = resolveBukkitIsStoppingMethod(); /** @@ -426,19 +422,7 @@ public class IrisToolbelt { } public static void beginWorldMaintenance(String worldName, String reason, boolean bypassMantleStages) { - if (worldName == null) { - return; - } - - int depth = worldMaintenanceDepth.computeIfAbsent(worldName, k -> new AtomicInteger()).incrementAndGet(); - if (bypassMantleStages) { - worldMaintenanceMantleBypassDepth.computeIfAbsent(worldName, k -> new AtomicInteger()).incrementAndGet(); - } - if (IrisSettings.get().getGeneral().isDebug()) { - IrisLogging.info("World maintenance enter: " + worldName + " reason=" + reason + " depth=" + depth + " bypassMantle=" + bypassMantleStages); - } else { - IrisLogging.debug("World maintenance enter: " + worldName + " reason=" + reason + " depth=" + depth + " bypassMantle=" + bypassMantleStages); - } + WorldMaintenance.beginWorldMaintenance(worldName, reason, bypassMantleStages); } public static void endWorldMaintenance(World world, String reason) { @@ -450,36 +434,7 @@ public class IrisToolbelt { } public static void endWorldMaintenance(String worldName, String reason) { - if (worldName == null) { - return; - } - - AtomicInteger depthCounter = worldMaintenanceDepth.get(worldName); - if (depthCounter == null) { - return; - } - - int depth = depthCounter.decrementAndGet(); - if (depth <= 0) { - worldMaintenanceDepth.remove(worldName, depthCounter); - depth = 0; - } - - AtomicInteger bypassCounter = worldMaintenanceMantleBypassDepth.get(worldName); - int bypassDepth = 0; - if (bypassCounter != null) { - bypassDepth = bypassCounter.decrementAndGet(); - if (bypassDepth <= 0) { - worldMaintenanceMantleBypassDepth.remove(worldName, bypassCounter); - bypassDepth = 0; - } - } - - if (IrisSettings.get().getGeneral().isDebug()) { - IrisLogging.info("World maintenance exit: " + worldName + " reason=" + reason + " depth=" + depth + " bypassMantleDepth=" + bypassDepth); - } else { - IrisLogging.debug("World maintenance exit: " + worldName + " reason=" + reason + " depth=" + depth + " bypassMantleDepth=" + bypassDepth); - } + WorldMaintenance.endWorldMaintenance(worldName, reason); } public static boolean isWorldMaintenanceActive(World world) { @@ -487,12 +442,7 @@ public class IrisToolbelt { } public static boolean isWorldMaintenanceActive(String worldName) { - if (worldName == null) { - return false; - } - - AtomicInteger counter = worldMaintenanceDepth.get(worldName); - return counter != null && counter.get() > 0; + return WorldMaintenance.isWorldMaintenanceActive(worldName); } public static boolean isWorldMaintenanceBypassingMantleStages(World world) { @@ -500,20 +450,15 @@ public class IrisToolbelt { } public static boolean isWorldMaintenanceBypassingMantleStages(String worldName) { - if (worldName == null) { - return false; - } - - AtomicInteger counter = worldMaintenanceMantleBypassDepth.get(worldName); - return counter != null && counter.get() > 0; + return WorldMaintenance.isWorldMaintenanceBypassingMantleStages(worldName); } public static void retainMantleDataForSlice(String className) { - toolbeltConfiguration.put("retain.mantle." + className, Boolean.TRUE); + WorldMaintenance.retainMantleDataForSlice(className); } public static boolean isRetainingMantleDataForSlice(String className) { - return !toolbeltConfiguration.isEmpty() && toolbeltConfiguration.get("retain.mantle." + className) == Boolean.TRUE; + return WorldMaintenance.isRetainingMantleDataForSlice(className); } public static T getMantleData(World world, int x, int y, int z, Class of) { diff --git a/core/src/main/java/art/arcane/iris/core/tools/WorldMaintenance.java b/core/src/main/java/art/arcane/iris/core/tools/WorldMaintenance.java new file mode 100644 index 000000000..3e4960535 --- /dev/null +++ b/core/src/main/java/art/arcane/iris/core/tools/WorldMaintenance.java @@ -0,0 +1,101 @@ +package art.arcane.iris.core.tools; + +import art.arcane.iris.core.IrisSettings; +import art.arcane.iris.spi.IrisLogging; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +public final class WorldMaintenance { + private static final Map worldMaintenanceDepth = new ConcurrentHashMap<>(); + private static final Map worldMaintenanceMantleBypassDepth = new ConcurrentHashMap<>(); + private static final Set retainedMantleSlices = ConcurrentHashMap.newKeySet(); + + private WorldMaintenance() { + } + + public static void beginWorldMaintenance(String worldName, String reason) { + beginWorldMaintenance(worldName, reason, false); + } + + public static void beginWorldMaintenance(String worldName, String reason, boolean bypassMantleStages) { + if (worldName == null) { + return; + } + + int depth = worldMaintenanceDepth.computeIfAbsent(worldName, k -> new AtomicInteger()).incrementAndGet(); + if (bypassMantleStages) { + worldMaintenanceMantleBypassDepth.computeIfAbsent(worldName, k -> new AtomicInteger()).incrementAndGet(); + } + if (IrisSettings.get().getGeneral().isDebug()) { + IrisLogging.info("World maintenance enter: " + worldName + " reason=" + reason + " depth=" + depth + " bypassMantle=" + bypassMantleStages); + } else { + IrisLogging.debug("World maintenance enter: " + worldName + " reason=" + reason + " depth=" + depth + " bypassMantle=" + bypassMantleStages); + } + } + + public static void endWorldMaintenance(String worldName, String reason) { + if (worldName == null) { + return; + } + + AtomicInteger depthCounter = worldMaintenanceDepth.get(worldName); + if (depthCounter == null) { + return; + } + + int depth = depthCounter.decrementAndGet(); + if (depth <= 0) { + worldMaintenanceDepth.remove(worldName, depthCounter); + depth = 0; + } + + AtomicInteger bypassCounter = worldMaintenanceMantleBypassDepth.get(worldName); + int bypassDepth = 0; + if (bypassCounter != null) { + bypassDepth = bypassCounter.decrementAndGet(); + if (bypassDepth <= 0) { + worldMaintenanceMantleBypassDepth.remove(worldName, bypassCounter); + bypassDepth = 0; + } + } + + if (IrisSettings.get().getGeneral().isDebug()) { + IrisLogging.info("World maintenance exit: " + worldName + " reason=" + reason + " depth=" + depth + " bypassMantleDepth=" + bypassDepth); + } else { + IrisLogging.debug("World maintenance exit: " + worldName + " reason=" + reason + " depth=" + depth + " bypassMantleDepth=" + bypassDepth); + } + } + + public static boolean isWorldMaintenanceActive(String worldName) { + if (worldName == null) { + return false; + } + + AtomicInteger counter = worldMaintenanceDepth.get(worldName); + return counter != null && counter.get() > 0; + } + + public static boolean isWorldMaintenanceBypassingMantleStages(String worldName) { + if (worldName == null) { + return false; + } + + AtomicInteger counter = worldMaintenanceMantleBypassDepth.get(worldName); + return counter != null && counter.get() > 0; + } + + public static void retainMantleDataForSlice(String className) { + if (className == null) { + return; + } + + retainedMantleSlices.add(className); + } + + public static boolean isRetainingMantleDataForSlice(String className) { + return className != null && retainedMantleSlices.contains(className); + } +} diff --git a/core/src/main/java/art/arcane/iris/engine/IrisEngineMantle.java b/core/src/main/java/art/arcane/iris/engine/IrisEngineMantle.java index 7d6cb3e08..1326a9a49 100644 --- a/core/src/main/java/art/arcane/iris/engine/IrisEngineMantle.java +++ b/core/src/main/java/art/arcane/iris/engine/IrisEngineMantle.java @@ -20,7 +20,7 @@ package art.arcane.iris.engine; import art.arcane.iris.spi.IrisPlatforms; import art.arcane.iris.core.IrisSettings; -import art.arcane.iris.core.tools.IrisToolbelt; +import art.arcane.iris.core.tools.WorldMaintenance; import art.arcane.iris.engine.EnginePanic; import art.arcane.iris.core.nms.container.Pair; import art.arcane.iris.engine.data.cache.AtomicCache; @@ -327,7 +327,7 @@ public class IrisEngineMantle implements EngineMantle { @Override public boolean shouldRetainSlice(Class sliceType) { - return IrisToolbelt.isRetainingMantleDataForSlice(sliceType.getCanonicalName()); + return WorldMaintenance.isRetainingMantleDataForSlice(sliceType.getCanonicalName()); } @Override diff --git a/core/src/main/java/art/arcane/iris/engine/framework/Engine.java b/core/src/main/java/art/arcane/iris/engine/framework/Engine.java index a01d1511e..557cc3cb2 100644 --- a/core/src/main/java/art/arcane/iris/engine/framework/Engine.java +++ b/core/src/main/java/art/arcane/iris/engine/framework/Engine.java @@ -27,7 +27,7 @@ import art.arcane.iris.core.loader.IrisData; import art.arcane.iris.core.loader.IrisRegistrant; import art.arcane.iris.core.nms.container.BlockPos; import art.arcane.iris.core.nms.container.Pair; -import art.arcane.iris.core.tools.IrisToolbelt; +import art.arcane.iris.core.tools.WorldMaintenance; import art.arcane.iris.engine.IrisComplex; import art.arcane.iris.engine.UpperDimensionContext; import art.arcane.iris.engine.data.chunk.TerrainChunk; @@ -673,7 +673,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat return false; } String worldName = world.name(); - if (!IrisToolbelt.isWorldMaintenanceActive(worldName)) { + if (!WorldMaintenance.isWorldMaintenanceActive(worldName)) { return false; } PregeneratorJob pregeneratorJob = PregeneratorJob.getInstance(); diff --git a/core/src/main/java/art/arcane/iris/engine/framework/EngineMode.java b/core/src/main/java/art/arcane/iris/engine/framework/EngineMode.java index 831592450..babe12219 100644 --- a/core/src/main/java/art/arcane/iris/engine/framework/EngineMode.java +++ b/core/src/main/java/art/arcane/iris/engine/framework/EngineMode.java @@ -18,7 +18,7 @@ package art.arcane.iris.engine.framework; -import art.arcane.iris.core.tools.IrisToolbelt; +import art.arcane.iris.core.tools.WorldMaintenance; import art.arcane.iris.core.gui.PregeneratorJob; import art.arcane.iris.engine.IrisComplex; import art.arcane.iris.engine.mantle.EngineMantle; @@ -92,7 +92,7 @@ public interface EngineMode extends Staged { } private boolean shouldDisableContextCacheForMaintenance() { - boolean maintenanceActive = IrisToolbelt.isWorldMaintenanceActive(getEngine().getWorld().realWorld()); + boolean maintenanceActive = WorldMaintenance.isWorldMaintenanceActive(getEngine().getWorld().name()); if (!maintenanceActive) { return false; } diff --git a/core/src/main/java/art/arcane/iris/engine/mantle/MantleWriter.java b/core/src/main/java/art/arcane/iris/engine/mantle/MantleWriter.java index 4681bc1a7..1b0454390 100644 --- a/core/src/main/java/art/arcane/iris/engine/mantle/MantleWriter.java +++ b/core/src/main/java/art/arcane/iris/engine/mantle/MantleWriter.java @@ -23,7 +23,7 @@ import art.arcane.iris.spi.IrisLogging; import art.arcane.iris.util.project.matter.TileWrapper; import com.google.common.collect.ImmutableList; import art.arcane.iris.core.IrisSettings; -import art.arcane.iris.core.tools.IrisToolbelt; +import art.arcane.iris.core.tools.WorldMaintenance; import art.arcane.iris.core.loader.IrisData; import art.arcane.iris.engine.data.cache.Cache; import art.arcane.iris.engine.framework.Engine; @@ -74,7 +74,7 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable { this.z = z; final boolean foliaMaintenance = J.isFolia() - && IrisToolbelt.isWorldMaintenanceActive(engineMantle.getEngine().getWorld().realWorld()); + && WorldMaintenance.isWorldMaintenanceActive(engineMantle.getEngine().getWorld().name()); final int parallelism = foliaMaintenance ? 1 : (multicore ? Runtime.getRuntime().availableProcessors() / 2 : 4); if (foliaMaintenance && IrisSettings.get().getGeneral().isDebug()) { IrisLogging.info("MantleWriter using sequential chunk prefetch for maintenance regen at " + x + "," + z + "."); diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisDimension.java b/core/src/main/java/art/arcane/iris/engine/object/IrisDimension.java index 120984bd7..b385070de 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisDimension.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisDimension.java @@ -43,6 +43,7 @@ import art.arcane.iris.util.common.plugin.VolmitSender; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import lombok.ToString; import lombok.experimental.Accessors; import org.bukkit.World.Environment; import org.bukkit.block.Biome; @@ -56,7 +57,8 @@ import java.util.Map; @NoArgsConstructor @Desc("Represents a dimension") @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = false, doNotUseGetters = true) +@ToString(doNotUseGetters = true) public class IrisDimension extends IrisRegistrant { private final transient AtomicCache parallaxSize = new AtomicCache<>(); private final transient AtomicCache rockLayerGenerator = new AtomicCache<>(); diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisLoot.java b/core/src/main/java/art/arcane/iris/engine/object/IrisLoot.java index c06f069e5..ef9b126a8 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisLoot.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisLoot.java @@ -35,7 +35,9 @@ import art.arcane.volmlib.util.math.RNG; import art.arcane.iris.util.project.noise.CNG; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import lombok.ToString; import lombok.experimental.Accessors; import org.bukkit.DyeColor; import org.bukkit.Material; @@ -57,6 +59,8 @@ import java.util.Optional; @AllArgsConstructor @Desc("Represents a loot entry") @Data +@EqualsAndHashCode(doNotUseGetters = true) +@ToString(doNotUseGetters = true) public class IrisLoot { private final transient AtomicCache chance = new AtomicCache<>(); private final transient AtomicCache dyeColorResolved = new AtomicCache<>();