diff options
Diffstat (limited to 'src/main')
11 files changed, 189 insertions, 98 deletions
diff --git a/src/main/java/com/raeids/stratus/hook/GuiNewChatHook.java b/src/main/java/com/raeids/stratus/hook/GuiNewChatHook.java index 4c50e5c..4fb9e0c 100644 --- a/src/main/java/com/raeids/stratus/hook/GuiNewChatHook.java +++ b/src/main/java/com/raeids/stratus/hook/GuiNewChatHook.java @@ -1,8 +1,7 @@ package com.raeids.stratus.hook; public interface GuiNewChatHook { - int getX(); - int getY(); + int getRight(); boolean shouldCopy(); - String copyString(); + String getStratusChatComponent(int mouseY); } diff --git a/src/main/java/com/raeids/stratus/mixin/EntityPlayerSPMixin.java b/src/main/java/com/raeids/stratus/mixin/EntityPlayerSPMixin.java new file mode 100644 index 0000000..44ef05d --- /dev/null +++ b/src/main/java/com/raeids/stratus/mixin/EntityPlayerSPMixin.java @@ -0,0 +1,21 @@ +package com.raeids.stratus.mixin; + +import com.raeids.stratus.config.StratusConfig; +import com.raeids.stratus.hook.ChatTabs; +import net.minecraft.client.entity.EntityPlayerSP; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +@Mixin(EntityPlayerSP.class) +public class EntityPlayerSPMixin { + @ModifyVariable(method = "sendChatMessage", at = @At("HEAD"), ordinal = 0, argsOnly = true) + private String handleSentMessages(String value) { + if (value.startsWith("/")) return value; + if (StratusConfig.INSTANCE.getChatTabs() && ChatTabs.INSTANCE.getCurrentTab() != null && !ChatTabs.INSTANCE.getCurrentTab().getPrefix().isEmpty()) { + return ChatTabs.INSTANCE.getCurrentTab().getPrefix() + value; + } else { + return value; + } + } +}
\ No newline at end of file diff --git a/src/main/java/com/raeids/stratus/mixin/GuiChatMixin.java b/src/main/java/com/raeids/stratus/mixin/GuiChatMixin.java index 4f9b2eb..2e46980 100644 --- a/src/main/java/com/raeids/stratus/mixin/GuiChatMixin.java +++ b/src/main/java/com/raeids/stratus/mixin/GuiChatMixin.java @@ -4,13 +4,19 @@ import com.raeids.stratus.config.StratusConfig; import com.raeids.stratus.hook.ChatSearchingKt; import com.raeids.stratus.hook.ChatTab; import com.raeids.stratus.hook.ChatTabs; +import com.raeids.stratus.hook.GuiNewChatHook; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiChat; import net.minecraft.client.gui.GuiScreen; +import org.lwjgl.input.Mouse; 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.awt.*; +import java.awt.datatransfer.StringSelection; + @Mixin(GuiChat.class) public abstract class GuiChatMixin extends GuiScreen { @@ -19,8 +25,10 @@ public abstract class GuiChatMixin extends GuiScreen { if (StratusConfig.INSTANCE.getChatSearch()) { ChatSearchingKt.initGui(); } - for (ChatTab chatTab : ChatTabs.INSTANCE.getTabs()) { - buttonList.add(chatTab.getButton()); + if (StratusConfig.INSTANCE.getChatTabs()) { + for (ChatTab chatTab : ChatTabs.INSTANCE.getTabs()) { + buttonList.add(chatTab.getButton()); + } } } @@ -61,5 +69,13 @@ public abstract class GuiChatMixin extends GuiScreen { if (ChatSearchingKt.getInputField() != null) { ChatSearchingKt.getInputField().mouseClicked(mouseX, mouseY, mouseButton); } + GuiNewChatHook hook = ((GuiNewChatHook) Minecraft.getMinecraft().ingameGUI.getChatGUI()); + if (hook.shouldCopy() && hook.getRight() <= mouseX && hook.getRight() + 9 > mouseX) { + try { + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(hook.getStratusChatComponent(Mouse.getY())), null); + } catch (Exception e) { + e.printStackTrace(); + } + } } } diff --git a/src/main/java/com/raeids/stratus/mixin/GuiNewChatMixin.java b/src/main/java/com/raeids/stratus/mixin/GuiNewChatMixin.java index 5732778..5def2e5 100644 --- a/src/main/java/com/raeids/stratus/mixin/GuiNewChatMixin.java +++ b/src/main/java/com/raeids/stratus/mixin/GuiNewChatMixin.java @@ -1,17 +1,17 @@ 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.GuiIngameForgeHook; import com.raeids.stratus.hook.GuiNewChatHook; import gg.essential.universal.UResolution; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.ChatLine; -import net.minecraft.client.gui.Gui; -import net.minecraft.client.gui.GuiNewChat; +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.lwjgl.input.Mouse; import org.spongepowered.asm.lib.Opcodes; @@ -25,18 +25,27 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.List; @Mixin(GuiNewChat.class) -public class GuiNewChatMixin extends Gui implements GuiNewChatHook { - @Unique private int stratus$x = 0; - @Unique private int stratus$y = 0; +public abstract class GuiNewChatMixin extends Gui implements GuiNewChatHook { + @Unique private int stratus$right = 0; @Unique private boolean stratus$shouldCopy; - @Unique private ChatLine stratus$chatLine; + @Unique private boolean stratus$chatCheck; @Shadow @Final private Minecraft mc; @Shadow @Final private List<ChatLine> drawnChatLines; + + @Shadow public abstract boolean getChatOpen(); + + @Shadow public abstract float getChatScale(); + + @Shadow public abstract int getLineCount(); + + @Shadow private int scrollPos; @Unique private static final ResourceLocation COPY = new ResourceLocation("stratus:copy.png"); @Inject(method = "setChatLine", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/MathHelper;floor_float(F)I", shift = At.Shift.AFTER)) private void setDoing(IChatComponent chatComponent, int chatLineId, int updateCounter, boolean displayOnly, CallbackInfo ci) { - ChatTabs.INSTANCE.setDoing(true); + if (StratusConfig.INSTANCE.getChatTabs()) { + ChatTabs.INSTANCE.setDoing(true); + } } @Inject(method = "drawChat", at = @At("HEAD")) @@ -44,6 +53,7 @@ public class GuiNewChatMixin extends Gui implements GuiNewChatHook { if (Stratus.INSTANCE.getKeybind().isPressed()) { Stratus.INSTANCE.setDoTheThing(true); } + stratus$chatCheck = false; } @ModifyVariable(method = "drawChat", at = @At("HEAD"), argsOnly = true) @@ -58,42 +68,19 @@ public class GuiNewChatMixin extends Gui implements GuiNewChatHook { : linesToDraw; } - @Redirect(method = "drawChat", at = @At(value = "INVOKE", target = "Ljava/util/List;get(I)Ljava/lang/Object;")) - private Object captureChatLine(List<ChatLine> instance, int i) { - stratus$chatLine = instance.get(i); - return stratus$chatLine; - } - + //TODO: fix with patcher @Redirect(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(int left, int top, int right, int bottom, int color) { drawRect(left, top, right, bottom, color); - final int k1 = Mouse.getX() * UResolution.getScaledWidth() / this.mc.displayWidth; - final int l1 = UResolution.getScaledHeight() - Mouse.getY() * UResolution.getScaledHeight() / this.mc.displayHeight - 1; - int mouseX = k1 - ((GuiIngameForgeHook) mc.ingameGUI).getX() - 2; - int mouseY = l1 - ((GuiIngameForgeHook) mc.ingameGUI).getY() - 20; - if (mouseX >= left && mouseY <= bottom && mouseX - 9 <= right && mouseY >= top) { - stratus$shouldCopy = 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$x = right; - stratus$y = top; - Gui.drawModalRectWithCustomSizedTexture(right, top, 0f, 0f, 9, 9, 9, 9); - GlStateManager.disableAlpha(); - GlStateManager.disableRescaleNormal(); - GlStateManager.disableLighting(); - GlStateManager.popMatrix(); - } else if (stratus$shouldCopy) { - stratus$shouldCopy = false; + if (mc.currentScreen instanceof GuiChat) { + final int k1 = Mouse.getX() * UResolution.getScaledWidth() / this.mc.displayWidth; + final int l1 = UResolution.getScaledHeight() - Mouse.getY() * UResolution.getScaledHeight() / this.mc.displayHeight - 1; + int mouseX = k1 - ((GuiIngameForgeHook) mc.ingameGUI).getX() - 2; + int mouseY = l1 - ((GuiIngameForgeHook) mc.ingameGUI).getY() - 20; + if (mouseX >= left && mouseY < bottom && mouseX < right + 9 && mouseY >= top) { + stratus$shouldCopy = true; + drawCopyChatBox(right, top); + } } } @@ -102,14 +89,16 @@ public class GuiNewChatMixin extends Gui implements GuiNewChatHook { return ChatSearchingKt.filterMessages(drawnChatLines); } - @Override - public int getX() { - return stratus$x; + @Inject(method = "drawChat", at = @At("RETURN")) + private void checkStuff(int j2, CallbackInfo ci) { + if (!stratus$chatCheck && stratus$shouldCopy) { + stratus$shouldCopy = false; + } } @Override - public int getY() { - return stratus$y; + public int getRight() { + return stratus$right; } @Override @@ -117,8 +106,50 @@ public class GuiNewChatMixin extends Gui implements GuiNewChatHook { return stratus$shouldCopy; } + 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 copyString() { - return stratus$chatLine.getChatComponent().getFormattedText(); + 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; + 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; } } diff --git a/src/main/java/com/raeids/stratus/mixin/GuiUtilRenderComponentsMixin.java b/src/main/java/com/raeids/stratus/mixin/GuiUtilRenderComponentsMixin.java index 05378cd..8579f7a 100644 --- a/src/main/java/com/raeids/stratus/mixin/GuiUtilRenderComponentsMixin.java +++ b/src/main/java/com/raeids/stratus/mixin/GuiUtilRenderComponentsMixin.java @@ -1,5 +1,6 @@ package com.raeids.stratus.mixin; +import com.raeids.stratus.config.StratusConfig; import com.raeids.stratus.hook.ChatTabs; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.GuiUtilRenderComponents; @@ -16,11 +17,11 @@ import java.util.List; public class GuiUtilRenderComponentsMixin { @Inject(method = "splitText", at = @At("HEAD"), cancellable = true) private static void cancelText(IChatComponent k, int s1, FontRenderer chatcomponenttext, boolean l, boolean chatcomponenttext2, CallbackInfoReturnable<List<IChatComponent>> cir) { - if (ChatTabs.INSTANCE.isDoing()) { - ChatTabs.INSTANCE.setDoing(false); - if (!ChatTabs.INSTANCE.shouldRender(k.getUnformattedTextForChat())) { + if (StratusConfig.INSTANCE.getChatTabs() && ChatTabs.INSTANCE.isDoing()) { + if (!ChatTabs.INSTANCE.shouldRender(k)) { cir.setReturnValue(Collections.emptyList()); } + ChatTabs.INSTANCE.setDoing(false); } } } diff --git a/src/main/kotlin/com/raeids/stratus/Stratus.kt b/src/main/kotlin/com/raeids/stratus/Stratus.kt index 1b74fa0..0bf6831 100644 --- a/src/main/kotlin/com/raeids/stratus/Stratus.kt +++ b/src/main/kotlin/com/raeids/stratus/Stratus.kt @@ -3,7 +3,6 @@ package com.raeids.stratus import com.raeids.stratus.command.StratusCommand import com.raeids.stratus.config.StratusConfig import com.raeids.stratus.hook.ChatTabs -import com.raeids.stratus.hook.GuiNewChatHook import com.raeids.stratus.mixin.GuiNewChatAccessor import com.raeids.stratus.updater.Updater import com.raeids.stratus.utils.RenderHelper @@ -14,7 +13,6 @@ import net.minecraft.client.gui.FontRenderer import net.minecraft.client.gui.GuiChat import net.minecraft.client.settings.KeyBinding import net.minecraft.client.shader.Framebuffer -import net.minecraftforge.client.event.MouseEvent import net.minecraftforge.common.MinecraftForge.EVENT_BUS import net.minecraftforge.fml.client.registry.ClientRegistry import net.minecraftforge.fml.common.Mod @@ -23,8 +21,6 @@ import net.minecraftforge.fml.common.event.FMLPreInitializationEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import net.minecraftforge.fml.common.gameevent.TickEvent import org.lwjgl.input.Keyboard -import java.awt.Toolkit -import java.awt.datatransfer.StringSelection import java.io.File import java.text.SimpleDateFormat import java.util.* @@ -67,18 +63,6 @@ object Stratus { } @SubscribeEvent - fun onMouseClick(event: MouseEvent) { - val hook = Minecraft.getMinecraft().ingameGUI.chatGUI as GuiNewChatHook - if (hook.shouldCopy()) { - try { - Toolkit.getDefaultToolkit().systemClipboard.setContents(StringSelection(hook.copyString()), null) - } catch (e: Exception) { - e.printStackTrace() - } - } - } - - @SubscribeEvent fun onTickEvent(event: TickEvent.ClientTickEvent) { if (event.phase == TickEvent.Phase.START && Minecraft.getMinecraft().theWorld != null && Minecraft.getMinecraft().thePlayer != null && (Minecraft.getMinecraft().currentScreen == null || Minecraft.getMinecraft().currentScreen is GuiChat)) { if (doTheThing) { diff --git a/src/main/kotlin/com/raeids/stratus/config/StratusConfig.kt b/src/main/kotlin/com/raeids/stratus/config/StratusConfig.kt index 7a2dc65..905f847 100644 --- a/src/main/kotlin/com/raeids/stratus/config/StratusConfig.kt +++ b/src/main/kotlin/com/raeids/stratus/config/StratusConfig.kt @@ -1,6 +1,8 @@ package com.raeids.stratus.config import com.raeids.stratus.Stratus +import com.raeids.stratus.hook.ChatTab +import com.raeids.stratus.hook.ChatTabs import com.raeids.stratus.updater.DownloadGui import com.raeids.stratus.updater.Updater import gg.essential.api.EssentialAPI @@ -15,12 +17,36 @@ object StratusConfig : Vigilant(File(Stratus.modDir, "${Stratus.ID}.toml"), Stra type = PropertyType.SWITCH, name = "Chat Searching", description = "Add a chat search bar.", - category = "General" + category = "Searching" ) var chatSearch = true @Property( type = PropertyType.SWITCH, + name = "Chat Tabs", + description = "Add chat tabs.", + category = "Tabs" + ) + var chatTabs = true + get() { + if (!field) return false + return if (hypixelOnlyChatTabs) { + EssentialAPI.getMinecraftUtil().isHypixel() + } else { + true + } + } + + @Property( + type = PropertyType.SWITCH, + name = "Enable Only on Hypixel", + description = "Enable chat tabs only in Hypixel.", + category = "Tabs" + ) + var hypixelOnlyChatTabs = true + + @Property( + type = PropertyType.SWITCH, name = "Show Update Notification", description = "Show a notification when you start Minecraft informing you of new updates.", category = "Updater" @@ -44,5 +70,9 @@ object StratusConfig : Vigilant(File(Stratus.modDir, "${Stratus.ID}.toml"), Stra init { initialize() + registerListener("chatTabs") { funny: Boolean -> + chatTabs = funny + ChatTabs.currentTab = ChatTab("ALL", false, null, null, null, null, null, "") + } } }
\ No newline at end of file diff --git a/src/main/kotlin/com/raeids/stratus/hook/ChatRegexes.kt b/src/main/kotlin/com/raeids/stratus/hook/ChatRegexes.kt new file mode 100644 index 0000000..fd743ea --- /dev/null +++ b/src/main/kotlin/com/raeids/stratus/hook/ChatRegexes.kt @@ -0,0 +1,11 @@ +package com.raeids.stratus.hook + +data class ChatRegexes(val regexList: List<String>?) { + val compiledRegexList: MutableList<Regex> = arrayListOf() + + init { + regexList?.forEach { + compiledRegexList.add(Regex(it)) + } + } +} diff --git a/src/main/kotlin/com/raeids/stratus/hook/ChatTab.kt b/src/main/kotlin/com/raeids/stratus/hook/ChatTab.kt index f2fd0fc..3609fdc 100644 --- a/src/main/kotlin/com/raeids/stratus/hook/ChatTab.kt +++ b/src/main/kotlin/com/raeids/stratus/hook/ChatTab.kt @@ -3,39 +3,38 @@ package com.raeids.stratus.hook import com.google.gson.annotations.SerializedName import kotlinx.coroutines.runBlocking import net.minecraft.client.Minecraft +import net.minecraft.util.EnumChatFormatting +import net.minecraft.util.IChatComponent data class ChatTab( - @SerializedName("name") val name: String, + val name: String, + val unformatted: Boolean, @SerializedName("starts") val startsWith: List<String>?, - @SerializedName("contains") val contains: List<String>?, + val contains: List<String>?, @SerializedName("ends") val endsWith: List<String>?, - @SerializedName("equals") val equals: List<String>?, + val equals: List<String>?, @SerializedName("regex") val uncompiledRegex: List<String>?, - @SerializedName("prefix") val prefix: String + val prefix: String ) { lateinit var button: CleanButton - var compiledRegex: MutableList<Regex> = arrayListOf() + lateinit var compiledRegex: ChatRegexes //Ugly hack to make GSON not make button / regex null fun initialize() { - compiledRegex = arrayListOf() + compiledRegex = ChatRegexes(uncompiledRegex) val width = Minecraft.getMinecraft().fontRendererObj.getStringWidth(name) button = CleanButton(653452, runBlocking { val returnValue = x - 2 x += 6 + width return@runBlocking returnValue }, 0, width + 4, 12, this) - if (uncompiledRegex != null && uncompiledRegex.isNotEmpty()) { - uncompiledRegex.forEach { - compiledRegex.add(Regex(it)) - } - } } - fun shouldRender(message: String): Boolean { + fun shouldRender(chatComponent: IChatComponent): Boolean { if (startsWith == null && equals == null && endsWith == null && contains == null && uncompiledRegex == null) { return true } + val message = if (unformatted) EnumChatFormatting.getTextWithoutFormattingCodes(chatComponent.unformattedText) else chatComponent.formattedText equals?.forEach { if (message == it) { return true @@ -56,15 +55,9 @@ data class ChatTab( return true } } - if ((uncompiledRegex != null) && uncompiledRegex.isNotEmpty()) { - try { - compiledRegex.forEach { - if (it.matches(message)) { - return true - } - } - } catch (_: Throwable) { - + compiledRegex.compiledRegexList.forEach { + if (it.matches(message)) { + return true } } return false diff --git a/src/main/kotlin/com/raeids/stratus/hook/ChatTabs.kt b/src/main/kotlin/com/raeids/stratus/hook/ChatTabs.kt index 0e845d5..b162671 100644 --- a/src/main/kotlin/com/raeids/stratus/hook/ChatTabs.kt +++ b/src/main/kotlin/com/raeids/stratus/hook/ChatTabs.kt @@ -3,6 +3,7 @@ package com.raeids.stratus.hook import com.google.gson.* import com.raeids.stratus.Stratus import net.minecraft.client.Minecraft +import net.minecraft.util.IChatComponent import java.io.File object ChatTabs { @@ -43,7 +44,7 @@ object ChatTabs { currentTab = tabs[0] } - fun shouldRender(message: String): Boolean { + fun shouldRender(message: IChatComponent): Boolean { return currentTab?.shouldRender(message) ?: true } @@ -57,9 +58,10 @@ object ChatTabs { } private fun generateDefaultTabs(): JsonArray { - val all = ChatTab("ALL", null, null, null, null, null, "") + val all = ChatTab("ALL", false, null, null, null, null, null, "/ac ") val party = ChatTab( "PARTY", + false, listOf("§r§9Party §8> ", "§r§9P §8> ", "§eThe party was transferred to §r", "§eKicked §r"), null, listOf( @@ -78,7 +80,8 @@ object ChatTabs { ) val guild = ChatTab( "GUILD", - listOf("§r§2Guild > ", "§r§2G > "), + true, + listOf("Guild >", "G >"), null, null, null, @@ -87,7 +90,8 @@ object ChatTabs { ) val pm = ChatTab( "PM", - listOf("§dTo ", "§dFrom "), + true, + listOf("To ", "From "), null, null, null, diff --git a/src/main/resources/mixins.stratus.json b/src/main/resources/mixins.stratus.json index 35f3de0..7e8339e 100644 --- a/src/main/resources/mixins.stratus.json +++ b/src/main/resources/mixins.stratus.json @@ -8,6 +8,7 @@ "GuiNewChatAccessor", "GuiUtilRenderComponentsMixin", "GuiIngameForgeMixin", + "EntityPlayerSPMixin", "GuiNewChatMixin" ], "verbose": true |