diff options
author | Wyvest <45589059+Wyvest@users.noreply.github.com> | 2022-01-16 16:27:15 +0700 |
---|---|---|
committer | Wyvest <45589059+Wyvest@users.noreply.github.com> | 2022-01-16 16:27:15 +0700 |
commit | 4e587bc97c3aee3c3458a6ac60a43122f7c7971e (patch) | |
tree | ab9df90c3b5763d60ea702fd13f15461bbb56421 /src/main | |
parent | 42f8aa3024772e708143d49355130ef2a7999243 (diff) | |
download | Chatting-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
Diffstat (limited to 'src/main')
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" ], |