diff --git a/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/MemoryWorld.java b/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/MemoryWorld.java index 20ac7f44f..86b3e5833 100644 --- a/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/MemoryWorld.java +++ b/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/MemoryWorld.java @@ -4,8 +4,10 @@ import com.google.common.collect.ImmutableList; import com.mojang.serialization.Lifecycle; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.IMemoryWorld; +import com.volmit.iris.util.scheduling.J; import net.minecraft.core.BlockPos; import net.minecraft.core.Registry; +import net.minecraft.core.RegistryAccess; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; @@ -24,11 +26,13 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; 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.PatrolSpawner; import net.minecraft.world.level.levelgen.PhantomSpawner; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; +import net.minecraft.world.level.storage.ServerLevelData; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -49,10 +53,12 @@ import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.lang.ref.WeakReference; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; import java.util.Locale; import java.util.Map; import java.util.Objects; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; @@ -75,7 +81,7 @@ public class MemoryWorld implements IMemoryWorld { var tempDir = Files.createTempDirectory("MemoryGenerator"); LevelStorageSource source = LevelStorageSource.createDefault(tempDir); - ResourceKey stemKey = ResourceKey.create(Registry.LEVEL_STEM_REGISTRY, new ResourceLocation(levelType.getKey(), levelType.getNamespace())); + ResourceKey stemKey = ResourceKey.create(Registry.LEVEL_STEM_REGISTRY, new ResourceLocation(levelType.getNamespace(), levelType.getKey())); var access = source.createAccess(name, stemKey); var registry = server.registryAccess().registryOrThrow(Registry.LEVEL_STEM_REGISTRY); @@ -90,7 +96,25 @@ public class MemoryWorld implements IMemoryWorld { if (levelStem == null) throw new IllegalStateException("Unknown dimension type: " + stemKey); - var worldInfo = new CraftWorldInfo(worldData, access, creator.environment(), levelStem.typeHolder().value()); + CraftWorldInfo worldInfo; + try { + worldInfo = new CraftWorldInfo(worldData, access, creator.environment(), levelStem.typeHolder().value()); + } catch (Throwable e) { + try { + var c = CraftWorldInfo.class.getDeclaredConstructor( + ServerLevelData.class, + LevelStorageSource.LevelStorageAccess.class, + World.Environment.class, + DimensionType.class, + net.minecraft.world.level.chunk.ChunkGenerator.class, + RegistryAccess.Frozen.class); + + worldInfo = c.newInstance(worldData, access, creator.environment(), levelStem.typeHolder().value(), levelStem.generator(), server.registryAccess()); + } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | + IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } if (biomeProvider == null && generator != null) { biomeProvider = generator.getDefaultBiomeProvider(worldInfo); } @@ -154,6 +178,20 @@ public class MemoryWorld implements IMemoryWorld { @Override public void close() throws Exception { + if (!Bukkit.isPrimaryThread()) { + var future = new CompletableFuture(); + J.s(() -> { + try { + close(); + future.complete(null); + } catch (Exception e) { + future.completeExceptionally(e); + } + }); + future.join(); + return; + } + var level = this.level.get(); if (level == null || !this.level.compareAndSet(level, null)) return; diff --git a/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/MemoryWorld.java b/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/MemoryWorld.java index 394965eae..e4cfd9434 100644 --- a/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/MemoryWorld.java +++ b/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/MemoryWorld.java @@ -5,6 +5,7 @@ import com.mojang.serialization.Lifecycle; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.IMemoryWorld; import net.minecraft.core.BlockPos; +import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -27,12 +28,14 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; 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.PatrolSpawner; import net.minecraft.world.level.levelgen.PhantomSpawner; import net.minecraft.world.level.levelgen.WorldOptions; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; +import net.minecraft.world.level.storage.ServerLevelData; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -53,6 +56,7 @@ import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.lang.ref.WeakReference; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; import java.util.Locale; import java.util.Map; @@ -78,7 +82,7 @@ public class MemoryWorld implements IMemoryWorld { var tempDir = Files.createTempDirectory("MemoryGenerator"); LevelStorageSource source = LevelStorageSource.createDefault(tempDir); - ResourceKey stemKey = ResourceKey.create(Registries.LEVEL_STEM, new ResourceLocation(levelType.getKey(), levelType.getNamespace())); + ResourceKey stemKey = ResourceKey.create(Registries.LEVEL_STEM, new ResourceLocation(levelType.getNamespace(), levelType.getKey())); var access = source.createAccess(name, stemKey); var worldLoader = server.worldLoader; @@ -98,7 +102,25 @@ public class MemoryWorld implements IMemoryWorld { if (levelStem == null) throw new IllegalStateException("Unknown dimension type: " + stemKey); - var worldInfo = new CraftWorldInfo(worldData, access, creator.environment(), levelStem.type().value()); + CraftWorldInfo worldInfo; + try { + worldInfo = new CraftWorldInfo(worldData, access, creator.environment(), levelStem.type().value()); + } catch (Throwable e) { + try { + var c = CraftWorldInfo.class.getDeclaredConstructor( + ServerLevelData.class, + LevelStorageSource.LevelStorageAccess.class, + World.Environment.class, + DimensionType.class, + net.minecraft.world.level.chunk.ChunkGenerator.class, + RegistryAccess.Frozen.class); + + worldInfo = c.newInstance(worldData, access, creator.environment(), levelStem.type().value(), levelStem.generator(), server.registryAccess()); + } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | + IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } if (biomeProvider == null && generator != null) { biomeProvider = generator.getDefaultBiomeProvider(worldInfo); } diff --git a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/MemoryWorld.java b/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/MemoryWorld.java index f3d59a64b..ea9e9e8fe 100644 --- a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/MemoryWorld.java +++ b/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/MemoryWorld.java @@ -4,7 +4,9 @@ import com.google.common.collect.ImmutableList; import com.mojang.serialization.Lifecycle; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.IMemoryWorld; +import com.volmit.iris.util.scheduling.J; import net.minecraft.core.BlockPos; +import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -27,12 +29,14 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; 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.PatrolSpawner; import net.minecraft.world.level.levelgen.PhantomSpawner; import net.minecraft.world.level.levelgen.WorldOptions; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; +import net.minecraft.world.level.storage.ServerLevelData; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -53,9 +57,11 @@ import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.lang.ref.WeakReference; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; import java.util.Locale; import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; @@ -78,7 +84,7 @@ public class MemoryWorld implements IMemoryWorld { var tempDir = Files.createTempDirectory("MemoryGenerator"); LevelStorageSource source = LevelStorageSource.createDefault(tempDir); - ResourceKey stemKey = ResourceKey.create(Registries.LEVEL_STEM, new ResourceLocation(levelType.getKey(), levelType.getNamespace())); + ResourceKey stemKey = ResourceKey.create(Registries.LEVEL_STEM, new ResourceLocation(levelType.getNamespace(), levelType.getKey())); var access = source.createAccess(name, stemKey); var worldLoader = server.worldLoader; @@ -98,7 +104,25 @@ public class MemoryWorld implements IMemoryWorld { if (levelStem == null) throw new IllegalStateException("Unknown dimension type: " + stemKey); - var worldInfo = new CraftWorldInfo(worldData, access, creator.environment(), levelStem.type().value()); + CraftWorldInfo worldInfo; + try { + worldInfo = new CraftWorldInfo(worldData, access, creator.environment(), levelStem.type().value()); + } catch (Throwable e) { + try { + var c = CraftWorldInfo.class.getDeclaredConstructor( + ServerLevelData.class, + LevelStorageSource.LevelStorageAccess.class, + World.Environment.class, + DimensionType.class, + net.minecraft.world.level.chunk.ChunkGenerator.class, + RegistryAccess.Frozen.class); + + worldInfo = c.newInstance(worldData, access, creator.environment(), levelStem.type().value(), levelStem.generator(), server.registryAccess()); + } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | + IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } if (biomeProvider == null && generator != null) { biomeProvider = generator.getDefaultBiomeProvider(worldInfo); } @@ -162,12 +186,25 @@ public class MemoryWorld implements IMemoryWorld { @Override public void close() throws Exception { + if (!Bukkit.isPrimaryThread()) { + var future = new CompletableFuture(); + J.s(() -> { + try { + close(); + future.complete(null); + } catch (Exception e) { + future.completeExceptionally(e); + } + }); + future.join(); + return; + } + var level = this.level.get(); if (level == null || !this.level.compareAndSet(level, null)) return; - level.getChunkSource().close(false); - level.entityManager.close(false); + level.close(); level.convertable.deleteLevel(); level.convertable.close(); diff --git a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/MemoryWorld.java b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/MemoryWorld.java index 0bf76e41e..bdccdd5d2 100644 --- a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/MemoryWorld.java +++ b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/MemoryWorld.java @@ -4,7 +4,9 @@ import com.google.common.collect.ImmutableList; import com.mojang.serialization.Lifecycle; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.IMemoryWorld; +import com.volmit.iris.util.scheduling.J; import net.minecraft.core.BlockPos; +import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -27,12 +29,14 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; 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.PatrolSpawner; import net.minecraft.world.level.levelgen.PhantomSpawner; import net.minecraft.world.level.levelgen.WorldOptions; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; +import net.minecraft.world.level.storage.ServerLevelData; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -53,9 +57,11 @@ import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.lang.ref.WeakReference; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; import java.util.Locale; import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; @@ -78,7 +84,7 @@ public class MemoryWorld implements IMemoryWorld { var tempDir = Files.createTempDirectory("MemoryGenerator"); LevelStorageSource source = LevelStorageSource.createDefault(tempDir); - ResourceKey stemKey = ResourceKey.create(Registries.LEVEL_STEM, new ResourceLocation(levelType.getKey(), levelType.getNamespace())); + ResourceKey stemKey = ResourceKey.create(Registries.LEVEL_STEM, new ResourceLocation(levelType.getNamespace(), levelType.getKey())); var access = source.createAccess(name, stemKey); var worldLoader = server.worldLoader; @@ -98,7 +104,25 @@ public class MemoryWorld implements IMemoryWorld { if (levelStem == null) throw new IllegalStateException("Unknown dimension type: " + stemKey); - var worldInfo = new CraftWorldInfo(worldData, access, creator.environment(), levelStem.type().value()); + CraftWorldInfo worldInfo; + try { + worldInfo = new CraftWorldInfo(worldData, access, creator.environment(), levelStem.type().value()); + } catch (Throwable e) { + try { + var c = CraftWorldInfo.class.getDeclaredConstructor( + ServerLevelData.class, + LevelStorageSource.LevelStorageAccess.class, + World.Environment.class, + DimensionType.class, + net.minecraft.world.level.chunk.ChunkGenerator.class, + RegistryAccess.Frozen.class); + + worldInfo = c.newInstance(worldData, access, creator.environment(), levelStem.type().value(), levelStem.generator(), server.registryAccess()); + } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | + IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } if (biomeProvider == null && generator != null) { biomeProvider = generator.getDefaultBiomeProvider(worldInfo); } @@ -163,12 +187,25 @@ public class MemoryWorld implements IMemoryWorld { @Override public void close() throws Exception { + if (!Bukkit.isPrimaryThread()) { + var future = new CompletableFuture(); + J.s(() -> { + try { + close(); + future.complete(null); + } catch (Exception e) { + future.completeExceptionally(e); + } + }); + future.join(); + return; + } + var level = this.level.get(); if (level == null || !this.level.compareAndSet(level, null)) return; - level.getChunkSource().close(false); - level.entityManager.close(false); + level.close(); level.convertable.deleteLevel(); level.convertable.close(); diff --git a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/MemoryWorld.java b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/MemoryWorld.java index 56e730e07..37cd66128 100644 --- a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/MemoryWorld.java +++ b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/MemoryWorld.java @@ -4,7 +4,9 @@ import com.google.common.collect.ImmutableList; import com.mojang.serialization.Lifecycle; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.IMemoryWorld; +import com.volmit.iris.util.scheduling.J; import net.minecraft.core.BlockPos; +import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -27,12 +29,14 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; 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.PatrolSpawner; import net.minecraft.world.level.levelgen.PhantomSpawner; import net.minecraft.world.level.levelgen.WorldOptions; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; +import net.minecraft.world.level.storage.ServerLevelData; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -53,9 +57,11 @@ import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.lang.ref.WeakReference; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; import java.util.Locale; import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; @@ -78,7 +84,7 @@ public class MemoryWorld implements IMemoryWorld { var tempDir = Files.createTempDirectory("MemoryGenerator"); LevelStorageSource source = LevelStorageSource.createDefault(tempDir); - ResourceKey stemKey = ResourceKey.create(Registries.LEVEL_STEM, new ResourceLocation(levelType.getKey(), levelType.getNamespace())); + ResourceKey stemKey = ResourceKey.create(Registries.LEVEL_STEM, new ResourceLocation(levelType.getNamespace(), levelType.getKey())); var access = source.createAccess(name, stemKey); var worldLoader = server.worldLoader; @@ -98,7 +104,25 @@ public class MemoryWorld implements IMemoryWorld { if (levelStem == null) throw new IllegalStateException("Unknown dimension type: " + stemKey); - var worldInfo = new CraftWorldInfo(worldData, access, creator.environment(), levelStem.type().value()); + CraftWorldInfo worldInfo; + try { + worldInfo = new CraftWorldInfo(worldData, access, creator.environment(), levelStem.type().value()); + } catch (Throwable e) { + try { + var c = CraftWorldInfo.class.getDeclaredConstructor( + ServerLevelData.class, + LevelStorageSource.LevelStorageAccess.class, + World.Environment.class, + DimensionType.class, + net.minecraft.world.level.chunk.ChunkGenerator.class, + RegistryAccess.Frozen.class); + + worldInfo = c.newInstance(worldData, access, creator.environment(), levelStem.type().value(), levelStem.generator(), server.registryAccess()); + } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | + IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } if (biomeProvider == null && generator != null) { biomeProvider = generator.getDefaultBiomeProvider(worldInfo); } @@ -163,12 +187,25 @@ public class MemoryWorld implements IMemoryWorld { @Override public void close() throws Exception { + if (!Bukkit.isPrimaryThread()) { + var future = new CompletableFuture(); + J.s(() -> { + try { + close(); + future.complete(null); + } catch (Exception e) { + future.completeExceptionally(e); + } + }); + future.join(); + return; + } + var level = this.level.get(); if (level == null || !this.level.compareAndSet(level, null)) return; - level.getChunkSource().close(false); - level.entityManager.close(false); + level.close(); level.convertable.deleteLevel(); level.convertable.close(); diff --git a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/MemoryWorld.java b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/MemoryWorld.java index 77c56e5d5..2239fcaff 100644 --- a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/MemoryWorld.java +++ b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/MemoryWorld.java @@ -4,7 +4,9 @@ import com.google.common.collect.ImmutableList; import com.mojang.serialization.Lifecycle; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.IMemoryWorld; +import com.volmit.iris.util.scheduling.J; import net.minecraft.core.BlockPos; +import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -27,12 +29,14 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; 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.PatrolSpawner; import net.minecraft.world.level.levelgen.PhantomSpawner; import net.minecraft.world.level.levelgen.WorldOptions; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; +import net.minecraft.world.level.storage.ServerLevelData; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -57,9 +61,11 @@ import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.lang.ref.WeakReference; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; import java.util.Locale; import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; @@ -82,7 +88,7 @@ public class MemoryWorld implements IMemoryWorld { var tempDir = Files.createTempDirectory("MemoryGenerator"); LevelStorageSource source = LevelStorageSource.createDefault(tempDir); - ResourceKey stemKey = ResourceKey.create(Registries.LEVEL_STEM, new ResourceLocation(levelType.getKey(), levelType.getNamespace())); + ResourceKey stemKey = ResourceKey.create(Registries.LEVEL_STEM, new ResourceLocation(levelType.getNamespace(), levelType.getKey())); var access = source.createAccess(name, stemKey); var worldLoader = server.worldLoader; @@ -102,7 +108,25 @@ public class MemoryWorld implements IMemoryWorld { if (levelStem == null) throw new IllegalStateException("Unknown dimension type: " + stemKey); - var worldInfo = new CraftWorldInfo(worldData, access, creator.environment(), levelStem.type().value()); + CraftWorldInfo worldInfo; + try { + worldInfo = new CraftWorldInfo(worldData, access, creator.environment(), levelStem.type().value()); + } catch (Throwable e) { + try { + var c = CraftWorldInfo.class.getDeclaredConstructor( + ServerLevelData.class, + LevelStorageSource.LevelStorageAccess.class, + World.Environment.class, + DimensionType.class, + net.minecraft.world.level.chunk.ChunkGenerator.class, + RegistryAccess.Frozen.class); + + worldInfo = c.newInstance(worldData, access, creator.environment(), levelStem.type().value(), levelStem.generator(), server.registryAccess()); + } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | + IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } if (biomeProvider == null && generator != null) { biomeProvider = generator.getDefaultBiomeProvider(worldInfo); } @@ -167,12 +191,25 @@ public class MemoryWorld implements IMemoryWorld { @Override public void close() throws Exception { + if (!Bukkit.isPrimaryThread()) { + var future = new CompletableFuture(); + J.s(() -> { + try { + close(); + future.complete(null); + } catch (Exception e) { + future.completeExceptionally(e); + } + }); + future.join(); + return; + } + var level = this.level.get(); if (level == null || !this.level.compareAndSet(level, null)) return; - level.getChunkSource().close(false); - level.entityManager.close(false); + level.close(); level.convertable.deleteLevel(); level.convertable.close(); diff --git a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/MemoryWorld.java b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/MemoryWorld.java index 575f7b05c..aa0d67f83 100644 --- a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/MemoryWorld.java +++ b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/MemoryWorld.java @@ -4,7 +4,9 @@ import com.google.common.collect.ImmutableList; import com.mojang.serialization.Lifecycle; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.IMemoryWorld; +import com.volmit.iris.util.scheduling.J; import net.minecraft.core.BlockPos; +import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -27,12 +29,14 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; 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.PatrolSpawner; import net.minecraft.world.level.levelgen.PhantomSpawner; import net.minecraft.world.level.levelgen.WorldOptions; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; +import net.minecraft.world.level.storage.ServerLevelData; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -54,9 +58,11 @@ import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.lang.ref.WeakReference; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; import java.util.Locale; import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; @@ -79,7 +85,7 @@ public class MemoryWorld implements IMemoryWorld { var tempDir = Files.createTempDirectory("MemoryGenerator"); LevelStorageSource source = LevelStorageSource.createDefault(tempDir); - ResourceKey stemKey = ResourceKey.create(Registries.LEVEL_STEM, new ResourceLocation(levelType.getKey(), levelType.getNamespace())); + ResourceKey stemKey = ResourceKey.create(Registries.LEVEL_STEM, new ResourceLocation(levelType.getNamespace(), levelType.getKey())); var access = source.createAccess(name, stemKey); var worldLoader = server.worldLoader; @@ -100,7 +106,25 @@ public class MemoryWorld implements IMemoryWorld { if (levelStem == null) throw new IllegalStateException("Unknown dimension type: " + stemKey); - var worldInfo = new CraftWorldInfo(worldData, access, creator.environment(), levelStem.type().value()); + CraftWorldInfo worldInfo; + try { + worldInfo = new CraftWorldInfo(worldData, access, creator.environment(), levelStem.type().value()); + } catch (Throwable e) { + try { + var c = CraftWorldInfo.class.getDeclaredConstructor( + ServerLevelData.class, + LevelStorageSource.LevelStorageAccess.class, + World.Environment.class, + DimensionType.class, + net.minecraft.world.level.chunk.ChunkGenerator.class, + RegistryAccess.Frozen.class); + + worldInfo = c.newInstance(worldData, access, creator.environment(), levelStem.type().value(), levelStem.generator(), server.registryAccess()); + } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | + IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } if (biomeProvider == null && generator != null) { biomeProvider = generator.getDefaultBiomeProvider(worldInfo); } @@ -164,12 +188,25 @@ public class MemoryWorld implements IMemoryWorld { @Override public void close() throws Exception { + if (!Bukkit.isPrimaryThread()) { + var future = new CompletableFuture(); + J.s(() -> { + try { + close(); + future.complete(null); + } catch (Exception e) { + future.completeExceptionally(e); + } + }); + future.join(); + return; + } + var level = this.level.get(); if (level == null || !this.level.compareAndSet(level, null)) return; - level.getChunkSource().close(false); - level.entityManager.close(false); + level.close(); level.convertable.deleteLevel(); level.convertable.close(); diff --git a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/MemoryWorld.java b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/MemoryWorld.java index 0298912c2..7678e33f5 100644 --- a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/MemoryWorld.java +++ b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/MemoryWorld.java @@ -4,7 +4,9 @@ import com.google.common.collect.ImmutableList; import com.mojang.serialization.Lifecycle; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.IMemoryWorld; +import com.volmit.iris.util.scheduling.J; import net.minecraft.core.BlockPos; +import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -27,12 +29,14 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; 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.PatrolSpawner; import net.minecraft.world.level.levelgen.PhantomSpawner; import net.minecraft.world.level.levelgen.WorldOptions; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; +import net.minecraft.world.level.storage.ServerLevelData; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -54,11 +58,15 @@ import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.lang.ref.WeakReference; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; +import java.util.Arrays; import java.util.Locale; import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; public class MemoryWorld implements IMemoryWorld { private static final AtomicLong C = new AtomicLong(); @@ -79,7 +87,7 @@ public class MemoryWorld implements IMemoryWorld { var tempDir = Files.createTempDirectory("MemoryGenerator"); LevelStorageSource source = LevelStorageSource.createDefault(tempDir); - ResourceKey stemKey = ResourceKey.create(Registries.LEVEL_STEM, ResourceLocation.fromNamespaceAndPath(levelType.getKey(), levelType.getNamespace())); + ResourceKey stemKey = ResourceKey.create(Registries.LEVEL_STEM, ResourceLocation.fromNamespaceAndPath(levelType.getNamespace(), levelType.getKey())); var access = source.createAccess(name, stemKey); var worldLoader = server.worldLoader; @@ -100,7 +108,25 @@ public class MemoryWorld implements IMemoryWorld { if (levelStem == null) throw new IllegalStateException("Unknown dimension type: " + stemKey); - var worldInfo = new CraftWorldInfo(worldData, access, creator.environment(), levelStem.type().value()); + CraftWorldInfo worldInfo; + try { + worldInfo = new CraftWorldInfo(worldData, access, creator.environment(), levelStem.type().value()); + } catch (Throwable e) { + try { + var c = CraftWorldInfo.class.getDeclaredConstructor( + ServerLevelData.class, + LevelStorageSource.LevelStorageAccess.class, + World.Environment.class, + DimensionType.class, + net.minecraft.world.level.chunk.ChunkGenerator.class, + RegistryAccess.Frozen.class); + + worldInfo = c.newInstance(worldData, access, creator.environment(), levelStem.type().value(), levelStem.generator(), server.registryAccess()); + } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | + IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } if (biomeProvider == null && generator != null) { biomeProvider = generator.getDefaultBiomeProvider(worldInfo); } @@ -164,12 +190,25 @@ public class MemoryWorld implements IMemoryWorld { @Override public void close() throws Exception { + if (!Bukkit.isPrimaryThread()) { + var future = new CompletableFuture(); + J.s(() -> { + try { + close(); + future.complete(null); + } catch (Exception e) { + future.completeExceptionally(e); + } + }); + future.join(); + return; + } + var level = this.level.get(); if (level == null || !this.level.compareAndSet(level, null)) return; - level.getChunkSource().close(false); - level.entityManager.close(false); + level.close(); level.convertable.deleteLevel(); level.convertable.close();