From 5142c048c719cd2c8b3f267f3cd6187f3849bac5 Mon Sep 17 00:00:00 2001 From: Brian Neumann-Fopiano Date: Thu, 11 Jun 2026 18:50:37 -0400 Subject: [PATCH] Plugin Eviction --- .gitignore | 2 + .../core/nms/v1_21_R7/CustomBiomeSource.java | 8 +- .../core/nms/v1_21_R7/IrisChunkGenerator.java | 10 +- .../iris/core/nms/v1_21_R7/NMSBinding.java | 40 ++++---- .../core/nms/v26_1_R1/CustomBiomeSource.java | 8 +- .../core/nms/v26_1_R1/IrisChunkGenerator.java | 10 +- .../iris/core/nms/v26_1_R1/NMSBinding.java | 50 +++++----- adapters/bukkit/plugin/build.gradle | 43 ++++++++ .../src/main/java/art/arcane/iris/Iris.java | 4 +- .../iris/core/commands/CommandDatapack.java | 0 .../iris/core/commands/CommandDeveloper.java | 3 +- .../iris/core/commands/CommandEdit.java | 0 .../iris/core/commands/CommandFind.java | 4 +- .../iris/core/commands/CommandIris.java | 4 +- .../iris/core/commands/CommandObject.java | 4 +- .../iris/core/commands/CommandPack.java | 0 .../iris/core/commands/CommandPregen.java | 0 .../iris/core/commands/CommandStructure.java | 0 .../iris/core/commands/CommandStudio.java | 6 +- .../iris/core/commands/CommandWhat.java | 0 .../arcane/iris/core/edit/BlockEditor.java | 0 .../iris/core/edit/BukkitBlockEditor.java | 0 .../iris/core/gui/NoiseExplorerGUI.java | 0 .../art/arcane/iris/core/gui/VisionGUI.java | 0 .../iris/core/link/IrisPapiExpansion.java | 0 .../arcane/iris/core/service/CommandSVC.java | 0 .../art/arcane/iris/core/service/EditSVC.java | 0 .../iris/core/service/IrisEngineSVC.java | 0 .../core/service/IrisIntegrationService.java | 0 .../art/arcane/iris/core/service/WandSVC.java | 0 .../arcane/iris/core/wand/WandSelection.java | 0 .../plugin}/src/main/resources/plugin.yml | 0 .../art/arcane/iris/IrisDiagnosticsTest.java | 0 .../iris/core/StudioRuntimeCleanupTest.java | 0 .../iris/core/service/IrisEngineSVCTest.java | 0 build.gradle | 1 + core/build.gradle | 18 +--- core/purity-allowlist.txt | 20 ---- .../java/art/arcane/iris/core/IrisWorlds.java | 34 +++++-- .../arcane/iris/core/ServerConfigurator.java | 79 +++++++-------- .../arcane/iris/core/edit/DustRevealer.java | 13 +-- .../arcane/iris/core/gui/PregeneratorJob.java | 16 +-- .../core/lifecycle/PaperLibBootstrap.java | 6 +- .../lifecycle/PaperLikeRuntimeBackend.java | 6 +- .../core/lifecycle/WorldLifecycleService.java | 16 +-- .../core/lifecycle/WorldLifecycleSupport.java | 4 +- .../core/runtime/StudioOpenCoordinator.java | 24 ++--- .../iris/core/runtime/WorldDeletionQueue.java | 29 ++++++ .../runtime/WorldRuntimeControlService.java | 14 +-- .../iris/core/safeguard/task/Diagnostic.java | 12 +-- .../iris/core/safeguard/task/Tasks.java | 19 +++- .../arcane/iris/core/service/BoardSVC.java | 8 +- .../arcane/iris/core/service/StudioSVC.java | 74 +++++++------- .../arcane/iris/engine/object/IrisObject.java | 1 - .../iris/platform/bukkit/BukkitPlatform.java | 12 +++ .../iris/util/common/misc/WebCache.java | 97 +++++++++++++++++++ .../context/ChunkContextPrefillPlanTest.java | 4 - settings.gradle | 1 + .../java/art/arcane/iris/spi/IrisLogging.java | 9 +- 59 files changed, 457 insertions(+), 256 deletions(-) create mode 100644 adapters/bukkit/plugin/build.gradle rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/Iris.java (99%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/commands/CommandDatapack.java (100%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/commands/CommandDeveloper.java (99%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/commands/CommandEdit.java (100%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/commands/CommandFind.java (98%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/commands/CommandIris.java (99%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/commands/CommandObject.java (99%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/commands/CommandPack.java (100%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/commands/CommandPregen.java (100%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/commands/CommandStructure.java (100%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/commands/CommandStudio.java (99%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/commands/CommandWhat.java (100%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/edit/BlockEditor.java (100%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/edit/BukkitBlockEditor.java (100%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/gui/NoiseExplorerGUI.java (100%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/gui/VisionGUI.java (100%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/link/IrisPapiExpansion.java (100%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/service/CommandSVC.java (100%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/service/EditSVC.java (100%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/service/IrisEngineSVC.java (100%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/service/IrisIntegrationService.java (100%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/service/WandSVC.java (100%) rename {core => adapters/bukkit/plugin}/src/main/java/art/arcane/iris/core/wand/WandSelection.java (100%) rename {core => adapters/bukkit/plugin}/src/main/resources/plugin.yml (100%) rename {core => adapters/bukkit/plugin}/src/test/java/art/arcane/iris/IrisDiagnosticsTest.java (100%) rename {core => adapters/bukkit/plugin}/src/test/java/art/arcane/iris/core/StudioRuntimeCleanupTest.java (100%) rename {core => adapters/bukkit/plugin}/src/test/java/art/arcane/iris/core/service/IrisEngineSVCTest.java (100%) create mode 100644 core/src/main/java/art/arcane/iris/core/runtime/WorldDeletionQueue.java create mode 100644 core/src/main/java/art/arcane/iris/util/common/misc/WebCache.java diff --git a/.gitignore b/.gitignore index 53ce7d898..f6ab8351f 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,5 @@ DataPackExamples/ TreeGenStuff/ dist/ +core/plugins/ +adapters/bukkit/plugin/plugins/ diff --git a/adapters/bukkit/nms/v1_21_R7/src/main/java/art/arcane/iris/core/nms/v1_21_R7/CustomBiomeSource.java b/adapters/bukkit/nms/v1_21_R7/src/main/java/art/arcane/iris/core/nms/v1_21_R7/CustomBiomeSource.java index 75d0b10a9..6519c70f0 100644 --- a/adapters/bukkit/nms/v1_21_R7/src/main/java/art/arcane/iris/core/nms/v1_21_R7/CustomBiomeSource.java +++ b/adapters/bukkit/nms/v1_21_R7/src/main/java/art/arcane/iris/core/nms/v1_21_R7/CustomBiomeSource.java @@ -1,7 +1,7 @@ package art.arcane.iris.core.nms.v1_21_R7; import com.mojang.serialization.MapCodec; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; import art.arcane.iris.engine.data.cache.AtomicCache; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.object.IrisBiome; @@ -101,7 +101,7 @@ public class CustomBiomeSource extends BiomeSource { if (i.getReturnType().equals(returns)) { i.setAccessible(true); try { - Iris.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()"); + IrisLogging.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()"); return i.invoke(in); } catch (Throwable e) { e.printStackTrace(); @@ -118,7 +118,7 @@ public class CustomBiomeSource extends BiomeSource { if (i.getType().equals(returnType)) { i.setAccessible(true); try { - Iris.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName()); + IrisLogging.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName()); return (T) i.get(in); } catch (IllegalAccessException e) { e.printStackTrace(); @@ -152,7 +152,7 @@ public class CustomBiomeSource extends BiomeSource { if (fallback != null) { m.put(j.getId(), fallback); } - Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); + IrisLogging.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); continue; } m.put(j.getId(), holder); diff --git a/adapters/bukkit/nms/v1_21_R7/src/main/java/art/arcane/iris/core/nms/v1_21_R7/IrisChunkGenerator.java b/adapters/bukkit/nms/v1_21_R7/src/main/java/art/arcane/iris/core/nms/v1_21_R7/IrisChunkGenerator.java index a570093ef..b724be667 100644 --- a/adapters/bukkit/nms/v1_21_R7/src/main/java/art/arcane/iris/core/nms/v1_21_R7/IrisChunkGenerator.java +++ b/adapters/bukkit/nms/v1_21_R7/src/main/java/art/arcane/iris/core/nms/v1_21_R7/IrisChunkGenerator.java @@ -2,7 +2,7 @@ package art.arcane.iris.core.nms.v1_21_R7; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.MapCodec; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.object.IrisImportedStructureControl; import art.arcane.iris.util.common.reflect.WrappedField; @@ -93,7 +93,7 @@ public class IrisChunkGenerator extends CustomChunkGenerator { return Pair.of(best, bestHolder); } } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); } if (!importedControl().active()) { return null; @@ -105,8 +105,8 @@ public class IrisChunkGenerator extends CustomChunkGenerator { try { return delegate.findNearestMapStructure(level, reachable, pos, radius, findUnexplored); } catch (Throwable e) { - Iris.error("Vanilla structure locate failed near " + pos.getX() + ", " + pos.getZ() + ": " + e); - Iris.reportError(e); + IrisLogging.error("Vanilla structure locate failed near " + pos.getX() + ", " + pos.getZ() + ": " + e); + IrisLogging.reportError(e); return null; } } @@ -254,7 +254,7 @@ public class IrisChunkGenerator extends CustomChunkGenerator { structureManager.startsForStructure(sectionPos, structure) .forEach(start -> start.placeInChunk(target, structureManager, this, random, placeArea, chunkPos)); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); } } index++; diff --git a/adapters/bukkit/nms/v1_21_R7/src/main/java/art/arcane/iris/core/nms/v1_21_R7/NMSBinding.java b/adapters/bukkit/nms/v1_21_R7/src/main/java/art/arcane/iris/core/nms/v1_21_R7/NMSBinding.java index 6e82a120c..69320da4e 100644 --- a/adapters/bukkit/nms/v1_21_R7/src/main/java/art/arcane/iris/core/nms/v1_21_R7/NMSBinding.java +++ b/adapters/bukkit/nms/v1_21_R7/src/main/java/art/arcane/iris/core/nms/v1_21_R7/NMSBinding.java @@ -1,7 +1,7 @@ package art.arcane.iris.core.nms.v1_21_R7; import com.mojang.brigadier.exceptions.CommandSyntaxException; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; import art.arcane.iris.core.nms.INMSBinding; import art.arcane.iris.core.nms.container.BiomeColor; import art.arcane.iris.core.nms.container.Pair; @@ -120,7 +120,7 @@ public class NMSBinding implements INMSBinding { if (i.getReturnType().equals(returns)) { i.setAccessible(true); try { - Iris.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()"); + IrisLogging.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()"); return i.invoke(in); } catch (Throwable e) { e.printStackTrace(); @@ -141,7 +141,7 @@ public class NMSBinding implements INMSBinding { if (i.getType().equals(returnType)) { i.setAccessible(true); try { - Iris.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName()); + IrisLogging.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName()); return (T) i.get(in); } catch (IllegalAccessException e) { e.printStackTrace(); @@ -223,7 +223,7 @@ public class NMSBinding implements INMSBinding { var level = ((CraftWorld) pos.getWorld()).getHandle(); var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()); if (!J.runAt(pos, () -> merge(level, blockPos, tag))) { - Iris.warn("[NMS] Failed to schedule tile deserialize at " + blockPos + " in world " + pos.getWorld().getName()); + IrisLogging.warn("[NMS] Failed to schedule tile deserialize at " + blockPos + " in world " + pos.getWorld().getName()); } } @@ -235,7 +235,7 @@ public class NMSBinding implements INMSBinding { try { var blockEntity = level.getBlockEntity(blockPos); if (blockEntity == null) { - Iris.warn("[NMS] BlockEntity not found at " + blockPos); + IrisLogging.warn("[NMS] BlockEntity not found at " + blockPos); var state = level.getBlockState(blockPos); if (!state.hasBlockEntity()) { return; @@ -248,8 +248,8 @@ public class NMSBinding implements INMSBinding { var accessor = new BlockDataAccessor(blockEntity, blockPos); accessor.setData(accessor.getData().merge(tag)); } catch (Throwable e) { - Iris.warn("[NMS] Failed to merge tile data at " + blockPos + ": " + e.getMessage()); - Iris.reportError(e); + IrisLogging.warn("[NMS] Failed to merge tile data at " + blockPos + ": " + e.getMessage()); + IrisLogging.reportError(e); } } @@ -398,7 +398,7 @@ public class NMSBinding implements INMSBinding { try { registry().lookupOrThrow(Registries.STRUCTURE).keySet().forEach(k -> keys.add(k.toString())); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); } return keys; } @@ -409,7 +409,7 @@ public class NMSBinding implements INMSBinding { try { registry().lookupOrThrow(Registries.STRUCTURE_SET).keySet().forEach(k -> keys.add(k.toString())); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); } return keys; } @@ -422,7 +422,7 @@ public class NMSBinding implements INMSBinding { BiomeSource source = level.getChunkSource().getGenerator().getBiomeSource(); keys.addAll(VanillaStructureBiomes.reachableStructureKeys(level, source)); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); } return keys; } @@ -433,7 +433,7 @@ public class NMSBinding implements INMSBinding { try { keys.addAll(VanillaStructureBiomes.structureBiomeKeys(registry(), structureKey)); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); } return keys; } @@ -446,7 +446,7 @@ public class NMSBinding implements INMSBinding { BiomeSource source = level.getChunkSource().getGenerator().getBiomeSource(); keys.addAll(VanillaStructureBiomes.possibleBiomeKeys(source)); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); } return keys; } @@ -530,7 +530,7 @@ public class NMSBinding implements INMSBinding { } a.incrementAndGet(); - Iris.debug("Custom Biome: " + i); + IrisLogging.debug("Custom Biome: " + i); }); return a.get(); @@ -617,12 +617,12 @@ public class NMSBinding implements INMSBinding { if (dimensionType != null) { String actualDimensionType = dimensionType.identifier().toString(); if (!dimensionType.identifier().getNamespace().equals("iris")) { - Iris.error("Loaded world %s with invalid dimension type! expected=%s actual=%s", world.getName(), expectedDimensionType, actualDimensionType); + IrisLogging.error("Loaded world %s with invalid dimension type! expected=%s actual=%s", world.getName(), expectedDimensionType, actualDimensionType); } else { - Iris.debug("Loaded world " + world.getName() + " with Iris dimension type " + actualDimensionType); + IrisLogging.debug("Loaded world " + world.getName() + " with Iris dimension type " + actualDimensionType); } } else { - Iris.error("Loaded world %s with unknown dimension type! expected=%s", world.getName(), expectedDimensionType); + IrisLogging.error("Loaded world %s with unknown dimension type! expected=%s", world.getName(), expectedDimensionType); } IrisChunkGenerator irisGenerator = new IrisChunkGenerator(worldGenContext.generator(), seed, engine, world); @@ -673,8 +673,8 @@ public class NMSBinding implements INMSBinding { } return null; } catch (Throwable e) { - Iris.error("Unable to get entity dimensions for " + entity + "!"); - Iris.reportError(e); + IrisLogging.error("Unable to get entity dimensions for " + entity + "!"); + IrisLogging.reportError(e); return null; } } @@ -800,7 +800,7 @@ public class NMSBinding implements INMSBinding { if (injected.getAndSet(true)) return true; try { - Iris.info("Injecting Bukkit"); + IrisLogging.info("Injecting Bukkit"); var buddy = new ByteBuddy(); buddy.redefine(ServerLevel.class) .visit(Advice.to(ServerLevelAdvice.class).on(ElementMatchers.isConstructor() @@ -817,7 +817,7 @@ public class NMSBinding implements INMSBinding { return true; } catch (Throwable e) { - Iris.error(C.RED + "Failed to inject Bukkit"); + IrisLogging.error(C.RED + "Failed to inject Bukkit"); e.printStackTrace(); } return false; diff --git a/adapters/bukkit/nms/v26_1_R1/src/main/java/art/arcane/iris/core/nms/v26_1_R1/CustomBiomeSource.java b/adapters/bukkit/nms/v26_1_R1/src/main/java/art/arcane/iris/core/nms/v26_1_R1/CustomBiomeSource.java index f992a6472..7eee970b7 100644 --- a/adapters/bukkit/nms/v26_1_R1/src/main/java/art/arcane/iris/core/nms/v26_1_R1/CustomBiomeSource.java +++ b/adapters/bukkit/nms/v26_1_R1/src/main/java/art/arcane/iris/core/nms/v26_1_R1/CustomBiomeSource.java @@ -1,7 +1,7 @@ package art.arcane.iris.core.nms.v26_1_R1; import com.mojang.serialization.MapCodec; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; import art.arcane.iris.engine.data.cache.AtomicCache; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.object.IrisBiome; @@ -101,7 +101,7 @@ public class CustomBiomeSource extends BiomeSource { if (i.getReturnType().equals(returns)) { i.setAccessible(true); try { - Iris.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()"); + IrisLogging.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()"); return i.invoke(in); } catch (Throwable e) { e.printStackTrace(); @@ -118,7 +118,7 @@ public class CustomBiomeSource extends BiomeSource { if (i.getType().equals(returnType)) { i.setAccessible(true); try { - Iris.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName()); + IrisLogging.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName()); return (T) i.get(in); } catch (IllegalAccessException e) { e.printStackTrace(); @@ -152,7 +152,7 @@ public class CustomBiomeSource extends BiomeSource { if (fallback != null) { m.put(j.getId(), fallback); } - Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); + IrisLogging.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); continue; } m.put(j.getId(), holder); diff --git a/adapters/bukkit/nms/v26_1_R1/src/main/java/art/arcane/iris/core/nms/v26_1_R1/IrisChunkGenerator.java b/adapters/bukkit/nms/v26_1_R1/src/main/java/art/arcane/iris/core/nms/v26_1_R1/IrisChunkGenerator.java index aa5eebdbf..e5b17af68 100644 --- a/adapters/bukkit/nms/v26_1_R1/src/main/java/art/arcane/iris/core/nms/v26_1_R1/IrisChunkGenerator.java +++ b/adapters/bukkit/nms/v26_1_R1/src/main/java/art/arcane/iris/core/nms/v26_1_R1/IrisChunkGenerator.java @@ -2,7 +2,7 @@ package art.arcane.iris.core.nms.v26_1_R1; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.MapCodec; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.object.IrisImportedStructureControl; import art.arcane.iris.util.common.reflect.WrappedField; @@ -93,7 +93,7 @@ public class IrisChunkGenerator extends CustomChunkGenerator { return Pair.of(best, bestHolder); } } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); } if (!importedControl().active()) { return null; @@ -105,8 +105,8 @@ public class IrisChunkGenerator extends CustomChunkGenerator { try { return delegate.findNearestMapStructure(level, reachable, pos, radius, findUnexplored); } catch (Throwable e) { - Iris.error("Vanilla structure locate failed near " + pos.getX() + ", " + pos.getZ() + ": " + e); - Iris.reportError(e); + IrisLogging.error("Vanilla structure locate failed near " + pos.getX() + ", " + pos.getZ() + ": " + e); + IrisLogging.reportError(e); return null; } } @@ -254,7 +254,7 @@ public class IrisChunkGenerator extends CustomChunkGenerator { structureManager.startsForStructure(sectionPos, structure) .forEach(start -> start.placeInChunk(target, structureManager, this, random, placeArea, chunkPos)); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); } } index++; diff --git a/adapters/bukkit/nms/v26_1_R1/src/main/java/art/arcane/iris/core/nms/v26_1_R1/NMSBinding.java b/adapters/bukkit/nms/v26_1_R1/src/main/java/art/arcane/iris/core/nms/v26_1_R1/NMSBinding.java index abaa1b1ae..55c81a301 100644 --- a/adapters/bukkit/nms/v26_1_R1/src/main/java/art/arcane/iris/core/nms/v26_1_R1/NMSBinding.java +++ b/adapters/bukkit/nms/v26_1_R1/src/main/java/art/arcane/iris/core/nms/v26_1_R1/NMSBinding.java @@ -1,7 +1,7 @@ package art.arcane.iris.core.nms.v26_1_R1; import com.mojang.brigadier.exceptions.CommandSyntaxException; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; import art.arcane.iris.core.nms.INMSBinding; import art.arcane.iris.core.nms.container.BiomeColor; import art.arcane.iris.core.nms.container.Pair; @@ -132,7 +132,7 @@ public class NMSBinding implements INMSBinding { if (i.getReturnType().equals(returns)) { i.setAccessible(true); try { - Iris.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()"); + IrisLogging.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()"); return i.invoke(in); } catch (Throwable e) { e.printStackTrace(); @@ -153,7 +153,7 @@ public class NMSBinding implements INMSBinding { if (i.getType().equals(returnType)) { i.setAccessible(true); try { - Iris.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName()); + IrisLogging.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName()); return (T) i.get(in); } catch (IllegalAccessException e) { e.printStackTrace(); @@ -235,7 +235,7 @@ public class NMSBinding implements INMSBinding { var level = ((CraftWorld) pos.getWorld()).getHandle(); var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()); if (!J.runAt(pos, () -> merge(level, blockPos, tag))) { - Iris.warn("[NMS] Failed to schedule tile deserialize at " + blockPos + " in world " + pos.getWorld().getName()); + IrisLogging.warn("[NMS] Failed to schedule tile deserialize at " + blockPos + " in world " + pos.getWorld().getName()); } } @@ -247,7 +247,7 @@ public class NMSBinding implements INMSBinding { try { var blockEntity = level.getBlockEntity(blockPos); if (blockEntity == null) { - Iris.warn("[NMS] BlockEntity not found at " + blockPos); + IrisLogging.warn("[NMS] BlockEntity not found at " + blockPos); var state = level.getBlockState(blockPos); if (!state.hasBlockEntity()) { return; @@ -260,8 +260,8 @@ public class NMSBinding implements INMSBinding { var accessor = new BlockDataAccessor(blockEntity, blockPos); accessor.setData(accessor.getData().merge(tag)); } catch (Throwable e) { - Iris.warn("[NMS] Failed to merge tile data at " + blockPos + ": " + e.getMessage()); - Iris.reportError(e); + IrisLogging.warn("[NMS] Failed to merge tile data at " + blockPos + ": " + e.getMessage()); + IrisLogging.reportError(e); } } @@ -410,7 +410,7 @@ public class NMSBinding implements INMSBinding { try { registry().lookupOrThrow(Registries.STRUCTURE).keySet().forEach(k -> keys.add(k.toString())); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); } return keys; } @@ -421,7 +421,7 @@ public class NMSBinding implements INMSBinding { try { registry().lookupOrThrow(Registries.STRUCTURE_SET).keySet().forEach(k -> keys.add(k.toString())); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); } return keys; } @@ -434,7 +434,7 @@ public class NMSBinding implements INMSBinding { BiomeSource source = level.getChunkSource().getGenerator().getBiomeSource(); keys.addAll(VanillaStructureBiomes.reachableStructureKeys(level, source)); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); } return keys; } @@ -445,7 +445,7 @@ public class NMSBinding implements INMSBinding { try { keys.addAll(VanillaStructureBiomes.structureBiomeKeys(registry(), structureKey)); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); } return keys; } @@ -458,7 +458,7 @@ public class NMSBinding implements INMSBinding { BiomeSource source = level.getChunkSource().getGenerator().getBiomeSource(); keys.addAll(VanillaStructureBiomes.possibleBiomeKeys(source)); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); } return keys; } @@ -480,7 +480,7 @@ public class NMSBinding implements INMSBinding { keys.add(group + "|" + id); } } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); } return keys; } @@ -511,7 +511,7 @@ public class NMSBinding implements INMSBinding { WorldgenRandom random = new WorldgenRandom(new XoroshiroRandomSource(seed)); return cf.place(level, generator, random, new BlockPos(x, y, z)); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); return false; } } @@ -576,7 +576,7 @@ public class NMSBinding implements INMSBinding { } return new int[]{box.minX(), box.minY(), box.minZ(), box.maxX(), box.maxY(), box.maxZ()}; } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); return null; } } @@ -665,7 +665,7 @@ public class NMSBinding implements INMSBinding { } a.incrementAndGet(); - Iris.debug("Custom Biome: " + i); + IrisLogging.debug("Custom Biome: " + i); }); return a.get(); @@ -767,7 +767,7 @@ public class NMSBinding implements INMSBinding { finishChunkRewrite(level, chunk); return true; } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); return false; } } @@ -798,7 +798,7 @@ public class NMSBinding implements INMSBinding { finishChunkRewrite(level, chunk); return true; } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); return false; } } @@ -846,12 +846,12 @@ public class NMSBinding implements INMSBinding { if (dimensionType != null) { String actualDimensionType = dimensionType.identifier().toString(); if (!dimensionType.identifier().getNamespace().equals("iris")) { - Iris.error("Loaded world %s with invalid dimension type! expected=%s actual=%s", world.getName(), expectedDimensionType, actualDimensionType); + IrisLogging.error("Loaded world %s with invalid dimension type! expected=%s actual=%s", world.getName(), expectedDimensionType, actualDimensionType); } else { - Iris.debug("Loaded world " + world.getName() + " with Iris dimension type " + actualDimensionType); + IrisLogging.debug("Loaded world " + world.getName() + " with Iris dimension type " + actualDimensionType); } } else { - Iris.error("Loaded world %s with unknown dimension type! expected=%s", world.getName(), expectedDimensionType); + IrisLogging.error("Loaded world %s with unknown dimension type! expected=%s", world.getName(), expectedDimensionType); } IrisChunkGenerator irisGenerator = new IrisChunkGenerator(worldGenContext.generator(), seed, engine, world); @@ -902,8 +902,8 @@ public class NMSBinding implements INMSBinding { } return null; } catch (Throwable e) { - Iris.error("Unable to get entity dimensions for " + entity + "!"); - Iris.reportError(e); + IrisLogging.error("Unable to get entity dimensions for " + entity + "!"); + IrisLogging.reportError(e); return null; } } @@ -1029,7 +1029,7 @@ public class NMSBinding implements INMSBinding { if (injected.getAndSet(true)) return true; try { - Iris.info("Injecting Bukkit"); + IrisLogging.info("Injecting Bukkit"); var buddy = new ByteBuddy(); buddy.redefine(ServerLevel.class) .visit(Advice.to(ServerLevelAdvice.class).on(ElementMatchers.isConstructor() @@ -1046,7 +1046,7 @@ public class NMSBinding implements INMSBinding { return true; } catch (Throwable e) { - Iris.error(C.RED + "Failed to inject Bukkit"); + IrisLogging.error(C.RED + "Failed to inject Bukkit"); e.printStackTrace(); } return false; diff --git a/adapters/bukkit/plugin/build.gradle b/adapters/bukkit/plugin/build.gradle new file mode 100644 index 000000000..19de7dd5c --- /dev/null +++ b/adapters/bukkit/plugin/build.gradle @@ -0,0 +1,43 @@ +def apiVersion = '26.1' +def mainClass = 'art.arcane.iris.Iris' + +String volmLibCoordinate = providers.gradleProperty('volmLibCoordinate') + .orElse('com.github.VolmitSoftware:VolmLib:master-SNAPSHOT') + .get() + +dependencies { + compileOnly(project(':core')) + compileOnly(volmLibCoordinate) { + changing = true + transitive = false + } + compileOnly(libs.spigot) + testImplementation('junit:junit:4.13.2') + testImplementation(libs.spigot) + testImplementation(libs.bstats) + testImplementation(libs.sentry) + testImplementation(project(':core')) + testImplementation(volmLibCoordinate) { + changing = true + transitive = false + } + compileOnly(libs.placeholderApi) + compileOnly(libs.multiverseCore) +} + +tasks.named('processResources').configure { + def pluginProperties = [ + name : rootProject.name, + version : rootProject.version, + apiVersion: apiVersion, + main : mainClass, + ] + inputs.properties(pluginProperties) + filesMatching('**/plugin.yml') { + expand(pluginProperties) + } +} + +tasks.named('jar', Jar).configure { + archiveBaseName.set('iris-bukkit-plugin') +} diff --git a/core/src/main/java/art/arcane/iris/Iris.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/Iris.java similarity index 99% rename from core/src/main/java/art/arcane/iris/Iris.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/Iris.java index 5988bf2cc..634f92aa5 100644 --- a/core/src/main/java/art/arcane/iris/Iris.java +++ b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/Iris.java @@ -78,7 +78,6 @@ import art.arcane.iris.util.common.misc.ServerProperties; import art.arcane.iris.util.simd.SimdSupport; import art.arcane.volmlib.util.scheduling.Queue; import art.arcane.volmlib.util.scheduling.ShurikenQueue; -import io.papermc.lib.PaperLib; import lombok.NonNull; import org.bukkit.*; import org.bukkit.block.data.BlockData; @@ -593,6 +592,7 @@ public class Iris extends VolmitPlugin implements Listener, ReloadAware { tickets = new ChunkTickets(); linkMultiverseCore = new MultiverseCoreLink(); IrisServices.register(MultiverseCoreLink.class, linkMultiverseCore); + IrisServices.register(art.arcane.iris.core.runtime.WorldDeletionQueue.class, (art.arcane.iris.core.runtime.WorldDeletionQueue) Iris::queueWorldDeletionOnStartup); settingsFile = getDataFile("settings.json"); configHotloadEngine = new ConfigHotloadEngine( Iris::isSettingsFile, @@ -912,7 +912,7 @@ public class Iris extends VolmitPlugin implements Listener, ReloadAware { for (Player i : getServer().getOnlinePlayers()) { final Runnable playerTask = () -> { i.setGameMode(GameMode.SPECTATOR); - PaperLib.teleportAsync(i, spawn); + BukkitPlatform.teleportAsync(i, spawn); }; if (!J.runEntity(i, playerTask)) { playerTask.run(); diff --git a/core/src/main/java/art/arcane/iris/core/commands/CommandDatapack.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandDatapack.java similarity index 100% rename from core/src/main/java/art/arcane/iris/core/commands/CommandDatapack.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandDatapack.java diff --git a/core/src/main/java/art/arcane/iris/core/commands/CommandDeveloper.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandDeveloper.java similarity index 99% rename from core/src/main/java/art/arcane/iris/core/commands/CommandDeveloper.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandDeveloper.java index ffdb4e1f5..e2848458c 100644 --- a/core/src/main/java/art/arcane/iris/core/commands/CommandDeveloper.java +++ b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandDeveloper.java @@ -22,6 +22,7 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import art.arcane.iris.Iris; +import art.arcane.iris.platform.bukkit.BukkitPlatform; import art.arcane.iris.core.IrisSettings; import art.arcane.iris.core.ServerConfigurator; import art.arcane.iris.core.nms.datapack.DataVersion; @@ -116,7 +117,7 @@ public class CommandDeveloper implements DirectorExecutor { for (int rz = centerZ - radius; rz <= centerZ + radius; rz++) { org.bukkit.ChunkSnapshot snapshot; try { - org.bukkit.Chunk loaded = io.papermc.lib.PaperLib.getChunkAtAsync(world, rx, rz, true).get(); + org.bukkit.Chunk loaded = art.arcane.iris.platform.bukkit.BukkitPlatform.chunkAtAsync(world, rx, rz, true).get(); snapshot = loaded.getChunkSnapshot(false, false, false); } catch (Throwable e) { Iris.reportError(e); diff --git a/core/src/main/java/art/arcane/iris/core/commands/CommandEdit.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandEdit.java similarity index 100% rename from core/src/main/java/art/arcane/iris/core/commands/CommandEdit.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandEdit.java diff --git a/core/src/main/java/art/arcane/iris/core/commands/CommandFind.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandFind.java similarity index 98% rename from core/src/main/java/art/arcane/iris/core/commands/CommandFind.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandFind.java index d2a2b4d4d..caf15671a 100644 --- a/core/src/main/java/art/arcane/iris/core/commands/CommandFind.java +++ b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandFind.java @@ -19,6 +19,7 @@ package art.arcane.iris.core.commands; import art.arcane.iris.Iris; +import art.arcane.iris.platform.bukkit.BukkitPlatform; import art.arcane.iris.core.service.ObjectStudioSaveService; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.framework.IrisStructureLocator; @@ -34,7 +35,6 @@ import art.arcane.volmlib.util.collection.KList; import art.arcane.volmlib.util.director.DirectorOrigin; import art.arcane.volmlib.util.director.annotations.Director; import art.arcane.volmlib.util.director.annotations.Param; -import io.papermc.lib.PaperLib; import org.bukkit.Location; import org.bukkit.NamespacedKey; import org.bukkit.Registry; @@ -145,7 +145,7 @@ public class CommandFind implements DirectorExecutor { Location at = result.getLocation(); int y = target.getWorld().getHighestBlockYAt(at.getBlockX(), at.getBlockZ()) + 2; Location dest = new Location(target.getWorld(), at.getBlockX() + 0.5, y, at.getBlockZ() + 0.5); - PaperLib.teleportAsync(target, dest); + BukkitPlatform.teleportAsync(target, dest); sender().sendMessage(C.GREEN + "Teleported to " + structure + " @ " + at.getBlockX() + ", " + at.getBlockZ()); } catch (Throwable t) { sender().sendMessage(C.RED + "Could not locate " + structure + ": " + t.getClass().getSimpleName()); diff --git a/core/src/main/java/art/arcane/iris/core/commands/CommandIris.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandIris.java similarity index 99% rename from core/src/main/java/art/arcane/iris/core/commands/CommandIris.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandIris.java index f9a78c62e..2bfe12a0e 100644 --- a/core/src/main/java/art/arcane/iris/core/commands/CommandIris.java +++ b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandIris.java @@ -19,6 +19,7 @@ package art.arcane.iris.core.commands; import art.arcane.iris.Iris; +import art.arcane.iris.platform.bukkit.BukkitPlatform; import art.arcane.iris.core.IrisSettings; import art.arcane.iris.core.IrisWorlds; import art.arcane.iris.core.ServerConfigurator; @@ -45,7 +46,6 @@ import art.arcane.iris.util.common.parallel.SyncExecutor; import art.arcane.iris.util.common.misc.ServerProperties; import art.arcane.iris.util.common.plugin.VolmitSender; import art.arcane.iris.util.common.scheduling.J; -import io.papermc.lib.PaperLib; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; @@ -294,7 +294,7 @@ public class CommandIris implements DirectorExecutor { final Location spawn = world.getSpawnLocation(); final Runnable teleportTask = () -> { - PaperLib.teleportAsync(target, spawn); + BukkitPlatform.teleportAsync(target, spawn); new VolmitSender(target).sendMessage(C.GREEN + "You have been teleported to " + world.getName() + "."); }; if (!J.runEntity(target, teleportTask)) { diff --git a/core/src/main/java/art/arcane/iris/core/commands/CommandObject.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandObject.java similarity index 99% rename from core/src/main/java/art/arcane/iris/core/commands/CommandObject.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandObject.java index 0550a421b..ed0b3955b 100644 --- a/core/src/main/java/art/arcane/iris/core/commands/CommandObject.java +++ b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandObject.java @@ -19,6 +19,7 @@ package art.arcane.iris.core.commands; import art.arcane.iris.Iris; +import art.arcane.iris.platform.bukkit.BukkitPlatform; import art.arcane.iris.core.link.WorldEditLink; import art.arcane.iris.core.loader.IrisData; import art.arcane.iris.core.loader.ResourceLoader; @@ -49,7 +50,6 @@ import art.arcane.iris.util.common.director.specialhandlers.ObjectTargetHandler; import art.arcane.iris.util.common.format.C; import art.arcane.iris.util.common.math.Direction; import art.arcane.volmlib.util.math.RNG; -import io.papermc.lib.PaperLib; import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; @@ -148,7 +148,7 @@ public class CommandObject implements DirectorExecutor { if (p != null) { Location target = new Location(world, 0.5D, 66D, 0.5D); J.runEntity(p, () -> { - PaperLib.teleportAsync(p, target).thenRun(() -> p.setGameMode(GameMode.CREATIVE)); + BukkitPlatform.teleportAsync(p, target).thenRun(() -> p.setGameMode(GameMode.CREATIVE)); }); } } diff --git a/core/src/main/java/art/arcane/iris/core/commands/CommandPack.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandPack.java similarity index 100% rename from core/src/main/java/art/arcane/iris/core/commands/CommandPack.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandPack.java diff --git a/core/src/main/java/art/arcane/iris/core/commands/CommandPregen.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandPregen.java similarity index 100% rename from core/src/main/java/art/arcane/iris/core/commands/CommandPregen.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandPregen.java diff --git a/core/src/main/java/art/arcane/iris/core/commands/CommandStructure.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandStructure.java similarity index 100% rename from core/src/main/java/art/arcane/iris/core/commands/CommandStructure.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandStructure.java diff --git a/core/src/main/java/art/arcane/iris/core/commands/CommandStudio.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandStudio.java similarity index 99% rename from core/src/main/java/art/arcane/iris/core/commands/CommandStudio.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandStudio.java index c23e5a129..22e4ff19f 100644 --- a/core/src/main/java/art/arcane/iris/core/commands/CommandStudio.java +++ b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandStudio.java @@ -19,6 +19,7 @@ package art.arcane.iris.core.commands; import art.arcane.iris.Iris; +import art.arcane.iris.platform.bukkit.BukkitPlatform; import art.arcane.iris.core.IrisSettings; import art.arcane.iris.core.gui.NoiseExplorerGUI; import art.arcane.iris.core.gui.VisionGUI; @@ -63,7 +64,6 @@ import art.arcane.iris.util.common.scheduling.J; import art.arcane.volmlib.util.scheduling.O; import art.arcane.volmlib.util.scheduling.PrecisionStopwatch; import art.arcane.iris.util.common.scheduling.jobs.ParallelRadiusJob; -import io.papermc.lib.PaperLib; import org.bukkit.*; import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryType; @@ -615,7 +615,7 @@ public class CommandStudio implements DirectorExecutor { sender().sendMessage(C.GREEN + "Sending you to the studio world!"); var player = player(); - PaperLib.teleportAsync(player(), Iris.service(StudioSVC.class) + BukkitPlatform.teleportAsync(player(), Iris.service(StudioSVC.class) .getActiveProject() .getActiveProvider() .getTarget() @@ -674,7 +674,7 @@ public class CommandStudio implements DirectorExecutor { pw.println("Iris Version: " + Iris.instance.getDescription().getVersion()); pw.println("Bukkit Version: " + Bukkit.getBukkitVersion()); pw.println("MC Version: " + Bukkit.getVersion()); - pw.println("PaperSpigot: " + (PaperLib.isPaper() ? "Yup!" : "Nope!")); + pw.println("PaperSpigot: " + (BukkitPlatform.isPaperServer() ? "Yup!" : "Nope!")); pw.println("Report Captured At: " + new Date()); pw.println("Chunks: (" + chunks.size() + "): "); diff --git a/core/src/main/java/art/arcane/iris/core/commands/CommandWhat.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandWhat.java similarity index 100% rename from core/src/main/java/art/arcane/iris/core/commands/CommandWhat.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/commands/CommandWhat.java diff --git a/core/src/main/java/art/arcane/iris/core/edit/BlockEditor.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/edit/BlockEditor.java similarity index 100% rename from core/src/main/java/art/arcane/iris/core/edit/BlockEditor.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/edit/BlockEditor.java diff --git a/core/src/main/java/art/arcane/iris/core/edit/BukkitBlockEditor.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/edit/BukkitBlockEditor.java similarity index 100% rename from core/src/main/java/art/arcane/iris/core/edit/BukkitBlockEditor.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/edit/BukkitBlockEditor.java diff --git a/core/src/main/java/art/arcane/iris/core/gui/NoiseExplorerGUI.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/gui/NoiseExplorerGUI.java similarity index 100% rename from core/src/main/java/art/arcane/iris/core/gui/NoiseExplorerGUI.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/gui/NoiseExplorerGUI.java diff --git a/core/src/main/java/art/arcane/iris/core/gui/VisionGUI.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/gui/VisionGUI.java similarity index 100% rename from core/src/main/java/art/arcane/iris/core/gui/VisionGUI.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/gui/VisionGUI.java diff --git a/core/src/main/java/art/arcane/iris/core/link/IrisPapiExpansion.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/link/IrisPapiExpansion.java similarity index 100% rename from core/src/main/java/art/arcane/iris/core/link/IrisPapiExpansion.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/link/IrisPapiExpansion.java diff --git a/core/src/main/java/art/arcane/iris/core/service/CommandSVC.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/service/CommandSVC.java similarity index 100% rename from core/src/main/java/art/arcane/iris/core/service/CommandSVC.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/service/CommandSVC.java diff --git a/core/src/main/java/art/arcane/iris/core/service/EditSVC.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/service/EditSVC.java similarity index 100% rename from core/src/main/java/art/arcane/iris/core/service/EditSVC.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/service/EditSVC.java diff --git a/core/src/main/java/art/arcane/iris/core/service/IrisEngineSVC.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/service/IrisEngineSVC.java similarity index 100% rename from core/src/main/java/art/arcane/iris/core/service/IrisEngineSVC.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/service/IrisEngineSVC.java diff --git a/core/src/main/java/art/arcane/iris/core/service/IrisIntegrationService.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/service/IrisIntegrationService.java similarity index 100% rename from core/src/main/java/art/arcane/iris/core/service/IrisIntegrationService.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/service/IrisIntegrationService.java diff --git a/core/src/main/java/art/arcane/iris/core/service/WandSVC.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/service/WandSVC.java similarity index 100% rename from core/src/main/java/art/arcane/iris/core/service/WandSVC.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/service/WandSVC.java diff --git a/core/src/main/java/art/arcane/iris/core/wand/WandSelection.java b/adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/wand/WandSelection.java similarity index 100% rename from core/src/main/java/art/arcane/iris/core/wand/WandSelection.java rename to adapters/bukkit/plugin/src/main/java/art/arcane/iris/core/wand/WandSelection.java diff --git a/core/src/main/resources/plugin.yml b/adapters/bukkit/plugin/src/main/resources/plugin.yml similarity index 100% rename from core/src/main/resources/plugin.yml rename to adapters/bukkit/plugin/src/main/resources/plugin.yml diff --git a/core/src/test/java/art/arcane/iris/IrisDiagnosticsTest.java b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/IrisDiagnosticsTest.java similarity index 100% rename from core/src/test/java/art/arcane/iris/IrisDiagnosticsTest.java rename to adapters/bukkit/plugin/src/test/java/art/arcane/iris/IrisDiagnosticsTest.java diff --git a/core/src/test/java/art/arcane/iris/core/StudioRuntimeCleanupTest.java b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/StudioRuntimeCleanupTest.java similarity index 100% rename from core/src/test/java/art/arcane/iris/core/StudioRuntimeCleanupTest.java rename to adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/StudioRuntimeCleanupTest.java diff --git a/core/src/test/java/art/arcane/iris/core/service/IrisEngineSVCTest.java b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/service/IrisEngineSVCTest.java similarity index 100% rename from core/src/test/java/art/arcane/iris/core/service/IrisEngineSVCTest.java rename to adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/service/IrisEngineSVCTest.java diff --git a/build.gradle b/build.gradle index e5dd17977..75a3dd807 100644 --- a/build.gradle +++ b/build.gradle @@ -102,6 +102,7 @@ dependencies { add('included', project(path: ":adapters:bukkit:nms:${key}", configuration: 'runtimeElements')) } add('included', project(path: ':core', configuration: 'shadow')) + add('included', project(path: ':adapters:bukkit:plugin', configuration: 'runtimeElements')) add('jarJar', project(':core:agent')) } diff --git a/core/build.gradle b/core/build.gradle index aefb0a295..6af94040f 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -39,8 +39,6 @@ plugins { alias(libs.plugins.kotlin.lombok) } -def apiVersion = '26.1' -def mainClass = 'art.arcane.iris.Iris' def lib = 'art.arcane.iris.util' String volmLibCoordinate = providers.gradleProperty('volmLibCoordinate') .orElse('com.github.VolmitSoftware:VolmLib:master-SNAPSHOT') @@ -225,21 +223,7 @@ tasks.named('test', Test).configure { jvmArgs('--add-modules', 'jdk.incubator.vector') } -tasks.named('processResources').configure { - /** - * Expand properties into plugin yml - */ - def pluginProperties = [ - name : rootProject.name, - version : rootProject.version, - apiVersion: apiVersion, - main : mainClass, - ] - inputs.properties(pluginProperties) - filesMatching('**/plugin.yml') { - expand(pluginProperties) - } -} +configurations.matching { it.name.startsWith('slim') }.all { } def runningTestTasks = gradle.startParameter.taskNames.any { String taskName -> taskName.toLowerCase().contains('test') } if (runningTestTasks) { diff --git a/core/purity-allowlist.txt b/core/purity-allowlist.txt index dbc21b63b..9bf47abec 100644 --- a/core/purity-allowlist.txt +++ b/core/purity-allowlist.txt @@ -1,22 +1,10 @@ -art/arcane/iris/core/commands/CommandDeveloper.java -art/arcane/iris/core/commands/CommandFind.java -art/arcane/iris/core/commands/CommandIris.java -art/arcane/iris/core/commands/CommandObject.java -art/arcane/iris/core/commands/CommandPregen.java -art/arcane/iris/core/commands/CommandStructure.java -art/arcane/iris/core/commands/CommandStudio.java -art/arcane/iris/core/commands/CommandWhat.java art/arcane/iris/core/datapack/DatapackIngestService.java -art/arcane/iris/core/edit/BlockEditor.java art/arcane/iris/core/edit/BlockSignal.java -art/arcane/iris/core/edit/BukkitBlockEditor.java art/arcane/iris/core/edit/DustRevealer.java art/arcane/iris/core/events/IrisEngineEvent.java art/arcane/iris/core/events/IrisEngineHotloadEvent.java art/arcane/iris/core/events/IrisLootEvent.java -art/arcane/iris/core/gui/NoiseExplorerGUI.java art/arcane/iris/core/gui/PregeneratorJob.java -art/arcane/iris/core/gui/VisionGUI.java art/arcane/iris/core/IrisRuntimeSchedulerMode.java art/arcane/iris/core/IrisWorlds.java art/arcane/iris/core/lifecycle/BukkitPublicBackend.java @@ -42,7 +30,6 @@ art/arcane/iris/core/link/data/MythicMobsDataProvider.java art/arcane/iris/core/link/data/NexoDataProvider.java art/arcane/iris/core/link/ExternalDataProvider.java art/arcane/iris/core/link/Identifier.java -art/arcane/iris/core/link/IrisPapiExpansion.java art/arcane/iris/core/link/MultiverseCoreLink.java art/arcane/iris/core/link/WorldEditLink.java art/arcane/iris/core/nms/datapack/v1206/DataFixerV1206.java @@ -72,17 +59,12 @@ art/arcane/iris/core/safeguard/Mode.java art/arcane/iris/core/safeguard/task/Tasks.java art/arcane/iris/core/ServerConfigurator.java art/arcane/iris/core/service/BoardSVC.java -art/arcane/iris/core/service/CommandSVC.java -art/arcane/iris/core/service/EditSVC.java art/arcane/iris/core/service/ExternalDataSVC.java art/arcane/iris/core/service/GlobalCacheSVC.java -art/arcane/iris/core/service/IrisEngineSVC.java -art/arcane/iris/core/service/IrisIntegrationService.java art/arcane/iris/core/service/ObjectStudioSaveService.java art/arcane/iris/core/service/ObjectSVC.java art/arcane/iris/core/service/StudioSVC.java art/arcane/iris/core/service/TreeSVC.java -art/arcane/iris/core/service/WandSVC.java art/arcane/iris/core/structure/BulkStructureImporter.java art/arcane/iris/core/structure/FeatureImporter.java art/arcane/iris/core/structure/StructureCaptureImporter.java @@ -95,7 +77,6 @@ art/arcane/iris/core/tools/IrisReflectiveAPI.java art/arcane/iris/core/tools/IrisToolbelt.java art/arcane/iris/core/tools/IrisWorldCreator.java art/arcane/iris/core/tools/TreePlausibilizer.java -art/arcane/iris/core/wand/WandSelection.java art/arcane/iris/engine/actuator/IrisBiomeActuator.java art/arcane/iris/engine/data/chunk/LinkedTerrainChunk.java art/arcane/iris/engine/data/chunk/TerrainChunk.java @@ -171,7 +152,6 @@ art/arcane/iris/engine/platform/BukkitChunkGenerator.java art/arcane/iris/engine/platform/DummyBiomeProvider.java art/arcane/iris/engine/platform/DummyChunkGenerator.java art/arcane/iris/engine/platform/studio/generators/ObjectStudioGenerator.java -art/arcane/iris/Iris.java art/arcane/iris/platform/bukkit/BukkitBiome.java art/arcane/iris/platform/bukkit/BukkitBlockState.java art/arcane/iris/platform/bukkit/BukkitEntityType.java diff --git a/core/src/main/java/art/arcane/iris/core/IrisWorlds.java b/core/src/main/java/art/arcane/iris/core/IrisWorlds.java index 84f0b06dc..fe1208ab0 100644 --- a/core/src/main/java/art/arcane/iris/core/IrisWorlds.java +++ b/core/src/main/java/art/arcane/iris/core/IrisWorlds.java @@ -3,7 +3,8 @@ package art.arcane.iris.core; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; +import art.arcane.iris.spi.IrisPlatforms; import art.arcane.iris.core.loader.IrisData; import art.arcane.iris.engine.data.cache.AtomicCache; import art.arcane.iris.engine.object.IrisDimension; @@ -36,7 +37,7 @@ public class IrisWorlds { public static IrisWorlds get() { return cache.aquire(() -> { - File file = Iris.instance.getDataFile("worlds.json"); + File file = IrisPlatforms.get().dataFile("worlds.json"); if (!file.exists()) { return new IrisWorlds(new KMap<>()); } @@ -46,9 +47,9 @@ public class IrisWorlds { KMap worlds = GSON.fromJson(json, TYPE); return new IrisWorlds(Objects.requireNonNullElseGet(worlds, KMap::new)); } catch (Throwable e) { - Iris.error("Failed to load worlds.json!"); + IrisLogging.error("Failed to load worlds.json!"); e.printStackTrace(); - Iris.reportError(e); + IrisLogging.reportError(e); } return new IrisWorlds(new KMap<>()); @@ -81,7 +82,7 @@ public class IrisWorlds { return getWorlds() .entrySet() .stream() - .map(entry -> Iris.loadDimension(entry.getKey(), entry.getValue())) + .map(entry -> loadDimension(entry.getKey(), entry.getValue())) .filter(Objects::nonNull); } @@ -93,12 +94,12 @@ public class IrisWorlds { clean(); if (!dirty) return; try { - IO.write(Iris.instance.getDataFile("worlds.json"), OutputStreamWriter::new, writer -> GSON.toJson(worlds, TYPE, writer)); + IO.write(IrisPlatforms.get().dataFile("worlds.json"), OutputStreamWriter::new, writer -> GSON.toJson(worlds, TYPE, writer)); dirty = false; } catch (IOException e) { - Iris.error("Failed to save worlds.json!"); + IrisLogging.error("Failed to save worlds.json!"); e.printStackTrace(); - Iris.reportError(e); + IrisLogging.reportError(e); } } @@ -134,4 +135,21 @@ public class IrisWorlds { return result; } + + private static art.arcane.iris.engine.object.IrisDimension loadDimension(String worldName, String id) { + java.io.File pack = new java.io.File(org.bukkit.Bukkit.getWorldContainer(), String.join(java.io.File.separator, worldName, "iris", "pack")); + art.arcane.iris.engine.object.IrisDimension dimension = pack.isDirectory() ? art.arcane.iris.core.loader.IrisData.get(pack).getDimensionLoader().load(id) : null; + if (dimension == null) { + dimension = art.arcane.iris.core.loader.IrisData.loadAnyDimension(id, null); + } + if (dimension == null) { + IrisLogging.warn("Unable to find dimension type " + id + " Looking for online packs..."); + art.arcane.iris.spi.IrisServices.get(art.arcane.iris.core.service.StudioSVC.class).downloadSearch(new art.arcane.iris.util.common.plugin.VolmitSender(org.bukkit.Bukkit.getConsoleSender()), id, false); + dimension = art.arcane.iris.core.loader.IrisData.loadAnyDimension(id, null); + if (dimension != null) { + IrisLogging.info("Resolved missing dimension, proceeding."); + } + } + return dimension; + } } diff --git a/core/src/main/java/art/arcane/iris/core/ServerConfigurator.java b/core/src/main/java/art/arcane/iris/core/ServerConfigurator.java index 2b9a1ce58..c8d801932 100644 --- a/core/src/main/java/art/arcane/iris/core/ServerConfigurator.java +++ b/core/src/main/java/art/arcane/iris/core/ServerConfigurator.java @@ -18,7 +18,8 @@ package art.arcane.iris.core; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; +import art.arcane.iris.spi.IrisPlatforms; import art.arcane.iris.core.datapack.DatapackIngestService; import art.arcane.iris.core.loader.IrisData; import art.arcane.iris.core.nms.INMS; @@ -98,8 +99,8 @@ public class ServerConfigurator { long spigotTimeout = TimeUnit.MINUTES.toSeconds(5); if (tt < spigotTimeout) { - Iris.warn("Updating spigot.yml timeout-time: " + tt + " -> " + spigotTimeout + " (5 minutes)"); - Iris.warn("You can disable this change (autoconfigureServer) in Iris settings, then change back the value."); + IrisLogging.warn("Updating spigot.yml timeout-time: " + tt + " -> " + spigotTimeout + " (5 minutes)"); + IrisLogging.warn("You can disable this change (autoconfigureServer) in Iris settings, then change back the value."); f.set("settings.timeout-time", spigotTimeout); f.save(spigotConfig); } @@ -113,8 +114,8 @@ public class ServerConfigurator { long watchdog = TimeUnit.MINUTES.toMillis(3); if (tt < watchdog) { - Iris.warn("Updating paper.yml watchdog early-warning-delay: " + tt + " -> " + watchdog + " (3 minutes)"); - Iris.warn("You can disable this change (autoconfigureServer) in Iris settings, then change back the value."); + IrisLogging.warn("Updating paper.yml watchdog early-warning-delay: " + tt + " -> " + watchdog + " (3 minutes)"); + IrisLogging.warn("You can disable this change (autoconfigureServer) in Iris settings, then change back the value."); f.set("watchdog.early-warning-delay", watchdog); f.save(spigotConfig); } @@ -141,7 +142,7 @@ public class ServerConfigurator { IDataFixer fixer = DataVersion.getDefault(); if (fixer == null) { DataVersion fallback = DataVersion.getLatest(); - Iris.warn("Primary datapack fixer was null, forcing latest fixer: " + fallback.getVersion()); + IrisLogging.warn("Primary datapack fixer was null, forcing latest fixer: " + fallback.getVersion()); fixer = fallback.get(); } return installDataPacks(fixer, fullInstall); @@ -149,13 +150,13 @@ public class ServerConfigurator { public static boolean installDataPacks(IDataFixer fixer, boolean fullInstall) { if (fixer == null) { - Iris.error("Unable to install datapacks, fixer is null!"); + IrisLogging.error("Unable to install datapacks, fixer is null!"); return false; } if (fullInstall) { - Iris.info("Checking Data Packs..."); + IrisLogging.info("Checking Data Packs..."); } else { - Iris.verbose("Checking Data Packs..."); + IrisLogging.debug("Checking Data Packs..."); } DimensionHeight height = new DimensionHeight(fixer); KList folders = getDatapacksFolder(); @@ -166,25 +167,25 @@ public class ServerConfigurator { stream.flatMap(height::merge) .parallel() .forEach(dim -> { - Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath()); + IrisLogging.debug(" Checking Dimension " + dim.getLoadFile().getPath()); dim.installBiomes(fixer, dim::getLoader, folders, biomes.computeIfAbsent(dim.getLoadKey(), k -> new KSet<>())); dim.installDimensionType(fixer, folders); }); } IrisDimension.writeShared(folders, height); if (fullInstall) { - Iris.info("Data Packs Setup!"); + IrisLogging.info("Data Packs Setup!"); } else { - Iris.verbose("Data Packs Setup!"); + IrisLogging.debug("Data Packs Setup!"); } return fullInstall && verifyDataPacksPost(IrisSettings.get().getAutoConfiguration().isAutoRestartOnCustomBiomeInstall()); } public static boolean installDataPacksIfChanged(boolean fullInstall) { - File packsDir = Iris.instance.getDataFolder("packs"); + File packsDir = IrisPlatforms.get().dataFolder("packs"); String current = computePackFingerprint(packsDir); - File cacheFile = new File(Iris.instance.getDataFolder("cache"), "datapack-fingerprint"); + File cacheFile = new File(IrisPlatforms.get().dataFolder("cache"), "datapack-fingerprint"); String cached = ""; if (cacheFile.exists()) { try { @@ -194,7 +195,7 @@ public class ServerConfigurator { } } if (!current.isEmpty() && current.equals(cached)) { - Iris.verbose("Data packs unchanged, skipping install."); + IrisLogging.debug("Data packs unchanged, skipping install."); return false; } boolean result = installDataPacks(fullInstall); @@ -202,7 +203,7 @@ public class ServerConfigurator { cacheFile.getParentFile().mkdirs(); Files.writeString(cacheFile.toPath(), current, StandardCharsets.UTF_8); } catch (IOException e) { - Iris.warn("Failed to write datapack fingerprint cache: " + e.getMessage()); + IrisLogging.warn("Failed to write datapack fingerprint cache: " + e.getMessage()); } return result; } @@ -286,7 +287,7 @@ public class ServerConfigurator { try (Stream stream = allPacks()) { boolean bad = stream .map(data -> { - Iris.verbose("Checking Pack: " + data.getDataFolder().getPath()); + IrisLogging.debug("Checking Pack: " + data.getDataFolder().getPath()); var loader = data.getDimensionLoader(); return loader.loadAll(loader.getPossibleKeys()) .stream() @@ -304,16 +305,16 @@ public class ServerConfigurator { if (allowRestarting) { restart(); } else if (INMS.get().supportsDataPacks()) { - Iris.error("============================================================================"); - Iris.error(C.ITALIC + "You need to restart your server to properly generate custom biomes."); - Iris.error(C.ITALIC + "By continuing, Iris will use backup biomes in place of the custom biomes."); - Iris.error("----------------------------------------------------------------------------"); - Iris.error(C.UNDERLINE + "IT IS HIGHLY RECOMMENDED YOU RESTART THE SERVER BEFORE GENERATING!"); - Iris.error("============================================================================"); + IrisLogging.error("============================================================================"); + IrisLogging.error(C.ITALIC + "You need to restart your server to properly generate custom biomes."); + IrisLogging.error(C.ITALIC + "By continuing, Iris will use backup biomes in place of the custom biomes."); + IrisLogging.error("----------------------------------------------------------------------------"); + IrisLogging.error(C.UNDERLINE + "IT IS HIGHLY RECOMMENDED YOU RESTART THE SERVER BEFORE GENERATING!"); + IrisLogging.error("============================================================================"); for (Player i : Bukkit.getOnlinePlayers()) { if (i.isOp() || i.hasPermission("iris.all")) { - VolmitSender sender = new VolmitSender(i, Iris.instance.getTag("WARNING")); + VolmitSender sender = new VolmitSender(i, art.arcane.iris.platform.bukkit.BukkitPlatform.volmitPlugin().getTag("WARNING")); sender.sendMessage("There are some Iris Packs that have custom biomes in them"); sender.sendMessage("You need to restart your server to use these packs."); } @@ -326,11 +327,11 @@ public class ServerConfigurator { public static void restart() { J.s(() -> { - Iris.warn("New data pack entries have been installed in Iris! Restarting server!"); - Iris.warn("This will only happen when your pack changes (updates/first time setup)"); - Iris.warn("(You can disable this auto restart in iris settings)"); + IrisLogging.warn("New data pack entries have been installed in Iris! Restarting server!"); + IrisLogging.warn("This will only happen when your pack changes (updates/first time setup)"); + IrisLogging.warn("(You can disable this auto restart in iris settings)"); J.s(() -> { - Iris.warn("Looks like the restart command didn't work. Stopping the server instead!"); + IrisLogging.warn("Looks like the restart command didn't work. Stopping the server instead!"); Bukkit.shutdown(); }, 100); Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "restart"); @@ -354,11 +355,11 @@ public class ServerConfigurator { if (!INMS.get().supportsDataPacks()) { if (!keys.isEmpty()) { - Iris.warn("==================================================================================="); - Iris.warn("Pack " + key + " has " + keys.size() + " custom biome(s). "); - Iris.warn("Your server version does not yet support datapacks for iris."); - Iris.warn("The world will generate these biomes as backup biomes."); - Iris.warn("===================================================================================="); + IrisLogging.warn("==================================================================================="); + IrisLogging.warn("Pack " + key + " has " + keys.size() + " custom biome(s). "); + IrisLogging.warn("Your server version does not yet support datapacks for iris."); + IrisLogging.warn("The world will generate these biomes as backup biomes."); + IrisLogging.warn("===================================================================================="); } return true; @@ -368,26 +369,26 @@ public class ServerConfigurator { Object o = INMS.get().getCustomBiomeBaseFor(i); if (o == null) { - Iris.warn("The Biome " + i + " is not registered on the server."); + IrisLogging.warn("The Biome " + i + " is not registered on the server."); warn = true; } } if (INMS.get().missingDimensionTypes(dimension.getDimensionTypeKey())) { - Iris.warn("The Dimension Type for " + dimension.getLoadFile() + " is not registered on the server."); + IrisLogging.warn("The Dimension Type for " + dimension.getLoadFile() + " is not registered on the server."); warn = true; } if (warn) { - Iris.error("The Pack " + key + " is INCAPABLE of generating custom biomes"); - Iris.error("If not done automatically, restart your server before generating with this pack!"); + IrisLogging.error("The Pack " + key + " is INCAPABLE of generating custom biomes"); + IrisLogging.error("If not done automatically, restart your server before generating with this pack!"); } return !warn; } public static Stream allPacks() { - File[] packs = Iris.instance.getDataFolder("packs").listFiles(File::isDirectory); + File[] packs = IrisPlatforms.get().dataFolder("packs").listFiles(File::isDirectory); Stream locals = packs == null ? Stream.empty() : Arrays.stream(packs); return Stream.concat(locals .filter( base -> { @@ -422,7 +423,7 @@ public class ServerConfigurator { } public Stream merge(IrisData data) { - Iris.verbose("Checking Pack: " + data.getDataFolder().getPath()); + IrisLogging.debug("Checking Pack: " + data.getDataFolder().getPath()); var loader = data.getDimensionLoader(); return loader.loadAll(loader.getPossibleKeys()) .stream() diff --git a/core/src/main/java/art/arcane/iris/core/edit/DustRevealer.java b/core/src/main/java/art/arcane/iris/core/edit/DustRevealer.java index 868489cb1..0e70e7632 100644 --- a/core/src/main/java/art/arcane/iris/core/edit/DustRevealer.java +++ b/core/src/main/java/art/arcane/iris/core/edit/DustRevealer.java @@ -18,7 +18,8 @@ package art.arcane.iris.core.edit; -import art.arcane.iris.Iris; +import art.arcane.iris.platform.bukkit.BukkitPlatform; +import art.arcane.iris.spi.IrisLogging; import art.arcane.iris.core.nms.INMS; import art.arcane.iris.core.tools.IrisToolbelt; import art.arcane.iris.engine.framework.Engine; @@ -101,7 +102,7 @@ public class DustRevealer { is(new BlockPosition(block.getX() + 1, block.getY() - 1, block.getZ() - 1)); is(new BlockPosition(block.getX() + 1, block.getY() - 1, block.getZ() + 1)); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); e.printStackTrace(); } }); @@ -195,7 +196,7 @@ public class DustRevealer { lines.add("Server biome: " + INMS.get().getTrueBiomeBaseKey(block.getLocation()) + " (ID: " + INMS.get().getTrueBiomeBaseId(INMS.get().getTrueBiomeBase(block.getLocation())) + ")"); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); } if (region != null) { @@ -255,7 +256,7 @@ public class DustRevealer { try { return supplier.get(); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); return null; } } @@ -269,9 +270,9 @@ public class DustRevealer { .color(NamedTextColor.GREEN) .clickEvent(ClickEvent.copyToClipboard(payload)) .hoverEvent(HoverEvent.showText(Component.text("Copy block stats to clipboard"))); - Iris.audiences.player(sender.player()).sendMessage(button); + BukkitPlatform.audiences().player(sender.player()).sendMessage(button); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); } } diff --git a/core/src/main/java/art/arcane/iris/core/gui/PregeneratorJob.java b/core/src/main/java/art/arcane/iris/core/gui/PregeneratorJob.java index 40a1a9815..0cd61e997 100644 --- a/core/src/main/java/art/arcane/iris/core/gui/PregeneratorJob.java +++ b/core/src/main/java/art/arcane/iris/core/gui/PregeneratorJob.java @@ -18,7 +18,9 @@ package art.arcane.iris.core.gui; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; +import art.arcane.iris.spi.IrisServices; +import art.arcane.iris.spi.IrisPlatforms; import art.arcane.iris.core.IrisSettings; import art.arcane.iris.core.pregenerator.IrisPregenerator; import art.arcane.iris.core.pregenerator.PregenListener; @@ -183,8 +185,8 @@ public class PregeneratorJob implements PregenListener { try { return Color.decode(v); } catch (Throwable e) { - Iris.reportError(e); - Iris.error("Error Parsing 'color', (" + c + ")"); + IrisLogging.reportError(e); + IrisLogging.error("Error Parsing 'color', (" + c + ")"); } return Color.RED; @@ -217,7 +219,7 @@ public class PregeneratorJob implements PregenListener { renderer.func.accept(new Position2(x, z), color); } } catch (Throwable ignored) { - Iris.error("Failed to draw pregen"); + IrisLogging.error("Failed to draw pregen"); } } @@ -236,7 +238,7 @@ public class PregeneratorJob implements PregenListener { J.sleep(3000); frame.setVisible(false); } catch (Throwable ignored) { - Iris.error("Error closing pregen gui"); + IrisLogging.error("Error closing pregen gui"); } }); } @@ -259,7 +261,7 @@ public class PregeneratorJob implements PregenListener { frame.setSize(1000, 1000); frame.setVisible(true); } catch (Throwable ignored) { - Iris.error("Error opening pregen gui"); + IrisLogging.error("Error opening pregen gui"); } }); } @@ -421,7 +423,7 @@ public class PregeneratorJob implements PregenListener { try { order.pop().run(); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); } } diff --git a/core/src/main/java/art/arcane/iris/core/lifecycle/PaperLibBootstrap.java b/core/src/main/java/art/arcane/iris/core/lifecycle/PaperLibBootstrap.java index 3805ca4f4..1da04f38a 100644 --- a/core/src/main/java/art/arcane/iris/core/lifecycle/PaperLibBootstrap.java +++ b/core/src/main/java/art/arcane/iris/core/lifecycle/PaperLibBootstrap.java @@ -1,6 +1,8 @@ package art.arcane.iris.core.lifecycle; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; +import art.arcane.iris.spi.IrisServices; +import art.arcane.iris.spi.IrisPlatforms; import io.papermc.lib.PaperLib; import io.papermc.lib.environments.PaperEnvironment; import org.bukkit.Bukkit; @@ -30,7 +32,7 @@ public final class PaperLibBootstrap { } PaperLib.setCustomEnvironment(new ModernPaperEnvironment()); - Iris.info("PaperLib version detection failed for MC " + bukkitVersion + "; forced modern Paper environment"); + IrisLogging.info("PaperLib version detection failed for MC " + bukkitVersion + "; forced modern Paper environment"); } static boolean isModernVersionScheme(String bukkitVersion) { diff --git a/core/src/main/java/art/arcane/iris/core/lifecycle/PaperLikeRuntimeBackend.java b/core/src/main/java/art/arcane/iris/core/lifecycle/PaperLikeRuntimeBackend.java index 1b96c9247..03aa84124 100644 --- a/core/src/main/java/art/arcane/iris/core/lifecycle/PaperLikeRuntimeBackend.java +++ b/core/src/main/java/art/arcane/iris/core/lifecycle/PaperLikeRuntimeBackend.java @@ -1,6 +1,8 @@ package art.arcane.iris.core.lifecycle; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; +import art.arcane.iris.spi.IrisServices; +import art.arcane.iris.spi.IrisPlatforms; import org.bukkit.Bukkit; import org.bukkit.World; @@ -44,7 +46,7 @@ final class PaperLikeRuntimeBackend implements WorldLifecycleBackend { WorldLifecycleStaging.stageGenerator(request.worldName(), request.generator(), request.biomeProvider()); WorldLifecycleSupport.stageRuntimeConfiguration(request.worldName()); - Iris.debug("WorldLifecycle runtime LevelStem: world=" + request.worldName() + IrisLogging.debug("WorldLifecycle runtime LevelStem: world=" + request.worldName() + ", backend=paper_like_runtime, flavor=" + capabilities.paperLikeFlavor().name().toLowerCase(Locale.ROOT) + ", registrySource=" + WorldLifecycleSupport.runtimeLevelStemRegistrySource(request)); Object levelStem = WorldLifecycleSupport.resolveRuntimeLevelStem(capabilities, request); diff --git a/core/src/main/java/art/arcane/iris/core/lifecycle/WorldLifecycleService.java b/core/src/main/java/art/arcane/iris/core/lifecycle/WorldLifecycleService.java index b70edc1ae..672a37e0f 100644 --- a/core/src/main/java/art/arcane/iris/core/lifecycle/WorldLifecycleService.java +++ b/core/src/main/java/art/arcane/iris/core/lifecycle/WorldLifecycleService.java @@ -1,6 +1,8 @@ package art.arcane.iris.core.lifecycle; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; +import art.arcane.iris.spi.IrisServices; +import art.arcane.iris.spi.IrisPlatforms; import art.arcane.iris.util.common.scheduling.J; import org.bukkit.World; @@ -42,7 +44,7 @@ public final class WorldLifecycleService { CapabilitySnapshot capabilities = CapabilitySnapshot.probe(); instance = new WorldLifecycleService(capabilities); - Iris.info("WorldLifecycle capabilities: %s", capabilities.describe()); + IrisLogging.info("WorldLifecycle capabilities: %s", capabilities.describe()); return instance; } } @@ -56,18 +58,18 @@ public final class WorldLifecycleService { try { backend = selectCreateBackend(request); } catch (Throwable e) { - Iris.reportError("WorldLifecycle create backend selection failed for world=\"" + request.worldName() + IrisLogging.reportError("WorldLifecycle create backend selection failed for world=\"" + request.worldName() + "\", caller=" + request.callerKind().name().toLowerCase() + ".", e); return CompletableFuture.failedFuture(e); } - Iris.info("WorldLifecycle create: world=%s, caller=%s, backend=%s", + IrisLogging.info("WorldLifecycle create: world=%s, caller=%s, backend=%s", request.worldName(), request.callerKind().name().toLowerCase(), backend.backendName()); return backend.create(request).whenComplete((world, throwable) -> { if (throwable != null) { Throwable cause = WorldLifecycleSupport.unwrap(throwable); - Iris.reportError("WorldLifecycle create failed: world=\"" + request.worldName() + IrisLogging.reportError("WorldLifecycle create failed: world=\"" + request.worldName() + "\", caller=" + request.callerKind().name().toLowerCase() + ", backend=" + backend.backendName() + ", family=" + capabilities.serverFamily().id() + ".", cause); @@ -105,14 +107,14 @@ public final class WorldLifecycleService { private boolean unloadDirect(World world, boolean save) { WorldLifecycleBackend backend = selectUnloadBackend(world.getName()); - Iris.info("WorldLifecycle unload: world=%s, backend=%s", + IrisLogging.info("WorldLifecycle unload: world=%s, backend=%s", world.getName(), backend.backendName()); boolean unloaded; try { unloaded = backend.unload(world, save); } catch (Throwable e) { - Iris.reportError("WorldLifecycle unload failed: world=\"" + world.getName() + IrisLogging.reportError("WorldLifecycle unload failed: world=\"" + world.getName() + "\", backend=" + backend.backendName() + ", family=" + capabilities.serverFamily().id() + ".", e); if (e instanceof RuntimeException runtimeException) { diff --git a/core/src/main/java/art/arcane/iris/core/lifecycle/WorldLifecycleSupport.java b/core/src/main/java/art/arcane/iris/core/lifecycle/WorldLifecycleSupport.java index a09df22e4..7f14f307e 100644 --- a/core/src/main/java/art/arcane/iris/core/lifecycle/WorldLifecycleSupport.java +++ b/core/src/main/java/art/arcane/iris/core/lifecycle/WorldLifecycleSupport.java @@ -1,6 +1,8 @@ package art.arcane.iris.core.lifecycle; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; +import art.arcane.iris.spi.IrisServices; +import art.arcane.iris.spi.IrisPlatforms; import art.arcane.iris.core.link.Identifier; import art.arcane.iris.core.nms.INMS; import art.arcane.iris.core.nms.INMSBinding; diff --git a/core/src/main/java/art/arcane/iris/core/runtime/StudioOpenCoordinator.java b/core/src/main/java/art/arcane/iris/core/runtime/StudioOpenCoordinator.java index 055f1c246..bc85b1bbc 100644 --- a/core/src/main/java/art/arcane/iris/core/runtime/StudioOpenCoordinator.java +++ b/core/src/main/java/art/arcane/iris/core/runtime/StudioOpenCoordinator.java @@ -1,6 +1,8 @@ package art.arcane.iris.core.runtime; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; +import art.arcane.iris.spi.IrisServices; +import art.arcane.iris.spi.IrisPlatforms; import art.arcane.iris.core.lifecycle.WorldLifecycleService; import art.arcane.iris.core.project.IrisProject; import art.arcane.iris.core.tools.IrisCreator; @@ -87,7 +89,7 @@ public final class StudioOpenCoordinator { try { long openStart = System.currentTimeMillis(); long t = openStart; - Iris.debug("[Studio timing] ===== studio open START: " + request.worldName() + " ====="); + IrisLogging.debug("[Studio timing] ===== studio open START: " + request.worldName() + " ====="); updateStage(request, "resolve_dimension", 0.04D); if (IrisToolbelt.getDimension(request.dimensionKey()) == null) { throw new IrisException("Dimension cannot be found for id " + request.dimensionKey() + "."); @@ -186,16 +188,16 @@ public final class StudioOpenCoordinator { } t = logStudioPhase("finalize + openVSCode", t, openStart); - Iris.info("Studio open: " + world.getName() + " ready in " + (System.currentTimeMillis() - openStart) + "ms"); + IrisLogging.info("Studio open: " + world.getName() + " ready in " + (System.currentTimeMillis() - openStart) + "ms"); future.complete(new StudioOpenResult(world, safeEntry)); } catch (Throwable e) { - Iris.reportError("Studio open failed for world \"" + request.worldName() + "\".", e); + IrisLogging.reportError("Studio open failed for world \"" + request.worldName() + "\".", e); if (!request.retainOnFailure()) { try { updateStage(request, "cleanup", 1.00D); closeWorld(provider, request.worldName(), world, true, request.project()); } catch (Throwable cleanupError) { - Iris.reportError("Studio cleanup failed for world \"" + request.worldName() + "\".", cleanupError); + IrisLogging.reportError("Studio cleanup failed for world \"" + request.worldName() + "\".", cleanupError); } } future.completeExceptionally(e); @@ -204,7 +206,7 @@ public final class StudioOpenCoordinator { private long logStudioPhase(String phase, long t, long openStart) { long now = System.currentTimeMillis(); - Iris.debug("[Studio timing] " + phase + " = " + (now - t) + "ms (cumulative " + (now - openStart) + "ms)"); + IrisLogging.debug("[Studio timing] " + phase + " = " + (now - t) + "ms (cumulative " + (now - openStart) + "ms)"); return now; } @@ -219,7 +221,7 @@ public final class StudioOpenCoordinator { CompletableFuture loaded = new CompletableFuture<>(); J.s(() -> { try { - world.addPluginChunkTicket(chunkX, chunkZ, Iris.instance); + world.addPluginChunkTicket(chunkX, chunkZ, art.arcane.iris.platform.bukkit.BukkitPlatform.plugin()); } catch (Throwable t) { loaded.completeExceptionally(t); return; @@ -331,7 +333,7 @@ public final class StudioOpenCoordinator { continue; } - Iris.linkMultiverseCore.removeFromConfig(familyWorld); + IrisServices.get(art.arcane.iris.core.link.MultiverseCoreLink.class).removeFromConfig(familyWorld); WorldLifecycleService.get().unload(familyWorld, false); } } @@ -353,7 +355,7 @@ public final class StudioOpenCoordinator { deleteWorldFolderAsync(folder, 40).get(15L, TimeUnit.SECONDS); } catch (Throwable e) { liveDeleted = false; - Iris.reportError("Studio folder deletion retries failed for \"" + folder.getAbsolutePath() + "\".", unwrapFailure(e)); + IrisLogging.reportError("Studio folder deletion retries failed for \"" + folder.getAbsolutePath() + "\".", unwrapFailure(e)); } if (folder.exists()) { @@ -366,11 +368,11 @@ public final class StudioOpenCoordinator { } try { - Iris.queueWorldDeletionOnStartup(Collections.singleton(worldName)); + IrisServices.get(WorldDeletionQueue.class).queueForStartupDeletion(Collections.singleton(worldName)); return new WorldFamilyDeleteResult(false, true); } catch (IOException e) { if (unloadCompletedLive) { - Iris.reportError("Failed to queue deferred deletion for world \"" + worldName + "\".", e); + IrisLogging.reportError("Failed to queue deferred deletion for world \"" + worldName + "\".", e); } return new WorldFamilyDeleteResult(false, false); } diff --git a/core/src/main/java/art/arcane/iris/core/runtime/WorldDeletionQueue.java b/core/src/main/java/art/arcane/iris/core/runtime/WorldDeletionQueue.java new file mode 100644 index 000000000..edc06cac3 --- /dev/null +++ b/core/src/main/java/art/arcane/iris/core/runtime/WorldDeletionQueue.java @@ -0,0 +1,29 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2026 Arcane Arts (Volmit Software) + * + * 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 art.arcane.iris.core.runtime; + +import java.io.IOException; +import java.util.Collection; + +/** + * Queues world folders for deletion at next startup. + */ +public interface WorldDeletionQueue { + int queueForStartupDeletion(Collection worldNames) throws IOException; +} 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 47200a886..83005030c 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 @@ -1,6 +1,8 @@ package art.arcane.iris.core.runtime; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; +import art.arcane.iris.spi.IrisServices; +import art.arcane.iris.spi.IrisPlatforms; import art.arcane.iris.core.IrisSettings; import art.arcane.iris.core.lifecycle.CapabilitySnapshot; import art.arcane.iris.core.lifecycle.ServerFamily; @@ -58,7 +60,7 @@ public final class WorldRuntimeControlService { CapabilitySnapshot capabilities = WorldLifecycleService.get().capabilities(); instance = new WorldRuntimeControlService(capabilities); - Iris.info("WorldRuntimeControl capabilities: %s", instance.capabilityDescription); + IrisLogging.info("WorldRuntimeControl capabilities: %s", instance.capabilityDescription); return instance; } } @@ -80,7 +82,7 @@ public final class WorldRuntimeControlService { return false; } - Iris.linkMultiverseCore.removeFromConfig(world); + IrisServices.get(art.arcane.iris.core.link.MultiverseCoreLink.class).removeFromConfig(world); setIntGameRule(world, 0, "SPAWN_CHUNK_RADIUS", "spawnChunkRadius"); if (!IrisSettings.get().getStudio().isDisableTimeAndWeather()) { return true; @@ -157,7 +159,7 @@ public final class WorldRuntimeControlService { backend.syncTime(world); return true; } catch (Throwable e) { - Iris.reportError("Runtime time control failed for world \"" + world.getName() + "\".", e); + IrisLogging.reportError("Runtime time control failed for world \"" + world.getName() + "\".", e); return false; } } @@ -185,7 +187,7 @@ public final class WorldRuntimeControlService { engine.getMantle().getComponents(); engine.getMantle().getRealRadius(); } catch (Throwable e) { - Iris.reportError("Failed to prepare generator state for world \"" + world.getName() + "\".", e); + IrisLogging.reportError("Failed to prepare generator state for world \"" + world.getName() + "\".", e); } } @@ -263,7 +265,7 @@ public final class WorldRuntimeControlService { } if (Boolean.TRUE.equals(success)) { - J.runEntity(player, () -> Iris.service(BoardSVC.class).updatePlayer(player)); + J.runEntity(player, () -> IrisServices.get(BoardSVC.class).updatePlayer(player)); future.complete(true); return; } diff --git a/core/src/main/java/art/arcane/iris/core/safeguard/task/Diagnostic.java b/core/src/main/java/art/arcane/iris/core/safeguard/task/Diagnostic.java index 132a6310f..7b69cef02 100644 --- a/core/src/main/java/art/arcane/iris/core/safeguard/task/Diagnostic.java +++ b/core/src/main/java/art/arcane/iris/core/safeguard/task/Diagnostic.java @@ -1,6 +1,6 @@ package art.arcane.iris.core.safeguard.task; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; import art.arcane.iris.util.common.format.C; import java.io.ByteArrayOutputStream; @@ -82,11 +82,11 @@ public class Diagnostic { } public enum Logger { - DEBUG(Iris::debug), - RAW(Iris::msg), - INFO(Iris::info), - WARN(Iris::warn), - ERROR(Iris::error); + DEBUG(IrisLogging::debug), + RAW(IrisLogging::msg), + INFO(IrisLogging::info), + WARN(IrisLogging::warn), + ERROR(IrisLogging::error); private final Consumer logger; 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 ca7982939..6aee4290b 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 @@ -1,6 +1,6 @@ package art.arcane.iris.core.safeguard.task; -import art.arcane.iris.Iris; +import art.arcane.iris.platform.bukkit.BukkitPlatform; import art.arcane.iris.core.IrisWorlds; import art.arcane.iris.core.nms.INMS; import art.arcane.iris.core.nms.v1X.NMSBinding1X; @@ -85,7 +85,7 @@ public final class Tasks { }); private static final Task VERSION = Task.of("version", () -> { - String[] parts = Iris.instance.getDescription().getVersion().split("-"); + String[] parts = BukkitPlatform.plugin().getDescription().getVersion().split("-"); String supportedVersions; if (parts.length >= 3) { String minVersion = parts[1]; @@ -147,7 +147,7 @@ public final class Tasks { }); private static final Task JAVA = Task.of("java", () -> { - int version = Iris.getJavaVersion(); + int version = javaVersion(); if (version == 25) { return withDiagnostics(Mode.STABLE); } @@ -208,4 +208,17 @@ public final class Tasks { private static ValueWithDiagnostics withDiagnostics(Mode mode, List diagnostics) { return new ValueWithDiagnostics<>(mode, diagnostics); } + + private static int javaVersion() { + String version = System.getProperty("java.version"); + if (version.startsWith("1.")) { + version = version.substring(2, 3); + } else { + int dot = version.indexOf("."); + if (dot != -1) { + version = version.substring(0, dot); + } + } + return Integer.parseInt(version); + } } diff --git a/core/src/main/java/art/arcane/iris/core/service/BoardSVC.java b/core/src/main/java/art/arcane/iris/core/service/BoardSVC.java index 774c8e4d7..edb8f543a 100644 --- a/core/src/main/java/art/arcane/iris/core/service/BoardSVC.java +++ b/core/src/main/java/art/arcane/iris/core/service/BoardSVC.java @@ -18,7 +18,9 @@ package art.arcane.iris.core.service; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; +import art.arcane.iris.spi.IrisServices; +import art.arcane.iris.spi.IrisPlatforms; import art.arcane.iris.core.IrisSettings; import art.arcane.iris.core.loader.IrisData; import art.arcane.iris.core.tools.IrisToolbelt; @@ -65,7 +67,7 @@ public class BoardSVC implements IrisService, BoardProvider { cleanupLeakedMainScoreboard(); - for (Player player : Iris.instance.getServer().getOnlinePlayers()) { + for (Player player : art.arcane.iris.platform.bukkit.BukkitPlatform.volmitPlugin().getServer().getOnlinePlayers()) { J.runEntity(player, () -> updatePlayer(player)); } } @@ -95,7 +97,7 @@ public class BoardSVC implements IrisService, BoardProvider { team.unregister(); } } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); } } diff --git a/core/src/main/java/art/arcane/iris/core/service/StudioSVC.java b/core/src/main/java/art/arcane/iris/core/service/StudioSVC.java index 218ab2b3b..6562fe05a 100644 --- a/core/src/main/java/art/arcane/iris/core/service/StudioSVC.java +++ b/core/src/main/java/art/arcane/iris/core/service/StudioSVC.java @@ -19,7 +19,9 @@ package art.arcane.iris.core.service; import com.google.gson.JsonSyntaxException; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; +import art.arcane.iris.spi.IrisServices; +import art.arcane.iris.spi.IrisPlatforms; import art.arcane.iris.core.IrisSettings; import art.arcane.iris.core.ServerConfigurator; import art.arcane.iris.core.lifecycle.WorldLifecycleService; @@ -71,11 +73,11 @@ public class StudioSVC implements IrisService { if (!f.exists()) { if (pack.equals("overworld")) { - Iris.info("Downloading Default Pack " + pack + " (latest on master)"); - Iris.service(StudioSVC.class).downloadBranch(Iris.getSender(), "IrisDimensions/overworld", "master", false); + IrisLogging.info("Downloading Default Pack " + pack + " (latest on master)"); + IrisServices.get(StudioSVC.class).downloadBranch(art.arcane.iris.platform.bukkit.BukkitPlatform.console(), "IrisDimensions/overworld", "master", false); ServerConfigurator.installDataPacksIfChanged(true); } else { - Iris.warn("Default pack '" + pack + "' is not installed. Please download it manually with /iris download " + pack); + IrisLogging.warn("Default pack '" + pack + "' is not installed. Please download it manually with /iris download " + pack); } } }); @@ -83,7 +85,7 @@ public class StudioSVC implements IrisService { @Override public void onDisable() { - Iris.debug("Studio Mode Active: Closing Projects"); + IrisLogging.debug("Studio Mode Active: Closing Projects"); boolean stopping = IrisToolbelt.isServerStopping(); LinkedHashSet worldNamesToDelete = new LinkedHashSet<>(TransientWorldCleanupSupport.collectTransientStudioWorldNames(Bukkit.getWorldContainer())); @@ -113,7 +115,7 @@ public class StudioSVC implements IrisService { try { generator.close(); } catch (Throwable e) { - Iris.reportError("Failed to close studio generator for \"" + i.getName() + "\" during shutdown.", e); + IrisLogging.reportError("Failed to close studio generator for \"" + i.getName() + "\" during shutdown.", e); } } } @@ -123,7 +125,7 @@ public class StudioSVC implements IrisService { try { art.arcane.iris.core.tools.IrisCreator.removeTransientStudioWorldsFromBukkitYml(); } catch (Throwable e) { - Iris.reportError("Failed to unregister transient studio worlds from bukkit.yml during shutdown.", e); + IrisLogging.reportError("Failed to unregister transient studio worlds from bukkit.yml during shutdown.", e); } queueStudioWorldDeletionOnStartup(worldNamesToDelete); @@ -155,7 +157,7 @@ public class StudioSVC implements IrisService { try { FileUtils.copyDirectory(f, folder); } catch (IOException e) { - Iris.reportError(e); + IrisLogging.reportError(e); } } @@ -173,14 +175,14 @@ public class StudioSVC implements IrisService { FileUtils.copyFile(i, new File(folder, i.getName())); } catch (IOException e) { e.printStackTrace(); - Iris.reportError(e); + IrisLogging.reportError(e); } } else { try { FileUtils.copyDirectory(i, new File(folder, i.getName())); } catch (IOException e) { e.printStackTrace(); - Iris.reportError(e); + IrisLogging.reportError(e); } } } @@ -221,13 +223,13 @@ public class StudioSVC implements IrisService { return; } - Iris.info("Resolved pack '" + key + "' to " + url); + IrisLogging.info("Resolved pack '" + key + "' to " + url); String[] nodes = url.split("\\Q/\\E"); String repo = nodes.length == 1 ? "IrisDimensions/" + nodes[0] : nodes[0] + "/" + nodes[1]; String branch = nodes.length > 2 ? nodes[2] : "stable"; download(sender, repo, branch, forceOverwrite, false); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); e.printStackTrace(); sender.sendMessage("Failed to download '" + key + "'."); } @@ -237,7 +239,7 @@ public class StudioSVC implements IrisService { try { download(sender, "IrisDimensions", url, forceOverwrite, true); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); e.printStackTrace(); sender.sendMessage("Failed to download 'IrisDimensions/overworld' from " + url + "."); } @@ -247,7 +249,7 @@ public class StudioSVC implements IrisService { try { download(sender, repo, branch, forceOverwrite, false); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); e.printStackTrace(); sender.sendMessage("Failed to download '" + repo + "' (branch " + branch + ")."); } @@ -260,8 +262,8 @@ public class StudioSVC implements IrisService { public void download(VolmitSender sender, String repo, String branch, boolean forceOverwrite, boolean directUrl) throws JsonSyntaxException, IOException { String url = directUrl ? branch : "https://codeload.github.com/" + repo + "/zip/refs/heads/" + branch; sender.sendMessage("Downloading " + url + " "); //The extra space stops a bug in adventure API from repeating the last letter of the URL - File zip = Iris.getNonCachedFile("pack-" + repo, url); - File temp = Iris.getTemp(); + File zip = art.arcane.iris.util.common.misc.WebCache.getNonCachedFile("pack-" + repo, url); + File temp = art.arcane.iris.util.common.misc.WebCache.getTemp(); File work = new File(temp, "dl-" + UUID.randomUUID()); File packs = getWorkspaceFolder(); @@ -275,7 +277,7 @@ public class StudioSVC implements IrisService { try { ZipUtil.unpack(zip, work); } catch (Throwable e) { - Iris.reportError(e); + IrisLogging.reportError(e); e.printStackTrace(); sender.sendMessage( """ @@ -298,7 +300,7 @@ public class StudioSVC implements IrisService { try { dir = zipFiles.length > 1 ? work : zipFiles[0].isDirectory() ? zipFiles[0] : null; } catch (NullPointerException e) { - Iris.reportError(e); + IrisLogging.reportError(e); sender.sendMessage("Error when finding home directory. Are there any non-text characters in the file name?"); return; } @@ -358,9 +360,9 @@ public class StudioSVC implements IrisService { JSONObject a; if (cached) { - a = new JSONObject(Iris.getCached("cachedlisting", LISTING)); + a = new JSONObject(art.arcane.iris.util.common.misc.WebCache.getCached("cachedlisting", LISTING)); } else { - a = new JSONObject(Iris.getNonCached(true + "listing", LISTING)); + a = new JSONObject(art.arcane.iris.util.common.misc.WebCache.getNonCached(true + "listing", LISTING)); } KMap l = new KMap<>(); @@ -386,7 +388,7 @@ public class StudioSVC implements IrisService { open(sender, seed, dimm, (w) -> { }); } catch (Exception e) { - Iris.reportError("Failed to open studio world \"" + dimm + "\".", e); + IrisLogging.reportError("Failed to open studio world \"" + dimm + "\".", e); sender.sendMessage("Failed to open studio world: " + e.getMessage()); } } @@ -411,14 +413,14 @@ public class StudioSVC implements IrisService { CompletableFuture pendingClose = close(); pendingClose.whenComplete((closeResult, closeThrowable) -> { if (closeThrowable != null) { - Iris.reportError("Failed while closing an existing studio project before opening \"" + dimm + "\".", closeThrowable); + IrisLogging.reportError("Failed while closing an existing studio project before opening \"" + dimm + "\".", closeThrowable); J.s(() -> sender.sendMessage("Failed to close the existing studio project: " + closeThrowable.getMessage())); return; } if (closeResult != null && closeResult.failureCause() != null) { Throwable failure = closeResult.failureCause(); - Iris.reportError("Failed while closing an existing studio project before opening \"" + dimm + "\".", failure); + IrisLogging.reportError("Failed while closing an existing studio project before opening \"" + dimm + "\".", failure); J.s(() -> sender.sendMessage("Failed to close the existing studio project: " + failure.getMessage())); return; } @@ -449,11 +451,11 @@ public class StudioSVC implements IrisService { } public File getWorkspaceFolder(String... sub) { - return Iris.instance.getDataFolderList(WORKSPACE_NAME, sub); + return art.arcane.iris.platform.bukkit.BukkitPlatform.volmitPlugin().getDataFolderList(WORKSPACE_NAME, sub); } public File getWorkspaceFile(String... sub) { - return Iris.instance.getDataFileList(WORKSPACE_NAME, sub); + return art.arcane.iris.platform.bukkit.BukkitPlatform.volmitPlugin().getDataFileList(WORKSPACE_NAME, sub); } public CompletableFuture close() { @@ -465,7 +467,7 @@ public class StudioSVC implements IrisService { return CompletableFuture.completedFuture(new art.arcane.iris.core.runtime.StudioOpenCoordinator.StudioCloseResult(null, true, true, false, null)); } - Iris.debug("Closing Active Project"); + IrisLogging.debug("Closing Active Project"); IrisProject project = activeProject; activeProject = null; activeClose = project.close(); @@ -477,21 +479,21 @@ public class StudioSVC implements IrisService { try { IrisToolbelt.evacuate(world); } catch (Throwable e) { - Iris.reportError("Failed to evacuate studio world \"" + world.getName() + "\" during shutdown cleanup.", e); + IrisLogging.reportError("Failed to evacuate studio world \"" + world.getName() + "\" during shutdown cleanup.", e); } if (generator != null) { try { generator.close(); } catch (Throwable e) { - Iris.reportError("Failed to close studio generator for \"" + world.getName() + "\" during shutdown cleanup.", e); + IrisLogging.reportError("Failed to close studio generator for \"" + world.getName() + "\" during shutdown cleanup.", e); } } try { WorldLifecycleService.get().unload(world, false); } catch (Throwable e) { - Iris.reportError("Failed to unload studio world \"" + world.getName() + "\" during shutdown cleanup.", e); + IrisLogging.reportError("Failed to unload studio world \"" + world.getName() + "\" during shutdown cleanup.", e); } deleteTransientStudioFolders(world.getName()); @@ -536,9 +538,9 @@ public class StudioSVC implements IrisService { } try { - Iris.queueWorldDeletionOnStartup(List.copyOf(normalizedNames)); + IrisServices.get(art.arcane.iris.core.runtime.WorldDeletionQueue.class).queueForStartupDeletion(List.copyOf(normalizedNames)); } catch (IOException e) { - Iris.reportError("Failed to queue studio world deletion on startup.", e); + IrisLogging.reportError("Failed to queue studio world deletion on startup.", e); } } @@ -551,14 +553,14 @@ public class StudioSVC implements IrisService { File newPack = getWorkspaceFolder(newName); if (importPack.listFiles().length == 0) { - Iris.warn("Couldn't find the pack to create a new dimension from."); + IrisLogging.warn("Couldn't find the pack to create a new dimension from."); return; } try { FileUtils.copyDirectory(importPack, newPack, pathname -> !pathname.getAbsolutePath().contains(".git"), false); } catch (IOException e) { - Iris.reportError(e); + IrisLogging.reportError(e); e.printStackTrace(); } @@ -569,7 +571,7 @@ public class StudioSVC implements IrisService { try { FileUtils.copyFile(dimFile, newDimFile); } catch (IOException e) { - Iris.reportError(e); + IrisLogging.reportError(e); e.printStackTrace(); } @@ -583,7 +585,7 @@ public class StudioSVC implements IrisService { IO.writeAll(newDimFile, json.toString(4)); } } catch (JSONException | IOException e) { - Iris.reportError(e); + IrisLogging.reportError(e); e.printStackTrace(); } @@ -592,7 +594,7 @@ public class StudioSVC implements IrisService { JSONObject ws = p.createCodeWorkspaceConfig(); IO.writeAll(getWorkspaceFile(newName, newName + ".code-workspace"), ws.toString(0)); } catch (JSONException | IOException e) { - Iris.reportError(e); + IrisLogging.reportError(e); e.printStackTrace(); } } diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisObject.java b/core/src/main/java/art/arcane/iris/engine/object/IrisObject.java index 292020a9a..a7b2c4982 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisObject.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisObject.java @@ -952,7 +952,6 @@ public class IrisObject extends IrisRegistrant { String key = o.getLoadKey(); if (key != null) { if (config.getForbiddenCollisions().contains(key) && !config.getAllowedCollisions().contains(key)) { - // Iris.debug("%s collides with %s (%s / %s / %s)", getLoadKey(), key, i, j, k); return -1; } } diff --git a/core/src/main/java/art/arcane/iris/platform/bukkit/BukkitPlatform.java b/core/src/main/java/art/arcane/iris/platform/bukkit/BukkitPlatform.java index b6de8f8f2..206d01d23 100644 --- a/core/src/main/java/art/arcane/iris/platform/bukkit/BukkitPlatform.java +++ b/core/src/main/java/art/arcane/iris/platform/bukkit/BukkitPlatform.java @@ -209,6 +209,18 @@ public final class BukkitPlatform implements IrisPlatform { return INMS.get().getDataVersion().getPackFormat(); } + public static java.util.concurrent.CompletableFuture teleportAsync(Entity entity, Location destination) { + return io.papermc.lib.PaperLib.teleportAsync(entity, destination); + } + + public static boolean isPaperServer() { + return io.papermc.lib.PaperLib.isPaper(); + } + + public static java.util.concurrent.CompletableFuture chunkAtAsync(World world, int x, int z, boolean generate) { + return io.papermc.lib.PaperLib.getChunkAtAsync(world, x, z, generate); + } + @Override public String platformName() { return "bukkit"; diff --git a/core/src/main/java/art/arcane/iris/util/common/misc/WebCache.java b/core/src/main/java/art/arcane/iris/util/common/misc/WebCache.java new file mode 100644 index 000000000..cad6467aa --- /dev/null +++ b/core/src/main/java/art/arcane/iris/util/common/misc/WebCache.java @@ -0,0 +1,97 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2026 Arcane Arts (Volmit Software) + * + * 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 art.arcane.iris.util.common.misc; + +import art.arcane.iris.spi.IrisLogging; +import art.arcane.iris.spi.IrisPlatforms; +import art.arcane.volmlib.util.io.IO; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URI; + +/** + * Download cache helpers over the platform data folder. + */ +public final class WebCache { + private WebCache() { + } + + public static File getTemp() { + return IrisPlatforms.get().dataFolder("cache", "temp"); + } + + public static File getCached(String name, String url) { + String h = IO.hash(name + "@" + url); + File f = IrisPlatforms.get().dataFile("cache", h.substring(0, 2), h.substring(3, 5), h); + + if (!f.exists()) { + try (BufferedInputStream in = new BufferedInputStream(URI.create(url).toURL().openStream()); FileOutputStream fileOutputStream = new FileOutputStream(f)) { + byte[] dataBuffer = new byte[1024]; + int bytesRead; + while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) { + fileOutputStream.write(dataBuffer, 0, bytesRead); + IrisLogging.debug("Aquiring " + name); + } + } catch (IOException e) { + IrisLogging.reportError(e); + } + } + + return f.exists() ? f : null; + } + + public static String getNonCached(String name, String url) { + String h = IO.hash(name + "*" + url); + File f = IrisPlatforms.get().dataFile("cache", h.substring(0, 2), h.substring(3, 5), h); + + try (BufferedInputStream in = new BufferedInputStream(URI.create(url).toURL().openStream()); FileOutputStream fileOutputStream = new FileOutputStream(f)) { + byte[] dataBuffer = new byte[1024]; + int bytesRead; + while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) { + fileOutputStream.write(dataBuffer, 0, bytesRead); + } + } catch (IOException e) { + IrisLogging.reportError(e); + } + + return ""; + } + + public static File getNonCachedFile(String name, String url) { + String h = IO.hash(name + "*" + url); + File f = IrisPlatforms.get().dataFile("cache", h.substring(0, 2), h.substring(3, 5), h); + IrisLogging.debug("Download " + name + " -> " + url); + try (BufferedInputStream in = new BufferedInputStream(URI.create(url).toURL().openStream()); FileOutputStream fileOutputStream = new FileOutputStream(f)) { + byte[] dataBuffer = new byte[1024]; + int bytesRead; + while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) { + fileOutputStream.write(dataBuffer, 0, bytesRead); + } + + fileOutputStream.flush(); + } catch (IOException e) { + IrisLogging.reportError(e); + } + + return f; + } +} diff --git a/core/src/test/java/art/arcane/iris/util/project/context/ChunkContextPrefillPlanTest.java b/core/src/test/java/art/arcane/iris/util/project/context/ChunkContextPrefillPlanTest.java index 548e184b7..6d5ae33bb 100644 --- a/core/src/test/java/art/arcane/iris/util/project/context/ChunkContextPrefillPlanTest.java +++ b/core/src/test/java/art/arcane/iris/util/project/context/ChunkContextPrefillPlanTest.java @@ -1,6 +1,5 @@ package art.arcane.iris.util.project.context; -import art.arcane.iris.Iris; import art.arcane.iris.engine.IrisComplex; import art.arcane.iris.engine.object.IrisBiome; import art.arcane.iris.engine.object.IrisRegion; @@ -167,14 +166,12 @@ public class ChunkContextPrefillPlanTest { } private void assertPrefillAsyncDecision(String threadName, boolean expected) throws InterruptedException, ExecutionException, java.util.concurrent.TimeoutException { - Iris previous = Iris.instance; ExecutorService executor = Executors.newSingleThreadExecutor(runnable -> { Thread thread = new Thread(runnable); thread.setName(threadName); return thread; }); try { - Iris.instance = mock(Iris.class); Future future = executor.submit(() -> ChunkContext.shouldPrefillAsync(2)); boolean actual = future.get(10, TimeUnit.SECONDS); if (expected) { @@ -183,7 +180,6 @@ public class ChunkContextPrefillPlanTest { assertFalse(actual); } } finally { - Iris.instance = previous; executor.shutdownNow(); } } diff --git a/settings.gradle b/settings.gradle index 42c96bc12..7a7993a25 100644 --- a/settings.gradle +++ b/settings.gradle @@ -70,6 +70,7 @@ if (useLocalVolmLib && localVolmLibDirectory != null) { include(':core', ':core:agent') include(':spi') +include(':adapters:bukkit:plugin') include(':adapters:bukkit:nms:v1_21_R7') include(':adapters:bukkit:nms:v26_1_R1') include(':adapters:fabric') diff --git a/spi/src/main/java/art/arcane/iris/spi/IrisLogging.java b/spi/src/main/java/art/arcane/iris/spi/IrisLogging.java index ed467349e..f32327d37 100644 --- a/spi/src/main/java/art/arcane/iris/spi/IrisLogging.java +++ b/spi/src/main/java/art/arcane/iris/spi/IrisLogging.java @@ -71,8 +71,8 @@ public final class IrisLogging { } if (error != null) { - System.out.println("[Iris/ERROR] " + error.getClass().getName() + (error.getMessage() == null ? "" : ": " + error.getMessage())); - error.printStackTrace(System.out); + System.err.println("[Iris/ERROR] " + error.getClass().getName() + (error.getMessage() == null ? "" : ": " + error.getMessage())); + error.printStackTrace(System.err); } } @@ -82,6 +82,11 @@ public final class IrisLogging { return; } + if (level == LogLevel.WARN || level == LogLevel.ERROR) { + System.err.println("[Iris/" + level + "] " + message); + return; + } + System.out.println("[Iris/" + level + "] " + message); }