From f3266c7e8cf24e1c34793d5074177465934382dc Mon Sep 17 00:00:00 2001 From: Vinrobot Date: Sat, 12 Aug 2023 02:26:08 +0200 Subject: [PATCH] Parse message when added to ChatHub rather than at each frame --- .../mcemote/client/MinecraftEmoteModClient.java | 4 +--- .../mcemote/client/mixin/ChatHudMixin.java | 13 +++++-------- .../vinrobot/mcemote/client/text/EmoteParser.java | 14 ++++++++++++++ .../mcemote/client/text/EmotesManager.java | 12 +++++++++++- 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/client/java/net/vinrobot/mcemote/client/MinecraftEmoteModClient.java b/src/client/java/net/vinrobot/mcemote/client/MinecraftEmoteModClient.java index e5e9822..285dd29 100644 --- a/src/client/java/net/vinrobot/mcemote/client/MinecraftEmoteModClient.java +++ b/src/client/java/net/vinrobot/mcemote/client/MinecraftEmoteModClient.java @@ -31,8 +31,6 @@ public void onInitializeClient() { final ServiceLoader serviceLoader = ServiceLoader.load(IEmoteProvider.class); final List providers = ListHelper.sort(serviceLoader); - int codePoint = 100; - for (final IEmoteProvider provider : providers) { final String providerName = provider.getClass().getName(); @@ -43,7 +41,7 @@ public void onInitializeClient() { provider.registerEmotes(config, emotes::add); for (final Emote emote : emotes) { - EMOTES_MANAGER.addEmote(codePoint++, emote); + EMOTES_MANAGER.addEmote(emote); } MinecraftEmoteMod.LOGGER.info("Registered " + emotes.size() + " emotes from provider " + providerName); diff --git a/src/client/java/net/vinrobot/mcemote/client/mixin/ChatHudMixin.java b/src/client/java/net/vinrobot/mcemote/client/mixin/ChatHudMixin.java index e18b1ff..d90c771 100644 --- a/src/client/java/net/vinrobot/mcemote/client/mixin/ChatHudMixin.java +++ b/src/client/java/net/vinrobot/mcemote/client/mixin/ChatHudMixin.java @@ -2,22 +2,19 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.hud.ChatHud; -import net.minecraft.text.OrderedText; +import net.minecraft.text.Text; import net.vinrobot.mcemote.client.MinecraftEmoteModClient; import net.vinrobot.mcemote.client.text.EmoteParser; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.ModifyVariable; @Mixin(ChatHud.class) @Environment(EnvType.CLIENT) public class ChatHudMixin { - @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawTextWithShadow(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/text/OrderedText;III)I")) - private int drawTextWithShadow(DrawContext instance, TextRenderer textRenderer, OrderedText orderedText, int x, int y, int color) { - orderedText = EmoteParser.wrapOrderedText(orderedText, MinecraftEmoteModClient.EMOTES_MANAGER); - return instance.drawTextWithShadow(textRenderer, orderedText, x, y, color); + @ModifyVariable(at = @At("HEAD"), method = "addMessage(Lnet/minecraft/text/Text;Lnet/minecraft/network/message/MessageSignatureData;ILnet/minecraft/client/gui/hud/MessageIndicator;Z)V", ordinal = 0) + private Text addMessage(Text message) { + return EmoteParser.wrapText(message, MinecraftEmoteModClient.EMOTES_MANAGER); } } diff --git a/src/client/java/net/vinrobot/mcemote/client/text/EmoteParser.java b/src/client/java/net/vinrobot/mcemote/client/text/EmoteParser.java index 8404cb8..d907326 100644 --- a/src/client/java/net/vinrobot/mcemote/client/text/EmoteParser.java +++ b/src/client/java/net/vinrobot/mcemote/client/text/EmoteParser.java @@ -5,6 +5,7 @@ import net.minecraft.text.CharacterVisitor; import net.minecraft.text.ClickEvent; import net.minecraft.text.HoverEvent; +import net.minecraft.text.MutableText; import net.minecraft.text.OrderedText; import net.minecraft.text.Style; import net.minecraft.text.Text; @@ -37,6 +38,19 @@ public static OrderedText wrapOrderedText(OrderedText orderedText, EmotesManager }; } + public static Text wrapText(Text text, EmotesManager emotesManager) { + final OrderedText orderedText = wrapOrderedText(text.asOrderedText(), emotesManager); + + final MutableText mutableText = Text.empty(); + orderedText.accept((index, style, codePoint) -> { + final String character = String.valueOf(Character.toChars(codePoint)); + mutableText.append(Text.literal(character).setStyle(style)); + return true; + }); + + return mutableText; + } + @Override public boolean accept(int index, Style style, int codePoint) { if (Character.isWhitespace(codePoint)) { diff --git a/src/client/java/net/vinrobot/mcemote/client/text/EmotesManager.java b/src/client/java/net/vinrobot/mcemote/client/text/EmotesManager.java index d2a4189..d4779b7 100644 --- a/src/client/java/net/vinrobot/mcemote/client/text/EmotesManager.java +++ b/src/client/java/net/vinrobot/mcemote/client/text/EmotesManager.java @@ -13,7 +13,10 @@ public class EmotesManager { private final Map emoteByNames = new HashMap<>(); private final Map emoteByCodePoints = new HashMap<>(); - public EmotePair addEmote(int codePoint, Emote emote) { + private int nextCodePoint = 1; + + public EmotePair addEmote(Emote emote) { + final int codePoint = this.nextCodePoint++; final String name = emote.getName(); final EmotePair emotePair = new EmotePair(codePoint, emote); @@ -39,6 +42,13 @@ public Optional removeEmote(int codePoint) { .map(this.emoteByNames::remove); } + public void clearEmotes() { + // Don't reset nextCodePoint, so that new emotes will have + // unique code points during the entire life of this object. + this.emoteByNames.clear(); + this.emoteByCodePoints.clear(); + } + public Optional getByName(String name) { return Optional.ofNullable(this.emoteByNames.get(name)); }