diff --git a/src/paper/java/me/clip/placeholderapi/PAPIComponents.java b/src/paper/java/me/clip/placeholderapi/PAPIComponents.java index dc341c2..1eeedf0 100644 --- a/src/paper/java/me/clip/placeholderapi/PAPIComponents.java +++ b/src/paper/java/me/clip/placeholderapi/PAPIComponents.java @@ -25,11 +25,14 @@ import me.clip.placeholderapi.replacer.ExactReplacer; import me.clip.placeholderapi.replacer.RelationalExactReplacer; import me.clip.placeholderapi.replacer.Replacer; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.ComponentLike; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.function.Function; import java.util.stream.Collectors; import static me.clip.placeholderapi.PlaceholderAPI.RELATIONAL_PLACEHOLDER_PATTERN; @@ -43,122 +46,236 @@ public final class PAPIComponents { * Translates all placeholders into their corresponding values. *
The pattern of a valid placeholder is {@literal %_%}. * - * @param player Player to parse the placeholders against + * @param player Player to parse the placeholders against * @param component Component to set the placeholder values in * @return Component containing all translated placeholders */ @NotNull public static Component setPlaceholders(final OfflinePlayer player, @NotNull final Component component) { - if (PlaceholderAPIPlugin.getInstance().getPlaceholderAPIConfig().useAdventureProvidedReplacer()) { - return component.replaceText(config -> config.match(PlaceholderAPI.PLACEHOLDER_PATTERN).replacement((result, builder) -> - builder.content(PERCENT_EXACT_REPLACER.apply(result.group(), player, PlaceholderAPIPlugin.getInstance().getLocalExpansionManager()::getExpansion)))); - } - - return ComponentReplacer.replace(component, str -> PlaceholderAPI.setPlaceholders(player, str)); + return setPlaceholders(player, component, null); } /** * Translates all placeholders into their corresponding values. *
The pattern of a valid placeholder is {@literal %_%}. * - * @param player Player to parse the placeholders against + * @param player Player to parse the placeholders against + * @param component Component to set the placeholder values in + * @param deserializer Optional function to serialize parsed placeholder values into ComponentLike + * @return Component containing all translated placeholders + */ + @NotNull + public static Component setPlaceholders(final OfflinePlayer player, @NotNull final Component component, @Nullable Function deserializer) { + if (PlaceholderAPIPlugin.getInstance().getPlaceholderAPIConfig().useAdventureProvidedReplacer()) { + return component.replaceText(config -> config.match(PlaceholderAPI.PLACEHOLDER_PATTERN).replacement((result, builder) -> { + String parsed = PERCENT_EXACT_REPLACER.apply(result.group(), player, PlaceholderAPIPlugin.getInstance().getLocalExpansionManager()::getExpansion); + return deserializer == null ? builder.content(parsed) : deserializer.apply(parsed); + })); + } + + return ComponentReplacer.replace(component, str -> PlaceholderAPI.setPlaceholders(player, str), deserializer == null ? null : s -> deserializer.apply(s).asComponent()); + } + + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal %_%}. + * + * @param player Player to parse the placeholders against * @param components List of Components to set the placeholder values in * @return List of Components containing all translated placeholders */ @NotNull public static List setPlaceholders(final OfflinePlayer player, @NotNull final List components) { - return components.stream().map(component -> setPlaceholders(player, component)).collect(Collectors.toList()); + return setPlaceholders(player, components, null); } /** * Translates all placeholders into their corresponding values. *
The pattern of a valid placeholder is {@literal %_%}. * - * @param player Player to parse the placeholders against + * @param player Player to parse the placeholders against + * @param components List of Components to set the placeholder values in + * @param deserializer Optional function to serialize parsed placeholder values into ComponentLike + * @return List of Components containing all translated placeholders + */ + @NotNull + public static List setPlaceholders(final OfflinePlayer player, @NotNull final List components, @Nullable Function deserializer) { + return components.stream().map(component -> setPlaceholders(player, component, deserializer == null ? null : s -> deserializer.apply(s).asComponent())).collect(Collectors.toList()); + } + + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal %_%}. + * + * @param player Player to parse the placeholders against * @param component Component to set the placeholder values in * @return Component containing all translated placeholders */ @NotNull public static Component setPlaceholders(final Player player, @NotNull final Component component) { - return setPlaceholders((OfflinePlayer) player, component); + return setPlaceholders(player, component, null); } /** * Translates all placeholders into their corresponding values. *
The pattern of a valid placeholder is {@literal %_%}. * - * @param player Player to parse the placeholders against + * @param player Player to parse the placeholders against + * @param component Component to set the placeholder values in + * @param deserializer Optional function to serialize parsed placeholder values into ComponentLike + * @return Component containing all translated placeholders + */ + @NotNull + public static Component setPlaceholders(final Player player, @NotNull final Component component, @Nullable Function deserializer) { + return setPlaceholders((OfflinePlayer) player, component, deserializer); + } + + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal %_%}. + * + * @param player Player to parse the placeholders against * @param components List of Components to set the placeholder values in * @return List of components containing all translated placeholders */ @NotNull public static List setPlaceholders(final Player player, @NotNull final List components) { - return setPlaceholders((OfflinePlayer) player, components); + return setPlaceholders(player, components, null); + } + + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal %_%}. + * + * @param player Player to parse the placeholders against + * @param components List of Components to set the placeholder values in + * @param deserializer Optional function to serialize parsed placeholder values into ComponentLike + * @return List of components containing all translated placeholders + */ + @NotNull + public static List setPlaceholders(final Player player, @NotNull final List components, @Nullable Function deserializer) { + return setPlaceholders((OfflinePlayer) player, components, deserializer); } /** * Translates all placeholders into their corresponding values. *
The pattern of a valid placeholder is {@literal {_}}. * - * @param player Player to parse the placeholders against + * @param player Player to parse the placeholders against * @param component Component to set the placeholder values in * @return Component containing all translated placeholders */ @NotNull public static Component setBracketPlaceholders(final OfflinePlayer player, @NotNull final Component component) { + return setBracketPlaceholders(player, component, null); + } + + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal {_}}. + * + * @param player Player to parse the placeholders against + * @param component Component to set the placeholder values in + * @param deserializer Optional function to serialize parsed placeholder values into ComponentLike + * @return Component containing all translated placeholders + */ + @NotNull + public static Component setBracketPlaceholders(final OfflinePlayer player, @NotNull final Component component, @Nullable Function deserializer) { if (PlaceholderAPIPlugin.getInstance().getPlaceholderAPIConfig().useAdventureReplacer()) { return component.replaceText(config -> config.match(PlaceholderAPI.BRACKET_PLACEHOLDER_PATTERN).replacement((result, builder) -> builder.content(BRACKET_EXACT_REPLACER.apply(result.group(), player, PlaceholderAPIPlugin.getInstance().getLocalExpansionManager()::getExpansion)))); } - return ComponentReplacer.replace(component, str -> PlaceholderAPI.setBracketPlaceholders(player, str)); + return ComponentReplacer.replace(component, str -> PlaceholderAPI.setBracketPlaceholders(player, str), deserializer == null ? null : s -> deserializer.apply(s).asComponent()); } /** * Translates all placeholders into their corresponding values. *
The pattern of a valid placeholder is {@literal {_}}. * - * @param player Player to parse the placeholders against + * @param player Player to parse the placeholders against * @param components List of Components to set the placeholder values in * @return List of Components containing all translated placeholders */ @NotNull public static List setBracketPlaceholders(final OfflinePlayer player, @NotNull final List components) { - return components.stream().map(component -> setBracketPlaceholders(player, component)).collect(Collectors.toList()); + return setBracketPlaceholders(player, components, null); } /** * Translates all placeholders into their corresponding values. *
The pattern of a valid placeholder is {@literal {_}}. * - * @param player Player to parse the placeholders against + * @param player Player to parse the placeholders against + * @param components List of Components to set the placeholder values in + * @param deserializer Optional function to serialize parsed placeholder values into ComponentLike + * @return List of Components containing all translated placeholders + */ + @NotNull + public static List setBracketPlaceholders(final OfflinePlayer player, @NotNull final List components, @Nullable Function deserializer) { + return components.stream().map(component -> setBracketPlaceholders(player, component, deserializer)).collect(Collectors.toList()); + } + + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal {_}}. + * + * @param player Player to parse the placeholders against * @param component Component to set the placeholder values in * @return Component containing all translated placeholders */ @NotNull public static Component setBracketPlaceholders(final Player player, @NotNull final Component component) { - return setBracketPlaceholders((OfflinePlayer) player, component); + return setBracketPlaceholders(player, component, null); } /** * Translates all placeholders into their corresponding values. *
The pattern of a valid placeholder is {@literal {_}}. * - * @param player Player to parse the placeholders against + * @param player Player to parse the placeholders against + * @param component Component to set the placeholder values in + * @param deserializer Optional function to serialize parsed placeholder values into ComponentLike + * @return Component containing all translated placeholders + */ + @NotNull + public static Component setBracketPlaceholders(final Player player, @NotNull final Component component, @Nullable Function deserializer) { + return setBracketPlaceholders((OfflinePlayer) player, component, deserializer); + } + + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal {_}}. + * + * @param player Player to parse the placeholders against * @param components List of Components to set the placeholder values in * @return List of Components containing all translated placeholders */ @NotNull public static List setBracketPlaceholders(final Player player, @NotNull final List components) { - return setBracketPlaceholders((OfflinePlayer) player, components); + return setBracketPlaceholders(player, components, null); + } + + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal {_}}. + * + * @param player Player to parse the placeholders against + * @param components List of Components to set the placeholder values in + * @param deserializer Optional function to serialize parsed placeholder values into ComponentLike + * @return List of Components containing all translated placeholders + */ + @NotNull + public static List setBracketPlaceholders(final Player player, @NotNull final List components, @Nullable Function deserializer) { + return setBracketPlaceholders((OfflinePlayer) player, components, deserializer); } /** * set relational placeholders in the text specified placeholders are matched with the pattern * {@literal %%} when set with this method * - * @param one First player to compare - * @param two Second player to compare + * @param one First player to compare + * @param two Second player to compare * @param component Component to parse the placeholders in * @return The Component containing the parsed relational placeholders */ @@ -172,8 +289,8 @@ public final class PAPIComponents { * Translate placeholders in the provided List based on the relation of the two provided players. *
The pattern of a valid placeholder is {@literal %rel__%}. * - * @param one Player to compare - * @param two Player to compare + * @param one Player to compare + * @param two Player to compare * @param components List of Components to parse the placeholder values to * @return The List of Components containing the parsed relational placeholders */ @@ -181,4 +298,4 @@ public final class PAPIComponents { return components.stream().map(line -> setRelationalPlaceholders(one, two, line)) .collect(Collectors.toList()); } -} +} \ No newline at end of file diff --git a/src/paper/java/me/clip/placeholderapi/replacer/ComponentReplacer.java b/src/paper/java/me/clip/placeholderapi/replacer/ComponentReplacer.java index a14b0a0..cfa593b 100644 --- a/src/paper/java/me/clip/placeholderapi/replacer/ComponentReplacer.java +++ b/src/paper/java/me/clip/placeholderapi/replacer/ComponentReplacer.java @@ -8,6 +8,7 @@ import net.kyori.adventure.text.event.DataComponentValue; import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.format.Style; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.HashMap; @@ -17,25 +18,25 @@ import java.util.function.Function; public class ComponentReplacer { @NotNull - public static Component replace(@NotNull final Component component, @NotNull final Function replacer) { - return rebuild(component, replacer); + public static Component replace(@NotNull final Component component, @NotNull final Function replacer, @Nullable final Function deserializer) { + return rebuild(component, replacer, deserializer); } @NotNull - private static Component rebuild(@NotNull final Component component, @NotNull final Function replacer) { + private static Component rebuild(@NotNull final Component component, @NotNull final Function replacer, @Nullable final Function deserializer) { Component rebuilt; if (component instanceof TextComponent) { final TextComponent text = (TextComponent) component; final String replaced = replacer.apply(text.content()); - rebuilt = Component.text(replaced); + rebuilt = deserializer == null ? Component.text(replaced) : deserializer.apply(replaced); } else if (component instanceof TranslatableComponent) { final TranslatableComponent translatable = (TranslatableComponent) component; final List arguments = new ArrayList<>(); for (final ComponentLike arg : translatable.arguments()) { - arguments.add(rebuild(arg.asComponent(), replacer)); + arguments.add(rebuild(arg.asComponent(), replacer, deserializer)); } rebuilt = Component.translatable(translatable.key(), arguments); @@ -52,12 +53,12 @@ public class ComponentReplacer { rebuilt = Component.empty(); } - rebuilt = rebuilt.style(rebuildStyle(component.style(), replacer)); + rebuilt = rebuilt.style(rebuildStyle(component.style(), replacer, deserializer)); if (!component.children().isEmpty()) { final List children = new ArrayList<>(); for (Component child : component.children()) { - children.add(rebuild(child, replacer)); + children.add(rebuild(child, replacer, deserializer)); } rebuilt = rebuilt.children(children); } @@ -66,7 +67,7 @@ public class ComponentReplacer { } @NotNull - private static Style rebuildStyle(@NotNull final Style style, @NotNull final Function replacer) { + private static Style rebuildStyle(@NotNull final Style style, @NotNull final Function replacer, @Nullable final Function deserializer) { final Style.Builder builder = style.toBuilder(); final ClickEvent click = style.clickEvent(); @@ -77,7 +78,7 @@ public class ComponentReplacer { final HoverEvent hover = style.hoverEvent(); if (hover != null) { - builder.hoverEvent(rebuildHoverEvent(hover, replacer)); + builder.hoverEvent(rebuildHoverEvent(hover, replacer, deserializer)); } return builder.build(); @@ -113,11 +114,11 @@ public class ComponentReplacer { } @NotNull - private static HoverEvent rebuildHoverEvent(@NotNull final HoverEvent hover, @NotNull final Function replacer) { + private static HoverEvent rebuildHoverEvent(@NotNull final HoverEvent hover, @NotNull final Function replacer, @Nullable final Function deserializer) { final Object value = hover.value(); if (value instanceof Component) { - final Component rebuilt = rebuild((Component) value, replacer); + final Component rebuilt = rebuild((Component) value, replacer, deserializer); return HoverEvent.showText(rebuilt); } @@ -130,7 +131,7 @@ public class ComponentReplacer { Component rebuiltName = null; if (entity.name() != null) { - rebuiltName = rebuild(entity.name(), replacer); + rebuiltName = rebuild(entity.name(), replacer, deserializer); } return HoverEvent.showEntity(entity.type(), entity.id(), rebuiltName);