From cbbdb0248f5cef374a74ac3dfb40b8f67c7db8a3 Mon Sep 17 00:00:00 2001 From: Business Goose Date: Wed, 4 May 2022 16:04:52 +0100 Subject: [PATCH 1/5] Allow players to use MiniMessage --- .../main/java/dev/plex/listener/impl/ChatListener.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/server/src/main/java/dev/plex/listener/impl/ChatListener.java b/server/src/main/java/dev/plex/listener/impl/ChatListener.java index 724e68a..2f99048 100644 --- a/server/src/main/java/dev/plex/listener/impl/ChatListener.java +++ b/server/src/main/java/dev/plex/listener/impl/ChatListener.java @@ -9,6 +9,7 @@ import io.papermc.paper.chat.ChatRenderer; import io.papermc.paper.event.player.AsyncChatEvent; import net.kyori.adventure.audience.Audience; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TextReplacementConfig; import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.format.NamedTextColor; @@ -59,7 +60,7 @@ public class ChatListener extends PlexListener @Override public @NotNull Component render(@NotNull Player source, @NotNull Component sourceDisplayName, @NotNull Component message, @NotNull Audience viewer) { - message = message.replaceText(URL_REPLACEMENT_CONFIG); + String text = ((TextComponent)message).content(); if (hasPrefix) { @@ -70,14 +71,16 @@ public class ChatListener extends PlexListener .append(Component.space()) .append(Component.text("»").color(NamedTextColor.GRAY)) .append(Component.space()) - .append(message); + .append(PlexUtils.mmDeserialize(text)) + .replaceText(URL_REPLACEMENT_CONFIG); } return Component.empty() .append(PlexUtils.mmDeserialize(plugin.config.getString("chat.name-color", "") + MiniMessage.builder().tags(TagResolver.resolver(StandardTags.color(), StandardTags.rainbow(), StandardTags.decorations(), StandardTags.gradient(), StandardTags.transition())).build().serialize(sourceDisplayName))) .append(Component.space()) .append(Component.text("»").color(NamedTextColor.GRAY)) .append(Component.space()) - .append(message); + .append(PlexUtils.mmDeserialize(text)) + .replaceText(URL_REPLACEMENT_CONFIG); } } } From d716f77ac030d3f4ec5b21e8e2fd835727c60a22 Mon Sep 17 00:00:00 2001 From: Business Goose Date: Wed, 4 May 2022 16:08:52 +0100 Subject: [PATCH 2/5] Use a variable for the chat component & if they have a prefix, append the prefix to that variable instead of using else if --- .../java/dev/plex/listener/impl/ChatListener.java | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/server/src/main/java/dev/plex/listener/impl/ChatListener.java b/server/src/main/java/dev/plex/listener/impl/ChatListener.java index 2f99048..285ef8f 100644 --- a/server/src/main/java/dev/plex/listener/impl/ChatListener.java +++ b/server/src/main/java/dev/plex/listener/impl/ChatListener.java @@ -61,20 +61,15 @@ public class ChatListener extends PlexListener public @NotNull Component render(@NotNull Player source, @NotNull Component sourceDisplayName, @NotNull Component message, @NotNull Audience viewer) { String text = ((TextComponent)message).content(); + Component component = Component.empty(); if (hasPrefix) { - return Component.empty() - .append(prefix) - .append(Component.space()) - .append(PlexUtils.mmDeserialize(plugin.config.getString("chat.name-color", "") + MiniMessage.builder().tags(TagResolver.resolver(StandardTags.color(), StandardTags.rainbow(), StandardTags.decorations(), StandardTags.gradient(), StandardTags.transition())).build().serialize(sourceDisplayName))) - .append(Component.space()) - .append(Component.text("»").color(NamedTextColor.GRAY)) - .append(Component.space()) - .append(PlexUtils.mmDeserialize(text)) - .replaceText(URL_REPLACEMENT_CONFIG); + component = component.append(prefix); } - return Component.empty() + + return component + .append(Component.space()) .append(PlexUtils.mmDeserialize(plugin.config.getString("chat.name-color", "") + MiniMessage.builder().tags(TagResolver.resolver(StandardTags.color(), StandardTags.rainbow(), StandardTags.decorations(), StandardTags.gradient(), StandardTags.transition())).build().serialize(sourceDisplayName))) .append(Component.space()) .append(Component.text("»").color(NamedTextColor.GRAY)) From 3604add18a53d081e7921dc7dcf3b3570ffed734 Mon Sep 17 00:00:00 2001 From: Business Goose Date: Wed, 4 May 2022 16:29:25 +0100 Subject: [PATCH 3/5] Add getting text from component to PlexUtils --- .../dev/plex/listener/impl/ChatListener.java | 3 +- .../main/java/dev/plex/util/PlexUtils.java | 35 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/dev/plex/listener/impl/ChatListener.java b/server/src/main/java/dev/plex/listener/impl/ChatListener.java index 285ef8f..c600dda 100644 --- a/server/src/main/java/dev/plex/listener/impl/ChatListener.java +++ b/server/src/main/java/dev/plex/listener/impl/ChatListener.java @@ -60,7 +60,8 @@ public class ChatListener extends PlexListener @Override public @NotNull Component render(@NotNull Player source, @NotNull Component sourceDisplayName, @NotNull Component message, @NotNull Audience viewer) { - String text = ((TextComponent)message).content(); + String text = PlexUtils.getTextFromComponent(message); + Component component = Component.empty(); if (hasPrefix) diff --git a/server/src/main/java/dev/plex/util/PlexUtils.java b/server/src/main/java/dev/plex/util/PlexUtils.java index 40e75d5..137dd4a 100644 --- a/server/src/main/java/dev/plex/util/PlexUtils.java +++ b/server/src/main/java/dev/plex/util/PlexUtils.java @@ -13,6 +13,7 @@ import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.standard.StandardTags; @@ -166,6 +167,40 @@ public class PlexUtils implements PlexBase return f; } + + public static String getTextFromComponent(Component component) + { + try + { + return ((TextComponent)component).content(); + } + catch (Exception e) + { + PlexLog.warn("Unable to get text of component", e.getLocalizedMessage()); + return ""; + } + } + + public static String getTextFromComponents(Component... components) + { + try + { + StringBuilder builder = new StringBuilder(); + + for (Component component : components) + { + builder.append(getTextFromComponent(component)); + } + + return builder.toString(); + } + catch (Exception e) + { + PlexLog.warn("Unable to get text of components", e.getLocalizedMessage()); + return ""; + } + } + public static List getPlayerNameList() { return Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList()); From 45b338fd9b56f035916398e94b382bc9d4390cb2 Mon Sep 17 00:00:00 2001 From: Business Goose Date: Wed, 4 May 2022 17:08:35 +0100 Subject: [PATCH 4/5] Make a safe mini message class with a custom tag resolver --- .../java/dev/plex/command/impl/TagCMD.java | 18 +------ .../dev/plex/listener/impl/ChatListener.java | 4 +- .../main/java/dev/plex/rank/RankManager.java | 4 +- .../main/java/dev/plex/util/PlexUtils.java | 20 +++----- .../util/minimessage/SafeMiniMessage.java | 48 +++++++++++++++++++ 5 files changed, 61 insertions(+), 33 deletions(-) create mode 100644 server/src/main/java/dev/plex/util/minimessage/SafeMiniMessage.java diff --git a/server/src/main/java/dev/plex/command/impl/TagCMD.java b/server/src/main/java/dev/plex/command/impl/TagCMD.java index e03658b..5f70123 100644 --- a/server/src/main/java/dev/plex/command/impl/TagCMD.java +++ b/server/src/main/java/dev/plex/command/impl/TagCMD.java @@ -7,10 +7,9 @@ import dev.plex.command.annotation.CommandPermissions; import dev.plex.command.source.RequiredCommandSource; import dev.plex.player.PlexPlayer; import dev.plex.rank.enums.Rank; -import dev.plex.util.PlexUtils; +import dev.plex.util.minimessage.SafeMiniMessage; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.minimessage.tag.standard.StandardTags; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.apache.commons.lang.StringUtils; import org.bukkit.command.CommandSender; @@ -49,7 +48,7 @@ public class TagCMD extends PlexCommand } String prefix = StringUtils.join(args, " ", 1, args.length); - Component convertedComponent = removeEvents(PlexUtils.mmCustomDeserialize(prefix = prefix.replace("", "").replace("
", ""), StandardTags.color(), StandardTags.rainbow(), StandardTags.decorations(), StandardTags.gradient(), StandardTags.transition())); //noColorComponentFromString(prefix) + Component convertedComponent = SafeMiniMessage.mmDeserializeWithoutEvents(prefix); if (PlainTextComponentSerializer.plainText().serialize(convertedComponent).length() > plugin.config.getInt("chat.max-tag-length", 16)) { @@ -90,19 +89,6 @@ public class TagCMD extends PlexCommand } return usage(); } - - private Component removeEvents(Component component) - { - if (component.clickEvent() != null) - { - component = component.clickEvent(null); - } - if (component.hoverEvent() != null) - { - component = component.hoverEvent(null); - } - return component; - } } diff --git a/server/src/main/java/dev/plex/listener/impl/ChatListener.java b/server/src/main/java/dev/plex/listener/impl/ChatListener.java index c600dda..493040b 100644 --- a/server/src/main/java/dev/plex/listener/impl/ChatListener.java +++ b/server/src/main/java/dev/plex/listener/impl/ChatListener.java @@ -5,11 +5,11 @@ import dev.plex.listener.PlexListener; import dev.plex.listener.annotation.Toggleable; import dev.plex.player.PlexPlayer; import dev.plex.util.PlexUtils; +import dev.plex.util.minimessage.SafeMiniMessage; import io.papermc.paper.chat.ChatRenderer; import io.papermc.paper.event.player.AsyncChatEvent; import net.kyori.adventure.audience.Audience; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TextReplacementConfig; import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.format.NamedTextColor; @@ -75,7 +75,7 @@ public class ChatListener extends PlexListener .append(Component.space()) .append(Component.text("»").color(NamedTextColor.GRAY)) .append(Component.space()) - .append(PlexUtils.mmDeserialize(text)) + .append(SafeMiniMessage.mmDeserializeWithoutEvents(text)) .replaceText(URL_REPLACEMENT_CONFIG); } } diff --git a/server/src/main/java/dev/plex/rank/RankManager.java b/server/src/main/java/dev/plex/rank/RankManager.java index 4b7e984..41c25de 100644 --- a/server/src/main/java/dev/plex/rank/RankManager.java +++ b/server/src/main/java/dev/plex/rank/RankManager.java @@ -5,6 +5,7 @@ import dev.plex.player.PlexPlayer; import dev.plex.rank.enums.Rank; import dev.plex.rank.enums.Title; import dev.plex.util.PlexUtils; +import dev.plex.util.minimessage.SafeMiniMessage; import java.io.File; import java.io.FileInputStream; import java.io.FileWriter; @@ -14,7 +15,6 @@ import java.util.stream.Collectors; import lombok.SneakyThrows; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.minimessage.tag.standard.StandardTags; import org.json.JSONArray; import org.json.JSONObject; import org.json.JSONTokener; @@ -95,7 +95,7 @@ public class RankManager { if (!player.getPrefix().equals("")) { - return PlexUtils.mmCustomDeserialize(player.getPrefix(), StandardTags.color(), StandardTags.rainbow(), StandardTags.decorations(), StandardTags.gradient(), StandardTags.transition()); + return SafeMiniMessage.mmDeserializeWithoutEvents(player.getPrefix()); } if (Plex.get().config.contains("titles.owners") && Plex.get().config.getStringList("titles.owners").contains(player.getName())) { diff --git a/server/src/main/java/dev/plex/util/PlexUtils.java b/server/src/main/java/dev/plex/util/PlexUtils.java index 137dd4a..6be9f53 100644 --- a/server/src/main/java/dev/plex/util/PlexUtils.java +++ b/server/src/main/java/dev/plex/util/PlexUtils.java @@ -30,6 +30,8 @@ import org.bukkit.plugin.Plugin; public class PlexUtils implements PlexBase { + private static final MiniMessage MINI_MESSAGE = MiniMessage.miniMessage(); + public static List DEVELOPERS = Arrays.asList("78408086-1991-4c33-a571-d8fa325465b2", // Telesphoreo "f5cd54c4-3a24-4213-9a56-c06c49594dff", // Taahh @@ -114,14 +116,6 @@ public class PlexUtils implements PlexBase return false; } - private static final MiniMessage safeMessage = MiniMessage.builder().tags(TagResolver.builder().resolvers( - StandardTags.color(), - StandardTags.decorations(), - StandardTags.gradient(), - StandardTags.rainbow(), - StandardTags.reset() - ).build()).build(); - public static String mmStripColor(String input) { return PlainTextComponentSerializer.plainText().serialize(mmDeserialize(input)); @@ -137,10 +131,10 @@ public class PlexUtils implements PlexBase ZonedDateTime date = ZonedDateTime.now(ZoneId.of(TimeUtils.TIMEZONE)); if (aprilFools && date.getMonth() == Month.APRIL && date.getDayOfMonth() == 1) { - Component component = MiniMessage.miniMessage().deserialize(input); // removes existing tags - return MiniMessage.miniMessage().deserialize("" + PlainTextComponentSerializer.plainText().serialize(component)); + Component component = MINI_MESSAGE.deserialize(input); // removes existing tags + return MINI_MESSAGE.deserialize("" + PlainTextComponentSerializer.plainText().serialize(component)); } - return MiniMessage.miniMessage().deserialize(input); + return MINI_MESSAGE.deserialize(input); } public static Component mmCustomDeserialize(String input, TagResolver... resolvers) @@ -150,7 +144,7 @@ public class PlexUtils implements PlexBase public static Component messageComponent(String entry, Object... objects) { - return MiniMessage.miniMessage().deserialize(messageString(entry, objects)); + return MINI_MESSAGE.deserialize(messageString(entry, objects)); } public static String messageString(String entry, Object... objects) @@ -208,7 +202,7 @@ public class PlexUtils implements PlexBase public static void broadcast(String s) { - Bukkit.broadcast(MiniMessage.miniMessage().deserialize(s)); + Bukkit.broadcast(MINI_MESSAGE.deserialize(s)); } public static void broadcast(Component component) diff --git a/server/src/main/java/dev/plex/util/minimessage/SafeMiniMessage.java b/server/src/main/java/dev/plex/util/minimessage/SafeMiniMessage.java new file mode 100644 index 0000000..3a76bac --- /dev/null +++ b/server/src/main/java/dev/plex/util/minimessage/SafeMiniMessage.java @@ -0,0 +1,48 @@ +package dev.plex.util.minimessage; + +import com.google.common.collect.ImmutableList; +import java.util.List; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.Context; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.ParsingException; +import net.kyori.adventure.text.minimessage.tag.Tag; +import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class SafeMiniMessage +{ + public static final MiniMessage MINI_MESSAGE = MiniMessage.builder().tags(new SafeMiniMessageTagResolver()).build(); + + public static Component mmDeserialize(String text) + { + return MINI_MESSAGE.deserialize(text); + } + + public static Component mmDeserializeWithoutEvents(String text) + { + return mmDeserialize(text) + .clickEvent(null) + .hoverEvent(null); + } + + public static class SafeMiniMessageTagResolver implements TagResolver + { + private static final TagResolver STANDARD_RESOLVER = TagResolver.standard(); + private static final List IGNORED_TAGS = ImmutableList.of("obfuscated", "obf", "br", "newline"); + + @Override + public @Nullable Tag resolve(@NotNull String name, @NotNull ArgumentQueue arguments, @NotNull Context ctx) throws ParsingException + { + return IGNORED_TAGS.contains(name.toLowerCase()) ? null : STANDARD_RESOLVER.resolve(name, arguments, ctx); + } + + @Override + public boolean has(@NotNull String name) + { + return STANDARD_RESOLVER.has(name); + } + } +} From 0e3eeaeac36360d4be9548e70f1f68c6baae55c8 Mon Sep 17 00:00:00 2001 From: Business Goose Date: Wed, 4 May 2022 17:40:58 +0100 Subject: [PATCH 5/5] Allow books and signs to use SafeMiniMessage --- .../dev/plex/listener/impl/BookListener.java | 30 +++++++++++++++++++ .../dev/plex/listener/impl/SignListener.java | 20 +++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 server/src/main/java/dev/plex/listener/impl/BookListener.java create mode 100644 server/src/main/java/dev/plex/listener/impl/SignListener.java diff --git a/server/src/main/java/dev/plex/listener/impl/BookListener.java b/server/src/main/java/dev/plex/listener/impl/BookListener.java new file mode 100644 index 0000000..701f628 --- /dev/null +++ b/server/src/main/java/dev/plex/listener/impl/BookListener.java @@ -0,0 +1,30 @@ +package dev.plex.listener.impl; + +import dev.plex.listener.PlexListener; +import dev.plex.util.PlexUtils; +import dev.plex.util.minimessage.SafeMiniMessage; +import java.util.ArrayList; +import java.util.List; +import net.kyori.adventure.inventory.Book; +import net.kyori.adventure.text.Component; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerEditBookEvent; +import org.bukkit.inventory.meta.BookMeta; + +public class BookListener extends PlexListener +{ + @EventHandler(priority = EventPriority.HIGHEST) + public void onBookEdit(PlayerEditBookEvent event) + { + List pages = new ArrayList<>(); + + for (Component page : event.getNewBookMeta().pages()) + { + pages.add(SafeMiniMessage.mmDeserialize(PlexUtils.getTextFromComponent(page))); + } + + + event.setNewBookMeta((BookMeta)event.getNewBookMeta().pages(pages)); + } +} diff --git a/server/src/main/java/dev/plex/listener/impl/SignListener.java b/server/src/main/java/dev/plex/listener/impl/SignListener.java new file mode 100644 index 0000000..ce4b613 --- /dev/null +++ b/server/src/main/java/dev/plex/listener/impl/SignListener.java @@ -0,0 +1,20 @@ +package dev.plex.listener.impl; + +import dev.plex.listener.PlexListener; +import dev.plex.util.PlexUtils; +import dev.plex.util.minimessage.SafeMiniMessage; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.SignChangeEvent; + +public class SignListener extends PlexListener +{ + @EventHandler(priority = EventPriority.HIGHEST) + public void onSignEdit(SignChangeEvent event) + { + for (int i = 0; i < event.lines().size(); i++) + { + event.line(i, SafeMiniMessage.mmDeserialize(PlexUtils.getTextFromComponent(event.line(i)))); + } + } +}