From a911685aafc19bcbad33e1fe5d415ea0b8fd73f1 Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Wed, 5 Mar 2025 21:58:30 +0100 Subject: [PATCH 01/13] Fix world gen datapack incompatibilities --- core/src/main/java/com/volmit/iris/Iris.java | 6 ++-- .../iris/core/commands/CommandIris.java | 6 ++-- .../volmit/iris/core/tools/IrisCreator.java | 3 +- .../iris/core/nms/v1_20_R1/NMSBinding.java | 34 ++++++++++++++++-- .../iris/core/nms/v1_20_R2/NMSBinding.java | 36 ++++++++++++++++--- .../iris/core/nms/v1_20_R3/NMSBinding.java | 36 ++++++++++++++++--- .../iris/core/nms/v1_20_R4/NMSBinding.java | 30 ++++++++++++++++ .../iris/core/nms/v1_21_R1/NMSBinding.java | 36 ++++++++++++++++--- .../iris/core/nms/v1_21_R2/NMSBinding.java | 30 ++++++++++++++++ .../iris/core/nms/v1_21_R3/NMSBinding.java | 30 ++++++++++++++++ 10 files changed, 225 insertions(+), 22 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/Iris.java b/core/src/main/java/com/volmit/iris/Iris.java index 45e7a4765..99c7927e5 100644 --- a/core/src/main/java/com/volmit/iris/Iris.java +++ b/core/src/main/java/com/volmit/iris/Iris.java @@ -515,11 +515,11 @@ public class Iris extends VolmitPlugin implements Listener { Iris.info("Loading World: %s | Generator: %s", s, generator); Iris.info(C.LIGHT_PURPLE + "Preparing Spawn for " + s + "' using Iris:" + generator + "..."); - new WorldCreator(s) + WorldCreator c = new WorldCreator(s) .type(IrisWorldCreator.IRIS) .generator(getDefaultWorldGenerator(s, generator)) - .environment(IrisData.loadAnyDimension(generator).getEnvironment()) - .createWorld(); + .environment(IrisData.loadAnyDimension(generator).getEnvironment()); + INMS.get().createWorld(c); Iris.info(C.LIGHT_PURPLE + "Loaded " + s + "!"); } } catch (Throwable e) { diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index 054ec042f..9279beb71 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -599,10 +599,10 @@ public class CommandIris implements DecreeExecutor { continue; } Iris.info(C.LIGHT_PURPLE + "Preparing Spawn for " + s + "' using Iris:" + generator + "..."); - new WorldCreator(s) + WorldCreator c = new WorldCreator(s) .generator(getDefaultWorldGenerator(s, generator)) - .environment(IrisData.loadAnyDimension(generator).getEnvironment()) - .createWorld(); + .environment(IrisData.loadAnyDimension(generator).getEnvironment()); + INMS.get().createWorld(c); Iris.info(C.LIGHT_PURPLE + "Loaded " + s + "!"); } } catch (Throwable e) { diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java b/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java index 6f14bc5d3..ddcd5ff85 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java @@ -22,6 +22,7 @@ import com.google.common.util.concurrent.AtomicDouble; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.ServerConfigurator; +import com.volmit.iris.core.nms.INMS; import com.volmit.iris.core.pregenerator.PregenTask; import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.engine.object.IrisDimension; @@ -170,7 +171,7 @@ public class IrisCreator { try { J.sfut(() -> { - world.set(wc.createWorld()); + world.set(INMS.get().createWorld(wc)); }).get(); } catch (Throwable e) { e.printStackTrace(); diff --git a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java index a9ad26383..9858d14ca 100644 --- a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java +++ b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java @@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_20_R1; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.Lifecycle; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMSBinding; import com.volmit.iris.core.nms.container.BiomeColor; @@ -20,14 +21,15 @@ import com.volmit.iris.util.nbt.mca.palette.*; import com.volmit.iris.util.nbt.tag.CompoundTag; import com.volmit.iris.util.scheduling.J; import it.unimi.dsi.fastutil.objects.Object2IntMap; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; +import lombok.SneakyThrows; +import net.minecraft.core.*; import net.minecraft.core.Registry; -import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.*; import net.minecraft.nbt.Tag; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.WorldLoader; import net.minecraft.server.commands.data.BlockDataAccessor; import net.minecraft.server.level.ServerLevel; import net.minecraft.tags.TagKey; @@ -85,6 +87,7 @@ public class NMSBinding implements INMSBinding { private final KMap baseBiomeCache = new KMap<>(); private final BlockData AIR = Material.AIR.createBlockData(); private final AtomicCache> biomeMapCache = new AtomicCache<>(); + private final AtomicCache dataLoadContext = new AtomicCache<>(); private final AtomicCache> registryCache = new AtomicCache<>(); private final AtomicCache> globalCache = new AtomicCache<>(); private final AtomicCache registryAccess = new AtomicCache<>(); @@ -628,4 +631,29 @@ public class NMSBinding implements INMSBinding { } } } + + @Override + @SneakyThrows + public World createWorld(WorldCreator creator) { + var server = ((CraftServer) Bukkit.getServer()); + var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class); + var nmsServer = server.getServer(); + var old = nmsServer.worldLoader; + + field.setAccessible(true); + field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of( + new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()).freeze() + )).freeze() + ))); + + try { + return server.createWorld(creator); + } finally { + field.set(nmsServer, old); + } + } } diff --git a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java index 804f35074..16d630ddb 100644 --- a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java +++ b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java @@ -15,10 +15,16 @@ import java.util.Vector; import java.util.concurrent.atomic.AtomicInteger; import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.Lifecycle; import com.volmit.iris.core.nms.container.BiomeColor; import com.volmit.iris.util.scheduling.J; +import lombok.SneakyThrows; +import net.minecraft.core.*; +import net.minecraft.core.Registry; import net.minecraft.nbt.*; import net.minecraft.nbt.Tag; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.WorldLoader; import net.minecraft.server.commands.data.BlockDataAccessor; import net.minecraft.tags.TagKey; import net.minecraft.world.level.LevelReader; @@ -61,10 +67,6 @@ import com.volmit.iris.util.nbt.mca.palette.*; import com.volmit.iris.util.nbt.tag.CompoundTag; import it.unimi.dsi.fastutil.objects.Object2IntMap; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -83,6 +85,7 @@ public class NMSBinding implements INMSBinding { private final KMap baseBiomeCache = new KMap<>(); private final BlockData AIR = Material.AIR.createBlockData(); private final AtomicCache> biomeMapCache = new AtomicCache<>(); + private final AtomicCache dataLoadContext = new AtomicCache<>(); private final AtomicCache> registryCache = new AtomicCache<>(); private final AtomicCache> globalCache = new AtomicCache<>(); private final AtomicCache registryAccess = new AtomicCache<>(); @@ -630,4 +633,29 @@ public class NMSBinding implements INMSBinding { public static Holder biomeToBiomeBase(Registry registry, Biome biome) { return registry.getHolderOrThrow(ResourceKey.create(Registries.BIOME, CraftNamespacedKey.toMinecraft(biome.getKey()))); } + + @Override + @SneakyThrows + public World createWorld(WorldCreator creator) { + var server = ((CraftServer) Bukkit.getServer()); + var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class); + var nmsServer = server.getServer(); + var old = nmsServer.worldLoader; + + field.setAccessible(true); + field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of( + new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()).freeze() + )).freeze() + ))); + + try { + return server.createWorld(creator); + } finally { + field.set(nmsServer, old); + } + } } diff --git a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java index 59a124514..8389535d2 100644 --- a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java +++ b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java @@ -15,10 +15,16 @@ import java.util.Vector; import java.util.concurrent.atomic.AtomicInteger; import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.Lifecycle; import com.volmit.iris.core.nms.container.BiomeColor; import com.volmit.iris.util.scheduling.J; +import lombok.SneakyThrows; +import net.minecraft.core.*; +import net.minecraft.core.Registry; import net.minecraft.nbt.*; import net.minecraft.nbt.Tag; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.WorldLoader; import net.minecraft.server.commands.data.BlockDataAccessor; import net.minecraft.tags.TagKey; import net.minecraft.world.level.LevelReader; @@ -61,10 +67,6 @@ import com.volmit.iris.util.nbt.mca.palette.*; import com.volmit.iris.util.nbt.tag.CompoundTag; import it.unimi.dsi.fastutil.objects.Object2IntMap; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -83,6 +85,7 @@ public class NMSBinding implements INMSBinding { private final KMap baseBiomeCache = new KMap<>(); private final BlockData AIR = Material.AIR.createBlockData(); private final AtomicCache> biomeMapCache = new AtomicCache<>(); + private final AtomicCache dataLoadContext = new AtomicCache<>(); private final AtomicCache> registryCache = new AtomicCache<>(); private final AtomicCache> globalCache = new AtomicCache<>(); private final AtomicCache registryAccess = new AtomicCache<>(); @@ -631,4 +634,29 @@ public class NMSBinding implements INMSBinding { public static Holder biomeToBiomeBase(Registry registry, Biome biome) { return registry.getHolderOrThrow(ResourceKey.create(Registries.BIOME, CraftNamespacedKey.toMinecraft(biome.getKey()))); } + + @Override + @SneakyThrows + public World createWorld(WorldCreator creator) { + var server = ((CraftServer) Bukkit.getServer()); + var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class); + var nmsServer = server.getServer(); + var old = nmsServer.worldLoader; + + field.setAccessible(true); + field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of( + new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()).freeze() + )).freeze() + ))); + + try { + return server.createWorld(creator); + } finally { + field.set(nmsServer, old); + } + } } diff --git a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java index ea7518d6a..68293d885 100644 --- a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java +++ b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java @@ -8,10 +8,12 @@ import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.Lifecycle; import com.volmit.iris.core.nms.container.BiomeColor; import com.volmit.iris.core.nms.datapack.DataVersion; import com.volmit.iris.util.nbt.tag.CompoundTag; import com.volmit.iris.util.scheduling.J; +import lombok.SneakyThrows; import net.minecraft.core.*; import net.minecraft.core.Registry; import net.minecraft.core.component.DataComponents; @@ -25,6 +27,8 @@ import net.minecraft.nbt.LongTag; import net.minecraft.nbt.ShortTag; import net.minecraft.nbt.StringTag; import net.minecraft.nbt.Tag; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.WorldLoader; import net.minecraft.server.commands.data.BlockDataAccessor; import net.minecraft.server.commands.data.DataCommands; import net.minecraft.server.level.ServerLevel; @@ -86,6 +90,7 @@ public class NMSBinding implements INMSBinding { private final KMap baseBiomeCache = new KMap<>(); private final BlockData AIR = Material.AIR.createBlockData(); private final AtomicCache> biomeMapCache = new AtomicCache<>(); + private final AtomicCache dataLoadContext = new AtomicCache<>(); private final AtomicCache> registryCache = new AtomicCache<>(); private final AtomicCache> globalCache = new AtomicCache<>(); private final AtomicCache registryAccess = new AtomicCache<>(); @@ -650,4 +655,29 @@ public class NMSBinding implements INMSBinding { return keys; } + + @Override + @SneakyThrows + public World createWorld(WorldCreator creator) { + var server = ((CraftServer) Bukkit.getServer()); + var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class); + var nmsServer = server.getServer(); + var old = nmsServer.worldLoader; + + field.setAccessible(true); + field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of( + new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()).freeze() + )).freeze() + ))); + + try { + return server.createWorld(creator); + } finally { + field.set(nmsServer, old); + } + } } diff --git a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java index be0a12f5b..25cc5f087 100644 --- a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java +++ b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java @@ -12,12 +12,18 @@ import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.Lifecycle; import com.volmit.iris.core.nms.container.BiomeColor; import com.volmit.iris.core.nms.datapack.DataVersion; import com.volmit.iris.util.scheduling.J; +import lombok.SneakyThrows; +import net.minecraft.core.*; +import net.minecraft.core.Registry; import net.minecraft.core.component.DataComponents; import net.minecraft.nbt.*; import net.minecraft.nbt.Tag; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.WorldLoader; import net.minecraft.server.commands.data.BlockDataAccessor; import net.minecraft.server.level.ChunkMap; import net.minecraft.tags.TagKey; @@ -64,10 +70,6 @@ import com.volmit.iris.util.nbt.mca.palette.*; import com.volmit.iris.util.nbt.tag.CompoundTag; import it.unimi.dsi.fastutil.objects.Object2IntMap; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -85,6 +87,7 @@ public class NMSBinding implements INMSBinding { private final KMap baseBiomeCache = new KMap<>(); private final BlockData AIR = Material.AIR.createBlockData(); private final AtomicCache> biomeMapCache = new AtomicCache<>(); + private final AtomicCache dataLoadContext = new AtomicCache<>(); private final AtomicCache> registryCache = new AtomicCache<>(); private final AtomicCache> globalCache = new AtomicCache<>(); private final AtomicCache registryAccess = new AtomicCache<>(); @@ -657,4 +660,29 @@ public class NMSBinding implements INMSBinding { return keys; } + + @Override + @SneakyThrows + public World createWorld(WorldCreator creator) { + var server = ((CraftServer) Bukkit.getServer()); + var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class); + var nmsServer = server.getServer(); + var old = nmsServer.worldLoader; + + field.setAccessible(true); + field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of( + new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()).freeze() + )).freeze() + ))); + + try { + return server.createWorld(creator); + } finally { + field.set(nmsServer, old); + } + } } diff --git a/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java b/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java index 0522d35f9..9d5de6bdb 100644 --- a/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java +++ b/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java @@ -7,14 +7,18 @@ import java.lang.reflect.Modifier; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; +import com.mojang.serialization.Lifecycle; import com.volmit.iris.core.nms.container.BiomeColor; import com.volmit.iris.core.nms.datapack.DataVersion; import com.volmit.iris.util.scheduling.J; +import lombok.SneakyThrows; import net.minecraft.core.*; import net.minecraft.core.Registry; import net.minecraft.core.component.DataComponents; import net.minecraft.nbt.*; import net.minecraft.nbt.Tag; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.WorldLoader; import net.minecraft.server.commands.data.BlockDataAccessor; import net.minecraft.tags.TagKey; import net.minecraft.world.item.component.CustomData; @@ -72,6 +76,7 @@ public class NMSBinding implements INMSBinding { private final KMap baseBiomeCache = new KMap<>(); private final BlockData AIR = Material.AIR.createBlockData(); private final AtomicCache> biomeMapCache = new AtomicCache<>(); + private final AtomicCache dataLoadContext = new AtomicCache<>(); private final AtomicCache> registryCache = new AtomicCache<>(); private final AtomicCache> globalCache = new AtomicCache<>(); private final AtomicCache registryAccess = new AtomicCache<>(); @@ -644,4 +649,29 @@ public class NMSBinding implements INMSBinding { return keys; } + + @Override + @SneakyThrows + public World createWorld(WorldCreator creator) { + var server = ((CraftServer) Bukkit.getServer()); + var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class); + var nmsServer = server.getServer(); + var old = nmsServer.worldLoader; + + field.setAccessible(true); + field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of( + new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()).freeze() + )).freeze() + ))); + + try { + return server.createWorld(creator); + } finally { + field.set(nmsServer, old); + } + } } diff --git a/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java b/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java index 7a5ac4f9d..982ef1223 100644 --- a/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java +++ b/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java @@ -1,6 +1,7 @@ package com.volmit.iris.core.nms.v1_21_R3; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.serialization.Lifecycle; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMSBinding; import com.volmit.iris.core.nms.container.BiomeColor; @@ -19,6 +20,7 @@ import com.volmit.iris.util.nbt.mca.palette.*; import com.volmit.iris.util.nbt.tag.CompoundTag; import com.volmit.iris.util.scheduling.J; import it.unimi.dsi.fastutil.objects.Object2IntMap; +import lombok.SneakyThrows; import net.minecraft.core.Registry; import net.minecraft.core.*; import net.minecraft.core.component.DataComponents; @@ -27,6 +29,8 @@ import net.minecraft.nbt.Tag; import net.minecraft.nbt.*; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.WorldLoader; import net.minecraft.server.commands.data.BlockDataAccessor; import net.minecraft.server.level.ServerLevel; import net.minecraft.tags.TagKey; @@ -71,6 +75,7 @@ public class NMSBinding implements INMSBinding { private final KMap baseBiomeCache = new KMap<>(); private final BlockData AIR = Material.AIR.createBlockData(); private final AtomicCache> biomeMapCache = new AtomicCache<>(); + private final AtomicCache dataLoadContext = new AtomicCache<>(); private final AtomicCache> registryCache = new AtomicCache<>(); private final AtomicCache> globalCache = new AtomicCache<>(); private final AtomicCache registryAccess = new AtomicCache<>(); @@ -643,4 +648,29 @@ public class NMSBinding implements INMSBinding { return keys; } + + @Override + @SneakyThrows + public World createWorld(WorldCreator creator) { + var server = ((CraftServer) Bukkit.getServer()); + var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class); + var nmsServer = server.getServer(); + var old = nmsServer.worldLoader; + + field.setAccessible(true); + field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of( + new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()).freeze() + )).freeze() + ))); + + try { + return server.createWorld(creator); + } finally { + field.set(nmsServer, old); + } + } } From 686ae57b5bb5537b52840d5a04512bd89a160858 Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Sun, 9 Mar 2025 19:18:13 +0100 Subject: [PATCH 02/13] switch from world preset to direct level stems --- core/src/main/java/com/volmit/iris/Iris.java | 1 - .../iris/core/nms/datapack/IDataFixer.java | 40 ------------------- .../iris/core/tools/IrisWorldCreator.java | 16 -------- .../iris/core/nms/v1_20_R1/NMSBinding.java | 29 ++++++++++++-- .../iris/core/nms/v1_20_R2/NMSBinding.java | 28 +++++++++++-- .../iris/core/nms/v1_20_R3/NMSBinding.java | 28 +++++++++++-- .../iris/core/nms/v1_20_R4/NMSBinding.java | 29 ++++++++++++-- .../iris/core/nms/v1_21_R1/NMSBinding.java | 28 +++++++++++-- .../iris/core/nms/v1_21_R2/NMSBinding.java | 28 +++++++++++-- .../iris/core/nms/v1_21_R3/NMSBinding.java | 28 +++++++++++-- 10 files changed, 177 insertions(+), 78 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/Iris.java b/core/src/main/java/com/volmit/iris/Iris.java index 99c7927e5..d848cdd9e 100644 --- a/core/src/main/java/com/volmit/iris/Iris.java +++ b/core/src/main/java/com/volmit/iris/Iris.java @@ -516,7 +516,6 @@ public class Iris extends VolmitPlugin implements Listener { Iris.info(C.LIGHT_PURPLE + "Preparing Spawn for " + s + "' using Iris:" + generator + "..."); WorldCreator c = new WorldCreator(s) - .type(IrisWorldCreator.IRIS) .generator(getDefaultWorldGenerator(s, generator)) .environment(IrisData.loadAnyDimension(generator).getEnvironment()); INMS.get().createWorld(c); diff --git a/core/src/main/java/com/volmit/iris/core/nms/datapack/IDataFixer.java b/core/src/main/java/com/volmit/iris/core/nms/datapack/IDataFixer.java index 7ea4e1ded..4d972128e 100644 --- a/core/src/main/java/com/volmit/iris/core/nms/datapack/IDataFixer.java +++ b/core/src/main/java/com/volmit/iris/core/nms/datapack/IDataFixer.java @@ -20,46 +20,6 @@ public interface IDataFixer { return obj; } - default JSONObject createPreset() { - return new JSONObject(""" -{ - "dimensions": { - "minecraft:overworld": { - "type": "iris:overworld", - "generator": { - "type": "minecraft:noise", - "biome_source": { - "type": "minecraft:multi_noise", - "preset": "minecraft:overworld" - }, - "settings": "minecraft:overworld" - } - }, - "minecraft:the_end": { - "type": "iris:the_end", - "generator": { - "type": "minecraft:noise", - "biome_source": { - "type": "minecraft:the_end" - }, - "settings": "minecraft:end" - } - }, - "minecraft:the_nether": { - "type": "iris:the_nether", - "generator": { - "type": "minecraft:noise", - "biome_source": { - "type": "minecraft:multi_noise", - "preset": "minecraft:nether" - }, - "settings": "minecraft:nether" - } - } - } -}"""); - } - enum Dimension { OVERRWORLD, NETHER, diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java b/core/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java index c1799c07d..97ec2eceb 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java @@ -32,8 +32,6 @@ import sun.misc.Unsafe; import java.io.File; public class IrisWorldCreator { - public static final WorldType IRIS; - private String name; private boolean studio = false; private String dimensionName = null; @@ -85,7 +83,6 @@ public class IrisWorldCreator { return new WorldCreator(name) - .type(IRIS) .environment(findEnvironment()) .generateStructures(true) .generator(g).seed(seed); @@ -104,17 +101,4 @@ public class IrisWorldCreator { this.studio = studio; return this; } - - static { - try { - var unsafe = new WrappedField(Unsafe.class, "theUnsafe").get(); - var iris = (WorldType) unsafe.allocateInstance(WorldType.class); - unsafe.putIntVolatile(iris, unsafe.objectFieldOffset(Enum.class.getDeclaredField("ordinal")), 0); - unsafe.putObjectVolatile(iris, unsafe.objectFieldOffset(Enum.class.getDeclaredField("name")), "IRIS"); - - IRIS = iris; - } catch (Throwable e) { - throw new ExceptionInInitializerError(e); - } - } } diff --git a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java index 9858d14ca..32964212e 100644 --- a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java +++ b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java @@ -27,6 +27,7 @@ import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.*; import net.minecraft.nbt.Tag; +import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.WorldLoader; @@ -43,6 +44,8 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.dimension.DimensionType; +import net.minecraft.world.level.dimension.LevelStem; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -571,6 +574,8 @@ public class NMSBinding implements INMSBinding { public void inject(long seed, Engine engine, World world) { var chunkMap = ((CraftWorld)world).getHandle().getChunkSource().chunkMap; + if (!chunkMap.level.dimension().location().getPath().startsWith("iris")) + Iris.error("Loaded world %s with invalid dimension type!", world.getName()); chunkMap.generator = new IrisChunkGenerator(chunkMap.generator, seed, engine, world); } @@ -645,9 +650,7 @@ public class NMSBinding implements INMSBinding { old.resources(), old.dataConfiguration(), old.datapackWorldgen(), - new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of( - new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()).freeze() - )).freeze() + createRegistryAccess() ))); try { @@ -656,4 +659,24 @@ public class NMSBinding implements INMSBinding { field.set(nmsServer, old); } } + + private RegistryAccess.Frozen createRegistryAccess() { + var access = registry(); + var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE); + var levelStems = access.registryOrThrow(Registries.LEVEL_STEM); + + var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); + register(fake, levelStems, dimensions, LevelStem.OVERWORLD); + register(fake, levelStems, dimensions, LevelStem.NETHER); + register(fake, levelStems, dimensions, LevelStem.END); + + return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); + } + + private void register(MappedRegistry target, Registry levelStems, Registry dimensions, ResourceKey key) { + target.register(key, new LevelStem( + dimensions.getHolderOrThrow(ResourceKey.create(Registries.DIMENSION_TYPE, new ResourceLocation("iris", key.location().getPath()))), + levelStems.getOrThrow(key).generator() + ), Lifecycle.stable()); + } } diff --git a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java index 16d630ddb..f37090480 100644 --- a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java +++ b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java @@ -29,6 +29,8 @@ import net.minecraft.server.commands.data.BlockDataAccessor; import net.minecraft.tags.TagKey; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.dimension.DimensionType; +import net.minecraft.world.level.dimension.LevelStem; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -541,6 +543,8 @@ public class NMSBinding implements INMSBinding { public void inject(long seed, Engine engine, World world) { var chunkMap = ((CraftWorld)world).getHandle().getChunkSource().chunkMap; + if (!chunkMap.level.dimension().location().getPath().startsWith("iris")) + Iris.error("Loaded world %s with invalid dimension type!", world.getName()); chunkMap.generator = new IrisChunkGenerator(chunkMap.generator, seed, engine, world); } @@ -647,9 +651,7 @@ public class NMSBinding implements INMSBinding { old.resources(), old.dataConfiguration(), old.datapackWorldgen(), - new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of( - new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()).freeze() - )).freeze() + createRegistryAccess() ))); try { @@ -658,4 +660,24 @@ public class NMSBinding implements INMSBinding { field.set(nmsServer, old); } } + + private RegistryAccess.Frozen createRegistryAccess() { + var access = registry(); + var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE); + var levelStems = access.registryOrThrow(Registries.LEVEL_STEM); + + var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); + register(fake, levelStems, dimensions, LevelStem.OVERWORLD); + register(fake, levelStems, dimensions, LevelStem.NETHER); + register(fake, levelStems, dimensions, LevelStem.END); + + return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); + } + + private void register(MappedRegistry target, Registry levelStems, Registry dimensions, ResourceKey key) { + target.register(key, new LevelStem( + dimensions.getHolderOrThrow(ResourceKey.create(Registries.DIMENSION_TYPE, new ResourceLocation("iris", key.location().getPath()))), + levelStems.getOrThrow(key).generator() + ), Lifecycle.stable()); + } } diff --git a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java index 8389535d2..06c84620b 100644 --- a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java +++ b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java @@ -29,6 +29,8 @@ import net.minecraft.server.commands.data.BlockDataAccessor; import net.minecraft.tags.TagKey; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.dimension.DimensionType; +import net.minecraft.world.level.dimension.LevelStem; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -541,6 +543,8 @@ public class NMSBinding implements INMSBinding { public void inject(long seed, Engine engine, World world) { var chunkMap = ((CraftWorld)world).getHandle().getChunkSource().chunkMap; + if (!chunkMap.level.dimension().location().getPath().startsWith("iris")) + Iris.error("Loaded world %s with invalid dimension type!", world.getName()); chunkMap.generator = new IrisChunkGenerator(chunkMap.generator, seed, engine, world); } @@ -648,9 +652,7 @@ public class NMSBinding implements INMSBinding { old.resources(), old.dataConfiguration(), old.datapackWorldgen(), - new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of( - new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()).freeze() - )).freeze() + createRegistryAccess() ))); try { @@ -659,4 +661,24 @@ public class NMSBinding implements INMSBinding { field.set(nmsServer, old); } } + + private RegistryAccess.Frozen createRegistryAccess() { + var access = registry(); + var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE); + var levelStems = access.registryOrThrow(Registries.LEVEL_STEM); + + var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); + register(fake, levelStems, dimensions, LevelStem.OVERWORLD); + register(fake, levelStems, dimensions, LevelStem.NETHER); + register(fake, levelStems, dimensions, LevelStem.END); + + return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); + } + + private void register(MappedRegistry target, Registry levelStems, Registry dimensions, ResourceKey key) { + target.register(key, new LevelStem( + dimensions.getHolderOrThrow(ResourceKey.create(Registries.DIMENSION_TYPE, new ResourceLocation("iris", key.location().getPath()))), + levelStems.getOrThrow(key).generator() + ), Lifecycle.stable()); + } } diff --git a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java index 68293d885..be7a8c0be 100644 --- a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java +++ b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java @@ -38,6 +38,8 @@ import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.chunk.status.ChunkStatus; +import net.minecraft.world.level.dimension.DimensionType; +import net.minecraft.world.level.dimension.LevelStem; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -549,6 +551,9 @@ public class NMSBinding implements INMSBinding { public void inject(long seed, Engine engine, World world) { var chunkMap = ((CraftWorld)world).getHandle().getChunkSource().chunkMap; + if (!chunkMap.level.dimension().location().getPath().startsWith("iris")) + Iris.error("Loaded world %s with invalid dimension type!", world.getName()); + chunkMap.generator = new IrisChunkGenerator(chunkMap.generator, seed, engine, world); } @@ -669,9 +674,7 @@ public class NMSBinding implements INMSBinding { old.resources(), old.dataConfiguration(), old.datapackWorldgen(), - new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of( - new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()).freeze() - )).freeze() + createRegistryAccess() ))); try { @@ -680,4 +683,24 @@ public class NMSBinding implements INMSBinding { field.set(nmsServer, old); } } + + private RegistryAccess.Frozen createRegistryAccess() { + var access = registry(); + var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE); + var levelStems = access.registryOrThrow(Registries.LEVEL_STEM); + + var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); + register(fake, levelStems, dimensions, LevelStem.OVERWORLD); + register(fake, levelStems, dimensions, LevelStem.NETHER); + register(fake, levelStems, dimensions, LevelStem.END); + + return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); + } + + private void register(MappedRegistry target, Registry levelStems, Registry dimensions, ResourceKey key) { + target.register(key, new LevelStem( + dimensions.getHolder(new ResourceLocation("iris", key.location().getPath())).orElseThrow(), + levelStems.getOrThrow(key).generator() + ), RegistrationInfo.BUILT_IN); + } } diff --git a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java index 25cc5f087..6e540ca26 100644 --- a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java +++ b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java @@ -32,6 +32,8 @@ import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.chunk.status.ChunkStatus; import net.minecraft.world.level.chunk.status.WorldGenContext; +import net.minecraft.world.level.dimension.DimensionType; +import net.minecraft.world.level.dimension.LevelStem; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -549,6 +551,8 @@ public class NMSBinding implements INMSBinding { var worldGenContextField = getField(chunkMap.getClass(), WorldGenContext.class); worldGenContextField.setAccessible(true); var worldGenContext = (WorldGenContext) worldGenContextField.get(chunkMap); + if (!chunkMap.level.dimension().location().getPath().startsWith("iris")) + Iris.error("Loaded world %s with invalid dimension type!", world.getName()); var newContext = new WorldGenContext( worldGenContext.level(), new IrisChunkGenerator(worldGenContext.generator(), seed, engine, world), @@ -674,9 +678,7 @@ public class NMSBinding implements INMSBinding { old.resources(), old.dataConfiguration(), old.datapackWorldgen(), - new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of( - new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()).freeze() - )).freeze() + createRegistryAccess() ))); try { @@ -685,4 +687,24 @@ public class NMSBinding implements INMSBinding { field.set(nmsServer, old); } } + + private RegistryAccess.Frozen createRegistryAccess() { + var access = registry(); + var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE); + var levelStems = access.registryOrThrow(Registries.LEVEL_STEM); + + var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); + register(fake, levelStems, dimensions, LevelStem.OVERWORLD); + register(fake, levelStems, dimensions, LevelStem.NETHER); + register(fake, levelStems, dimensions, LevelStem.END); + + return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); + } + + private void register(MappedRegistry target, Registry levelStems, Registry dimensions, ResourceKey key) { + target.register(key, new LevelStem( + dimensions.getHolder(ResourceLocation.fromNamespaceAndPath("iris", key.location().getPath())).orElseThrow(), + levelStems.getOrThrow(key).generator() + ), RegistrationInfo.BUILT_IN); + } } diff --git a/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java b/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java index 9d5de6bdb..3170bbb00 100644 --- a/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java +++ b/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java @@ -26,6 +26,8 @@ import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.chunk.status.ChunkStatus; import net.minecraft.world.level.chunk.status.WorldGenContext; +import net.minecraft.world.level.dimension.DimensionType; +import net.minecraft.world.level.dimension.LevelStem; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -538,6 +540,8 @@ public class NMSBinding implements INMSBinding { var worldGenContextField = getField(chunkMap.getClass(), WorldGenContext.class); worldGenContextField.setAccessible(true); var worldGenContext = (WorldGenContext) worldGenContextField.get(chunkMap); + if (!chunkMap.level.dimension().location().getPath().startsWith("iris")) + Iris.error("Loaded world %s with invalid dimension type!", world.getName()); var newContext = new WorldGenContext( worldGenContext.level(), new IrisChunkGenerator(worldGenContext.generator(), seed, engine, world), @@ -663,9 +667,7 @@ public class NMSBinding implements INMSBinding { old.resources(), old.dataConfiguration(), old.datapackWorldgen(), - new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of( - new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()).freeze() - )).freeze() + createRegistryAccess() ))); try { @@ -674,4 +676,24 @@ public class NMSBinding implements INMSBinding { field.set(nmsServer, old); } } + + private RegistryAccess.Frozen createRegistryAccess() { + var access = registry(); + var dimensions = access.lookupOrThrow(Registries.DIMENSION_TYPE); + var levelStems = access.lookupOrThrow(Registries.LEVEL_STEM); + + var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); + register(fake, levelStems, dimensions, LevelStem.OVERWORLD); + register(fake, levelStems, dimensions, LevelStem.NETHER); + register(fake, levelStems, dimensions, LevelStem.END); + + return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); + } + + private void register(MappedRegistry target, Registry levelStems, Registry dimensions, ResourceKey key) { + target.register(key, new LevelStem( + dimensions.get(ResourceLocation.fromNamespaceAndPath("iris", key.location().getPath())).orElseThrow(), + levelStems.getValueOrThrow(key).generator() + ), RegistrationInfo.BUILT_IN); + } } diff --git a/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java b/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java index 982ef1223..2a45ca360 100644 --- a/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java +++ b/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java @@ -45,6 +45,8 @@ import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.status.ChunkStatus; import net.minecraft.world.level.chunk.status.WorldGenContext; +import net.minecraft.world.level.dimension.DimensionType; +import net.minecraft.world.level.dimension.LevelStem; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -537,6 +539,8 @@ public class NMSBinding implements INMSBinding { var worldGenContextField = getField(chunkMap.getClass(), WorldGenContext.class); worldGenContextField.setAccessible(true); var worldGenContext = (WorldGenContext) worldGenContextField.get(chunkMap); + if (!chunkMap.level.dimension().location().getPath().startsWith("iris")) + Iris.error("Loaded world %s with invalid dimension type!", world.getName()); var newContext = new WorldGenContext( worldGenContext.level(), new IrisChunkGenerator(worldGenContext.generator(), seed, engine, world), @@ -662,9 +666,7 @@ public class NMSBinding implements INMSBinding { old.resources(), old.dataConfiguration(), old.datapackWorldgen(), - new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of( - new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()).freeze() - )).freeze() + createRegistryAccess() ))); try { @@ -673,4 +675,24 @@ public class NMSBinding implements INMSBinding { field.set(nmsServer, old); } } + + private RegistryAccess.Frozen createRegistryAccess() { + var access = registry(); + var dimensions = access.lookupOrThrow(Registries.DIMENSION_TYPE); + var levelStems = access.lookupOrThrow(Registries.LEVEL_STEM); + + var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); + register(fake, levelStems, dimensions, LevelStem.OVERWORLD); + register(fake, levelStems, dimensions, LevelStem.NETHER); + register(fake, levelStems, dimensions, LevelStem.END); + + return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); + } + + private void register(MappedRegistry target, Registry levelStems, Registry dimensions, ResourceKey key) { + target.register(key, new LevelStem( + dimensions.get(ResourceLocation.fromNamespaceAndPath("iris", key.location().getPath())).orElseThrow(), + levelStems.getValueOrThrow(key).generator() + ), RegistrationInfo.BUILT_IN); + } } From 94bf530d93ed789525296187fe2579e461792f08 Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Sun, 9 Mar 2025 19:19:37 +0100 Subject: [PATCH 03/13] add setting to enable changing to the vanilla dimension height values --- .../com/volmit/iris/core/IrisSettings.java | 1 + .../iris/engine/object/IrisDimension.java | 63 +++++++------------ 2 files changed, 23 insertions(+), 41 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/IrisSettings.java b/core/src/main/java/com/volmit/iris/core/IrisSettings.java index 8a687b564..5381a7e39 100644 --- a/core/src/main/java/com/volmit/iris/core/IrisSettings.java +++ b/core/src/main/java/com/volmit/iris/core/IrisSettings.java @@ -181,6 +181,7 @@ public class IrisSettings { public boolean splashLogoStartup = true; public boolean useConsoleCustomColors = true; public boolean useCustomColorsIngame = true; + public boolean adjustVanillaHeight = false; public String forceMainWorld = ""; public int spinh = -20; public int spins = 7; diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java index eb0493f52..818a8ac78 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java @@ -19,6 +19,7 @@ package com.volmit.iris.engine.object; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.ServerConfigurator.DimensionHeight; import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.loader.IrisRegistrant; @@ -409,9 +410,6 @@ public class IrisDimension extends IrisRegistrant { Iris.verbose(" Installing Data Pack Dimension Types: \"iris:overworld\", \"iris:the_nether\", \"iris:the_end\""); changed = writeDimensionType(changed, datapacks, height); - Iris.verbose(" Installing Data Pack World Preset: \"minecraft:iris\""); - changed = writeWorldPreset(changed, datapacks, fixer); - if (write) { File mcm = new File(datapacks, "iris/pack.mcmeta"); try { @@ -449,55 +447,38 @@ public class IrisDimension extends IrisRegistrant { } public boolean writeDimensionType(boolean changed, File datapacks, DimensionHeight height) { - File dimTypeOverworld = new File(datapacks, "iris/data/iris/dimension_type/overworld.json"); - if (!dimTypeOverworld.exists()) - changed = true; - dimTypeOverworld.getParentFile().mkdirs(); - try { - IO.writeAll(dimTypeOverworld, height.overworldType()); - } catch (IOException e) { - Iris.reportError(e); - e.printStackTrace(); - } - - - File dimTypeNether = new File(datapacks, "iris/data/iris/dimension_type/the_nether.json"); - if (!dimTypeNether.exists()) - changed = true; - dimTypeNether.getParentFile().mkdirs(); - try { - IO.writeAll(dimTypeNether, height.netherType()); - } catch (IOException e) { - Iris.reportError(e); - e.printStackTrace(); - } - - - File dimTypeEnd = new File(datapacks, "iris/data/iris/dimension_type/the_end.json"); - if (!dimTypeEnd.exists()) - changed = true; - dimTypeEnd.getParentFile().mkdirs(); - try { - IO.writeAll(dimTypeEnd, height.endType()); - } catch (IOException e) { - Iris.reportError(e); - e.printStackTrace(); - } + changed = write(changed, datapacks, "overworld", height.overworldType()); + changed = write(changed, datapacks, "the_nether", height.netherType()); + changed = write(changed, datapacks, "the_end", height.endType()); return changed; } - public boolean writeWorldPreset(boolean changed, File datapacks, IDataFixer fixer) { - File worldPreset = new File(datapacks, "iris/data/minecraft/worldgen/world_preset/iris.json"); - if (!worldPreset.exists()) + private static boolean write(boolean changed, File datapacks, String type, String json) { + File dimType = new File(datapacks, "iris/data/iris/dimension_type/" + type + ".json"); + if (!dimType.exists()) changed = true; + dimType.getParentFile().mkdirs(); try { - IO.writeAll(worldPreset, fixer.createPreset()); + IO.writeAll(dimType, json); } catch (IOException e) { Iris.reportError(e); e.printStackTrace(); } + if (IrisSettings.get().getGeneral().adjustVanillaHeight) { + File dimTypeVanilla = new File(datapacks, "iris/data/minecraft/dimension_type/" + type + ".json"); + if (!dimTypeVanilla.exists()) + changed = true; + dimTypeVanilla.getParentFile().mkdirs(); + try { + IO.writeAll(dimTypeVanilla, json); + } catch (IOException e) { + Iris.reportError(e); + e.printStackTrace(); + } + } + return changed; } } From 1c5eb8b910567a220f917dfec45b88c9a6eb10be Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Mon, 10 Mar 2025 12:09:28 +0100 Subject: [PATCH 04/13] automatically update vanilla dimension type if present in Iris datapack --- .../main/java/com/volmit/iris/core/ServerConfigurator.java | 1 + .../java/com/volmit/iris/engine/object/IrisDimension.java | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java b/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java index 9a641f1d3..8d579d859 100644 --- a/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java +++ b/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java @@ -107,6 +107,7 @@ public class ServerConfigurator { DimensionHeight height = new DimensionHeight(fixer); allPacks().flatMap(height::merge) + .toList() .forEach(dim -> { for (File dpack : getDatapacksFolder()) { Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath()); diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java index 818a8ac78..08dc3b77f 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java @@ -456,6 +456,8 @@ public class IrisDimension extends IrisRegistrant { private static boolean write(boolean changed, File datapacks, String type, String json) { File dimType = new File(datapacks, "iris/data/iris/dimension_type/" + type + ".json"); + File dimTypeVanilla = new File(datapacks, "iris/data/minecraft/dimension_type/" + type + ".json"); + if (!dimType.exists()) changed = true; dimType.getParentFile().mkdirs(); @@ -466,8 +468,7 @@ public class IrisDimension extends IrisRegistrant { e.printStackTrace(); } - if (IrisSettings.get().getGeneral().adjustVanillaHeight) { - File dimTypeVanilla = new File(datapacks, "iris/data/minecraft/dimension_type/" + type + ".json"); + if (IrisSettings.get().getGeneral().adjustVanillaHeight || dimTypeVanilla.exists()) { if (!dimTypeVanilla.exists()) changed = true; dimTypeVanilla.getParentFile().mkdirs(); From 7fa1484b215d12f6f8608057a61d5e657cbb0752 Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Tue, 11 Mar 2025 14:24:27 +0100 Subject: [PATCH 05/13] fix levelstem injection not working for main worlds --- core/src/main/java/com/volmit/iris/Iris.java | 2 + .../com/volmit/iris/core/nms/INMSBinding.java | 14 ++- .../iris/core/nms/container/AutoClosing.java | 22 +++++ .../engine/object/IrisContextInjector.java | 67 +++++++++++++ .../iris/util/misc/ServerProperties.java | 39 ++++++++ .../iris/core/nms/v1_20_R1/NMSBinding.java | 95 +++++++++++++++---- .../iris/core/nms/v1_20_R2/NMSBinding.java | 95 +++++++++++++++---- .../iris/core/nms/v1_20_R3/NMSBinding.java | 95 +++++++++++++++---- .../iris/core/nms/v1_20_R4/NMSBinding.java | 90 ++++++++++++++---- .../iris/core/nms/v1_21_R1/NMSBinding.java | 90 ++++++++++++++---- .../iris/core/nms/v1_21_R2/NMSBinding.java | 91 ++++++++++++++---- .../iris/core/nms/v1_21_R3/NMSBinding.java | 91 ++++++++++++++---- 12 files changed, 659 insertions(+), 132 deletions(-) create mode 100644 core/src/main/java/com/volmit/iris/core/nms/container/AutoClosing.java create mode 100644 core/src/main/java/com/volmit/iris/engine/object/IrisContextInjector.java create mode 100644 core/src/main/java/com/volmit/iris/util/misc/ServerProperties.java diff --git a/core/src/main/java/com/volmit/iris/Iris.java b/core/src/main/java/com/volmit/iris/Iris.java index d848cdd9e..db0d69377 100644 --- a/core/src/main/java/com/volmit/iris/Iris.java +++ b/core/src/main/java/com/volmit/iris/Iris.java @@ -35,6 +35,7 @@ import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.core.tools.IrisWorldCreator; import com.volmit.iris.engine.EnginePanic; import com.volmit.iris.engine.object.IrisCompat; +import com.volmit.iris.engine.object.IrisContextInjector; import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.engine.object.IrisWorld; import com.volmit.iris.engine.platform.BukkitChunkGenerator; @@ -466,6 +467,7 @@ public class Iris extends VolmitPlugin implements Listener { configWatcher = new FileWatcher(getDataFile("settings.json")); services.values().forEach(IrisService::onEnable); services.values().forEach(this::registerListener); + registerListener(new IrisContextInjector()); J.s(() -> { J.a(() -> PaperLib.suggestPaper(this)); J.a(() -> IO.delete(getTemp())); diff --git a/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java b/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java index d75c87672..ac3894f65 100644 --- a/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java +++ b/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java @@ -18,7 +18,9 @@ package com.volmit.iris.core.nms; +import com.volmit.iris.core.nms.container.AutoClosing; import com.volmit.iris.core.nms.container.BiomeColor; +import com.volmit.iris.core.nms.container.Pair; import com.volmit.iris.core.nms.datapack.DataVersion; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.util.collection.KList; @@ -91,7 +93,9 @@ public interface INMSBinding { MCABiomeContainer newBiomeContainer(int min, int max); default World createWorld(WorldCreator c) { - return c.createWorld(); + try (var ignored = injectLevelStems()) { + return c.createWorld(); + } } int countCustomBiomes(); @@ -125,4 +129,12 @@ public interface INMSBinding { } KList getStructureKeys(); + + default AutoClosing injectLevelStems() { + return new AutoClosing(() -> {}); + } + + default Pair injectUncached(boolean overworld, boolean nether, boolean end) { + return new Pair<>(0, injectLevelStems()); + } } diff --git a/core/src/main/java/com/volmit/iris/core/nms/container/AutoClosing.java b/core/src/main/java/com/volmit/iris/core/nms/container/AutoClosing.java new file mode 100644 index 000000000..afa2ba9dc --- /dev/null +++ b/core/src/main/java/com/volmit/iris/core/nms/container/AutoClosing.java @@ -0,0 +1,22 @@ +package com.volmit.iris.core.nms.container; + +import com.volmit.iris.util.function.NastyRunnable; +import lombok.AllArgsConstructor; + +import java.util.concurrent.atomic.AtomicBoolean; + +@AllArgsConstructor +public class AutoClosing implements AutoCloseable { + private final AtomicBoolean closed = new AtomicBoolean(); + private final NastyRunnable action; + + @Override + public void close() { + if (closed.getAndSet(true)) return; + try { + action.run(); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } +} diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisContextInjector.java b/core/src/main/java/com/volmit/iris/engine/object/IrisContextInjector.java new file mode 100644 index 000000000..772a4c560 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisContextInjector.java @@ -0,0 +1,67 @@ +package com.volmit.iris.engine.object; + +import com.volmit.iris.core.nms.INMS; +import com.volmit.iris.core.nms.container.AutoClosing; +import com.volmit.iris.util.misc.ServerProperties; +import org.bukkit.Bukkit; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.world.WorldInitEvent; + +import java.util.List; + +import static com.volmit.iris.Iris.instance; + +public class IrisContextInjector implements Listener { + private AutoClosing autoClosing = null; + private final int totalWorlds; + private int worldCounter = 0; + + public IrisContextInjector() { + if (!Bukkit.getWorlds().isEmpty()) { + totalWorlds = 0; + return; + } + + String levelName = ServerProperties.LEVEL_NAME; + List irisWorlds = irisWorlds(); + boolean overworld = irisWorlds.contains(levelName); + boolean nether = irisWorlds.contains(levelName + "_nether"); + boolean end = irisWorlds.contains(levelName + "_end"); + + int i = 1; + if (Bukkit.getAllowNether()) i++; + if (Bukkit.getAllowEnd()) i++; + + if (overworld || nether || end) { + var pair = INMS.get().injectUncached(overworld, nether, end); + i += pair.getA() - 3; + autoClosing = pair.getB(); + } + + totalWorlds = i; + } + + @EventHandler + public void on(WorldInitEvent event) { + if (++worldCounter < totalWorlds) return; + if (autoClosing != null) { + autoClosing.close(); + autoClosing = null; + } + instance.unregisterListener(this); + } + + private List irisWorlds() { + var config = YamlConfiguration.loadConfiguration(ServerProperties.BUKKIT_YML); + ConfigurationSection section = config.getConfigurationSection("worlds"); + if (section == null) return List.of(); + + return section.getKeys(false) + .stream() + .filter(k -> section.getString(k + ".generator", "").startsWith("Iris")) + .toList(); + } +} diff --git a/core/src/main/java/com/volmit/iris/util/misc/ServerProperties.java b/core/src/main/java/com/volmit/iris/util/misc/ServerProperties.java new file mode 100644 index 000000000..b79e844f1 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/util/misc/ServerProperties.java @@ -0,0 +1,39 @@ +package com.volmit.iris.util.misc; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Properties; + +public class ServerProperties { + public static final Properties DATA = new Properties(); + public static final File SERVER_PROPERTIES; + public static final File BUKKIT_YML; + + public static final String LEVEL_NAME = DATA.getProperty("level-name", "world"); + + static { + String[] args = ProcessHandle.current() + .info() + .arguments() + .orElse(new String[0]); + + String propertiesPath = "server.properties"; + String bukkitYml = "bukkit.yml"; + + for (int i = 0; i < args.length - 1; i++) { + switch (args[i]) { + case "-c", "--config" -> propertiesPath = args[i + 1]; + case "-b", "--bukkit-settings" -> bukkitYml = args[i + 1]; + } + } + + SERVER_PROPERTIES = new File(propertiesPath); + BUKKIT_YML = new File(bukkitYml); + try (FileInputStream in = new FileInputStream(SERVER_PROPERTIES)){ + DATA.load(in); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java index 32964212e..0a0e51a6e 100644 --- a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java +++ b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java @@ -5,6 +5,7 @@ import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Lifecycle; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMSBinding; +import com.volmit.iris.core.nms.container.AutoClosing; import com.volmit.iris.core.nms.container.BiomeColor; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; @@ -78,11 +79,10 @@ import java.io.DataOutputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Vector; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Function; public class NMSBinding implements INMSBinding { @@ -94,6 +94,7 @@ public class NMSBinding implements INMSBinding { private final AtomicCache> registryCache = new AtomicCache<>(); private final AtomicCache> globalCache = new AtomicCache<>(); private final AtomicCache registryAccess = new AtomicCache<>(); + private final ReentrantLock dataContextLock = new ReentrantLock(true); private final AtomicCache byIdRef = new AtomicCache<>(); private Field biomeStorageCache = null; @@ -574,8 +575,9 @@ public class NMSBinding implements INMSBinding { public void inject(long seed, Engine engine, World world) { var chunkMap = ((CraftWorld)world).getHandle().getChunkSource().chunkMap; - if (!chunkMap.level.dimension().location().getPath().startsWith("iris")) - Iris.error("Loaded world %s with invalid dimension type!", world.getName()); + var dimensionType = chunkMap.level.dimensionTypeRegistration().unwrapKey().orElse(null); + if (dimensionType != null && !dimensionType.location().getNamespace().equals("iris")) + Iris.error("Loaded world %s with invalid dimension type! (%s)", world.getName(), dimensionType.location().toString()); chunkMap.generator = new IrisChunkGenerator(chunkMap.generator, seed, engine, world); } @@ -637,38 +639,79 @@ public class NMSBinding implements INMSBinding { } } + @Override + public AutoClosing injectLevelStems() { + return inject(this::supplier); + } + @Override @SneakyThrows - public World createWorld(WorldCreator creator) { + public com.volmit.iris.core.nms.container.Pair injectUncached(boolean overworld, boolean nether, boolean end) { + var reg = registry(); + var field = getField(RegistryAccess.ImmutableRegistryAccess.class, Map.class); + field.setAccessible(true); + + AutoClosing closing = inject(old -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + createRegistryAccess(old.datapackDimensions(), true, overworld, nether, end) + ) + ); + + var injected = ((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions().registryOrThrow(Registries.LEVEL_STEM); + var old = (Map>, Registry>) field.get(reg); + var fake = new HashMap<>(old); + fake.put(Registries.LEVEL_STEM, injected); + field.set(reg, fake); + + return new com.volmit.iris.core.nms.container.Pair<>( + injected.size(), + new AutoClosing(() -> { + closing.close(); + field.set(reg, old); + })); + } + + private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) { + return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + createRegistryAccess(old.datapackDimensions(), false, true, true, true) + )); + } + + @SneakyThrows + private AutoClosing inject(Function transformer) { + if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!"); + var server = ((CraftServer) Bukkit.getServer()); var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class); var nmsServer = server.getServer(); var old = nmsServer.worldLoader; field.setAccessible(true); - field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( - old.resources(), - old.dataConfiguration(), - old.datapackWorldgen(), - createRegistryAccess() - ))); + field.set(nmsServer, transformer.apply(old)); - try { - return server.createWorld(creator); - } finally { + return new AutoClosing(() -> { field.set(nmsServer, old); - } + dataContextLock.unlock(); + }); } - private RegistryAccess.Frozen createRegistryAccess() { + private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) { var access = registry(); var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE); var levelStems = access.registryOrThrow(Registries.LEVEL_STEM); var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); - register(fake, levelStems, dimensions, LevelStem.OVERWORLD); - register(fake, levelStems, dimensions, LevelStem.NETHER); - register(fake, levelStems, dimensions, LevelStem.END); + if (overworld) register(fake, levelStems, dimensions, LevelStem.OVERWORLD); + if (nether) register(fake, levelStems, dimensions, LevelStem.NETHER); + if (end) register(fake, levelStems, dimensions, LevelStem.END); + copy(fake, datapack.registry(Registries.LEVEL_STEM).orElse(null)); + + if (copy) copy(fake, levelStems); return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); } @@ -679,4 +722,14 @@ public class NMSBinding implements INMSBinding { levelStems.getOrThrow(key).generator() ), Lifecycle.stable()); } + + private void copy(MappedRegistry target, Registry source) { + if (source == null) return; + source.registryKeySet().forEach(key -> { + var value = source.get(key); + var info = source.lifecycle(value); + if (value != null && info != null && !target.containsKey(key)) + target.register(key, value, info); + }); + } } diff --git a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java index f37090480..924e04791 100644 --- a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java +++ b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java @@ -8,14 +8,14 @@ import java.io.DataOutputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Vector; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Function; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Lifecycle; +import com.volmit.iris.core.nms.container.AutoClosing; import com.volmit.iris.core.nms.container.BiomeColor; import com.volmit.iris.util.scheduling.J; import lombok.SneakyThrows; @@ -91,6 +91,7 @@ public class NMSBinding implements INMSBinding { private final AtomicCache> registryCache = new AtomicCache<>(); private final AtomicCache> globalCache = new AtomicCache<>(); private final AtomicCache registryAccess = new AtomicCache<>(); + private final ReentrantLock dataContextLock = new ReentrantLock(true); private final AtomicCache byIdRef = new AtomicCache<>(); private Field biomeStorageCache = null; @@ -543,8 +544,9 @@ public class NMSBinding implements INMSBinding { public void inject(long seed, Engine engine, World world) { var chunkMap = ((CraftWorld)world).getHandle().getChunkSource().chunkMap; - if (!chunkMap.level.dimension().location().getPath().startsWith("iris")) - Iris.error("Loaded world %s with invalid dimension type!", world.getName()); + var dimensionType = chunkMap.level.dimensionTypeRegistration().unwrapKey().orElse(null); + if (dimensionType != null && !dimensionType.location().getNamespace().equals("iris")) + Iris.error("Loaded world %s with invalid dimension type! (%s)", world.getName(), dimensionType.location().toString()); chunkMap.generator = new IrisChunkGenerator(chunkMap.generator, seed, engine, world); } @@ -638,38 +640,79 @@ public class NMSBinding implements INMSBinding { return registry.getHolderOrThrow(ResourceKey.create(Registries.BIOME, CraftNamespacedKey.toMinecraft(biome.getKey()))); } + @Override + public AutoClosing injectLevelStems() { + return inject(this::supplier); + } + @Override @SneakyThrows - public World createWorld(WorldCreator creator) { + public com.volmit.iris.core.nms.container.Pair injectUncached(boolean overworld, boolean nether, boolean end) { + var reg = registry(); + var field = getField(RegistryAccess.ImmutableRegistryAccess.class, Map.class); + field.setAccessible(true); + + AutoClosing closing = inject(old -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + createRegistryAccess(old.datapackDimensions(), true, overworld, nether, end) + ) + ); + + var injected = ((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions().registryOrThrow(Registries.LEVEL_STEM); + var old = (Map>, Registry>) field.get(reg); + var fake = new HashMap<>(old); + fake.put(Registries.LEVEL_STEM, injected); + field.set(reg, fake); + + return new com.volmit.iris.core.nms.container.Pair<>( + injected.size(), + new AutoClosing(() -> { + closing.close(); + field.set(reg, old); + })); + } + + private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) { + return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + createRegistryAccess(old.datapackDimensions(), false, true, true, true) + )); + } + + @SneakyThrows + private AutoClosing inject(Function transformer) { + if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!"); + var server = ((CraftServer) Bukkit.getServer()); var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class); var nmsServer = server.getServer(); var old = nmsServer.worldLoader; field.setAccessible(true); - field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( - old.resources(), - old.dataConfiguration(), - old.datapackWorldgen(), - createRegistryAccess() - ))); + field.set(nmsServer, transformer.apply(old)); - try { - return server.createWorld(creator); - } finally { + return new AutoClosing(() -> { field.set(nmsServer, old); - } + dataContextLock.unlock(); + }); } - private RegistryAccess.Frozen createRegistryAccess() { + private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) { var access = registry(); var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE); var levelStems = access.registryOrThrow(Registries.LEVEL_STEM); var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); - register(fake, levelStems, dimensions, LevelStem.OVERWORLD); - register(fake, levelStems, dimensions, LevelStem.NETHER); - register(fake, levelStems, dimensions, LevelStem.END); + if (overworld) register(fake, levelStems, dimensions, LevelStem.OVERWORLD); + if (nether) register(fake, levelStems, dimensions, LevelStem.NETHER); + if (end) register(fake, levelStems, dimensions, LevelStem.END); + copy(fake, datapack.registry(Registries.LEVEL_STEM).orElse(null)); + + if (copy) copy(fake, levelStems); return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); } @@ -680,4 +723,14 @@ public class NMSBinding implements INMSBinding { levelStems.getOrThrow(key).generator() ), Lifecycle.stable()); } + + private void copy(MappedRegistry target, Registry source) { + if (source == null) return; + source.registryKeySet().forEach(key -> { + var value = source.get(key); + var info = source.lifecycle(value); + if (value != null && info != null && !target.containsKey(key)) + target.register(key, value, info); + }); + } } diff --git a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java index 06c84620b..283e4a594 100644 --- a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java +++ b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java @@ -8,14 +8,14 @@ import java.io.DataOutputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Vector; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Function; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Lifecycle; +import com.volmit.iris.core.nms.container.AutoClosing; import com.volmit.iris.core.nms.container.BiomeColor; import com.volmit.iris.util.scheduling.J; import lombok.SneakyThrows; @@ -91,6 +91,7 @@ public class NMSBinding implements INMSBinding { private final AtomicCache> registryCache = new AtomicCache<>(); private final AtomicCache> globalCache = new AtomicCache<>(); private final AtomicCache registryAccess = new AtomicCache<>(); + private final ReentrantLock dataContextLock = new ReentrantLock(true); private final AtomicCache byIdRef = new AtomicCache<>(); private Field biomeStorageCache = null; @@ -543,8 +544,9 @@ public class NMSBinding implements INMSBinding { public void inject(long seed, Engine engine, World world) { var chunkMap = ((CraftWorld)world).getHandle().getChunkSource().chunkMap; - if (!chunkMap.level.dimension().location().getPath().startsWith("iris")) - Iris.error("Loaded world %s with invalid dimension type!", world.getName()); + var dimensionType = chunkMap.level.dimensionTypeRegistration().unwrapKey().orElse(null); + if (dimensionType != null && !dimensionType.location().getNamespace().equals("iris")) + Iris.error("Loaded world %s with invalid dimension type! (%s)", world.getName(), dimensionType.location().toString()); chunkMap.generator = new IrisChunkGenerator(chunkMap.generator, seed, engine, world); } @@ -639,38 +641,79 @@ public class NMSBinding implements INMSBinding { return registry.getHolderOrThrow(ResourceKey.create(Registries.BIOME, CraftNamespacedKey.toMinecraft(biome.getKey()))); } + @Override + public AutoClosing injectLevelStems() { + return inject(this::supplier); + } + @Override @SneakyThrows - public World createWorld(WorldCreator creator) { + public com.volmit.iris.core.nms.container.Pair injectUncached(boolean overworld, boolean nether, boolean end) { + var reg = registry(); + var field = getField(RegistryAccess.ImmutableRegistryAccess.class, Map.class); + field.setAccessible(true); + + AutoClosing closing = inject(old -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + createRegistryAccess(old.datapackDimensions(), true, overworld, nether, end) + ) + ); + + var injected = ((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions().registryOrThrow(Registries.LEVEL_STEM); + var old = (Map>, Registry>) field.get(reg); + var fake = new HashMap<>(old); + fake.put(Registries.LEVEL_STEM, injected); + field.set(reg, fake); + + return new com.volmit.iris.core.nms.container.Pair<>( + injected.size(), + new AutoClosing(() -> { + closing.close(); + field.set(reg, old); + })); + } + + private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) { + return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + createRegistryAccess(old.datapackDimensions(), false, true, true, true) + )); + } + + @SneakyThrows + private AutoClosing inject(Function transformer) { + if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!"); + var server = ((CraftServer) Bukkit.getServer()); var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class); var nmsServer = server.getServer(); var old = nmsServer.worldLoader; field.setAccessible(true); - field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( - old.resources(), - old.dataConfiguration(), - old.datapackWorldgen(), - createRegistryAccess() - ))); + field.set(nmsServer, transformer.apply(old)); - try { - return server.createWorld(creator); - } finally { + return new AutoClosing(() -> { field.set(nmsServer, old); - } + dataContextLock.unlock(); + }); } - private RegistryAccess.Frozen createRegistryAccess() { + private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) { var access = registry(); var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE); var levelStems = access.registryOrThrow(Registries.LEVEL_STEM); var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); - register(fake, levelStems, dimensions, LevelStem.OVERWORLD); - register(fake, levelStems, dimensions, LevelStem.NETHER); - register(fake, levelStems, dimensions, LevelStem.END); + if (overworld) register(fake, levelStems, dimensions, LevelStem.OVERWORLD); + if (nether) register(fake, levelStems, dimensions, LevelStem.NETHER); + if (end) register(fake, levelStems, dimensions, LevelStem.END); + copy(fake, datapack.registry(Registries.LEVEL_STEM).orElse(null)); + + if (copy) copy(fake, levelStems); return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); } @@ -681,4 +724,14 @@ public class NMSBinding implements INMSBinding { levelStems.getOrThrow(key).generator() ), Lifecycle.stable()); } + + private void copy(MappedRegistry target, Registry source) { + if (source == null) return; + source.registryKeySet().forEach(key -> { + var value = source.get(key); + var info = source.lifecycle(value); + if (value != null && info != null && !target.containsKey(key)) + target.register(key, value, info); + }); + } } diff --git a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java index be7a8c0be..14e103eb5 100644 --- a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java +++ b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java @@ -6,9 +6,12 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Function; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Lifecycle; +import com.volmit.iris.core.nms.container.AutoClosing; import com.volmit.iris.core.nms.container.BiomeColor; import com.volmit.iris.core.nms.datapack.DataVersion; import com.volmit.iris.util.nbt.tag.CompoundTag; @@ -96,6 +99,7 @@ public class NMSBinding implements INMSBinding { private final AtomicCache> registryCache = new AtomicCache<>(); private final AtomicCache> globalCache = new AtomicCache<>(); private final AtomicCache registryAccess = new AtomicCache<>(); + private final ReentrantLock dataContextLock = new ReentrantLock(true); private final AtomicCache byIdRef = new AtomicCache<>(); private Field biomeStorageCache = null; @@ -551,8 +555,9 @@ public class NMSBinding implements INMSBinding { public void inject(long seed, Engine engine, World world) { var chunkMap = ((CraftWorld)world).getHandle().getChunkSource().chunkMap; - if (!chunkMap.level.dimension().location().getPath().startsWith("iris")) - Iris.error("Loaded world %s with invalid dimension type!", world.getName()); + var dimensionType = chunkMap.level.dimensionTypeRegistration().unwrapKey().orElse(null); + if (dimensionType != null && !dimensionType.location().getNamespace().equals("iris")) + Iris.error("Loaded world %s with invalid dimension type! (%s)", world.getName(), dimensionType.location().toString()); chunkMap.generator = new IrisChunkGenerator(chunkMap.generator, seed, engine, world); } @@ -661,38 +666,79 @@ public class NMSBinding implements INMSBinding { return keys; } + @Override + public AutoClosing injectLevelStems() { + return inject(this::supplier); + } + @Override @SneakyThrows - public World createWorld(WorldCreator creator) { + public com.volmit.iris.core.nms.container.Pair injectUncached(boolean overworld, boolean nether, boolean end) { + var reg = registry(); + var field = getField(RegistryAccess.ImmutableRegistryAccess.class, Map.class); + field.setAccessible(true); + + AutoClosing closing = inject(old -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + createRegistryAccess(old.datapackDimensions(), true, overworld, nether, end) + ) + ); + + var injected = ((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions().registryOrThrow(Registries.LEVEL_STEM); + var old = (Map>, Registry>) field.get(reg); + var fake = new HashMap<>(old); + fake.put(Registries.LEVEL_STEM, injected); + field.set(reg, fake); + + return new com.volmit.iris.core.nms.container.Pair<>( + injected.size(), + new AutoClosing(() -> { + closing.close(); + field.set(reg, old); + })); + } + + private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) { + return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + createRegistryAccess(old.datapackDimensions(), false, true, true, true) + )); + } + + @SneakyThrows + private AutoClosing inject(Function transformer) { + if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!"); + var server = ((CraftServer) Bukkit.getServer()); var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class); var nmsServer = server.getServer(); var old = nmsServer.worldLoader; field.setAccessible(true); - field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( - old.resources(), - old.dataConfiguration(), - old.datapackWorldgen(), - createRegistryAccess() - ))); + field.set(nmsServer, transformer.apply(old)); - try { - return server.createWorld(creator); - } finally { + return new AutoClosing(() -> { field.set(nmsServer, old); - } + dataContextLock.unlock(); + }); } - private RegistryAccess.Frozen createRegistryAccess() { + private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) { var access = registry(); var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE); var levelStems = access.registryOrThrow(Registries.LEVEL_STEM); var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); - register(fake, levelStems, dimensions, LevelStem.OVERWORLD); - register(fake, levelStems, dimensions, LevelStem.NETHER); - register(fake, levelStems, dimensions, LevelStem.END); + if (overworld) register(fake, levelStems, dimensions, LevelStem.OVERWORLD); + if (nether) register(fake, levelStems, dimensions, LevelStem.NETHER); + if (end) register(fake, levelStems, dimensions, LevelStem.END); + copy(fake, datapack.registry(Registries.LEVEL_STEM).orElse(null)); + + if (copy) copy(fake, levelStems); return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); } @@ -703,4 +749,14 @@ public class NMSBinding implements INMSBinding { levelStems.getOrThrow(key).generator() ), RegistrationInfo.BUILT_IN); } + + private void copy(MappedRegistry target, Registry source) { + if (source == null) return; + source.registryKeySet().forEach(key -> { + var value = source.get(key); + var info = source.registrationInfo(key).orElse(null); + if (value != null && info != null && !target.containsKey(key)) + target.register(key, value, info); + }); + } } diff --git a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java index 6e540ca26..da85e16de 100644 --- a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java +++ b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java @@ -10,9 +10,12 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Function; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Lifecycle; +import com.volmit.iris.core.nms.container.AutoClosing; import com.volmit.iris.core.nms.container.BiomeColor; import com.volmit.iris.core.nms.datapack.DataVersion; import com.volmit.iris.util.scheduling.J; @@ -93,6 +96,7 @@ public class NMSBinding implements INMSBinding { private final AtomicCache> registryCache = new AtomicCache<>(); private final AtomicCache> globalCache = new AtomicCache<>(); private final AtomicCache registryAccess = new AtomicCache<>(); + private final ReentrantLock dataContextLock = new ReentrantLock(true); private final AtomicCache byIdRef = new AtomicCache<>(); private Field biomeStorageCache = null; @@ -551,8 +555,9 @@ public class NMSBinding implements INMSBinding { var worldGenContextField = getField(chunkMap.getClass(), WorldGenContext.class); worldGenContextField.setAccessible(true); var worldGenContext = (WorldGenContext) worldGenContextField.get(chunkMap); - if (!chunkMap.level.dimension().location().getPath().startsWith("iris")) - Iris.error("Loaded world %s with invalid dimension type!", world.getName()); + var dimensionType = chunkMap.level.dimensionTypeRegistration().unwrapKey().orElse(null); + if (dimensionType != null && !dimensionType.location().getNamespace().equals("iris")) + Iris.error("Loaded world %s with invalid dimension type! (%s)", world.getName(), dimensionType.location().toString()); var newContext = new WorldGenContext( worldGenContext.level(), new IrisChunkGenerator(worldGenContext.generator(), seed, engine, world), @@ -665,38 +670,79 @@ public class NMSBinding implements INMSBinding { return keys; } + @Override + public AutoClosing injectLevelStems() { + return inject(this::supplier); + } + @Override @SneakyThrows - public World createWorld(WorldCreator creator) { + public com.volmit.iris.core.nms.container.Pair injectUncached(boolean overworld, boolean nether, boolean end) { + var reg = registry(); + var field = getField(RegistryAccess.ImmutableRegistryAccess.class, Map.class); + field.setAccessible(true); + + AutoClosing closing = inject(old -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + createRegistryAccess(old.datapackDimensions(), true, overworld, nether, end) + ) + ); + + var injected = ((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions().registryOrThrow(Registries.LEVEL_STEM); + var old = (Map>, Registry>) field.get(reg); + var fake = new HashMap<>(old); + fake.put(Registries.LEVEL_STEM, injected); + field.set(reg, fake); + + return new com.volmit.iris.core.nms.container.Pair<>( + injected.size(), + new AutoClosing(() -> { + closing.close(); + field.set(reg, old); + })); + } + + private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) { + return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + createRegistryAccess(old.datapackDimensions(), false, true, true, true) + )); + } + + @SneakyThrows + private AutoClosing inject(Function transformer) { + if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!"); + var server = ((CraftServer) Bukkit.getServer()); var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class); var nmsServer = server.getServer(); var old = nmsServer.worldLoader; field.setAccessible(true); - field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( - old.resources(), - old.dataConfiguration(), - old.datapackWorldgen(), - createRegistryAccess() - ))); + field.set(nmsServer, transformer.apply(old)); - try { - return server.createWorld(creator); - } finally { + return new AutoClosing(() -> { field.set(nmsServer, old); - } + dataContextLock.unlock(); + }); } - private RegistryAccess.Frozen createRegistryAccess() { + private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) { var access = registry(); var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE); var levelStems = access.registryOrThrow(Registries.LEVEL_STEM); var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); - register(fake, levelStems, dimensions, LevelStem.OVERWORLD); - register(fake, levelStems, dimensions, LevelStem.NETHER); - register(fake, levelStems, dimensions, LevelStem.END); + if (overworld) register(fake, levelStems, dimensions, LevelStem.OVERWORLD); + if (nether) register(fake, levelStems, dimensions, LevelStem.NETHER); + if (end) register(fake, levelStems, dimensions, LevelStem.END); + copy(fake, datapack.registry(Registries.LEVEL_STEM).orElse(null)); + + if (copy) copy(fake, levelStems); return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); } @@ -707,4 +753,14 @@ public class NMSBinding implements INMSBinding { levelStems.getOrThrow(key).generator() ), RegistrationInfo.BUILT_IN); } + + private void copy(MappedRegistry target, Registry source) { + if (source == null) return; + source.registryKeySet().forEach(key -> { + var value = source.get(key); + var info = source.registrationInfo(key).orElse(null); + if (value != null && info != null && !target.containsKey(key)) + target.register(key, value, info); + }); + } } diff --git a/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java b/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java index 3170bbb00..5773392ae 100644 --- a/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java +++ b/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java @@ -6,9 +6,13 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Function; import com.mojang.serialization.Lifecycle; +import com.volmit.iris.core.nms.container.AutoClosing; import com.volmit.iris.core.nms.container.BiomeColor; +import com.volmit.iris.core.nms.container.Pair; import com.volmit.iris.core.nms.datapack.DataVersion; import com.volmit.iris.util.scheduling.J; import lombok.SneakyThrows; @@ -82,6 +86,7 @@ public class NMSBinding implements INMSBinding { private final AtomicCache> registryCache = new AtomicCache<>(); private final AtomicCache> globalCache = new AtomicCache<>(); private final AtomicCache registryAccess = new AtomicCache<>(); + private final ReentrantLock dataContextLock = new ReentrantLock(true); private final AtomicCache byIdRef = new AtomicCache<>(); private Field biomeStorageCache = null; @@ -540,8 +545,9 @@ public class NMSBinding implements INMSBinding { var worldGenContextField = getField(chunkMap.getClass(), WorldGenContext.class); worldGenContextField.setAccessible(true); var worldGenContext = (WorldGenContext) worldGenContextField.get(chunkMap); - if (!chunkMap.level.dimension().location().getPath().startsWith("iris")) - Iris.error("Loaded world %s with invalid dimension type!", world.getName()); + var dimensionType = chunkMap.level.dimensionTypeRegistration().unwrapKey().orElse(null); + if (dimensionType != null && !dimensionType.location().getNamespace().equals("iris")) + Iris.error("Loaded world %s with invalid dimension type! (%s)", world.getName(), dimensionType.location().toString()); var newContext = new WorldGenContext( worldGenContext.level(), new IrisChunkGenerator(worldGenContext.generator(), seed, engine, world), @@ -654,38 +660,79 @@ public class NMSBinding implements INMSBinding { return keys; } + @Override + public AutoClosing injectLevelStems() { + return inject(this::supplier); + } + @Override @SneakyThrows - public World createWorld(WorldCreator creator) { + public Pair injectUncached(boolean overworld, boolean nether, boolean end) { + var reg = registry(); + var field = getField(RegistryAccess.ImmutableRegistryAccess.class, Map.class); + field.setAccessible(true); + + AutoClosing closing = inject(old -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + createRegistryAccess(old.datapackDimensions(), true, overworld, nether, end) + ) + ); + + var injected = ((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions().lookupOrThrow(Registries.LEVEL_STEM); + var old = (Map>, Registry>) field.get(reg); + var fake = new HashMap<>(old); + fake.put(Registries.LEVEL_STEM, injected); + field.set(reg, fake); + + return new Pair<>( + injected.size(), + new AutoClosing(() -> { + closing.close(); + field.set(reg, old); + })); + } + + private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) { + return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + createRegistryAccess(old.datapackDimensions(), false, true, true, true) + )); + } + + @SneakyThrows + private AutoClosing inject(Function transformer) { + if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!"); + var server = ((CraftServer) Bukkit.getServer()); var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class); var nmsServer = server.getServer(); var old = nmsServer.worldLoader; field.setAccessible(true); - field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( - old.resources(), - old.dataConfiguration(), - old.datapackWorldgen(), - createRegistryAccess() - ))); + field.set(nmsServer, transformer.apply(old)); - try { - return server.createWorld(creator); - } finally { + return new AutoClosing(() -> { field.set(nmsServer, old); - } + dataContextLock.unlock(); + }); } - private RegistryAccess.Frozen createRegistryAccess() { + private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) { var access = registry(); var dimensions = access.lookupOrThrow(Registries.DIMENSION_TYPE); var levelStems = access.lookupOrThrow(Registries.LEVEL_STEM); var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); - register(fake, levelStems, dimensions, LevelStem.OVERWORLD); - register(fake, levelStems, dimensions, LevelStem.NETHER); - register(fake, levelStems, dimensions, LevelStem.END); + if (overworld) register(fake, levelStems, dimensions, LevelStem.OVERWORLD); + if (nether) register(fake, levelStems, dimensions, LevelStem.NETHER); + if (end) register(fake, levelStems, dimensions, LevelStem.END); + copy(fake, datapack.lookup(Registries.LEVEL_STEM).orElse(null)); + + if (copy) copy(fake, levelStems); return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); } @@ -696,4 +743,14 @@ public class NMSBinding implements INMSBinding { levelStems.getValueOrThrow(key).generator() ), RegistrationInfo.BUILT_IN); } + + private void copy(MappedRegistry target, Registry source) { + if (source == null) return; + source.listElementIds().forEach(key -> { + var value = source.getValue(key); + var info = source.registrationInfo(key).orElse(null); + if (value != null && info != null && !target.containsKey(key)) + target.register(key, value, info); + }); + } } diff --git a/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java b/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java index 2a45ca360..e31895550 100644 --- a/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java +++ b/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java @@ -4,7 +4,9 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.serialization.Lifecycle; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMSBinding; +import com.volmit.iris.core.nms.container.AutoClosing; import com.volmit.iris.core.nms.container.BiomeColor; +import com.volmit.iris.core.nms.container.Pair; import com.volmit.iris.core.nms.datapack.DataVersion; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; @@ -72,6 +74,8 @@ import java.lang.reflect.Modifier; import java.util.List; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Function; public class NMSBinding implements INMSBinding { private final KMap baseBiomeCache = new KMap<>(); @@ -81,6 +85,7 @@ public class NMSBinding implements INMSBinding { private final AtomicCache> registryCache = new AtomicCache<>(); private final AtomicCache> globalCache = new AtomicCache<>(); private final AtomicCache registryAccess = new AtomicCache<>(); + private final ReentrantLock dataContextLock = new ReentrantLock(true); private final AtomicCache byIdRef = new AtomicCache<>(); private Field biomeStorageCache = null; @@ -539,8 +544,9 @@ public class NMSBinding implements INMSBinding { var worldGenContextField = getField(chunkMap.getClass(), WorldGenContext.class); worldGenContextField.setAccessible(true); var worldGenContext = (WorldGenContext) worldGenContextField.get(chunkMap); - if (!chunkMap.level.dimension().location().getPath().startsWith("iris")) - Iris.error("Loaded world %s with invalid dimension type!", world.getName()); + var dimensionType = chunkMap.level.dimensionTypeRegistration().unwrapKey().orElse(null); + if (dimensionType != null && !dimensionType.location().getNamespace().equals("iris")) + Iris.error("Loaded world %s with invalid dimension type! (%s)", world.getName(), dimensionType.location().toString()); var newContext = new WorldGenContext( worldGenContext.level(), new IrisChunkGenerator(worldGenContext.generator(), seed, engine, world), @@ -653,38 +659,79 @@ public class NMSBinding implements INMSBinding { return keys; } + @Override + public AutoClosing injectLevelStems() { + return inject(this::supplier); + } + @Override @SneakyThrows - public World createWorld(WorldCreator creator) { + public Pair injectUncached(boolean overworld, boolean nether, boolean end) { + var reg = registry(); + var field = getField(RegistryAccess.ImmutableRegistryAccess.class, Map.class); + field.setAccessible(true); + + AutoClosing closing = inject(old -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + createRegistryAccess(old.datapackDimensions(), true, overworld, nether, end) + ) + ); + + var injected = ((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions().lookupOrThrow(Registries.LEVEL_STEM); + var old = (Map>, Registry>) field.get(reg); + var fake = new HashMap<>(old); + fake.put(Registries.LEVEL_STEM, injected); + field.set(reg, fake); + + return new Pair<>( + injected.size(), + new AutoClosing(() -> { + closing.close(); + field.set(reg, old); + })); + } + + private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) { + return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( + old.resources(), + old.dataConfiguration(), + old.datapackWorldgen(), + createRegistryAccess(old.datapackDimensions(), false, true, true, true) + )); + } + + @SneakyThrows + private AutoClosing inject(Function transformer) { + if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!"); + var server = ((CraftServer) Bukkit.getServer()); var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class); var nmsServer = server.getServer(); var old = nmsServer.worldLoader; field.setAccessible(true); - field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( - old.resources(), - old.dataConfiguration(), - old.datapackWorldgen(), - createRegistryAccess() - ))); + field.set(nmsServer, transformer.apply(old)); - try { - return server.createWorld(creator); - } finally { + return new AutoClosing(() -> { field.set(nmsServer, old); - } + dataContextLock.unlock(); + }); } - private RegistryAccess.Frozen createRegistryAccess() { + private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) { var access = registry(); var dimensions = access.lookupOrThrow(Registries.DIMENSION_TYPE); var levelStems = access.lookupOrThrow(Registries.LEVEL_STEM); var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); - register(fake, levelStems, dimensions, LevelStem.OVERWORLD); - register(fake, levelStems, dimensions, LevelStem.NETHER); - register(fake, levelStems, dimensions, LevelStem.END); + if (overworld) register(fake, levelStems, dimensions, LevelStem.OVERWORLD); + if (nether) register(fake, levelStems, dimensions, LevelStem.NETHER); + if (end) register(fake, levelStems, dimensions, LevelStem.END); + copy(fake, datapack.lookup(Registries.LEVEL_STEM).orElse(null)); + + if (copy) copy(fake, levelStems); return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); } @@ -695,4 +742,14 @@ public class NMSBinding implements INMSBinding { levelStems.getValueOrThrow(key).generator() ), RegistrationInfo.BUILT_IN); } + + private void copy(MappedRegistry target, Registry source) { + if (source == null) return; + source.listElementIds().forEach(key -> { + var value = source.getValue(key); + var info = source.registrationInfo(key).orElse(null); + if (value != null && info != null && !target.containsKey(key)) + target.register(key, value, info); + }); + } } From c4f0722614b34d674d502edcf373c6496ea2298c Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Tue, 18 Mar 2025 11:15:57 +0100 Subject: [PATCH 06/13] improve datapack setup speed --- .../volmit/iris/core/ServerConfigurator.java | 40 ++++-- .../iris/engine/object/IrisDimension.java | 116 +++++++++--------- 2 files changed, 83 insertions(+), 73 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java b/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java index 8d579d859..aace8e897 100644 --- a/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java +++ b/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java @@ -28,21 +28,23 @@ import com.volmit.iris.engine.object.IrisBiomeCustom; import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.engine.object.IrisRange; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.format.C; import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.scheduling.J; import lombok.Data; +import lombok.NonNull; import org.bukkit.Bukkit; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; import java.util.Arrays; -import java.util.List; import java.util.concurrent.TimeUnit; import java.util.stream.Stream; @@ -89,7 +91,7 @@ public class ServerConfigurator { } } - private static List getDatapacksFolder() { + private static KList getDatapacksFolder() { if (!IrisSettings.get().getGeneral().forceMainWorld.isEmpty()) { return new KList().qadd(new File(Bukkit.getWorldContainer(), IrisSettings.get().getGeneral().forceMainWorld + "/datapacks")); } @@ -105,15 +107,16 @@ public class ServerConfigurator { public static void installDataPacks(IDataFixer fixer, boolean fullInstall) { Iris.info("Checking Data Packs..."); DimensionHeight height = new DimensionHeight(fixer); + KList folders = getDatapacksFolder(); + KMap> biomes = new KMap<>(); allPacks().flatMap(height::merge) - .toList() + .parallel() .forEach(dim -> { - for (File dpack : getDatapacksFolder()) { - Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath()); - dim.installDataPack(fixer, dim::getLoader, dpack, height); - } + Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath()); + dim.installBiomes(fixer, dim::getLoader, folders, biomes.computeIfAbsent(dim.getLoadKey(), k -> new KSet<>())); }); + IrisDimension.writeShared(folders, height); Iris.info("Data Packs Setup!"); @@ -165,7 +168,7 @@ public class ServerConfigurator { 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)"); J.s(() -> { - Iris.warn("Looks like the restart command diddn't work. Stopping the server instead!"); + Iris.warn("Looks like the restart command didn't work. Stopping the server instead!"); Bukkit.shutdown(); }, 100); Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "restart"); @@ -173,22 +176,24 @@ public class ServerConfigurator { } public static boolean verifyDataPackInstalled(IrisDimension dimension) { - IrisData idm = IrisData.get(Iris.instance.getDataFolder("packs", dimension.getLoadKey())); KSet keys = new KSet<>(); boolean warn = false; - for (IrisBiome i : dimension.getAllBiomes(() -> idm)) { + for (IrisBiome i : dimension.getAllBiomes(dimension::getLoader)) { if (i.isCustom()) { for (IrisBiomeCustom j : i.getCustomDerivitives()) { keys.add(dimension.getLoadKey() + ":" + j.getId()); } } } + String key = getWorld(dimension.getLoader()); + if (key == null) key = dimension.getLoadKey(); + else key += "/" + dimension.getLoadKey(); if (!INMS.get().supportsDataPacks()) { if (!keys.isEmpty()) { Iris.warn("==================================================================================="); - Iris.warn("Pack " + dimension.getLoadKey() + " has " + keys.size() + " custom biome(s). "); + 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("===================================================================================="); @@ -207,7 +212,7 @@ public class ServerConfigurator { } if (warn) { - Iris.error("The Pack " + dimension.getLoadKey() + " is INCAPABLE of generating custom biomes"); + 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!"); } @@ -221,6 +226,17 @@ public class ServerConfigurator { .map(IrisData::get); } + @Nullable + public static String getWorld(@NonNull IrisData data) { + String worldContainer = Bukkit.getWorldContainer().getAbsolutePath(); + if (!worldContainer.endsWith(File.separator)) worldContainer += File.separator; + + String path = data.getDataFolder().getAbsolutePath(); + if (!path.startsWith(worldContainer)) return null; + int l = path.endsWith(File.separator) ? 11 : 10; + return path.substring(worldContainer.length(), path.length() - l); + } + private static Stream listFiles(File parent) { var files = parent.listFiles(); return files == null ? Stream.empty() : Arrays.stream(files); diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java index 08dc3b77f..f2c5b724c 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java @@ -28,6 +28,7 @@ import com.volmit.iris.core.nms.datapack.IDataFixer; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.data.DataProvider; import com.volmit.iris.util.io.IO; import com.volmit.iris.util.json.JSONObject; @@ -378,57 +379,35 @@ public class IrisDimension extends IrisRegistrant { return landBiomeStyle; } - public boolean installDataPack(IDataFixer fixer, DataProvider data, File datapacks, DimensionHeight height) { - boolean write = false; - boolean changed = false; - - IO.delete(new File(datapacks, "iris/data/" + getLoadKey().toLowerCase())); - - for (IrisBiome i : getAllBiomes(data)) { - if (i.isCustom()) { - write = true; - - for (IrisBiomeCustom j : i.getCustomDerivitives()) { - File output = new File(datapacks, "iris/data/" + getLoadKey().toLowerCase() + "/worldgen/biome/" + j.getId() + ".json"); - - if (!output.exists()) { - changed = true; - } - - Iris.verbose(" Installing Data Pack Biome: " + output.getPath()); - output.getParentFile().mkdirs(); - try { - IO.writeAll(output, j.generateJson(fixer)); - } catch (IOException e) { - Iris.reportError(e); - e.printStackTrace(); - } - } - } - } - - Iris.verbose(" Installing Data Pack Dimension Types: \"iris:overworld\", \"iris:the_nether\", \"iris:the_end\""); - changed = writeDimensionType(changed, datapacks, height); - - if (write) { - File mcm = new File(datapacks, "iris/pack.mcmeta"); - try { - IO.writeAll(mcm, """ - { - "pack": { - "description": "Iris Data Pack. This pack contains all installed Iris Packs' resources.", - "pack_format": {} - } + public void installBiomes(IDataFixer fixer, DataProvider data, KList folders, KSet biomes) { + getAllBiomes(data) + .stream() + .filter(IrisBiome::isCustom) + .map(IrisBiome::getCustomDerivitives) + .flatMap(KList::stream) + .parallel() + .forEach(j -> { + String json = j.generateJson(fixer); + synchronized (biomes) { + if (!biomes.add(j.getId())) { + Iris.verbose("Duplicate Data Pack Biome: " + getLoadKey() + "/" + j.getId()); + return; } - """.replace("{}", INMS.get().getDataVersion().getPackFormat() + "")); - } catch (IOException e) { - Iris.reportError(e); - e.printStackTrace(); - } - Iris.verbose(" Installing Data Pack MCMeta: " + mcm.getPath()); - } + } - return changed; + for (File datapacks : folders) { + File output = new File(datapacks, "iris/data/" + getLoadKey().toLowerCase() + "/worldgen/biome/" + j.getId() + ".json"); + + Iris.verbose(" Installing Data Pack Biome: " + output.getPath()); + output.getParentFile().mkdirs(); + try { + IO.writeAll(output, json); + } catch (IOException e) { + Iris.reportError(e); + e.printStackTrace(); + } + } + }); } @Override @@ -446,20 +425,39 @@ public class IrisDimension extends IrisRegistrant { } - public boolean writeDimensionType(boolean changed, File datapacks, DimensionHeight height) { - changed = write(changed, datapacks, "overworld", height.overworldType()); - changed = write(changed, datapacks, "the_nether", height.netherType()); - changed = write(changed, datapacks, "the_end", height.endType()); + public static void writeShared(KList folders, DimensionHeight height) { + Iris.verbose(" Installing Data Pack Dimension Types: \"iris:overworld\", \"iris:the_nether\", \"iris:the_end\""); + for (File datapacks : folders) { + write(datapacks, "overworld", height.overworldType()); + write(datapacks, "the_nether", height.netherType()); + write(datapacks, "the_end", height.endType()); + } - return changed; + String raw = """ + { + "pack": { + "description": "Iris Data Pack. This pack contains all installed Iris Packs' resources.", + "pack_format": {} + } + } + """.replace("{}", INMS.get().getDataVersion().getPackFormat() + ""); + + for (File datapacks : folders) { + File mcm = new File(datapacks, "iris/pack.mcmeta"); + try { + IO.writeAll(mcm, raw); + } catch (IOException e) { + Iris.reportError(e); + e.printStackTrace(); + } + Iris.verbose(" Installing Data Pack MCMeta: " + mcm.getPath()); + } } - private static boolean write(boolean changed, File datapacks, String type, String json) { + private static void write(File datapacks, String type, String json) { File dimType = new File(datapacks, "iris/data/iris/dimension_type/" + type + ".json"); File dimTypeVanilla = new File(datapacks, "iris/data/minecraft/dimension_type/" + type + ".json"); - if (!dimType.exists()) - changed = true; dimType.getParentFile().mkdirs(); try { IO.writeAll(dimType, json); @@ -469,8 +467,6 @@ public class IrisDimension extends IrisRegistrant { } if (IrisSettings.get().getGeneral().adjustVanillaHeight || dimTypeVanilla.exists()) { - if (!dimTypeVanilla.exists()) - changed = true; dimTypeVanilla.getParentFile().mkdirs(); try { IO.writeAll(dimTypeVanilla, json); @@ -479,7 +475,5 @@ public class IrisDimension extends IrisRegistrant { e.printStackTrace(); } } - - return changed; } } From dfe4894be7114033c8a3aa6cc8102e2dca0b05ac Mon Sep 17 00:00:00 2001 From: Aidan Aeternum Date: Tue, 18 Mar 2025 16:40:33 -0400 Subject: [PATCH 07/13] v+ --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4c54935f6..709ccc019 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ plugins { } -version '3.6.3-1.20.1-1.21.4' +version '3.6.4-1.20.1-1.21.4' // ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED // ======================== WINDOWS ============================= From 06a45056d9eb2e7d63788c54a620933932741ab0 Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Sat, 22 Mar 2025 12:31:30 +0100 Subject: [PATCH 08/13] use flat level source instead of trying to get the levelstems --- .../iris/core/nms/v1_20_R1/NMSBinding.java | 30 ++++++++++++++----- .../iris/core/nms/v1_20_R2/NMSBinding.java | 30 ++++++++++++++----- .../iris/core/nms/v1_20_R3/NMSBinding.java | 30 ++++++++++++++----- .../iris/core/nms/v1_20_R4/NMSBinding.java | 30 ++++++++++++++----- .../iris/core/nms/v1_21_R1/NMSBinding.java | 30 ++++++++++++++----- .../iris/core/nms/v1_21_R2/NMSBinding.java | 30 ++++++++++++++----- .../iris/core/nms/v1_21_R3/NMSBinding.java | 30 ++++++++++++++----- 7 files changed, 154 insertions(+), 56 deletions(-) diff --git a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java index 0a0e51a6e..04dee2073 100644 --- a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java +++ b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java @@ -38,7 +38,9 @@ import net.minecraft.tags.TagKey; import net.minecraft.world.entity.EntityDimensions; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.biome.BiomeSource; +import net.minecraft.world.level.biome.Biomes; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; @@ -47,6 +49,9 @@ import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.levelgen.FlatLevelSource; +import net.minecraft.world.level.levelgen.flat.FlatLayerInfo; +import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -703,23 +708,32 @@ public class NMSBinding implements INMSBinding { private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) { var access = registry(); var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE); - var levelStems = access.registryOrThrow(Registries.LEVEL_STEM); + var settings = new FlatLevelGeneratorSettings( + Optional.empty(), + access.lookupOrThrow(Registries.BIOME).getOrThrow(Biomes.THE_VOID), + List.of() + ); + settings.getLayersInfo().add(new FlatLayerInfo(1, Blocks.AIR)); + settings.updateLayers(); + + var source = new FlatLevelSource(settings); var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); - if (overworld) register(fake, levelStems, dimensions, LevelStem.OVERWORLD); - if (nether) register(fake, levelStems, dimensions, LevelStem.NETHER); - if (end) register(fake, levelStems, dimensions, LevelStem.END); + if (overworld) register(fake, dimensions, source, LevelStem.OVERWORLD); + if (nether) register(fake, dimensions, source, LevelStem.NETHER); + if (end) register(fake, dimensions, source, LevelStem.END); copy(fake, datapack.registry(Registries.LEVEL_STEM).orElse(null)); - if (copy) copy(fake, levelStems); + if (copy) copy(fake, access.registryOrThrow(Registries.LEVEL_STEM)); return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); } - private void register(MappedRegistry target, Registry levelStems, Registry dimensions, ResourceKey key) { + private void register(MappedRegistry target, Registry dimensions, FlatLevelSource source, ResourceKey key) { + var loc = new ResourceLocation("iris", key.location().getPath()); target.register(key, new LevelStem( - dimensions.getHolderOrThrow(ResourceKey.create(Registries.DIMENSION_TYPE, new ResourceLocation("iris", key.location().getPath()))), - levelStems.getOrThrow(key).generator() + dimensions.getHolder(ResourceKey.create(Registries.DIMENSION_TYPE, loc)).orElseThrow(() -> new IllegalStateException("Missing dimension type " + loc + " in " + dimensions.keySet())), + source ), Lifecycle.stable()); } diff --git a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java index 924e04791..89b22cfd5 100644 --- a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java +++ b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java @@ -28,9 +28,14 @@ import net.minecraft.server.WorldLoader; import net.minecraft.server.commands.data.BlockDataAccessor; import net.minecraft.tags.TagKey; import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.biome.Biomes; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.levelgen.FlatLevelSource; +import net.minecraft.world.level.levelgen.flat.FlatLayerInfo; +import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -704,23 +709,32 @@ public class NMSBinding implements INMSBinding { private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) { var access = registry(); var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE); - var levelStems = access.registryOrThrow(Registries.LEVEL_STEM); + var settings = new FlatLevelGeneratorSettings( + Optional.empty(), + access.lookupOrThrow(Registries.BIOME).getOrThrow(Biomes.THE_VOID), + List.of() + ); + settings.getLayersInfo().add(new FlatLayerInfo(1, Blocks.AIR)); + settings.updateLayers(); + + var source = new FlatLevelSource(settings); var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); - if (overworld) register(fake, levelStems, dimensions, LevelStem.OVERWORLD); - if (nether) register(fake, levelStems, dimensions, LevelStem.NETHER); - if (end) register(fake, levelStems, dimensions, LevelStem.END); + if (overworld) register(fake, dimensions, source, LevelStem.OVERWORLD); + if (nether) register(fake, dimensions, source, LevelStem.NETHER); + if (end) register(fake, dimensions, source, LevelStem.END); copy(fake, datapack.registry(Registries.LEVEL_STEM).orElse(null)); - if (copy) copy(fake, levelStems); + if (copy) copy(fake, access.registryOrThrow(Registries.LEVEL_STEM)); return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); } - private void register(MappedRegistry target, Registry levelStems, Registry dimensions, ResourceKey key) { + private void register(MappedRegistry target, Registry dimensions, FlatLevelSource source, ResourceKey key) { + var loc = new ResourceLocation("iris", key.location().getPath()); target.register(key, new LevelStem( - dimensions.getHolderOrThrow(ResourceKey.create(Registries.DIMENSION_TYPE, new ResourceLocation("iris", key.location().getPath()))), - levelStems.getOrThrow(key).generator() + dimensions.getHolder(ResourceKey.create(Registries.DIMENSION_TYPE, loc)).orElseThrow(() -> new IllegalStateException("Missing dimension type " + loc + " in " + dimensions.keySet())), + source ), Lifecycle.stable()); } diff --git a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java index 283e4a594..20319a3ed 100644 --- a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java +++ b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java @@ -28,9 +28,14 @@ import net.minecraft.server.WorldLoader; import net.minecraft.server.commands.data.BlockDataAccessor; import net.minecraft.tags.TagKey; import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.biome.Biomes; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.levelgen.FlatLevelSource; +import net.minecraft.world.level.levelgen.flat.FlatLayerInfo; +import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -705,23 +710,32 @@ public class NMSBinding implements INMSBinding { private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) { var access = registry(); var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE); - var levelStems = access.registryOrThrow(Registries.LEVEL_STEM); + var settings = new FlatLevelGeneratorSettings( + Optional.empty(), + access.lookupOrThrow(Registries.BIOME).getOrThrow(Biomes.THE_VOID), + List.of() + ); + settings.getLayersInfo().add(new FlatLayerInfo(1, Blocks.AIR)); + settings.updateLayers(); + + var source = new FlatLevelSource(settings); var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); - if (overworld) register(fake, levelStems, dimensions, LevelStem.OVERWORLD); - if (nether) register(fake, levelStems, dimensions, LevelStem.NETHER); - if (end) register(fake, levelStems, dimensions, LevelStem.END); + if (overworld) register(fake, dimensions, source, LevelStem.OVERWORLD); + if (nether) register(fake, dimensions, source, LevelStem.NETHER); + if (end) register(fake, dimensions, source, LevelStem.END); copy(fake, datapack.registry(Registries.LEVEL_STEM).orElse(null)); - if (copy) copy(fake, levelStems); + if (copy) copy(fake, access.registryOrThrow(Registries.LEVEL_STEM)); return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); } - private void register(MappedRegistry target, Registry levelStems, Registry dimensions, ResourceKey key) { + private void register(MappedRegistry target, Registry dimensions, FlatLevelSource source, ResourceKey key) { + var loc = new ResourceLocation("iris", key.location().getPath()); target.register(key, new LevelStem( - dimensions.getHolderOrThrow(ResourceKey.create(Registries.DIMENSION_TYPE, new ResourceLocation("iris", key.location().getPath()))), - levelStems.getOrThrow(key).generator() + dimensions.getHolder(ResourceKey.create(Registries.DIMENSION_TYPE, loc)).orElseThrow(() -> new IllegalStateException("Missing dimension type " + loc + " in " + dimensions.keySet())), + source ), Lifecycle.stable()); } diff --git a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java index 14e103eb5..29d66b026 100644 --- a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java +++ b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java @@ -38,11 +38,16 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.tags.TagKey; import net.minecraft.world.item.component.CustomData; import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.biome.Biomes; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.chunk.status.ChunkStatus; import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.levelgen.FlatLevelSource; +import net.minecraft.world.level.levelgen.flat.FlatLayerInfo; +import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -730,23 +735,32 @@ public class NMSBinding implements INMSBinding { private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) { var access = registry(); var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE); - var levelStems = access.registryOrThrow(Registries.LEVEL_STEM); + var settings = new FlatLevelGeneratorSettings( + Optional.empty(), + access.lookupOrThrow(Registries.BIOME).getOrThrow(Biomes.THE_VOID), + List.of() + ); + settings.getLayersInfo().add(new FlatLayerInfo(1, Blocks.AIR)); + settings.updateLayers(); + + var source = new FlatLevelSource(settings); var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); - if (overworld) register(fake, levelStems, dimensions, LevelStem.OVERWORLD); - if (nether) register(fake, levelStems, dimensions, LevelStem.NETHER); - if (end) register(fake, levelStems, dimensions, LevelStem.END); + if (overworld) register(fake, dimensions, source, LevelStem.OVERWORLD); + if (nether) register(fake, dimensions, source, LevelStem.NETHER); + if (end) register(fake, dimensions, source, LevelStem.END); copy(fake, datapack.registry(Registries.LEVEL_STEM).orElse(null)); - if (copy) copy(fake, levelStems); + if (copy) copy(fake, access.registryOrThrow(Registries.LEVEL_STEM)); return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); } - private void register(MappedRegistry target, Registry levelStems, Registry dimensions, ResourceKey key) { + private void register(MappedRegistry target, Registry dimensions, FlatLevelSource source, ResourceKey key) { + var loc = new ResourceLocation("iris", key.location().getPath()); target.register(key, new LevelStem( - dimensions.getHolder(new ResourceLocation("iris", key.location().getPath())).orElseThrow(), - levelStems.getOrThrow(key).generator() + dimensions.getHolder(ResourceKey.create(Registries.DIMENSION_TYPE, loc)).orElseThrow(() -> new IllegalStateException("Missing dimension type " + loc + " in " + dimensions.keySet())), + source ), RegistrationInfo.BUILT_IN); } diff --git a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java index da85e16de..edf76e919 100644 --- a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java +++ b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java @@ -32,11 +32,16 @@ import net.minecraft.server.level.ChunkMap; import net.minecraft.tags.TagKey; import net.minecraft.world.item.component.CustomData; import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.biome.Biomes; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.chunk.status.ChunkStatus; import net.minecraft.world.level.chunk.status.WorldGenContext; import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.levelgen.FlatLevelSource; +import net.minecraft.world.level.levelgen.flat.FlatLayerInfo; +import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -734,23 +739,32 @@ public class NMSBinding implements INMSBinding { private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) { var access = registry(); var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE); - var levelStems = access.registryOrThrow(Registries.LEVEL_STEM); + var settings = new FlatLevelGeneratorSettings( + Optional.empty(), + access.lookupOrThrow(Registries.BIOME).getOrThrow(Biomes.THE_VOID), + List.of() + ); + settings.getLayersInfo().add(new FlatLayerInfo(1, Blocks.AIR)); + settings.updateLayers(); + + var source = new FlatLevelSource(settings); var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); - if (overworld) register(fake, levelStems, dimensions, LevelStem.OVERWORLD); - if (nether) register(fake, levelStems, dimensions, LevelStem.NETHER); - if (end) register(fake, levelStems, dimensions, LevelStem.END); + if (overworld) register(fake, dimensions, source, LevelStem.OVERWORLD); + if (nether) register(fake, dimensions, source, LevelStem.NETHER); + if (end) register(fake, dimensions, source, LevelStem.END); copy(fake, datapack.registry(Registries.LEVEL_STEM).orElse(null)); - if (copy) copy(fake, levelStems); + if (copy) copy(fake, access.registryOrThrow(Registries.LEVEL_STEM)); return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); } - private void register(MappedRegistry target, Registry levelStems, Registry dimensions, ResourceKey key) { + private void register(MappedRegistry target, Registry dimensions, FlatLevelSource source, ResourceKey key) { + var loc = ResourceLocation.fromNamespaceAndPath("iris", key.location().getPath()); target.register(key, new LevelStem( - dimensions.getHolder(ResourceLocation.fromNamespaceAndPath("iris", key.location().getPath())).orElseThrow(), - levelStems.getOrThrow(key).generator() + dimensions.getHolder(ResourceKey.create(Registries.DIMENSION_TYPE, loc)).orElseThrow(() -> new IllegalStateException("Missing dimension type " + loc + " in " + dimensions.keySet())), + source ), RegistrationInfo.BUILT_IN); } diff --git a/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java b/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java index 5773392ae..fd2a60574 100644 --- a/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java +++ b/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java @@ -27,11 +27,16 @@ import net.minecraft.server.commands.data.BlockDataAccessor; import net.minecraft.tags.TagKey; import net.minecraft.world.item.component.CustomData; import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.biome.Biomes; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.chunk.status.ChunkStatus; import net.minecraft.world.level.chunk.status.WorldGenContext; import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.levelgen.FlatLevelSource; +import net.minecraft.world.level.levelgen.flat.FlatLayerInfo; +import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -724,23 +729,32 @@ public class NMSBinding implements INMSBinding { private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) { var access = registry(); var dimensions = access.lookupOrThrow(Registries.DIMENSION_TYPE); - var levelStems = access.lookupOrThrow(Registries.LEVEL_STEM); + var settings = new FlatLevelGeneratorSettings( + Optional.empty(), + access.lookupOrThrow(Registries.BIOME).getOrThrow(Biomes.THE_VOID), + List.of() + ); + settings.getLayersInfo().add(new FlatLayerInfo(1, Blocks.AIR)); + settings.updateLayers(); + + var source = new FlatLevelSource(settings); var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); - if (overworld) register(fake, levelStems, dimensions, LevelStem.OVERWORLD); - if (nether) register(fake, levelStems, dimensions, LevelStem.NETHER); - if (end) register(fake, levelStems, dimensions, LevelStem.END); + if (overworld) register(fake, dimensions, source, LevelStem.OVERWORLD); + if (nether) register(fake, dimensions, source, LevelStem.NETHER); + if (end) register(fake, dimensions, source, LevelStem.END); copy(fake, datapack.lookup(Registries.LEVEL_STEM).orElse(null)); - if (copy) copy(fake, levelStems); + if (copy) copy(fake, access.lookupOrThrow(Registries.LEVEL_STEM)); return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); } - private void register(MappedRegistry target, Registry levelStems, Registry dimensions, ResourceKey key) { + private void register(MappedRegistry target, Registry dimensions, FlatLevelSource source, ResourceKey key) { + var loc = ResourceLocation.fromNamespaceAndPath("iris", key.location().getPath()); target.register(key, new LevelStem( - dimensions.get(ResourceLocation.fromNamespaceAndPath("iris", key.location().getPath())).orElseThrow(), - levelStems.getValueOrThrow(key).generator() + dimensions.get(loc).orElseThrow(() -> new IllegalStateException("Missing dimension type " + loc + " in " + dimensions.keySet())), + source ), RegistrationInfo.BUILT_IN); } diff --git a/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java b/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java index e31895550..011256342 100644 --- a/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java +++ b/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java @@ -39,7 +39,9 @@ import net.minecraft.tags.TagKey; import net.minecraft.world.entity.EntityType; import net.minecraft.world.item.component.CustomData; import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.biome.Biomes; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; @@ -49,6 +51,9 @@ import net.minecraft.world.level.chunk.status.ChunkStatus; import net.minecraft.world.level.chunk.status.WorldGenContext; import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.levelgen.FlatLevelSource; +import net.minecraft.world.level.levelgen.flat.FlatLayerInfo; +import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -723,23 +728,32 @@ public class NMSBinding implements INMSBinding { private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) { var access = registry(); var dimensions = access.lookupOrThrow(Registries.DIMENSION_TYPE); - var levelStems = access.lookupOrThrow(Registries.LEVEL_STEM); + var settings = new FlatLevelGeneratorSettings( + Optional.empty(), + access.lookupOrThrow(Registries.BIOME).getOrThrow(Biomes.THE_VOID), + List.of() + ); + settings.getLayersInfo().add(new FlatLayerInfo(1, Blocks.AIR)); + settings.updateLayers(); + + var source = new FlatLevelSource(settings); var fake = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.experimental()); - if (overworld) register(fake, levelStems, dimensions, LevelStem.OVERWORLD); - if (nether) register(fake, levelStems, dimensions, LevelStem.NETHER); - if (end) register(fake, levelStems, dimensions, LevelStem.END); + if (overworld) register(fake, dimensions, source, LevelStem.OVERWORLD); + if (nether) register(fake, dimensions, source, LevelStem.NETHER); + if (end) register(fake, dimensions, source, LevelStem.END); copy(fake, datapack.lookup(Registries.LEVEL_STEM).orElse(null)); - if (copy) copy(fake, levelStems); + if (copy) copy(fake, access.lookupOrThrow(Registries.LEVEL_STEM)); return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze(); } - private void register(MappedRegistry target, Registry levelStems, Registry dimensions, ResourceKey key) { + private void register(MappedRegistry target, Registry dimensions, FlatLevelSource source, ResourceKey key) { + var loc = ResourceLocation.fromNamespaceAndPath("iris", key.location().getPath()); target.register(key, new LevelStem( - dimensions.get(ResourceLocation.fromNamespaceAndPath("iris", key.location().getPath())).orElseThrow(), - levelStems.getValueOrThrow(key).generator() + dimensions.get(loc).orElseThrow(() -> new IllegalStateException("Missing dimension type " + loc + " in " + dimensions.keySet())), + source ), RegistrationInfo.BUILT_IN); } From 24355064ffd58494b7dad14cd8df3359867cb942 Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Sun, 23 Mar 2025 13:09:57 +0100 Subject: [PATCH 09/13] add safeguard for missing dimension types to prevent world corruption --- core/src/main/java/com/volmit/iris/Iris.java | 6 ++++-- .../volmit/iris/core/ServerConfigurator.java | 2 ++ .../com/volmit/iris/core/nms/INMSBinding.java | 16 +++++++--------- .../volmit/iris/core/nms/v1X/NMSBinding1X.java | 17 +++++++++++++++++ .../iris/core/safeguard/IrisSafeguard.java | 9 +++++++++ .../iris/core/safeguard/ServerBootSFG.java | 8 ++++++++ .../volmit/iris/core/safeguard/UtilsSFG.java | 5 +++++ .../iris/engine/object/IrisContextInjector.java | 10 ++++++++++ .../volmit/iris/util/misc/ServerProperties.java | 7 ++++++- .../iris/core/nms/v1_20_R1/NMSBinding.java | 15 ++++++++++++++- .../iris/core/nms/v1_20_R2/NMSBinding.java | 15 ++++++++++++++- .../iris/core/nms/v1_20_R3/NMSBinding.java | 15 ++++++++++++++- .../iris/core/nms/v1_20_R4/NMSBinding.java | 15 ++++++++++++++- .../iris/core/nms/v1_21_R1/NMSBinding.java | 15 ++++++++++++++- .../iris/core/nms/v1_21_R2/NMSBinding.java | 15 ++++++++++++++- .../iris/core/nms/v1_21_R3/NMSBinding.java | 15 ++++++++++++++- 16 files changed, 166 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/Iris.java b/core/src/main/java/com/volmit/iris/Iris.java index db0d69377..07e01c6e4 100644 --- a/core/src/main/java/com/volmit/iris/Iris.java +++ b/core/src/main/java/com/volmit/iris/Iris.java @@ -459,15 +459,17 @@ public class Iris extends VolmitPlugin implements Listener { initialize("com.volmit.iris.core.service").forEach((i) -> services.put((Class) i.getClass(), (IrisService) i)); INMS.get(); IO.delete(new File("iris")); + compat = IrisCompat.configured(getDataFile("compat.json")); + ServerConfigurator.configure(); + new IrisContextInjector(); IrisSafeguard.IrisSafeguardSystem(); getSender().setTag(getTag()); - compat = IrisCompat.configured(getDataFile("compat.json")); + IrisSafeguard.earlySplash(); linkMultiverseCore = new MultiverseCoreLink(); linkMythicMobs = new MythicMobsLink(); configWatcher = new FileWatcher(getDataFile("settings.json")); services.values().forEach(IrisService::onEnable); services.values().forEach(this::registerListener); - registerListener(new IrisContextInjector()); J.s(() -> { J.a(() -> PaperLib.suggestPaper(this)); J.a(() -> IO.delete(getTemp())); diff --git a/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java b/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java index aace8e897..ffeae3115 100644 --- a/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java +++ b/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java @@ -31,6 +31,7 @@ import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.format.C; +import com.volmit.iris.util.misc.ServerProperties; import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.scheduling.J; import lombok.Data; @@ -97,6 +98,7 @@ public class ServerConfigurator { } KList worlds = new KList<>(); Bukkit.getServer().getWorlds().forEach(w -> worlds.add(new File(w.getWorldFolder(), "datapacks"))); + if (worlds.isEmpty()) worlds.add(new File(Bukkit.getWorldContainer(), ServerProperties.LEVEL_NAME + "/datapacks")); return worlds; } diff --git a/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java b/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java index ac3894f65..25e5f688b 100644 --- a/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java +++ b/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java @@ -32,15 +32,12 @@ import com.volmit.iris.util.nbt.mca.palette.MCAPaletteAccess; import com.volmit.iris.util.nbt.tag.CompoundTag; import org.bukkit.*; import org.bukkit.block.Biome; -import org.bukkit.entity.Dolphin; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.generator.ChunkGenerator; -import org.bukkit.generator.structure.Structure; import org.bukkit.inventory.ItemStack; -import java.awt.*; import java.awt.Color; public interface INMSBinding { @@ -93,6 +90,9 @@ public interface INMSBinding { MCABiomeContainer newBiomeContainer(int min, int max); default World createWorld(WorldCreator c) { + if (missingDimensionTypes(true, true, true)) + throw new IllegalStateException("Missing dimenstion types to create world"); + try (var ignored = injectLevelStems()) { return c.createWorld(); } @@ -130,11 +130,9 @@ public interface INMSBinding { KList getStructureKeys(); - default AutoClosing injectLevelStems() { - return new AutoClosing(() -> {}); - } + AutoClosing injectLevelStems(); - default Pair injectUncached(boolean overworld, boolean nether, boolean end) { - return new Pair<>(0, injectLevelStems()); - } + Pair injectUncached(boolean overworld, boolean nether, boolean end); + + boolean missingDimensionTypes(boolean overworld, boolean nether, boolean end); } diff --git a/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java b/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java index fa722e688..33f83ddd4 100644 --- a/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java +++ b/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java @@ -20,7 +20,9 @@ package com.volmit.iris.core.nms.v1X; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMSBinding; +import com.volmit.iris.core.nms.container.AutoClosing; import com.volmit.iris.core.nms.container.BiomeColor; +import com.volmit.iris.core.nms.container.Pair; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; @@ -118,6 +120,21 @@ public class NMSBinding1X implements INMSBinding { return new KList<>(list); } + @Override + public AutoClosing injectLevelStems() { + return new AutoClosing(() -> {}); + } + + @Override + public Pair injectUncached(boolean overworld, boolean nether, boolean end) { + return new Pair<>(0, new AutoClosing(() -> {})); + } + + @Override + public boolean missingDimensionTypes(boolean overworld, boolean nether, boolean end) { + return false; + } + @Override public CompoundTag serializeEntity(Entity location) { return null; diff --git a/core/src/main/java/com/volmit/iris/core/safeguard/IrisSafeguard.java b/core/src/main/java/com/volmit/iris/core/safeguard/IrisSafeguard.java index 4fb25371a..5217be9f2 100644 --- a/core/src/main/java/com/volmit/iris/core/safeguard/IrisSafeguard.java +++ b/core/src/main/java/com/volmit/iris/core/safeguard/IrisSafeguard.java @@ -1,6 +1,7 @@ package com.volmit.iris.core.safeguard; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; public class IrisSafeguard { public static boolean unstablemode = false; @@ -11,5 +12,13 @@ public class IrisSafeguard { Iris.info("Enabled Iris SafeGuard"); ServerBootSFG.BootCheck(); } + + public static void earlySplash() { + if (ServerBootSFG.safeguardPassed || IrisSettings.get().getGeneral().DoomsdayAnnihilationSelfDestructMode) + return; + + Iris.instance.splash(); + UtilsSFG.splash(); + } } diff --git a/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java b/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java index a1de18768..2c59c2ae9 100644 --- a/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java +++ b/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java @@ -3,6 +3,7 @@ package com.volmit.iris.core.safeguard; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMS; import com.volmit.iris.core.nms.v1X.NMSBinding1X; +import com.volmit.iris.engine.object.IrisContextInjector; import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; @@ -29,6 +30,7 @@ public class ServerBootSFG { public static boolean isJRE = false; public static boolean hasPrivileges = true; public static boolean unsuportedversion = false; + public static boolean missingDimensionTypes = false; protected static boolean safeguardPassed; public static boolean passedserversoftware = true; protected static int count; @@ -110,6 +112,12 @@ public class ServerBootSFG { severityMedium++; } + if (IrisContextInjector.isMissingDimensionTypes()) { + missingDimensionTypes = true; + joiner.add("Missing Dimension Types"); + severityHigh++; + } + allIncompatibilities = joiner.toString(); safeguardPassed = (severityHigh == 0 && severityMedium == 0 && severityLow == 0); diff --git a/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java b/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java index cfff91b62..c45cfc7bb 100644 --- a/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java +++ b/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java @@ -39,6 +39,11 @@ public class UtilsSFG { Iris.safeguard(C.RED + "Server Version"); Iris.safeguard(C.RED + "- Iris only supports 1.20.1 > 1.21.4"); } + if (ServerBootSFG.missingDimensionTypes) { + Iris.safeguard(C.RED + "Dimension Types"); + Iris.safeguard(C.RED + "- Required Iris dimension types were not loaded."); + Iris.safeguard(C.RED + "- If this still happens after a restart please contact support."); + } if (!ServerBootSFG.passedserversoftware) { Iris.safeguard(C.YELLOW + "Unsupported Server Software"); Iris.safeguard(C.YELLOW + "- Please consider using Paper or Purpur instead."); diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisContextInjector.java b/core/src/main/java/com/volmit/iris/engine/object/IrisContextInjector.java index 772a4c560..3ecafab8a 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisContextInjector.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisContextInjector.java @@ -3,6 +3,7 @@ package com.volmit.iris.engine.object; import com.volmit.iris.core.nms.INMS; import com.volmit.iris.core.nms.container.AutoClosing; import com.volmit.iris.util.misc.ServerProperties; +import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; @@ -15,6 +16,8 @@ import java.util.List; import static com.volmit.iris.Iris.instance; public class IrisContextInjector implements Listener { + @Getter + private static boolean missingDimensionTypes = false; private AutoClosing autoClosing = null; private final int totalWorlds; private int worldCounter = 0; @@ -35,6 +38,12 @@ public class IrisContextInjector implements Listener { if (Bukkit.getAllowNether()) i++; if (Bukkit.getAllowEnd()) i++; + if (INMS.get().missingDimensionTypes(overworld, nether, end)) { + missingDimensionTypes = true; + totalWorlds = 0; + return; + } + if (overworld || nether || end) { var pair = INMS.get().injectUncached(overworld, nether, end); i += pair.getA() - 3; @@ -42,6 +51,7 @@ public class IrisContextInjector implements Listener { } totalWorlds = i; + instance.registerListener(this); } @EventHandler diff --git a/core/src/main/java/com/volmit/iris/util/misc/ServerProperties.java b/core/src/main/java/com/volmit/iris/util/misc/ServerProperties.java index b79e844f1..ecfc4f518 100644 --- a/core/src/main/java/com/volmit/iris/util/misc/ServerProperties.java +++ b/core/src/main/java/com/volmit/iris/util/misc/ServerProperties.java @@ -10,7 +10,7 @@ public class ServerProperties { public static final File SERVER_PROPERTIES; public static final File BUKKIT_YML; - public static final String LEVEL_NAME = DATA.getProperty("level-name", "world"); + public static final String LEVEL_NAME; static { String[] args = ProcessHandle.current() @@ -20,11 +20,13 @@ public class ServerProperties { String propertiesPath = "server.properties"; String bukkitYml = "bukkit.yml"; + String levelName = null; for (int i = 0; i < args.length - 1; i++) { switch (args[i]) { case "-c", "--config" -> propertiesPath = args[i + 1]; case "-b", "--bukkit-settings" -> bukkitYml = args[i + 1]; + case "-w", "--level-name", "--world" -> levelName = args[i + 1]; } } @@ -35,5 +37,8 @@ public class ServerProperties { } catch (IOException e) { throw new RuntimeException(e); } + + if (levelName != null) LEVEL_NAME = levelName; + else LEVEL_NAME = DATA.getProperty("level-name", "world"); } } diff --git a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java index 04dee2073..66723b82a 100644 --- a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java +++ b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java @@ -678,6 +678,15 @@ public class NMSBinding implements INMSBinding { })); } + @Override + public boolean missingDimensionTypes(boolean overworld, boolean nether, boolean end) { + var registry = registry().registryOrThrow(Registries.DIMENSION_TYPE); + if (overworld) overworld = !registry.containsKey(createIrisKey(LevelStem.OVERWORLD)); + if (nether) nether = !registry.containsKey(createIrisKey(LevelStem.NETHER)); + if (end) end = !registry.containsKey(createIrisKey(LevelStem.END)); + return overworld || nether || end; + } + private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) { return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( old.resources(), @@ -730,7 +739,7 @@ public class NMSBinding implements INMSBinding { } private void register(MappedRegistry target, Registry dimensions, FlatLevelSource source, ResourceKey key) { - var loc = new ResourceLocation("iris", key.location().getPath()); + var loc = createIrisKey(key); target.register(key, new LevelStem( dimensions.getHolder(ResourceKey.create(Registries.DIMENSION_TYPE, loc)).orElseThrow(() -> new IllegalStateException("Missing dimension type " + loc + " in " + dimensions.keySet())), source @@ -746,4 +755,8 @@ public class NMSBinding implements INMSBinding { target.register(key, value, info); }); } + + private ResourceLocation createIrisKey(ResourceKey key) { + return new ResourceLocation("iris", key.location().getPath()); + } } diff --git a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java index 89b22cfd5..6ef8bd4a8 100644 --- a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java +++ b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java @@ -679,6 +679,15 @@ public class NMSBinding implements INMSBinding { })); } + @Override + public boolean missingDimensionTypes(boolean overworld, boolean nether, boolean end) { + var registry = registry().registryOrThrow(Registries.DIMENSION_TYPE); + if (overworld) overworld = !registry.containsKey(createIrisKey(LevelStem.OVERWORLD)); + if (nether) nether = !registry.containsKey(createIrisKey(LevelStem.NETHER)); + if (end) end = !registry.containsKey(createIrisKey(LevelStem.END)); + return overworld || nether || end; + } + private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) { return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( old.resources(), @@ -731,7 +740,7 @@ public class NMSBinding implements INMSBinding { } private void register(MappedRegistry target, Registry dimensions, FlatLevelSource source, ResourceKey key) { - var loc = new ResourceLocation("iris", key.location().getPath()); + var loc = createIrisKey(key); target.register(key, new LevelStem( dimensions.getHolder(ResourceKey.create(Registries.DIMENSION_TYPE, loc)).orElseThrow(() -> new IllegalStateException("Missing dimension type " + loc + " in " + dimensions.keySet())), source @@ -747,4 +756,8 @@ public class NMSBinding implements INMSBinding { target.register(key, value, info); }); } + + private ResourceLocation createIrisKey(ResourceKey key) { + return new ResourceLocation("iris", key.location().getPath()); + } } diff --git a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java index 20319a3ed..84eec1ff5 100644 --- a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java +++ b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java @@ -680,6 +680,15 @@ public class NMSBinding implements INMSBinding { })); } + @Override + public boolean missingDimensionTypes(boolean overworld, boolean nether, boolean end) { + var registry = registry().registryOrThrow(Registries.DIMENSION_TYPE); + if (overworld) overworld = !registry.containsKey(createIrisKey(LevelStem.OVERWORLD)); + if (nether) nether = !registry.containsKey(createIrisKey(LevelStem.NETHER)); + if (end) end = !registry.containsKey(createIrisKey(LevelStem.END)); + return overworld || nether || end; + } + private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) { return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( old.resources(), @@ -732,7 +741,7 @@ public class NMSBinding implements INMSBinding { } private void register(MappedRegistry target, Registry dimensions, FlatLevelSource source, ResourceKey key) { - var loc = new ResourceLocation("iris", key.location().getPath()); + var loc = createIrisKey(key); target.register(key, new LevelStem( dimensions.getHolder(ResourceKey.create(Registries.DIMENSION_TYPE, loc)).orElseThrow(() -> new IllegalStateException("Missing dimension type " + loc + " in " + dimensions.keySet())), source @@ -748,4 +757,8 @@ public class NMSBinding implements INMSBinding { target.register(key, value, info); }); } + + private ResourceLocation createIrisKey(ResourceKey key) { + return new ResourceLocation("iris", key.location().getPath()); + } } diff --git a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java index 29d66b026..0dffeb195 100644 --- a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java +++ b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java @@ -705,6 +705,15 @@ public class NMSBinding implements INMSBinding { })); } + @Override + public boolean missingDimensionTypes(boolean overworld, boolean nether, boolean end) { + var registry = registry().registryOrThrow(Registries.DIMENSION_TYPE); + if (overworld) overworld = !registry.containsKey(createIrisKey(LevelStem.OVERWORLD)); + if (nether) nether = !registry.containsKey(createIrisKey(LevelStem.NETHER)); + if (end) end = !registry.containsKey(createIrisKey(LevelStem.END)); + return overworld || nether || end; + } + private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) { return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( old.resources(), @@ -757,7 +766,7 @@ public class NMSBinding implements INMSBinding { } private void register(MappedRegistry target, Registry dimensions, FlatLevelSource source, ResourceKey key) { - var loc = new ResourceLocation("iris", key.location().getPath()); + var loc = createIrisKey(key); target.register(key, new LevelStem( dimensions.getHolder(ResourceKey.create(Registries.DIMENSION_TYPE, loc)).orElseThrow(() -> new IllegalStateException("Missing dimension type " + loc + " in " + dimensions.keySet())), source @@ -773,4 +782,8 @@ public class NMSBinding implements INMSBinding { target.register(key, value, info); }); } + + private ResourceLocation createIrisKey(ResourceKey key) { + return new ResourceLocation("iris", key.location().getPath()); + } } diff --git a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java index edf76e919..71b59e65a 100644 --- a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java +++ b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java @@ -709,6 +709,15 @@ public class NMSBinding implements INMSBinding { })); } + @Override + public boolean missingDimensionTypes(boolean overworld, boolean nether, boolean end) { + var registry = registry().registryOrThrow(Registries.DIMENSION_TYPE); + if (overworld) overworld = !registry.containsKey(createIrisKey(LevelStem.OVERWORLD)); + if (nether) nether = !registry.containsKey(createIrisKey(LevelStem.NETHER)); + if (end) end = !registry.containsKey(createIrisKey(LevelStem.END)); + return overworld || nether || end; + } + private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) { return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( old.resources(), @@ -761,7 +770,7 @@ public class NMSBinding implements INMSBinding { } private void register(MappedRegistry target, Registry dimensions, FlatLevelSource source, ResourceKey key) { - var loc = ResourceLocation.fromNamespaceAndPath("iris", key.location().getPath()); + var loc = createIrisKey(key); target.register(key, new LevelStem( dimensions.getHolder(ResourceKey.create(Registries.DIMENSION_TYPE, loc)).orElseThrow(() -> new IllegalStateException("Missing dimension type " + loc + " in " + dimensions.keySet())), source @@ -777,4 +786,8 @@ public class NMSBinding implements INMSBinding { target.register(key, value, info); }); } + + private ResourceLocation createIrisKey(ResourceKey key) { + return ResourceLocation.fromNamespaceAndPath("iris", key.location().getPath()); + } } diff --git a/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java b/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java index fd2a60574..27a379228 100644 --- a/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java +++ b/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java @@ -699,6 +699,15 @@ public class NMSBinding implements INMSBinding { })); } + @Override + public boolean missingDimensionTypes(boolean overworld, boolean nether, boolean end) { + var registry = registry().lookupOrThrow(Registries.DIMENSION_TYPE); + if (overworld) overworld = !registry.containsKey(createIrisKey(LevelStem.OVERWORLD)); + if (nether) nether = !registry.containsKey(createIrisKey(LevelStem.NETHER)); + if (end) end = !registry.containsKey(createIrisKey(LevelStem.END)); + return overworld || nether || end; + } + private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) { return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( old.resources(), @@ -751,7 +760,7 @@ public class NMSBinding implements INMSBinding { } private void register(MappedRegistry target, Registry dimensions, FlatLevelSource source, ResourceKey key) { - var loc = ResourceLocation.fromNamespaceAndPath("iris", key.location().getPath()); + var loc = createIrisKey(key); target.register(key, new LevelStem( dimensions.get(loc).orElseThrow(() -> new IllegalStateException("Missing dimension type " + loc + " in " + dimensions.keySet())), source @@ -767,4 +776,8 @@ public class NMSBinding implements INMSBinding { target.register(key, value, info); }); } + + private ResourceLocation createIrisKey(ResourceKey key) { + return ResourceLocation.fromNamespaceAndPath("iris", key.location().getPath()); + } } diff --git a/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java b/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java index 011256342..efb282d86 100644 --- a/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java +++ b/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java @@ -698,6 +698,15 @@ public class NMSBinding implements INMSBinding { })); } + @Override + public boolean missingDimensionTypes(boolean overworld, boolean nether, boolean end) { + var registry = registry().lookupOrThrow(Registries.DIMENSION_TYPE); + if (overworld) overworld = !registry.containsKey(createIrisKey(LevelStem.OVERWORLD)); + if (nether) nether = !registry.containsKey(createIrisKey(LevelStem.NETHER)); + if (end) end = !registry.containsKey(createIrisKey(LevelStem.END)); + return overworld || nether || end; + } + private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) { return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext( old.resources(), @@ -750,7 +759,7 @@ public class NMSBinding implements INMSBinding { } private void register(MappedRegistry target, Registry dimensions, FlatLevelSource source, ResourceKey key) { - var loc = ResourceLocation.fromNamespaceAndPath("iris", key.location().getPath()); + var loc = createIrisKey(key); target.register(key, new LevelStem( dimensions.get(loc).orElseThrow(() -> new IllegalStateException("Missing dimension type " + loc + " in " + dimensions.keySet())), source @@ -766,4 +775,8 @@ public class NMSBinding implements INMSBinding { target.register(key, value, info); }); } + + private ResourceLocation createIrisKey(ResourceKey key) { + return ResourceLocation.fromNamespaceAndPath("iris", key.location().getPath()); + } } From 1b1b9d97b72c76a5af37ba9fdbc1a80bd7591c19 Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Tue, 25 Mar 2025 19:15:47 +0100 Subject: [PATCH 10/13] update overworld pack to 31020 --- core/src/main/java/com/volmit/iris/core/nms/INMS.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/core/nms/INMS.java b/core/src/main/java/com/volmit/iris/core/nms/INMS.java index d9a960341..3daefa900 100644 --- a/core/src/main/java/com/volmit/iris/core/nms/INMS.java +++ b/core/src/main/java/com/volmit/iris/core/nms/INMS.java @@ -37,7 +37,7 @@ public class INMS { "1.21.4", "v1_21_R3" ); private static final List PACKS = List.of( - new Version(21, 4, "31010"), + new Version(21, 4, "31020"), new Version(21, 2, "31000"), new Version(20, 1, "3910") ); From bdb7cc61e552bc9efbde9d2e5f20224990274474 Mon Sep 17 00:00:00 2001 From: Aidan Aeternum Date: Wed, 26 Mar 2025 15:41:35 -0400 Subject: [PATCH 11/13] v+ --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 709ccc019..da1f2c218 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ plugins { } -version '3.6.4-1.20.1-1.21.4' +version '3.6.5-1.20.1-1.21.4' // ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED // ======================== WINDOWS ============================= From c468eb1ab1521ea06743245a4a924b6e3c6dd763 Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Thu, 6 Mar 2025 15:50:52 +0100 Subject: [PATCH 12/13] make pregen use block radius as input --- .../iris/core/commands/CommandDeveloper.java | 2 +- .../iris/core/commands/CommandPregen.java | 12 +-- .../volmit/iris/core/gui/PregeneratorJob.java | 17 ++- .../iris/core/pregenerator/ChunkUpdater.java | 9 +- .../core/pregenerator/IrisPregenerator.java | 5 +- .../iris/core/pregenerator/PregenTask.java | 100 +++++++++++++----- .../iris/core/tools/IrisPackBenchmarking.java | 4 +- 7 files changed, 97 insertions(+), 52 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java index f2991e75a..9b4203490 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java @@ -140,7 +140,7 @@ public class CommandDeveloper implements DecreeExecutor { public void packBenchmark( @Param(description = "The pack to bench", aliases = {"pack"}, defaultValue = "overworld") IrisDimension dimension, - @Param(description = "Radius in regions", defaultValue = "5") + @Param(description = "Radius in regions", defaultValue = "2048") int radius, @Param(description = "Open GUI while benchmarking", defaultValue = "false") boolean gui diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandPregen.java b/core/src/main/java/com/volmit/iris/core/commands/CommandPregen.java index e3ed1c844..6d7bc42a6 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandPregen.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandPregen.java @@ -19,9 +19,7 @@ package com.volmit.iris.core.commands; import com.volmit.iris.Iris; -import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.gui.PregeneratorJob; -import com.volmit.iris.core.pregenerator.LazyPregenerator; import com.volmit.iris.core.pregenerator.PregenTask; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.util.decree.DecreeExecutor; @@ -29,12 +27,9 @@ import com.volmit.iris.util.decree.annotations.Decree; import com.volmit.iris.util.decree.annotations.Param; import com.volmit.iris.util.format.C; import com.volmit.iris.util.math.Position2; -import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.util.Vector; -import java.io.File; - @Decree(name = "pregen", aliases = "pregenerate", description = "Pregenerate your Iris worlds!") public class CommandPregen implements DecreeExecutor { @Decree(description = "Pregenerate a world") @@ -52,13 +47,12 @@ public class CommandPregen implements DecreeExecutor { sender().sendMessage(C.RED + "Please make sure the world is loaded & the engine is initialized. Generate a new chunk, for example."); } radius = Math.max(radius, 1024); - int w = (radius >> 9 + 1) * 2; IrisToolbelt.pregenerate(PregenTask .builder() - .center(new Position2(center.getBlockX() >> 9, center.getBlockZ() >> 9)) + .center(new Position2(center.getBlockX(), center.getBlockZ())) .gui(true) - .width(w) - .height(w) + .radiusX(radius) + .radiusZ(radius) .build(), world); String msg = C.GREEN + "Pregen started in " + C.GOLD + world.getName() + C.GREEN + " of " + C.GOLD + (radius * 2) + C.GREEN + " by " + C.GOLD + (radius * 2) + C.GREEN + " blocks from " + C.GOLD + center.getX() + "," + center.getZ(); sender().sendMessage(msg); diff --git a/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java b/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java index 35569f6f6..63b8919db 100644 --- a/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java +++ b/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java @@ -24,7 +24,6 @@ import com.volmit.iris.core.pregenerator.IrisPregenerator; import com.volmit.iris.core.pregenerator.PregenListener; import com.volmit.iris.core.pregenerator.PregenTask; import com.volmit.iris.core.pregenerator.PregeneratorMethod; -import com.volmit.iris.core.tools.IrisPackBenchmarking; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.format.Form; @@ -45,8 +44,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Consumer; -import static com.volmit.iris.core.tools.IrisPackBenchmarking.benchmarkInProgress; - public class PregeneratorJob implements PregenListener { private static final Color COLOR_EXISTS = parseColor("#4d7d5b"); private static final Color COLOR_BLACK = parseColor("#4d7d5b"); @@ -81,12 +78,12 @@ public class PregeneratorJob implements PregenListener { this.task = task; this.pregenerator = new IrisPregenerator(task, method, this); max = new Position2(0, 0); - min = new Position2(0, 0); - task.iterateRegions((xx, zz) -> { - min.setX(Math.min(xx << 5, min.getX())); - min.setZ(Math.min(zz << 5, min.getZ())); - max.setX(Math.max((xx << 5) + 31, max.getX())); - max.setZ(Math.max((zz << 5) + 31, max.getZ())); + min = new Position2(Integer.MAX_VALUE, Integer.MAX_VALUE); + task.iterateAllChunks((xx, zz) -> { + min.setX(Math.min(xx, min.getX())); + min.setZ(Math.min(zz, min.getZ())); + max.setX(Math.max(xx, max.getX())); + max.setZ(Math.max(zz, max.getZ())); }); if (IrisSettings.get().getGui().isUseServerLaunchedGuis() && task.isGui()) { @@ -162,7 +159,7 @@ public class PregeneratorJob implements PregenListener { } public void drawRegion(int x, int z, Color color) { - J.a(() -> PregenTask.iterateRegion(x, z, (xx, zz) -> { + J.a(() -> task.iterateChunks(x, z, (xx, zz) -> { draw(xx, zz, color); J.sleep(3); })); diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java index e8c00d3df..cb8407272 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java @@ -165,8 +165,11 @@ public class ChunkUpdater { if (rX < dimensions.min.getX() || rX > dimensions.max.getX() || rZ < dimensions.min.getZ() || rZ > dimensions.max.getZ()) { return; } + if (!new File(world.getWorldFolder(), "region" + File.separator + rX + "." + rZ + ".mca").exists()) { + return; + } - PregenTask.iterateRegion(rX, rZ, (x, z) -> { + task.iterateChunks(rX, rZ, (x, z) -> { while (paused.get() && !cancelled.get()) { J.sleep(50); } @@ -348,8 +351,8 @@ public class ChunkUpdater { int width = maxZ - minZ + 1; return new Dimensions(new Position2(minX, minZ), new Position2(maxX, maxZ), height * width, PregenTask.builder() - .width((int) Math.ceil(width / 2d)) - .height((int) Math.ceil(height / 2d)) + .radiusZ((int) Math.ceil(width / 2d * 512)) + .radiusX((int) Math.ceil(height / 2d * 512)) .center(new Position2(oX, oZ)) .build()); } diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java index 56ee44b05..57aa8b0eb 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java @@ -19,7 +19,6 @@ package com.volmit.iris.core.pregenerator; import com.volmit.iris.Iris; -import com.volmit.iris.core.pack.IrisPack; import com.volmit.iris.core.tools.IrisPackBenchmarking; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KSet; @@ -83,7 +82,7 @@ public class IrisPregenerator { generatedLast = new AtomicInteger(0); generatedLastMinute = new AtomicInteger(0); totalChunks = new AtomicInteger(0); - task.iterateRegions((_a, _b) -> totalChunks.addAndGet(1024)); + task.iterateAllChunks((_a, _b) -> totalChunks.incrementAndGet()); startTime = new AtomicLong(M.ms()); ticker = new Looper() { @Override @@ -194,7 +193,7 @@ public class IrisPregenerator { } else if (!regions) { hit = true; listener.onRegionGenerating(x, z); - PregenTask.iterateRegion(x, z, (xx, zz) -> { + task.iterateChunks(x, z, (xx, zz) -> { while (paused.get() && !shutdown.get()) { J.sleep(50); } diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java b/core/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java index 015a418a1..db8d76e7a 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java @@ -32,17 +32,26 @@ import java.util.Comparator; @Data public class PregenTask { private static final Position2 ZERO = new Position2(0, 0); - private static final KList ORDER_CENTER = computeChunkOrder(); private static final KMap> ORDERS = new KMap<>(); @Builder.Default - private boolean gui = false; + private final boolean gui = false; @Builder.Default - private Position2 center = new Position2(0, 0); + private final Position2 center = new Position2(0, 0); @Builder.Default - private int width = 1; + private final int radiusX = 1; @Builder.Default - private int height = 1; + private final int radiusZ = 1; + + private final Bounds bounds = new Bounds(); + + protected PregenTask(boolean gui, Position2 center, int radiusX, int radiusZ) { + this.gui = gui; + this.center = new ProxiedPos(center); + this.radiusX = radiusX; + this.radiusZ = radiusZ; + bounds.update(); + } public static void iterateRegion(int xr, int zr, Spiraled s, Position2 pull) { for (Position2 i : ORDERS.computeIfAbsent(pull, PregenTask::computeOrder)) { @@ -70,29 +79,72 @@ public class PregenTask { return p; } - private static KList computeChunkOrder() { - Position2 center = new Position2(15, 15); - KList p = new KList<>(); - new Spiraler(33, 33, (x, z) -> { - int xx = x + 15; - int zz = z + 15; - if (xx < 0 || xx > 31 || zz < 0 || zz > 31) { - return; - } - - p.add(new Position2(xx, zz)); - }).drain(); - p.sort(Comparator.comparing((i) -> i.distance(center))); - return p; + public void iterateRegions(Spiraled s) { + var bound = bounds.region(); + new Spiraler(bound.sizeX, bound.sizeZ, ((x, z) -> { + if (bound.check(x, z)) s.on(x, z); + })).setOffset(center.getX() >> 9, center.getZ() >> 9).drain(); } - public void iterateRegions(Spiraled s) { - new Spiraler(getWidth() * 2, getHeight() * 2, s) - .setOffset(center.getX(), center.getZ()).drain(); + public void iterateChunks(int rX, int rZ, Spiraled s) { + var bound = bounds.chunk(); + iterateRegion(rX, rZ, ((x, z) -> { + if (bound.check(x, z)) s.on(x, z); + })); } public void iterateAllChunks(Spiraled s) { - new Spiraler(getWidth() * 2, getHeight() * 2, (x, z) -> iterateRegion(x, z, s)) - .setOffset(center.getX(), center.getZ()).drain(); + iterateRegions(((rX, rZ) -> iterateChunks(rX, rZ, s))); + } + + private class Bounds { + private Bound chunk = null; + private Bound region = null; + + public void update() { + int maxX = center.getX() + radiusX; + int maxZ = center.getZ() + radiusZ; + int minX = center.getX() - radiusX; + int minZ = center.getZ() - radiusZ; + + chunk = new Bound(minX >> 4, minZ >> 4, Math.ceilDiv(maxX, 16), Math.ceilDiv(maxZ, 16)); + region = new Bound(minX >> 9, minZ >> 9, Math.ceilDiv(maxX, 512), Math.ceilDiv(maxZ, 512)); + } + + public Bound chunk() { + if (chunk == null) update(); + return chunk; + } + + public Bound region() { + if (region == null) update(); + return region; + } + } + + private record Bound(int minX, int maxX, int minZ, int maxZ, int sizeX, int sizeZ) { + private Bound(int minX, int minZ, int maxX, int maxZ) { + this(minX, maxX, minZ, maxZ, maxZ - minZ + 1, maxZ - minZ + 1); + } + + boolean check(int x, int z) { + return x >= minX && x <= maxX && z >= minZ && z <= maxZ; + } + } + + private static class ProxiedPos extends Position2 { + public ProxiedPos(Position2 p) { + super(p.getX(), p.getZ()); + } + + @Override + public void setX(int x) { + throw new IllegalStateException("This Position2 may not be modified"); + } + + @Override + public void setZ(int z) { + throw new IllegalStateException("This Position2 may not be modified"); + } } } diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java b/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java index 9d41279c9..8667542a9 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java @@ -146,8 +146,8 @@ public class IrisPackBenchmarking { IrisToolbelt.pregenerate(PregenTask .builder() .gui(gui) - .width(radius) - .height(radius) + .radiusX(radius) + .radiusZ(radius) .build(), Bukkit.getWorld("benchmark") ); } From 407e51378c94954adaa5e4663f7489f2fbb47e66 Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Sat, 15 Mar 2025 16:28:18 +0100 Subject: [PATCH 13/13] fix applying x offset to z coords in Spiraler --- core/src/main/java/com/volmit/iris/util/math/Spiraler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/util/math/Spiraler.java b/core/src/main/java/com/volmit/iris/util/math/Spiraler.java index fc8716bb7..f6f52f2bd 100644 --- a/core/src/main/java/com/volmit/iris/util/math/Spiraler.java +++ b/core/src/main/java/com/volmit/iris/util/math/Spiraler.java @@ -63,7 +63,7 @@ public class Spiraler { public void next() { if ((-sizeX / 2 <= x) && (x <= sizeX / 2) && (-sizeZ / 2 <= z) && (z <= sizeZ / 2)) { - spiraled.on(x + ox, z + ox); + spiraled.on(x + ox, z + oz); } if ((x == z) || ((x < 0) && (x == -z)) || ((x > 0) && (x == 1 - z))) {