StatsCounterFix.java

net.minecraft.util.datafix.fixes.StatsCounterFix

信息

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

    TODO

字段/常量

  • SPECIAL_OBJECTIVE_CRITERIA

    • 类型: Set<String>
    • 修饰符: private static final
    • 源码定位: L23
    • 说明:

      TODO

  • SKIP

    • 类型: Set<String>
    • 修饰符: private static final
    • 源码定位: L68
    • 说明:

      TODO

  • CUSTOM_MAP

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

      TODO

  • BLOCK_KEY

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

      TODO

  • NEW_BLOCK_KEY

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

      TODO

  • ITEM_KEYS

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

      TODO

  • ENTITY_KEYS

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

      TODO

  • ENTITIES

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

      TODO

  • NEW_CUSTOM_KEY

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

      TODO

内部类/嵌套类型

  • net.minecraft.util.datafix.fixes.StatsCounterFix.StatType
    • 类型: record
    • 修饰符: private
    • 源码定位: L285
    • 说明:

      TODO

构造器

public StatsCounterFix(Schema outputSchema, boolean changesType) @ L187

  • 构造器名:StatsCounterFix
  • 源码定位:L187
  • 修饰符:public

参数:

  • outputSchema: Schema
  • changesType: boolean

说明:

TODO

方法

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

private static StatsCounterFix.StatType unpackLegacyKey(String key) @ L191

  • 方法名:unpackLegacyKey
  • 源码定位:L191
  • 返回类型:StatsCounterFix.StatType
  • 修饰符:private static

参数:

  • key: String

说明:

TODO

public TypeRewriteRule makeRule() @ L230

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

参数:

说明:

TODO

private TypeRewriteRule makeStatFixer() @ L235

  • 方法名:makeStatFixer
  • 源码定位:L235
  • 返回类型:TypeRewriteRule
  • 修饰符:private

参数:

说明:

TODO

private TypeRewriteRule makeObjectiveFixer() @ L260

  • 方法名:makeObjectiveFixer
  • 源码定位:L260
  • 返回类型:TypeRewriteRule
  • 修饰符:private

参数:

说明:

TODO

private static String upgradeItem(String name) @ L277

  • 方法名:upgradeItem
  • 源码定位:L277
  • 返回类型:String
  • 修饰符:private static

参数:

  • name: String

说明:

TODO

private static String upgradeBlock(String name) @ L281

  • 方法名:upgradeBlock
  • 源码定位:L281
  • 返回类型:String
  • 修饰符:private static

参数:

  • name: String

说明:

TODO

代码

