From 9cf76a8ee6bbcd946d5f6e9a88deea2b0b0fa40f Mon Sep 17 00:00:00 2001 From: Allink Date: Sun, 2 Apr 2023 01:11:43 +0100 Subject: [PATCH] Make links clickable again with a TextReplacementConfig Fixes #341 --- .../extras/modules/player/PlayerChat.java | 59 ++++++++++++++++--- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/src/main/java/pw/kaboom/extras/modules/player/PlayerChat.java b/src/main/java/pw/kaboom/extras/modules/player/PlayerChat.java index b898478..a282f28 100644 --- a/src/main/java/pw/kaboom/extras/modules/player/PlayerChat.java +++ b/src/main/java/pw/kaboom/extras/modules/player/PlayerChat.java @@ -2,18 +2,24 @@ package pw.kaboom.extras.modules.player; import io.papermc.paper.chat.ChatRenderer; import io.papermc.paper.event.player.AsyncChatEvent; -import java.io.IOException; -import java.util.UUID; -import javax.annotation.Nonnull; 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; +import net.kyori.adventure.text.format.TextDecoration; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import javax.annotation.Nonnull; +import java.io.IOException; +import java.util.UUID; +import java.util.regex.Pattern; + public final class PlayerChat implements Listener { private static final PlayerChatRenderer CHAT_RENDERER = new PlayerChatRenderer(); @@ -39,6 +45,43 @@ public final class PlayerChat implements Listener { } public static class PlayerChatRenderer implements ChatRenderer { + private static final TextReplacementConfig URL_REPLACEMENT_CONFIG = + TextReplacementConfig + .builder() + .match(Pattern + .compile("((https?://(www\\.)?)?[-a-zA-Z0-9@:%._+~#=]" + + "{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_+.~#?&/=]*))")) + .replacement((b, c) -> { + if (c == null) { + return null; + } + + if (b.groupCount() < 1) { + return null; + } + + final String content = b.group(1); + final String url; + + /* + Minecraft doesn't accept "www.google.com" or "google.com" as URLs + in click events + */ + if (content.contains("://")) { + url = content; + } else { + url = "https://" + content; + } + + return Component.text(content, NamedTextColor.BLUE) + .decorate(TextDecoration.UNDERLINED) + .clickEvent(ClickEvent.openUrl(url)); + }) + .build(); + + private static final LegacyComponentSerializer LEGACY_COMPONENT_SERIALIZER = + LegacyComponentSerializer + .legacyAmpersand(); @Override public @Nonnull Component render(@Nonnull Player player, @@ -65,10 +108,12 @@ public final class PlayerChat implements Listener { .append(Component.text(":")) .append(Component.space()); - return newComponent.append(LegacyComponentSerializer - .legacyAmpersand() - .deserialize(message) - ); + final Component messageWithColorCodes = LEGACY_COMPONENT_SERIALIZER + .deserialize(message); + final Component completedMessage = messageWithColorCodes + .replaceText(URL_REPLACEMENT_CONFIG); + + return newComponent.append(completedMessage); } } }