From 8b907903951a033529f40149150cc534578bd0e1 Mon Sep 17 00:00:00 2001 From: RTAkland Date: Thu, 14 Nov 2024 20:09:15 +0800 Subject: [PATCH] feat: add split frame and upgrade ronebot to 2.5.2 --- gradle/libs.versions.toml | 2 +- src/main/kotlin/cn/rtast/fancybot/FancyBot.kt | 53 ++++++++++++------- .../commands/misc/MinecraftCommand.kt | 12 ++--- .../commands/parse/AsciiArtCommand.kt | 5 +- .../rtast/fancybot/util/CommandInterceptor.kt | 7 +-- 5 files changed, 48 insertions(+), 31 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5f16553..12ab8d2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] kotlinVersion = "2.0.20" -ronebotVersion = "2.4.8" +ronebotVersion = "2.5.2" 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 5faa2a7..8de98e9 100644 --- a/src/main/kotlin/cn/rtast/fancybot/FancyBot.kt +++ b/src/main/kotlin/cn/rtast/fancybot/FancyBot.kt @@ -18,19 +18,10 @@ 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.enums.WSType -import cn.rtast.fancybot.util.* -import cn.rtast.fancybot.util.misc.ImageBed -import cn.rtast.fancybot.util.misc.convertToDate -import cn.rtast.fancybot.util.misc.initBackgroundTasks -import cn.rtast.fancybot.util.misc.initCommand -import cn.rtast.fancybot.util.misc.initFilesDir -import cn.rtast.fancybot.util.misc.initItems -import cn.rtast.fancybot.util.misc.initSetuIndex -import cn.rtast.fancybot.util.misc.makeGif -import cn.rtast.fancybot.util.misc.toBufferedImage -import cn.rtast.fancybot.util.misc.toByteArray -import cn.rtast.fancybot.util.misc.toGrayscale -import cn.rtast.fancybot.util.misc.toURL +import cn.rtast.fancybot.util.CommandInterceptor +import cn.rtast.fancybot.util.Logger +import cn.rtast.fancybot.util.initDatabase +import cn.rtast.fancybot.util.misc.* import cn.rtast.fancybot.util.str.encodeToBase64 import cn.rtast.rob.ROneBotFactory import cn.rtast.rob.entity.* @@ -45,14 +36,16 @@ import cn.rtast.rob.enums.QQFace import cn.rtast.rob.onebot.MessageChain import cn.rtast.rob.onebot.OneBotAction import cn.rtast.rob.onebot.OneBotListener +import cn.rtast.rob.segment.NewLine +import cn.rtast.rob.segment.Text import com.madgag.gif.fmsware.GifDecoder -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext +import kotlinx.coroutines.* +import java.io.ByteArrayOutputStream import java.io.File import java.net.URI +import java.util.zip.ZipEntry +import java.util.zip.ZipOutputStream +import javax.imageio.ImageIO class FancyBot : OneBotListener { @@ -166,6 +159,30 @@ class FancyBot : OneBotListener { } message.reply(msg.build()) } + + "/拆帧", "/cj" -> { + val gifStream = getMsg.images.first().file.toURL().openStream() + val decoder = GifDecoder() + decoder.read(gifStream) + val frames = (0 until decoder.frameCount).map { decoder.getFrame(it) } + val byteArrayOutputStream = ByteArrayOutputStream() + ZipOutputStream(byteArrayOutputStream).use { zipOut -> + for ((index, image) in frames.withIndex()) { + val imageOutputStream = ByteArrayOutputStream() + ImageIO.write(image, "png", imageOutputStream) + val entry = ZipEntry("frame_$index.png") + zipOut.putNextEntry(entry) + zipOut.write(imageOutputStream.toByteArray()) + zipOut.closeEntry() + } + } + val zipBytes = byteArrayOutputStream.toByteArray() + logger.info("Split frame size: ${zipBytes.size / 1024 / 1024}MB") + val imgBedUrl = ImageBed.upload(zipBytes, "zip") + val shortLink = imgBedUrl.makeShortLink() + val msg = Text(imgBedUrl) + NewLine() + Text(shortLink) + message.reply(msg) + } } } diff --git a/src/main/kotlin/cn/rtast/fancybot/commands/misc/MinecraftCommand.kt b/src/main/kotlin/cn/rtast/fancybot/commands/misc/MinecraftCommand.kt index c9bb95d..355c47d 100644 --- a/src/main/kotlin/cn/rtast/fancybot/commands/misc/MinecraftCommand.kt +++ b/src/main/kotlin/cn/rtast/fancybot/commands/misc/MinecraftCommand.kt @@ -49,10 +49,10 @@ import cn.rtast.rcon.exceptions.AuthFailedException import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.PrivateMessage import cn.rtast.rob.onebot.MessageChain -import cn.rtast.rob.onebot.toMessageChain import cn.rtast.rob.onebot.toNode import cn.rtast.rob.segment.NewLine import cn.rtast.rob.segment.Text +import cn.rtast.rob.segment.toMessageChain import cn.rtast.rob.util.BaseCommand import okhttp3.FormBody import java.awt.AlphaComposite @@ -99,7 +99,7 @@ class MinecraftWikiCommand : BaseCommand() { "s", "搜索" -> { val searchKeyword = args.drop(1).joinToString(" ").trim() val messages = mutableListOf() - val headerMessage = listOf("结果如下:").toMessageChain() + val headerMessage = MessageChain.Builder().addText("结果如下:").build() messages.add(headerMessage) Http.get( "$baseApiUrl/search/title", @@ -134,7 +134,7 @@ class MinecraftWikiCommand : BaseCommand() { response = Http.get(response.redirectTarget) } val messages = mutableListOf() - val headerMsg = listOf("标题${response.title}的内容如下").toMessageChain() + val headerMsg = MessageChain.Builder().addText("标题${response.title}的内容如下").build() val footerMsg = listOf( Text("数据来源: https://zh.minecraft.wiki"), NewLine(), @@ -551,7 +551,7 @@ class RCONCommand : BaseCommand() { return } val messages = mutableListOf() - .also { it.add(listOf("所有配置如下").toMessageChain()) } + .also { it.add(MessageChain.Builder().addText("所有配置如下").build()) } allRcons.forEach { val msg = MessageChain.Builder() .addText("名称: ${it.name}") @@ -594,8 +594,8 @@ class RCONCommand : BaseCommand() { try { val result = rconManager.executeCommand(message.sender.userId, name, command) val messages = mutableListOf() - .also { it.add(listOf("执行结果如下").toMessageChain()) } - .also { it.add(listOf(result).toMessageChain()) } + .also { it.add(MessageChain.Builder().addText("执行结果如下").build()) } + .also { it.add(MessageChain.Builder().addText(result).build()) } .toNode(configManager.selfId) message.reply(messages) } catch (_: AuthFailedException) { diff --git a/src/main/kotlin/cn/rtast/fancybot/commands/parse/AsciiArtCommand.kt b/src/main/kotlin/cn/rtast/fancybot/commands/parse/AsciiArtCommand.kt index c69d0c3..a492d74 100644 --- a/src/main/kotlin/cn/rtast/fancybot/commands/parse/AsciiArtCommand.kt +++ b/src/main/kotlin/cn/rtast/fancybot/commands/parse/AsciiArtCommand.kt @@ -19,7 +19,6 @@ import cn.rtast.rob.entity.GetMessage import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.enums.ArrayMessageType import cn.rtast.rob.onebot.MessageChain -import cn.rtast.rob.onebot.toMessageChain import cn.rtast.rob.util.BaseCommand import com.madgag.gif.fmsware.GifDecoder import kotlinx.coroutines.Dispatchers @@ -131,10 +130,10 @@ class AsciiArtCommand : BaseCommand() { return msg } } catch (_: OutOfMemoryError) { - return listOf("GIF处理失败: 内存溢出").toMessageChain() + return MessageChain.Builder().addText("GIF处理失败: 内存溢出").build() logger.info("GIF处理失败: 内存溢出") } catch (e: Exception) { - return listOf("处理GIF失败: ${e.message}").toMessageChain() + return MessageChain.Builder().addText("处理GIF失败: ${e.message}").build() logger.info("gif处理失败: ${e.message}") } } diff --git a/src/main/kotlin/cn/rtast/fancybot/util/CommandInterceptor.kt b/src/main/kotlin/cn/rtast/fancybot/util/CommandInterceptor.kt index 2342686..9144669 100644 --- a/src/main/kotlin/cn/rtast/fancybot/util/CommandInterceptor.kt +++ b/src/main/kotlin/cn/rtast/fancybot/util/CommandInterceptor.kt @@ -12,19 +12,20 @@ import cn.rtast.rob.ROneBotFactory import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.PrivateMessage import cn.rtast.rob.interceptor.ExecutionInterceptor +import cn.rtast.rob.util.BaseCommand import java.io.File -class CommandInterceptor : ExecutionInterceptor { +class CommandInterceptor : ExecutionInterceptor() { companion object { val file = File(ROOT_PATH, "/caches/command_execution_count").apply { createNewFile() } } - override suspend fun afterGroupExecute(message: GroupMessage) { + override suspend fun afterGroupExecute(message: GroupMessage, command: BaseCommand) { file.writeText(ROneBotFactory.totalCommandExecutionTimes.toString()) } - override suspend fun afterPrivateExecute(message: PrivateMessage) { + override suspend fun afterPrivateExecute(message: PrivateMessage, command: BaseCommand) { file.writeText(ROneBotFactory.totalCommandExecutionTimes.toString()) } } \ No newline at end of file