DebugBrainDump.java

net.minecraft.util.debug.DebugBrainDump

信息

  • 全限定名:net.minecraft.util.debug.DebugBrainDump
  • 类型:public record
  • 包:net.minecraft.util.debug
  • 源码路径:src/main/java/net/minecraft/util/debug/DebugBrainDump.java
  • 起始行号:L39
  • 职责:

    TODO

字段/常量

  • STREAM_CODEC
    • 类型: StreamCodec<FriendlyByteBuf,DebugBrainDump>
    • 修饰符: public static final
    • 源码定位: L55
    • 说明:

      TODO

内部类/嵌套类型

构造器

public DebugBrainDump(FriendlyByteBuf input) @ L57

  • 构造器名:DebugBrainDump
  • 源码定位:L57
  • 修饰符:public

参数:

  • input: FriendlyByteBuf

说明:

TODO

方法

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

public void write(FriendlyByteBuf output) @ L76

  • 方法名:write
  • 源码定位:L76
  • 返回类型:void
  • 修饰符:public

参数:

  • output: FriendlyByteBuf

说明:

TODO

public static DebugBrainDump takeBrainDump(ServerLevel serverLevel, LivingEntity entity) @ L93

  • 方法名:takeBrainDump
  • 源码定位:L93
  • 返回类型:DebugBrainDump
  • 修饰符:public static

参数:

  • serverLevel: ServerLevel
  • entity: LivingEntity

说明:

TODO

private static Set<BlockPos> getKnownBlockPositions(Brain<?> brain, MemoryModuleType<GlobalPos>... memories) @ L130

  • 方法名:getKnownBlockPositions
  • 源码定位:L130
  • 返回类型:Set
  • 修饰符:private static

参数:

  • brain: Brain<?>
  • memories: MemoryModuleType

说明:

TODO

private static List<String> getVillagerGossips(Villager villager) @ L140

  • 方法名:getVillagerGossips
  • 源码定位:L140
  • 返回类型:List
  • 修饰符:private static

参数:

  • villager: Villager

说明:

TODO

private static List<String> getMemoryDescriptions(ServerLevel level, LivingEntity body, long timestamp) @ L149

  • 方法名:getMemoryDescriptions
  • 源码定位:L149
  • 返回类型:List
  • 修饰符:private static

参数:

  • level: ServerLevel
  • body: LivingEntity
  • timestamp: long

说明:

TODO

private static String getMemoryDescription(ServerLevel level, long timestamp, MemoryModuleType<?> memoryType, Optional<?> maybeValue, OptionalLong ttl) @ L176

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

参数:

  • level: ServerLevel
  • timestamp: long
  • memoryType: MemoryModuleType<?>
  • maybeValue: Optional<?>
  • ttl: OptionalLong

说明:

TODO

private static String getShortDescription(ServerLevel level, Object obj) @ L195

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

参数:

  • level: ServerLevel
  • obj: Object

说明:

TODO

public boolean hasPoi(BlockPos poiPos) @ L216

  • 方法名:hasPoi
  • 源码定位:L216
  • 返回类型:boolean
  • 修饰符:public

参数:

  • poiPos: BlockPos

说明:

TODO

public boolean hasPotentialPoi(BlockPos poiPos) @ L220

  • 方法名:hasPotentialPoi
  • 源码定位:L220
  • 返回类型:boolean
  • 修饰符:public

参数:

  • poiPos: BlockPos

说明:

TODO

代码

