feat: support generate ascii art with reply

This commit is contained in:
2024-10-12 20:59:31 +08:00
parent ff65333a8f
commit 95355d92fe
2 files changed
+87 -51

No files matched your search

+11 -4
View File
@@ -76,19 +76,26 @@ class FancyBot : OneBotListener {
calculateResult?.let { message.reply(calculateResult) } calculateResult?.let { message.reply(calculateResult) }
} }
if (message.message.any { it.type == ArrayMessageType.reply }) { // Image url parse if (message.message.any { it.type == ArrayMessageType.reply }) {
val command = message.message.reversed().find { it.type == ArrayMessageType.text }!!.data.text!! val command = message.message.reversed().find { it.type == ArrayMessageType.text }!!.data.text!!
val replyId = message.message.find { it.type == ArrayMessageType.reply }!!.data.id!! val replyId = message.message.find { it.type == ArrayMessageType.reply }!!.data.id!!
if (command.contains("图来") || command.contains("图链")) {
val getMsg = this.getMessage(replyId.toString().toLong()) val getMsg = this.getMessage(replyId.toString().toLong())
if (command.contains("/ascii") || command.contains("/asc")) {
// 使用回复消息的方式直接对一个图片进行生成Ascii art的操作
val url = AsciiArtCommand.getImageUrl(getMsg)
val image = AsciiArtCommand.generateAsciiArt(url)
message.reply(image)
}
if (command.contains("图来") || command.contains("图链")) {
// 获取一个或多个图片的链接, 并且生成一个或多个短链接
ImageURLCommand.callback(message, getMsg) ImageURLCommand.callback(message, getMsg)
} }
if (command.contains("reaction")) { if (command.contains("reaction")) {
val getMsg = this.getMessage(replyId.toString().toLong()) // 使用reaction刷屏回应一条消息
ReactionCommand.reaction(this, message, getMsg.messageId) ReactionCommand.reaction(this, message, getMsg.messageId)
} }
if (command.contains("图床")) { if (command.contains("图床")) {
val getMsg = this.getMessage(replyId.toString().toLong()) // 将一个图片上传到图床
val imagesUrl = ImageURLCommand.getImageUrl(getMsg) val imagesUrl = ImageURLCommand.getImageUrl(getMsg)
if (imagesUrl.isEmpty()) { if (imagesUrl.isEmpty()) {
message.reply("这个消息里没有图片呢!") message.reply("这个消息里没有图片呢!")
@@ -15,11 +15,13 @@ import cn.rtast.fancybot.util.misc.ImageBed
import cn.rtast.fancybot.util.misc.makeGif import cn.rtast.fancybot.util.misc.makeGif
import cn.rtast.fancybot.util.str.encodeToBase64 import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.fancybot.util.misc.toByteArray import cn.rtast.fancybot.util.misc.toByteArray
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.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener import cn.rtast.rob.util.ob.OneBotListener
import cn.rtast.rob.util.ob.asMessageChain
import com.madgag.gif.fmsware.GifDecoder import com.madgag.gif.fmsware.GifDecoder
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@@ -91,14 +93,7 @@ class AsciiArtCommand : BaseCommand() {
return img return img
} }
suspend fun callback(message: GroupMessage) { suspend fun generateAsciiArt(url: String): MessageChain {
if (message.sender.userId !in waitingList) return
waitingList.removeIf { it == message.sender.userId }
if (message.message.any { it.type == ArrayMessageType.image }
|| message.message.any { it.type == ArrayMessageType.mface }) {
val url = if (message.message.any { it.type == ArrayMessageType.image })
message.message.find { it.type == ArrayMessageType.image }!!.data.file!!
else message.message.find { it.type == ArrayMessageType.mface }!!.data.url!!
val gifStream = withContext(Dispatchers.IO) { URI(url).toURL().openStream() } val gifStream = withContext(Dispatchers.IO) { URI(url).toURL().openStream() }
val decoder = GifDecoder() val decoder = GifDecoder()
try { try {
@@ -113,7 +108,7 @@ class AsciiArtCommand : BaseCommand() {
.addImage(imageBytes.encodeToBase64(), true) .addImage(imageBytes.encodeToBase64(), true)
.addText(imageBedUrl) .addText(imageBedUrl)
.build() .build()
message.reply(msg) return msg
} else { } else {
logger.info("制作GIF Ascii art中, 总帧数: ${decoder.frameCount}") logger.info("制作GIF Ascii art中, 总帧数: ${decoder.frameCount}")
val frames = (0 until decoder.frameCount).map { decoder.getFrame(it) } val frames = (0 until decoder.frameCount).map { decoder.getFrame(it) }
@@ -134,19 +129,53 @@ class AsciiArtCommand : BaseCommand() {
.addImage(gifBase64, true) .addImage(gifBase64, true)
.addText(imageBedUrl) .addText(imageBedUrl)
.build() .build()
message.reply(msg) return msg
} }
} catch (_: OutOfMemoryError) { } catch (_: OutOfMemoryError) {
message.reply("GIF处理失败: 内存溢出") return listOf("GIF处理失败: 内存溢出").asMessageChain()
logger.info("GIF处理失败: 内存溢出") logger.info("GIF处理失败: 内存溢出")
} catch (e: Exception) { } catch (e: Exception) {
message.reply("处理GIF失败: ${e.message}") return listOf("处理GIF失败: ${e.message}").asMessageChain()
logger.info("gif处理失败: ${e.message}") logger.info("gif处理失败: ${e.message}")
} }
}
suspend fun callback(message: GroupMessage) {
if (message.sender.userId !in waitingList) return
waitingList.removeIf { it == message.sender.userId }
if (message.message.any { it.type == ArrayMessageType.image }
|| message.message.any { it.type == ArrayMessageType.mface }) {
val url = this.getImageUrl(message)
val msg = this.generateAsciiArt(url)
message.reply(msg)
} else { } else {
message.reply("回复错误已取消本次操作") message.reply("回复错误已取消本次操作")
} }
} }
fun getImageUrl(groupMessage: GroupMessage): String {
return getImageUrlFromUnified(toUnifiedMessage(groupMessage))
}
fun getImageUrl(getMessageData: GetMessage.Data): String {
return getImageUrlFromUnified(toUnifiedMessage(getMessageData))
}
private fun getImageUrlFromUnified(messages: List<UnifiedMessage>): String {
return if (messages.any { it.type == ArrayMessageType.image })
messages.find { it.type == ArrayMessageType.image }!!.file!!
else messages.find { it.type == ArrayMessageType.mface }!!.url!!
}
private fun toUnifiedMessage(groupMessage: GroupMessage): List<UnifiedMessage> {
return groupMessage.message.map { UnifiedMessage(it.type, it.data.file, it.data.url) }
}
private fun toUnifiedMessage(getMessageData: GetMessage.Data): List<UnifiedMessage> {
return getMessageData.message.map { UnifiedMessage(it.type, it.data.file, it.data.url) }
}
private data class UnifiedMessage(val type: ArrayMessageType, val file: String?, val url: String?)
} }
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) { override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {