diff --git a/mod-fabric/resources/pixelchat.mixins.json b/mod-fabric/resources/pixelchat.mixins.json index 003321a..bae1f33 100644 --- a/mod-fabric/resources/pixelchat.mixins.json +++ b/mod-fabric/resources/pixelchat.mixins.json @@ -6,7 +6,8 @@ "defaultRequire": 1 }, "client": [ + "BossBarHudMixin", "ChatScreenMixin", - "BossBarHudMixin" + "ChatHudMixin" ] } \ No newline at end of file diff --git a/mod-fabric/src/eu/e99/pixelchat/fabric/mixin/ChatHudMixin.java b/mod-fabric/src/eu/e99/pixelchat/fabric/mixin/ChatHudMixin.java new file mode 100644 index 0000000..00ae260 --- /dev/null +++ b/mod-fabric/src/eu/e99/pixelchat/fabric/mixin/ChatHudMixin.java @@ -0,0 +1,107 @@ +package eu.e99.pixelchat.fabric.mixin; + +import net.minecraft.client.gui.hud.ChatHud; +import net.minecraft.text.*; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; + +@Mixin(ChatHud.class) +public class ChatHudMixin { + + @ModifyVariable( + method = "addMessage(Lnet/minecraft/text/Text;Lnet/minecraft/network/message/MessageSignatureData;Lnet/minecraft/client/gui/hud/MessageIndicator;)V", + at = @At("HEAD"), + index = 1, + argsOnly = true + ) + private Text pixelchat$modifyText(Text text) { + TextContent content = text.getContent(); + List siblings = text.getSiblings().stream() + .map(this::pixelchat$modifyText) + .toList(); + Style style = text.getStyle(); + + return switch (content) { + case PlainTextContent plain -> { + String string = plain.string(); + + MutableText newText = newTextWithLinks(string); + for (Text sibling : siblings) { + newText = newText.append(sibling); + } + + newText = newText.setStyle(style); + yield newText; + } + case TranslatableTextContent translatable -> { + Object[] args = translatable.getArgs(); + for (int i = 0; i < args.length; i++) { + args[i] = switch (args[i]) { + case Text arg -> pixelchat$modifyText(arg); + case String string -> newTextWithLinks(string); + default -> args; + }; + } + + yield newText( + new TranslatableTextContent( + translatable.getKey(), + translatable.getFallback(), + args + ), + siblings, + style + ); + } + default -> text; + }; + } + + @Unique + private MutableText newText(TextContent content, List siblings, Style style) { + MutableText text = MutableText.of(content); + for (Text sibling : siblings) { + text = text.append(sibling); + } + + text = text.setStyle(style); + return text; + } + + @Unique + private MutableText newTextWithLinks(String string) { + // TODO: Does this cover all cases? Probably not, but it's good enough for now + MutableText result = Text.empty(); + String[] split = string.split(" "); + + for (int i = 0; i < split.length; i++) { + String segment = split[i]; + MutableText text = Text.literal(segment); + + try { + URI uri = new URI(segment); + ClickEvent event = new ClickEvent( + ClickEvent.Action.OPEN_URL, + uri.toString() + ); + + text = text.styled(style -> { + style = style.withClickEvent(event); + return style; + }); + } catch (URISyntaxException ignored) { + } + + result.append(text); + if (i < split.length - 1) result.append(" "); + } + + return result; + } +}