From 367f07a6fc2bbc0ba48376779c4ce87baa5d3330 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Tue, 21 Apr 2020 15:18:14 +0800 Subject: [PATCH] Automatic login; Some amendments to the bot manager (#65) * Betty tryNTimes * UTF8 * Automatic login; Some modifications about BotManager * Make `internal` and rename --- build.gradle.kts | 4 + mirai-console/build.gradle.kts | 5 +- .../net/mamoe/mirai/console/utils/Utils.java | 29 ++-- .../net/mamoe/mirai/console/MiraiConsole.kt | 3 + .../mirai/console/command/DefaultCommands.kt | 153 ++++++++++-------- .../mamoe/mirai/console/utils/BotHelper.kt | 17 +- 6 files changed, 129 insertions(+), 82 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 4c85decf8..e21f6c092 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,6 +2,10 @@ import kotlin.math.pow +tasks.withType(JavaCompile::class.java) { + options.encoding = "UTF8" +} + buildscript { repositories { maven(url = "https://dl.bintray.com/kotlin/kotlin-eap") diff --git a/mirai-console/build.gradle.kts b/mirai-console/build.gradle.kts index 126d48652..5ea5e70a3 100644 --- a/mirai-console/build.gradle.kts +++ b/mirai-console/build.gradle.kts @@ -106,4 +106,7 @@ compileTestKotlin.kotlinOptions { java { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 -} \ No newline at end of file +} +tasks.withType(JavaCompile::class.java) { + options.encoding = "UTF8" +} diff --git a/mirai-console/src/main/java/net/mamoe/mirai/console/utils/Utils.java b/mirai-console/src/main/java/net/mamoe/mirai/console/utils/Utils.java index 47455af79..72f9d3f2a 100644 --- a/mirai-console/src/main/java/net/mamoe/mirai/console/utils/Utils.java +++ b/mirai-console/src/main/java/net/mamoe/mirai/console/utils/Utils.java @@ -10,26 +10,29 @@ public class Utils { * 否则就会throw */ public static T tryNTimes( + /*@Range(from=1, to=Integer.MAX_VALUE)*/ int n, Callable callable ) throws Exception { - - T result = null; + if (n < 0) { + throw new IllegalArgumentException("Must be executed at least once."); + } Exception last = null; - while(n-- > 0){ - try{ - result = callable.call(); - break; - }catch(Exception e){last=e;} + while (n-- > 0) { + try { + return callable.call(); + } catch (Exception e) { + if (last == null) { + last = e; + } else { + last.addSuppressed(e); + } + } } - if(result != null){ - return result; - } - - if(last == null){ - last = new Exception("unknown error"); + if (last == null) { + throw new Exception("unknown error"); } throw last; diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt index 3a82a279a..53f76f3de 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt @@ -94,6 +94,9 @@ object MiraiConsole { logger("Mirai-console 启动完成") logger("\"/login qqnumber qqpassword \" to login a bot") logger("\"/login qq号 qq密码 \" 来登录一个BOT") + + /* 尝试从系统配置自动登录 */ + DefaultCommands.tryLoginAuto() } /** 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 104e6071f..ae61909de 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 @@ -9,14 +9,13 @@ package net.mamoe.mirai.console.command +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch import net.mamoe.mirai.Bot import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.center.PluginCenter import net.mamoe.mirai.console.plugins.PluginManager -import net.mamoe.mirai.console.utils.addManager -import net.mamoe.mirai.console.utils.checkManager -import net.mamoe.mirai.console.utils.managers -import net.mamoe.mirai.console.utils.removeManager +import net.mamoe.mirai.console.utils.* import net.mamoe.mirai.contact.sendMessage import net.mamoe.mirai.event.subscribeMessages import net.mamoe.mirai.getFriendOrNull @@ -30,6 +29,69 @@ import java.util.* */ object DefaultCommands { + private suspend fun CommandSender.login(account: Long, password: String) { + MiraiConsole.logger("[Bot Login]", 0, "login...") + try { + MiraiConsole.frontEnd.prePushBot(account) + val bot = Bot(account, password) { + fileBasedDeviceInfo() + this.loginSolver = MiraiConsole.frontEnd.createLoginSolver() + this.botLoggerSupplier = { + SimpleLogger("BOT $account]") { _, message, e -> + MiraiConsole.logger("[BOT $account]", account, message) + if (e != null) { + MiraiConsole.logger("[NETWORK ERROR]", account, e)//因为在一页 所以可以不打QQ + } + } + } + this.networkLoggerSupplier = { + SimpleLogger("BOT $account") { _, message, e -> + MiraiConsole.logger("[NETWORK]", account, message)//因为在一页 所以可以不打QQ + if (e != null) { + MiraiConsole.logger("[NETWORK ERROR]", account, e)//因为在一页 所以可以不打QQ + } + } + } + } + bot.login() + bot.subscribeMessages { + startsWith("/") { message -> + if (bot.checkManager(this.sender.id)) { + val sender = if (this is GroupMessage) { + GroupContactCommandSender(this.sender, this.subject) + } else { + ContactCommandSender(this.subject) + } + CommandManager.runCommand( + sender, message + ) + } + } + } + sendMessage("$account login successes") + MiraiConsole.frontEnd.pushBot(bot) + } catch (e: Exception) { + sendMessage("$account login failed -> " + e.message) + } + } + + private fun String.property(): String? = System.getProperty(this) + + @JvmSynthetic + internal fun tryLoginAuto() { + // For java -Dmirai.account=10086 -Dmirai.password=Password -jar mirai-console-wrapper-X.jar + 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") + return + } + GlobalScope.launch { + ConsoleCommandSender.login(account, password) + } + } + operator fun invoke() { registerConsoleCommands { name = "manager" @@ -68,8 +130,11 @@ object DefaultCommands { MiraiConsole.logger("[Bot Manager]", 0, it[2] + " 不是一个ID") return@onCommand false } - bot.addManager(adminID) - MiraiConsole.logger("[Bot Manager]", 0, it[2] + "增加成功") + if (bot.addManager(adminID)) { + MiraiConsole.logger("[Bot Manager]", 0, it[2] + "增加成功") + } else { + MiraiConsole.logger("[Bot Manager]", 0, it[2] + "已经是一个manager了") + } } "remove" -> { if (it.size < 3) { @@ -99,7 +164,7 @@ object DefaultCommands { } } - registerConsoleCommands{ + registerConsoleCommands { name = "login" description = "机器人登录" onCommand { @@ -114,49 +179,7 @@ object DefaultCommands { } val qqNumber = it[0].toLong() val qqPassword = it[1] - MiraiConsole.logger("[Bot Login]", 0, "login...") - try { - MiraiConsole.frontEnd.prePushBot(qqNumber) - val bot = Bot(qqNumber, qqPassword) { - fileBasedDeviceInfo() - this.loginSolver = MiraiConsole.frontEnd.createLoginSolver() - this.botLoggerSupplier = { - SimpleLogger("BOT $qqNumber]") { _, message, e -> - MiraiConsole.logger("[BOT $qqNumber]", qqNumber, message) - if (e != null) { - MiraiConsole.logger("[NETWORK ERROR]", qqNumber, e)//因为在一页 所以可以不打QQ - } - } - } - this.networkLoggerSupplier = { - SimpleLogger("BOT $qqNumber") { _, message, e -> - MiraiConsole.logger("[NETWORK]", qqNumber, message)//因为在一页 所以可以不打QQ - if (e != null) { - MiraiConsole.logger("[NETWORK ERROR]", qqNumber, e)//因为在一页 所以可以不打QQ - } - } - } - } - bot.login() - bot.subscribeMessages { - startsWith("/") { message -> - if (bot.checkManager(this.sender.id)) { - val sender = if(this is GroupMessage) { - GroupContactCommandSender(this.sender,this.subject) - }else{ - ContactCommandSender(this.subject) - } - CommandManager.runCommand( - sender, message - ) - } - } - } - sendMessage("$qqNumber login successes") - MiraiConsole.frontEnd.pushBot(bot) - } catch (e: Exception) { - sendMessage("$qqNumber login failed -> " + e.message) - } + login(qqNumber, qqPassword) true } } @@ -278,7 +301,7 @@ object DefaultCommands { name = "reload" alias = listOf("reloadPlugins") description = "重新加载全部插件" - onCommand{ + onCommand { PluginManager.reloadPlugins() sendMessage("重新加载完成") true @@ -293,7 +316,7 @@ object DefaultCommands { val center = PluginCenter.Default - suspend fun showPage(num:Int){ + suspend fun showPage(num: Int) { sendMessage("正在连接" + center.name) val list = PluginCenter.Default.fetchPlugin(num) appendMessage("\n") @@ -302,36 +325,36 @@ object DefaultCommands { } } - suspend fun installPlugin(name: String){ + suspend fun installPlugin(name: String) { sendMessage("正在连接" + center.name) val plugin = center.findPlugin(name) - if(plugin == null){ + if (plugin == null) { sendMessage("插件未找到, 请注意大小写") return } sendMessage("正在安装" + plugin.name) - try{ - center.downloadPlugin(name){} + try { + center.downloadPlugin(name) {} sendMessage("安装" + plugin.name + "成功") - }catch (e: Exception){ - sendMessage("安装" + plugin.name + "失败, " + (e.message?:"未知原因")) + } catch (e: Exception) { + sendMessage("安装" + plugin.name + "失败, " + (e.message ?: "未知原因")) } } - if(it.isEmpty()){ + if (it.isEmpty()) { showPage(1) - }else{ + } else { val arg = it[0] - val id = try{ - arg.toInt() - }catch (e:Exception){ + val id = try { + arg.toInt() + } catch (e: Exception) { 0 } - if(id > 0){ + if (id > 0) { showPage(id) - }else{ + } else { installPlugin(arg) } } diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/BotHelper.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/BotHelper.kt index fdffe1f3b..cd324888c 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/BotHelper.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/BotHelper.kt @@ -23,11 +23,22 @@ internal object BotManagers { val BOT_MANAGERS: ConfigSection by config.withDefaultWriteSave { ConfigSectionImpl() } } -fun Bot.addManager(long: Long) { +@JvmName("addManager") +@JvmSynthetic +@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN) +fun Bot.addManagerDeprecated(long: Long) { + addManager(long) +} + +fun Bot.addManager(long: Long): Boolean { BOT_MANAGERS.putIfAbsent(this.id.toString(), mutableListOf()) BOT_MANAGERS[this.id.toString()] = - (BOT_MANAGERS.getLongList(this.id.toString()) as MutableList).apply { add(long) } + (BOT_MANAGERS.getLongList(this.id.toString()) as MutableList).apply { + if (contains(long)) return@addManager false + add(long) + } BotManagers.config.save() + return true } fun Bot.removeManager(long: Long) { @@ -48,6 +59,6 @@ fun Bot.checkManager(long: Long): Boolean { } -fun getBotManagers(bot:Bot):List{ +fun getBotManagers(bot: Bot): List { return bot.managers }