StructuresBecomeConfiguredFix.java

net.minecraft.util.datafix.fixes.StructuresBecomeConfiguredFix

信息

  • 全限定名:net.minecraft.util.datafix.fixes.StructuresBecomeConfiguredFix
  • 类型:public class
  • 包:net.minecraft.util.datafix.fixes
  • 源码路径:src/main/java/net/minecraft/util/datafix/fixes/StructuresBecomeConfiguredFix.java
  • 起始行号:L25
  • 继承:DataFix
  • 职责:

    TODO

字段/常量

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L26
    • 说明:

      TODO

  • CONVERSION_MAP

    • 类型: Map<String,StructuresBecomeConfiguredFix.Conversion>
    • 修饰符: private static final
    • 源码定位: L27
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.util.datafix.fixes.StructuresBecomeConfiguredFix.Conversion
    • 类型: record
    • 修饰符: private
    • 源码定位: L209
    • 说明:

      TODO

构造器

public StructuresBecomeConfiguredFix(Schema outputSchema) @ L120

  • 构造器名:StructuresBecomeConfiguredFix
  • 源码定位:L120
  • 修饰符:public

参数:

  • outputSchema: Schema

说明:

TODO

方法

下面的方法块按源码顺序生成。

protected TypeRewriteRule makeRule() @ L124

  • 方法名:makeRule
  • 源码定位:L124
  • 返回类型:TypeRewriteRule
  • 修饰符:protected

参数:

说明:

TODO

private Dynamic<?> fix(Dynamic<?> chunk) @ L131

  • 方法名:fix
  • 源码定位:L131
  • 返回类型:Dynamic<?>
  • 修饰符:private

参数:

  • chunk: Dynamic<?>

说明:

TODO

private Dynamic<?> updateStarts(Dynamic<?> starts, Dynamic<?> chunk) @ L138

  • 方法名:updateStarts
  • 源码定位:L138
  • 返回类型:Dynamic<?>
  • 修饰符:private

参数:

  • starts: Dynamic<?>
  • chunk: Dynamic<?>

说明:

TODO

private Dynamic<?> updateReferences(Dynamic<?> references, Dynamic<?> chunk) @ L154

  • 方法名:updateReferences
  • 源码定位:L154
  • 返回类型:Dynamic<?>
  • 修饰符:private

参数:

  • references: Dynamic<?>
  • chunk: Dynamic<?>

说明:

TODO

private Dynamic<?> findUpdatedStructureType(Dynamic<?> dynamicKey, Dynamic<?> chunk) @ L177

  • 方法名:findUpdatedStructureType
  • 源码定位:L177
  • 返回类型:Dynamic<?>
  • 修饰符:private

参数:

  • dynamicKey: Dynamic<?>
  • chunk: Dynamic<?>

说明:

TODO

private Optional<String> guessConfiguration(Dynamic<?> chunk, StructuresBecomeConfiguredFix.Conversion conversion) @ L195

  • 方法名:guessConfiguration
  • 源码定位:L195
  • 返回类型:Optional
  • 修饰符:private

参数:

  • chunk: Dynamic<?>
  • conversion: StructuresBecomeConfiguredFix.Conversion

说明:

TODO

代码