public class StatsCounterFix extends DataFix {
    private static final Set<String> SPECIAL_OBJECTIVE_CRITERIA = Set.of(
        "dummy",
        "trigger",
        "deathCount",
        "playerKillCount",
        "totalKillCount",
        "health",
        "food",
        "air",
        "armor",
        "xp",
        "level",
        "killedByTeam.aqua",
        "killedByTeam.black",
        "killedByTeam.blue",
        "killedByTeam.dark_aqua",
        "killedByTeam.dark_blue",
        "killedByTeam.dark_gray",
        "killedByTeam.dark_green",
        "killedByTeam.dark_purple",
        "killedByTeam.dark_red",
        "killedByTeam.gold",
        "killedByTeam.gray",
        "killedByTeam.green",
        "killedByTeam.light_purple",
        "killedByTeam.red",
        "killedByTeam.white",
        "killedByTeam.yellow",
        "teamkill.aqua",
        "teamkill.black",
        "teamkill.blue",
        "teamkill.dark_aqua",
        "teamkill.dark_blue",
        "teamkill.dark_gray",
        "teamkill.dark_green",
        "teamkill.dark_purple",
        "teamkill.dark_red",
        "teamkill.gold",
        "teamkill.gray",
        "teamkill.green",
        "teamkill.light_purple",
        "teamkill.red",
        "teamkill.white",
        "teamkill.yellow"
    );
    private static final Set<String> SKIP = ImmutableSet.<String>builder()
        .add("stat.craftItem.minecraft.spawn_egg")
        .add("stat.useItem.minecraft.spawn_egg")
        .add("stat.breakItem.minecraft.spawn_egg")
        .add("stat.pickup.minecraft.spawn_egg")
        .add("stat.drop.minecraft.spawn_egg")
        .build();
    private static final Map<String, String> CUSTOM_MAP = ImmutableMap.<String, String>builder()
        .put("stat.leaveGame", "minecraft:leave_game")
        .put("stat.playOneMinute", "minecraft:play_one_minute")
        .put("stat.timeSinceDeath", "minecraft:time_since_death")
        .put("stat.sneakTime", "minecraft:sneak_time")
        .put("stat.walkOneCm", "minecraft:walk_one_cm")
        .put("stat.crouchOneCm", "minecraft:crouch_one_cm")
        .put("stat.sprintOneCm", "minecraft:sprint_one_cm")
        .put("stat.swimOneCm", "minecraft:swim_one_cm")
        .put("stat.fallOneCm", "minecraft:fall_one_cm")
        .put("stat.climbOneCm", "minecraft:climb_one_cm")
        .put("stat.flyOneCm", "minecraft:fly_one_cm")
        .put("stat.diveOneCm", "minecraft:dive_one_cm")
        .put("stat.minecartOneCm", "minecraft:minecart_one_cm")
        .put("stat.boatOneCm", "minecraft:boat_one_cm")
        .put("stat.pigOneCm", "minecraft:pig_one_cm")
        .put("stat.horseOneCm", "minecraft:horse_one_cm")
        .put("stat.aviateOneCm", "minecraft:aviate_one_cm")
        .put("stat.jump", "minecraft:jump")
        .put("stat.drop", "minecraft:drop")
        .put("stat.damageDealt", "minecraft:damage_dealt")
        .put("stat.damageTaken", "minecraft:damage_taken")
        .put("stat.deaths", "minecraft:deaths")
        .put("stat.mobKills", "minecraft:mob_kills")
        .put("stat.animalsBred", "minecraft:animals_bred")
        .put("stat.playerKills", "minecraft:player_kills")
        .put("stat.fishCaught", "minecraft:fish_caught")
        .put("stat.talkedToVillager", "minecraft:talked_to_villager")
        .put("stat.tradedWithVillager", "minecraft:traded_with_villager")
        .put("stat.cakeSlicesEaten", "minecraft:eat_cake_slice")
        .put("stat.cauldronFilled", "minecraft:fill_cauldron")
        .put("stat.cauldronUsed", "minecraft:use_cauldron")
        .put("stat.armorCleaned", "minecraft:clean_armor")
        .put("stat.bannerCleaned", "minecraft:clean_banner")
        .put("stat.brewingstandInteraction", "minecraft:interact_with_brewingstand")
        .put("stat.beaconInteraction", "minecraft:interact_with_beacon")
        .put("stat.dropperInspected", "minecraft:inspect_dropper")
        .put("stat.hopperInspected", "minecraft:inspect_hopper")
        .put("stat.dispenserInspected", "minecraft:inspect_dispenser")
        .put("stat.noteblockPlayed", "minecraft:play_noteblock")
        .put("stat.noteblockTuned", "minecraft:tune_noteblock")
        .put("stat.flowerPotted", "minecraft:pot_flower")
        .put("stat.trappedChestTriggered", "minecraft:trigger_trapped_chest")
        .put("stat.enderchestOpened", "minecraft:open_enderchest")
        .put("stat.itemEnchanted", "minecraft:enchant_item")
        .put("stat.recordPlayed", "minecraft:play_record")
        .put("stat.furnaceInteraction", "minecraft:interact_with_furnace")
        .put("stat.craftingTableInteraction", "minecraft:interact_with_crafting_table")
        .put("stat.chestOpened", "minecraft:open_chest")
        .put("stat.sleepInBed", "minecraft:sleep_in_bed")
        .put("stat.shulkerBoxOpened", "minecraft:open_shulker_box")
        .build();
    private static final String BLOCK_KEY = "stat.mineBlock";
    private static final String NEW_BLOCK_KEY = "minecraft:mined";
    private static final Map<String, String> ITEM_KEYS = ImmutableMap.<String, String>builder()
        .put("stat.craftItem", "minecraft:crafted")
        .put("stat.useItem", "minecraft:used")
        .put("stat.breakItem", "minecraft:broken")
        .put("stat.pickup", "minecraft:picked_up")
        .put("stat.drop", "minecraft:dropped")
        .build();
    private static final Map<String, String> ENTITY_KEYS = ImmutableMap.<String, String>builder()
        .put("stat.entityKilledBy", "minecraft:killed_by")
        .put("stat.killEntity", "minecraft:killed")
        .build();
    private static final Map<String, String> ENTITIES = ImmutableMap.<String, String>builder()
        .put("Bat", "minecraft:bat")
        .put("Blaze", "minecraft:blaze")
        .put("CaveSpider", "minecraft:cave_spider")
        .put("Chicken", "minecraft:chicken")
        .put("Cow", "minecraft:cow")
        .put("Creeper", "minecraft:creeper")
        .put("Donkey", "minecraft:donkey")
        .put("ElderGuardian", "minecraft:elder_guardian")
        .put("Enderman", "minecraft:enderman")
        .put("Endermite", "minecraft:endermite")
        .put("EvocationIllager", "minecraft:evocation_illager")
        .put("Ghast", "minecraft:ghast")
        .put("Guardian", "minecraft:guardian")
        .put("Horse", "minecraft:horse")
        .put("Husk", "minecraft:husk")
        .put("Llama", "minecraft:llama")
        .put("LavaSlime", "minecraft:magma_cube")
        .put("MushroomCow", "minecraft:mooshroom")
        .put("Mule", "minecraft:mule")
        .put("Ozelot", "minecraft:ocelot")
        .put("Parrot", "minecraft:parrot")
        .put("Pig", "minecraft:pig")
        .put("PolarBear", "minecraft:polar_bear")
        .put("Rabbit", "minecraft:rabbit")
        .put("Sheep", "minecraft:sheep")
        .put("Shulker", "minecraft:shulker")
        .put("Silverfish", "minecraft:silverfish")
        .put("SkeletonHorse", "minecraft:skeleton_horse")
        .put("Skeleton", "minecraft:skeleton")
        .put("Slime", "minecraft:slime")
        .put("Spider", "minecraft:spider")
        .put("Squid", "minecraft:squid")
        .put("Stray", "minecraft:stray")
        .put("Vex", "minecraft:vex")
        .put("Villager", "minecraft:villager")
        .put("VindicationIllager", "minecraft:vindication_illager")
        .put("Witch", "minecraft:witch")
        .put("WitherSkeleton", "minecraft:wither_skeleton")
        .put("Wolf", "minecraft:wolf")
        .put("ZombieHorse", "minecraft:zombie_horse")
        .put("PigZombie", "minecraft:zombie_pigman")
        .put("ZombieVillager", "minecraft:zombie_villager")
        .put("Zombie", "minecraft:zombie")
        .build();
    private static final String NEW_CUSTOM_KEY = "minecraft:custom";
 
