From 3e41a4630dae82a13811a39dd6e7b6271f83d8a0 Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 27 May 2022 18:12:43 +0200 Subject: [PATCH] Make sure BiomeAPI is initialized with the correct registry --- .../org/betterx/bclib/api/LifeCycleAPI.java | 77 +++++++++++++++---- .../betterx/bclib/api/biomes/BiomeAPI.java | 3 +- .../bclib/api/worldgen/WorldGenUtil.java | 67 ++++++++-------- .../mixin/client/CreateWorldScreenMixin.java | 8 +- .../betterx/bclib/mixin/common/MainMixin.java | 64 +++------------ .../mixin/common/PrimaryLevelDataMixin.java | 6 +- .../mixin/common/WorldOpenFlowsMixin.java | 2 +- .../bclib/world/generator/BCLBiomeSource.java | 2 +- 8 files changed, 117 insertions(+), 112 deletions(-) diff --git a/src/main/java/org/betterx/bclib/api/LifeCycleAPI.java b/src/main/java/org/betterx/bclib/api/LifeCycleAPI.java index 81467908..1713461c 100644 --- a/src/main/java/org/betterx/bclib/api/LifeCycleAPI.java +++ b/src/main/java/org/betterx/bclib/api/LifeCycleAPI.java @@ -1,6 +1,10 @@ package org.betterx.bclib.api; +import net.minecraft.client.gui.screens.worldselection.WorldGenSettingsComponent; import net.minecraft.core.Registry; +import net.minecraft.core.RegistryAccess; +import net.minecraft.nbt.Tag; +import net.minecraft.resources.RegistryOps; import net.minecraft.resources.ResourceKey; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; @@ -15,9 +19,12 @@ import net.minecraft.world.level.storage.ServerLevelData; import org.betterx.bclib.api.biomes.BiomeAPI; import org.betterx.bclib.api.dataexchange.DataExchangeAPI; import org.betterx.bclib.api.datafixer.DataFixerAPI; +import org.betterx.bclib.api.worldgen.WorldGenUtil; +import org.betterx.bclib.mixin.common.RegistryOpsAccessor; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.concurrent.Executor; /** @@ -28,7 +35,7 @@ public class LifeCycleAPI { private final static List onLoadLevel = new ArrayList<>(2); private final static List beforeLoadLevel = new ArrayList<>(2); - public static void startingWorld(LevelStorageSource.LevelStorageAccess levelStorageAccess, + public static void newWorldSetup(LevelStorageSource.LevelStorageAccess levelStorageAccess, WorldGenSettings settings) { DataExchangeAPI.prepareServerside(); BiomeAPI.prepareNewLevel(); @@ -37,7 +44,7 @@ public class LifeCycleAPI { _runBeforeLevelLoad(); } - public static void startingWorld(String levelID, + public static void newWorldSetup(String levelID, WorldGenSettings worldGenSettings, LevelStorageSource levelSource) { DataExchangeAPI.prepareServerside(); @@ -47,6 +54,48 @@ public class LifeCycleAPI { _runBeforeLevelLoad(); } + public static void newWorldSetup(LevelStorageSource.LevelStorageAccess levelStorageAccess) { + BiomeAPI.prepareNewLevel(); + DataFixerAPI.fixData(levelStorageAccess, false, (didFix) -> {/* not called when showUI==false */}); + + _runBeforeLevelLoad(); + } + + public static WorldGenSettings worldLoadStarted(WorldGenSettings settings, + Optional> registryOps) { + if (registryOps.orElse(null) instanceof RegistryOpsAccessor acc) { + BiomeAPI.initRegistry(acc.bcl_getRegistryAccess() + .registry(Registry.BIOME_REGISTRY) + .orElse(null)); + } + settings = WorldGenUtil.fixSettingsInCurrentWorld(registryOps, settings); + + return settings; + } + + private static void worldCreationStarted(RegistryAccess access) { + BiomeAPI.initRegistry(access + .registry(Registry.BIOME_REGISTRY) + .orElse(null)); + } + + public static void worldCreationStarted(RegistryOps regOps) { + if (regOps instanceof RegistryOpsAccessor acc) { + worldCreationStarted(acc.bcl_getRegistryAccess()); + } + } + + public static void worldCreationStarted(Optional levelStorageAccess, + WorldGenSettingsComponent worldGenSettingsComponent) { + worldCreationStarted(worldGenSettingsComponent.registryHolder()); + + if (levelStorageAccess.isPresent()) { + newWorldSetup(levelStorageAccess.get(), + worldGenSettingsComponent.settings().worldGenSettings()); + } + } + + /** * A callback function that is used for each new ServerLevel instance */ @@ -143,18 +192,18 @@ public class LifeCycleAPI { List list, boolean bl2) { onLoadLevel.forEach(c -> c.onLoad( - world, - minecraftServer, - executor, - levelStorageAccess, - serverLevelData, - resourceKey, - chunkProgressListener, - bl, - l, - list, - bl2) - ); + world, + minecraftServer, + executor, + levelStorageAccess, + serverLevelData, + resourceKey, + chunkProgressListener, + bl, + l, + list, + bl2) + ); final long seed = world.getSeed(); final Registry biomeRegistry = world.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY); diff --git a/src/main/java/org/betterx/bclib/api/biomes/BiomeAPI.java b/src/main/java/org/betterx/bclib/api/biomes/BiomeAPI.java index 1d58cc41..d57fef61 100644 --- a/src/main/java/org/betterx/bclib/api/biomes/BiomeAPI.java +++ b/src/main/java/org/betterx/bclib/api/biomes/BiomeAPI.java @@ -169,8 +169,7 @@ public class BiomeAPI { */ public static void initRegistry(Registry biomeRegistry) { if (biomeRegistry != BiomeAPI.biomeRegistry) { - System.out.println("Switching Registry to " + biomeRegistry);//17015, 19009, 19058, 19009 - BiomeAPI.biomeRegistry = biomeRegistry; + BiomeAPI.biomeRegistry = biomeRegistry; //12819 CLIENT.clear(); } } diff --git a/src/main/java/org/betterx/bclib/api/worldgen/WorldGenUtil.java b/src/main/java/org/betterx/bclib/api/worldgen/WorldGenUtil.java index 061ff5ff..ca84cd8f 100644 --- a/src/main/java/org/betterx/bclib/api/worldgen/WorldGenUtil.java +++ b/src/main/java/org/betterx/bclib/api/worldgen/WorldGenUtil.java @@ -37,7 +37,6 @@ import org.betterx.bclib.world.generator.BCLibNetherBiomeSource; import java.util.Map; import java.util.Optional; - import org.jetbrains.annotations.NotNull; public class WorldGenUtil { @@ -85,6 +84,8 @@ public class WorldGenUtil { * * @param settings * @return + * @see BCLChunkGenerator#injectNoiseSettings(WorldGenSettings) for the correcponding behaviour + * for new worlds */ public static WorldGenSettings fixSettingsInCurrentWorld(Optional> registryOps, WorldGenSettings settings) { @@ -121,10 +122,10 @@ public class WorldGenUtil { boolean generateStructures, boolean generateBonusChest) { return createWorldFromPreset(BCLWorldPresets.DEFAULT.orElseThrow(), - registryAccess, - seed, - generateStructures, - generateBonusChest); + registryAccess, + seed, + generateStructures, + generateBonusChest); } public static Pair defaultWorldDataSupplier(RegistryAccess.Frozen frozen) { @@ -146,7 +147,7 @@ public class WorldGenUtil { int biomeSourceVersion, RegistryAccess registryAccess, WorldGenSettings worldGenSettings - ) { + ) { Optional> oLevelStem = referenceStemForVersion( dimensionKey, biomeSourceVersion, @@ -154,12 +155,12 @@ public class WorldGenUtil { worldGenSettings.seed(), worldGenSettings.generateStructures(), worldGenSettings.generateStructures() - ); + ); return replaceGenerator(dimensionKey, - dimensionTypeKey, - registryAccess, - worldGenSettings, - oLevelStem.map(l -> l.value().generator()).orElseThrow()); + dimensionTypeKey, + registryAccess, + worldGenSettings, + oLevelStem.map(l -> l.value().generator()).orElseThrow()); } public static WorldGenSettings replaceGenerator( @@ -168,31 +169,31 @@ public class WorldGenUtil { RegistryAccess registryAccess, WorldGenSettings worldGenSettings, ChunkGenerator generator - ) { + ) { Registry dimensionTypeRegistry = registryAccess.registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY); Registry newDimensions = withDimension(dimensionKey, - dimensionTypeKey, - dimensionTypeRegistry, - worldGenSettings.dimensions(), - generator); + dimensionTypeKey, + dimensionTypeRegistry, + worldGenSettings.dimensions(), + generator); return new WorldGenSettings(worldGenSettings.seed(), - worldGenSettings.generateStructures(), - worldGenSettings.generateBonusChest(), - newDimensions); + worldGenSettings.generateStructures(), + worldGenSettings.generateBonusChest(), + newDimensions); } public static WorldGenSettings replaceStem( ResourceKey dimensionKey, WorldGenSettings worldGenSettings, LevelStem levelStem - ) { + ) { Registry newDimensions = withDimension(dimensionKey, - worldGenSettings.dimensions(), - levelStem); + worldGenSettings.dimensions(), + levelStem); return new WorldGenSettings(worldGenSettings.seed(), - worldGenSettings.generateStructures(), - worldGenSettings.generateBonusChest(), - newDimensions); + worldGenSettings.generateStructures(), + worldGenSettings.generateBonusChest(), + newDimensions); } public static Registry withDimension(ResourceKey dimensionKey, @@ -212,17 +213,17 @@ public class WorldGenUtil { Registry inputDimensions, LevelStem levelStem) { MappedRegistry writableRegistry = new MappedRegistry<>(Registry.LEVEL_STEM_REGISTRY, - Lifecycle.experimental(), - null); + Lifecycle.experimental(), + null); writableRegistry.register(dimensionKey, - levelStem, - Lifecycle.stable()); + levelStem, + Lifecycle.stable()); for (Map.Entry, LevelStem> entry : inputDimensions.entrySet()) { ResourceKey resourceKey = entry.getKey(); if (resourceKey == dimensionKey) continue; writableRegistry.register(resourceKey, - entry.getValue(), - inputDimensions.lifecycle(entry.getValue())); + entry.getValue(), + inputDimensions.lifecycle(entry.getValue())); } return writableRegistry; } @@ -239,7 +240,7 @@ public class WorldGenUtil { long seed, boolean generateStructures, boolean generateBonusChest - ) { + ) { final WorldGenSettings referenceSettings; if (biomeSourceVersion == BCLBiomeSource.BIOME_SOURCE_VERSION_VANILLA) { referenceSettings = net.minecraft.world.level.levelgen.presets.WorldPresets.createNormalWorldFromPreset( @@ -383,5 +384,5 @@ public class WorldGenUtil { this.biomes = biomes; } } - + } diff --git a/src/main/java/org/betterx/bclib/mixin/client/CreateWorldScreenMixin.java b/src/main/java/org/betterx/bclib/mixin/client/CreateWorldScreenMixin.java index 19fd70ab..8b0749db 100644 --- a/src/main/java/org/betterx/bclib/mixin/client/CreateWorldScreenMixin.java +++ b/src/main/java/org/betterx/bclib/mixin/client/CreateWorldScreenMixin.java @@ -57,13 +57,9 @@ public class CreateWorldScreenMixin { }; } + //this is called when a new world is first created @Inject(method = "createNewWorldDirectory", at = @At("RETURN")) void bcl_createNewWorld(CallbackInfoReturnable> cir) { - Optional levelStorageAccess = cir.getReturnValue(); - if (levelStorageAccess.isPresent()) { - LifeCycleAPI.startingWorld(levelStorageAccess.get(), - worldGenSettingsComponent.settings().worldGenSettings()); - } + LifeCycleAPI.worldCreationStarted(cir.getReturnValue(), this.worldGenSettingsComponent); } - } diff --git a/src/main/java/org/betterx/bclib/mixin/common/MainMixin.java b/src/main/java/org/betterx/bclib/mixin/common/MainMixin.java index b5e4758f..853299dd 100644 --- a/src/main/java/org/betterx/bclib/mixin/common/MainMixin.java +++ b/src/main/java/org/betterx/bclib/mixin/common/MainMixin.java @@ -1,72 +1,32 @@ package org.betterx.bclib.mixin.common; +import net.minecraft.nbt.Tag; +import net.minecraft.resources.RegistryOps; import net.minecraft.server.Main; -import net.minecraft.server.dedicated.DedicatedServerSettings; import net.minecraft.world.level.storage.LevelStorageSource; -import joptsimple.ArgumentAcceptingOptionSpec; -import joptsimple.OptionParser; -import joptsimple.OptionSet; +import com.mojang.serialization.DynamicOps; import org.betterx.bclib.api.LifeCycleAPI; -import org.betterx.bclib.api.biomes.BiomeAPI; -import org.betterx.bclib.api.datafixer.DataFixerAPI; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.ModifyVariable; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.io.File; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Optional; @Mixin(Main.class) abstract public class MainMixin { @ModifyVariable(method = "main", ordinal = 0, at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/level/storage/LevelStorageSource$LevelStorageAccess;getSummary()Lnet/minecraft/world/level/storage/LevelSummary;")) private static LevelStorageSource.LevelStorageAccess bc_createAccess(LevelStorageSource.LevelStorageAccess levelStorageAccess) { - BiomeAPI.prepareNewLevel(); - DataFixerAPI.fixData(levelStorageAccess, false, (didFix) -> {/* not called when showUI==false */}); - - LifeCycleAPI._runBeforeLevelLoad(); + LifeCycleAPI.newWorldSetup(levelStorageAccess); return levelStorageAccess; } - //@Inject(method = "main", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/storage/LevelStorageSource;createDefault(Ljava/nio/file/Path;)Lnet/minecraft/world/level/storage/LevelStorageSource;")) - private static void bclib_callServerFix(String[] args, CallbackInfo ci) { - OptionParser parser = new OptionParser(); - ArgumentAcceptingOptionSpec optionUniverse = parser.accepts("universe") - .withRequiredArg() - .defaultsTo(".", new String[0]); - ArgumentAcceptingOptionSpec optionWorld = parser.accepts("world").withRequiredArg(); - - //this is only for compat reasons, we do not need to read thise options in our mixin, but it seems to cause - //errors if they are not defined - parser.accepts("nogui"); - parser.accepts("initSettings", "Initializes 'server.properties' and 'eula.txt', then quits"); - parser.accepts("demo"); - parser.accepts("bonusChest"); - parser.accepts("forceUpgrade"); - parser.accepts("eraseCache"); - parser.accepts("safeMode", "Loads level with vanilla datapack only"); - parser.accepts("help").forHelp(); - parser.accepts("singleplayer").withRequiredArg(); - parser.accepts("port").withRequiredArg().ofType(Integer.class).defaultsTo(-1, new Integer[0]); - parser.accepts("serverId").withRequiredArg(); - parser.accepts("jfrProfile"); - parser.nonOptions(); - - OptionSet options = parser.parse(args); - - Path settingPath = Paths.get("server.properties"); - DedicatedServerSettings settings = new DedicatedServerSettings(settingPath); - - File file = new File(options.valueOf(optionUniverse)); - String levelID = Optional.ofNullable(options.valueOf(optionWorld)).orElse(settings.getProperties().levelName); - - LevelStorageSource levelStorageSource = LevelStorageSource.createDefault(file.toPath()); - DataFixerAPI.fixData(levelStorageSource, levelID, false, (didFix) -> {/* not called when showUI==false */}); - - LifeCycleAPI._runBeforeLevelLoad(); + @ModifyArg(method = "method_43613", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/storage/LevelStorageSource$LevelStorageAccess;getDataTag(Lcom/mojang/serialization/DynamicOps;Lnet/minecraft/world/level/DataPackConfig;Lcom/mojang/serialization/Lifecycle;)Lnet/minecraft/world/level/storage/WorldData;")) + private static DynamicOps bcl_onCreate(DynamicOps dynamicOps) { + if (dynamicOps instanceof RegistryOps regOps) { + LifeCycleAPI.worldCreationStarted(regOps); + } + return dynamicOps; } + } diff --git a/src/main/java/org/betterx/bclib/mixin/common/PrimaryLevelDataMixin.java b/src/main/java/org/betterx/bclib/mixin/common/PrimaryLevelDataMixin.java index 612813a5..e5fff02a 100644 --- a/src/main/java/org/betterx/bclib/mixin/common/PrimaryLevelDataMixin.java +++ b/src/main/java/org/betterx/bclib/mixin/common/PrimaryLevelDataMixin.java @@ -11,8 +11,8 @@ import net.minecraft.world.level.storage.PrimaryLevelData; import com.mojang.datafixers.DataFixer; import com.mojang.serialization.Dynamic; import com.mojang.serialization.Lifecycle; +import org.betterx.bclib.api.LifeCycleAPI; import org.betterx.bclib.api.worldgen.BCLChunkGenerator; -import org.betterx.bclib.api.worldgen.WorldGenUtil; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -59,9 +59,9 @@ public class PrimaryLevelDataMixin { @ModifyArg(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/storage/PrimaryLevelData;(Lcom/mojang/datafixers/DataFixer;ILnet/minecraft/nbt/CompoundTag;ZIIIFJJIIIZIZZZLnet/minecraft/world/level/border/WorldBorder$Settings;IILjava/util/UUID;Ljava/util/Set;Lnet/minecraft/world/level/timers/TimerQueue;Lnet/minecraft/nbt/CompoundTag;Lnet/minecraft/nbt/CompoundTag;Lnet/minecraft/world/level/LevelSettings;Lnet/minecraft/world/level/levelgen/WorldGenSettings;Lcom/mojang/serialization/Lifecycle;)V")) private static WorldGenSettings bcl_fixSettings(WorldGenSettings settings) { Optional> registryOps = bcl_lastRegistryAccess.get(); - settings = WorldGenUtil.fixSettingsInCurrentWorld(registryOps, settings); - + settings = LifeCycleAPI.worldLoadStarted(settings, registryOps); bcl_lastRegistryAccess.set(Optional.empty()); return settings; } + } diff --git a/src/main/java/org/betterx/bclib/mixin/common/WorldOpenFlowsMixin.java b/src/main/java/org/betterx/bclib/mixin/common/WorldOpenFlowsMixin.java index 78fe28e6..d52a3dff 100644 --- a/src/main/java/org/betterx/bclib/mixin/common/WorldOpenFlowsMixin.java +++ b/src/main/java/org/betterx/bclib/mixin/common/WorldOpenFlowsMixin.java @@ -58,7 +58,7 @@ public abstract class WorldOpenFlowsMixin { RegistryAccess registryAccess, WorldGenSettings worldGenSettings, CallbackInfo ci) { - LifeCycleAPI.startingWorld(levelID, worldGenSettings, this.levelSource); + LifeCycleAPI.newWorldSetup(levelID, worldGenSettings, this.levelSource); } @Inject(method = "createLevelFromExistingSettings", at = @At("HEAD")) diff --git a/src/main/java/org/betterx/bclib/world/generator/BCLBiomeSource.java b/src/main/java/org/betterx/bclib/world/generator/BCLBiomeSource.java index 53bd5ffd..07a0ab7b 100644 --- a/src/main/java/org/betterx/bclib/world/generator/BCLBiomeSource.java +++ b/src/main/java/org/betterx/bclib/world/generator/BCLBiomeSource.java @@ -42,7 +42,7 @@ public abstract class BCLBiomeSource extends BiomeSource { System.out.println(this + " with Registry: " + biomeRegistry.getClass().getName() + "@" + Integer.toHexString( biomeRegistry.hashCode())); - BiomeAPI.initRegistry(biomeRegistry); + //BiomeAPI.initRegistry(biomeRegistry); } final public void setSeed(long seed) {