public class StructuresBecomeConfiguredFix extends DataFix {
    private static final Logger LOGGER = LogUtils.getLogger();
    private static final Map<String, StructuresBecomeConfiguredFix.Conversion> CONVERSION_MAP = ImmutableMap.<String, StructuresBecomeConfiguredFix.Conversion>builder()
        .put(
            "mineshaft",
            StructuresBecomeConfiguredFix.Conversion.biomeMapped(
                Map.of(List.of("minecraft:badlands", "minecraft:eroded_badlands", "minecraft:wooded_badlands"), "minecraft:mineshaft_mesa"),
                "minecraft:mineshaft"
            )
        )
        .put(
            "shipwreck",
            StructuresBecomeConfiguredFix.Conversion.biomeMapped(
                Map.of(List.of("minecraft:beach", "minecraft:snowy_beach"), "minecraft:shipwreck_beached"), "minecraft:shipwreck"
            )
        )
        .put(
            "ocean_ruin",
            StructuresBecomeConfiguredFix.Conversion.biomeMapped(
                Map.of(List.of("minecraft:warm_ocean", "minecraft:lukewarm_ocean", "minecraft:deep_lukewarm_ocean"), "minecraft:ocean_ruin_warm"),
                "minecraft:ocean_ruin_cold"
            )
        )
        .put(
            "village",
            StructuresBecomeConfiguredFix.Conversion.biomeMapped(
                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",
            StructuresBecomeConfiguredFix.Conversion.biomeMapped(
                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"
            )
        )
        .put("pillager_outpost", StructuresBecomeConfiguredFix.Conversion.trivial("minecraft:pillager_outpost"))
        .put("mansion", StructuresBecomeConfiguredFix.Conversion.trivial("minecraft:mansion"))
        .put("jungle_pyramid", StructuresBecomeConfiguredFix.Conversion.trivial("minecraft:jungle_pyramid"))
        .put("desert_pyramid", StructuresBecomeConfiguredFix.Conversion.trivial("minecraft:desert_pyramid"))
        .put("igloo", StructuresBecomeConfiguredFix.Conversion.trivial("minecraft:igloo"))
        .put("swamp_hut", StructuresBecomeConfiguredFix.Conversion.trivial("minecraft:swamp_hut"))
        .put("stronghold", StructuresBecomeConfiguredFix.Conversion.trivial("minecraft:stronghold"))
        .put("monument", StructuresBecomeConfiguredFix.Conversion.trivial("minecraft:monument"))
        .put("fortress", StructuresBecomeConfiguredFix.Conversion.trivial("minecraft:fortress"))
        .put("endcity", StructuresBecomeConfiguredFix.Conversion.trivial("minecraft:end_city"))
        .put("buried_treasure", StructuresBecomeConfiguredFix.Conversion.trivial("minecraft:buried_treasure"))
        .put("nether_fossil", StructuresBecomeConfiguredFix.Conversion.trivial("minecraft:nether_fossil"))
        .put("bastion_remnant", StructuresBecomeConfiguredFix.Conversion.trivial("minecraft:bastion_remnant"))
        .build();
 
    public StructuresBecomeConfiguredFix(Schema outputSchema) {
        super(outputSchema, false);
    }
 
    @Override
    protected TypeRewriteRule makeRule() {
        Type<?> chunkType = this.getInputSchema().getType(References.CHUNK);
        Type<?> newChunkType = this.getInputSchema().getType(References.CHUNK);
        return this.writeFixAndRead("StucturesToConfiguredStructures", chunkType, newChunkType, this::fix);
    }
 
    private Dynamic<?> fix(Dynamic<?> chunk) {
        return chunk.update(
            "structures",
            structures -> structures.update("starts", s -> this.updateStarts(s, chunk)).update("References", r -> this.updateReferences(r, chunk))
        );
    }
 
    private Dynamic<?> updateStarts(Dynamic<?> starts, Dynamic<?> chunk) {
        Map<? extends Dynamic<?>, ? extends Dynamic<?>> values = starts.getMapValues().result().orElse(Map.of());
        HashMap<Dynamic<?>, Dynamic<?>> newMap = Maps.newHashMap();
        values.forEach((key, start) -> {
            if (!start.get("id").asString("INVALID").equals("INVALID")) {
                Dynamic<?> newKey = this.findUpdatedStructureType((Dynamic<?>)key, chunk);
                if (newKey == null) {
                    LOGGER.warn("Encountered unknown structure in datafixer: {}", key.asString("<missing key>"));
                } else {
                    newMap.computeIfAbsent(newKey, k -> start.set("id", newKey));
                }
            }
        });
        return chunk.createMap(newMap);
    }
 
    private Dynamic<?> updateReferences(Dynamic<?> references, Dynamic<?> chunk) {
        Map<? extends Dynamic<?>, ? extends Dynamic<?>> values = references.getMapValues().result().orElse(Map.of());
        HashMap<Dynamic<?>, Dynamic<?>> newMap = Maps.newHashMap();
        values.forEach(
            (key, refList) -> {
                if (refList.asLongStream().count() != 0L) {
                    Dynamic<?> newKey = this.findUpdatedStructureType((Dynamic<?>)key, chunk);
                    if (newKey == null) {
                        LOGGER.warn("Encountered unknown structure in datafixer: {}", key.asString("<missing key>"));
                    } else {
                        newMap.compute(
                            newKey,
                            (k, oldRefList) -> oldRefList == null
                                ? refList
                                : refList.createLongList(LongStream.concat(oldRefList.asLongStream(), refList.asLongStream()))
                        );
                    }
                }
            }
        );
        return chunk.createMap(newMap);
    }
 
    private @Nullable Dynamic<?> findUpdatedStructureType(Dynamic<?> dynamicKey, Dynamic<?> chunk) {
        String key = dynamicKey.asString("UNKNOWN").toLowerCase(Locale.ROOT);
        StructuresBecomeConfiguredFix.Conversion conversion = CONVERSION_MAP.get(key);
        if (conversion == null) {
            return null;
        } else {
            String resultingId = conversion.fallback;
            if (!conversion.biomeMapping().isEmpty()) {
                Optional<String> result = this.guessConfiguration(chunk, conversion);
                if (result.isPresent()) {
                    resultingId = result.get();
                }
            }
 
            return chunk.createString(resultingId);
        }
    }
 
    private Optional<String> guessConfiguration(Dynamic<?> chunk, StructuresBecomeConfiguredFix.Conversion conversion) {
        Object2IntArrayMap<String> matches = new Object2IntArrayMap<>();
        chunk.get("sections").asList(Function.identity()).forEach(s -> s.get("biomes").get("palette").asList(Function.identity()).forEach(biome -> {
            String mapping = conversion.biomeMapping().get(biome.asString(""));
            if (mapping != null) {
                matches.mergeInt(mapping, 1, Integer::sum);
            }
        }));
        return matches.object2IntEntrySet()
            .stream()
            .max(Comparator.comparingInt(it.unimi.dsi.fastutil.objects.Object2IntMap.Entry::getIntValue))
            .map(Entry::getKey);
    }
 
    private record Conversion(Map<String, String> biomeMapping, String fallback) {
        public static StructuresBecomeConfiguredFix.Conversion trivial(String result) {
            return new StructuresBecomeConfiguredFix.Conversion(Map.of(), result);
        }
 
        public static StructuresBecomeConfiguredFix.Conversion biomeMapped(Map<List<String>, String> mapping, String fallback) {
            return new StructuresBecomeConfiguredFix.Conversion(unpack(mapping), fallback);
        }
 
        private static Map<String, String> unpack(Map<List<String>, String> packed) {
            Builder<String, String> builder = ImmutableMap.builder();
 
            for (Entry<List<String>, String> entry : packed.entrySet()) {
                entry.getKey().forEach(k -> builder.put(k, entry.getValue()));
            }
 
            return builder.build();
        }
    }
}

引用的其他类