diff --git a/src/main/java/org/polyfrost/chatting/hook/ChatLineHook.java b/src/main/java/org/polyfrost/chatting/hook/ChatLineHook.java index 22f180c..50b9ce3 100644 --- a/src/main/java/org/polyfrost/chatting/hook/ChatLineHook.java +++ b/src/main/java/org/polyfrost/chatting/hook/ChatLineHook.java @@ -8,14 +8,8 @@ public interface ChatLineHook { HashSet> chatLines = new HashSet<>(); - boolean isDetected(); - void setDetected(boolean detected); + boolean hasDetected(); NetworkPlayerInfo getPlayerInfo(); - void setPlayerInfo(NetworkPlayerInfo playerInfo); - NetworkPlayerInfo getDetectedPlayerInfo(); - void setDetectedPlayerInfo(NetworkPlayerInfo detectedPlayerInfo); - boolean isFirstDetection(); - void setFirstDetection(boolean firstDetection); void updatePlayerInfo(); diff --git a/src/main/java/org/polyfrost/chatting/mixin/ChatLineMixin.java b/src/main/java/org/polyfrost/chatting/mixin/ChatLineMixin.java index cde09ea..2e5f21c 100644 --- a/src/main/java/org/polyfrost/chatting/mixin/ChatLineMixin.java +++ b/src/main/java/org/polyfrost/chatting/mixin/ChatLineMixin.java @@ -7,23 +7,28 @@ import org.polyfrost.chatting.config.ChattingConfig; import org.polyfrost.chatting.hook.ChatLineHook; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.ChatLine; +import net.minecraft.client.network.NetHandlerPlayClient; import net.minecraft.client.network.NetworkPlayerInfo; import net.minecraft.util.IChatComponent; -import org.polyfrost.chatting.utils.ChatHeadHooks; +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.lang.ref.WeakReference; +import java.util.HashMap; +import java.util.Map; @Mixin(ChatLine.class) public class ChatLineMixin implements ChatLineHook { private boolean detected = false; - private boolean firstDetection = true; + private boolean first = true; private NetworkPlayerInfo playerInfo; private NetworkPlayerInfo detectedPlayerInfo; + private static NetworkPlayerInfo lastPlayerInfo; private static long lastUniqueId = 0; private long uniqueId = 0; @@ -32,52 +37,70 @@ private void onInit(int i, IChatComponent iChatComponent, int j, CallbackInfo ci lastUniqueId++; uniqueId = lastUniqueId; chatLines.add(new WeakReference<>((ChatLine) (Object) this)); - ChatHeadHooks.INSTANCE.detect(iChatComponent.getFormattedText(), (ChatLine) (Object) this); - } - - @Override - public boolean isDetected() { - return detected; - } - - @Override - public void setDetected(boolean detected) { - this.detected = detected; - } - - @Override - public NetworkPlayerInfo getPlayerInfo() { - return playerInfo; + NetHandlerPlayClient netHandler = Minecraft.getMinecraft().getNetHandler(); + if (netHandler == null) return; + Map nicknameCache = new HashMap<>(); + try { + for (String word : iChatComponent.getFormattedText().split("(§.)|\\W")) { + if (word.isEmpty()) continue; + playerInfo = netHandler.getPlayerInfo(word); + if (playerInfo == null) { + playerInfo = getPlayerFromNickname(word, netHandler, nicknameCache); + } + if (playerInfo != null) { + detectedPlayerInfo = playerInfo; + detected = true; + if (playerInfo == lastPlayerInfo) { + first = false; + if (ChattingConfig.INSTANCE.getHideChatHeadOnConsecutiveMessages()) { + playerInfo = null; + } + } else { + lastPlayerInfo = playerInfo; + } + break; + } + } + } catch (Exception ignored) { + } } - @Override - public void setPlayerInfo(NetworkPlayerInfo playerInfo) { - this.playerInfo = playerInfo; - } + @Nullable + private static NetworkPlayerInfo getPlayerFromNickname(String word, NetHandlerPlayClient connection, Map nicknameCache) { + if (nicknameCache.isEmpty()) { + for (NetworkPlayerInfo p : connection.getPlayerInfoMap()) { + IChatComponent displayName = p.getDisplayName(); + if (displayName != null) { + String nickname = displayName.getUnformattedTextForChat(); + if (word.equals(nickname)) { + nicknameCache.clear(); + return p; + } - @Override - public NetworkPlayerInfo getDetectedPlayerInfo() { - return detectedPlayerInfo; - } + nicknameCache.put(nickname, p); + } + } + } else { + // use prepared cache + return nicknameCache.get(word); + } - @Override - public void setDetectedPlayerInfo(NetworkPlayerInfo detectedPlayerInfo) { - this.detectedPlayerInfo = detectedPlayerInfo; + return null; } @Override - public boolean isFirstDetection() { - return firstDetection; + public boolean hasDetected() { + return detected; } @Override - public void setFirstDetection(boolean firstDetection) { - this.firstDetection = firstDetection; + public NetworkPlayerInfo getPlayerInfo() { + return playerInfo; } @Override public void updatePlayerInfo() { - if (ChattingConfig.INSTANCE.getHideChatHeadOnConsecutiveMessages() && !firstDetection) { + if (ChattingConfig.INSTANCE.getHideChatHeadOnConsecutiveMessages() && !first) { playerInfo = null; } else { playerInfo = detectedPlayerInfo; diff --git a/src/main/java/org/polyfrost/chatting/mixin/GuiChatMixin.java b/src/main/java/org/polyfrost/chatting/mixin/GuiChatMixin.java index 8d55e0a..e95d256 100644 --- a/src/main/java/org/polyfrost/chatting/mixin/GuiChatMixin.java +++ b/src/main/java/org/polyfrost/chatting/mixin/GuiChatMixin.java @@ -1,7 +1,6 @@ package org.polyfrost.chatting.mixin; import cc.polyfrost.oneconfig.libs.universal.UDesktop; -import cc.polyfrost.oneconfig.libs.universal.UResolution; import org.polyfrost.chatting.chat.*; import org.polyfrost.chatting.config.ChattingConfig; import org.polyfrost.chatting.gui.components.ClearButton; @@ -113,15 +112,6 @@ private int modifyInputBoxColor(int color) { return ChattingConfig.INSTANCE.getInputBoxBackgroundColor().getRGB(); } - @ModifyArg(method = "drawScreen", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiNewChat;getChatComponent(II)Lnet/minecraft/util/IChatComponent;"), index = 0) - private int modifyChatComponentX(int x) { - if (ChattingConfig.INSTANCE.getShowChatHeads()) { - return x - (10 * (int) UResolution.getScaleFactor()); - } else { - return x; - } - } - @Inject(method = "mouseClicked", at = @At("HEAD")) private void mouseClicked(int mouseX, int mouseY, int mouseButton, CallbackInfo ci) { GuiNewChatHook hook = ((GuiNewChatHook) Minecraft.getMinecraft().ingameGUI.getChatGUI()); @@ -146,15 +136,6 @@ private void mouseClicked(int mouseX, int mouseY, int mouseButton, CallbackInfo } - @ModifyArg(method = "mouseClicked", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiNewChat;getChatComponent(II)Lnet/minecraft/util/IChatComponent;"), index = 0) - private int modifyChatComponentX2(int x) { - if (ChattingConfig.INSTANCE.getShowChatHeads()) { - return x - (10 * (int) UResolution.getScaleFactor()); - } else { - return x; - } - } - @ModifyArg(method = "keyTyped", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiChat;sendChatMessage(Ljava/lang/String;)V"), index = 0) private String modifySentMessage(String original) { if (ChattingConfig.INSTANCE.getChatShortcuts()) { diff --git a/src/main/java/org/polyfrost/chatting/mixin/GuiNewChatMixin.java b/src/main/java/org/polyfrost/chatting/mixin/GuiNewChatMixin.java index 4733ab6..bc90730 100644 --- a/src/main/java/org/polyfrost/chatting/mixin/GuiNewChatMixin.java +++ b/src/main/java/org/polyfrost/chatting/mixin/GuiNewChatMixin.java @@ -1,13 +1,10 @@ package org.polyfrost.chatting.mixin; import cc.polyfrost.oneconfig.libs.universal.UMouse; -import cc.polyfrost.oneconfig.libs.universal.UResolution; import cc.polyfrost.oneconfig.utils.Notifications; -import net.minecraft.util.IChatComponent; import org.polyfrost.chatting.Chatting; import org.polyfrost.chatting.chat.ChatSearchingManager; import org.polyfrost.chatting.config.ChattingConfig; -import org.polyfrost.chatting.hook.ChatLineHook; import org.polyfrost.chatting.hook.GuiNewChatHook; import org.polyfrost.chatting.utils.ModCompatHooks; import org.polyfrost.chatting.utils.RenderUtils; @@ -23,7 +20,6 @@ import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.*; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.invoke.arg.Args; import java.awt.datatransfer.StringSelection; @@ -165,44 +161,6 @@ private void checkStuff(int j2, CallbackInfo ci) { } } - @Unique - private boolean chatting$cancelChatComponent = false; - @Unique - private int chatting$lastMouseX = 0; - @Unique - private int chatting$lastMouseY = 0; - - @Inject(method = "getChatComponent", at = @At(value = "INVOKE", target = "Ljava/util/List;get(I)Ljava/lang/Object;")) - private void storeMouseXAndY(int mouseX, int mouseY, CallbackInfoReturnable cir) { - chatting$lastMouseX = mouseX; - chatting$lastMouseY = mouseY; - } - - @ModifyVariable(method = "getChatComponent", at = @At("STORE"), ordinal = 0) - private ChatLine storeChatLine(ChatLine line) { - if (ChattingConfig.INSTANCE.getShowChatHeads() && !((ChatLineHook) line).isDetected() && !ChattingConfig.INSTANCE.getOffsetNonPlayerMessages()) { - int i = (int) UResolution.getScaleFactor(); - float f = this.getChatScale(); - int j = chatting$lastMouseX / i - 3; - int k = chatting$lastMouseY / i - 27; - j = MathHelper.floor_float((float)j / f); - k = MathHelper.floor_float((float)k / f); - int l = Math.min(this.getLineCount(), this.drawnChatLines.size()); - if (j > MathHelper.floor_float((float)this.getChatWidth() / this.getChatScale()) && k < this.mc.fontRendererObj.FONT_HEIGHT * l + l) { - chatting$cancelChatComponent = true; - } - } - return line; - } - - @Inject(method = "getChatComponent", at = @At(value = "INVOKE", target = "Ljava/util/List;get(I)Ljava/lang/Object;", shift = At.Shift.AFTER), cancellable = true) - private void cancelChatComponent(int mouseX, int mouseY, CallbackInfoReturnable cir) { - if (chatting$cancelChatComponent) { - cir.setReturnValue(null); - chatting$cancelChatComponent = false; - } - } - @Override public int getRight() { return chatting$right; diff --git a/src/main/java/org/polyfrost/chatting/mixin/GuiUtilRenderComponentsMixin.java b/src/main/java/org/polyfrost/chatting/mixin/GuiUtilRenderComponentsMixin.java deleted file mode 100644 index fd497a6..0000000 --- a/src/main/java/org/polyfrost/chatting/mixin/GuiUtilRenderComponentsMixin.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.polyfrost.chatting.mixin; - -import net.minecraft.client.gui.GuiUtilRenderComponents; -import org.polyfrost.chatting.config.ChattingConfig; -import org.polyfrost.chatting.utils.ChatHeadHooks; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(GuiUtilRenderComponents.class) -public class GuiUtilRenderComponentsMixin { - @Redirect(method = "splitText", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/FontRenderer;getStringWidth(Ljava/lang/String;)I")) - private static int modifyChatLineX(net.minecraft.client.gui.FontRenderer fontRenderer, String text) { - if (ChattingConfig.INSTANCE.getShowChatHeads() && (ChattingConfig.INSTANCE.getOffsetNonPlayerMessages() || ChatHeadHooks.INSTANCE.detect(text, null))) { - return fontRenderer.getStringWidth(text) + 10; - } - return fontRenderer.getStringWidth(text); - } -} diff --git a/src/main/kotlin/org/polyfrost/chatting/Chatting.kt b/src/main/kotlin/org/polyfrost/chatting/Chatting.kt index cf439ce..0e8745c 100644 --- a/src/main/kotlin/org/polyfrost/chatting/Chatting.kt +++ b/src/main/kotlin/org/polyfrost/chatting/Chatting.kt @@ -245,7 +245,7 @@ object Chatting { } val fr: FontRenderer = ModCompatHooks.fontRenderer - val width = messages.maxOf { fr.getStringWidth(it.value) + (if (ChattingConfig.showChatHeads && ((it.key as ChatLineHook).isDetected || ChattingConfig.offsetNonPlayerMessages)) 10 else 0) } + 4 + val width = messages.maxOf { fr.getStringWidth(it.value) + (if (ChattingConfig.showChatHeads && ((it.key as ChatLineHook).hasDetected() || ChattingConfig.offsetNonPlayerMessages)) 10 else 0) } + 4 val fb: Framebuffer = createBindFramebuffer(width * 2, (messages.size * 9) * 2) val file = File(Minecraft.getMinecraft().mcDataDir, "screenshots/chat/" + fileFormatter.format(Date())) diff --git a/src/main/kotlin/org/polyfrost/chatting/utils/ChatHeadHooks.kt b/src/main/kotlin/org/polyfrost/chatting/utils/ChatHeadHooks.kt deleted file mode 100644 index aa777c1..0000000 --- a/src/main/kotlin/org/polyfrost/chatting/utils/ChatHeadHooks.kt +++ /dev/null @@ -1,74 +0,0 @@ -package org.polyfrost.chatting.utils - -import net.minecraft.client.Minecraft -import net.minecraft.client.gui.ChatLine -import net.minecraft.client.network.NetHandlerPlayClient -import net.minecraft.client.network.NetworkPlayerInfo -import org.polyfrost.chatting.config.ChattingConfig.hideChatHeadOnConsecutiveMessages -import org.polyfrost.chatting.hook.ChatLineHook - -object ChatHeadHooks { - private var lastPlayerInfo: NetworkPlayerInfo? = null - fun detect(formattedText: String, chatLine: ChatLine?): Boolean { - if (chatLine !is ChatLineHook) { - return false - } - val netHandler = Minecraft.getMinecraft().netHandler ?: return false - val nicknameCache: MutableMap = HashMap() - var detected = false - try { - formattedText.split("(§.)|\\W".toRegex()).dropLastWhile { it.isEmpty() } - .forEach { word -> - if (word.isNotEmpty()) { - var maybePlayerInfo = netHandler.getPlayerInfo(word) - if (maybePlayerInfo == null) { - maybePlayerInfo = getPlayerFromNickname(word, netHandler, nicknameCache) - } - if (maybePlayerInfo != null) { - detected = true - chatLine.run { - playerInfo = maybePlayerInfo - detectedPlayerInfo = playerInfo - isDetected = true - if (playerInfo == lastPlayerInfo) { - isFirstDetection = false - if (hideChatHeadOnConsecutiveMessages) { - playerInfo = null - } - } else { - lastPlayerInfo = playerInfo - } - return@forEach - } - } - } - } - } catch (ignored: Exception) { - } - return detected - } - - private fun getPlayerFromNickname( - word: String, - connection: NetHandlerPlayClient, - nicknameCache: MutableMap - ): NetworkPlayerInfo? { - if (nicknameCache.isEmpty()) { - for (p in connection.playerInfoMap) { - val displayName = p.displayName - if (displayName != null) { - val nickname = displayName.unformattedTextForChat - if (word == nickname) { - nicknameCache.clear() - return p - } - nicknameCache[nickname] = p - } - } - } else { - // use prepared cache - return nicknameCache[word] - } - return null - } -} \ No newline at end of file diff --git a/src/main/kotlin/org/polyfrost/chatting/utils/ModCompatHooks.kt b/src/main/kotlin/org/polyfrost/chatting/utils/ModCompatHooks.kt index 591461d..b6198fa 100644 --- a/src/main/kotlin/org/polyfrost/chatting/utils/ModCompatHooks.kt +++ b/src/main/kotlin/org/polyfrost/chatting/utils/ModCompatHooks.kt @@ -58,7 +58,7 @@ object ModCompatHooks { var actualX = x if (showChatHeads && !screenshot) { val hook = chatLine as ChatLineHook - if (hook.isDetected || offsetNonPlayerMessages) { + if (hook.hasDetected() || offsetNonPlayerMessages) { actualX += 10f } val networkPlayerInfo = hook.playerInfo diff --git a/src/main/resources/mixins.chatting.json b/src/main/resources/mixins.chatting.json index 429b9f5..ce96f59 100644 --- a/src/main/resources/mixins.chatting.json +++ b/src/main/resources/mixins.chatting.json @@ -1,24 +1,23 @@ { - "compatibilityLevel": "JAVA_8", - "minVersion": "0.7", - "package": "org.polyfrost.chatting.mixin", - "refmap": "mixins.${id}.refmap.json", - "verbose": true, - "client": [ - "ChatLineMixin", - "ClientCommandHandlerMixin", - "EntityPlayerSPMixin", - "GuiChatMixin", - "GuiNewChatAccessor", - "GuiNewChatMapMixin", - "GuiNewChatMixin", - "GuiNewChatMixin_ChatHeight", - "GuiNewChatMixin_ChatSearching", - "GuiNewChatMixin_ChatTabs", - "GuiNewChatMixin_Scrolling", - "GuiNewChatMixin_SmoothMessages", - "GuiNewChatMixin_TextRendering", - "GuiUtilRenderComponentsMixin", - "GuiUtilsMixin" - ] + "compatibilityLevel": "JAVA_8", + "minVersion": "0.7", + "package": "org.polyfrost.chatting.mixin", + "refmap": "mixins.${id}.refmap.json", + "verbose": true, + "client": [ + "ChatLineMixin", + "ClientCommandHandlerMixin", + "EntityPlayerSPMixin", + "GuiChatMixin", + "GuiNewChatAccessor", + "GuiNewChatMapMixin", + "GuiNewChatMixin", + "GuiNewChatMixin_ChatHeight", + "GuiNewChatMixin_ChatSearching", + "GuiNewChatMixin_ChatTabs", + "GuiNewChatMixin_Scrolling", + "GuiNewChatMixin_SmoothMessages", + "GuiNewChatMixin_TextRendering", + "GuiUtilsMixin" + ] } \ No newline at end of file