--- a/net/minecraft/network/chat/ComponentUtils.java +++ b/net/minecraft/network/chat/ComponentUtils.java @@ -33,6 +_,7 @@ } } + @io.papermc.paper.annotation.DoNotUse // Paper - validate separators - right now this method is only used for separator evaluation. Error on build if this changes to re-evaluate. public static Optional updateForEntity( @Nullable CommandSourceStack commandSourceStack, Optional optionalComponent, @Nullable Entity entity, int recursionDepth ) throws CommandSyntaxException { @@ -41,12 +_,40 @@ : Optional.empty(); } + // Paper start - validate separator + public static Optional updateSeparatorForEntity(@Nullable CommandSourceStack source, Optional text, @Nullable Entity sender, int depth) throws CommandSyntaxException { + if (text.isEmpty() || !isValidSelector(text.get())) return Optional.empty(); + return Optional.of(updateForEntity(source, text.get(), sender, depth)); + } + + public static boolean isValidSelector(final Component component) { + final ComponentContents contents = component.getContents(); + + if (contents instanceof net.minecraft.network.chat.contents.NbtContents || contents instanceof net.minecraft.network.chat.contents.SelectorContents) + return false; + if (contents instanceof final net.minecraft.network.chat.contents.TranslatableContents translatableContents) { + for (final Object arg : translatableContents.getArgs()) { + if (arg instanceof final Component argumentAsComponent && !isValidSelector(argumentAsComponent)) + return false; + } + } + + return true; + } + // Paper end - validate separator + public static MutableComponent updateForEntity( @Nullable CommandSourceStack commandSourceStack, Component component, @Nullable Entity entity, int recursionDepth ) throws CommandSyntaxException { if (recursionDepth > 100) { return component.copy(); } else { + // Paper start - adventure; pass actual vanilla component + if (component instanceof io.papermc.paper.adventure.AdventureComponent adventureComponent) { + component = adventureComponent.deepConverted(); + } + // Paper end - adventure; pass actual vanilla component + MutableComponent mutableComponent = component.getContents().resolve(commandSourceStack, entity, recursionDepth + 1); for (Component component1 : component.getSiblings()) {