From fac2d5491a16c0e544e6271c17d408452d0825f4 Mon Sep 17 00:00:00 2001 From: RTAkland Date: Thu, 31 Oct 2024 21:32:42 +0800 Subject: [PATCH] feat: add more feature --- gradle/libs.versions.toml | 2 +- src/main/kotlin/cn/rtast/fancybot/FancyBot.kt | 91 ++++++++++--------- .../commands/reply/InvertImageCommand.kt | 31 +++++++ .../commands/reply/RandomRGBCommand.kt | 33 +++++++ .../cn/rtast/fancybot/util/misc/Image.kt | 41 +++++++++ 5 files changed, 153 insertions(+), 45 deletions(-) create mode 100644 src/main/kotlin/cn/rtast/fancybot/commands/reply/InvertImageCommand.kt create mode 100644 src/main/kotlin/cn/rtast/fancybot/commands/reply/RandomRGBCommand.kt diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 72fb1fa..787dce3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] kotlinVersion = "2.0.20" -ronebotVersion = "2.2.1" +ronebotVersion = "2.2.3" shadowVersion = "8.3.0" okhttpVersion = "5.0.0-alpha.14" exposedVersion = "0.53.0" diff --git a/src/main/kotlin/cn/rtast/fancybot/FancyBot.kt b/src/main/kotlin/cn/rtast/fancybot/FancyBot.kt index f7a90d2..d828867 100644 --- a/src/main/kotlin/cn/rtast/fancybot/FancyBot.kt +++ b/src/main/kotlin/cn/rtast/fancybot/FancyBot.kt @@ -14,6 +14,8 @@ import cn.rtast.fancybot.commands.misc.ScanQRCodeCommand import cn.rtast.fancybot.commands.misc.ShortLinkCommand.Companion.makeShortLink import cn.rtast.fancybot.commands.parse.* import cn.rtast.fancybot.commands.reply.ImageBedCommand +import cn.rtast.fancybot.commands.reply.InvertImageCommand +import cn.rtast.fancybot.commands.reply.RandomRGBCommand import cn.rtast.fancybot.commands.reply.SpeedUpGIFCommand import cn.rtast.fancybot.entity.nailong.NaiLongDetectPayload import cn.rtast.fancybot.entity.nailong.NaiLongDetectResponse @@ -119,53 +121,54 @@ class FancyBot : OneBotListener { } if (message.message.any { it.type == ArrayMessageType.reply }) { - val command = message.message.reversed().find { it.type == ArrayMessageType.text }!!.data.text!! + val command = message.text.trim() val replyId = message.message.find { it.type == ArrayMessageType.reply }!!.data.id!! val getMsg = message.action.getMessage(replyId.toString().toLong()) - val plainTextContent = getMsg.message - .filter { it.type == ArrayMessageType.text } - .joinToString { it.data.text!! } - if (command.contains("/倒放") || command.contains("/df")) ReverseGIFCommand.reverse(message, getMsg) - if (command.contains("/图来") || command.contains("/图链")) ImageURLCommand.callback(message, getMsg) - if (command.contains("/图床")) ImageBedCommand.execute(getMsg, message) - if (command.contains("/reaction")) ReactionCommand.reaction( - message.action, - message.groupId, - getMsg.messageId - ) - if (command.contains("/sl") || command.contains("/short")) message.reply( - plainTextContent.trim().makeShortLink() - ) - if (command.contains("/ascii") || command.contains("/asc")) { - val url = AsciiArtCommand.getImageUrl(getMsg) - val image = AsciiArtCommand.generateAsciiArt(url) - message.reply(image) - } - if (command.contains("/pb") || command.contains("/pastebin")) { - val pastebinUrl = PastebinCommand.createPastebin(plainTextContent) - message.reply(pastebinUrl) - } - if (command.contains("/加速")) { - val multiply = command.split("加速").last().toFloat() - SpeedUpGIFCommand.speedUp(message, getMsg, multiply) - } - if (command.contains("/黑白")) { - val msg = MessageChain.Builder() - getMsg.message.filter { it.type == ArrayMessageType.image || it.type == ArrayMessageType.mface } - .forEach { - val imgUrl = it.data.file!! - val decoder = GifDecoder() - val imageStream = withContext(Dispatchers.IO) { imgUrl.toURL().openStream() } - decoder.read(imageStream) - if (decoder.frameCount == 0) { - msg.addImage(imageStream.readBytes().toBufferedImage().toByteArray().encodeToBase64(), true) - } else { - val frames = (0 until decoder.frameCount).map { decoder.getFrame(it).toGrayscale() } - val base64 = decoder.makeGif(frames).encodeToBase64() - msg.addImage(base64, true) + val plainTextContent = getMsg.text + when (command) { + "/倒放", "/df" -> ReverseGIFCommand.reverse(message, getMsg) + "/图来", "/图链" -> ImageURLCommand.callback(message, getMsg) + "/图床" -> ImageBedCommand.execute(getMsg, message) + "/reaction" -> ReactionCommand.reaction(message.action, message.groupId, getMsg.messageId) + "/sl", "/short" -> message.reply(plainTextContent.trim().makeShortLink()) + "/rc", "/随机颜色" -> RandomRGBCommand.random(message, getMsg) + "/颜色反转", "/iv" -> InvertImageCommand.invert(message, getMsg) + "/ascii", "/asc" -> { + val url = AsciiArtCommand.getImageUrl(getMsg) + val image = AsciiArtCommand.generateAsciiArt(url) + message.reply(image) + } + + "/pb", "/pastebin" -> { + val pastebinUrl = PastebinCommand.createPastebin(plainTextContent) + message.reply(pastebinUrl) + } + + "/加速" -> { + val multiply = command.split("加速").last().toFloat() + SpeedUpGIFCommand.speedUp(message, getMsg, multiply) + } + + "/黑白", "/灰度" -> { + val msg = MessageChain.Builder() + getMsg.message.filter { it.type == ArrayMessageType.image || it.type == ArrayMessageType.mface } + .forEach { + val imgUrl = it.data.file!! + val decoder = GifDecoder() + val imageStream = withContext(Dispatchers.IO) { imgUrl.toURL().openStream() } + decoder.read(imageStream) + if (decoder.frameCount == 0) { + msg.addImage( + imageStream.readBytes().toBufferedImage().toByteArray().encodeToBase64(), true + ) + } else { + val frames = (0 until decoder.frameCount).map { decoder.getFrame(it).toGrayscale() } + val base64 = decoder.makeGif(frames).encodeToBase64() + msg.addImage(base64, true) + } } - } - message.reply(msg.build()) + message.reply(msg.build()) + } } } diff --git a/src/main/kotlin/cn/rtast/fancybot/commands/reply/InvertImageCommand.kt b/src/main/kotlin/cn/rtast/fancybot/commands/reply/InvertImageCommand.kt new file mode 100644 index 0000000..053b502 --- /dev/null +++ b/src/main/kotlin/cn/rtast/fancybot/commands/reply/InvertImageCommand.kt @@ -0,0 +1,31 @@ +/* + * Copyright © 2024 RTAkland + * Author: RTAkland + * Date: 2024/10/31 + */ + + +package cn.rtast.fancybot.commands.reply + +import cn.rtast.fancybot.util.misc.invertColor +import cn.rtast.fancybot.util.misc.toBufferedImage +import cn.rtast.fancybot.util.misc.toByteArray +import cn.rtast.fancybot.util.misc.toURL +import cn.rtast.fancybot.util.str.encodeToBase64 +import cn.rtast.rob.entity.GetMessage +import cn.rtast.rob.entity.GroupMessage +import cn.rtast.rob.entity.images +import cn.rtast.rob.util.ob.MessageChain + +object InvertImageCommand { + + suspend fun invert(message: GroupMessage, getMsg: GetMessage.Message) { + val msg = MessageChain.Builder() + getMsg.images.forEach { + val img = it.file.toURL().readBytes().toBufferedImage() + .invertColor().toByteArray().encodeToBase64() + msg.addImage(img, true) + } + message.reply(msg.build()) + } +} \ No newline at end of file diff --git a/src/main/kotlin/cn/rtast/fancybot/commands/reply/RandomRGBCommand.kt b/src/main/kotlin/cn/rtast/fancybot/commands/reply/RandomRGBCommand.kt new file mode 100644 index 0000000..bac14c8 --- /dev/null +++ b/src/main/kotlin/cn/rtast/fancybot/commands/reply/RandomRGBCommand.kt @@ -0,0 +1,33 @@ +/* + * Copyright © 2024 RTAkland + * Author: RTAkland + * Date: 2024/10/31 + */ + + +package cn.rtast.fancybot.commands.reply + +import cn.rtast.fancybot.util.misc.randomColor +import cn.rtast.fancybot.util.misc.toBufferedImage +import cn.rtast.fancybot.util.misc.toByteArray +import cn.rtast.fancybot.util.misc.toURL +import cn.rtast.fancybot.util.str.encodeToBase64 +import cn.rtast.rob.entity.GetMessage +import cn.rtast.rob.entity.GroupMessage +import cn.rtast.rob.entity.images +import cn.rtast.rob.util.ob.MessageChain + +object RandomRGBCommand { + + suspend fun random(message: GroupMessage, getMsg: GetMessage.Message) { + val msg = MessageChain.Builder() + getMsg.images.forEach { + msg.addImage( + it.file.toURL().readBytes().toBufferedImage() + .randomColor().toByteArray().encodeToBase64(), + true + ) + } + message.reply(msg.build()) + } +} \ No newline at end of file diff --git a/src/main/kotlin/cn/rtast/fancybot/util/misc/Image.kt b/src/main/kotlin/cn/rtast/fancybot/util/misc/Image.kt index 4cea849..9ba31e5 100644 --- a/src/main/kotlin/cn/rtast/fancybot/util/misc/Image.kt +++ b/src/main/kotlin/cn/rtast/fancybot/util/misc/Image.kt @@ -16,6 +16,7 @@ import java.awt.image.BufferedImage import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import javax.imageio.ImageIO +import kotlin.random.Random private fun BufferedImage.getScaledWidth(maxWidth: Double, maxHeight: Double): Pair { @@ -145,4 +146,44 @@ fun BufferedImage.toGrayscale(): BufferedImage { } } return grayscaleImage +} + +fun BufferedImage.invertColor(): BufferedImage { + val width = this.width + val height = this.height + for (x in 0 until width) { + for (y in 0 until height) { + val rgba = this.getRGB(x, y) + val a = rgba shr 24 and 0xff + val r = 255 - (rgba shr 16 and 0xff) + val g = 255 - (rgba shr 8 and 0xff) + val b = 255 - (rgba and 0xff) + val invertedColor = (a shl 24) or (r shl 16) or (g shl 8) or b + this.setRGB(x, y, invertedColor) + } + } + return this +} + +fun BufferedImage.randomColor(): BufferedImage { + val width = this.width + val height = this.height + for (x in 0 until width) { + for (y in 0 until height) { + val rgba = this.getRGB(x, y) + val a = (rgba shr 24) and 0xff + val r = (rgba shr 16) and 0xff + val g = (rgba shr 8) and 0xff + val b = rgba and 0xff + if (a < 255 || (r == 255 && g == 255 && b == 255) || (r == 0 && g == 0 && b == 0)) { + continue + } + val newR = Random.nextInt(256) + val newG = Random.nextInt(256) + val newB = Random.nextInt(256) + val randomColor = (a shl 24) or (newR shl 16) or (newG shl 8) or newB + this.setRGB(x, y, randomColor) + } + } + return this } \ No newline at end of file