    public StatsCounterFix(Schema outputSchema, boolean changesType) {
        super(outputSchema, changesType);
    }
 
    private static StatsCounterFix.@Nullable StatType unpackLegacyKey(String key) {
        if (SKIP.contains(key)) {
            return null;
        } else {
            String customKey = CUSTOM_MAP.get(key);
            if (customKey != null) {
                return new StatsCounterFix.StatType("minecraft:custom", customKey);
            } else {
                int splitIndex = StringUtils.ordinalIndexOf(key, ".", 2);
                if (splitIndex < 0) {
                    return null;
                } else {
                    String prefix = key.substring(0, splitIndex);
                    if ("stat.mineBlock".equals(prefix)) {
                        String newKey = upgradeBlock(key.substring(splitIndex + 1).replace('.', ':'));
                        return new StatsCounterFix.StatType("minecraft:mined", newKey);
                    } else {
                        String itemKey = ITEM_KEYS.get(prefix);
                        if (itemKey != null) {
                            String oldItem = key.substring(splitIndex + 1).replace('.', ':');
                            String newItem = upgradeItem(oldItem);
                            String newKey = newItem == null ? oldItem : newItem;
                            return new StatsCounterFix.StatType(itemKey, newKey);
                        } else {
                            String entityKey = ENTITY_KEYS.get(prefix);
                            if (entityKey != null) {
                                String oldEntity = key.substring(splitIndex + 1).replace('.', ':');
                                String newKey = ENTITIES.getOrDefault(oldEntity, oldEntity);
                                return new StatsCounterFix.StatType(entityKey, newKey);
                            } else {
                                return null;
                            }
                        }
                    }
                }
            }
        }
    }
 
