package net.minecraft.network.chat.contents; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.logging.LogUtils; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.Optional; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.arguments.selector.EntitySelector; import net.minecraft.commands.arguments.selector.EntitySelectorParser; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.ComponentContents; import net.minecraft.network.chat.ComponentSerialization; import net.minecraft.network.chat.ComponentUtils; import net.minecraft.network.chat.FormattedText; import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.Style; import net.minecraft.world.entity.Entity; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; public class SelectorContents implements ComponentContents { private static final Logger LOGGER = LogUtils.getLogger(); public static final MapCodec CODEC = RecordCodecBuilder.mapCodec( instance -> instance.group( Codec.STRING.fieldOf("selector").forGetter(SelectorContents::getPattern), ComponentSerialization.CODEC.optionalFieldOf("separator").forGetter(SelectorContents::getSeparator) ) .apply(instance, SelectorContents::new) ); public static final ComponentContents.Type TYPE = new ComponentContents.Type<>(CODEC, "selector"); private final String pattern; @Nullable private final EntitySelector selector; protected final Optional separator; public SelectorContents(String pattern, Optional separator) { this.pattern = pattern; this.separator = separator; this.selector = parseSelector(pattern); } @Nullable private static EntitySelector parseSelector(String selector) { EntitySelector entitySelector = null; try { EntitySelectorParser entitySelectorParser = new EntitySelectorParser(new StringReader(selector), true); entitySelector = entitySelectorParser.parse(); } catch (CommandSyntaxException var3) { LOGGER.warn("Invalid selector component: {}: {}", selector, var3.getMessage()); } return entitySelector; } @Override public ComponentContents.Type type() { return TYPE; } public String getPattern() { return this.pattern; } @Nullable public EntitySelector getSelector() { return this.selector; } public Optional getSeparator() { return this.separator; } @Override public MutableComponent resolve(@Nullable CommandSourceStack nbtPathPattern, @Nullable Entity entity, int recursionDepth) throws CommandSyntaxException { if (nbtPathPattern != null && this.selector != null) { Optional optional = ComponentUtils.updateForEntity(nbtPathPattern, this.separator, entity, recursionDepth); return ComponentUtils.formatList(this.selector.findEntities(nbtPathPattern), optional, Entity::getDisplayName); } else { return Component.empty(); } } @Override public Optional visit(FormattedText.StyledContentConsumer styledContentConsumer, Style style) { return styledContentConsumer.accept(style, this.pattern); } @Override public Optional visit(FormattedText.ContentConsumer contentConsumer) { return contentConsumer.accept(this.pattern); } public boolean equals(Object object) { return this == object ? true : object instanceof SelectorContents selectorContents && this.pattern.equals(selectorContents.pattern) && this.separator.equals(selectorContents.separator); } public int hashCode() { int i = this.pattern.hashCode(); return 31 * i + this.separator.hashCode(); } public String toString() { return "pattern{" + this.pattern + "}"; } }