aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWyvest <45589059+Wyvest@users.noreply.github.com>2022-01-16 16:27:15 +0700
committerWyvest <45589059+Wyvest@users.noreply.github.com>2022-01-16 16:27:15 +0700
commit4e587bc97c3aee3c3458a6ac60a43122f7c7971e (patch)
treeab9df90c3b5763d60ea702fd13f15461bbb56421
parent42f8aa3024772e708143d49355130ef2a7999243 (diff)
downloadChatting-4e587bc97c3aee3c3458a6ac60a43122f7c7971e.tar.gz
Chatting-4e587bc97c3aee3c3458a6ac60a43122f7c7971e.tar.bz2
Chatting-4e587bc97c3aee3c3458a6ac60a43122f7c7971e.zip
new: remove scroll bar
new: chat background color fix: fix chat tab buttons not having bordered text
-rw-r--r--src/main/java/cc/woverflow/chatting/mixin/GuiNewChatMixin.java26
-rw-r--r--src/main/java/cc/woverflow/chatting/mixin/WyvtilsListenerMixin.java4
-rw-r--r--src/main/kotlin/cc/woverflow/chatting/Chatting.kt12
-rw-r--r--src/main/kotlin/cc/woverflow/chatting/config/ChattingConfig.kt18
-rw-r--r--src/main/kotlin/cc/woverflow/chatting/gui/components/CleanButton.kt12
-rw-r--r--src/main/kotlin/cc/woverflow/chatting/gui/components/RenderType.kt7
-rw-r--r--src/main/kotlin/cc/woverflow/chatting/gui/components/ScreenshotButton.kt3
-rw-r--r--src/main/kotlin/cc/woverflow/chatting/gui/components/SearchButton.kt3
-rw-r--r--src/main/kotlin/cc/woverflow/chatting/gui/components/TabButton.kt3
-rw-r--r--src/main/kotlin/cc/woverflow/chatting/utils/ModCompatHooks.kt3
-rw-r--r--src/main/kotlin/cc/woverflow/chatting/utils/RenderHelper.kt248
-rw-r--r--src/main/kotlin/cc/woverflow/chatting/utils/renderutils.kt244
-rw-r--r--src/main/resources/mixins.chatting.json1
13 files changed, 318 insertions, 266 deletions
diff --git a/src/main/java/cc/woverflow/chatting/mixin/GuiNewChatMixin.java b/src/main/java/cc/woverflow/chatting/mixin/GuiNewChatMixin.java
index 677ba4c..d6bc8f5 100644
--- a/src/main/java/cc/woverflow/chatting/mixin/GuiNewChatMixin.java
+++ b/src/main/java/cc/woverflow/chatting/mixin/GuiNewChatMixin.java
@@ -7,7 +7,7 @@ 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 cc.woverflow.chatting.utils.RenderUtils;
import gg.essential.universal.UMouse;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.*;
@@ -125,6 +125,28 @@ public abstract class GuiNewChatMixin extends Gui implements GuiNewChatHook {
return ModCompatHooks.redirectDrawString(text, x, y, color);
}
+ @ModifyArg(method = "drawChat", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiNewChat;drawRect(IIIII)V", ordinal = 0), index = 4)
+ private int changeChatBackgroundColor(int color) {
+ return (((color >> 24) & 0xFF) << 24) |
+ ((ChattingConfig.INSTANCE.getChatBackgroundColor().getRed() & 0xFF) << 16) |
+ ((ChattingConfig.INSTANCE.getChatBackgroundColor().getGreen() & 0xFF) << 8) |
+ ((ChattingConfig.INSTANCE.getChatBackgroundColor().getBlue() & 0xFF));
+ }
+
+ @Redirect(method = "drawChat", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiNewChat;drawRect(IIIII)V", ordinal = 1))
+ private void redirectScrollBar(int left, int top, int right, int bottom, int color) {
+ if (!ChattingConfig.INSTANCE.getRemoveScrollBar()) {
+ drawRect(left, top, right, bottom, color);
+ }
+ }
+
+ @Redirect(method = "drawChat", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiNewChat;drawRect(IIIII)V", ordinal = 2))
+ private void redirectScrollBar2(int left, int top, int right, int bottom, int color) {
+ if (!ChattingConfig.INSTANCE.getRemoveScrollBar()) {
+ drawRect(left, top, right, bottom, color);
+ }
+ }
+
@Inject(method = "drawChat", at = @At("RETURN"))
private void checkStuff(int j2, CallbackInfo ci) {
if (!chatting$chatCheck && chatting$shouldCopy) {
@@ -210,7 +232,7 @@ public abstract class GuiNewChatMixin extends Gui implements GuiNewChatHook {
if (GuiScreen.isShiftKeyDown()) {
if (fullLine != null) {
BufferedImage image = Chatting.INSTANCE.screenshotLine(fullLine);
- if (image != null) RenderHelper.INSTANCE.copyBufferedImageToClipboard(image);
+ if (image != null) RenderUtils.copyToClipboard(image);
}
return null;
}
diff --git a/src/main/java/cc/woverflow/chatting/mixin/WyvtilsListenerMixin.java b/src/main/java/cc/woverflow/chatting/mixin/WyvtilsListenerMixin.java
index 7b22479..f5b7cfb 100644
--- a/src/main/java/cc/woverflow/chatting/mixin/WyvtilsListenerMixin.java
+++ b/src/main/java/cc/woverflow/chatting/mixin/WyvtilsListenerMixin.java
@@ -1,6 +1,6 @@
package cc.woverflow.chatting.mixin;
-import cc.woverflow.chatting.utils.RenderHelper;
+import cc.woverflow.chatting.utils.RenderUtils;
import org.spongepowered.asm.mixin.Dynamic;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
@@ -16,6 +16,6 @@ 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();
+ if (RenderUtils.getBypassWyvtils()) ci.cancel();
}
}
diff --git a/src/main/kotlin/cc/woverflow/chatting/Chatting.kt b/src/main/kotlin/cc/woverflow/chatting/Chatting.kt
index 4588847..a72fcbb 100644
--- a/src/main/kotlin/cc/woverflow/chatting/Chatting.kt
+++ b/src/main/kotlin/cc/woverflow/chatting/Chatting.kt
@@ -9,7 +9,9 @@ import cc.woverflow.chatting.hook.GuiNewChatHook
import cc.woverflow.chatting.mixin.GuiNewChatAccessor
import cc.woverflow.chatting.updater.Updater
import cc.woverflow.chatting.utils.ModCompatHooks
-import cc.woverflow.chatting.utils.RenderHelper
+import cc.woverflow.chatting.utils.copyToClipboard
+import cc.woverflow.chatting.utils.createBindFramebuffer
+import cc.woverflow.chatting.utils.screenshot
import com.google.gson.JsonParser
import gg.essential.api.EssentialAPI
import gg.essential.api.gui.buildConfirmationModal
@@ -213,9 +215,7 @@ object Chatting {
chatLines.add(drawnLines[i].chatComponent.formattedText)
}
- screenshot(chatLines, chat.chatWidth)?.let {
- RenderHelper.copyBufferedImageToClipboard(it)
- }
+ screenshot(chatLines, chat.chatWidth)?.copyToClipboard()
}
}
@@ -230,7 +230,7 @@ object Chatting {
}
val fr: FontRenderer = ModCompatHooks.fontRenderer
- val fb: Framebuffer = RenderHelper.createBindFramebuffer(width * 3, (messages.size * 9) * 3)
+ val fb: Framebuffer = createBindFramebuffer(width * 3, (messages.size * 9) * 3)
val file = File(Minecraft.getMinecraft().mcDataDir, "screenshots/chat/" + fileFormatter.format(Date()))
GlStateManager.scale(3f, 3f, 1f)
@@ -240,7 +240,7 @@ object Chatting {
fr.drawStringWithShadow(messages[i], 0f, (messages.size - 1 - i) * 9f, 0xffffff)
}
- val image = RenderHelper.screenshotFramebuffer(fb, file)
+ val image = fb.screenshot(file)
Minecraft.getMinecraft().entityRenderer.setupOverlayRendering()
Minecraft.getMinecraft().framebuffer.bindFramebuffer(true)
EssentialAPI.getNotifications()
diff --git a/src/main/kotlin/cc/woverflow/chatting/config/ChattingConfig.kt b/src/main/kotlin/cc/woverflow/chatting/config/ChattingConfig.kt
index 4065966..1c70b49 100644
--- a/src/main/kotlin/cc/woverflow/chatting/config/ChattingConfig.kt
+++ b/src/main/kotlin/cc/woverflow/chatting/config/ChattingConfig.kt
@@ -13,6 +13,7 @@ import gg.essential.vigilance.data.Category
import gg.essential.vigilance.data.Property
import gg.essential.vigilance.data.PropertyType
import gg.essential.vigilance.data.SortingBehavior
+import java.awt.Color
import java.io.File
object ChattingConfig : Vigilant(File(Chatting.modDir, "${Chatting.ID}.toml"), Chatting.NAME, sortingBehavior = ConfigSorting) {
@@ -36,6 +37,23 @@ object ChattingConfig : Vigilant(File(Chatting.modDir, "${Chatting.ID}.toml"), C
@Property(
type = PropertyType.SWITCH,
+ name = "Remove Scroll Bar",
+ description = "Remove the scroll bar.",
+ category = "General"
+ )
+ var removeScrollBar = false
+
+ @Property(
+ type = PropertyType.COLOR,
+ name = "Chat Background Color",
+ description = "Change the color of the chat background.",
+ category = "General",
+ allowAlpha = false
+ )
+ var chatBackgroundColor = Color(0, 0, 0, 50)
+
+ @Property(
+ type = PropertyType.SWITCH,
name = "Inform for Alternatives",
description = "Inform the user if a mod they are using can be replaced by a feature in Chatting.",
category = "General"
diff --git a/src/main/kotlin/cc/woverflow/chatting/gui/components/CleanButton.kt b/src/main/kotlin/cc/woverflow/chatting/gui/components/CleanButton.kt
index b67510a..f761a9a 100644
--- a/src/main/kotlin/cc/woverflow/chatting/gui/components/CleanButton.kt
+++ b/src/main/kotlin/cc/woverflow/chatting/gui/components/CleanButton.kt
@@ -1,6 +1,7 @@
package cc.woverflow.chatting.gui.components
import cc.woverflow.chatting.Chatting
+import cc.woverflow.chatting.utils.drawBorderedString
import club.sk1er.patcher.config.PatcherConfig
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.GuiButton
@@ -12,7 +13,7 @@ import java.awt.Color
* https://github.com/P0keDev/ChatShortcuts/blob/master/LICENSE
* @author P0keDev
*/
-open class CleanButton(buttonId: Int, private val x: () -> Int, private val y: () -> Int, widthIn: Int, heightIn: Int, name: String) :
+open class CleanButton(buttonId: Int, private val x: () -> Int, private val y: () -> Int, widthIn: Int, heightIn: Int, name: String, private val renderType: () -> RenderType) :
GuiButton(buttonId, x.invoke(), 0, widthIn, heightIn, name) {
open fun isEnabled(): Boolean {
@@ -59,7 +60,14 @@ open class CleanButton(buttonId: Int, private val x: () -> Int, private val y: (
} else if (hovered) {
j = 16777120
}
- drawCenteredString(fontrenderer, displayString, xPosition + width / 2, yPosition + (height - 8) / 2, j)
+ when (renderType.invoke()) {
+ RenderType.NONE, RenderType.SHADOW -> {
+ drawCenteredString(fontrenderer, displayString, xPosition + width / 2, yPosition + (height - 8) / 2, j)
+ }
+ RenderType.FULL -> {
+ fontrenderer.drawBorderedString(displayString, (xPosition + width / 2) - (fontrenderer.getStringWidth(displayString) / 2), yPosition + (height - 8) / 2, j)
+ }
+ }
}
}
diff --git a/src/main/kotlin/cc/woverflow/chatting/gui/components/RenderType.kt b/src/main/kotlin/cc/woverflow/chatting/gui/components/RenderType.kt
new file mode 100644
index 0000000..8a56d5b
--- /dev/null
+++ b/src/main/kotlin/cc/woverflow/chatting/gui/components/RenderType.kt
@@ -0,0 +1,7 @@
+package cc.woverflow.chatting.gui.components
+
+enum class RenderType {
+ NONE,
+ SHADOW,
+ FULL
+} \ No newline at end of file
diff --git a/src/main/kotlin/cc/woverflow/chatting/gui/components/ScreenshotButton.kt b/src/main/kotlin/cc/woverflow/chatting/gui/components/ScreenshotButton.kt
index 379444c..ff51a1e 100644
--- a/src/main/kotlin/cc/woverflow/chatting/gui/components/ScreenshotButton.kt
+++ b/src/main/kotlin/cc/woverflow/chatting/gui/components/ScreenshotButton.kt
@@ -11,7 +11,8 @@ import net.minecraft.client.renderer.GlStateManager
import net.minecraft.util.ResourceLocation
class ScreenshotButton :
- CleanButton(448318, { UResolution.scaledWidth - 28 }, { UResolution.scaledHeight - 27 }, 12, 12, "") {
+ CleanButton(448318, { UResolution.scaledWidth - 28 }, { UResolution.scaledHeight - 27 }, 12, 12, "",
+ { RenderType.NONE }) {
override fun onMousePress() {
val chat = Minecraft.getMinecraft().ingameGUI.chatGUI
diff --git a/src/main/kotlin/cc/woverflow/chatting/gui/components/SearchButton.kt b/src/main/kotlin/cc/woverflow/chatting/gui/components/SearchButton.kt
index a0f875e..71633a3 100644
--- a/src/main/kotlin/cc/woverflow/chatting/gui/components/SearchButton.kt
+++ b/src/main/kotlin/cc/woverflow/chatting/gui/components/SearchButton.kt
@@ -10,7 +10,8 @@ import net.minecraft.client.renderer.GlStateManager
import net.minecraft.util.ResourceLocation
class SearchButton :
- CleanButton(3993935, { UResolution.scaledWidth - 14 }, { UResolution.scaledHeight - 27 }, 12, 12, "") {
+ CleanButton(3993935, { UResolution.scaledWidth - 14 }, { UResolution.scaledHeight - 27 }, 12, 12, "",
+ { RenderType.NONE }) {
val inputField = SearchTextField()
private var chatBox = false
diff --git a/src/main/kotlin/cc/woverflow/chatting/gui/components/TabButton.kt b/src/main/kotlin/cc/woverflow/chatting/gui/components/TabButton.kt
index 5342629..25190e1 100644
--- a/src/main/kotlin/cc/woverflow/chatting/gui/components/TabButton.kt
+++ b/src/main/kotlin/cc/woverflow/chatting/gui/components/TabButton.kt
@@ -2,12 +2,13 @@ package cc.woverflow.chatting.gui.components
import cc.woverflow.chatting.chat.ChatTab
import cc.woverflow.chatting.chat.ChatTabs
+import cc.woverflow.chatting.config.ChattingConfig
import gg.essential.universal.UResolution
class TabButton(buttonId: Int, x: Int, widthIn: Int, heightIn: Int, private val chatTab: ChatTab) :
CleanButton(buttonId, { x }, {
UResolution.scaledHeight - 26
- }, widthIn, heightIn, chatTab.name) {
+ }, widthIn, heightIn, chatTab.name, { RenderType.values()[ChattingConfig.textRenderType] }) {
override fun onMousePress() {
ChatTabs.currentTab = chatTab
diff --git a/src/main/kotlin/cc/woverflow/chatting/utils/ModCompatHooks.kt b/src/main/kotlin/cc/woverflow/chatting/utils/ModCompatHooks.kt
index e69a36b..2f21429 100644
--- a/src/main/kotlin/cc/woverflow/chatting/utils/ModCompatHooks.kt
+++ b/src/main/kotlin/cc/woverflow/chatting/utils/ModCompatHooks.kt
@@ -5,7 +5,6 @@ import com.llamalad7.betterchat.BetterChat
import cc.woverflow.chatting.Chatting.isBetterChat
import cc.woverflow.chatting.Chatting.isPatcher
import cc.woverflow.chatting.config.ChattingConfig.textRenderType
-import cc.woverflow.chatting.utils.RenderHelper.drawBorderedString
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.FontRenderer
@@ -38,7 +37,7 @@ object ModCompatHooks {
fontRenderer.drawString(text, x, y, color, false)
}
2 -> {
- drawBorderedString(fontRenderer, text, x.toInt(), y.toInt(), color)
+ fontRenderer.drawBorderedString(text, x.toInt(), y.toInt(), color)
}
else -> fontRenderer.drawString(text, x, y, color, true)
}
diff --git a/src/main/kotlin/cc/woverflow/chatting/utils/RenderHelper.kt b/src/main/kotlin/cc/woverflow/chatting/utils/RenderHelper.kt
deleted file mode 100644
index 53870c1..0000000
--- a/src/main/kotlin/cc/woverflow/chatting/utils/RenderHelper.kt
+++ /dev/null
@@ -1,248 +0,0 @@
-package cc.woverflow.chatting.utils
-
-import cc.woverflow.chatting.config.ChattingConfig
-import cc.woverflow.chatting.hook.GuiNewChatHook
-import net.minecraft.client.Minecraft
-import net.minecraft.client.gui.FontRenderer
-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 {
- private val regex = Regex("(?i)\\u00A7[0-9a-f]")
- var bypassWyvtils = false
- private set
-
- /**
- * 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 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
- val pixelBuffer = BufferUtils.createIntBuffer(i)
- val pixelValues = IntArray(i)
- GL11.glPixelStorei(GL11.GL_PACK_ALIGNMENT, 1)
- GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1)
- GlStateManager.bindTexture(framebuffer.framebufferTexture)
- GL11.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, pixelBuffer)
- pixelBuffer[pixelValues] //Load buffer into array
- TextureUtil.processPixelValues(pixelValues, w, h) //Flip vertically
- val bufferedimage = BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB)
- val j = framebuffer.framebufferTextureHeight - framebuffer.framebufferHeight
- for (k in j until framebuffer.framebufferTextureHeight) {
- for (l in 0 until framebuffer.framebufferWidth) {
- bufferedimage.setRGB(l, k - j, pixelValues[k * framebuffer.framebufferTextureWidth + l])
- }
- }
- if (ChattingConfig.copyMode != 1) {
- try {
- file.parentFile.mkdirs()
- ImageIO.write(bufferedimage, "png", file)
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }
- return bufferedimage
- }
-
- /**
- * Taken from https://github.com/Moulberry/HyChat
- */
- fun createBindFramebuffer(w: Int, h: Int): Framebuffer {
- val framebuffer = Framebuffer(w, h, false)
- framebuffer.framebufferColor[0] = 0x36 / 255f
- framebuffer.framebufferColor[1] = 0x39 / 255f
- framebuffer.framebufferColor[2] = 0x3F / 255f
- framebuffer.framebufferClear()
- GlStateManager.matrixMode(5889)
- GlStateManager.loadIdentity()
- GlStateManager.ortho(0.0, w.toDouble(), h.toDouble(), 0.0, 1000.0, 3000.0)
- GlStateManager.matrixMode(5888)
- GlStateManager.loadIdentity()
- GlStateManager.translate(0.0f, 0.0f, -2000.0f)
- framebuffer.bindFramebuffer(true)
- return framebuffer
- }
-
- /**
- * Taken from https://github.com/Moulberry/HyChat
- */
- fun drawBorderedString(
- fontRendererIn: FontRenderer,
- text: String,
- x: Int,
- y: Int,
- color: Int
- ): Int {
- val noColors = text.replace(regex, "\u00A7r")
- var yes = 0
- if (((Minecraft.getMinecraft().ingameGUI.chatGUI as GuiNewChatHook).textOpacity / 4) > 3) {
- bypassWyvtils = true
- for (xOff in -2..2) {
- for (yOff in -2..2) {
- if (xOff * xOff != yOff * yOff) {
- yes += fontRendererIn.drawString(
- noColors,
- (xOff / 2f) + x, (yOff / 2f) + y, ((Minecraft.getMinecraft().ingameGUI.chatGUI as GuiNewChatHook).textOpacity / 4) shl 24, false
- )
- }
- }
- }
- bypassWyvtils = false
- }
- yes += fontRendererIn.drawString(text, x, y, color)
- return yes
- }
-} \ No newline at end of file
diff --git a/src/main/kotlin/cc/woverflow/chatting/utils/renderutils.kt b/src/main/kotlin/cc/woverflow/chatting/utils/renderutils.kt
new file mode 100644
index 0000000..0496905
--- /dev/null
+++ b/src/main/kotlin/cc/woverflow/chatting/utils/renderutils.kt
@@ -0,0 +1,244 @@
+@file:JvmName("RenderUtils")
+
+package cc.woverflow.chatting.utils
+
+import cc.woverflow.chatting.config.ChattingConfig
+import cc.woverflow.chatting.hook.GuiNewChatHook
+import net.minecraft.client.Minecraft
+import net.minecraft.client.gui.FontRenderer
+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
+
+var bypassWyvtils = false
+ private set
+
+private val regex = Regex("(?i)\\u00A7[0-9a-f]")
+
+/**
+ * Taken from https://github.com/Moulberry/HyChat
+ */
+fun createBindFramebuffer(w: Int, h: Int): Framebuffer {
+ val framebuffer = Framebuffer(w, h, false)
+ framebuffer.framebufferColor[0] = 0x36 / 255f
+ framebuffer.framebufferColor[1] = 0x39 / 255f
+ framebuffer.framebufferColor[2] = 0x3F / 255f
+ framebuffer.framebufferClear()
+ GlStateManager.matrixMode(5889)
+ GlStateManager.loadIdentity()
+ GlStateManager.ortho(0.0, w.toDouble(), h.toDouble(), 0.0, 1000.0, 3000.0)
+ GlStateManager.matrixMode(5888)
+ GlStateManager.loadIdentity()
+ GlStateManager.translate(0.0f, 0.0f, -2000.0f)
+ framebuffer.bindFramebuffer(true)
+ return framebuffer
+}
+
+/**
+ * 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 BufferedImage.copyToClipboard() {
+ if (SystemUtils.IS_OS_WINDOWS) {
+ try {
+ val width = this.width
+ val height = this.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 = this.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 = this.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 =
+ this.getRGB(0, 0, this.width, this.height, null, 0, this.width)
+ val newImage = BufferedImage(this.width, this.height, BufferedImage.TYPE_INT_RGB)
+ newImage.setRGB(0, 0, newImage.width, newImage.height, pixels, 0, newImage.width)
+
+ try {
+ Toolkit.getDefaultToolkit().systemClipboard.setContents(ImageTransferable(this), null)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+}
+
+/**
+ * Taken from https://github.com/Moulberry/HyChat
+ */
+fun Framebuffer.screenshot(file: File): BufferedImage {
+ val w = this.framebufferWidth
+ val h = this.framebufferHeight
+ val i = w * h
+ val pixelBuffer = BufferUtils.createIntBuffer(i)
+ val pixelValues = IntArray(i)
+ GL11.glPixelStorei(GL11.GL_PACK_ALIGNMENT, 1)
+ GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1)
+ GlStateManager.bindTexture(this.framebufferTexture)
+ GL11.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, pixelBuffer)
+ pixelBuffer[pixelValues] //Load buffer into array
+ TextureUtil.processPixelValues(pixelValues, w, h) //Flip vertically
+ val bufferedimage = BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB)
+ val j = this.framebufferTextureHeight - this.framebufferHeight
+ for (k in j until this.framebufferTextureHeight) {
+ for (l in 0 until this.framebufferWidth) {
+ bufferedimage.setRGB(l, k - j, pixelValues[k * this.framebufferTextureWidth + l])
+ }
+ }
+ if (ChattingConfig.copyMode != 1) {
+ try {
+ file.parentFile.mkdirs()
+ ImageIO.write(bufferedimage, "png", file)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ return bufferedimage
+}
+
+/**
+ * Taken from https://github.com/Moulberry/HyChat
+ */
+fun FontRenderer.drawBorderedString(text: String,
+ x: Int,
+ y: Int,
+ color: Int): Int {
+ val noColors = text.replace(regex, "\u00A7r")
+ var yes = 0
+ if (((Minecraft.getMinecraft().ingameGUI.chatGUI as GuiNewChatHook).textOpacity / 4) > 3) {
+ bypassWyvtils = true
+ for (xOff in -2..2) {
+ for (yOff in -2..2) {
+ if (xOff * xOff != yOff * yOff) {
+ yes += drawString(
+ noColors,
+ (xOff / 2f) + x, (yOff / 2f) + y, ((Minecraft.getMinecraft().ingameGUI.chatGUI as GuiNewChatHook).textOpacity / 4) shl 24, false
+ )
+ }
+ }
+ }
+ bypassWyvtils = false
+ }
+ yes += drawString(text, x, y, color)
+ return yes
+} \ No newline at end of file
diff --git a/src/main/resources/mixins.chatting.json b/src/main/resources/mixins.chatting.json
index 9377858..3a488ae 100644
--- a/src/main/resources/mixins.chatting.json
+++ b/src/main/resources/mixins.chatting.json
@@ -10,7 +10,6 @@
"GuiNewChatAccessor",
"GuiNewChatMapMixin",
"GuiNewChatMixin",
- "GuiIngameForgeMixin",
"GuiUtilsMixin",
"WyvtilsListenerMixin"
],