1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
package com.raeids.stratus.mixin;
import com.raeids.stratus.Stratus;
import com.raeids.stratus.config.StratusConfig;
import com.raeids.stratus.hook.ChatSearchingKt;
import com.raeids.stratus.hook.ChatTabs;
import com.raeids.stratus.hook.GuiNewChatHook;
import com.raeids.stratus.hook.ModCompatHooks;
import gg.essential.universal.UMouse;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.*;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.util.IChatComponent;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
import org.spongepowered.asm.lib.Opcodes;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
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.invoke.arg.Args;
import java.util.List;
@Mixin(value = GuiNewChat.class, priority = Integer.MIN_VALUE)
public abstract class GuiNewChatMixin extends Gui implements GuiNewChatHook {
@Unique private int stratus$right = 0;
@Unique private boolean stratus$shouldCopy;
@Unique private boolean stratus$chatCheck;
@Shadow @Final private Minecraft mc;
@Shadow @Final private List<ChatLine> drawnChatLines;
@SuppressWarnings({"FieldCanBeLocal", "unused"})
private float percentComplete;
@Shadow public abstract boolean getChatOpen();
@Shadow public abstract float getChatScale();
@Shadow public abstract int getLineCount();
@Shadow private int scrollPos;
@Shadow @Final private List<ChatLine> chatLines;
@Shadow public abstract void deleteChatLine(int id);
@Unique private static final ResourceLocation COPY = new ResourceLocation("stratus:copy.png");
@Inject(method = "printChatMessageWithOptionalDeletion", at = @At("HEAD"), cancellable = true)
private void handlePrintChatMessage(IChatComponent chatComponent, int chatLineId, CallbackInfo ci) {
handleChatTabMessage(chatComponent, chatLineId, mc.ingameGUI.getUpdateCounter(), false, ci);
}
@Inject(method = "setChatLine", at = @At("HEAD"), cancellable = true)
private void handleSetChatLine(IChatComponent chatComponent, int chatLineId, int updateCounter, boolean displayOnly, CallbackInfo ci) {
handleChatTabMessage(chatComponent, chatLineId, updateCounter, displayOnly, ci);
}
@Inject(method = "drawChat", at = @At("HEAD"))
private void checkScreenshotKeybind(int j2, CallbackInfo ci) {
if (Stratus.INSTANCE.getKeybind().isPressed()) {
Stratus.INSTANCE.setDoTheThing(true);
}
stratus$chatCheck = false;
}
@ModifyVariable(method = "drawChat", at = @At("HEAD"), argsOnly = true)
private int setUpdateCounterWhjenYes(int updateCounter) {
return Stratus.INSTANCE.getDoTheThing() ? 0 : updateCounter;
}
@ModifyVariable(method = "drawChat", at = @At("STORE"), index = 2)
private int setChatLimitWhenYes(int linesToDraw) {
return Stratus.INSTANCE.getDoTheThing()
? GuiNewChat.calculateChatboxHeight(mc.gameSettings.chatHeightFocused) / 9
: linesToDraw;
}
//TODO: fix with betterchat
@ModifyArgs(method = "drawChat", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiNewChat;drawRect(IIIII)V"), slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/util/MathHelper;clamp_double(DDD)D"), to = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;enableBlend()V")))
private void captureDrawRect(Args args) {
int left = args.get(0);
int top = args.get(1);
int right = args.get(2);
int bottom = args.get(3);
if (mc.currentScreen instanceof GuiChat) {
float f = this.getChatScale();
int mouseX = MathHelper.floor_double(UMouse.getScaledX()) - 3;
int mouseY = MathHelper.floor_double(UMouse.getScaledY()) - 27 + (Stratus.INSTANCE.isBetterChat() ? ModCompatHooks.getYOffset() : 0) - (Stratus.INSTANCE.isPatcher() && ModCompatHooks.getChatPosition() ? 12 : 0);
mouseX = MathHelper.floor_float((float)mouseX / f);
mouseY = -(MathHelper.floor_float((float)mouseY / f)); //WHY DO I NEED TO DO THIS
if (mouseX >= (left + (Stratus.INSTANCE.isBetterChat() ? ModCompatHooks.getXOffset() : 0)) && mouseY < bottom && mouseX < (right + 9 + (Stratus.INSTANCE.isBetterChat() ? ModCompatHooks.getXOffset() : 0)) && mouseY >= top) {
stratus$shouldCopy = true;
drawCopyChatBox(right, top);
}
}
}
@Redirect(method = "drawChat", at = @At(value = "FIELD", target = "Lnet/minecraft/client/gui/GuiNewChat;drawnChatLines:Ljava/util/List;", opcode = Opcodes.GETFIELD))
private List<ChatLine> injected(GuiNewChat instance) {
return ChatSearchingKt.filterMessages(drawnChatLines);
}
@Inject(method = "drawChat", at = @At("RETURN"))
private void checkStuff(int j2, CallbackInfo ci) {
if (!stratus$chatCheck && stratus$shouldCopy) {
stratus$shouldCopy = false;
}
}
@Override
public int getRight() {
return stratus$right;
}
@Override
public boolean shouldCopy() {
return stratus$shouldCopy;
}
private void handleChatTabMessage(IChatComponent chatComponent, int chatLineId, int updateCounter, boolean displayOnly, CallbackInfo ci) {
if (StratusConfig.INSTANCE.getChatTabs()) {
if (!ChatTabs.INSTANCE.shouldRender(chatComponent)) {
percentComplete = 1.0F;
if (chatLineId != 0) {
deleteChatLine(chatLineId);
}
if (!displayOnly) {
chatLines.add(0, new ChatLine(updateCounter, chatComponent, chatLineId));
while (this.chatLines.size() > (Stratus.INSTANCE.isPatcher() ? 32767 : 100))
{
this.chatLines.remove(this.chatLines.size() - 1);
}
}
ci.cancel();
}
}
}
private void drawCopyChatBox(int right, int top) {
stratus$chatCheck = true;
GlStateManager.enableRescaleNormal();
GlStateManager.enableBlend();
GlStateManager.enableDepth();
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
GlStateManager.pushMatrix();
mc.getTextureManager().bindTexture(COPY);
GlStateManager.enableRescaleNormal();
GlStateManager.enableAlpha();
GlStateManager.alphaFunc(516, 0.1f);
GlStateManager.enableBlend();
GlStateManager.blendFunc(770, 771);
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
stratus$right = right;
Gui.drawModalRectWithCustomSizedTexture(right, top, 0f, 0f, 9, 9, 9, 9);
GlStateManager.disableAlpha();
GlStateManager.disableRescaleNormal();
GlStateManager.disableLighting();
GlStateManager.popMatrix();
}
@Override
public String getStratusChatComponent(int mouseY) {
if (this.getChatOpen()) {
ScaledResolution scaledresolution = new ScaledResolution(this.mc);
int i = scaledresolution.getScaleFactor();
float f = this.getChatScale();
int k = mouseY / i - 27 + (Stratus.INSTANCE.isBetterChat() ? ModCompatHooks.getYOffset() : 0) - (Stratus.INSTANCE.isPatcher() && ModCompatHooks.getChatPosition() ? 12 : 0);
k = MathHelper.floor_float((float) k / f);
if (k >= 0) {
int l = Math.min(this.getLineCount(), this.drawnChatLines.size());
if (k < this.mc.fontRendererObj.FONT_HEIGHT * l + l) {
int i1 = k / this.mc.fontRendererObj.FONT_HEIGHT + this.scrollPos;
if (i1 >= 0 && i1 < this.drawnChatLines.size()) {
return this.drawnChatLines.get(i1).getChatComponent().getFormattedText();
}
}
}
}
return null;
}
}
|