From 416ff1623df04c8f5f0ad35629487932305b86b8 Mon Sep 17 00:00:00 2001
From: Silly <sillysys@proton.me>
Date: Sun, 6 Oct 2024 16:03:43 -0400
Subject: [PATCH] Make headpats animated :3

---
 .../astralbot/commands/discord/FunCommands.kt |  77 ++++++++++--------
 .../dev/erdragh/astralbot/util/GifWriter.kt   |  70 ++++++++++++++++
 common/src/main/resources/headpat.png         | Bin 2960 -> 0 bytes
 common/src/main/resources/headpat/pet0.gif    | Bin 0 -> 2764 bytes
 common/src/main/resources/headpat/pet1.gif    | Bin 0 -> 3042 bytes
 common/src/main/resources/headpat/pet2.gif    | Bin 0 -> 2934 bytes
 common/src/main/resources/headpat/pet3.gif    | Bin 0 -> 2936 bytes
 common/src/main/resources/headpat/pet4.gif    | Bin 0 -> 2598 bytes
 8 files changed, 115 insertions(+), 32 deletions(-)
 create mode 100644 common/src/main/kotlin/dev/erdragh/astralbot/util/GifWriter.kt
 delete mode 100644 common/src/main/resources/headpat.png
 create mode 100644 common/src/main/resources/headpat/pet0.gif
 create mode 100644 common/src/main/resources/headpat/pet1.gif
 create mode 100644 common/src/main/resources/headpat/pet2.gif
 create mode 100644 common/src/main/resources/headpat/pet3.gif
 create mode 100644 common/src/main/resources/headpat/pet4.gif

diff --git a/common/src/main/kotlin/dev/erdragh/astralbot/commands/discord/FunCommands.kt b/common/src/main/kotlin/dev/erdragh/astralbot/commands/discord/FunCommands.kt
index 3a38048..3a50e4a 100644
--- a/common/src/main/kotlin/dev/erdragh/astralbot/commands/discord/FunCommands.kt
+++ b/common/src/main/kotlin/dev/erdragh/astralbot/commands/discord/FunCommands.kt
@@ -1,11 +1,13 @@
 package dev.erdragh.astralbot.commands.discord
 
+import dev.erdragh.astralbot.util.GifWriter
 import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent
 import net.dv8tion.jda.api.interactions.commands.OptionType
 import net.dv8tion.jda.api.interactions.commands.build.Commands
 import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData
 import net.dv8tion.jda.api.utils.FileUpload
-import java.awt.Color
+import java.awt.Graphics2D
+import java.awt.RenderingHints
 import java.awt.image.BufferedImage
 import java.io.ByteArrayOutputStream
 import java.net.URL
