diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/center/CuiPluginCenter.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/center/CuiPluginCenter.kt index 4704e95b2..394f9c2e5 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/center/CuiPluginCenter.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/center/CuiPluginCenter.kt @@ -3,39 +3,41 @@ package net.mamoe.mirai.console.center import com.google.gson.JsonArray import com.google.gson.JsonObject import com.google.gson.JsonParser +import io.ktor.client.HttpClient +import io.ktor.client.engine.cio.CIO +import io.ktor.client.request.get +import io.ktor.util.KtorExperimentalAPI import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import net.mamoe.mirai.console.plugins.PluginManager +import net.mamoe.mirai.console.utils.retryCatching import net.mamoe.mirai.console.utils.tryNTimes -import org.jsoup.Connection -import org.jsoup.Jsoup import java.io.File import java.io.FileOutputStream import java.net.HttpURLConnection import java.net.URL -import kotlin.system.exitProcess -internal object CuiPluginCenter: PluginCenter{ +internal object CuiPluginCenter : PluginCenter { - var plugins:JsonArray? = null + var plugins: JsonArray? = null /** * 一页10个吧,pageMinNum=1 */ override suspend fun fetchPlugin(page: Int): Map { check(page > 0) - val startIndex = (page-1)*10 - val endIndex = startIndex+9 + val startIndex = (page - 1) * 10 + val endIndex = startIndex + 9 val map = mutableMapOf() (startIndex until endIndex).forEach { - if(plugins == null){ + if (plugins == null) { refresh() } - if(it >= plugins!!.size()){ + if (it >= plugins!!.size()) { return@forEach } val info = plugins!![it] - with(info.asJsonObject){ + with(info.asJsonObject) { map[this.get("name").asString] = PluginCenter.PluginInsight( this.get("name")?.asString ?: "", this.get("version")?.asString ?: "", @@ -51,22 +53,21 @@ internal object CuiPluginCenter: PluginCenter{ return map } + @OptIn(KtorExperimentalAPI::class) + private val Http = HttpClient(CIO) + override suspend fun findPlugin(name: String): PluginCenter.PluginInfo? { - val result = withContext(Dispatchers.IO){ - tryNTimes { - Jsoup - .connect("https://miraiapi.jasonczc.cn/getPluginDetailedInfo?name=$name") - .method(Connection.Method.GET) - .ignoreContentType(true) - .execute() - } - }.body() + val result = retryCatching(3) { + Http.get("https://miraiapi.jasonczc.cn/getPluginDetailedInfo?name=$name") + }.recover { + return null + }.getOrNull() ?: return null - if(result == "err:not found"){ + if (result == "err:not found") { return null } - return result.asJson().run{ + return result.asJson().run { PluginCenter.PluginInfo( this.get("name")?.asString ?: "", this.get("version")?.asString ?: "", @@ -86,23 +87,15 @@ internal object CuiPluginCenter: PluginCenter{ } override suspend fun refresh() { - val results = - withContext(Dispatchers.IO) { - tryNTimes { - Jsoup - .connect("https://miraiapi.jasonczc.cn/getPluginList") - .ignoreContentType(true) - .execute() - } - }.body().asJson() - - if(!(results.has("success") && results["success"].asBoolean)){ + val results = Http.get("https://miraiapi.jasonczc.cn/getPluginList").asJson() + + if (!(results.has("success") && results["success"].asBoolean)) { error("Failed to fetch plugin list from Cui Cloud") } plugins = results.get("result").asJsonArray//先不解析 } - override suspend fun T.downloadPlugin(name: String, progressListener: T.(Float) -> Unit):File{ + override suspend fun T.downloadPlugin(name: String, progressListener: T.(Float) -> Unit): File { val info = findPlugin(name) ?: error("Plugin Not Found") val targetFile = File(PluginManager.pluginsPath, "$name-" + info.version + ".jar") withContext(Dispatchers.IO) { @@ -129,7 +122,7 @@ internal object CuiPluginCenter: PluginCenter{ get() = "崔云" - fun String.asJson(): JsonObject { + private fun String.asJson(): JsonObject { return JsonParser.parseString(this).asJsonObject } diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/center/PluginCenter.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/center/PluginCenter.kt index 16994cf8b..e16ec513a 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/center/PluginCenter.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/center/PluginCenter.kt @@ -42,8 +42,8 @@ interface PluginCenter { suspend fun fetchPlugin(page: Int): Map /** - * 尝试获取到某个插件by全名, case sensitive - * null则没有 + * 尝试获取到某个插件 by 全名, case sensitive + * null 则没有 */ suspend fun findPlugin(name:String):PluginInfo? diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/DefaultCommands.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/DefaultCommands.kt index 1c47126e4..bfb6720e9 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/DefaultCommands.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/DefaultCommands.kt @@ -12,6 +12,7 @@ package net.mamoe.mirai.console.command import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import net.mamoe.mirai.Bot +import net.mamoe.mirai.Bot.Companion.botInstances import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.center.PluginCenter import net.mamoe.mirai.console.plugins.PluginManager @@ -86,8 +87,10 @@ object DefaultCommands { val account = ("mirai.account".property() ?: return).toLong() val password = "mirai.password".property() ?: "mirai.passphrase".property() ?: "mirai.passwd".property() if (password == null) { - MiraiConsole.logger.invoke(SimpleLogger.LogPriority.ERROR, "[AUTO LOGIN]", account, - "Find the account to be logged in, but no password specified") + MiraiConsole.logger.invoke( + SimpleLogger.LogPriority.ERROR, "[AUTO LOGIN]", account, + "Find the account to be logged in, but no password specified" + ) return } GlobalScope.launch { @@ -193,12 +196,12 @@ object DefaultCommands { onCommand { args -> when (args.size) { 0 -> { - sendMessage("当前有" + MiraiConsole.bots.size + "个BOT在线") + sendMessage("当前有" + botInstances.size + "个BOT在线") } 1 -> { val bot = args[0] var find = false - MiraiConsole.bots.forEach { + botInstances.forEach { if (it.id.toString().contains(bot)) { find = true appendMessage( @@ -226,11 +229,11 @@ object DefaultCommands { return@onCommand false } val bot: Bot? = if (it.size == 2) { - if (MiraiConsole.bots.isEmpty()) { + if (botInstances.isEmpty()) { MiraiConsole.logger("还没有BOT登录") return@onCommand false } - MiraiConsole.bots[0] + botInstances[0] } else { MiraiConsole.getBotOrNull(it[0].toLong()) } @@ -319,27 +322,33 @@ object DefaultCommands { val center = PluginCenter.Default suspend fun showPage(num: Int) { - sendMessage("正在连接" + center.name) + sendMessage("正在连接 " + center.name) val list = PluginCenter.Default.fetchPlugin(num) + if (list.isEmpty()) { + sendMessage("页码过大") + return + } + sendMessage("显示插件列表第 $num 页") appendMessage("\n") list.values.forEach { - appendMessage("=>" + it.name + " ;作者: " + it.author + " ;介绍: " + it.description) + appendMessage("=> " + it.name + " ;作者: " + it.author + " ;介绍: " + it.description) } + sendMessage("使用 /install ${num + 1} 查看下一页") } suspend fun installPlugin(name: String) { - sendMessage("正在连接" + center.name) + sendMessage("正在连接 " + center.name) val plugin = center.findPlugin(name) if (plugin == null) { sendMessage("插件未找到, 请注意大小写") return } - sendMessage("正在安装" + plugin.name) + sendMessage("正在安装 " + plugin.name) try { center.downloadPlugin(name) {} - sendMessage("安装" + plugin.name + "成功") + sendMessage("安装 " + plugin.name + " 成功, 请重启服务器以更新") } catch (e: Exception) { - sendMessage("安装" + plugin.name + "失败, " + (e.message ?: "未知原因")) + sendMessage("安装 " + plugin.name + " 失败, " + (e.message ?: "未知原因")) } } @@ -348,12 +357,7 @@ object DefaultCommands { } else { val arg = args[0] - val id = try { - arg.toInt() - } catch (e: Exception) { - 0 - } - + val id = arg.toIntOrNull() ?: 0 if (id > 0) { showPage(id) } else {