mirror of
https://github.com/FabricMC/fabric.git
synced 2025-04-21 03:10:54 -04:00
21w41a
Remove SurfaceBuilder related APIs. Remove PersistentDynamicRegistryHandler as the bug (MC-202036) it fixed was fixed a few weeks ago.
This commit is contained in:
parent
b43623a4c6
commit
bb09662468
15 changed files with 12 additions and 407 deletions
build.gradle
fabric-biome-api-v1
build.gradle
src
main/java/net/fabricmc/fabric
api/biome/v1
impl/biome/modification
mixin/biome/modification
testmod/java/net/fabricmc/fabric/test/biome
fabric-registry-sync-v0
|
@ -9,7 +9,7 @@ plugins {
|
|||
id "eclipse"
|
||||
id "idea"
|
||||
id "maven-publish"
|
||||
id "fabric-loom" version "0.10.23" apply false
|
||||
id "fabric-loom" version "0.10.31" apply false
|
||||
id "org.cadixdev.licenser" version "0.6.1"
|
||||
id "org.ajoberstar.grgit" version "3.1.0"
|
||||
id "com.matthewprenger.cursegradle" version "1.4.0"
|
||||
|
@ -19,8 +19,8 @@ plugins {
|
|||
def ENV = System.getenv()
|
||||
|
||||
class Globals {
|
||||
static def baseVersion = "0.40.8"
|
||||
static def mcVersion = "21w40a"
|
||||
static def baseVersion = "0.40.9"
|
||||
static def mcVersion = "21w41a"
|
||||
static def yarnVersion = "+build.1"
|
||||
static def loaderVersion = "0.11.7"
|
||||
static def preRelease = true
|
||||
|
@ -264,6 +264,7 @@ subprojects {
|
|||
|
||||
afterEvaluate {
|
||||
genSources.enabled = false
|
||||
genSourcesWithCfr.enabled = false
|
||||
unpickJar.enabled = false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
archivesBaseName = "fabric-biome-api-v1"
|
||||
version = getSubprojectVersion(project, "4.0.3")
|
||||
version = getSubprojectVersion(project, "5.0.0")
|
||||
|
||||
loom {
|
||||
accessWidenerPath = file("src/main/resources/fabric-biome-api-v1.accesswidener")
|
||||
|
|
|
@ -38,8 +38,6 @@ import net.minecraft.world.gen.carver.ConfiguredCarver;
|
|||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.gen.feature.StructureFeature;
|
||||
import net.minecraft.world.gen.surfacebuilder.ConfiguredSurfaceBuilder;
|
||||
import net.minecraft.world.gen.surfacebuilder.ConfiguredSurfaceBuilders;
|
||||
|
||||
import net.fabricmc.fabric.impl.biome.modification.BuiltInRegistryKeys;
|
||||
|
||||
|
@ -288,23 +286,6 @@ public interface BiomeModificationContext {
|
|||
}
|
||||
|
||||
interface GenerationSettingsContext {
|
||||
/**
|
||||
* Sets the biomes surface builder to a surface builder registered in {@link BuiltinRegistries#CONFIGURED_SURFACE_BUILDER}.
|
||||
*
|
||||
* <p>This method is intended for use with the surface builders found in {@link ConfiguredSurfaceBuilders}.
|
||||
*
|
||||
* <p><b>NOTE:</b> In case the configured surface builder is overridden in a datapack, the datapacks version
|
||||
* will be used.
|
||||
*/
|
||||
default void setBuiltInSurfaceBuilder(ConfiguredSurfaceBuilder<?> configuredSurfaceBuilder) {
|
||||
setSurfaceBuilder(BuiltInRegistryKeys.get(configuredSurfaceBuilder));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the biomes surface builder to the surface builder identified by the given key.
|
||||
*/
|
||||
void setSurfaceBuilder(RegistryKey<ConfiguredSurfaceBuilder<?>> surfaceBuilderKey);
|
||||
|
||||
/**
|
||||
* Removes a feature from one of this biomes generation steps, and returns if any features were removed.
|
||||
*/
|
||||
|
|
|
@ -24,8 +24,6 @@ import net.minecraft.util.registry.RegistryKey;
|
|||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.gen.surfacebuilder.ConfiguredSurfaceBuilder;
|
||||
import net.minecraft.world.gen.surfacebuilder.ConfiguredSurfaceBuilders;
|
||||
|
||||
import net.fabricmc.fabric.impl.biome.modification.BuiltInRegistryKeys;
|
||||
|
||||
|
@ -43,30 +41,6 @@ public interface BiomeSelectionContext {
|
|||
*/
|
||||
Biome getBiome();
|
||||
|
||||
/**
|
||||
* Returns true if this biome uses the given built-in surface builder, which must be registered
|
||||
* in the {@link net.minecraft.util.registry.BuiltinRegistries}.
|
||||
*
|
||||
* <p>This method is intended for use with the Vanilla surface builders found in {@link ConfiguredSurfaceBuilders}.
|
||||
*/
|
||||
default boolean hasBuiltInSurfaceBuilder(ConfiguredSurfaceBuilder<?> surfaceBuilder) {
|
||||
RegistryKey<ConfiguredSurfaceBuilder<?>> key = BuiltInRegistryKeys.get(surfaceBuilder);
|
||||
return hasSurfaceBuilder(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this biome uses a surface builder that has the given key.
|
||||
*/
|
||||
default boolean hasSurfaceBuilder(RegistryKey<ConfiguredSurfaceBuilder<?>> key) {
|
||||
return getSurfaceBuilderKey().orElse(null) == key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to retrieve the registry key for this biomes current surface builder, which may be empty, if the
|
||||
* surface builder is not registered.
|
||||
*/
|
||||
Optional<RegistryKey<ConfiguredSurfaceBuilder<?>>> getSurfaceBuilderKey();
|
||||
|
||||
/**
|
||||
* Returns true if this biome has the given configured feature, which must be registered
|
||||
* in the {@link net.minecraft.util.registry.BuiltinRegistries}.
|
||||
|
|
|
@ -52,7 +52,6 @@ import net.minecraft.world.gen.feature.ConfiguredFeature;
|
|||
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.gen.feature.Feature;
|
||||
import net.minecraft.world.gen.feature.StructureFeature;
|
||||
import net.minecraft.world.gen.surfacebuilder.ConfiguredSurfaceBuilder;
|
||||
|
||||
import net.fabricmc.fabric.api.biome.v1.BiomeModificationContext;
|
||||
import net.fabricmc.fabric.mixin.biome.modification.BiomeAccessor;
|
||||
|
@ -220,7 +219,6 @@ public class BiomeModificationContextImpl implements BiomeModificationContext {
|
|||
private final Registry<ConfiguredCarver<?>> carvers = registries.get(Registry.CONFIGURED_CARVER_KEY);
|
||||
private final Registry<ConfiguredFeature<?, ?>> features = registries.get(Registry.CONFIGURED_FEATURE_KEY);
|
||||
private final Registry<ConfiguredStructureFeature<?, ?>> structures = registries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY);
|
||||
private final Registry<ConfiguredSurfaceBuilder<?>> surfaceBuilders = registries.get(Registry.CONFIGURED_SURFACE_BUILDER_KEY);
|
||||
private final GenerationSettings generationSettings = biome.getGenerationSettings();
|
||||
private final GenerationSettingsAccessor accessor = (GenerationSettingsAccessor) generationSettings;
|
||||
|
||||
|
@ -301,13 +299,6 @@ public class BiomeModificationContextImpl implements BiomeModificationContext {
|
|||
accessor.fabric_setFlowerFeatures(ImmutableList.copyOf(accessor.fabric_getFlowerFeatures()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSurfaceBuilder(RegistryKey<ConfiguredSurfaceBuilder<?>> surfaceBuilderKey) {
|
||||
// We do not need to delay evaluation of this since the registries are already fully built
|
||||
ConfiguredSurfaceBuilder<?> surfaceBuilder = surfaceBuilders.getOrThrow(surfaceBuilderKey);
|
||||
accessor.fabric_setSurfaceBuilder(() -> surfaceBuilder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeFeature(GenerationStep.Feature step, RegistryKey<ConfiguredFeature<?, ?>> configuredFeatureKey) {
|
||||
ConfiguredFeature<?, ?> configuredFeature = features.getOrThrow(configuredFeatureKey);
|
||||
|
|
|
@ -29,7 +29,6 @@ import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
|||
import net.minecraft.world.gen.chunk.StructuresConfig;
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.gen.surfacebuilder.ConfiguredSurfaceBuilder;
|
||||
|
||||
import net.fabricmc.fabric.api.biome.v1.BiomeSelectionContext;
|
||||
|
||||
|
@ -55,12 +54,6 @@ public class BiomeSelectionContextImpl implements BiomeSelectionContext {
|
|||
return biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<RegistryKey<ConfiguredSurfaceBuilder<?>>> getSurfaceBuilderKey() {
|
||||
Registry<ConfiguredSurfaceBuilder<?>> registry = dynamicRegistries.get(Registry.CONFIGURED_SURFACE_BUILDER_KEY);
|
||||
return registry.getKey(biome.getGenerationSettings().getSurfaceBuilder().get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<RegistryKey<ConfiguredFeature<?, ?>>> getFeatureKey(ConfiguredFeature<?, ?> configuredFeature) {
|
||||
Registry<ConfiguredFeature<?, ?>> registry = dynamicRegistries.get(Registry.CONFIGURED_FEATURE_KEY);
|
||||
|
|
|
@ -23,7 +23,6 @@ import net.minecraft.util.registry.RegistryKey;
|
|||
import net.minecraft.world.gen.carver.ConfiguredCarver;
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.gen.surfacebuilder.ConfiguredSurfaceBuilder;
|
||||
|
||||
/**
|
||||
* Utility class for getting the registry keys of built-in worldgen objects and throwing proper exceptions if they
|
||||
|
@ -34,11 +33,6 @@ public final class BuiltInRegistryKeys {
|
|||
private BuiltInRegistryKeys() {
|
||||
}
|
||||
|
||||
public static RegistryKey<ConfiguredSurfaceBuilder<?>> get(ConfiguredSurfaceBuilder<?> configuredSurfaceBuilder) {
|
||||
return BuiltinRegistries.CONFIGURED_SURFACE_BUILDER.getKey(configuredSurfaceBuilder)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Given surface builder is not built-in: " + configuredSurfaceBuilder));
|
||||
}
|
||||
|
||||
public static RegistryKey<ConfiguredStructureFeature<?, ?>> get(ConfiguredStructureFeature<?, ?> configuredStructure) {
|
||||
return BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE.getKey(configuredStructure)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Given configured structure is not built-in: " + configuredStructure));
|
||||
|
|
|
@ -28,13 +28,9 @@ import net.minecraft.world.biome.GenerationSettings;
|
|||
import net.minecraft.world.gen.GenerationStep;
|
||||
import net.minecraft.world.gen.carver.ConfiguredCarver;
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.gen.surfacebuilder.ConfiguredSurfaceBuilder;
|
||||
|
||||
@Mixin(GenerationSettings.class)
|
||||
public interface GenerationSettingsAccessor {
|
||||
@Accessor("surfaceBuilder")
|
||||
Supplier<ConfiguredSurfaceBuilder<?>> fabric_getSurfaceBuilder();
|
||||
|
||||
@Accessor("carvers")
|
||||
Map<GenerationStep.Carver, List<Supplier<ConfiguredCarver<?>>>> fabric_getCarvers();
|
||||
|
||||
|
@ -44,10 +40,6 @@ public interface GenerationSettingsAccessor {
|
|||
@Accessor("flowerFeatures")
|
||||
List<ConfiguredFeature<?, ?>> fabric_getFlowerFeatures();
|
||||
|
||||
@Accessor("surfaceBuilder")
|
||||
@Mutable
|
||||
void fabric_setSurfaceBuilder(Supplier<ConfiguredSurfaceBuilder<?>> value);
|
||||
|
||||
@Accessor("carvers")
|
||||
@Mutable
|
||||
void fabric_setCarvers(Map<GenerationStep.Carver, List<Supplier<ConfiguredCarver<?>>>> value);
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
|
||||
package net.fabricmc.fabric.test.biome;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.class_6727;
|
||||
import net.minecraft.sound.BiomeMoodSound;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
|
@ -36,11 +35,6 @@ import net.minecraft.world.gen.feature.ConfiguredFeatures;
|
|||
import net.minecraft.world.gen.feature.DefaultBiomeFeatures;
|
||||
import net.minecraft.world.gen.feature.Feature;
|
||||
import net.minecraft.world.gen.feature.FeatureConfig;
|
||||
import net.minecraft.world.gen.surfacebuilder.ConfiguredSurfaceBuilder;
|
||||
import net.minecraft.world.gen.surfacebuilder.ConfiguredSurfaceBuilders;
|
||||
import net.minecraft.world.gen.surfacebuilder.SurfaceBuilder;
|
||||
import net.minecraft.world.gen.surfacebuilder.SurfaceConfig;
|
||||
import net.minecraft.world.gen.surfacebuilder.TernarySurfaceConfig;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.biome.v1.BiomeModifications;
|
||||
|
@ -70,17 +64,14 @@ public class FabricBiomeTest implements ModInitializer {
|
|||
private static final RegistryKey<Biome> TEST_END_MIDLANDS = RegistryKey.of(Registry.BIOME_KEY, new Identifier(MOD_ID, "test_end_midlands"));
|
||||
private static final RegistryKey<Biome> TEST_END_BARRRENS = RegistryKey.of(Registry.BIOME_KEY, new Identifier(MOD_ID, "test_end_barrens"));
|
||||
|
||||
private static BlockState STONE = Blocks.STONE.getDefaultState();
|
||||
private static ConfiguredSurfaceBuilder<TernarySurfaceConfig> TEST_END_SURFACE_BUILDER = registerTestSurfaceBuilder(new Identifier(MOD_ID, "end"), SurfaceBuilder.DEFAULT.withConfig(new TernarySurfaceConfig(STONE, STONE, STONE)));
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
Registry.register(BuiltinRegistries.BIOME, TEST_CRIMSON_FOREST.getValue(), DefaultBiomeCreator.createCrimsonForest());
|
||||
Registry.register(BuiltinRegistries.BIOME, TEST_CRIMSON_FOREST.getValue(), class_6727.method_39149());
|
||||
|
||||
NetherBiomes.addNetherBiome(BiomeKeys.THE_END, MultiNoiseUtil.createNoiseValuePoint(0.0F, 0.5F, 0.0F, 0.0F, 0.0f, 0.1F));
|
||||
NetherBiomes.addNetherBiome(TEST_CRIMSON_FOREST, MultiNoiseUtil.createNoiseValuePoint(0.0F, 0.5F, 0.0F, 0.0F, 0.0f, 0.275F));
|
||||
|
||||
Registry.register(BuiltinRegistries.BIOME, CUSTOM_PLAINS.getValue(), DefaultBiomeCreator.createPlains(false));
|
||||
Registry.register(BuiltinRegistries.BIOME, CUSTOM_PLAINS.getValue(), DefaultBiomeCreator.createPlains(false, false, false));
|
||||
|
||||
Registry.register(BuiltinRegistries.BIOME, TEST_END_HIGHLANDS.getValue(), createEndHighlands());
|
||||
Registry.register(BuiltinRegistries.BIOME, TEST_END_MIDLANDS.getValue(), createEndMidlands());
|
||||
|
@ -107,13 +98,6 @@ public class FabricBiomeTest implements ModInitializer {
|
|||
.add(ModificationPhase.ADDITIONS,
|
||||
BiomeSelectors.foundInOverworld(),
|
||||
modification -> modification.getWeather().setDownfall(100))
|
||||
.add(ModificationPhase.ADDITIONS,
|
||||
BiomeSelectors.foundInOverworld().and(BiomeSelectors.excludeByKey(BiomeKeys.PLAINS)).and(
|
||||
context -> context.hasBuiltInSurfaceBuilder(ConfiguredSurfaceBuilders.GRASS)
|
||||
),
|
||||
context -> {
|
||||
context.getGenerationSettings().setBuiltInSurfaceBuilder(ConfiguredSurfaceBuilders.CRIMSON_FOREST);
|
||||
})
|
||||
.add(ModificationPhase.ADDITIONS,
|
||||
BiomeSelectors.categories(Biome.Category.DESERT),
|
||||
context -> {
|
||||
|
@ -128,20 +112,19 @@ public class FabricBiomeTest implements ModInitializer {
|
|||
|
||||
// These are used for testing the spacing of custom end biomes.
|
||||
private static Biome createEndHighlands() {
|
||||
GenerationSettings.Builder builder = (new GenerationSettings.Builder()).surfaceBuilder(TEST_END_SURFACE_BUILDER)
|
||||
GenerationSettings.Builder builder = (new GenerationSettings.Builder())
|
||||
.feature(GenerationStep.Feature.SURFACE_STRUCTURES, ConfiguredFeatures.END_GATEWAY)
|
||||
.feature(GenerationStep.Feature.VEGETAL_DECORATION, ConfiguredFeatures.CHORUS_PLANT);
|
||||
return composeEndSpawnSettings(builder);
|
||||
}
|
||||
|
||||
public static Biome createEndMidlands() {
|
||||
GenerationSettings.Builder builder = (new GenerationSettings.Builder())
|
||||
.surfaceBuilder(TEST_END_SURFACE_BUILDER);
|
||||
GenerationSettings.Builder builder = (new GenerationSettings.Builder());
|
||||
return composeEndSpawnSettings(builder);
|
||||
}
|
||||
|
||||
public static Biome createEndBarrens() {
|
||||
GenerationSettings.Builder builder = (new GenerationSettings.Builder()).surfaceBuilder(TEST_END_SURFACE_BUILDER);
|
||||
GenerationSettings.Builder builder = (new GenerationSettings.Builder());
|
||||
return composeEndSpawnSettings(builder);
|
||||
}
|
||||
|
||||
|
@ -150,8 +133,4 @@ public class FabricBiomeTest implements ModInitializer {
|
|||
DefaultBiomeFeatures.addEndMobs(builder2);
|
||||
return (new Biome.Builder()).precipitation(Biome.Precipitation.NONE).category(Biome.Category.THEEND).temperature(0.5F).downfall(0.5F).effects((new BiomeEffects.Builder()).waterColor(4159204).waterFogColor(329011).fogColor(10518688).skyColor(0).moodSound(BiomeMoodSound.CAVE).build()).spawnSettings(builder2.build()).generationSettings(builder.build()).build();
|
||||
}
|
||||
|
||||
private static <SC extends SurfaceConfig> ConfiguredSurfaceBuilder<SC> registerTestSurfaceBuilder(Identifier id, ConfiguredSurfaceBuilder<SC> configuredSurfaceBuilder) {
|
||||
return BuiltinRegistries.add(BuiltinRegistries.CONFIGURED_SURFACE_BUILDER, id, configuredSurfaceBuilder);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
archivesBaseName = "fabric-registry-sync-v0"
|
||||
version = getSubprojectVersion(project, "0.7.13")
|
||||
version = getSubprojectVersion(project, "0.8.0")
|
||||
|
||||
moduleDependencies(project, [
|
||||
'fabric-api-base',
|
||||
|
|
|
@ -60,9 +60,6 @@ public class FabricRegistryInit implements ModInitializer {
|
|||
// Doesnt seem to be accessed apart from registering?
|
||||
RegistryAttributeHolder.get(Registry.CARVER);
|
||||
|
||||
// Doesnt seem to be accessed apart from registering?
|
||||
RegistryAttributeHolder.get(Registry.SURFACE_BUILDER);
|
||||
|
||||
// Serialised by string, doesnt seem to be synced
|
||||
RegistryAttributeHolder.get(Registry.FEATURE);
|
||||
|
||||
|
|
|
@ -1,216 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.impl.registry.sync;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.DynamicRegistryManager;
|
||||
import net.minecraft.util.registry.MutableRegistry;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
/**
|
||||
* This solves a bug in vanilla where datapack added biome IDs are not saved to disk. Thus adding or changing a biome
|
||||
* from a datapack/mod causes the ids to shift. This remaps the IDs in the {@link DynamicRegistryManager} in a similar
|
||||
* manner to the normal registry sync.
|
||||
*
|
||||
* <p>See: https://bugs.mojang.com/browse/MC-202036
|
||||
*
|
||||
* <p>This may cause issues when vanilla adds biomes in the future, this should be fixable by also remapping the static ID
|
||||
* map vanilla keeps.
|
||||
*/
|
||||
public class PersistentDynamicRegistryHandler {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
public static void remapDynamicRegistries(DynamicRegistryManager.Impl dynamicRegistryManager, Path saveDir) {
|
||||
LOGGER.debug("Starting registry remap");
|
||||
|
||||
NbtCompound registryData;
|
||||
|
||||
try {
|
||||
registryData = remapDynamicRegistries(dynamicRegistryManager, readCompoundTag(getDataPath(saveDir)));
|
||||
} catch (RemapException | IOException e) {
|
||||
throw new RuntimeException("Failed to read dynamic registry data", e);
|
||||
}
|
||||
|
||||
writeCompoundTag(registryData, getDataPath(saveDir));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static NbtCompound remapDynamicRegistries(DynamicRegistryManager.Impl dynamicRegistryManager, @Nullable NbtCompound existingTag) throws RemapException {
|
||||
NbtCompound registries = new NbtCompound();
|
||||
|
||||
// For now we only care about biomes, but lets keep our options open
|
||||
NbtCompound biomeRegistryData = null;
|
||||
|
||||
if (existingTag != null) {
|
||||
biomeRegistryData = existingTag.getCompound(Registry.BIOME_KEY.getValue().toString());
|
||||
}
|
||||
|
||||
MutableRegistry<?> registry = (MutableRegistry<?>) dynamicRegistryManager.get(Registry.BIOME_KEY);
|
||||
NbtCompound biomeIdMap = remapRegistry(Registry.BIOME_KEY.getValue(), registry, biomeRegistryData);
|
||||
registries.put(Registry.BIOME_KEY.getValue().toString(), biomeIdMap);
|
||||
|
||||
return registries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remaps a registry if existing data is passed in.
|
||||
* Then writes out the ids in the registry (remapped or a new world).
|
||||
* Keeps hold of the orphaned registry entries as to not overwrite them.
|
||||
*/
|
||||
private static <T> NbtCompound remapRegistry(Identifier registryId, MutableRegistry<T> registry, @Nullable NbtCompound existingTag) throws RemapException {
|
||||
if (!(registry instanceof RemappableRegistry)) {
|
||||
throw new UnsupportedOperationException("Cannot remap un re-mappable registry: " + registryId.toString());
|
||||
}
|
||||
|
||||
// This includes biomes added via datapacks via the vanilla method, along with mod provided biomes.
|
||||
boolean isModified = registry.getIds().stream().anyMatch(id -> !id.getNamespace().equals("minecraft"));
|
||||
|
||||
// The current registry might not be modified, but we might have previous changed vanilla ids that we should try and remap
|
||||
if (existingTag != null && !isModified) {
|
||||
isModified = existingTag.getKeys().stream()
|
||||
.map(existingTag::getString)
|
||||
.map(Identifier::new)
|
||||
.anyMatch(id -> !id.getNamespace().equals("minecraft"));
|
||||
}
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
if (existingTag == null) {
|
||||
LOGGER.debug("No existing data found, assuming new registry with {} entries. modded = {}", registry.getIds().size(), isModified);
|
||||
} else {
|
||||
LOGGER.debug("Existing registry data found. modded = {}", isModified);
|
||||
|
||||
for (T entry : registry) {
|
||||
//noinspection unchecked
|
||||
Identifier id = registry.getId(entry);
|
||||
int rawId = registry.getRawId(entry);
|
||||
|
||||
if (id == null || rawId < 0) continue;
|
||||
|
||||
if (existingTag.getKeys().contains(id.toString())) {
|
||||
int existingRawId = existingTag.getInt(id.toString());
|
||||
|
||||
if (rawId != existingRawId) {
|
||||
LOGGER.debug("Remapping {} {} -> {}", id.toString(), rawId, existingRawId);
|
||||
} else {
|
||||
LOGGER.debug("Using existing id for {} {}", id.toString(), rawId);
|
||||
}
|
||||
} else {
|
||||
LOGGER.debug("Found new registry entry {}", id.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we have some existing ids and the registry contains modded/datapack entries we remap the registry with those
|
||||
if (existingTag != null && isModified) {
|
||||
LOGGER.debug("Remapping {} with {} entries", registryId, registry.getIds().size());
|
||||
Object2IntMap<Identifier> idMap = new Object2IntOpenHashMap<>();
|
||||
|
||||
for (String key : existingTag.getKeys()) {
|
||||
idMap.put(new Identifier(key), existingTag.getInt(key));
|
||||
}
|
||||
|
||||
((RemappableRegistry) registry).remap(registryId.toString(), idMap, RemappableRegistry.RemapMode.AUTHORITATIVE);
|
||||
} else {
|
||||
LOGGER.debug("Skipping remap of {}", registryId);
|
||||
}
|
||||
|
||||
// Now start to build up what we are going to save out
|
||||
NbtCompound registryTag = new NbtCompound();
|
||||
|
||||
// Save all ids as they appear in the remapped, or new registry to disk even if not modded.
|
||||
for (T entry : registry) {
|
||||
//noinspection unchecked
|
||||
Identifier id = registry.getId(entry);
|
||||
|
||||
if (id == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int rawId = registry.getRawId(entry);
|
||||
registryTag.putInt(id.toString(), rawId);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for existing registry key/values that are not in the current registries.
|
||||
* This can happen when registry entries are removed, preventing that ID from being re-used by something else.
|
||||
*/
|
||||
if (existingTag != null) {
|
||||
for (String key : existingTag.getKeys()) {
|
||||
if (!registryTag.contains(key)) {
|
||||
LOGGER.debug("Saving orphaned registry entry: " + key);
|
||||
registryTag.putInt(key, existingTag.getInt(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return registryTag;
|
||||
}
|
||||
|
||||
private static Path getDataPath(Path saveDir) {
|
||||
return saveDir.resolve("data").resolve("fabricDynamicRegistry.dat");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static NbtCompound readCompoundTag(Path path) throws IOException {
|
||||
if (!Files.exists(path)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try (InputStream inputStream = Files.newInputStream(path)) {
|
||||
NbtCompound compoundTag = NbtIo.readCompressed(inputStream);
|
||||
|
||||
if (!compoundTag.contains("version") || !compoundTag.contains("registries") || compoundTag.getInt("version") != 1) {
|
||||
throw new UnsupportedOperationException("Unsupported dynamic registry data format. Try updating?");
|
||||
}
|
||||
|
||||
return compoundTag.getCompound("registries");
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeCompoundTag(NbtCompound compoundTag, Path path) {
|
||||
try {
|
||||
Files.createDirectories(path.getParent());
|
||||
|
||||
try (OutputStream outputStream = Files.newOutputStream(path, StandardOpenOption.CREATE)) {
|
||||
NbtCompound outputTag = new NbtCompound();
|
||||
outputTag.putInt("version", 1);
|
||||
outputTag.put("registries", compoundTag);
|
||||
|
||||
NbtIo.writeCompressed(outputTag, outputStream);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.registry.sync;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import com.mojang.serialization.DynamicOps;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import net.minecraft.server.Main;
|
||||
import net.minecraft.util.dynamic.RegistryOps;
|
||||
import net.minecraft.util.registry.DynamicRegistryManager;
|
||||
import net.minecraft.world.level.storage.LevelStorage;
|
||||
import net.minecraft.nbt.NbtElement;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
|
||||
import net.fabricmc.fabric.impl.registry.sync.PersistentDynamicRegistryHandler;
|
||||
|
||||
@Mixin(Main.class)
|
||||
public class MixinMain {
|
||||
@Unique
|
||||
private static Path fabric_saveDir;
|
||||
|
||||
@Redirect(method = "main", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/storage/LevelStorage;createSession(Ljava/lang/String;)Lnet/minecraft/world/level/storage/LevelStorage$Session;"))
|
||||
private static LevelStorage.Session levelStorageCreateSession(LevelStorage levelStorage, String levelName) throws IOException {
|
||||
LevelStorage.Session session = levelStorage.createSession(levelName);
|
||||
fabric_saveDir = ((AccessorLevelStorageSession) session).getDirectory();
|
||||
return session;
|
||||
}
|
||||
|
||||
@Redirect(method = "main", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/dynamic/RegistryOps;ofLoaded(Lcom/mojang/serialization/DynamicOps;Lnet/minecraft/resource/ResourceManager;Lnet/minecraft/util/registry/DynamicRegistryManager;)Lnet/minecraft/util/dynamic/RegistryOps;"))
|
||||
private static RegistryOps<NbtElement> ofRegistryOps(DynamicOps<NbtElement> delegate, ResourceManager resourceManager, DynamicRegistryManager impl) {
|
||||
RegistryOps<NbtElement> registryOps = RegistryOps.ofLoaded(delegate, resourceManager, impl);
|
||||
PersistentDynamicRegistryHandler.remapDynamicRegistries((DynamicRegistryManager.Impl) impl, fabric_saveDir);
|
||||
return registryOps;
|
||||
}
|
||||
}
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
package net.fabricmc.fabric.mixin.registry.sync.client;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
@ -25,20 +23,10 @@ import org.spongepowered.asm.mixin.Unique;
|
|||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.resource.DataPackSettings;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.util.registry.DynamicRegistryManager;
|
||||
import net.minecraft.world.SaveProperties;
|
||||
import net.minecraft.world.gen.GeneratorOptions;
|
||||
import net.minecraft.world.level.LevelInfo;
|
||||
import net.minecraft.world.level.storage.LevelStorage;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
|
||||
import net.fabricmc.fabric.impl.registry.sync.PersistentDynamicRegistryHandler;
|
||||
import net.fabricmc.fabric.mixin.registry.sync.AccessorLevelStorageSession;
|
||||
import net.fabricmc.fabric.impl.registry.sync.RegistrySyncManager;
|
||||
import net.fabricmc.fabric.impl.registry.sync.RemapException;
|
||||
|
||||
|
@ -56,17 +44,4 @@ public class MixinMinecraftClient {
|
|||
FABRIC_LOGGER.warn("Failed to unmap Fabric registries!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "createSaveProperties", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/util/dynamic/RegistryOps;ofLoaded(Lcom/mojang/serialization/DynamicOps;Lnet/minecraft/resource/ResourceManager;Lnet/minecraft/util/registry/DynamicRegistryManager;)Lnet/minecraft/util/dynamic/RegistryOps;"))
|
||||
private static void createSaveProperties(LevelStorage.Session session, DynamicRegistryManager.Impl impl, ResourceManager resourceManager, DataPackSettings dataPackSettings, CallbackInfoReturnable<SaveProperties> cir) {
|
||||
Path saveDir = ((AccessorLevelStorageSession) session).getDirectory();
|
||||
PersistentDynamicRegistryHandler.remapDynamicRegistries(impl, saveDir);
|
||||
}
|
||||
|
||||
// synthetic in method_29607 just after RegistryOps.of
|
||||
@Inject(method = "method_31125", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/util/dynamic/RegistryOps;ofLoaded(Lcom/mojang/serialization/DynamicOps;Lnet/minecraft/resource/ResourceManager;Lnet/minecraft/util/registry/DynamicRegistryManager;)Lnet/minecraft/util/dynamic/RegistryOps;"))
|
||||
private static void method_31125(DynamicRegistryManager.Impl impl, GeneratorOptions generatorOptions, LevelInfo levelInfo, LevelStorage.Session session, DynamicRegistryManager.Impl impl2, ResourceManager resourceManager, DataPackSettings dataPackSettings, CallbackInfoReturnable<SaveProperties> cir) {
|
||||
Path saveDir = ((AccessorLevelStorageSession) session).getDirectory();
|
||||
PersistentDynamicRegistryHandler.remapDynamicRegistries(impl, saveDir);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
"MixinDynamicRegistryManager",
|
||||
"MixinIdList",
|
||||
"MixinIdRegistry",
|
||||
"MixinMain",
|
||||
"MixinPlayerManager",
|
||||
"MixinLevelStorageSession",
|
||||
"MixinRegistry",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue