diff --git a/core/src/main/java/art/arcane/iris/Iris.java b/core/src/main/java/art/arcane/iris/Iris.java index 1c10df9cf..b682ab7f0 100644 --- a/core/src/main/java/art/arcane/iris/Iris.java +++ b/core/src/main/java/art/arcane/iris/Iris.java @@ -51,6 +51,7 @@ import art.arcane.iris.core.safeguard.IrisSafeguard; import art.arcane.iris.engine.platform.PlatformChunkGenerator; import art.arcane.iris.platform.bukkit.BukkitPlatform; import art.arcane.iris.spi.IrisPlatforms; +import art.arcane.iris.spi.IrisServices; import art.arcane.volmlib.integration.ReloadAware; import art.arcane.volmlib.util.collection.KList; import art.arcane.volmlib.util.collection.KMap; @@ -554,7 +555,10 @@ public class Iris extends VolmitPlugin implements Listener, ReloadAware { services = new KMap<>(); setupAudience(); Bindings.setupSentry(); - initialize("art.arcane.iris.core.service").forEach((i) -> services.put((Class) i.getClass(), (IrisService) i)); + initialize("art.arcane.iris.core.service").forEach((i) -> { + services.put((Class) i.getClass(), (IrisService) i); + IrisServices.register(i.getClass(), i); + }); IO.delete(new File("iris")); compat = IrisCompat.configured(getDataFile("compat.json")); ServerConfigurator.configure(); @@ -927,6 +931,7 @@ public class Iris extends VolmitPlugin implements Listener, ReloadAware { if (services != null) { services.values().forEach(IrisService::onDisable); } + IrisServices.clear(); if (configHotloadEngine != null) { configHotloadEngine.clear(); configHotloadEngine = null; diff --git a/core/src/main/java/art/arcane/iris/engine/IrisEngine.java b/core/src/main/java/art/arcane/iris/engine/IrisEngine.java index 90a3a1e9a..91368b39f 100644 --- a/core/src/main/java/art/arcane/iris/engine/IrisEngine.java +++ b/core/src/main/java/art/arcane/iris/engine/IrisEngine.java @@ -21,7 +21,8 @@ package art.arcane.iris.engine; import art.arcane.iris.spi.IrisLogging; import com.google.common.util.concurrent.AtomicDouble; import com.google.gson.Gson; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisPlatforms; +import art.arcane.iris.spi.IrisServices; import art.arcane.iris.core.IrisSettings; import art.arcane.iris.core.ServerConfigurator; import art.arcane.iris.core.events.IrisEngineHotloadEvent; @@ -391,7 +392,7 @@ public class IrisEngine implements Engine { @Override public void hotload() { hotloadSilently(); - Iris.callEvent(new IrisEngineHotloadEvent(this)); + IrisPlatforms.get().callEvent(new IrisEngineHotloadEvent(this)); } public void hotloadComplex() { @@ -433,9 +434,9 @@ public class IrisEngine implements Engine { if (data == null) { data = new IrisEngineData(); - data.getStatistics().setVersion(Iris.instance.getIrisVersion()); - data.getStatistics().setMCVersion(Iris.instance.getMCVersion()); - data.getStatistics().setUpgradedVersion(Iris.instance.getIrisVersion()); + data.getStatistics().setVersion(IrisPlatforms.get().irisVersionNumber()); + data.getStatistics().setMCVersion(IrisPlatforms.get().minecraftVersionNumber()); + data.getStatistics().setUpgradedVersion(IrisPlatforms.get().irisVersionNumber()); if (data.getStatistics().getVersion() == -1 || data.getStatistics().getMCVersion() == -1 ) { IrisLogging.error("Failed to setup Engine Data!"); } @@ -601,7 +602,7 @@ public class IrisEngine implements Engine { worldManager = null; getData().dump(); getData().clearLists(); - Iris.service(PreservationSVC.class).dereference(); + IrisServices.get(PreservationSVC.class).dereference(); IrisLogging.debug("Engine Fully Shutdown!"); } @@ -756,8 +757,8 @@ public class IrisEngine implements Engine { // Todo: this has potential if done right int EngineMCVersion = getEngineData().getStatistics().getMCVersion(); int EngineIrisVersion = getEngineData().getStatistics().getVersion(); - int MinecraftVersion = Iris.instance.getMCVersion(); - int IrisVersion = Iris.instance.getIrisVersion(); + int MinecraftVersion = IrisPlatforms.get().minecraftVersionNumber(); + int IrisVersion = IrisPlatforms.get().irisVersionNumber(); if (EngineIrisVersion != IrisVersion) { return false; } diff --git a/core/src/main/java/art/arcane/iris/engine/IrisEngineMantle.java b/core/src/main/java/art/arcane/iris/engine/IrisEngineMantle.java index adfdd1366..5be90893b 100644 --- a/core/src/main/java/art/arcane/iris/engine/IrisEngineMantle.java +++ b/core/src/main/java/art/arcane/iris/engine/IrisEngineMantle.java @@ -18,7 +18,7 @@ package art.arcane.iris.engine; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisPlatforms; import art.arcane.iris.core.IrisSettings; import art.arcane.iris.core.tools.IrisToolbelt; import art.arcane.iris.engine.EnginePanic; @@ -275,7 +275,7 @@ public class IrisEngineMantle implements EngineMantle { return new MantleHooks() { @Override public void onBeforeReadSection(int index) { - Iris.addPanic("read.section", "Section[" + index + "]"); + EnginePanic.add("read.section", "Section[" + index + "]"); } @Override @@ -285,17 +285,17 @@ public class IrisEngineMantle implements EngineMantle { art.arcane.volmlib.util.io.CountingDataInputStream din, IOException error) { IrisLogging.error("Failed to read chunk section, skipping it."); - Iris.addPanic("read.byte.range", start + " " + end); - Iris.addPanic("read.byte.current", din.count() + ""); + EnginePanic.add("read.byte.range", start + " " + end); + EnginePanic.add("read.byte.current", din.count() + ""); IrisLogging.reportError(error); error.printStackTrace(); - Iris.panic(); + EnginePanic.panic(); TectonicPlate.addError(); } @Override public void onBeforeReadChunk(int index) { - Iris.addPanic("read-chunk", "Chunk[" + index + "]"); + EnginePanic.add("read-chunk", "Chunk[" + index + "]"); } @Override @@ -310,11 +310,11 @@ public class IrisEngineMantle implements EngineMantle { art.arcane.volmlib.util.io.CountingDataInputStream din, Throwable error) { IrisLogging.error("Failed to read chunk, creating a new chunk instead."); - Iris.addPanic("read.byte.range", start + " " + end); - Iris.addPanic("read.byte.current", din.count() + ""); + EnginePanic.add("read.byte.range", start + " " + end); + EnginePanic.add("read.byte.current", din.count() + ""); IrisLogging.reportError(error); error.printStackTrace(); - Iris.panic(); + EnginePanic.panic(); } @Override @@ -373,7 +373,7 @@ public class IrisEngineMantle implements EngineMantle { TectonicPlate.read(worldHeight, in, regionName.startsWith("pv."), adapter, hooks)); } finally { if (TectonicPlate.hasError() && IrisSettings.get().getGeneral().isDumpMantleOnError()) { - File dump = Iris.instance.getDataFolder("dump", name + ".bin"); + File dump = IrisPlatforms.get().dataFile("dump", name + ".bin"); worker.dumpDecoded(name, dump.toPath()); } else { IrisLogging.debug("Read Tectonic Plate " + C.DARK_GREEN + name + C.RED + " in " + Form.duration(stopwatch.getMilliseconds(), 2)); diff --git a/core/src/main/java/art/arcane/iris/engine/IrisWorldManager.java b/core/src/main/java/art/arcane/iris/engine/IrisWorldManager.java index 98bd6f9c2..6a767423f 100644 --- a/core/src/main/java/art/arcane/iris/engine/IrisWorldManager.java +++ b/core/src/main/java/art/arcane/iris/engine/IrisWorldManager.java @@ -18,7 +18,6 @@ package art.arcane.iris.engine; -import art.arcane.iris.Iris; import art.arcane.iris.core.IrisSettings; import art.arcane.iris.core.gui.PregeneratorJob; import art.arcane.iris.core.loader.IrisData; @@ -771,7 +770,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager { chunkFuture.get(); } catch (InterruptedException ex) { Thread.currentThread().interrupt(); - Iris.verbose("Chunk warmup interrupted while loading async teleport chunk."); + IrisLogging.debug("Chunk warmup interrupted while loading async teleport chunk."); } catch (ExecutionException ex) { IrisLogging.reportError(ex); } diff --git a/core/src/main/java/art/arcane/iris/engine/framework/Engine.java b/core/src/main/java/art/arcane/iris/engine/framework/Engine.java index 6ff4ef773..9aaa02f1d 100644 --- a/core/src/main/java/art/arcane/iris/engine/framework/Engine.java +++ b/core/src/main/java/art/arcane/iris/engine/framework/Engine.java @@ -18,7 +18,7 @@ package art.arcane.iris.engine.framework; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisServices; import art.arcane.iris.core.IrisSettings; import art.arcane.iris.core.events.IrisLootEvent; import art.arcane.iris.core.gui.components.RenderType; @@ -386,7 +386,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat Runnable customTask = () -> { chunk.iterate(Identifier.class, (x, y, z, v) -> { - Iris.service(ExternalDataSVC.class).processUpdate(this, c.getBlock(x & 15, y + getWorld().minHeight(), z & 15), v); + IrisServices.get(ExternalDataSVC.class).processUpdate(this, c.getBlock(x & 15, y + getWorld().minHeight(), z & 15), v); }); }; diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisCompatabilityItemFilter.java b/core/src/main/java/art/arcane/iris/engine/object/IrisCompatabilityItemFilter.java index 80061bbc2..c6518add5 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisCompatabilityItemFilter.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisCompatabilityItemFilter.java @@ -18,7 +18,7 @@ package art.arcane.iris.engine.object; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; import art.arcane.iris.engine.data.cache.AtomicCache; import art.arcane.iris.engine.object.annotations.Desc; import art.arcane.iris.engine.object.annotations.Required; @@ -60,7 +60,7 @@ public class IrisCompatabilityItemFilter { return null; } - Iris.verbose("Compat: Using " + supplement + " in place of " + when + " since this server doesnt support '" + supplement + "'"); + IrisLogging.debug("Compat: Using " + supplement + " in place of " + when + " since this server doesnt support '" + supplement + "'"); return b; }); diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisDimension.java b/core/src/main/java/art/arcane/iris/engine/object/IrisDimension.java index afd91e14b..9ff2364b1 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisDimension.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisDimension.java @@ -18,7 +18,6 @@ package art.arcane.iris.engine.object; -import art.arcane.iris.Iris; import art.arcane.iris.core.IrisSettings; import art.arcane.iris.core.ServerConfigurator.DimensionHeight; import art.arcane.iris.core.loader.IrisData; @@ -488,7 +487,7 @@ public class IrisDimension extends IrisRegistrant { synchronized (biomes) { if (!biomes.add(customBiomeId)) { - Iris.verbose("Duplicate Data Pack Biome: " + getLoadKey() + "/" + customBiomeId); + IrisLogging.debug("Duplicate Data Pack Biome: " + getLoadKey() + "/" + customBiomeId); continue; } } @@ -496,7 +495,7 @@ public class IrisDimension extends IrisRegistrant { for (File datapacks : folders) { File output = new File(datapacks, "iris/data/" + namespace + "/worldgen/biome/" + customBiomeId + ".json"); - Iris.verbose(" Installing Data Pack Biome: " + output.getPath()); + IrisLogging.debug(" Installing Data Pack Biome: " + output.getPath()); output.getParentFile().mkdirs(); try { IO.writeAll(output, json); @@ -556,7 +555,7 @@ public class IrisDimension extends IrisRegistrant { String json = type.toJson(fixer); String dimensionTypeKey = getDimensionTypeKey(); - Iris.verbose(" Installing Data Pack Dimension Type: \"iris:" + dimensionTypeKey + '"'); + IrisLogging.debug(" Installing Data Pack Dimension Type: \"iris:" + dimensionTypeKey + '"'); for (File datapacks : folders) { File output = new File(datapacks, "iris/data/iris/dimension_type/" + dimensionTypeKey + ".json"); output.getParentFile().mkdirs(); @@ -585,7 +584,7 @@ public class IrisDimension extends IrisRegistrant { } public static void writeShared(KList folders, DimensionHeight height) { - Iris.verbose(" Installing Data Pack Vanilla Dimension Types"); + IrisLogging.debug(" Installing Data Pack Vanilla Dimension Types"); String[] jsonStrings = height.jsonStrings(); for (File datapacks : folders) { write(datapacks, "overworld", jsonStrings[0]); @@ -612,7 +611,7 @@ public class IrisDimension extends IrisRegistrant { IrisLogging.reportError(e); e.printStackTrace(); } - Iris.verbose(" Installing Data Pack MCMeta: " + mcm.getPath()); + IrisLogging.debug(" Installing Data Pack MCMeta: " + mcm.getPath()); } } diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisEntity.java b/core/src/main/java/art/arcane/iris/engine/object/IrisEntity.java index 26fa942f0..443d87d0c 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisEntity.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisEntity.java @@ -18,7 +18,7 @@ package art.arcane.iris.engine.object; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisServices; import art.arcane.iris.core.IrisSettings; import art.arcane.iris.core.link.Identifier; import art.arcane.iris.core.loader.IrisRegistrant; @@ -251,7 +251,7 @@ public class IrisEntity extends IrisRegistrant { l.setLootTable(new LootTable() { @Override public NamespacedKey getKey() { - return new NamespacedKey(Iris.instance, "loot-" + IrisEntity.this.hashCode()); + return new NamespacedKey("iris", "loot-" + IrisEntity.this.hashCode()); } @Override @@ -447,7 +447,7 @@ public class IrisEntity extends IrisRegistrant { } if (isSpecialType()) { - return Iris.service(ExternalDataSVC.class).spawnMob(at, Identifier.fromString(specialType)); + return IrisServices.get(ExternalDataSVC.class).spawnMob(at, Identifier.fromString(specialType)); } diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisLoot.java b/core/src/main/java/art/arcane/iris/engine/object/IrisLoot.java index 6561f7580..f457663b7 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisLoot.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisLoot.java @@ -18,7 +18,7 @@ package art.arcane.iris.engine.object; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisServices; import art.arcane.iris.core.link.Identifier; import art.arcane.iris.core.service.ExternalDataSVC; import art.arcane.iris.engine.data.cache.AtomicCache; @@ -148,7 +148,7 @@ public class IrisLoot { // TODO Better Third Party Item Acquisition private ItemStack getItemStack(RNG rng) { if (!type.startsWith("minecraft:") && type.contains(":")) { - Optional opt = Iris.service(ExternalDataSVC.class).getItemStack(Identifier.fromString(type), customNbt); + Optional opt = IrisServices.get(ExternalDataSVC.class).getItemStack(Identifier.fromString(type), customNbt); if (opt.isEmpty()) { IrisLogging.warn("Unknown Material: " + type); return new ItemStack(Material.AIR); diff --git a/core/src/main/java/art/arcane/iris/engine/object/annotations/functions/ComponentFlagFunction.java b/core/src/main/java/art/arcane/iris/engine/object/annotations/functions/ComponentFlagFunction.java index dae3d330e..eabc3086e 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/annotations/functions/ComponentFlagFunction.java +++ b/core/src/main/java/art/arcane/iris/engine/object/annotations/functions/ComponentFlagFunction.java @@ -1,11 +1,13 @@ package art.arcane.iris.engine.object.annotations.functions; -import art.arcane.iris.Iris; import art.arcane.iris.core.loader.IrisData; import art.arcane.iris.engine.framework.ListFunction; import art.arcane.iris.engine.mantle.ComponentFlag; import art.arcane.iris.engine.mantle.MantleComponent; +import art.arcane.iris.spi.IrisPlatforms; +import art.arcane.iris.util.common.scheduling.J; import art.arcane.volmlib.util.collection.KList; +import art.arcane.volmlib.util.io.JarScanner; import art.arcane.volmlib.util.mantle.flag.MantleFlag; import java.util.Objects; @@ -25,8 +27,11 @@ public class ComponentFlagFunction implements ListFunction> { public KList apply(IrisData data) { var engine = data.getEngine(); if (engine != null) return engine.getMantle().getComponentFlags().toStringList(); - return Iris.getClasses("art.arcane.iris.engine.mantle.components", ComponentFlag.class) + JarScanner scanner = new JarScanner(IrisPlatforms.get().pluginJar(), "art.arcane.iris.engine.mantle.components"); + J.attempt(scanner::scan); + return scanner.getClasses() .stream() + .filter(c -> c.isAnnotationPresent(ComponentFlag.class)) .filter(MantleComponent.class::isAssignableFrom) .map(c -> c.getDeclaredAnnotation(ComponentFlag.class)) .filter(Objects::nonNull) 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 08a2e44d6..91d6b10cd 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 @@ -41,6 +41,7 @@ import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; +import org.bukkit.event.Event; import org.bukkit.event.Listener; import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.inventory.ItemStack; @@ -168,6 +169,31 @@ public final class BukkitPlatform implements IrisPlatform { return Iris.instance.getDataFolder(); } + @Override + public File dataFile(String... path) { + return Iris.instance.getDataFile(path); + } + + @Override + public File pluginJar() { + return Iris.instance.getJarFile(); + } + + @Override + public int irisVersionNumber() { + return Iris.instance.getIrisVersion(); + } + + @Override + public int minecraftVersionNumber() { + return Iris.instance.getMCVersion(); + } + + @Override + public void callEvent(Object event) { + Iris.callEvent((Event) event); + } + @Override public void dispatchConsoleCommand(String command) { Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), command); @@ -183,6 +209,11 @@ public final class BukkitPlatform implements IrisPlatform { } } + @Override + public void msg(String message) { + Iris.msg(message); + } + @Override public void reportError(Throwable error) { Iris.reportError(error); diff --git a/core/src/main/java/art/arcane/iris/util/project/agent/Agent.java b/core/src/main/java/art/arcane/iris/util/project/agent/Agent.java index 552c149e2..a02243ac4 100644 --- a/core/src/main/java/art/arcane/iris/util/project/agent/Agent.java +++ b/core/src/main/java/art/arcane/iris/util/project/agent/Agent.java @@ -1,6 +1,6 @@ package art.arcane.iris.util.project.agent; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisPlatforms; import art.arcane.iris.spi.IrisLogging; import net.bytebuddy.agent.ByteBuddyAgent; import net.bytebuddy.dynamic.loading.ClassReloadingStrategy; @@ -13,7 +13,7 @@ import java.nio.file.StandardCopyOption; public class Agent { private static final String NAME = "art.arcane.iris.util.project.agent.Installer"; - public static final File AGENT_JAR = new File(Iris.instance.getDataFolder(), "agent.jar"); + public static final File AGENT_JAR = new File(IrisPlatforms.get().dataFolder(), "agent.jar"); public static ClassReloadingStrategy installed() { return ClassReloadingStrategy.of(getInstrumentation()); @@ -75,11 +75,6 @@ public class Agent { } private static InputStream openBundledAgentJar() { - InputStream stream = Iris.instance.getResource("agent.jar"); - if (stream != null) { - return stream; - } - return Agent.class.getClassLoader().getResourceAsStream("agent.jar"); } diff --git a/core/src/main/java/art/arcane/iris/util/project/context/ChunkContext.java b/core/src/main/java/art/arcane/iris/util/project/context/ChunkContext.java index 73d92cb69..cbc88d09d 100644 --- a/core/src/main/java/art/arcane/iris/util/project/context/ChunkContext.java +++ b/core/src/main/java/art/arcane/iris/util/project/context/ChunkContext.java @@ -1,6 +1,6 @@ package art.arcane.iris.util.project.context; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisPlatforms; import art.arcane.iris.engine.IrisComplex; import art.arcane.iris.engine.framework.EngineMetrics; import art.arcane.iris.engine.object.IrisBiome; @@ -98,7 +98,7 @@ public class ChunkContext { } static boolean shouldPrefillAsync(int fillTaskCount) { - if (fillTaskCount <= 1 || Iris.instance == null) { + if (fillTaskCount <= 1 || !IrisPlatforms.isBound()) { return false; } diff --git a/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkBiomeHunkView.java b/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkBiomeHunkView.java index fc8836ce2..12eb9cba0 100644 --- a/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkBiomeHunkView.java +++ b/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkBiomeHunkView.java @@ -18,7 +18,7 @@ package art.arcane.iris.util.project.hunk.view; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisServices; import art.arcane.iris.core.service.EditSVC; import art.arcane.iris.platform.bukkit.BukkitBiome; import art.arcane.iris.spi.PlatformBiome; @@ -31,7 +31,7 @@ public class ChunkBiomeHunkView extends art.arcane.volmlib.util.hunk.view.ChunkW public ChunkBiomeHunkView(Chunk chunk) { super(chunk, chunk.getWorld().getMaxHeight(), - (wx, y, wz, t) -> Iris.service(EditSVC.class).setBiome(chunk.getWorld(), wx, y, wz, (Biome) t.nativeHandle()), - (wx, y, wz) -> BukkitBiome.of(Iris.service(EditSVC.class).getBiome(chunk.getWorld(), wx, y, wz))); + (wx, y, wz, t) -> IrisServices.get(EditSVC.class).setBiome(chunk.getWorld(), wx, y, wz, (Biome) t.nativeHandle()), + (wx, y, wz) -> BukkitBiome.of(IrisServices.get(EditSVC.class).getBiome(chunk.getWorld(), wx, y, wz))); } } diff --git a/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkHunkView.java b/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkHunkView.java index 91c14a35e..02cfadb2d 100644 --- a/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkHunkView.java +++ b/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkHunkView.java @@ -18,7 +18,7 @@ package art.arcane.iris.util.project.hunk.view; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisServices; import art.arcane.iris.core.service.EditSVC; import art.arcane.iris.platform.bukkit.BukkitBlockState; import art.arcane.iris.spi.PlatformBlockState; @@ -31,7 +31,7 @@ public class ChunkHunkView extends art.arcane.volmlib.util.hunk.view.ChunkWorldH public ChunkHunkView(Chunk chunk) { super(chunk, chunk.getWorld().getMaxHeight(), - (wx, y, wz, t) -> Iris.service(EditSVC.class).set(chunk.getWorld(), wx, y, wz, (BlockData) t.nativeHandle()), - (wx, y, wz) -> BukkitBlockState.of(Iris.service(EditSVC.class).get(chunk.getWorld(), wx, y, wz))); + (wx, y, wz, t) -> IrisServices.get(EditSVC.class).set(chunk.getWorld(), wx, y, wz, (BlockData) t.nativeHandle()), + (wx, y, wz) -> BukkitBlockState.of(IrisServices.get(EditSVC.class).get(chunk.getWorld(), wx, y, wz))); } } diff --git a/core/src/main/java/art/arcane/iris/util/project/sentry/IrisLogger.java b/core/src/main/java/art/arcane/iris/util/project/sentry/IrisLogger.java index bf02be062..36b789711 100644 --- a/core/src/main/java/art/arcane/iris/util/project/sentry/IrisLogger.java +++ b/core/src/main/java/art/arcane/iris/util/project/sentry/IrisLogger.java @@ -1,6 +1,6 @@ package art.arcane.iris.util.project.sentry; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisLogging; import io.sentry.ILogger; import io.sentry.SentryLevel; import org.jetbrains.annotations.NotNull; @@ -12,7 +12,7 @@ import java.io.StringWriter; public class IrisLogger implements ILogger { @Override public void log(@NotNull SentryLevel level, @NotNull String message, @Nullable Object... args) { - Iris.msg(String.format("%s: %s", level, String.format(message, args))); + IrisLogging.msg(String.format("%s: %s", level, String.format(message, args))); } @Override @@ -20,7 +20,7 @@ public class IrisLogger implements ILogger { if (throwable == null) { log(level, message); } else { - Iris.msg(String.format("%s: %s\n%s", level, String.format(message, throwable), captureStackTrace(throwable))); + IrisLogging.msg(String.format("%s: %s\n%s", level, String.format(message, throwable), captureStackTrace(throwable))); } } @@ -29,7 +29,7 @@ public class IrisLogger implements ILogger { if (throwable == null) { log(level, message, args); } else { - Iris.msg(String.format("%s: %s\n%s", level, String.format(message, throwable), captureStackTrace(throwable))); + IrisLogging.msg(String.format("%s: %s\n%s", level, String.format(message, throwable), captureStackTrace(throwable))); } } diff --git a/core/src/main/java/art/arcane/iris/util/project/stream/utility/CachedDoubleStream2D.java b/core/src/main/java/art/arcane/iris/util/project/stream/utility/CachedDoubleStream2D.java index c99d9bb6c..8f30a358b 100644 --- a/core/src/main/java/art/arcane/iris/util/project/stream/utility/CachedDoubleStream2D.java +++ b/core/src/main/java/art/arcane/iris/util/project/stream/utility/CachedDoubleStream2D.java @@ -1,6 +1,6 @@ package art.arcane.iris.util.project.stream.utility; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisServices; import art.arcane.iris.core.service.PreservationSVC; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.framework.MeteredCache; @@ -19,7 +19,7 @@ public class CachedDoubleStream2D extends BasicStream implements Procedu this.stream = stream; this.engine = engine; this.cache = new WorldCache2DDouble((x, z) -> stream.getDouble(x, z), size); - Iris.service(PreservationSVC.class).registerCache(this); + IrisServices.get(PreservationSVC.class).registerCache(this); } @Override diff --git a/core/src/main/java/art/arcane/iris/util/project/stream/utility/CachedStream2D.java b/core/src/main/java/art/arcane/iris/util/project/stream/utility/CachedStream2D.java index 8a5b5a124..d30ed0a3e 100644 --- a/core/src/main/java/art/arcane/iris/util/project/stream/utility/CachedStream2D.java +++ b/core/src/main/java/art/arcane/iris/util/project/stream/utility/CachedStream2D.java @@ -18,7 +18,7 @@ package art.arcane.iris.util.project.stream.utility; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisServices; import art.arcane.iris.core.service.PreservationSVC; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.framework.MeteredCache; @@ -38,7 +38,7 @@ public class CachedStream2D extends BasicStream implements ProceduralStrea this.stream = stream; this.engine = engine; cache = new WorldCache2D<>(stream::get, size, () -> new ChunkCache2D<>("iris")); - Iris.service(PreservationSVC.class).registerCache(this); + IrisServices.get(PreservationSVC.class).registerCache(this); } @Override diff --git a/core/src/main/java/art/arcane/iris/util/project/stream/utility/CachedStream3D.java b/core/src/main/java/art/arcane/iris/util/project/stream/utility/CachedStream3D.java index cd340a0ae..ac33bb251 100644 --- a/core/src/main/java/art/arcane/iris/util/project/stream/utility/CachedStream3D.java +++ b/core/src/main/java/art/arcane/iris/util/project/stream/utility/CachedStream3D.java @@ -18,7 +18,7 @@ package art.arcane.iris.util.project.stream.utility; -import art.arcane.iris.Iris; +import art.arcane.iris.spi.IrisServices; import art.arcane.iris.core.service.PreservationSVC; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.framework.MeteredCache; @@ -36,7 +36,7 @@ public class CachedStream3D extends BasicStream implements ProceduralStrea this.stream = stream; this.engine = engine; cache = new KCache<>((k) -> stream.get(k.getX(), k.getY(), k.getZ()), size); - Iris.service(PreservationSVC.class).registerCache(this); + IrisServices.get(PreservationSVC.class).registerCache(this); } @Override 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 36663389a..f39a1dfab 100644 --- a/spi/src/main/java/art/arcane/iris/spi/IrisLogging.java +++ b/spi/src/main/java/art/arcane/iris/spi/IrisLogging.java @@ -40,6 +40,15 @@ public final class IrisLogging { emit(LogLevel.ERROR, safeFormat(format, args)); } + public static void msg(String message) { + if (IrisPlatforms.isBound()) { + IrisPlatforms.get().msg(message); + return; + } + + System.out.println("[Iris] " + message); + } + public static void reportError(Throwable error) { if (IrisPlatforms.isBound()) { IrisPlatforms.get().reportError(error); diff --git a/spi/src/main/java/art/arcane/iris/spi/IrisPlatform.java b/spi/src/main/java/art/arcane/iris/spi/IrisPlatform.java index 8feb60139..ec381f886 100644 --- a/spi/src/main/java/art/arcane/iris/spi/IrisPlatform.java +++ b/spi/src/main/java/art/arcane/iris/spi/IrisPlatform.java @@ -40,9 +40,21 @@ public interface IrisPlatform { File dataFolder(); + File dataFile(String... path); + + File pluginJar(); + + int irisVersionNumber(); + + int minecraftVersionNumber(); + + void callEvent(Object event); + void dispatchConsoleCommand(String command); void log(LogLevel level, String message); + void msg(String message); + void reportError(Throwable error); } diff --git a/spi/src/main/java/art/arcane/iris/spi/IrisServices.java b/spi/src/main/java/art/arcane/iris/spi/IrisServices.java new file mode 100644 index 000000000..80bd36321 --- /dev/null +++ b/spi/src/main/java/art/arcane/iris/spi/IrisServices.java @@ -0,0 +1,44 @@ +/* + * 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.spi; + +import java.util.concurrent.ConcurrentHashMap; + +public final class IrisServices { + private static final ConcurrentHashMap, Object> SERVICES = new ConcurrentHashMap<>(); + + private IrisServices() { + } + + public static void register(Class type, Object implementation) { + SERVICES.put(type, type.cast(implementation)); + } + + public static T get(Class type) { + Object implementation = SERVICES.get(type); + if (implementation == null) { + throw new IllegalStateException("No Iris service registered for " + type.getName()); + } + return type.cast(implementation); + } + + public static void clear() { + SERVICES.clear(); + } +}