feat: add split frame and upgrade ronebot to 2.5.2
This commit is contained in:
5 files changed
+48
-31
No files matched your search
@@ -1,6 +1,6 @@
|
|||||||
[versions]
|
[versions]
|
||||||
kotlinVersion = "2.0.20"
|
kotlinVersion = "2.0.20"
|
||||||
ronebotVersion = "2.4.8"
|
ronebotVersion = "2.5.2"
|
||||||
shadowVersion = "8.3.0"
|
shadowVersion = "8.3.0"
|
||||||
okhttpVersion = "5.0.0-alpha.14"
|
okhttpVersion = "5.0.0-alpha.14"
|
||||||
exposedVersion = "0.53.0"
|
exposedVersion = "0.53.0"
|
||||||
|
|||||||
@@ -18,19 +18,10 @@ import cn.rtast.fancybot.commands.reply.InvertImageCommand
|
|||||||
import cn.rtast.fancybot.commands.reply.RandomRGBCommand
|
import cn.rtast.fancybot.commands.reply.RandomRGBCommand
|
||||||
import cn.rtast.fancybot.commands.reply.SpeedUpGIFCommand
|
import cn.rtast.fancybot.commands.reply.SpeedUpGIFCommand
|
||||||
import cn.rtast.fancybot.enums.WSType
|
import cn.rtast.fancybot.enums.WSType
|
||||||
import cn.rtast.fancybot.util.*
|
import cn.rtast.fancybot.util.CommandInterceptor
|
||||||
import cn.rtast.fancybot.util.misc.ImageBed
|
import cn.rtast.fancybot.util.Logger
|
||||||
import cn.rtast.fancybot.util.misc.convertToDate
|
import cn.rtast.fancybot.util.initDatabase
|
||||||
import cn.rtast.fancybot.util.misc.initBackgroundTasks
|
import cn.rtast.fancybot.util.misc.*
|
||||||
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.str.encodeToBase64
|
import cn.rtast.fancybot.util.str.encodeToBase64
|
||||||
import cn.rtast.rob.ROneBotFactory
|
import cn.rtast.rob.ROneBotFactory
|
||||||
import cn.rtast.rob.entity.*
|
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.MessageChain
|
||||||
import cn.rtast.rob.onebot.OneBotAction
|
import cn.rtast.rob.onebot.OneBotAction
|
||||||
import cn.rtast.rob.onebot.OneBotListener
|
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 com.madgag.gif.fmsware.GifDecoder
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.Dispatchers
|
import java.io.ByteArrayOutputStream
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
import java.util.zip.ZipEntry
|
||||||
|
import java.util.zip.ZipOutputStream
|
||||||
|
import javax.imageio.ImageIO
|
||||||
|
|
||||||
class FancyBot : OneBotListener {
|
class FancyBot : OneBotListener {
|
||||||
|
|
||||||
@@ -166,6 +159,30 @@ class FancyBot : OneBotListener {
|
|||||||
}
|
}
|
||||||
message.reply(msg.build())
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,10 +49,10 @@ import cn.rtast.rcon.exceptions.AuthFailedException
|
|||||||
import cn.rtast.rob.entity.GroupMessage
|
import cn.rtast.rob.entity.GroupMessage
|
||||||
import cn.rtast.rob.entity.PrivateMessage
|
import cn.rtast.rob.entity.PrivateMessage
|
||||||
import cn.rtast.rob.onebot.MessageChain
|
import cn.rtast.rob.onebot.MessageChain
|
||||||
import cn.rtast.rob.onebot.toMessageChain
|
|
||||||
import cn.rtast.rob.onebot.toNode
|
import cn.rtast.rob.onebot.toNode
|
||||||
import cn.rtast.rob.segment.NewLine
|
import cn.rtast.rob.segment.NewLine
|
||||||
import cn.rtast.rob.segment.Text
|
import cn.rtast.rob.segment.Text
|
||||||
|
import cn.rtast.rob.segment.toMessageChain
|
||||||
import cn.rtast.rob.util.BaseCommand
|
import cn.rtast.rob.util.BaseCommand
|
||||||
import okhttp3.FormBody
|
import okhttp3.FormBody
|
||||||
import java.awt.AlphaComposite
|
import java.awt.AlphaComposite
|
||||||
@@ -99,7 +99,7 @@ class MinecraftWikiCommand : BaseCommand() {
|
|||||||
"s", "搜索" -> {
|
"s", "搜索" -> {
|
||||||
val searchKeyword = args.drop(1).joinToString(" ").trim()
|
val searchKeyword = args.drop(1).joinToString(" ").trim()
|
||||||
val messages = mutableListOf<MessageChain>()
|
val messages = mutableListOf<MessageChain>()
|
||||||
val headerMessage = listOf("结果如下:").toMessageChain()
|
val headerMessage = MessageChain.Builder().addText("结果如下:").build()
|
||||||
messages.add(headerMessage)
|
messages.add(headerMessage)
|
||||||
Http.get<MCWikiSearchResponse>(
|
Http.get<MCWikiSearchResponse>(
|
||||||
"$baseApiUrl/search/title",
|
"$baseApiUrl/search/title",
|
||||||
@@ -134,7 +134,7 @@ class MinecraftWikiCommand : BaseCommand() {
|
|||||||
response = Http.get<MCWikiPageResponse>(response.redirectTarget)
|
response = Http.get<MCWikiPageResponse>(response.redirectTarget)
|
||||||
}
|
}
|
||||||
val messages = mutableListOf<MessageChain>()
|
val messages = mutableListOf<MessageChain>()
|
||||||
val headerMsg = listOf("标题${response.title}的内容如下").toMessageChain()
|
val headerMsg = MessageChain.Builder().addText("标题${response.title}的内容如下").build()
|
||||||
val footerMsg = listOf(
|
val footerMsg = listOf(
|
||||||
Text("数据来源: https://zh.minecraft.wiki"),
|
Text("数据来源: https://zh.minecraft.wiki"),
|
||||||
NewLine(),
|
NewLine(),
|
||||||
@@ -551,7 +551,7 @@ class RCONCommand : BaseCommand() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
val messages = mutableListOf<MessageChain>()
|
val messages = mutableListOf<MessageChain>()
|
||||||
.also { it.add(listOf("所有配置如下").toMessageChain()) }
|
.also { it.add(MessageChain.Builder().addText("所有配置如下").build()) }
|
||||||
allRcons.forEach {
|
allRcons.forEach {
|
||||||
val msg = MessageChain.Builder()
|
val msg = MessageChain.Builder()
|
||||||
.addText("名称: ${it.name}")
|
.addText("名称: ${it.name}")
|
||||||
@@ -594,8 +594,8 @@ class RCONCommand : BaseCommand() {
|
|||||||
try {
|
try {
|
||||||
val result = rconManager.executeCommand(message.sender.userId, name, command)
|
val result = rconManager.executeCommand(message.sender.userId, name, command)
|
||||||
val messages = mutableListOf<MessageChain>()
|
val messages = mutableListOf<MessageChain>()
|
||||||
.also { it.add(listOf("执行结果如下").toMessageChain()) }
|
.also { it.add(MessageChain.Builder().addText("执行结果如下").build()) }
|
||||||
.also { it.add(listOf(result).toMessageChain()) }
|
.also { it.add(MessageChain.Builder().addText(result).build()) }
|
||||||
.toNode(configManager.selfId)
|
.toNode(configManager.selfId)
|
||||||
message.reply(messages)
|
message.reply(messages)
|
||||||
} catch (_: AuthFailedException) {
|
} catch (_: AuthFailedException) {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import cn.rtast.rob.entity.GetMessage
|
|||||||
import cn.rtast.rob.entity.GroupMessage
|
import cn.rtast.rob.entity.GroupMessage
|
||||||
import cn.rtast.rob.enums.ArrayMessageType
|
import cn.rtast.rob.enums.ArrayMessageType
|
||||||
import cn.rtast.rob.onebot.MessageChain
|
import cn.rtast.rob.onebot.MessageChain
|
||||||
import cn.rtast.rob.onebot.toMessageChain
|
|
||||||
import cn.rtast.rob.util.BaseCommand
|
import cn.rtast.rob.util.BaseCommand
|
||||||
import com.madgag.gif.fmsware.GifDecoder
|
import com.madgag.gif.fmsware.GifDecoder
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -131,10 +130,10 @@ class AsciiArtCommand : BaseCommand() {
|
|||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
} catch (_: OutOfMemoryError) {
|
} catch (_: OutOfMemoryError) {
|
||||||
return listOf("GIF处理失败: 内存溢出").toMessageChain()
|
return MessageChain.Builder().addText("GIF处理失败: 内存溢出").build()
|
||||||
logger.info("GIF处理失败: 内存溢出")
|
logger.info("GIF处理失败: 内存溢出")
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
return listOf("处理GIF失败: ${e.message}").toMessageChain()
|
return MessageChain.Builder().addText("处理GIF失败: ${e.message}").build()
|
||||||
logger.info("gif处理失败: ${e.message}")
|
logger.info("gif处理失败: ${e.message}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,19 +12,20 @@ import cn.rtast.rob.ROneBotFactory
|
|||||||
import cn.rtast.rob.entity.GroupMessage
|
import cn.rtast.rob.entity.GroupMessage
|
||||||
import cn.rtast.rob.entity.PrivateMessage
|
import cn.rtast.rob.entity.PrivateMessage
|
||||||
import cn.rtast.rob.interceptor.ExecutionInterceptor
|
import cn.rtast.rob.interceptor.ExecutionInterceptor
|
||||||
|
import cn.rtast.rob.util.BaseCommand
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class CommandInterceptor : ExecutionInterceptor {
|
class CommandInterceptor : ExecutionInterceptor() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val file = File(ROOT_PATH, "/caches/command_execution_count").apply { createNewFile() }
|
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())
|
file.writeText(ROneBotFactory.totalCommandExecutionTimes.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun afterPrivateExecute(message: PrivateMessage) {
|
override suspend fun afterPrivateExecute(message: PrivateMessage, command: BaseCommand) {
|
||||||
file.writeText(ROneBotFactory.totalCommandExecutionTimes.toString())
|
file.writeText(ROneBotFactory.totalCommandExecutionTimes.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user