aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorThatGravyBoat <thatgravyboat@gmail.com>2021-12-26 01:31:48 -0330
committerGitHub <noreply@github.com>2021-12-26 12:01:48 +0700
commit8f8d8e2dbe795309b69162bc3760dd4789fc6b73 (patch)
tree27f0df9ea4b3f793e4ad23e105330db97c2125b9 /src/main
parent4927d585ec72cb045a70718423228fa2cf55d071 (diff)
downloadChatting-8f8d8e2dbe795309b69162bc3760dd4789fc6b73.tar.gz
Chatting-8f8d8e2dbe795309b69162bc3760dd4789fc6b73.tar.bz2
Chatting-8f8d8e2dbe795309b69162bc3760dd4789fc6b73.zip
improve search button display and screenshotting, and fix tooltips (#2)
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/com/raeids/stratus/hook/GuiNewChatHook.java4
-rw-r--r--src/main/java/com/raeids/stratus/mixin/GuiChatMixin.java35
-rw-r--r--src/main/java/com/raeids/stratus/mixin/GuiNewChatAccessor.java4
-rw-r--r--src/main/java/com/raeids/stratus/mixin/GuiNewChatMixin.java33
-rw-r--r--src/main/kotlin/com/raeids/stratus/Stratus.kt60
-rw-r--r--src/main/kotlin/com/raeids/stratus/config/StratusConfig.kt13
-rw-r--r--src/main/kotlin/com/raeids/stratus/hook/ChatSearching.kt8
-rw-r--r--src/main/kotlin/com/raeids/stratus/hook/CleanSearchButton.kt18
-rw-r--r--src/main/kotlin/com/raeids/stratus/hook/ScreenshotButton.kt34
-rw-r--r--src/main/kotlin/com/raeids/stratus/utils/ImageTransferable.kt22
-rw-r--r--src/main/kotlin/com/raeids/stratus/utils/RenderHelper.kt159
-rw-r--r--src/main/resources/assets/stratus/screenshot.pngbin0 -> 162 bytes
-rw-r--r--src/main/resources/assets/stratus/search.pngbin0 -> 158 bytes
13 files changed, 336 insertions, 54 deletions
diff --git a/src/main/java/com/raeids/stratus/hook/GuiNewChatHook.java b/src/main/java/com/raeids/stratus/hook/GuiNewChatHook.java
index e37995a..aaa182e 100644
--- a/src/main/java/com/raeids/stratus/hook/GuiNewChatHook.java
+++ b/src/main/java/com/raeids/stratus/hook/GuiNewChatHook.java
@@ -2,10 +2,12 @@ package com.raeids.stratus.hook;
import net.minecraft.client.gui.ChatLine;
+import java.awt.datatransfer.Transferable;
+
public interface GuiNewChatHook {
int getRight();
boolean shouldCopy();
- String getStratusChatComponent(int mouseY);
+ Transferable getStratusChatComponent(int mouseY);
default ChatLine getFullMessage(ChatLine line) {
throw new AssertionError("getFullMessage not overridden on GuiNewChat");
}
diff --git a/src/main/java/com/raeids/stratus/mixin/GuiChatMixin.java b/src/main/java/com/raeids/stratus/mixin/GuiChatMixin.java
index 4b8142c..37fb0f3 100644
--- a/src/main/java/com/raeids/stratus/mixin/GuiChatMixin.java
+++ b/src/main/java/com/raeids/stratus/mixin/GuiChatMixin.java
@@ -1,27 +1,43 @@
package com.raeids.stratus.mixin;
+import com.google.common.collect.Lists;
import com.raeids.stratus.Stratus;
import com.raeids.stratus.config.StratusConfig;
import com.raeids.stratus.hook.*;
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.StringSelection;
+import java.awt.datatransfer.Transferable;
+import java.util.List;
@Mixin(GuiChat.class)
public abstract class GuiChatMixin extends GuiScreen {
+ @Unique
+ private static final List<String> 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 CleanSearchButton searchButton;
+ private ScreenshotButton screenshotButton;
@Inject(method = "initGui", at = @At("TAIL"))
private void init(CallbackInfo ci) {
@@ -29,6 +45,8 @@ public abstract class GuiChatMixin extends GuiScreen {
searchButton = new CleanSearchButton();
buttonList.add(searchButton);
}
+ screenshotButton = new ScreenshotButton();
+ buttonList.add(screenshotButton);
if (StratusConfig.INSTANCE.getChatTabs()) {
for (ChatTab chatTab : ChatTabs.INSTANCE.getTabs()) {
buttonList.add(chatTab.getButton());
@@ -56,14 +74,27 @@ public abstract class GuiChatMixin extends GuiScreen {
}
}
+ @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() + (Stratus.INSTANCE.isBetterChat() ? ModCompatHooks.getXOffset() : 0)) <= x && (hook.getRight() + (Stratus.INSTANCE.isBetterChat() ? ModCompatHooks.getXOffset() : 0)) + 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() + (Stratus.INSTANCE.isBetterChat() ? ModCompatHooks.getXOffset() : 0)) <= x && (hook.getRight() + (Stratus.INSTANCE.isBetterChat() ? ModCompatHooks.getXOffset() : 0)) + 9 > x) {
+ Transferable message = hook.getStratusChatComponent(Mouse.getY());
+ if (message == null) return;
try {
- Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(hook.getStratusChatComponent(Mouse.getY())), null);
+ Toolkit.getDefaultToolkit().getSystemClipboard().setContents(message, null);
} catch (Exception e) {
e.printStackTrace();
}
diff --git a/src/main/java/com/raeids/stratus/mixin/GuiNewChatAccessor.java b/src/main/java/com/raeids/stratus/mixin/GuiNewChatAccessor.java
index cc697d0..9b68d48 100644
--- a/src/main/java/com/raeids/stratus/mixin/GuiNewChatAccessor.java
+++ b/src/main/java/com/raeids/stratus/mixin/GuiNewChatAccessor.java
@@ -1,7 +1,6 @@
package com.raeids.stratus.mixin;
import net.minecraft.client.gui.ChatLine;
-import net.minecraft.client.gui.GuiChat;
import net.minecraft.client.gui.GuiNewChat;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@@ -12,4 +11,7 @@ import java.util.List;
public interface GuiNewChatAccessor {
@Accessor
List<ChatLine> getDrawnChatLines();
+
+ @Accessor
+ int getScrollPos();
}
diff --git a/src/main/java/com/raeids/stratus/mixin/GuiNewChatMixin.java b/src/main/java/com/raeids/stratus/mixin/GuiNewChatMixin.java
index 8d2602b..09c464b 100644
--- a/src/main/java/com/raeids/stratus/mixin/GuiNewChatMixin.java
+++ b/src/main/java/com/raeids/stratus/mixin/GuiNewChatMixin.java
@@ -1,12 +1,12 @@
package com.raeids.stratus.mixin;
-import com.google.common.collect.Lists;
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 com.raeids.stratus.utils.RenderHelper;
import gg.essential.universal.UMouse;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.*;
@@ -15,7 +15,6 @@ import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
-import net.minecraftforge.fml.client.config.GuiUtils;
import org.spongepowered.asm.lib.Opcodes;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
@@ -25,6 +24,9 @@ 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.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.Transferable;
+import java.awt.image.BufferedImage;
import java.util.List;
@Mixin(value = GuiNewChat.class, priority = Integer.MIN_VALUE)
@@ -51,14 +53,6 @@ public abstract class GuiNewChatMixin extends Gui implements GuiNewChatHook {
@Unique private static final ResourceLocation COPY = new ResourceLocation("stratus:copy.png");
- @Unique private static final List<String> COPY_TOOLTIP = Lists.newArrayList(
- "\u00A73\u00A7l\u00A7nCopy To Clipboard",
- "\u00A7lNORMAL CLICK\u00A7r - Full Message",
- "\u00A7lCTRL CLICK\u00A7r - Single Line",
- "",
- "\u00A73\u00A7l\u00A7nModifiers",
- "\u00A7lALT\u00A7r - Formatting Codes");
-
@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);
@@ -104,7 +98,7 @@ public abstract class GuiNewChatMixin extends Gui implements GuiNewChatHook {
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, mouseX, mouseY);
+ drawCopyChatBox(right, top);
}
}
}
@@ -150,7 +144,7 @@ public abstract class GuiNewChatMixin extends Gui implements GuiNewChatHook {
}
}
- private void drawCopyChatBox(int right, int top, int mouseX, int mouseY) {
+ private void drawCopyChatBox(int right, int top) {
stratus$chatCheck = true;
GlStateManager.enableRescaleNormal();
GlStateManager.enableBlend();
@@ -166,7 +160,6 @@ public abstract class GuiNewChatMixin extends Gui implements GuiNewChatHook {
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
stratus$right = right;
Gui.drawModalRectWithCustomSizedTexture(right, top, 0f, 0f, 9, 9, 9, 9);
- if (mouseX >= right) GuiUtils.drawHoveringText(COPY_TOOLTIP, mouseX, mouseY, mc.currentScreen.width, mc.currentScreen.height, 300, mc.fontRendererObj);
GlStateManager.disableAlpha();
GlStateManager.disableRescaleNormal();
GlStateManager.disableLighting();
@@ -174,7 +167,7 @@ public abstract class GuiNewChatMixin extends Gui implements GuiNewChatHook {
}
@Override
- public String getStratusChatComponent(int mouseY) {
+ public Transferable getStratusChatComponent(int mouseY) {
if (this.getChatOpen()) {
ScaledResolution scaledresolution = new ScaledResolution(this.mc);
int i = scaledresolution.getScaleFactor();
@@ -190,9 +183,17 @@ public abstract class GuiNewChatMixin extends Gui implements GuiNewChatHook {
if (i1 >= 0 && i1 < this.drawnChatLines.size()) {
ChatLine subLine = this.drawnChatLines.get(i1);
- ChatLine line = GuiScreen.isCtrlKeyDown() ? subLine : this.getFullMessage(subLine);
+ ChatLine fullLine = this.getFullMessage(subLine);
+ if (GuiScreen.isShiftKeyDown()) {
+ if (fullLine != null) {
+ BufferedImage image = Stratus.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 GuiScreen.isAltKeyDown() ? message : EnumChatFormatting.getTextWithoutFormattingCodes(message);
+ return new StringSelection(GuiScreen.isAltKeyDown() ? message : EnumChatFormatting.getTextWithoutFormattingCodes(message));
}
}
diff --git a/src/main/kotlin/com/raeids/stratus/Stratus.kt b/src/main/kotlin/com/raeids/stratus/Stratus.kt
index d771915..7588749 100644
--- a/src/main/kotlin/com/raeids/stratus/Stratus.kt
+++ b/src/main/kotlin/com/raeids/stratus/Stratus.kt
@@ -4,17 +4,18 @@ import com.raeids.stratus.command.StratusCommand
import com.raeids.stratus.config.StratusConfig
import com.raeids.stratus.hook.ChatShortcuts
import com.raeids.stratus.hook.ChatTabs
+import com.raeids.stratus.hook.GuiNewChatHook
+import com.raeids.stratus.hook.filterMessages
import com.raeids.stratus.mixin.GuiNewChatAccessor
import com.raeids.stratus.updater.Updater
import com.raeids.stratus.utils.RenderHelper
import gg.essential.api.EssentialAPI
import gg.essential.universal.UDesktop
import net.minecraft.client.Minecraft
-import net.minecraft.client.gui.FontRenderer
-import net.minecraft.client.gui.GuiChat
-import net.minecraft.client.renderer.GlStateManager
+import net.minecraft.client.gui.*
import net.minecraft.client.settings.KeyBinding
import net.minecraft.client.shader.Framebuffer
+import net.minecraft.util.MathHelper
import net.minecraftforge.common.MinecraftForge.EVENT_BUS
import net.minecraftforge.fml.client.registry.ClientRegistry
import net.minecraftforge.fml.common.Loader
@@ -25,6 +26,7 @@ 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.image.BufferedImage
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
@@ -81,38 +83,51 @@ object Stratus {
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) {
- screenshot()
+ screenshotChat()
doTheThing = false
}
}
}
- private fun screenshot() {
+ fun screenshotLine(line: ChatLine): BufferedImage? {
val hud = Minecraft.getMinecraft().ingameGUI
val chat = hud.chatGUI
+ val i = MathHelper.floor_float(chat.chatWidth/chat.chatScale)
+ return screenshot(GuiUtilRenderComponents.splitText(line.chatComponent, i, Minecraft.getMinecraft().fontRendererObj, false, false).map { it.formattedText }.reversed(), chat.chatWidth)
+ }
+
+ private fun screenshotChat() {
+ screenshotChat(0)
+ }
+
+ fun screenshotChat(scrollPos: Int) {
+ val hud = Minecraft.getMinecraft().ingameGUI
+ val chat = hud.chatGUI
+ val chatLines = ArrayList<String>()
+ filterMessages((chat as GuiNewChatHook).prevText, (chat as GuiNewChatAccessor).drawnChatLines)?.let { drawnLines ->
+ for (i in scrollPos until drawnLines.size.coerceAtMost(scrollPos+GuiNewChat.calculateChatboxHeight(Minecraft.getMinecraft().gameSettings.chatHeightFocused)/9)){
+ chatLines.add(drawnLines[i].chatComponent.formattedText)
+ }
- /* Render chat fully. */
- var w = chat.chatWidth
- var h = chat.chatHeight
- if ((chat as GuiNewChatAccessor).drawnChatLines.size < 20) {
- h = (chat as GuiNewChatAccessor).drawnChatLines
- .size * Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT
+ screenshot(chatLines, chat.chatWidth)?.let {
+ RenderHelper.copyBufferedImageToClipboard(it)
+ }
}
- if (w <= 0 || h <= 0 || (chat as GuiNewChatAccessor).drawnChatLines.isEmpty()) {
+ }
+
+ private fun screenshot(messages: List<String>, width: Int): BufferedImage? {
+ if (messages.isEmpty()) {
EssentialAPI.getNotifications().push("Stratus", "Chat window is empty.")
- return
+ return null
}
- val chatLines: MutableList<String> = ArrayList()
+
val fr: FontRenderer = Minecraft.getMinecraft().fontRendererObj
- for (chatLine in (chat as GuiNewChatAccessor).drawnChatLines) chatLines.add(chatLine.chatComponent.formattedText)
- if (chatLines.isNotEmpty()) {
- w = fr.getStringWidth(chatLines.stream().max(Comparator.comparingInt { obj: String -> obj.length }).get())
- }
- val fb: Framebuffer = RenderHelper.createBindFramebuffer(w, h)
- GlStateManager.translate(-2f, (160 - (180 - h)).toFloat(), 0f)
- chat.drawChat(hud.updateCounter)
+ val fb: Framebuffer = RenderHelper.createBindFramebuffer(width, messages.size*9)
val file = File(Minecraft.getMinecraft().mcDataDir, "screenshots/chat/" + fileFormatter.format(Date()))
- RenderHelper.screenshotFramebuffer(fb, file)
+
+ for (i in messages.indices) fr.drawStringWithShadow(messages[i], 0f, (messages.size-1-i)*9f, 0xffffff)
+
+ val image = RenderHelper.screenshotFramebuffer(fb, file)
Minecraft.getMinecraft().entityRenderer.setupOverlayRendering()
Minecraft.getMinecraft().framebuffer.bindFramebuffer(true)
EssentialAPI.getNotifications()
@@ -121,5 +136,6 @@ object Stratus {
EssentialAPI.getNotifications().push("Stratus", "Could not browse!")
}
}
+ return image
}
}
diff --git a/src/main/kotlin/com/raeids/stratus/config/StratusConfig.kt b/src/main/kotlin/com/raeids/stratus/config/StratusConfig.kt
index e9d2401..ecc0c09 100644
--- a/src/main/kotlin/com/raeids/stratus/config/StratusConfig.kt
+++ b/src/main/kotlin/com/raeids/stratus/config/StratusConfig.kt
@@ -24,6 +24,19 @@ object StratusConfig : Vigilant(File(Stratus.modDir, "${Stratus.ID}.toml"), Stra
var chatSearch = true
@Property(
+ type = PropertyType.SELECTOR,
+ name = "Screenshot Mode",
+ description = "The mode in which screenshotting will work.",
+ category = "Screenshotting",
+ options = [
+ "Save To System",
+ "Add To Clipboard",
+ "Both"
+ ]
+ )
+ var copyMode = 0
+
+ @Property(
type = PropertyType.SWITCH,
name = "Chat Tabs",
description = "Add chat tabs.",
diff --git a/src/main/kotlin/com/raeids/stratus/hook/ChatSearching.kt b/src/main/kotlin/com/raeids/stratus/hook/ChatSearching.kt
index 57cfc93..6dd4904 100644
--- a/src/main/kotlin/com/raeids/stratus/hook/ChatSearching.kt
+++ b/src/main/kotlin/com/raeids/stratus/hook/ChatSearching.kt
@@ -22,14 +22,14 @@ private var POOL: ThreadPoolExecutor = ThreadPoolExecutor(
)
}
-val cache: Cache<String, List<ChatLine?>> = Caffeine.newBuilder().executor(POOL).maximumSize(5000).build()
+val cache: Cache<String, List<ChatLine>> = Caffeine.newBuilder().executor(POOL).maximumSize(5000).build()
-fun filterMessages(text: String, list: List<ChatLine?>?): List<ChatLine?>? {
- if (list.isNullOrEmpty() || text.isBlank()) return list
+fun filterMessages(text: String, list: List<ChatLine>): List<ChatLine>? {
+ if (text.isBlank()) return list
val cached = cache.getIfPresent(text)
return cached ?: run {
cache.put(text, list.filter {
- it != null && UTextComponent.stripFormatting(it.chatComponent.unformattedText).lowercase()
+ UTextComponent.stripFormatting(it.chatComponent.unformattedText).lowercase()
.contains(text.lowercase())
})
cache.getIfPresent(text)
diff --git a/src/main/kotlin/com/raeids/stratus/hook/CleanSearchButton.kt b/src/main/kotlin/com/raeids/stratus/hook/CleanSearchButton.kt
index 4b7ba5a..7a68c75 100644
--- a/src/main/kotlin/com/raeids/stratus/hook/CleanSearchButton.kt
+++ b/src/main/kotlin/com/raeids/stratus/hook/CleanSearchButton.kt
@@ -1,10 +1,14 @@
package com.raeids.stratus.hook
+import com.raeids.stratus.Stratus
import gg.essential.universal.UResolution
import net.minecraft.client.Minecraft
+import net.minecraft.client.gui.Gui
import net.minecraft.client.gui.GuiTextField
+import net.minecraft.client.renderer.GlStateManager
+import net.minecraft.util.ResourceLocation
-class CleanSearchButton: CleanButton(3993935, {UResolution.scaledWidth - 42}, {UResolution.scaledHeight - 27}, 40, 12, "Search") {
+class CleanSearchButton: CleanButton(3993935, {UResolution.scaledWidth - 14}, {UResolution.scaledHeight - 27}, 12, 12, "") {
val inputField = SearchTextField()
private var chatBox = false
@@ -13,7 +17,6 @@ class CleanSearchButton: CleanButton(3993935, {UResolution.scaledWidth - 42}, {U
}
override fun onMousePress() {
- println("hi")
chatBox = !chatBox
inputField.setEnabled(chatBox)
inputField.isFocused = chatBox
@@ -24,6 +27,17 @@ class CleanSearchButton: CleanButton(3993935, {UResolution.scaledWidth - 42}, {U
override fun drawButton(mc: Minecraft, mouseX: Int, mouseY: Int) {
inputField.drawTextBox()
super.drawButton(mc, mouseX, mouseY)
+ if (visible) {
+ mc.textureManager.bindTexture(ResourceLocation(Stratus.ID, "search.png"))
+ if (isEnabled()) {
+ GlStateManager.color(224f/255f, 224f/255f, 224f/255f)
+ } else if (mouseX >= xPosition && mouseX <= xPosition + 10 && mouseY >= yPosition && mouseY <= yPosition + 10) {
+ GlStateManager.color(1f, 1f, 160f/255f)
+ } else {
+ GlStateManager.color(1f, 1f, 1f)
+ }
+ Gui.drawModalRectWithCustomSizedTexture(xPosition+1, yPosition+1, 0f, 0f, 10, 10, 10f, 10f)
+ }
}
inner class SearchTextField: GuiTextField(69420, Minecraft.getMinecraft().fontRendererObj, UResolution.scaledWidth * 4 / 5 - 60, UResolution.scaledHeight - 27, UResolution.scaledWidth / 5, 12) {
diff --git a/src/main/kotlin/com/raeids/stratus/hook/ScreenshotButton.kt b/src/main/kotlin/com/raeids/stratus/hook/ScreenshotButton.kt
new file mode 100644
index 0000000..70c64c2
--- /dev/null
+++ b/src/main/kotlin/com/raeids/stratus/hook/ScreenshotButton.kt
@@ -0,0 +1,34 @@
+package com.raeids.stratus.hook
+
+import com.raeids.stratus.Stratus
+import com.raeids.stratus.mixin.GuiNewChatAccessor
+import gg.essential.api.utils.GuiUtil
+import gg.essential.universal.UResolution
+import net.minecraft.client.Minecraft
+import net.minecraft.client.gui.Gui
+import net.minecraft.client.gui.GuiChat
+import net.minecraft.client.renderer.GlStateManager
+import net.minecraft.util.ResourceLocation
+
+class ScreenshotButton: CleanButton(448318, { UResolution.scaledWidth - 28}, { UResolution.scaledHeight - 27}, 12, 12, "") {
+
+ override fun onMousePress() {
+ val chat = Minecraft.getMinecraft().ingameGUI.chatGUI
+ if (GuiUtil.getOpenedScreen() is GuiChat) {
+ Stratus.screenshotChat((chat as GuiNewChatAccessor).scrollPos)
+ }
+ }
+
+ override fun drawButton(mc: Minecraft, mouseX: Int, mouseY: Int) {
+ super.drawButton(mc, mouseX, mouseY)
+ if (visible) {
+ if (hovered) {
+ GlStateManager.color(1f, 1f, 160f / 255f)
+ } else {
+ GlStateManager.color(1f, 1f, 1f)
+ }
+ mc.textureManager.bindTexture(ResourceLocation(Stratus.ID, "screenshot.png"))
+ Gui.drawModalRectWithCustomSizedTexture(xPosition + 1, yPosition + 1, 0f, 0f, 10, 10, 10f, 10f)
+ }
+ }
+} \ No newline at end of file
diff --git a/src/main/kotlin/com/raeids/stratus/utils/ImageTransferable.kt b/src/main/kotlin/com/raeids/stratus/utils/ImageTransferable.kt
new file mode 100644
index 0000000..81571a5
--- /dev/null
+++ b/src/main/kotlin/com/raeids/stratus/utils/ImageTransferable.kt
@@ -0,0 +1,22 @@
+package com.raeids.stratus.utils
+
+import java.awt.Image
+import java.awt.datatransfer.DataFlavor
+import java.awt.datatransfer.Transferable
+import java.awt.datatransfer.UnsupportedFlavorException
+
+class ImageTransferable(private val image: Image): Transferable {
+
+ override fun getTransferDataFlavors(): Array<DataFlavor> {
+ return arrayOf(DataFlavor.imageFlavor)
+ }
+
+ override fun isDataFlavorSupported(flavor: DataFlavor?): Boolean {
+ return DataFlavor.imageFlavor.equals(flavor)
+ }
+
+ override fun getTransferData(flavor: DataFlavor?): Any {
+ if (isDataFlavorSupported(flavor)) return image
+ throw UnsupportedFlavorException(flavor)
+ }
+} \ No newline at end of file
diff --git a/src/main/kotlin/com/raeids/stratus/utils/RenderHelper.kt b/src/main/kotlin/com/raeids/stratus/utils/RenderHelper.kt
index d2aac4d..664f5de 100644
--- a/src/main/kotlin/com/raeids/stratus/utils/RenderHelper.kt
+++ b/src/main/kotlin/com/raeids/stratus/utils/RenderHelper.kt
@@ -1,21 +1,165 @@
package com.raeids.stratus.utils
+import com.raeids.stratus.config.StratusConfig
import net.minecraft.client.renderer.GlStateManager
import net.minecraft.client.renderer.texture.TextureUtil
import net.minecraft.client.shader.Framebuffer
+import org.apache.commons.lang3.SystemUtils
import org.lwjgl.BufferUtils
import org.lwjgl.opengl.GL11
import org.lwjgl.opengl.GL12
+import sun.awt.datatransfer.DataTransferer
+import sun.awt.datatransfer.SunClipboard
+import java.awt.Toolkit
import java.awt.image.BufferedImage
import java.io.File
+import java.lang.reflect.Field
+import java.lang.reflect.Method
+import java.nio.ByteBuffer
+import java.nio.ByteOrder
import javax.imageio.ImageIO
object RenderHelper {
/**
* Taken from https://github.com/Moulberry/HyChat
+ * Modified so if not on Windows just in case it will switch it to RGB and remove the transparent background.
*/
- fun screenshotFramebuffer(framebuffer: Framebuffer, file: File) {
+ fun copyBufferedImageToClipboard(bufferedImage: BufferedImage) {
+ if (SystemUtils.IS_OS_WINDOWS) {
+ try {
+ val width = bufferedImage.width
+ val height = bufferedImage.height
+ val hdrSize = 0x28
+ val buffer: ByteBuffer = ByteBuffer.allocate(hdrSize + width * height * 4)
+ buffer.order(ByteOrder.LITTLE_ENDIAN)
+ //Header size
+ buffer.putInt(hdrSize)
+ //Width
+ buffer.putInt(width)
+ //Int32 biHeight;
+ buffer.putInt(height)
+ //Int16 biPlanes;
+ buffer.put(1.toByte())
+ buffer.put(0.toByte())
+ //Int16 biBitCount;
+ buffer.put(32.toByte())
+ buffer.put(0.toByte())
+ //Compression
+ buffer.putInt(0)
+ //Int32 biSizeImage;
+ buffer.putInt(width * height * 4)
+ buffer.putInt(0)
+ buffer.putInt(0)
+ buffer.putInt(0)
+ buffer.putInt(0)
+
+ //Image data
+ for (y in 0 until height) {
+ for (x in 0 until width) {
+ val argb: Int = bufferedImage.getRGB(x, height - y - 1)
+ if (argb shr 24 and 0xFF == 0) {
+ buffer.putInt(0x00000000)
+ } else {
+ buffer.putInt(argb)
+ }
+ }
+ }
+ buffer.flip()
+ val hdrSizev5 = 0x7C
+ val bufferv5: ByteBuffer = ByteBuffer.allocate(hdrSizev5 + width * height * 4)
+ bufferv5.order(ByteOrder.LITTLE_ENDIAN)
+ //Header size
+ bufferv5.putInt(hdrSizev5)
+ //Width
+ bufferv5.putInt(width)
+ //Int32 biHeight;
+ bufferv5.putInt(height)
+ //Int16 biPlanes;
+ bufferv5.put(1.toByte())
+ bufferv5.put(0.toByte())
+ //Int16 biBitCount;
+ bufferv5.put(32.toByte())
+ bufferv5.put(0.toByte())
+ //Compression
+ bufferv5.putInt(0)
+ //Int32 biSizeImage;
+ bufferv5.putInt(width * height * 4)
+ bufferv5.putInt(0)
+ bufferv5.putInt(0)
+ bufferv5.putInt(0)
+ bufferv5.putInt(0)
+ bufferv5.order(ByteOrder.BIG_ENDIAN)
+ bufferv5.putInt(-0x1000000)
+ bufferv5.putInt(0x00FF0000)
+ bufferv5.putInt(0x0000FF00)
+ bufferv5.putInt(0x000000FF)
+ bufferv5.order(ByteOrder.LITTLE_ENDIAN)
+
+ //BGRs
+ bufferv5.put(0x42.toByte())
+ bufferv5.put(0x47.toByte())
+ bufferv5.put(0x52.toByte())
+ bufferv5.put(0x73.toByte())
+ for (i in bufferv5.position() until hdrSizev5) {
+ bufferv5.put(0.toByte())
+ }
+
+ //Image data
+ for (y in 0 until height) {
+ for (x in 0 until width) {
+ val argb: Int = bufferedImage.getRGB(x, height - y - 1)
+ val a = argb shr 24 and 0xFF
+ var r = argb shr 16 and 0xFF
+ var g = argb shr 8 and 0xFF
+ var b = argb and 0xFF
+ r = r * a / 0xFF
+ g = g * a / 0xFF
+ b = b * a / 0xFF
+ bufferv5.putInt(a shl 24 or (r shl 16) or (g shl 8) or b)
+ }
+ }
+ bufferv5.flip()
+ val clip = Toolkit.getDefaultToolkit().systemClipboard
+ val dt = DataTransferer.getInstance()
+ val f: Field = dt.javaClass.getDeclaredField("CF_DIB")
+ f.isAccessible = true
+ val format: Long = f.getLong(null)
+ val openClipboard: Method = clip.javaClass.getDeclaredMethod("openClipboard", SunClipboard::class.java)
+ openClipboard.isAccessible = true
+ openClipboard.invoke(clip, clip)
+ val publishClipboardData: Method = clip.javaClass.getDeclaredMethod(
+ "publishClipboardData",
+ Long::class.javaPrimitiveType,
+ ByteArray::class.java
+ )
+ publishClipboardData.isAccessible = true
+ val arr: ByteArray = buffer.array()
+ publishClipboardData.invoke(clip, format, arr)
+ val closeClipboard: Method = clip.javaClass.getDeclaredMethod("closeClipboard")
+ closeClipboard.isAccessible = true
+ closeClipboard.invoke(clip)
+ return
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ val pixels: IntArray = bufferedImage.getRGB(0, 0, bufferedImage.width, bufferedImage.height, null, 0, bufferedImage.width)
+ val newImage = BufferedImage(bufferedImage.width, bufferedImage.height, BufferedImage.TYPE_INT_RGB)
+ newImage.setRGB(0, 0, newImage.width, newImage.height, pixels, 0, newImage.width)
+
+ try {
+ Toolkit.getDefaultToolkit().systemClipboard.setContents(ImageTransferable(bufferedImage), null)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+
+ /**
+ * Taken from https://github.com/Moulberry/HyChat
+ */
+ fun screenshotFramebuffer(framebuffer: Framebuffer, file: File): BufferedImage {
val w = framebuffer.framebufferWidth
val h = framebuffer.framebufferHeight
val i = w * h
@@ -34,12 +178,15 @@ object RenderHelper {
bufferedimage.setRGB(l, k - j, pixelValues[k * framebuffer.framebufferTextureWidth + l])
}
}
- try {
- file.parentFile.mkdirs()
- ImageIO.write(bufferedimage, "png", file)
- } catch (e: Exception) {
- e.printStackTrace()
+ if (StratusConfig.copyMode != 1) {
+ try {
+ file.parentFile.mkdirs()
+ ImageIO.write(bufferedimage, "png", file)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
}
+ return bufferedimage
}
/**
diff --git a/src/main/resources/assets/stratus/screenshot.png b/src/main/resources/assets/stratus/screenshot.png
new file mode 100644
index 0000000..8b6cc48
--- /dev/null
+++ b/src/main/resources/assets/stratus/screenshot.png
Binary files differ
diff --git a/src/main/resources/assets/stratus/search.png b/src/main/resources/assets/stratus/search.png
new file mode 100644
index 0000000..a5be877
--- /dev/null
+++ b/src/main/resources/assets/stratus/search.png
Binary files differ