    @Override
    public TypeRewriteRule makeRule() {
        return TypeRewriteRule.seq(this.makeStatFixer(), this.makeObjectiveFixer());
    }
 
    private TypeRewriteRule makeStatFixer() {
        Type<?> inputType = this.getInputSchema().getType(References.STATS);
        Type<?> outputType = this.getOutputSchema().getType(References.STATS);
        return this.fixTypeEverywhereTyped("StatsCounterFix", inputType, outputType, input -> {
            Dynamic<?> tag = input.get(DSL.remainderFinder());
            Map<Dynamic<?>, Dynamic<?>> stats = Maps.newHashMap();
            Optional<? extends Map<? extends Dynamic<?>, ? extends Dynamic<?>>> map = tag.getMapValues().result();
            if (map.isPresent()) {
                for (Entry<? extends Dynamic<?>, ? extends Dynamic<?>> entry : map.get().entrySet()) {
                    if (entry.getValue().asNumber().result().isPresent()) {
                        String key = entry.getKey().asString("");
                        StatsCounterFix.StatType statType = unpackLegacyKey(key);
                        if (statType != null) {
                            Dynamic<?> newTypeKey = tag.createString(statType.type());
                            Dynamic<?> element = stats.computeIfAbsent(newTypeKey, k -> tag.emptyMap());
                            stats.put(newTypeKey, element.set(statType.typeKey(), (Dynamic<?>)entry.getValue()));
                        }
                    }
                }
            }
 
            return Util.readTypedOrThrow(outputType, tag.emptyMap().set("stats", tag.createMap(stats)));
        });
    }
 
    private TypeRewriteRule makeObjectiveFixer() {
        Type<?> inputType = this.getInputSchema().getType(References.OBJECTIVE);
        Type<?> outputType = this.getOutputSchema().getType(References.OBJECTIVE);
        return this.fixTypeEverywhereTyped("ObjectiveStatFix", inputType, outputType, input -> {
            Dynamic<?> tag = input.get(DSL.remainderFinder());
            Dynamic<?> updatedTag = tag.update("CriteriaName", name -> DataFixUtils.orElse(name.asString().result().map(key -> {
                if (SPECIAL_OBJECTIVE_CRITERIA.contains(key)) {
                    return (String)key;
                } else {
                    StatsCounterFix.StatType statType = unpackLegacyKey(key);
                    return statType == null ? "dummy" : V1451_6.packNamespacedWithDot(statType.type) + ":" + V1451_6.packNamespacedWithDot(statType.typeKey);
                }
            }).map(name::createString), name));
            return Util.readTypedOrThrow(outputType, updatedTag);
        });
    }
 
    private static @Nullable String upgradeItem(String name) {
        return ItemStackTheFlatteningFix.updateItem(name, 0);
    }
 
    private static String upgradeBlock(String name) {
        return BlockStateData.upgradeBlock(name);
    }
 
    private record StatType(String type, String typeKey) {
    }
}

引用的其他类

  • Schema

    • 引用位置: 参数
  • Util

    • 引用位置: 方法调用
    • 关联成员: Util.readTypedOrThrow()
  • BlockStateData

    • 引用位置: 方法调用
    • 关联成员: BlockStateData.upgradeBlock()
  • ItemStackTheFlatteningFix

    • 引用位置: 方法调用
    • 关联成员: ItemStackTheFlatteningFix.updateItem()
  • V1451_6

    • 引用位置: 方法调用
    • 关联成员: V1451_6.packNamespacedWithDot()