@@ -15,7 +17,13 @@ object HeadpatCommand : HandledSlashCommand {
     private const val USER_OPTION = "user"
     override val command: SlashCommandData = Commands.slash("headpat", "Headpats a user")
         .addOption(OptionType.USER, USER_OPTION, "The user whose avatar will be headpat.", true)
-    private val headpatBaseImage = ImageIO.read(this.javaClass.getResource("/headpat.png"))
+
+    private val ANIMATION = floatArrayOf(-.05f, .1f, .2f, .19f, .1f)
+    private val FRAMES: Array<BufferedImage> = Array(5) { ImageIO.read(this::class.java.getResourceAsStream("/headpat/pet$it.gif")) }
+    private val RENDERING_HINTS = RenderingHints(mapOf(
+        RenderingHints.KEY_ANTIALIASING to RenderingHints.VALUE_ANTIALIAS_ON,
+        RenderingHints.KEY_RENDERING to RenderingHints.VALUE_RENDER_QUALITY
+    ))
 
     override fun handle(event: SlashCommandInteractionEvent) {
         event.deferReply(false).queue()
@@ -28,35 +36,40 @@ object HeadpatCommand : HandledSlashCommand {
 
         val url = URL(user.effectiveAvatarUrl)
         val avatar = ImageIO.read(url)
-        val headpatImage = BufferedImage(headpatBaseImage.width, headpatBaseImage.height, BufferedImage.TYPE_INT_ARGB)
-
-        val graphics = headpatImage.createGraphics()
-
-        val xOffset = 20
-        val yOffset = 20
-        graphics.drawImage(
-            avatar,
-            xOffset,
-            yOffset,
-            headpatImage.width - xOffset,
-            headpatImage.height - yOffset,
-            Color(0, 0, 0, 0),
-            null
-        )
-        graphics.drawImage(
-            headpatBaseImage,
-            0,
-            0,
-            headpatBaseImage.width,
-            headpatBaseImage.height,
-            Color(0, 0, 0, 0),
-            null
-        )
-
-        graphics.dispose()
-        val byteStream = ByteArrayOutputStream()
-        ImageIO.write(headpatImage, "png", byteStream)
-        event.hook.sendFiles(FileUpload.fromData(byteStream.toByteArray(), "headpat.png")).queue()
-    }
 
+        val stream: ByteArrayOutputStream
+
+        ByteArrayOutputStream().use { output ->
+            ImageIO.createImageOutputStream(output).use { out ->
+                GifWriter(
+                    out, BufferedImage.TYPE_INT_ARGB,
+                    timeBetweenFramesMS = 50, loopContinuously = true, transparent = true
+                ).use { gifWriter ->
+                    for (i in FRAMES.indices) {
+                        val frame = BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB)
+                        val graphics = frame.graphics as Graphics2D
+                        // set rendering hints to slightly improve quality
+                        graphics.setRenderingHints(RENDERING_HINTS)
+
+                        val offset1 = Math.round(ANIMATION[i] * 64)
+                        val offset2 = Math.round((-ANIMATION[i]) * 64)
+
+                        // draw avatar
+                        graphics.drawImage(avatar, 2, 32 + offset1, 128 - offset2, 128 - 32 - offset1, null)
+                        // draw hand
+                        graphics.drawImage(FRAMES[i], 0, 0, 128, 128, null)
+
+                        gifWriter.write(frame)
+
+                        graphics.dispose()
+                    }
+                }
+                out.flush()
+
+                stream = output
+            }
+        }
+
+        event.hook.sendFiles(FileUpload.fromData(stream.toByteArray(), "headpat.gif")).queue()
+    }
 }
