/* * Decompiled with CFR 0.152. * * Could not load the following classes: * org.jspecify.annotations.Nullable */ package net.minecraft.util.debug; import java.lang.runtime.SwitchBootstraps; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.Stream; import net.minecraft.core.BlockPos; import net.minecraft.core.GlobalPos; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.game.DebugEntityNameGenerator; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.StringUtil; import net.minecraft.world.SimpleContainer; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.ai.Brain; import net.minecraft.world.entity.ai.behavior.BehaviorControl; import net.minecraft.world.entity.ai.behavior.BlockPosTracker; import net.minecraft.world.entity.ai.behavior.EntityTracker; import net.minecraft.world.entity.ai.memory.ExpirableValue; import net.minecraft.world.entity.ai.memory.MemoryModuleType; import net.minecraft.world.entity.ai.memory.WalkTarget; import net.minecraft.world.entity.monster.warden.Warden; import net.minecraft.world.entity.npc.InventoryCarrier; import net.minecraft.world.entity.npc.Villager; import net.minecraft.world.entity.schedule.Activity; import org.jspecify.annotations.Nullable; public record DebugBrainDump(String name, String profession, int xp, float health, float maxHealth, String inventory, boolean wantsGolem, int angerLevel, List activities, List behaviors, List memories, List gossips, Set pois, Set potentialPois) { public static final StreamCodec STREAM_CODEC = StreamCodec.of((output, value) -> value.write((FriendlyByteBuf)((Object)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) { List list; int n; Villager villager; boolean wantsGolem; InventoryCarrier inventoryCarrier; SimpleContainer inventory; int xp; String profession; String name = DebugEntityNameGenerator.getEntityName(entity); if (entity instanceof Villager) { Villager villager2 = (Villager)entity; profession = villager2.getVillagerData().profession().getRegisteredName(); xp = villager2.getVillagerXp(); } else { profession = ""; xp = 0; } float health = entity.getHealth(); float maxHealth = entity.getMaxHealth(); Brain brain = entity.getBrain(); long gameTime = entity.level().getGameTime(); String inventoryStr = entity instanceof InventoryCarrier ? ((inventory = (inventoryCarrier = (InventoryCarrier)((Object)entity)).getInventory()).isEmpty() ? "" : ((Object)inventory).toString()) : ""; boolean bl = wantsGolem = entity instanceof Villager && (villager = (Villager)entity).wantsToSpawnGolem(gameTime); if (entity instanceof Warden) { Warden warden = (Warden)entity; n = warden.getClientAngerLevel(); } else { n = -1; } int angerLevel = n; List activities = brain.getActiveActivities().stream().map(Activity::getName).toList(); List behaviors = brain.getRunningBehaviors().stream().map(BehaviorControl::debugString).toList(); List memories = DebugBrainDump.getMemoryDescriptions(serverLevel, entity, gameTime).map(description -> StringUtil.truncateStringIfNecessary(description, 255, true)).toList(); Set pois = DebugBrainDump.getKnownBlockPositions(brain, MemoryModuleType.JOB_SITE, MemoryModuleType.HOME, MemoryModuleType.MEETING_POINT); Set potentialPois = DebugBrainDump.getKnownBlockPositions(brain, MemoryModuleType.POTENTIAL_JOB_SITE); if (entity instanceof Villager) { Villager villager3 = (Villager)entity; list = DebugBrainDump.getVillagerGossips(villager3); } else { list = List.of(); } List gossips = list; return new DebugBrainDump(name, profession, xp, health, maxHealth, inventoryStr, wantsGolem, angerLevel, activities, behaviors, memories, gossips, pois, potentialPois); } @SafeVarargs private static Set getKnownBlockPositions(Brain brain, MemoryModuleType ... memories) { return Stream.of(memories).filter(brain::hasMemoryValue).map(brain::getMemory).flatMap(Optional::stream).map(GlobalPos::pos).collect(Collectors.toSet()); } private static List getVillagerGossips(Villager villager) { ArrayList gossips = new ArrayList(); villager.getGossips().getGossipEntries().forEach((uuid, entries) -> { String gossipeeName = DebugEntityNameGenerator.getEntityName(uuid); entries.forEach((gossipType, value) -> gossips.add(gossipeeName + ": " + String.valueOf(gossipType) + ": " + value)); }); return gossips; } private static Stream getMemoryDescriptions(ServerLevel level, LivingEntity body, long timestamp) { return body.getBrain().getMemories().entrySet().stream().map(entry -> { MemoryModuleType memoryType = (MemoryModuleType)entry.getKey(); Optional optionalExpirableValue = (Optional)entry.getValue(); return DebugBrainDump.getMemoryDescription(level, timestamp, memoryType, optionalExpirableValue); }).sorted(); } private static String getMemoryDescription(ServerLevel level, long timestamp, MemoryModuleType memoryType, Optional> maybeValue) { Object description; if (maybeValue.isPresent()) { ExpirableValue expirableValue = maybeValue.get(); Object value = expirableValue.getValue(); if (memoryType == MemoryModuleType.HEARD_BELL_TIME) { long timeSince = timestamp - (Long)value; description = timeSince + " ticks ago"; } else { description = expirableValue.canExpire() ? DebugBrainDump.getShortDescription(level, value) + " (ttl: " + expirableValue.getTimeToLive() + ")" : DebugBrainDump.getShortDescription(level, value); } } else { description = "-"; } return BuiltInRegistries.MEMORY_MODULE_TYPE.getKey(memoryType).getPath() + ": " + (String)description; } private static String getShortDescription(ServerLevel level, @Nullable Object obj) { Object object = obj; int n = 0; return switch (SwitchBootstraps.typeSwitch("typeSwitch", new Object[]{UUID.class, Entity.class, WalkTarget.class, EntityTracker.class, GlobalPos.class, BlockPosTracker.class, DamageSource.class, Collection.class}, (Object)object, n)) { case -1 -> "-"; case 0 -> { UUID uuid = (UUID)object; yield DebugBrainDump.getShortDescription(level, level.getEntity(uuid)); } case 1 -> { Entity entity = (Entity)object; yield DebugEntityNameGenerator.getEntityName(entity); } case 2 -> { WalkTarget walkTarget = (WalkTarget)object; yield DebugBrainDump.getShortDescription(level, walkTarget.getTarget()); } case 3 -> { EntityTracker entityTracker = (EntityTracker)object; yield DebugBrainDump.getShortDescription(level, entityTracker.getEntity()); } case 4 -> { GlobalPos globalPos = (GlobalPos)object; yield DebugBrainDump.getShortDescription(level, globalPos.pos()); } case 5 -> { BlockPosTracker tracker = (BlockPosTracker)object; yield DebugBrainDump.getShortDescription(level, tracker.currentBlockPosition()); } case 6 -> { DamageSource damageSource = (DamageSource)object; Entity entity = damageSource.getEntity(); if (entity == null) { yield obj.toString(); } yield DebugBrainDump.getShortDescription(level, entity); } case 7 -> { Collection collection = (Collection)object; yield "[" + collection.stream().map(element -> DebugBrainDump.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); } }