From 43dafcce6d770759e3fd6c64785fad34ecc771b2 Mon Sep 17 00:00:00 2001 From: Scarlet-Phonavis Date: Fri, 5 Jul 2024 19:51:00 -0500 Subject: [PATCH] properties, shadows, and merges --- .../simpleircbridge/GameEventHandler.java | 9 +- .../SimpleIRCBridgeCommon.java | 99 +++++++++++++++++-- gradle.properties | 2 +- 3 files changed, 97 insertions(+), 13 deletions(-) diff --git a/common/src/main/java/net/stonebound/simpleircbridge/simpleircbridge/GameEventHandler.java b/common/src/main/java/net/stonebound/simpleircbridge/simpleircbridge/GameEventHandler.java index ec9a1db..5e6b9b1 100644 --- a/common/src/main/java/net/stonebound/simpleircbridge/simpleircbridge/GameEventHandler.java +++ b/common/src/main/java/net/stonebound/simpleircbridge/simpleircbridge/GameEventHandler.java @@ -3,6 +3,7 @@ import static net.stonebound.simpleircbridge.simpleircbridge.Config.ircFormatting; import static net.stonebound.simpleircbridge.simpleircbridge.SIBConstants.*; +import dev.architectury.event.events.common.ChatEvent; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.stonebound.simpleircbridge.utils.IRCMinecraftConverter; @@ -53,8 +54,12 @@ public void playerLoggedOut(ServerPlayer e) { // } - public void serverChat(ServerPlayer player, Component component) { - String content = SIBUtil.getRawText(component); + public void serverChat(ServerPlayer player, ChatEvent.ChatComponent component) { + Component chatComponent = component.get().copy(); + String content = SIBUtil.getRawText(chatComponent); + component.set(SimpleIRCBridgeCommon.newChatWithLinks(content, false)); + + if (player != null) { String playername = player.getName().getString(); diff --git a/common/src/main/java/net/stonebound/simpleircbridge/simpleircbridge/SimpleIRCBridgeCommon.java b/common/src/main/java/net/stonebound/simpleircbridge/simpleircbridge/SimpleIRCBridgeCommon.java index a73606d..d043e70 100644 --- a/common/src/main/java/net/stonebound/simpleircbridge/simpleircbridge/SimpleIRCBridgeCommon.java +++ b/common/src/main/java/net/stonebound/simpleircbridge/simpleircbridge/SimpleIRCBridgeCommon.java @@ -5,14 +5,22 @@ import dev.architectury.event.events.common.ChatEvent; import dev.architectury.event.events.common.LifecycleEvent; import dev.architectury.event.events.common.PlayerEvent; +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.ClickEvent; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.TextColor; import net.minecraft.server.MinecraftServer; import net.stonebound.simpleircbridge.utils.MircColors; import org.slf4j.Logger; import static net.stonebound.simpleircbridge.simpleircbridge.Config.channel; import static net.stonebound.simpleircbridge.simpleircbridge.Config.timestop; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class SimpleIRCBridgeCommon { @@ -32,13 +40,12 @@ public SimpleIRCBridgeCommon() { PlayerEvent.PLAYER_JOIN.register((Playerjoin) -> eventHandler.playerLoggedIn(Playerjoin)); PlayerEvent.PLAYER_QUIT.register((Playerquit) -> eventHandler.playerLoggedOut(Playerquit)); - ChatEvent.RECEIVED.register((ServerPlayer player, Component chat) -> { - eventHandler.serverChat(player, chat); - return EventResult.pass(); - }); + LifecycleEvent.SERVER_STARTING.register(this::serverStarting); LifecycleEvent.SERVER_STOPPING.register(this::serverStopping); LifecycleEvent.SERVER_STOPPED.register(this::serverStopped); + ChatEvent.DECORATE.register(eventHandler::serverChat); + } @@ -79,10 +86,82 @@ static Logger log() { } } - /* package-private */ - void sendToMinecraft (String line){ - if (this.mcServer != null) { - this.mcServer.getPlayerList().getPlayers().forEach(player -> player.sendSystemMessage(Component.literal(line))); - } - } + + /* package-private */ + void sendToMinecraft(String line) { + if (this.mcServer != null) { + this.mcServer.getPlayerList().getPlayers().forEach(player -> player.sendSystemMessage(newChatWithLinks(line, true))); + } + } + + /* + * Copyright (c) Forge Development LLC and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + static final Pattern URL_PATTERN = Pattern.compile( + // schema ipv4 OR namespace port path ends + // |-----------------| |-------------------------| |-------------------------| |---------| |--| |---------------| + "((?:[a-z0-9]{2,}:\\/\\/)?(?:(?:[0-9]{1,3}\\.){3}[0-9]{1,3}|(?:[-\\w_]{1,}\\.[a-z]{2,}?))(?::[0-9]{1,5})?.*?(?=[!\"\u00A7 \n]|$))", + Pattern.CASE_INSENSITIVE); + + public static Component newChatWithLinks(String string, boolean allowMissingHeader) { + // Includes ipv4 and domain pattern + // Matches an ip (xx.xxx.xx.xxx) or a domain (something.com) with or + // without a protocol or path. + MutableComponent ichat = null; + Matcher matcher = URL_PATTERN.matcher(string); + int lastEnd = 0; + + // Find all urls + while (matcher.find()) { + int start = matcher.start(); + int end = matcher.end(); + + // Append the previous left overs. + String part = string.substring(lastEnd, start); + if (!part.isEmpty()) { + if (ichat == null) + ichat = Component.literal(part); + else + ichat.append(part); + } + lastEnd = end; + String url = string.substring(start, end); + MutableComponent link = Component.literal(url); + + try { + // Add schema so client doesn't crash. + if ((new URI(url)).getScheme() == null) { + if (!allowMissingHeader) { + if (ichat == null) + ichat = Component.literal(url); + else + ichat.append(url); + continue; + } + url = "http://" + url; + } + } catch (URISyntaxException e) { + // Bad syntax bail out! + if (ichat == null) ichat = Component.literal(url); + else ichat.append(url); + continue; + } + + // Set the click event and append the link. + ClickEvent click = new ClickEvent(ClickEvent.Action.OPEN_URL, url); + link.setStyle(link.getStyle().withClickEvent(click).withUnderlined(true).withColor(TextColor.fromLegacyFormat(ChatFormatting.BLUE))); + if (ichat == null) + ichat = Component.literal(""); + ichat.append(link); + } + + // Append the rest of the message. + String end = string.substring(lastEnd); + if (ichat == null) + ichat = Component.literal(end); + else if (!end.isEmpty()) + ichat.append(Component.literal(string.substring(lastEnd))); + return ichat; + } } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index d9ddda8..c4b6872 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx2G org.gradle.parallel=true # Mod properties -mod_version = 1.0.3 +mod_version = 1.0.4 maven_group = net.stonebound.simpleircbridge archives_name = simpleircbridge enabled_platforms = fabric,forge,neoforge,quilt