aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorWyvest <45589059+Wyvest@users.noreply.github.com>2022-12-11 17:06:21 -0500
committerWyvest <45589059+Wyvest@users.noreply.github.com>2022-12-11 17:06:21 -0500
commit7ea5b9ab24c78f01bdbbd4357fc87b75bbe4d950 (patch)
tree14eb8e92f7afb0ac65c8cdfed7826d194f8460d0 /src/main/java
parentfc0f54e31911ae375672f04686b072b46afd1419 (diff)
downloadChatting-7ea5b9ab24c78f01bdbbd4357fc87b75bbe4d950.tar.gz
Chatting-7ea5b9ab24c78f01bdbbd4357fc87b75bbe4d950.tar.bz2
Chatting-7ea5b9ab24c78f01bdbbd4357fc87b75bbe4d950.zip
new: chat heads
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/cc/woverflow/chatting/hook/ChatLineHook.java15
-rw-r--r--src/main/java/cc/woverflow/chatting/mixin/ChatLineMixin.java101
-rw-r--r--src/main/java/cc/woverflow/chatting/mixin/GuiNewChatMixin.java29
3 files changed, 145 insertions, 0 deletions
diff --git a/src/main/java/cc/woverflow/chatting/hook/ChatLineHook.java b/src/main/java/cc/woverflow/chatting/hook/ChatLineHook.java
new file mode 100644
index 0000000..fb10225
--- /dev/null
+++ b/src/main/java/cc/woverflow/chatting/hook/ChatLineHook.java
@@ -0,0 +1,15 @@
+package cc.woverflow.chatting.hook;
+
+import net.minecraft.client.gui.ChatLine;
+import net.minecraft.client.network.NetworkPlayerInfo;
+
+import java.lang.ref.WeakReference;
+import java.util.HashSet;
+
+public interface ChatLineHook {
+ HashSet<WeakReference<ChatLine>> chatLines = new HashSet<>();
+ boolean hasDetected();
+ NetworkPlayerInfo getPlayerInfo();
+
+ void updatePlayerInfo();
+}
diff --git a/src/main/java/cc/woverflow/chatting/mixin/ChatLineMixin.java b/src/main/java/cc/woverflow/chatting/mixin/ChatLineMixin.java
new file mode 100644
index 0000000..b739284
--- /dev/null
+++ b/src/main/java/cc/woverflow/chatting/mixin/ChatLineMixin.java
@@ -0,0 +1,101 @@
+/*
+ * 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 cc.woverflow.chatting.mixin;
+
+import cc.woverflow.chatting.config.ChattingConfig;
+import cc.woverflow.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;
+
+ @Inject(method = "<init>", at = @At("RETURN"))
+ private void onInit(int i, IChatComponent iChatComponent, int j, CallbackInfo ci) {
+ chatLines.add(new WeakReference<>((ChatLine) (Object) this));
+ NetHandlerPlayClient netHandler = Minecraft.getMinecraft().getNetHandler();
+ Map<String, NetworkPlayerInfo> nicknameCache = new HashMap<>();
+ 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;
+ }
+ }
+ }
+
+ @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;
+ }
+ }
+}
diff --git a/src/main/java/cc/woverflow/chatting/mixin/GuiNewChatMixin.java b/src/main/java/cc/woverflow/chatting/mixin/GuiNewChatMixin.java
index 13c91ef..a430f8e 100644
--- a/src/main/java/cc/woverflow/chatting/mixin/GuiNewChatMixin.java
+++ b/src/main/java/cc/woverflow/chatting/mixin/GuiNewChatMixin.java
@@ -1,17 +1,20 @@
package cc.woverflow.chatting.mixin;
import cc.polyfrost.oneconfig.config.core.OneColor;
+import cc.polyfrost.oneconfig.utils.color.ColorUtils;
import cc.woverflow.chatting.Chatting;
import cc.woverflow.chatting.chat.ChatSearchingManager;
import cc.woverflow.chatting.chat.ChatTabs;
import cc.woverflow.chatting.config.ChattingConfig;
import cc.woverflow.chatting.gui.components.CleanButton;
+import cc.woverflow.chatting.hook.ChatLineHook;
import cc.woverflow.chatting.hook.GuiNewChatHook;
import cc.woverflow.chatting.utils.ModCompatHooks;
import cc.woverflow.chatting.utils.RenderUtils;
import cc.polyfrost.oneconfig.libs.universal.UMouse;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.*;
+import net.minecraft.client.network.NetworkPlayerInfo;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;
@@ -25,6 +28,7 @@ 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.callback.LocalCapture;
import org.spongepowered.asm.mixin.injection.invoke.arg.Args;
import java.awt.datatransfer.StringSelection;
@@ -141,6 +145,14 @@ public abstract class GuiNewChatMixin extends Gui implements GuiNewChatHook {
}
}
+ @Unique
+ private ChatLine chatting$drawingLine = null;
+
+ @Inject(method = "drawChat", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/ChatLine;getChatComponent()Lnet/minecraft/util/IChatComponent;"), locals = LocalCapture.CAPTURE_FAILSOFT)
+ private void captureChatLine(int updateCounter, CallbackInfo ci, int i, boolean bl, int j, int k, float f, float g, int l, int m, ChatLine chatLine, int n, double d, int o, int p, int q) {
+ chatting$drawingLine = chatLine;
+ }
+
@ModifyArgs(method = "drawChat", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/FontRenderer;drawStringWithShadow(Ljava/lang/String;FFI)I"))
private void drawChatBox(Args args) {
if (mc.currentScreen instanceof GuiChat) {
@@ -155,6 +167,23 @@ public abstract class GuiNewChatMixin extends Gui implements GuiNewChatHook {
}
}
lineInBounds = false;
+ if (ChattingConfig.INSTANCE.getShowChatHeads()) {
+ ChatLineHook hook = ((ChatLineHook) chatting$drawingLine);
+ if (hook.hasDetected() || ChattingConfig.INSTANCE.getOffsetNonPlayerMessages()) {
+ args.set(1, ((float) args.get(1)) + 10f);
+ }
+ NetworkPlayerInfo networkPlayerInfo = hook.getPlayerInfo();
+ if (networkPlayerInfo != null) {
+ GlStateManager.enableBlend();
+ GlStateManager.enableAlpha();
+ mc.getTextureManager().bindTexture(networkPlayerInfo.getLocationSkin());
+ GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
+ GlStateManager.color(1.0F, 1.0F, 1.0F, ColorUtils.getAlpha(args.get(3)) / 255f);
+ Gui.drawScaledCustomSizeModalRect((int) ((float) args.get(1) - 10f), (int) ((float) args.get(2) - 1f), 8.0F, 8.0F, 8, 8, 8, 8, 64.0F, 64.0F);
+ Gui.drawScaledCustomSizeModalRect((int) ((float) args.get(1) - 10f), (int) ((float) args.get(2) - 1f), 40.0F, 8.0F, 8, 8, 8, 8, 64.0F, 64.0F);
+ GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
+ }
+ }
}
private boolean isInBounds(int left, int top, int right, int bottom, float chatScale) {