From 13002b04df97a67c9d618bb845aa4a7f6a924bb7 Mon Sep 17 00:00:00 2001 From: Brian Neumann-Fopiano Date: Thu, 11 Jun 2026 14:29:32 -0400 Subject: [PATCH] World Ops --- .../framework/StructureReachability.java | 14 ++++++------ .../iris/engine/object/IrisCommand.java | 22 +++++++++---------- .../engine/object/IrisCommandRegistry.java | 5 ++++- .../arcane/iris/engine/object/IrisEntity.java | 5 ++++- .../iris/engine/object/IrisSpawner.java | 5 ++++- .../iris/engine/object/IrisTimeBlock.java | 4 ++-- .../iris/engine/object/IrisWeather.java | 10 ++++----- .../iris/platform/bukkit/BukkitPlatform.java | 5 +++++ .../iris/platform/bukkit/BukkitWorld.java | 15 +++++++++++++ .../art/arcane/iris/spi/IrisPlatform.java | 2 ++ .../art/arcane/iris/spi/PlatformWorld.java | 6 +++++ 11 files changed, 64 insertions(+), 29 deletions(-) diff --git a/core/src/main/java/art/arcane/iris/engine/framework/StructureReachability.java b/core/src/main/java/art/arcane/iris/engine/framework/StructureReachability.java index 1a90a3384..0882bef79 100644 --- a/core/src/main/java/art/arcane/iris/engine/framework/StructureReachability.java +++ b/core/src/main/java/art/arcane/iris/engine/framework/StructureReachability.java @@ -20,8 +20,8 @@ package art.arcane.iris.engine.framework; import art.arcane.iris.core.loader.IrisData; import art.arcane.iris.core.nms.INMS; +import art.arcane.iris.engine.object.IrisWorld; import art.arcane.volmlib.util.collection.KList; -import org.bukkit.World; import java.util.Collections; import java.util.LinkedHashSet; @@ -79,12 +79,12 @@ public final class StructureReachability { } private static Set build(Engine engine) { - World world = engine.getWorld() == null ? null : engine.getWorld().realWorld(); - if (world == null) { + IrisWorld world = engine.getWorld(); + if (world == null || world.realWorld() == null) { return Collections.emptySet(); } Set reachable = new LinkedHashSet<>(); - for (String key : INMS.get().getReachableStructureKeys(world)) { + for (String key : INMS.get().getReachableStructureKeys(world.realWorld())) { if (key != null && !key.isEmpty()) { reachable.add(key.toLowerCase()); } @@ -102,12 +102,12 @@ public final class StructureReachability { if (engine == null || structureKey == null || structureKey.isEmpty()) { return missing; } - World world = engine.getWorld() == null ? null : engine.getWorld().realWorld(); - if (world == null) { + IrisWorld world = engine.getWorld(); + if (world == null || world.realWorld() == null) { return missing; } Set possible = new LinkedHashSet<>(); - for (String key : INMS.get().getPossibleBiomeKeys(world)) { + for (String key : INMS.get().getPossibleBiomeKeys(world.realWorld())) { if (key != null) { possible.add(key.toLowerCase()); } diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisCommand.java b/core/src/main/java/art/arcane/iris/engine/object/IrisCommand.java index c8d847cbe..bd9262b9a 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisCommand.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisCommand.java @@ -18,19 +18,17 @@ package art.arcane.iris.engine.object; -import art.arcane.iris.Iris; import art.arcane.iris.engine.object.annotations.ArrayType; import art.arcane.iris.engine.object.annotations.Desc; import art.arcane.iris.engine.object.annotations.Required; import art.arcane.iris.engine.object.annotations.Snippet; +import art.arcane.iris.spi.IrisPlatforms; +import art.arcane.iris.spi.PlatformWorld; import art.arcane.iris.util.common.scheduling.J; import art.arcane.volmlib.util.collection.KList; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.World; @Snippet("command") @Accessors(chain = true) @@ -59,27 +57,27 @@ public class IrisCommand { @Desc("The weather that is required for the command to execute.") private IrisWeather weather = IrisWeather.ANY; - public boolean isValid(World world) { + public boolean isValid(PlatformWorld world) { return timeBlock.isWithin(world) && weather.is(world); } - public void run(Location at) { - if (!isValid(at.getWorld())) { + public void run(PlatformWorld world, int x, int y, int z) { + if (!isValid(world)) { return; } for (String command : commands) { command = (command.startsWith("/") ? command.replaceFirst("/", "") : command) - .replaceAll("\\Q{x}\\E", String.valueOf(at.getBlockX())) - .replaceAll("\\Q{y}\\E", String.valueOf(at.getBlockY())) - .replaceAll("\\Q{z}\\E", String.valueOf(at.getBlockZ())); + .replaceAll("\\Q{x}\\E", String.valueOf(x)) + .replaceAll("\\Q{y}\\E", String.valueOf(y)) + .replaceAll("\\Q{z}\\E", String.valueOf(z)); final String finalCommand = command; int safeDelay = (int) Math.max(0, Math.min(Integer.MAX_VALUE, delay)); if (repeat) { int safeRepeatDelay = (int) Math.max(1, Math.min(Integer.MAX_VALUE, repeatDelay)); - J.s(() -> J.sr(() -> Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), finalCommand), safeRepeatDelay), safeDelay); + J.s(() -> J.sr(() -> IrisPlatforms.get().dispatchConsoleCommand(finalCommand), safeRepeatDelay), safeDelay); } else { - J.s(() -> Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), finalCommand), safeDelay); + J.s(() -> IrisPlatforms.get().dispatchConsoleCommand(finalCommand), safeDelay); } } } diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisCommandRegistry.java b/core/src/main/java/art/arcane/iris/engine/object/IrisCommandRegistry.java index 71f5abd2e..d43023c96 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisCommandRegistry.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisCommandRegistry.java @@ -19,6 +19,8 @@ package art.arcane.iris.engine.object; import art.arcane.iris.engine.object.annotations.*; +import art.arcane.iris.platform.bukkit.BukkitWorld; +import art.arcane.iris.spi.PlatformWorld; import art.arcane.volmlib.util.collection.KList; import art.arcane.volmlib.util.math.RNG; import lombok.Data; @@ -67,12 +69,13 @@ public class IrisCommandRegistry { public void run(Player p) { if (rawCommands.isNotEmpty()) { + PlatformWorld world = new BukkitWorld(p.getWorld()); Location part = p.getLocation().clone().add( commandRandomAltX ? RNG.r.d(-commandOffsetX, commandOffsetX) : commandOffsetX, commandRandomAltY ? RNG.r.d(-commandOffsetY, commandOffsetY) : commandOffsetY, commandRandomAltZ ? RNG.r.d(-commandOffsetZ, commandOffsetZ) : commandOffsetZ); for (IrisCommand rawCommand : rawCommands) { - rawCommand.run(part); + rawCommand.run(world, part.getBlockX(), part.getBlockY(), part.getBlockZ()); if (commandAllRandomLocations) { part = p.getLocation().clone().add( commandRandomAltX ? RNG.r.d(-commandOffsetX, commandOffsetX) : commandOffsetX, 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 bb28f344c..21f42ab06 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 @@ -26,6 +26,8 @@ import art.arcane.iris.core.nms.INMS; import art.arcane.iris.core.service.ExternalDataSVC; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.object.annotations.*; +import art.arcane.iris.platform.bukkit.BukkitWorld; +import art.arcane.iris.spi.PlatformWorld; import art.arcane.volmlib.util.collection.KList; import art.arcane.iris.util.common.format.C; import art.arcane.volmlib.util.json.JSONObject; @@ -338,7 +340,8 @@ public class IrisEntity extends IrisRegistrant { if (rawCommands.isNotEmpty()) { final Location fat = at; - rawCommands.forEach(r -> r.run(fat)); + final PlatformWorld commandWorld = new BukkitWorld(fat.getWorld()); + rawCommands.forEach(r -> r.run(commandWorld, fat.getBlockX(), fat.getBlockY(), fat.getBlockZ())); } Location finalAt1 = at; diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisSpawner.java b/core/src/main/java/art/arcane/iris/engine/object/IrisSpawner.java index ed046333a..753196faf 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisSpawner.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisSpawner.java @@ -22,6 +22,8 @@ import art.arcane.iris.core.loader.IrisRegistrant; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.object.annotations.ArrayType; import art.arcane.iris.engine.object.annotations.Desc; +import art.arcane.iris.platform.bukkit.BukkitWorld; +import art.arcane.iris.spi.PlatformWorld; import art.arcane.volmlib.util.collection.KList; import art.arcane.volmlib.util.json.JSONObject; import art.arcane.iris.util.common.plugin.VolmitSender; @@ -90,7 +92,8 @@ public class IrisSpawner extends IrisRegistrant { } public boolean isValid(World world) { - return timeBlock.isWithin(world) && weather.is(world); + PlatformWorld platformWorld = new BukkitWorld(world); + return timeBlock.isWithin(platformWorld) && weather.is(platformWorld); } public boolean canSpawn(Engine engine) { diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisTimeBlock.java b/core/src/main/java/art/arcane/iris/engine/object/IrisTimeBlock.java index 6010b1d65..b681ec45d 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisTimeBlock.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisTimeBlock.java @@ -20,8 +20,8 @@ package art.arcane.iris.engine.object; import art.arcane.iris.engine.object.annotations.Desc; import art.arcane.iris.engine.object.annotations.Snippet; +import art.arcane.iris.spi.PlatformWorld; import lombok.Data; -import org.bukkit.World; @Snippet("time-block") @Data @@ -33,7 +33,7 @@ public class IrisTimeBlock { @Desc("The ending hour. Set both to the same number for any time. If they are both set to -1, it will always be not allowed.") private double endHour = 0; - public boolean isWithin(World world) { + public boolean isWithin(PlatformWorld world) { return isWithin(((world.getTime() / 1000D) + 6) % 24); } diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisWeather.java b/core/src/main/java/art/arcane/iris/engine/object/IrisWeather.java index 7279d6138..8c4a2a059 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisWeather.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisWeather.java @@ -19,7 +19,7 @@ package art.arcane.iris.engine.object; import art.arcane.iris.engine.object.annotations.Desc; -import org.bukkit.World; +import art.arcane.iris.spi.PlatformWorld; @Desc("Represents a weather type") public enum IrisWeather { @@ -35,11 +35,11 @@ public enum IrisWeather { @Desc("Any weather") ANY; - public boolean is(World world) { + public boolean is(PlatformWorld world) { return switch (this) { - case NONE -> world.isClearWeather(); - case DOWNFALL -> world.hasStorm(); - case DOWNFALL_WITH_THUNDER -> world.hasStorm() && world.isThundering(); + case NONE -> !world.isStorming() && !world.isThundering(); + case DOWNFALL -> world.isStorming(); + case DOWNFALL_WITH_THUNDER -> world.isStorming() && world.isThundering(); case ANY -> true; }; } 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 7338208c3..f791c5680 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 @@ -68,6 +68,11 @@ public final class BukkitPlatform implements IrisPlatform { return Iris.instance.getDataFolder(); } + @Override + public void dispatchConsoleCommand(String command) { + Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), command); + } + @Override public void log(LogLevel level, String message) { switch (level) { diff --git a/core/src/main/java/art/arcane/iris/platform/bukkit/BukkitWorld.java b/core/src/main/java/art/arcane/iris/platform/bukkit/BukkitWorld.java index ed91c7ba3..0a570ae54 100644 --- a/core/src/main/java/art/arcane/iris/platform/bukkit/BukkitWorld.java +++ b/core/src/main/java/art/arcane/iris/platform/bukkit/BukkitWorld.java @@ -74,6 +74,21 @@ public final class BukkitWorld implements PlatformWorld { return world.isChunkLoaded(chunkX, chunkZ); } + @Override + public long getTime() { + return world.getTime(); + } + + @Override + public boolean isStorming() { + return world.hasStorm(); + } + + @Override + public boolean isThundering() { + return world.isThundering(); + } + @Override public Object nativeHandle() { return world; 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 0806652fc..90d9bb6b4 100644 --- a/spi/src/main/java/art/arcane/iris/spi/IrisPlatform.java +++ b/spi/src/main/java/art/arcane/iris/spi/IrisPlatform.java @@ -36,5 +36,7 @@ public interface IrisPlatform { File dataFolder(); + void dispatchConsoleCommand(String command); + void log(LogLevel level, String message); } diff --git a/spi/src/main/java/art/arcane/iris/spi/PlatformWorld.java b/spi/src/main/java/art/arcane/iris/spi/PlatformWorld.java index ff29a5f1a..a80dcdeae 100644 --- a/spi/src/main/java/art/arcane/iris/spi/PlatformWorld.java +++ b/spi/src/main/java/art/arcane/iris/spi/PlatformWorld.java @@ -38,5 +38,11 @@ public interface PlatformWorld { boolean isChunkLoaded(int chunkX, int chunkZ); + long getTime(); + + boolean isStorming(); + + boolean isThundering(); + Object nativeHandle(); }