\ No newline at end of file
diff --git a/common/src/main/kotlin/dev/erdragh/astralbot/util/GifWriter.kt b/common/src/main/kotlin/dev/erdragh/astralbot/util/GifWriter.kt
new file mode 100644
index 0000000..1b61f5a
--- /dev/null
+++ b/common/src/main/kotlin/dev/erdragh/astralbot/util/GifWriter.kt
@@ -0,0 +1,70 @@
+package dev.erdragh.astralbot.util
+
+import java.awt.image.RenderedImage
+import java.io.IOException
+import javax.imageio.*
+import javax.imageio.metadata.IIOMetadata
+import javax.imageio.metadata.IIOMetadataNode
+import javax.imageio.stream.ImageOutputStream
+
+/**
+ * A simple utility for creating gifs.
+ *
+ * @author femmeromantic
+ */
+class GifWriter(
+    os: ImageOutputStream?, imageType: Int,
+    timeBetweenFramesMS: Int, loopContinuously: Boolean, transparent: Boolean
+) : AutoCloseable {
+    private val writer: ImageWriter =
+        ImageIO.getImageWritersBySuffix("gif").next() ?: throw IOException("No GIF Image Writers Exist!")
+    private val imageWriteParam: ImageWriteParam = writer.defaultWriteParam
+    private val metadata: IIOMetadata = writer.getDefaultImageMetadata(
+        ImageTypeSpecifier.createFromBufferedImageType(imageType),
+        imageWriteParam
+    )
+
+    init {
+        val root = metadata.getAsTree(metadata.nativeMetadataFormatName) as IIOMetadataNode
+        setGifAttributes(root, timeBetweenFramesMS, transparent, loopContinuously)
+        metadata.setFromTree(metadata.nativeMetadataFormatName, root)
+        writer.output = os
+        writer.prepareWriteSequence(null)
+    }
+
+    fun write(img: RenderedImage) {
+        writer.writeToSequence(IIOImage(img, null, metadata), imageWriteParam)
+    }
+
+    override fun close() {
+        writer.endWriteSequence()
+    }
+
+    private fun getOrCreate(root: IIOMetadataNode, name: String): IIOMetadataNode =
+        (0 until root.length)
+            .map { root.item(it) as IIOMetadataNode }
+            .firstOrNull { it.nodeName == name }
+            ?: IIOMetadataNode(name).also { root.appendChild(it) }
+
+    private fun setGifAttributes(
+        root: IIOMetadataNode, timeBetweenFramesMS: Int, transparent: Boolean, loopContinuously: Boolean
+    ) {
+        getOrCreate(root, "GraphicControlExtension").apply {
+            setAttribute("disposalMethod", "restoreToBackgroundColor")
+            setAttribute("userInputFlag", "FALSE")
+            setAttribute("transparentColorFlag", if (transparent) "TRUE" else "FALSE")
+            setAttribute("delayTime", (timeBetweenFramesMS / 10).toString())
+            setAttribute("transparentColorIndex", "0")
+        }
+        getOrCreate(root, "CommentExtensions").setAttribute("CommentExtension", "Test Comment")
+
+        val appEN = getOrCreate(root, "ApplicationExtensions")
+        val loop = if (loopContinuously) 0 else 1
+        IIOMetadataNode("ApplicationExtension").apply {
+            setAttribute("applicationID", "NETSCAPE")
+            setAttribute("authenticationCode", "2.0")
+            userObject = byteArrayOf(0x1, loop.toByte(), 0)
+            appEN.appendChild(this)
+        }
+    }
+}
\ No newline at end of file
diff --git a/common/src/main/resources/headpat.png b/common/src/main/resources/headpat.png
deleted file mode 100644
index 1e2763495537d787f2075e991257eac118cae8bf..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 2960
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
B)0O}L

diff --git a/common/src/main/resources/headpat/pet0.gif b/common/src/main/resources/headpat/pet0.gif
new file mode 100644
index 0000000000000000000000000000000000000000..09c40d4e7a84556d967867fde828c1ee43f292ee
GIT binary patch
literal 2764
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
S|NZcfzx?M<|N2`$2mm|EB`l}_

literal 0
HcmV?d00001

diff --git a/common/src/main/resources/headpat/pet1.gif b/common/src/main/resources/headpat/pet1.gif
new file mode 100644
index 0000000000000000000000000000000000000000..ee33972f075607ca88a07a64d7ba12d6933782ca
GIT binary patch
literal 3042
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
BSrq^P

literal 0
HcmV?d00001

diff --git a/common/src/main/resources/headpat/pet2.gif b/common/src/main/resources/headpat/pet2.gif
new file mode 100644
index 0000000000000000000000000000000000000000..4d09c162c71f28ee5c21e3e507030045dc3dfece
GIT binary patch
literal 2934
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

literal 0
HcmV?d00001

diff --git a/common/src/main/resources/headpat/pet3.gif b/common/src/main/resources/headpat/pet3.gif
new file mode 100644
index 0000000000000000000000000000000000000000..09dedb3ac08fae45c2ea5f3ee036433e497a3fef
GIT binary patch
literal 2936
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

literal 0
HcmV?d00001

diff --git a/common/src/main/resources/headpat/pet4.gif b/common/src/main/resources/headpat/pet4.gif
new file mode 100644
index 0000000000000000000000000000000000000000..f9fb14c6d828624605155b6ae4e290ec2a8d6c88
GIT binary patch
literal 2598
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
I{T>7WJAqclwEzGB

literal 0
HcmV?d00001