From 487709996c22fb0dbcac792076be799a09865600 Mon Sep 17 00:00:00 2001 From: Wyvest <45589059+Wyvest@users.noreply.github.com> Date: Mon, 3 Jan 2022 11:12:54 +0700 Subject: Chattils -> Chatting (1.1.0) Update images (ty Mo2men) update screenshot line tooltip (ty Mo2men) --- .../cc/woverflow/chattils/hook/GuiNewChatHook.java | 23 -- .../chattils/mixin/ClientCommandHandlerMixin.java | 34 --- .../chattils/mixin/EntityPlayerSPMixin.java | 21 -- .../cc/woverflow/chattils/mixin/GuiChatMixin.java | 117 ---------- .../chattils/mixin/GuiNewChatAccessor.java | 17 -- .../chattils/mixin/GuiNewChatMapMixin.java | 78 ------- .../woverflow/chattils/mixin/GuiNewChatMixin.java | 240 -------------------- .../cc/woverflow/chattils/mixin/GuiUtilsMixin.java | 22 -- .../chattils/mixin/WyvtilsListenerMixin.java | 21 -- .../cc/woverflow/chatting/hook/GuiNewChatHook.java | 23 ++ .../chatting/mixin/ClientCommandHandlerMixin.java | 33 +++ .../chatting/mixin/EntityPlayerSPMixin.java | 21 ++ .../cc/woverflow/chatting/mixin/GuiChatMixin.java | 117 ++++++++++ .../chatting/mixin/GuiNewChatAccessor.java | 17 ++ .../chatting/mixin/GuiNewChatMapMixin.java | 78 +++++++ .../woverflow/chatting/mixin/GuiNewChatMixin.java | 242 +++++++++++++++++++++ .../cc/woverflow/chatting/mixin/GuiUtilsMixin.java | 22 ++ .../chatting/mixin/WyvtilsListenerMixin.java | 21 ++ 18 files changed, 574 insertions(+), 573 deletions(-) delete mode 100644 src/main/java/cc/woverflow/chattils/hook/GuiNewChatHook.java delete mode 100644 src/main/java/cc/woverflow/chattils/mixin/ClientCommandHandlerMixin.java delete mode 100644 src/main/java/cc/woverflow/chattils/mixin/EntityPlayerSPMixin.java delete mode 100644 src/main/java/cc/woverflow/chattils/mixin/GuiChatMixin.java delete mode 100644 src/main/java/cc/woverflow/chattils/mixin/GuiNewChatAccessor.java delete mode 100644 src/main/java/cc/woverflow/chattils/mixin/GuiNewChatMapMixin.java delete mode 100644 src/main/java/cc/woverflow/chattils/mixin/GuiNewChatMixin.java delete mode 100644 src/main/java/cc/woverflow/chattils/mixin/GuiUtilsMixin.java delete mode 100644 src/main/java/cc/woverflow/chattils/mixin/WyvtilsListenerMixin.java create mode 100644 src/main/java/cc/woverflow/chatting/hook/GuiNewChatHook.java create mode 100644 src/main/java/cc/woverflow/chatting/mixin/ClientCommandHandlerMixin.java create mode 100644 src/main/java/cc/woverflow/chatting/mixin/EntityPlayerSPMixin.java create mode 100644 src/main/java/cc/woverflow/chatting/mixin/GuiChatMixin.java create mode 100644 src/main/java/cc/woverflow/chatting/mixin/GuiNewChatAccessor.java create mode 100644 src/main/java/cc/woverflow/chatting/mixin/GuiNewChatMapMixin.java create mode 100644 src/main/java/cc/woverflow/chatting/mixin/GuiNewChatMixin.java create mode 100644 src/main/java/cc/woverflow/chatting/mixin/GuiUtilsMixin.java create mode 100644 src/main/java/cc/woverflow/chatting/mixin/WyvtilsListenerMixin.java (limited to 'src/main/java/cc/woverflow') diff --git a/src/main/java/cc/woverflow/chattils/hook/GuiNewChatHook.java b/src/main/java/cc/woverflow/chattils/hook/GuiNewChatHook.java deleted file mode 100644 index f84fd43..0000000 --- a/src/main/java/cc/woverflow/chattils/hook/GuiNewChatHook.java +++ /dev/null @@ -1,23 +0,0 @@ -package cc.woverflow.chattils.hook; - -import net.minecraft.client.gui.ChatLine; - -import java.awt.datatransfer.Transferable; - -public interface GuiNewChatHook { - int getRight(); - - boolean shouldCopy(); - - Transferable getChattilsChatComponent(int mouseY); - - default ChatLine getFullMessage(ChatLine line) { - throw new AssertionError("getFullMessage not overridden on GuiNewChat"); - } - - String getPrevText(); - - void setPrevText(String prevText); - - int getTextOpacity(); -} diff --git a/src/main/java/cc/woverflow/chattils/mixin/ClientCommandHandlerMixin.java b/src/main/java/cc/woverflow/chattils/mixin/ClientCommandHandlerMixin.java deleted file mode 100644 index 0692342..0000000 --- a/src/main/java/cc/woverflow/chattils/mixin/ClientCommandHandlerMixin.java +++ /dev/null @@ -1,34 +0,0 @@ -package cc.woverflow.chattils.mixin; - -import cc.woverflow.chattils.chat.ChatShortcuts; -import cc.woverflow.chattils.config.ChattilsConfig; -import kotlin.Pair; -import net.minecraft.client.Minecraft; -import net.minecraft.command.CommandHandler; -import net.minecraft.command.ICommandSender; -import net.minecraft.util.BlockPos; -import net.minecraftforge.client.ClientCommandHandler; -import net.minecraftforge.fml.client.FMLClientHandler; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -import java.util.Iterator; -import java.util.List; - -@Mixin(value = ClientCommandHandler.class, remap = false) -public class ClientCommandHandlerMixin extends CommandHandler { - @Redirect(method = "autoComplete", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/client/ClientCommandHandler;getTabCompletionOptions(Lnet/minecraft/command/ICommandSender;Ljava/lang/String;Lnet/minecraft/util/BlockPos;)Ljava/util/List;")) - private List addChatShortcuts(ClientCommandHandler instance, ICommandSender iCommandSender, String leftOfCursor, BlockPos blockPos) { - Minecraft mc = FMLClientHandler.instance().getClient(); - List autocompleteList = instance.getTabCompletionOptions(mc.thePlayer, leftOfCursor, mc.thePlayer.getPosition()); - if (ChattilsConfig.INSTANCE.getChatShortcuts()) { - for (Pair pair : ChatShortcuts.INSTANCE.getShortcuts()) { - if (pair.getFirst().startsWith(leftOfCursor)) { - autocompleteList.add(pair.getFirst()); - } - } - } - return autocompleteList; - } -} diff --git a/src/main/java/cc/woverflow/chattils/mixin/EntityPlayerSPMixin.java b/src/main/java/cc/woverflow/chattils/mixin/EntityPlayerSPMixin.java deleted file mode 100644 index 48dfc10..0000000 --- a/src/main/java/cc/woverflow/chattils/mixin/EntityPlayerSPMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package cc.woverflow.chattils.mixin; - -import cc.woverflow.chattils.chat.ChatTabs; -import cc.woverflow.chattils.config.ChattilsConfig; -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 (ChattilsConfig.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/cc/woverflow/chattils/mixin/GuiChatMixin.java b/src/main/java/cc/woverflow/chattils/mixin/GuiChatMixin.java deleted file mode 100644 index 9af0204..0000000 --- a/src/main/java/cc/woverflow/chattils/mixin/GuiChatMixin.java +++ /dev/null @@ -1,117 +0,0 @@ -package cc.woverflow.chattils.mixin; - -import cc.woverflow.chattils.chat.ChatSearchingManager; -import cc.woverflow.chattils.chat.ChatShortcuts; -import cc.woverflow.chattils.chat.ChatTab; -import cc.woverflow.chattils.chat.ChatTabs; -import cc.woverflow.chattils.config.ChattilsConfig; -import cc.woverflow.chattils.gui.components.ScreenshotButton; -import cc.woverflow.chattils.gui.components.SearchButton; -import cc.woverflow.chattils.hook.GuiNewChatHook; -import cc.woverflow.chattils.utils.ModCompatHooks; -import com.google.common.collect.Lists; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiChat; -import net.minecraft.client.gui.GuiScreen; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.util.MathHelper; -import net.minecraftforge.fml.client.config.GuiUtils; -import org.apache.commons.lang3.StringUtils; -import org.lwjgl.input.Mouse; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyArg; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.awt.*; -import java.awt.datatransfer.Transferable; -import java.util.List; - -@Mixin(GuiChat.class) -public abstract class GuiChatMixin extends GuiScreen { - - @Unique - private static final List COPY_TOOLTIP = Lists.newArrayList( - "\u00A73\u00A7l\u00A7nCopy To Clipboard", - "\u00A7lNORMAL CLICK\u00A7r - Full Message", - "\u00A7lCTRL CLICK\u00A7r - Single Line", - "\u00A7lSHIFT CLICK\u00A7r - Screenshot Line", - "", - "\u00A73\u00A7l\u00A7nModifiers", - "\u00A7lALT\u00A7r - Formatting Codes"); - - private SearchButton searchButton; - - @Inject(method = "initGui", at = @At("TAIL")) - private void init(CallbackInfo ci) { - if (ChattilsConfig.INSTANCE.getChatSearch()) { - searchButton = new SearchButton(); - buttonList.add(searchButton); - } - buttonList.add(new ScreenshotButton()); - if (ChattilsConfig.INSTANCE.getChatTabs()) { - for (ChatTab chatTab : ChatTabs.INSTANCE.getTabs()) { - buttonList.add(chatTab.getButton()); - } - } - } - - @Inject(method = "updateScreen", at = @At("HEAD")) - private void updateScreen(CallbackInfo ci) { - if (ChattilsConfig.INSTANCE.getChatSearch() && searchButton.isEnabled()) { - searchButton.getInputField().updateCursorCounter(); - } - } - - @Inject(method = "keyTyped", at = @At("HEAD"), cancellable = true) - private void keyTyped(char typedChar, int keyCode, CallbackInfo ci) { - if (ChattilsConfig.INSTANCE.getChatSearch() && searchButton.isEnabled()) { - ci.cancel(); - if (keyCode == 1) { - searchButton.onMousePress(); - return; - } - searchButton.getInputField().textboxKeyTyped(typedChar, keyCode); - ChatSearchingManager.setPrevText(searchButton.getInputField().getText()); - } - } - - @Inject(method = "drawScreen", at = @At("HEAD")) - private void onDrawScreen(int mouseX, int mouseY, float partialTicks, CallbackInfo ci) { - GuiNewChatHook hook = ((GuiNewChatHook) Minecraft.getMinecraft().ingameGUI.getChatGUI()); - float f = mc.ingameGUI.getChatGUI().getChatScale(); - int x = MathHelper.floor_float((float) mouseX / f); - if (hook.shouldCopy() && (hook.getRight() + ModCompatHooks.getXOffset()) <= x && (hook.getRight() + ModCompatHooks.getXOffset()) + 9 > x) { - GuiUtils.drawHoveringText(COPY_TOOLTIP, mouseX, mouseY, width, height, -1, fontRendererObj); - GlStateManager.disableLighting(); - } - } - - @Inject(method = "mouseClicked", at = @At("HEAD")) - private void mouseClicked(int mouseX, int mouseY, int mouseButton, CallbackInfo ci) { - GuiNewChatHook hook = ((GuiNewChatHook) Minecraft.getMinecraft().ingameGUI.getChatGUI()); - float f = mc.ingameGUI.getChatGUI().getChatScale(); - int x = MathHelper.floor_float((float) mouseX / f); - if (hook.shouldCopy() && (hook.getRight() + ModCompatHooks.getXOffset()) <= x && (hook.getRight() + ModCompatHooks.getXOffset()) + 9 > x) { - Transferable message = hook.getChattilsChatComponent(Mouse.getY()); - if (message == null) return; - try { - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(message, null); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - @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 (ChattilsConfig.INSTANCE.getChatShortcuts()) { - if (original.startsWith("/")) { - return "/" + ChatShortcuts.INSTANCE.handleSentCommand(StringUtils.substringAfter(original, "/")); - } - } - return original; - } -} diff --git a/src/main/java/cc/woverflow/chattils/mixin/GuiNewChatAccessor.java b/src/main/java/cc/woverflow/chattils/mixin/GuiNewChatAccessor.java deleted file mode 100644 index 1bce77a..0000000 --- a/src/main/java/cc/woverflow/chattils/mixin/GuiNewChatAccessor.java +++ /dev/null @@ -1,17 +0,0 @@ -package cc.woverflow.chattils.mixin; - -import net.minecraft.client.gui.ChatLine; -import net.minecraft.client.gui.GuiNewChat; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import java.util.List; - -@Mixin(GuiNewChat.class) -public interface GuiNewChatAccessor { - @Accessor - List getDrawnChatLines(); - - @Accessor - int getScrollPos(); -} diff --git a/src/main/java/cc/woverflow/chattils/mixin/GuiNewChatMapMixin.java b/src/main/java/cc/woverflow/chattils/mixin/GuiNewChatMapMixin.java deleted file mode 100644 index 97d39c5..0000000 --- a/src/main/java/cc/woverflow/chattils/mixin/GuiNewChatMapMixin.java +++ /dev/null @@ -1,78 +0,0 @@ -package cc.woverflow.chattils.mixin; - -import cc.woverflow.chattils.hook.GuiNewChatHook; -import net.minecraft.client.gui.ChatLine; -import net.minecraft.client.gui.GuiNewChat; -import net.minecraft.util.IChatComponent; -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.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Mixin(value = GuiNewChat.class, priority = Integer.MIN_VALUE) -public abstract class GuiNewChatMapMixin implements GuiNewChatHook { - - @Unique private final Map drawnToFull = new HashMap<>(); - @Unique private final List tempDrawnLines = new ArrayList<>(); - @Unique private ChatLine lastTempLine = null; - - @Shadow @Final private List drawnChatLines; - @Shadow @Final private List chatLines; - - @Inject(method = "setChatLine", at = @At("HEAD")) - private void handleSetChatLine(IChatComponent chatComponent, int chatLineId, int updateCounter, boolean displayOnly, CallbackInfo ci) { - tempDrawnLines.clear(); - } - - @Inject(method = "setChatLine", at = @At(value = "INVOKE", target = "Ljava/util/List;add(ILjava/lang/Object;)V", ordinal = 0, shift = At.Shift.AFTER, remap = false)) - private void handleDrawnLineAdded(IChatComponent chatComponent, int chatLineId, int updateCounter, boolean displayOnly, CallbackInfo ci) { - if (!displayOnly) tempDrawnLines.add(drawnChatLines.get(0)); - else if (lastTempLine != null) { - drawnToFull.put(drawnChatLines.get(0), lastTempLine); - } - } - - @Inject(method = "setChatLine", at = @At(value = "INVOKE", target = "Ljava/util/List;remove(I)Ljava/lang/Object;", ordinal = 0, shift = At.Shift.BEFORE, remap = false)) - private void handleDrawnLineRemoved(IChatComponent chatComponent, int chatLineId, int updateCounter, boolean displayOnly, CallbackInfo ci) { - drawnToFull.remove(drawnChatLines.get(drawnChatLines.size() - 1)); - } - - @Inject(method = "setChatLine", at = @At("RETURN")) - private void handleLineAdded(IChatComponent chatComponent, int chatLineId, int updateCounter, boolean displayOnly, CallbackInfo ci) { - if (!displayOnly) { - ChatLine masterLine = chatLines.get(0); - for (ChatLine tempDrawnLine : tempDrawnLines) drawnToFull.put(tempDrawnLine, masterLine); - }else { - lastTempLine = null; - } - } - - @Inject(method = "refreshChat", at = @At("HEAD")) - private void handleRefreshedChat(CallbackInfo ci) { - drawnToFull.clear(); - } - - @Inject(method = "refreshChat", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiNewChat;setChatLine(Lnet/minecraft/util/IChatComponent;IIZ)V", ordinal = 0, shift = At.Shift.BEFORE)) - private void handleLineRefresh(CallbackInfo ci, int i, ChatLine chatline) { - lastTempLine = chatline; - } - - @Inject(method = "clearChatMessages", at = @At("HEAD")) - private void handleChatCleared(CallbackInfo ci) { - drawnToFull.clear(); - } - - @Override - public ChatLine getFullMessage(ChatLine line) { - return drawnToFull.getOrDefault(line, null); - } -} diff --git a/src/main/java/cc/woverflow/chattils/mixin/GuiNewChatMixin.java b/src/main/java/cc/woverflow/chattils/mixin/GuiNewChatMixin.java deleted file mode 100644 index eea68c8..0000000 --- a/src/main/java/cc/woverflow/chattils/mixin/GuiNewChatMixin.java +++ /dev/null @@ -1,240 +0,0 @@ -package cc.woverflow.chattils.mixin; - -import cc.woverflow.chattils.Chattils; -import cc.woverflow.chattils.chat.ChatSearchingManager; -import cc.woverflow.chattils.chat.ChatTabs; -import cc.woverflow.chattils.config.ChattilsConfig; -import cc.woverflow.chattils.hook.GuiNewChatHook; -import cc.woverflow.chattils.utils.ModCompatHooks; -import cc.woverflow.chattils.utils.RenderHelper; -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.EnumChatFormatting; -import net.minecraft.util.IChatComponent; -import net.minecraft.util.MathHelper; -import net.minecraft.util.ResourceLocation; -import org.objectweb.asm.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.callback.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.invoke.arg.Args; - -import java.awt.datatransfer.StringSelection; -import java.awt.datatransfer.Transferable; -import java.awt.image.BufferedImage; -import java.util.List; -import java.util.Locale; - -@Mixin(value = GuiNewChat.class, priority = Integer.MIN_VALUE) -public abstract class GuiNewChatMixin extends Gui implements GuiNewChatHook { - @Unique private int chattils$right = 0; - @Unique private boolean chattils$shouldCopy; - @Unique private boolean chattils$chatCheck; - @Unique private int chattils$textOpacity; - @Shadow @Final private Minecraft mc; - @Shadow @Final private List drawnChatLines; - @SuppressWarnings({"FieldCanBeLocal", "unused"}) - private float percentComplete; - private String chattils$previousText = ""; - - @Shadow public abstract boolean getChatOpen(); - - @Shadow public abstract float getChatScale(); - - @Shadow public abstract int getLineCount(); - - @Shadow private int scrollPos; - @Shadow @Final private List chatLines; - - @Shadow public abstract void deleteChatLine(int id); - - @Unique private static final ResourceLocation COPY = new ResourceLocation("chattils: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); - if (!EnumChatFormatting.getTextWithoutFormattingCodes(chatComponent.getUnformattedText()).toLowerCase(Locale.ENGLISH).contains(chattils$previousText.toLowerCase(Locale.ENGLISH))) { - percentComplete = 1.0F; - } - } - - @Inject(method = "setChatLine", at = @At("HEAD"), cancellable = true) - private void handleSetChatLine(IChatComponent chatComponent, int chatLineId, int updateCounter, boolean displayOnly, CallbackInfo ci) { - ChatSearchingManager.getCache().invalidateAll(); - handleChatTabMessage(chatComponent, chatLineId, updateCounter, displayOnly, ci); - } - - @Inject(method = "drawChat", at = @At("HEAD")) - private void checkScreenshotKeybind(int j2, CallbackInfo ci) { - if (Chattils.INSTANCE.getKeybind().isPressed()) { - Chattils.INSTANCE.setDoTheThing(true); - } - chattils$chatCheck = false; - } - - @ModifyVariable(method = "drawChat", at = @At("HEAD"), argsOnly = true) - private int setUpdateCounterWhjenYes(int updateCounter) { - return Chattils.INSTANCE.getDoTheThing() ? 0 : updateCounter; - } - - @ModifyVariable(method = "drawChat", at = @At("STORE"), index = 2) - private int setChatLimitWhenYes(int linesToDraw) { - return Chattils.INSTANCE.getDoTheThing() - ? GuiNewChat.calculateChatboxHeight(mc.gameSettings.chatHeightFocused) / 9 - : linesToDraw; - } - - @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 + ModCompatHooks.getYOffset() - ModCompatHooks.getChatPosition(); - mouseX = MathHelper.floor_float((float)mouseX / f); - mouseY = -(MathHelper.floor_float((float)mouseY / f)); //WHY DO I NEED TO DO THIS - if (mouseX >= (left + ModCompatHooks.getXOffset()) && mouseY < bottom && mouseX < (right + 9 + ModCompatHooks.getXOffset()) && mouseY >= top) { - chattils$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 injected(GuiNewChat instance) { - return ChatSearchingManager.filterMessages(chattils$previousText, drawnChatLines); - } - - @ModifyVariable(method = "drawChat", at = @At("STORE"), ordinal = 7) - private int modifyYeah(int value) { - return chattils$textOpacity = (int) (((float) (getChatOpen() ? 255 : value)) * (mc.gameSettings.chatOpacity * 0.9F + 0.1F)); - } - - @Redirect(method = "drawChat", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/FontRenderer;drawStringWithShadow(Ljava/lang/String;FFI)I")) - private int redirectDrawString(FontRenderer instance, String text, float x, float y, int color) { - return ModCompatHooks.redirectDrawString(text, x, y, color); - } - - @Inject(method = "drawChat", at = @At("RETURN")) - private void checkStuff(int j2, CallbackInfo ci) { - if (!chattils$chatCheck && chattils$shouldCopy) { - chattils$shouldCopy = false; - } - } - - @Inject(method = "getChatHeight", at = @At("HEAD"), cancellable = true) - private void customHeight_getChatHeight(CallbackInfoReturnable cir) { - if (ChattilsConfig.INSTANCE.getCustomChatHeight()) cir.setReturnValue(Chattils.INSTANCE.getChatHeight(this.getChatOpen())); - } - - @Override - public int getRight() { - return chattils$right; - } - - @Override - public boolean shouldCopy() { - return chattils$shouldCopy; - } - - private void handleChatTabMessage(IChatComponent chatComponent, int chatLineId, int updateCounter, boolean displayOnly, CallbackInfo ci) { - if (ChattilsConfig.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() > (100 + ModCompatHooks.getExtendedChatLength())) - { - this.chatLines.remove(this.chatLines.size() - 1); - } - } - ci.cancel(); - } - } - } - - private void drawCopyChatBox(int right, int top) { - chattils$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); - chattils$right = right; - Gui.drawModalRectWithCustomSizedTexture(right, top, 0f, 0f, 9, 9, 9, 9); - GlStateManager.disableAlpha(); - GlStateManager.disableRescaleNormal(); - GlStateManager.disableLighting(); - GlStateManager.popMatrix(); - } - - @Override - public Transferable getChattilsChatComponent(int mouseY) { - if (this.getChatOpen()) { - ScaledResolution scaledresolution = new ScaledResolution(this.mc); - int i = scaledresolution.getScaleFactor(); - float f = this.getChatScale(); - int k = mouseY / i - 27 + ModCompatHooks.getYOffset() - ModCompatHooks.getChatPosition(); - 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()) { - ChatLine subLine = this.drawnChatLines.get(i1); - ChatLine fullLine = this.getFullMessage(subLine); - if (GuiScreen.isShiftKeyDown()) { - if (fullLine != null) { - BufferedImage image = Chattils.INSTANCE.screenshotLine(fullLine); - if (image != null) RenderHelper.INSTANCE.copyBufferedImageToClipboard(image); - } - return null; - } - ChatLine line = GuiScreen.isCtrlKeyDown() ? subLine : fullLine; - String message = line == null ? "Could not find chat message." : line.getChatComponent().getFormattedText(); - return new StringSelection(GuiScreen.isAltKeyDown() ? message : EnumChatFormatting.getTextWithoutFormattingCodes(message)); - } - - } - } - } - return null; - } - - @Override - public String getPrevText() { - return chattils$previousText; - } - - @Override - public void setPrevText(String prevText) { - chattils$previousText = prevText; - } - - @Override - public int getTextOpacity() { - return chattils$textOpacity; - } -} diff --git a/src/main/java/cc/woverflow/chattils/mixin/GuiUtilsMixin.java b/src/main/java/cc/woverflow/chattils/mixin/GuiUtilsMixin.java deleted file mode 100644 index df8216b..0000000 --- a/src/main/java/cc/woverflow/chattils/mixin/GuiUtilsMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package cc.woverflow.chattils.mixin; - -import cc.woverflow.chattils.config.ChattilsConfig; -import net.minecraftforge.fml.client.config.GuiUtils; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(value = GuiUtils.class, remap = false) -public class GuiUtilsMixin { - @Shadow - public static void drawGradientRect(int zLevel, int left, int top, int right, int bottom, int startColor, int endColor) { - } - - @Redirect(method = "drawHoveringText", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/client/config/GuiUtils;drawGradientRect(IIIIIII)V")) - private static void redirectBackground(int zLevel, int left, int top, int right, int bottom, int startColor, int endColor) { - if (!ChattilsConfig.INSTANCE.getRemoveTooltipBackground()) { - drawGradientRect(zLevel, left, top, right, bottom, startColor, endColor); - } - } -} diff --git a/src/main/java/cc/woverflow/chattils/mixin/WyvtilsListenerMixin.java b/src/main/java/cc/woverflow/chattils/mixin/WyvtilsListenerMixin.java deleted file mode 100644 index 13a4167..0000000 --- a/src/main/java/cc/woverflow/chattils/mixin/WyvtilsListenerMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package cc.woverflow.chattils.mixin; - -import cc.woverflow.chattils.utils.RenderHelper; -import org.spongepowered.asm.mixin.Dynamic; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Pseudo; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Coerce; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Pseudo -@Mixin(targets = "net.wyvest.wyvtils.core.listener.Listener") -public class WyvtilsListenerMixin { - - @Dynamic("Wyvtils") - @Inject(method = "onStringRendered", at = @At("HEAD"), cancellable = true, remap = false) - private void cancelStringRender(@Coerce Object a, CallbackInfo ci) { - if (RenderHelper.INSTANCE.getBypassWyvtils()) ci.cancel(); - } -} diff --git a/src/main/java/cc/woverflow/chatting/hook/GuiNewChatHook.java b/src/main/java/cc/woverflow/chatting/hook/GuiNewChatHook.java new file mode 100644 index 0000000..51b19d4 --- /dev/null +++ b/src/main/java/cc/woverflow/chatting/hook/GuiNewChatHook.java @@ -0,0 +1,23 @@ +package cc.woverflow.chatting.hook; + +import net.minecraft.client.gui.ChatLine; + +import java.awt.datatransfer.Transferable; + +public interface GuiNewChatHook { + int getRight(); + + boolean shouldCopy(); + + Transferable getChattingChatComponent(int mouseY); + + default ChatLine getFullMessage(ChatLine line) { + throw new AssertionError("getFullMessage not overridden on GuiNewChat"); + } + + String getPrevText(); + + void setPrevText(String prevText); + + int getTextOpacity(); +} diff --git a/src/main/java/cc/woverflow/chatting/mixin/ClientCommandHandlerMixin.java b/src/main/java/cc/woverflow/chatting/mixin/ClientCommandHandlerMixin.java new file mode 100644 index 0000000..f771c87 --- /dev/null +++ b/src/main/java/cc/woverflow/chatting/mixin/ClientCommandHandlerMixin.java @@ -0,0 +1,33 @@ +package cc.woverflow.chatting.mixin; + +import cc.woverflow.chatting.chat.ChatShortcuts; +import cc.woverflow.chatting.config.ChattingConfig; +import kotlin.Pair; +import net.minecraft.client.Minecraft; +import net.minecraft.command.CommandHandler; +import net.minecraft.command.ICommandSender; +import net.minecraft.util.BlockPos; +import net.minecraftforge.client.ClientCommandHandler; +import net.minecraftforge.fml.client.FMLClientHandler; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.util.List; + +@Mixin(value = ClientCommandHandler.class, remap = false) +public class ClientCommandHandlerMixin extends CommandHandler { + @Redirect(method = "autoComplete", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/client/ClientCommandHandler;getTabCompletionOptions(Lnet/minecraft/command/ICommandSender;Ljava/lang/String;Lnet/minecraft/util/BlockPos;)Ljava/util/List;")) + private List addChatShortcuts(ClientCommandHandler instance, ICommandSender iCommandSender, String leftOfCursor, BlockPos blockPos) { + Minecraft mc = FMLClientHandler.instance().getClient(); + List autocompleteList = instance.getTabCompletionOptions(mc.thePlayer, leftOfCursor, mc.thePlayer.getPosition()); + if (ChattingConfig.INSTANCE.getChatShortcuts()) { + for (Pair pair : ChatShortcuts.INSTANCE.getShortcuts()) { + if (pair.getFirst().startsWith(leftOfCursor)) { + autocompleteList.add(pair.getFirst()); + } + } + } + return autocompleteList; + } +} diff --git a/src/main/java/cc/woverflow/chatting/mixin/EntityPlayerSPMixin.java b/src/main/java/cc/woverflow/chatting/mixin/EntityPlayerSPMixin.java new file mode 100644 index 0000000..42c5579 --- /dev/null +++ b/src/main/java/cc/woverflow/chatting/mixin/EntityPlayerSPMixin.java @@ -0,0 +1,21 @@ +package cc.woverflow.chatting.mixin; + +import cc.woverflow.chatting.chat.ChatTabs; +import cc.woverflow.chatting.config.ChattingConfig; +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 (ChattingConfig.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/cc/woverflow/chatting/mixin/GuiChatMixin.java b/src/main/java/cc/woverflow/chatting/mixin/GuiChatMixin.java new file mode 100644 index 0000000..73b76e7 --- /dev/null +++ b/src/main/java/cc/woverflow/chatting/mixin/GuiChatMixin.java @@ -0,0 +1,117 @@ +package cc.woverflow.chatting.mixin; + +import cc.woverflow.chatting.chat.ChatSearchingManager; +import cc.woverflow.chatting.chat.ChatShortcuts; +import cc.woverflow.chatting.chat.ChatTab; +import cc.woverflow.chatting.chat.ChatTabs; +import cc.woverflow.chatting.config.ChattingConfig; +import cc.woverflow.chatting.gui.components.ScreenshotButton; +import cc.woverflow.chatting.gui.components.SearchButton; +import cc.woverflow.chatting.hook.GuiNewChatHook; +import cc.woverflow.chatting.utils.ModCompatHooks; +import com.google.common.collect.Lists; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiChat; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.util.MathHelper; +import net.minecraftforge.fml.client.config.GuiUtils; +import org.apache.commons.lang3.StringUtils; +import org.lwjgl.input.Mouse; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.awt.*; +import java.awt.datatransfer.Transferable; +import java.util.List; + +@Mixin(GuiChat.class) +public abstract class GuiChatMixin extends GuiScreen { + + @Unique + private static final List COPY_TOOLTIP = Lists.newArrayList( + "\u00A7e\u00A7lCopy To Clipboard", + "\u00A7b\u00A7lNORMAL CLICK\u00A7r \u00A78- \u00A77Full Message", + "\u00A7b\u00A7lCTRL CLICK\u00A7r \u00A78- \u00A77Single Line", + "\u00A7b\u00A7lSHIFT CLICK\u00A7r \u00A78- \u00A77Screenshot Line", + "", + "\u00A7e\u00A7lModifiers", + "\u00A7b\u00A7lALT\u00A7r \u00A78- \u00A77Formatting Codes"); + + private SearchButton searchButton; + + @Inject(method = "initGui", at = @At("TAIL")) + private void init(CallbackInfo ci) { + if (ChattingConfig.INSTANCE.getChatSearch()) { + searchButton = new SearchButton(); + buttonList.add(searchButton); + } + buttonList.add(new ScreenshotButton()); + if (ChattingConfig.INSTANCE.getChatTabs()) { + for (ChatTab chatTab : ChatTabs.INSTANCE.getTabs()) { + buttonList.add(chatTab.getButton()); + } + } + } + + @Inject(method = "updateScreen", at = @At("HEAD")) + private void updateScreen(CallbackInfo ci) { + if (ChattingConfig.INSTANCE.getChatSearch() && searchButton.isEnabled()) { + searchButton.getInputField().updateCursorCounter(); + } + } + + @Inject(method = "keyTyped", at = @At("HEAD"), cancellable = true) + private void keyTyped(char typedChar, int keyCode, CallbackInfo ci) { + if (ChattingConfig.INSTANCE.getChatSearch() && searchButton.isEnabled()) { + ci.cancel(); + if (keyCode == 1) { + searchButton.onMousePress(); + return; + } + searchButton.getInputField().textboxKeyTyped(typedChar, keyCode); + ChatSearchingManager.setPrevText(searchButton.getInputField().getText()); + } + } + + @Inject(method = "drawScreen", at = @At("HEAD")) + private void onDrawScreen(int mouseX, int mouseY, float partialTicks, CallbackInfo ci) { + GuiNewChatHook hook = ((GuiNewChatHook) Minecraft.getMinecraft().ingameGUI.getChatGUI()); + float f = mc.ingameGUI.getChatGUI().getChatScale(); + int x = MathHelper.floor_float((float) mouseX / f); + if (hook.shouldCopy() && (hook.getRight() + ModCompatHooks.getXOffset()) <= x && (hook.getRight() + ModCompatHooks.getXOffset()) + 11 > x) { + GuiUtils.drawHoveringText(COPY_TOOLTIP, mouseX, mouseY, width, height, -1, fontRendererObj); + GlStateManager.disableLighting(); + } + } + + @Inject(method = "mouseClicked", at = @At("HEAD")) + private void mouseClicked(int mouseX, int mouseY, int mouseButton, CallbackInfo ci) { + GuiNewChatHook hook = ((GuiNewChatHook) Minecraft.getMinecraft().ingameGUI.getChatGUI()); + float f = mc.ingameGUI.getChatGUI().getChatScale(); + int x = MathHelper.floor_float((float) mouseX / f); + if (hook.shouldCopy() && (hook.getRight() + ModCompatHooks.getXOffset()) <= x && (hook.getRight() + ModCompatHooks.getXOffset()) + 11 > x) { + Transferable message = hook.getChattingChatComponent(Mouse.getY()); + if (message == null) return; + try { + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(message, null); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + @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()) { + if (original.startsWith("/")) { + return "/" + ChatShortcuts.INSTANCE.handleSentCommand(StringUtils.substringAfter(original, "/")); + } + } + return original; + } +} diff --git a/src/main/java/cc/woverflow/chatting/mixin/GuiNewChatAccessor.java b/src/main/java/cc/woverflow/chatting/mixin/GuiNewChatAccessor.java new file mode 100644 index 0000000..8b81a50 --- /dev/null +++ b/src/main/java/cc/woverflow/chatting/mixin/GuiNewChatAccessor.java @@ -0,0 +1,17 @@ +package cc.woverflow.chatting.mixin; + +import net.minecraft.client.gui.ChatLine; +import net.minecraft.client.gui.GuiNewChat; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.List; + +@Mixin(GuiNewChat.class) +public interface GuiNewChatAccessor { + @Accessor + List getDrawnChatLines(); + + @Accessor + int getScrollPos(); +} diff --git a/src/main/java/cc/woverflow/chatting/mixin/GuiNewChatMapMixin.java b/src/main/java/cc/woverflow/chatting/mixin/GuiNewChatMapMixin.java new file mode 100644 index 0000000..5b38bda --- /dev/null +++ b/src/main/java/cc/woverflow/chatting/mixin/GuiNewChatMapMixin.java @@ -0,0 +1,78 @@ +package cc.woverflow.chatting.mixin; + +import cc.woverflow.chatting.hook.GuiNewChatHook; +import net.minecraft.client.gui.ChatLine; +import net.minecraft.client.gui.GuiNewChat; +import net.minecraft.util.IChatComponent; +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.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Mixin(value = GuiNewChat.class, priority = Integer.MIN_VALUE) +public abstract class GuiNewChatMapMixin implements GuiNewChatHook { + + @Unique private final Map drawnToFull = new HashMap<>(); + @Unique private final List tempDrawnLines = new ArrayList<>(); + @Unique private ChatLine lastTempLine = null; + + @Shadow @Final private List drawnChatLines; + @Shadow @Final private List chatLines; + + @Inject(method = "setChatLine", at = @At("HEAD")) + private void handleSetChatLine(IChatComponent chatComponent, int chatLineId, int updateCounter, boolean displayOnly, CallbackInfo ci) { + tempDrawnLines.clear(); + } + + @Inject(method = "setChatLine", at = @At(value = "INVOKE", target = "Ljava/util/List;add(ILjava/lang/Object;)V", ordinal = 0, shift = At.Shift.AFTER, remap = false)) + private void handleDrawnLineAdded(IChatComponent chatComponent, int chatLineId, int updateCounter, boolean displayOnly, CallbackInfo ci) { + if (!displayOnly) tempDrawnLines.add(drawnChatLines.get(0)); + else if (lastTempLine != null) { + drawnToFull.put(drawnChatLines.get(0), lastTempLine); + } + } + + @Inject(method = "setChatLine", at = @At(value = "INVOKE", target = "Ljava/util/List;remove(I)Ljava/lang/Object;", ordinal = 0, shift = At.Shift.BEFORE, remap = false)) + private void handleDrawnLineRemoved(IChatComponent chatComponent, int chatLineId, int updateCounter, boolean displayOnly, CallbackInfo ci) { + drawnToFull.remove(drawnChatLines.get(drawnChatLines.size() - 1)); + } + + @Inject(method = "setChatLine", at = @At("RETURN")) + private void handleLineAdded(IChatComponent chatComponent, int chatLineId, int updateCounter, boolean displayOnly, CallbackInfo ci) { + if (!displayOnly) { + ChatLine masterLine = chatLines.get(0); + for (ChatLine tempDrawnLine : tempDrawnLines) drawnToFull.put(tempDrawnLine, masterLine); + }else { + lastTempLine = null; + } + } + + @Inject(method = "refreshChat", at = @At("HEAD")) + private void handleRefreshedChat(CallbackInfo ci) { + drawnToFull.clear(); + } + + @Inject(method = "refreshChat", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiNewChat;setChatLine(Lnet/minecraft/util/IChatComponent;IIZ)V", ordinal = 0, shift = At.Shift.BEFORE)) + private void handleLineRefresh(CallbackInfo ci, int i, ChatLine chatline) { + lastTempLine = chatline; + } + + @Inject(method = "clearChatMessages", at = @At("HEAD")) + private void handleChatCleared(CallbackInfo ci) { + drawnToFull.clear(); + } + + @Override + public ChatLine getFullMessage(ChatLine line) { + return drawnToFull.getOrDefault(line, null); + } +} diff --git a/src/main/java/cc/woverflow/chatting/mixin/GuiNewChatMixin.java b/src/main/java/cc/woverflow/chatting/mixin/GuiNewChatMixin.java new file mode 100644 index 0000000..4edafb2 --- /dev/null +++ b/src/main/java/cc/woverflow/chatting/mixin/GuiNewChatMixin.java @@ -0,0 +1,242 @@ +package cc.woverflow.chatting.mixin; + +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.GuiNewChatHook; +import cc.woverflow.chatting.utils.ModCompatHooks; +import cc.woverflow.chatting.utils.RenderHelper; +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.EnumChatFormatting; +import net.minecraft.util.IChatComponent; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import org.objectweb.asm.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.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.invoke.arg.Args; + +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.image.BufferedImage; +import java.util.List; +import java.util.Locale; + +@Mixin(value = GuiNewChat.class, priority = Integer.MIN_VALUE) +public abstract class GuiNewChatMixin extends Gui implements GuiNewChatHook { + @Unique private int chatting$right = 0; + @Unique private boolean chatting$shouldCopy; + @Unique private boolean chatting$chatCheck; + @Unique private int chatting$textOpacity; + @Shadow @Final private Minecraft mc; + @Shadow @Final private List drawnChatLines; + @SuppressWarnings({"FieldCanBeLocal", "unused"}) + private float percentComplete; + private String chatting$previousText = ""; + + @Shadow public abstract boolean getChatOpen(); + + @Shadow public abstract float getChatScale(); + + @Shadow public abstract int getLineCount(); + + @Shadow private int scrollPos; + @Shadow @Final private List chatLines; + + @Shadow public abstract void deleteChatLine(int id); + + @Unique private static final ResourceLocation COPY = new ResourceLocation("chatting: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); + if (!EnumChatFormatting.getTextWithoutFormattingCodes(chatComponent.getUnformattedText()).toLowerCase(Locale.ENGLISH).contains(chatting$previousText.toLowerCase(Locale.ENGLISH))) { + percentComplete = 1.0F; + } + } + + @Inject(method = "setChatLine", at = @At("HEAD"), cancellable = true) + private void handleSetChatLine(IChatComponent chatComponent, int chatLineId, int updateCounter, boolean displayOnly, CallbackInfo ci) { + ChatSearchingManager.getCache().invalidateAll(); + handleChatTabMessage(chatComponent, chatLineId, updateCounter, displayOnly, ci); + } + + @Inject(method = "drawChat", at = @At("HEAD")) + private void checkScreenshotKeybind(int j2, CallbackInfo ci) { + if (Chatting.INSTANCE.getKeybind().isPressed()) { + Chatting.INSTANCE.setDoTheThing(true); + } + chatting$chatCheck = false; + } + + @ModifyVariable(method = "drawChat", at = @At("HEAD"), argsOnly = true) + private int setUpdateCounterWhjenYes(int updateCounter) { + return Chatting.INSTANCE.getDoTheThing() ? 0 : updateCounter; + } + + @ModifyVariable(method = "drawChat", at = @At("STORE"), index = 2) + private int setChatLimitWhenYes(int linesToDraw) { + return Chatting.INSTANCE.getDoTheThing() + ? GuiNewChat.calculateChatboxHeight(mc.gameSettings.chatHeightFocused) / 9 + : linesToDraw; + } + + @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 + ModCompatHooks.getYOffset() - ModCompatHooks.getChatPosition(); + mouseX = MathHelper.floor_float((float)mouseX / f); + mouseY = -(MathHelper.floor_float((float)mouseY / f)); //WHY DO I NEED TO DO THIS + if (mouseX >= (left + ModCompatHooks.getXOffset()) && mouseY < bottom && mouseX < (right + 11 + ModCompatHooks.getXOffset()) && mouseY >= top) { + chatting$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 injected(GuiNewChat instance) { + return ChatSearchingManager.filterMessages(chatting$previousText, drawnChatLines); + } + + @ModifyVariable(method = "drawChat", at = @At("STORE"), ordinal = 7) + private int modifyYeah(int value) { + return chatting$textOpacity = (int) (((float) (getChatOpen() ? 255 : value)) * (mc.gameSettings.chatOpacity * 0.9F + 0.1F)); + } + + @Redirect(method = "drawChat", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/FontRenderer;drawStringWithShadow(Ljava/lang/String;FFI)I")) + private int redirectDrawString(FontRenderer instance, String text, float x, float y, int color) { + return ModCompatHooks.redirectDrawString(text, x, y, color); + } + + @Inject(method = "drawChat", at = @At("RETURN")) + private void checkStuff(int j2, CallbackInfo ci) { + if (!chatting$chatCheck && chatting$shouldCopy) { + chatting$shouldCopy = false; + } + } + + @Inject(method = "getChatHeight", at = @At("HEAD"), cancellable = true) + private void customHeight_getChatHeight(CallbackInfoReturnable cir) { + if (ChattingConfig.INSTANCE.getCustomChatHeight()) cir.setReturnValue(Chatting.INSTANCE.getChatHeight(this.getChatOpen())); + } + + @Override + public int getRight() { + return chatting$right; + } + + @Override + public boolean shouldCopy() { + return chatting$shouldCopy; + } + + private void handleChatTabMessage(IChatComponent chatComponent, int chatLineId, int updateCounter, boolean displayOnly, CallbackInfo ci) { + if (ChattingConfig.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() > (100 + ModCompatHooks.getExtendedChatLength())) + { + this.chatLines.remove(this.chatLines.size() - 1); + } + } + ci.cancel(); + } + } + } + + private void drawCopyChatBox(int right, int top) { + chatting$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); + chatting$right = right; + Gui.drawModalRectWithCustomSizedTexture(right, top, 0f, 0f, 9, 9, 9, 9); + drawRect(right - 1, top - 1, right + 10, top + 10, (((right + ModCompatHooks.getXOffset()) <= (UMouse.getScaledX() / mc.ingameGUI.getChatGUI().getChatScale()) && (right + ModCompatHooks.getXOffset()) + 11 > (UMouse.getScaledX() / mc.ingameGUI.getChatGUI().getChatScale())) ? CleanButton.Companion.getHoveredColor() : CleanButton.Companion.getColor())); + GlStateManager.disableAlpha(); + GlStateManager.disableRescaleNormal(); + GlStateManager.disableLighting(); + GlStateManager.popMatrix(); + } + + @Override + public Transferable getChattingChatComponent(int mouseY) { + if (this.getChatOpen()) { + ScaledResolution scaledresolution = new ScaledResolution(this.mc); + int i = scaledresolution.getScaleFactor(); + float f = this.getChatScale(); + int k = mouseY / i - 27 + ModCompatHooks.getYOffset() - ModCompatHooks.getChatPosition(); + 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()) { + ChatLine subLine = this.drawnChatLines.get(i1); + ChatLine fullLine = this.getFullMessage(subLine); + if (GuiScreen.isShiftKeyDown()) { + if (fullLine != null) { + BufferedImage image = Chatting.INSTANCE.screenshotLine(fullLine); + if (image != null) RenderHelper.INSTANCE.copyBufferedImageToClipboard(image); + } + return null; + } + ChatLine line = GuiScreen.isCtrlKeyDown() ? subLine : fullLine; + String message = line == null ? "Could not find chat message." : line.getChatComponent().getFormattedText(); + return new StringSelection(GuiScreen.isAltKeyDown() ? message : EnumChatFormatting.getTextWithoutFormattingCodes(message)); + } + + } + } + } + return null; + } + + @Override + public String getPrevText() { + return chatting$previousText; + } + + @Override + public void setPrevText(String prevText) { + chatting$previousText = prevText; + } + + @Override + public int getTextOpacity() { + return chatting$textOpacity; + } +} diff --git a/src/main/java/cc/woverflow/chatting/mixin/GuiUtilsMixin.java b/src/main/java/cc/woverflow/chatting/mixin/GuiUtilsMixin.java new file mode 100644 index 0000000..6489f67 --- /dev/null +++ b/src/main/java/cc/woverflow/chatting/mixin/GuiUtilsMixin.java @@ -0,0 +1,22 @@ +package cc.woverflow.chatting.mixin; + +import cc.woverflow.chatting.config.ChattingConfig; +import net.minecraftforge.fml.client.config.GuiUtils; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(value = GuiUtils.class, remap = false) +public class GuiUtilsMixin { + @Shadow + public static void drawGradientRect(int zLevel, int left, int top, int right, int bottom, int startColor, int endColor) { + } + + @Redirect(method = "drawHoveringText", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/client/config/GuiUtils;drawGradientRect(IIIIIII)V")) + private static void redirectBackground(int zLevel, int left, int top, int right, int bottom, int startColor, int endColor) { + if (!ChattingConfig.INSTANCE.getRemoveTooltipBackground()) { + drawGradientRect(zLevel, left, top, right, bottom, startColor, endColor); + } + } +} diff --git a/src/main/java/cc/woverflow/chatting/mixin/WyvtilsListenerMixin.java b/src/main/java/cc/woverflow/chatting/mixin/WyvtilsListenerMixin.java new file mode 100644 index 0000000..7b22479 --- /dev/null +++ b/src/main/java/cc/woverflow/chatting/mixin/WyvtilsListenerMixin.java @@ -0,0 +1,21 @@ +package cc.woverflow.chatting.mixin; + +import cc.woverflow.chatting.utils.RenderHelper; +import org.spongepowered.asm.mixin.Dynamic; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Coerce; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Pseudo +@Mixin(targets = "net.wyvest.wyvtils.core.listener.Listener") +public class WyvtilsListenerMixin { + + @Dynamic("Wyvtils") + @Inject(method = "onStringRendered", at = @At("HEAD"), cancellable = true, remap = false) + private void cancelStringRender(@Coerce Object a, CallbackInfo ci) { + if (RenderHelper.INSTANCE.getBypassWyvtils()) ci.cancel(); + } +} -- cgit