aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/polyfrost/chatting/mixin/ChatLineMixin.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/polyfrost/chatting/mixin/ChatLineMixin.java')
-rw-r--r--src/main/java/org/polyfrost/chatting/mixin/ChatLineMixin.java114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/main/java/org/polyfrost/chatting/mixin/ChatLineMixin.java b/src/main/java/org/polyfrost/chatting/mixin/ChatLineMixin.java
new file mode 100644
index 0000000..2e5f21c
--- /dev/null
+++ b/src/main/java/org/polyfrost/chatting/mixin/ChatLineMixin.java
@@ -0,0 +1,114 @@
+/*
+ * This file is from chat_heads is licensed under MPL-2.0, which can be found at https://www.mozilla.org/en-US/MPL/2.0/
+ * See: https://github.com/dzwdz/chat_heads/blob/fabric-1.16.x/LICENSE
+ */
+
+package org.polyfrost.chatting.mixin;
+
+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.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 first = true;
+ private NetworkPlayerInfo playerInfo;
+ private NetworkPlayerInfo detectedPlayerInfo;
+ private static NetworkPlayerInfo lastPlayerInfo;
+ private static long lastUniqueId = 0;
+ private long uniqueId = 0;
+
+ @Inject(method = "<init>", at = @At("RETURN"))
+ private void onInit(int i, IChatComponent iChatComponent, int j, CallbackInfo ci) {
+ lastUniqueId++;
+ uniqueId = lastUniqueId;
+ chatLines.add(new WeakReference<>((ChatLine) (Object) this));
+ NetHandlerPlayClient netHandler = Minecraft.getMinecraft().getNetHandler();
+ if (netHandler == null) return;
+ Map<String, NetworkPlayerInfo> 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) {
+ }
+ }
+
+ @Nullable
+ private static NetworkPlayerInfo getPlayerFromNickname(String word, NetHandlerPlayClient connection, Map<String, NetworkPlayerInfo> 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;
+ }
+
+ nicknameCache.put(nickname, p);
+ }
+ }
+ } else {
+ // use prepared cache
+ return nicknameCache.get(word);
+ }
+
+ return null;
+ }
+
+ @Override
+ public boolean hasDetected() {
+ return detected;
+ }
+
+ @Override
+ public NetworkPlayerInfo getPlayerInfo() {
+ return playerInfo;
+ }
+
+ @Override
+ public void updatePlayerInfo() {
+ if (ChattingConfig.INSTANCE.getHideChatHeadOnConsecutiveMessages() && !first) {
+ playerInfo = null;
+ } else {
+ playerInfo = detectedPlayerInfo;
+ }
+ }
+
+ @Override
+ public long getUniqueId() {
+ return uniqueId;
+ }
+}