public record DebugBrainDump(
    String name,
    String profession,
    int xp,
    float health,
    float maxHealth,
    String inventory,
    boolean wantsGolem,
    int angerLevel,
    List<String> activities,
    List<String> behaviors,
    List<String> memories,
    List<String> gossips,
    Set<BlockPos> pois,
    Set<BlockPos> potentialPois
) {
    public static final StreamCodec<FriendlyByteBuf, DebugBrainDump> STREAM_CODEC = StreamCodec.of((output, value) -> value.write(output), DebugBrainDump::new);
 
    public DebugBrainDump(FriendlyByteBuf input) {
        this(
            input.readUtf(),
            input.readUtf(),
            input.readInt(),
            input.readFloat(),
            input.readFloat(),
            input.readUtf(),
            input.readBoolean(),
            input.readInt(),
            input.readList(FriendlyByteBuf::readUtf),
            input.readList(FriendlyByteBuf::readUtf),
            input.readList(FriendlyByteBuf::readUtf),
            input.readList(FriendlyByteBuf::readUtf),
            input.readCollection(HashSet::new, BlockPos.STREAM_CODEC),
            input.readCollection(HashSet::new, BlockPos.STREAM_CODEC)
        );
    }
 
    public void write(FriendlyByteBuf output) {
        output.writeUtf(this.name);
        output.writeUtf(this.profession);
        output.writeInt(this.xp);
        output.writeFloat(this.health);
        output.writeFloat(this.maxHealth);
        output.writeUtf(this.inventory);
        output.writeBoolean(this.wantsGolem);
        output.writeInt(this.angerLevel);
        output.writeCollection(this.activities, FriendlyByteBuf::writeUtf);
        output.writeCollection(this.behaviors, FriendlyByteBuf::writeUtf);
        output.writeCollection(this.memories, FriendlyByteBuf::writeUtf);
        output.writeCollection(this.gossips, FriendlyByteBuf::writeUtf);
        output.writeCollection(this.pois, BlockPos.STREAM_CODEC);
        output.writeCollection(this.potentialPois, BlockPos.STREAM_CODEC);
    }
 
    public static DebugBrainDump takeBrainDump(ServerLevel serverLevel, LivingEntity entity) {
        String name = DebugEntityNameGenerator.getEntityName(entity);
        String profession;
        int xp;
        if (entity instanceof Villager villager) {
            profession = villager.getVillagerData().profession().getRegisteredName();
            xp = villager.getVillagerXp();
        } else {
            profession = "";
            xp = 0;
        }
 
        float health = entity.getHealth();
        float maxHealth = entity.getMaxHealth();
        Brain<?> brain = entity.getBrain();
        long gameTime = entity.level().getGameTime();
        String inventoryStr;
        if (entity instanceof InventoryCarrier inventoryCarrier) {
            Container inventory = inventoryCarrier.getInventory();
            inventoryStr = inventory.isEmpty() ? "" : inventory.toString();
        } else {
            inventoryStr = "";
        }
 
        boolean wantsGolem = entity instanceof Villager villager && villager.wantsToSpawnGolem(gameTime);
        int angerLevel = entity instanceof Warden warden ? warden.getClientAngerLevel() : -1;
        List<String> activities = brain.getActiveActivities().stream().map(Activity::getName).toList();
        List<String> behaviors = brain.getRunningBehaviors().stream().map(BehaviorControl::debugString).toList();
        List<String> memories = getMemoryDescriptions(serverLevel, entity, gameTime);
        Set<BlockPos> pois = getKnownBlockPositions(brain, MemoryModuleType.JOB_SITE, MemoryModuleType.HOME, MemoryModuleType.MEETING_POINT);
        Set<BlockPos> potentialPois = getKnownBlockPositions(brain, MemoryModuleType.POTENTIAL_JOB_SITE);
        List<String> gossips = entity instanceof Villager villagerx ? getVillagerGossips(villagerx) : List.of();
        return new DebugBrainDump(
            name, profession, xp, health, maxHealth, inventoryStr, wantsGolem, angerLevel, activities, behaviors, memories, gossips, pois, potentialPois
        );
    }
 
    @SafeVarargs
    private static Set<BlockPos> getKnownBlockPositions(Brain<?> brain, MemoryModuleType<GlobalPos>... memories) {
        return Stream.of(memories)
            .filter(brain::hasMemoryValue)
            .map(brain::getMemory)
            .flatMap(Optional::stream)
            .map(GlobalPos::pos)
            .collect(Collectors.toSet());
    }
 
    private static List<String> getVillagerGossips(Villager villager) {
        List<String> gossips = new ArrayList<>();
        villager.getGossips().getGossipEntries().forEach((uuid, entries) -> {
            String gossipeeName = DebugEntityNameGenerator.getEntityName(uuid);
            entries.forEach((gossipType, value) -> gossips.add(gossipeeName + ": " + gossipType + ": " + value));
        });
        return gossips;
    }
 
    private static List<String> getMemoryDescriptions(ServerLevel level, LivingEntity body, long timestamp) {
        final List<String> result = new ArrayList<>();
        body.getBrain().forEach(new Brain.Visitor() {
            @Override
            public <U> void acceptEmpty(MemoryModuleType<U> type) {
                this.collectResult(type, Optional.empty(), OptionalLong.empty());
            }
 
            @Override
            public <U> void accept(MemoryModuleType<U> type, U value) {
                this.collectResult(type, Optional.of(value), OptionalLong.empty());
            }
 
            @Override
            public <U> void accept(MemoryModuleType<U> type, U value, long timeToLive) {
                this.collectResult(type, Optional.of(value), OptionalLong.of(timestamp));
            }
 
            private void collectResult(MemoryModuleType<?> memoryType, Optional<?> value, OptionalLong ttl) {
                String description = DebugBrainDump.getMemoryDescription(level, timestamp, memoryType, value, ttl);
                result.add(StringUtil.truncateStringIfNecessary(description, 255, true));
            }
        });
        Collections.sort(result);
        return result;
    }
 
    private static String getMemoryDescription(ServerLevel level, long timestamp, MemoryModuleType<?> memoryType, Optional<?> maybeValue, OptionalLong ttl) {
        String description;
        if (maybeValue.isPresent()) {
            Object value = maybeValue.get();
            if (memoryType == MemoryModuleType.HEARD_BELL_TIME) {
                long timeSince = timestamp - (Long)value;
                description = timeSince + " ticks ago";
            } else if (ttl.isPresent()) {
                description = getShortDescription(level, value) + " (ttl: " + ttl.getAsLong() + ")";
            } else {
                description = getShortDescription(level, value);
            }
        } else {
            description = "-";
        }
 
        return BuiltInRegistries.MEMORY_MODULE_TYPE.getKey(memoryType).getPath() + ": " + description;
    }
 
    private static String getShortDescription(ServerLevel level, @Nullable Object obj) {
        return switch (obj) {
            case null -> "-";
            case UUID uuid -> getShortDescription(level, level.getEntity(uuid));
            case Entity entity -> DebugEntityNameGenerator.getEntityName(entity);
            case WalkTarget walkTarget -> getShortDescription(level, walkTarget.getTarget());
            case EntityTracker entityTracker -> getShortDescription(level, entityTracker.getEntity());
            case GlobalPos globalPos -> getShortDescription(level, globalPos.pos());
            case BlockPosTracker tracker -> getShortDescription(level, tracker.currentBlockPosition());
            case DamageSource damageSource -> {
                Entity entity = damageSource.getEntity();
                yield entity == null ? obj.toString() : getShortDescription(level, entity);
            }
            case NearestVisibleLivingEntities visibleEntities -> getShortDescription(level, visibleEntities.nearbyEntities());
            case Collection<?> collection -> "["
                + (String)collection.stream().map(element -> getShortDescription(level, element)).collect(Collectors.joining(", "))
                + "]";
            default -> obj.toString();
        };
    }
 
    public boolean hasPoi(BlockPos poiPos) {
        return this.pois.contains(poiPos);
    }
 
    public boolean hasPotentialPoi(BlockPos poiPos) {
        return this.potentialPois.contains(poiPos);
    }
}

引用的其他类