From a3698d5b7e44035fe75be3be0ea03a0a217f5e64 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Mon, 28 Feb 2022 23:21:15 +0100 Subject: [PATCH] Update Datafixer --- .../server/Rewrite-dataconverter-system.patch | 492 ++++++++++++++++-- 1 file changed, 458 insertions(+), 34 deletions(-) diff --git a/patches/server/Rewrite-dataconverter-system.patch b/patches/server/Rewrite-dataconverter-system.patch index 76ac940437..2352bf6643 100644 --- a/patches/server/Rewrite-dataconverter-system.patch +++ b/patches/server/Rewrite-dataconverter-system.patch @@ -214,14 +214,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +package ca.spottedleaf.dataconverter.minecraft; + +import ca.spottedleaf.dataconverter.converters.DataConverter; ++import com.mojang.logging.LogUtils; +import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntLinkedOpenHashSet; +import it.unimi.dsi.fastutil.ints.IntRBTreeSet; +import it.unimi.dsi.fastutil.longs.LongArrayList; +import it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet; -+import org.apache.logging.log4j.LogManager; -+import org.apache.logging.log4j.Logger; ++import org.slf4j.Logger; +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.Comparator; @@ -229,7 +229,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + +public final class MCVersionRegistry { + -+ private static final Logger LOGGER = LogManager.getLogger(); ++ private static final Logger LOGGER = LogUtils.getLogger(); + + protected static final Int2ObjectLinkedOpenHashMap VERSION_NAMES = new Int2ObjectLinkedOpenHashMap<>(); + protected static final IntArrayList VERSION_LIST; @@ -325,6 +325,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + 1906, + 1909, + 1911, ++ 1914, + 1917, + 1918, + 1920, @@ -396,7 +397,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + 2843, + 2846, + 2852, -+ // All up to 1.18-pre6 ++ 2967, ++ 2970 ++ // All up to 1.18.2-pre1 + }; + Arrays.sort(converterVersions); + @@ -939,6 +942,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public static final int V1_18_PRE4 = 2850; + public static final int V1_18_PRE5 = 2851; + public static final int V1_18_PRE6 = 2853; ++ public static final int V1_18_PRE7 = 2854; ++ public static final int V1_18_PRE8 = 2855; ++ public static final int V1_18_RC1 = 2856; ++ public static final int V1_18_RC2 = 2857; ++ public static final int V1_18_RC3 = 2858; ++ public static final int V1_18_RC4 = 2859; ++ public static final int V1_18 = 2860; ++ public static final int V1_18_1_PRE1 = 2861; ++ public static final int V1_18_1_RC1 = 2862; ++ public static final int V1_18_1_RC2 = 2863; ++ public static final int V1_18_1_RC3 = 2864; ++ public static final int V1_18_1 = 2865; ++ public static final int V22W03A = 2966; ++ public static final int V22W05A = 2967; ++ public static final int V22W06A = 2968; ++ public static final int V22W07A = 2969; ++ public static final int V1_18_2_PRE1 = 2971; +} diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/ReplacedDataFixerUpper.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/ReplacedDataFixerUpper.java new file mode 100644 @@ -1216,6 +1236,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import ca.spottedleaf.dataconverter.types.ObjectType; +import ca.spottedleaf.dataconverter.types.Types; +import com.mojang.datafixers.DataFixUtils; ++import com.mojang.logging.LogUtils; +import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; @@ -1223,8 +1244,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import it.unimi.dsi.fastutil.ints.IntIterator; +import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; +import net.minecraft.util.datafix.PackedBitStorage; -+import org.apache.logging.log4j.LogManager; -+import org.apache.logging.log4j.Logger; ++import org.slf4j.Logger; +import java.util.Arrays; +import java.util.BitSet; +import java.util.HashMap; @@ -1236,7 +1256,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + +public final class ConverterFlattenChunk extends DataConverter, MapType> { + -+ private static final Logger LOGGER = LogManager.getLogger(); ++ private static final Logger LOGGER = LogUtils.getLogger(); + + static final BitSet VIRTUAL_SET = new BitSet(256); + static final BitSet IDS_NEEDING_FIX_SET = new BitSet(256); @@ -5301,9 +5321,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import ca.spottedleaf.dataconverter.minecraft.MCVersions; +import ca.spottedleaf.dataconverter.types.MapType; +import ca.spottedleaf.dataconverter.types.Types; -+import org.apache.logging.log4j.LogManager; -+import org.apache.logging.log4j.Logger; -+ ++import com.mojang.logging.LogUtils; ++import org.slf4j.Logger; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; @@ -5312,7 +5331,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + +public final class ConverterFlattenItemStack extends DataConverter, MapType> { + -+ private static final Logger LOGGER = LogManager.getLogger(); ++ private static final Logger LOGGER = LogUtils.getLogger(); + + // Map of "id.damage" -> "flattened id" + private static final Map FLATTEN_MAP = new HashMap<>(); @@ -6503,6 +6522,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import ca.spottedleaf.dataconverter.minecraft.versions.V1905; +import ca.spottedleaf.dataconverter.minecraft.versions.V1906; +import ca.spottedleaf.dataconverter.minecraft.versions.V1911; ++import ca.spottedleaf.dataconverter.minecraft.versions.V1914; +import ca.spottedleaf.dataconverter.minecraft.versions.V1917; +import ca.spottedleaf.dataconverter.minecraft.versions.V1918; +import ca.spottedleaf.dataconverter.minecraft.versions.V1920; @@ -6572,6 +6592,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import ca.spottedleaf.dataconverter.minecraft.versions.V2843; +import ca.spottedleaf.dataconverter.minecraft.versions.V2846; +import ca.spottedleaf.dataconverter.minecraft.versions.V2852; ++import ca.spottedleaf.dataconverter.minecraft.versions.V2967; ++import ca.spottedleaf.dataconverter.minecraft.versions.V2970; +import ca.spottedleaf.dataconverter.minecraft.versions.V501; +import ca.spottedleaf.dataconverter.minecraft.versions.V502; +import ca.spottedleaf.dataconverter.minecraft.versions.V505; @@ -6588,9 +6610,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import ca.spottedleaf.dataconverter.minecraft.versions.V816; +import ca.spottedleaf.dataconverter.minecraft.versions.V820; +import ca.spottedleaf.dataconverter.minecraft.versions.V99; ++import com.mojang.logging.LogUtils; ++import org.slf4j.Logger; + +public final class MCTypeRegistry { + ++ private static final Logger LOGGER = LogUtils.getLogger(); ++ + public static final MCDataType LEVEL = new MCDataType("Level"); + public static final MCDataType PLAYER = new MCDataType("Player"); + public static final MCDataType CHUNK = new MCDataType("Chunk"); @@ -6618,6 +6644,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public static final MCDataType WORLD_GEN_SETTINGS = new MCDataType("WorldGenSettings"); + + static { ++ try { ++ registerAll(); ++ } catch (final ThreadDeath thr) { ++ throw thr; ++ } catch (final Throwable thr) { ++ LOGGER.error(LogUtils.FATAL_MARKER, "Failed to register data converters", thr); ++ throw new RuntimeException(thr); ++ } ++ } ++ ++ private static void registerAll() { + // General notes: + // - Structure converters run before everything. + // - ID specific converters run after structure converters. @@ -6703,6 +6740,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + V1906.register(); + // V1909 is just adding a simple block entity (jigsaw) + V1911.register(); ++ V1914.register(); + V1917.register(); + V1918.register(); + V1920.register(); @@ -6782,6 +6820,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + V2843.register(); + V2846.register(); + V2852.register(); ++ V2967.register(); ++ V2970.register(); + } + + private MCTypeRegistry() {} @@ -7204,12 +7244,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import ca.spottedleaf.dataconverter.types.ObjectType; +import ca.spottedleaf.dataconverter.types.MapType; +import ca.spottedleaf.dataconverter.types.Types; -+import org.apache.logging.log4j.LogManager; -+import org.apache.logging.log4j.Logger; ++import com.mojang.logging.LogUtils; ++import org.slf4j.Logger; + +public final class V102 { + -+ private static final Logger LOGGER = LogManager.getLogger(); ++ private static final Logger LOGGER = LogUtils.getLogger(); + + protected static final int VERSION = MCVersions.V15W32A + 2; + @@ -7540,13 +7580,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import ca.spottedleaf.dataconverter.minecraft.MCVersions; +import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; +import ca.spottedleaf.dataconverter.types.MapType; -+import org.apache.logging.log4j.LogManager; -+import org.apache.logging.log4j.Logger; ++import com.mojang.logging.LogUtils; ++import org.slf4j.Logger; ++ +import java.util.UUID; + +public final class V108 { + -+ private static final Logger LOGGER = LogManager.getLogger(); ++ private static final Logger LOGGER = LogUtils.getLogger(); + + protected static final int VERSION = MCVersions.V15W32C + 4; + @@ -10935,13 +10976,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import ca.spottedleaf.dataconverter.types.ListType; +import ca.spottedleaf.dataconverter.types.MapType; +import ca.spottedleaf.dataconverter.types.ObjectType; ++import com.mojang.logging.LogUtils; +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; -+import org.apache.logging.log4j.LogManager; -+import org.apache.logging.log4j.Logger; ++import org.slf4j.Logger; + +public final class V1624 { + -+ private static final Logger LOGGER = LogManager.getLogger(); ++ private static final Logger LOGGER = LogUtils.getLogger(); + + protected static final int VERSION = MCVersions.V18W32A + 1; + @@ -11445,6 +11486,39 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + +} +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V1914.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V1914.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V1914.java +@@ -0,0 +0,0 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V1914 { ++ ++ protected static final int VERSION = MCVersions.V18W48A; ++ ++ public static void register() { ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:chest", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String lootTable = data.getString("LootTable"); ++ ++ if ("minecraft:chests/village_blacksmith".equals(lootTable)) { ++ data.setString("LootTable", "minecraft:chests/village/village_weaponsmith"); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++} diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V1917.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V1917.java new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 @@ -15328,12 +15402,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import ca.spottedleaf.dataconverter.types.MapType; +import ca.spottedleaf.dataconverter.types.ObjectType; +import ca.spottedleaf.dataconverter.types.Types; ++import com.mojang.logging.LogUtils; +import it.unimi.dsi.fastutil.ints.Int2IntLinkedOpenHashMap; +import it.unimi.dsi.fastutil.ints.IntIterator; +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; +import org.apache.commons.lang3.mutable.MutableBoolean; -+import org.apache.logging.log4j.LogManager; -+import org.apache.logging.log4j.Logger; ++import org.slf4j.Logger; +import java.util.Arrays; +import java.util.BitSet; +import java.util.HashSet; @@ -15341,7 +15415,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + +public final class V2832 { + -+ protected static final Logger LOGGER = LogManager.getLogger(); ++ private static final Logger LOGGER = LogUtils.getLogger(); + + protected static final int VERSION = MCVersions.V1_17_1 + 102; + @@ -15600,7 +15674,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + try { + section.setLongs("BlockStates", resize(blockStates, gotBits, expectedBits)); + } catch (final Exception ex) { -+ LOGGER.fatal("Failed to rewrite mismatched palette and data storage for section y: " + sectionY ++ LOGGER.error("Failed to rewrite mismatched palette and data storage for section y: " + sectionY + + " for chunk [" + chunkX + "," + chunkZ + "], palette entries: " + palette.size() + ", data storage size: " + + blockStates.length, + ex @@ -16636,9 +16710,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ +package ca.spottedleaf.dataconverter.minecraft.versions; + ++import ca.spottedleaf.dataconverter.converters.DataConverter; +import ca.spottedleaf.dataconverter.minecraft.MCVersions; +import ca.spottedleaf.dataconverter.minecraft.converters.helpers.ConverterAbstractStringValueTypeRename; +import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.Types; +import java.util.Map; + +public final class V2843 { @@ -16647,6 +16727,90 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + public static void register() { + ConverterAbstractStringValueTypeRename.register(VERSION, MCTypeRegistry.BIOME, Map.of("minecraft:deep_warm_ocean", "minecraft:warm_ocean")::get); ++ ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ private static void moveOutOfBoundTicks(final ListType ticks, final MapType chunkRoot, final int chunkX, final int chunkZ, final String intoKey) { ++ if (ticks == null) { ++ return; ++ } ++ ++ ListType outOfBounds = null; ++ for (int i = 0, len = ticks.size(); i < len; ++i) { ++ final MapType tick = ticks.getMap(i); ++ final int x = tick.getInt("x"); ++ final int z = tick.getInt("z"); ++ // anything > 1 is lost, anything less than 1 stays. ++ if (Math.max(Math.abs(chunkX - (x >> 4)), Math.abs(chunkZ - (z >> 4))) == 1) { ++ // DFU doesn't remove, so neither do we. ++ if (outOfBounds == null) { ++ outOfBounds = Types.NBT.createEmptyList(); ++ } ++ outOfBounds.addMap(tick); ++ } ++ } ++ ++ if (outOfBounds != null) { ++ MapType upgradeData = chunkRoot.getMap("UpgradeData"); ++ if (upgradeData == null) { ++ chunkRoot.setMap("UpgradeData", upgradeData = Types.NBT.createEmptyMap()); ++ } ++ upgradeData.setList(intoKey, outOfBounds); ++ } ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ // After renames, so use new names ++ final int x = data.getInt("xPos"); ++ final int z = data.getInt("zPos"); ++ ++ moveOutOfBoundTicks(data.getList("block_ticks", ObjectType.MAP), data, x, z, "neighbor_block_ticks"); ++ moveOutOfBoundTicks(data.getList("fluid_ticks", ObjectType.MAP), data, x, z, "neighbor_fluid_ticks"); ++ ++ return null; ++ } ++ }); ++ ++ // DFU is missing schema for UpgradeData block names ++ MCTypeRegistry.CHUNK.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertList(MCTypeRegistry.ENTITY, data, "entities", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.TILE_ENTITY, data, "block_entities", fromVersion, toVersion); ++ ++ final ListType blockTicks = data.getList("block_ticks", ObjectType.MAP); ++ if (blockTicks != null) { ++ for (int i = 0, len = blockTicks.size(); i < len; ++i) { ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_NAME, blockTicks.getMap(i), "i", fromVersion, toVersion); ++ } ++ } ++ ++ final MapType upgradeData = data.getMap("UpgradeData"); ++ if (upgradeData != null) { ++ // Even though UpgradeData will retrieve the block from the World when the type no longer exists, ++ // the type from the world may not match what was actually queued. So, even though it may look like we ++ // can skip the walker here, we actually don't if we want to be thorough. ++ final ListType neighbourBlockTicks = upgradeData.getList("neighbor_block_ticks", ObjectType.MAP); ++ if (neighbourBlockTicks != null) { ++ for (int i = 0, len = neighbourBlockTicks.size(); i < len; ++i) { ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_NAME, neighbourBlockTicks.getMap(i), "i", fromVersion, toVersion); ++ } ++ } ++ } ++ ++ final ListType sections = data.getList("sections", ObjectType.MAP); ++ if (sections != null) { ++ for (int i = 0, len = sections.size(); i < len; ++i) { ++ final MapType section = sections.getMap(i); ++ ++ WalkerUtils.convertList(MCTypeRegistry.BIOME, section.getMap("biomes"), "palette", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, section.getMap("block_states"), "palette", fromVersion, toVersion); ++ } ++ } ++ ++ WalkerUtils.convertValues(MCTypeRegistry.STRUCTURE_FEATURE, data.getMap("structures"), "starts", fromVersion, toVersion); ++ ++ return null; ++ }); ++ + } +} diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V2846.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V2846.java @@ -16708,6 +16872,266 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + }); + } +} +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V2967.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V2967.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V2967.java +@@ -0,0 +0,0 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V2967 { ++ ++ protected static final int VERSION = MCVersions.V22W05A; ++ ++ public static void register() { ++ MCTypeRegistry.WORLD_GEN_SETTINGS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType dimensions = data.getMap("dimensions"); ++ ++ if (dimensions == null) { ++ return null; ++ } ++ ++ for (final String dimension : dimensions.keys()) { ++ final MapType dimensionData = dimensions.getMap(dimension); ++ if (dimensionData == null) { ++ continue; ++ } ++ ++ final MapType generator = dimensionData.getMap("generator"); ++ if (generator == null) { ++ continue; ++ } ++ ++ final MapType settings = generator.getMap("settings"); ++ if (settings == null) { ++ continue; ++ } ++ ++ final MapType structures = settings.getMap("structures"); ++ if (structures == null) { ++ continue; ++ } ++ ++ for (final String structureKey : structures.keys()) { ++ structures.getMap(structureKey).setString("type", "minecraft:random_spread"); ++ } ++ ++ final MapType stronghold = structures.getMap("stronghold"); ++ stronghold.setString("type", "minecraft:concentric_rings"); ++ structures.setMap("minecraft:stronghold", stronghold.copy()); ++ } ++ ++ return null; ++ } ++ }); ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V2970.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V2970.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V2970.java +@@ -0,0 +0,0 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.Types; ++import com.google.common.collect.ImmutableMap; ++import it.unimi.dsi.fastutil.objects.Object2IntMap; ++import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; ++import java.util.HashMap; ++import java.util.Iterator; ++import java.util.List; ++import java.util.Locale; ++import java.util.Map; ++ ++public final class V2970 { ++ ++ protected static final int VERSION = MCVersions.V22W07A + 1; ++ private static final Map CONVERSION_MAP = new HashMap<>( ++ ImmutableMap.builder() ++ .put("mineshaft", BiomeRemap.create(Map.of(List.of("minecraft:badlands", "minecraft:eroded_badlands", "minecraft:wooded_badlands"), "minecraft:mineshaft_mesa"), "minecraft:mineshaft")) ++ .put("shipwreck", BiomeRemap.create(Map.of(List.of("minecraft:beach", "minecraft:snowy_beach"), "minecraft:shipwreck_beached"), "minecraft:shipwreck")) ++ .put("ocean_ruin", BiomeRemap.create(Map.of(List.of("minecraft:warm_ocean", "minecraft:lukewarm_ocean", "minecraft:deep_lukewarm_ocean"), "minecraft:ocean_ruin_warm"), "minecraft:ocean_ruin_cold")) ++ .put("village", BiomeRemap.create(Map.of(List.of("minecraft:desert"), "minecraft:village_desert", List.of("minecraft:savanna"), "minecraft:village_savanna", List.of("minecraft:snowy_plains"), "minecraft:village_snowy", List.of("minecraft:taiga"), "minecraft:village_taiga"), "minecraft:village_plains")) ++ .put("ruined_portal", BiomeRemap.create(Map.of(List.of("minecraft:desert"), "minecraft:ruined_portal_desert", List.of("minecraft:badlands", "minecraft:eroded_badlands", "minecraft:wooded_badlands", "minecraft:windswept_hills", "minecraft:windswept_forest", "minecraft:windswept_gravelly_hills", "minecraft:savanna_plateau", "minecraft:windswept_savanna", "minecraft:stony_shore", "minecraft:meadow", "minecraft:frozen_peaks", "minecraft:jagged_peaks", "minecraft:stony_peaks", "minecraft:snowy_slopes"), "minecraft:ruined_portal_mountain", List.of("minecraft:bamboo_jungle", "minecraft:jungle", "minecraft:sparse_jungle"), "minecraft:ruined_portal_jungle", List.of("minecraft:deep_frozen_ocean", "minecraft:deep_cold_ocean", "minecraft:deep_ocean", "minecraft:deep_lukewarm_ocean", "minecraft:frozen_ocean", "minecraft:ocean", "minecraft:cold_ocean", "minecraft:lukewarm_ocean", "minecraft:warm_ocean"), "minecraft:ruined_portal_ocean"), "minecraft:ruined_portal")) // Fix MC-248814, ruined_portal_standard->ruined_portal ++ .put("pillager_outpost", BiomeRemap.create("minecraft:pillager_outpost")) ++ .put("mansion", BiomeRemap.create("minecraft:mansion")) ++ .put("jungle_pyramid", BiomeRemap.create("minecraft:jungle_pyramid")) ++ .put("desert_pyramid", BiomeRemap.create("minecraft:desert_pyramid")) ++ .put("igloo", BiomeRemap.create("minecraft:igloo")) ++ .put("swamp_hut", BiomeRemap.create("minecraft:swamp_hut")) ++ .put("stronghold", BiomeRemap.create("minecraft:stronghold")) ++ .put("monument", BiomeRemap.create("minecraft:monument")) ++ .put("fortress", BiomeRemap.create("minecraft:fortress")) ++ .put("endcity", BiomeRemap.create("minecraft:end_city")) ++ .put("buried_treasure", BiomeRemap.create("minecraft:buried_treasure")) ++ .put("nether_fossil", BiomeRemap.create("minecraft:nether_fossil")) ++ .put("bastion_remnant", BiomeRemap.create("minecraft:bastion_remnant")) ++ .build() ++ ); ++ ++ public static void register() { ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ private static Object2IntOpenHashMap countBiomes(final MapType chunk) { ++ final ListType sections = chunk.getList("sections", ObjectType.MAP); ++ if (sections == null) { ++ return null; ++ } ++ ++ final Object2IntOpenHashMap ret = new Object2IntOpenHashMap<>(); ++ ++ for (int i = 0, len = sections.size(); i < len; ++i) { ++ final MapType section = sections.getMap(i); ++ ++ final MapType biomes = section.getMap("biomes"); ++ ++ if (biomes == null) { ++ continue; ++ } ++ ++ final ListType palette = biomes.getList("palette", ObjectType.STRING); ++ ++ if (palette == null) { ++ continue; ++ } ++ ++ for (int k = 0, len2 = palette.size(); k < len2; ++k) { ++ ret.addTo(palette.getString(k), 1); ++ } ++ } ++ ++ return ret; ++ } ++ ++ private static String getStructureConverted(String id, final Object2IntOpenHashMap biomeCount) { ++ id = id.toLowerCase(Locale.ROOT); ++ final BiomeRemap remap = CONVERSION_MAP.get(id); ++ if (remap == null) { ++ throw new IllegalArgumentException("Unknown structure " + id); ++ } ++ if (remap.biomeToNewStructure == null || biomeCount == null) { ++ return remap.dfl; ++ } ++ ++ final Object2IntOpenHashMap remapCount = new Object2IntOpenHashMap<>(); ++ ++ for (final Iterator> iterator = biomeCount.object2IntEntrySet().fastIterator(); iterator.hasNext();) { ++ final Object2IntMap.Entry entry = iterator.next(); ++ final String remappedStructure = remap.biomeToNewStructure.get(entry.getKey()); ++ if (remappedStructure != null) { ++ remapCount.addTo(remappedStructure, entry.getIntValue()); ++ } ++ } ++ ++ String converted = remap.dfl; ++ int maxCount = 0; ++ ++ for (final Iterator> iterator = remapCount.object2IntEntrySet().fastIterator(); iterator.hasNext();) { ++ final Object2IntMap.Entry entry = iterator.next(); ++ final int count = entry.getIntValue(); ++ if (count > maxCount) { ++ maxCount = count; ++ converted = entry.getKey(); ++ } ++ } ++ ++ return converted; ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType structures = data.getMap("structures"); ++ if (structures == null || structures.isEmpty()) { ++ return null; ++ } ++ ++ final Object2IntOpenHashMap biomeCounts = countBiomes(data); ++ ++ final MapType starts = structures.getMap("starts"); ++ final MapType references = structures.getMap("References"); ++ ++ if (starts != null) { ++ final MapType newStarts = Types.NBT.createEmptyMap(); ++ structures.setMap("starts", newStarts); ++ ++ for (final String key : starts.keys()) { ++ final MapType value = starts.getMap(key); ++ if ("INVALID".equals(value.getString("id", "INVALID"))) { ++ continue; ++ } ++ ++ final String remapped = getStructureConverted(key, biomeCounts); ++ value.setString("id", remapped); ++ newStarts.setMap(remapped, value); ++ } ++ } ++ ++ // This TRULY is a guess, no idea what biomes the referent has. ++ if (references != null) { ++ final MapType newReferences = Types.NBT.createEmptyMap(); ++ structures.setMap("References", newReferences); ++ for (final String key : references.keys()) { ++ final long[] value = references.getLongs(key); ++ if (value.length == 0) { ++ continue; ++ } ++ ++ newReferences.setLongs(getStructureConverted(key, biomeCounts), value); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private static final class BiomeRemap { ++ ++ public final Map biomeToNewStructure; ++ public final String dfl; ++ ++ private BiomeRemap(final Map biomeToNewStructure, final String dfl) { ++ this.biomeToNewStructure = biomeToNewStructure; ++ this.dfl = dfl; ++ } ++ ++ public static BiomeRemap create(final String newId) { ++ return new BiomeRemap(null, newId); ++ } ++ ++ public static BiomeRemap create(final Map, String> biomeMap, final String newId) { ++ final Map biomeToNewStructure = new HashMap<>(); ++ ++ for (final Map.Entry, String> entry : biomeMap.entrySet()) { ++ final List biomes = entry.getKey(); ++ final String newBiomeStructure = entry.getValue(); ++ ++ for (int i = 0, len = biomes.size(); i < len; ++i) { ++ final String biome = biomes.get(i); ++ if (biomeToNewStructure.putIfAbsent(biome, newBiomeStructure) != null) { ++ throw new IllegalStateException("Duplicate biome remap: " + biome + " -> " + newBiomeStructure + ", but already mapped to " + biomeToNewStructure.get(biome)); ++ } ++ } ++ } ++ ++ return new BiomeRemap(biomeToNewStructure, newId); ++ } ++ } ++} diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V501.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V501.java new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 @@ -17055,18 +17479,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; +import ca.spottedleaf.dataconverter.types.ObjectType; +import ca.spottedleaf.dataconverter.types.MapType; ++import com.mojang.logging.LogUtils; +import net.minecraft.core.Registry; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.EntityBlock; -+import org.apache.logging.log4j.LogManager; -+import org.apache.logging.log4j.Logger; ++import org.slf4j.Logger; +import java.util.HashMap; +import java.util.Map; + +public final class V704 { + -+ private static final Logger LOGGER = LogManager.getLogger(); ++ private static final Logger LOGGER = LogUtils.getLogger(); + + protected static final int VERSION = MCVersions.V1_10_2 + 192; + @@ -17074,7 +17498,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Override + public String put(final String key, final String value) { + if (this.containsKey(key)) { -+ LOGGER.fatal("Duplicate item id to tile key: " + key); ++ LOGGER.error("Duplicate item id to tile key: " + key); + throw new RuntimeException(); // only devs should see the consequence of this... at least start up the damn thing... + } + return super.put(key, value); @@ -17399,14 +17823,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import ca.spottedleaf.dataconverter.types.ObjectType; +import ca.spottedleaf.dataconverter.types.ListType; +import ca.spottedleaf.dataconverter.types.MapType; -+import org.apache.logging.log4j.LogManager; -+import org.apache.logging.log4j.Logger; ++import com.mojang.logging.LogUtils; ++import org.slf4j.Logger; +import java.util.HashMap; +import java.util.Map; + +public final class V705 { + -+ private static final Logger LOGGER = LogManager.getLogger(); ++ private static final Logger LOGGER = LogUtils.getLogger(); + + protected static final int VERSION = MCVersions.V1_10_2 + 193; + @@ -17914,8 +18338,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import ca.spottedleaf.dataconverter.types.ObjectType; +import ca.spottedleaf.dataconverter.types.ListType; +import ca.spottedleaf.dataconverter.types.MapType; -+import org.apache.logging.log4j.LogManager; -+import org.apache.logging.log4j.Logger; ++import com.mojang.logging.LogUtils; ++import org.slf4j.Logger; +import java.util.HashMap; +import java.util.Map; + @@ -17923,7 +18347,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + // Structure for all data before data upgrading was added to minecraft (pre 15w32a) + -+ protected static final Logger LOGGER = LogManager.getLogger(); ++ private static final Logger LOGGER = LogUtils.getLogger(); + + protected static final int VERSION = MCVersions.V15W32A - 1; +