mirror of
https://github.com/jie65535/mirai-console-jcf-plugin.git
synced 2025-06-02 17:39:15 +08:00
commit
382b485fa7
@ -1,15 +1,22 @@
|
||||
package top.jie65535.jcf
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import net.mamoe.mirai.event.Event
|
||||
import net.mamoe.mirai.event.EventChannel
|
||||
import net.mamoe.mirai.event.events.MessageEvent
|
||||
import net.mamoe.mirai.event.subscribeMessages
|
||||
import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.message.data.MessageSource.Key.quote
|
||||
import net.mamoe.mirai.utils.ExternalResource.Companion.toExternalResource
|
||||
import net.mamoe.mirai.utils.MiraiLogger
|
||||
import top.jie65535.jcf.model.file.File
|
||||
import top.jie65535.jcf.model.mod.Mod
|
||||
import top.jie65535.jcf.util.PagedList
|
||||
import top.jie65535.jcf.util.HttpUtil
|
||||
import java.text.DecimalFormat
|
||||
import java.util.regex.Pattern
|
||||
import kotlin.math.min
|
||||
|
||||
class MessageHandler(
|
||||
private val service: MinecraftService,
|
||||
@ -28,14 +35,21 @@ class MessageHandler(
|
||||
} else {
|
||||
try {
|
||||
val pagedList = service.search(modClass, filter)
|
||||
handleModsSearchResult(pagedList)
|
||||
val msg = with(pagedList.current()) {
|
||||
if (size == 1) {
|
||||
handleShowMod(get(0))
|
||||
} else {
|
||||
handleModsSearchResult(pagedList)
|
||||
}
|
||||
}
|
||||
subject.sendMessage(msg)
|
||||
} catch (e: Throwable) {
|
||||
subject.sendMessage(message.quote() + "发生内部错误,请稍后重试")
|
||||
logger.error("消息\"$message\"引发异常", e)
|
||||
}
|
||||
}
|
||||
}// if
|
||||
}
|
||||
}
|
||||
}// for
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,31 +60,124 @@ class MessageHandler(
|
||||
val list = pagedList.current() // mod list
|
||||
val hasNext = pagedList.hasNext // 是否有下一页
|
||||
val hasPrev = pagedList.hasPrev // 是否有上一页
|
||||
TODO("将搜索列表转为QQ消息")
|
||||
return buildForwardMessage {
|
||||
bot says "30秒内回复编号查看"
|
||||
for ((x, mod) in list.withIndex()) {
|
||||
bot.id named x.toString() says PlainText(
|
||||
"""
|
||||
[${mod.name}] by ${mod.authors[0].name}
|
||||
${formatCount(mod.downloadCount)} Downloads Updated ${mod.dateModified.toLocalDate()}
|
||||
${mod.summary}
|
||||
${mod.links.websiteUrl}
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
var tmp = "回复:"
|
||||
if (hasPrev) tmp += "[P]上一页 "
|
||||
if (hasNext) tmp += "[N]下一页"
|
||||
bot says tmp
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理展示单个mod
|
||||
*/
|
||||
private fun handleShowMod(mod: Mod): Message {
|
||||
TODO("将mod转为QQ消息")
|
||||
private suspend fun MessageEvent.handleShowMod(mod: Mod): Message {
|
||||
return buildForwardMessage {
|
||||
// logo
|
||||
mod.logo.thumbnailUrl?.let {
|
||||
if (it.isNotBlank()) bot says loadImage(it)
|
||||
}
|
||||
// basic info
|
||||
bot says PlainText(with(mod) {
|
||||
"""
|
||||
$name
|
||||
作者:${authors[0].name}
|
||||
概括:$summary
|
||||
项目ID:$id
|
||||
创建时间:${dateCreated.toLocalDate()}
|
||||
最近更新:${dateModified.toLocalDate()}
|
||||
总下载:$downloadCount
|
||||
""".trimIndent()
|
||||
})
|
||||
// links
|
||||
bot says PlainText(with(mod.links) {
|
||||
"""
|
||||
主页:$websiteUrl
|
||||
支持页:$issuesUrl
|
||||
wiki:$wikiUrl
|
||||
开源页:$sourceUrl
|
||||
""".trimIndent()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理模组文件列表
|
||||
*/
|
||||
private suspend fun handleModFileList(pagedList: PagedList<File>): Message {
|
||||
private suspend fun MessageEvent.handleModFileList(pagedList: PagedList<File>): Message {
|
||||
val list = pagedList.current() // mod list
|
||||
val hasNext = pagedList.hasNext // 是否有下一页
|
||||
val hasPrev = pagedList.hasPrev // 是否有上一页
|
||||
TODO("将文件列表转为QQ消息")
|
||||
return buildForwardMessage {
|
||||
bot says "30秒内回复编号查看"
|
||||
for ((x, file) in list.withIndex()) {
|
||||
bot.id named x.toString() says PlainText(
|
||||
"""
|
||||
${file.displayName} [${file.releaseType}] [${file.fileDate.toLocalDate()}]
|
||||
${file.downloadUrl}
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
var tmp = "回复:"
|
||||
if (hasPrev) tmp += "[P]上一页 "
|
||||
if (hasNext) tmp += "[N]下一页"
|
||||
bot says tmp
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理模组文件更改日志
|
||||
* @param changelog 更改日志(HTML)
|
||||
*/
|
||||
private fun handleModFileChangelog(changelog: String): Message {
|
||||
TODO("将文件更改日志渲染为QQ消息")
|
||||
private fun MessageEvent.handleModFileChangelog(changelog: String): Message {
|
||||
val logs = HTMLPattern.matcher(changelog).replaceAll("")
|
||||
return sendLargeMessage(logs)
|
||||
}
|
||||
}
|
||||
|
||||
private val singleDecimalFormat = DecimalFormat("0.#")
|
||||
|
||||
private fun formatCount(count: Long): String = when {
|
||||
count < 1000000 -> singleDecimalFormat.format(count / 1000) + "K"
|
||||
count < 1000000000 -> singleDecimalFormat.format(count / 1000000) + "M"
|
||||
else -> count.toString()
|
||||
}
|
||||
|
||||
private suspend fun MessageEvent.loadImage(url: String): Image {
|
||||
val imgFileName = url.substringAfterLast("/")
|
||||
val file = PluginMain.resolveDataFile("cache/$imgFileName")
|
||||
val res = if (file.exists()) {
|
||||
file.readBytes().toExternalResource()
|
||||
} else {
|
||||
HttpUtil.downloadImage(url, file).toExternalResource()
|
||||
}
|
||||
val image = subject.uploadImage(res)
|
||||
withContext(Dispatchers.IO) {
|
||||
res.close()
|
||||
}
|
||||
return image
|
||||
}
|
||||
|
||||
private val HTMLPattern = Pattern.compile("<[^>]+>", Pattern.CASE_INSENSITIVE)
|
||||
private val ONE_GRP_SIZE = 5000
|
||||
private val ONE_MSG_SIZE = 500
|
||||
fun MessageEvent.sendLargeMessage(message: String): Message {
|
||||
return buildForwardMessage {
|
||||
for (g in message.indices step ONE_GRP_SIZE) {
|
||||
for (i in g until g + min(ONE_GRP_SIZE, message.length - g) step ONE_MSG_SIZE) {
|
||||
bot says PlainText(message.subSequence(i, i + (min(ONE_MSG_SIZE, message.length - i))))
|
||||
}
|
||||
}
|
||||
}
|
||||
}// fun
|
||||
}
|
||||
|
29
src/main/kotlin/top/jie65535/jcf/util/HttpUtil.kt
Normal file
29
src/main/kotlin/top/jie65535/jcf/util/HttpUtil.kt
Normal file
@ -0,0 +1,29 @@
|
||||
package top.jie65535.jcf.util
|
||||
|
||||
//import okhttp3.MediaType
|
||||
//import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import java.io.File
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
object HttpUtil {
|
||||
// private val JSON: MediaType? = "application/json; charset=utf-8".toMediaTypeOrNull()
|
||||
private val okHttpClient: OkHttpClient by lazy {
|
||||
OkHttpClient.Builder()
|
||||
.readTimeout(10, TimeUnit.SECONDS)
|
||||
.build()
|
||||
}
|
||||
|
||||
/**
|
||||
* ### 下载图片
|
||||
*/
|
||||
fun downloadImage(url: String, file: File): ByteArray {
|
||||
val request = Request.Builder().url(url).build()
|
||||
val imageByte = okHttpClient.newCall(request).execute().body!!.bytes()
|
||||
val fileParent = file.parentFile
|
||||
if (!fileParent.exists()) fileParent.mkdirs()
|
||||
file.writeBytes(imageByte)
|
||||
return imageByte
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user