From 74353d1aafc6f105e2c26fcb258a119ce822ae28 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 22 Aug 2020 01:38:32 +0800 Subject: [PATCH] Fix various bugs --- .../mirai/console/command/BuiltInCommands.kt | 68 ++++--------------- .../mirai/console/command/CommandManager.kt | 3 + .../console/command/CommandManagerImpl.kt | 7 +- .../CommandPermissionDeniedException.kt | 3 +- .../mamoe/mirai/console/command/RawCommand.kt | 2 +- .../mirai/console/command/SimpleCommand.kt | 35 ++++++++-- 6 files changed, 57 insertions(+), 61 deletions(-) diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/BuiltInCommands.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/BuiltInCommands.kt index 9cf52e96f..4a47c22fc 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/BuiltInCommands.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/BuiltInCommands.kt @@ -11,65 +11,28 @@ package net.mamoe.mirai.console.command import kotlinx.coroutines.cancel import kotlinx.coroutines.cancelAndJoin +import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock -import net.mamoe.mirai.Bot import net.mamoe.mirai.alsoLogin import net.mamoe.mirai.console.MiraiConsole -import net.mamoe.mirai.console.command.Command.Companion.primaryName import net.mamoe.mirai.console.command.CommandManagerImpl.allRegisteredCommands import net.mamoe.mirai.console.command.CommandManagerImpl.register -import net.mamoe.mirai.event.selectMessagesUnit -import net.mamoe.mirai.utils.DirectoryLogger -import net.mamoe.mirai.utils.weeksToMillis -import java.io.File +import net.mamoe.mirai.console.util.ConsoleExperimentalAPI +import net.mamoe.mirai.message.nextMessageOrNull +import net.mamoe.mirai.utils.secondsToMillis import kotlin.concurrent.thread import kotlin.system.exitProcess -/** - * 添加一个 [Bot] 实例到全局 Bot 列表, 但不登录. - */ -public fun MiraiConsole.addBot(id: Long, password: String): Bot { - return Bot(id, password) { - - /** - * 重定向 [网络日志][networkLoggerSupplier] 到指定目录. 若目录不存在将会自动创建 ([File.mkdirs]) - * @see DirectoryLogger - * @see redirectNetworkLogToDirectory - */ - fun redirectNetworkLogToDirectory( - dir: File = File("logs"), - retain: Long = 1.weeksToMillis, - identity: (bot: Bot) -> String = { "Net ${it.id}" } - ) { - require(!dir.isFile) { "dir must not be a file" } - dir.mkdirs() - networkLoggerSupplier = { DirectoryLogger(identity(it), dir, retain) } - } - - fun redirectBotLogToDirectory( - dir: File = File("logs"), - retain: Long = 1.weeksToMillis, - identity: (bot: Bot) -> String = { "Net ${it.id}" } - ) { - require(!dir.isFile) { "dir must not be a file" } - dir.mkdirs() - botLoggerSupplier = { DirectoryLogger(identity(it), dir, retain) } - } - - fileBasedDeviceInfo() - this.loginSolver = this@addBot.frontEnd.createLoginSolver() - redirectNetworkLogToDirectory() - // redirectBotLogToDirectory() - } -} +@ConsoleExperimentalAPI @Suppress("EXPOSED_SUPER_INTERFACE") public interface BuiltInCommand : Command, BuiltInCommandInternal // for identification internal interface BuiltInCommandInternal : Command +@ConsoleExperimentalAPI @Suppress("unused") public object BuiltInCommands { @@ -89,8 +52,9 @@ public object BuiltInCommands { ), BuiltInCommand { @Handler public suspend fun CommandSender.handle() { - sendMessage("现在有指令: ${allRegisteredCommands.joinToString { it.primaryName }}") - sendMessage("帮助还没写, 将就一下") + sendMessage(allRegisteredCommands.joinToString { + it.usage + "\n\n" + }) } } @@ -130,22 +94,20 @@ public object BuiltInCommands { ), BuiltInCommand { @Handler public suspend fun CommandSender.handle(id: Long, password: String) { - kotlin.runCatching { MiraiConsole.addBot(id, password).alsoLogin() }.fold( - onSuccess = { sendMessage("${it.nick} ($id) Login succeed") }, + onSuccess = { sendMessage("${it.nick} ($id) Login successful") }, onFailure = { throwable -> sendMessage( "Login failed: ${throwable.localizedMessage ?: throwable.message ?: throwable.toString()}" + if (this is MessageEventContextAware<*>) { - this.fromEvent.selectMessagesUnit { - "stacktrace" reply { - throwable.stackTraceToString() - } + CommandManagerImpl.launch { + fromEvent.nextMessageOrNull(60.secondsToMillis) { it.message.contentEquals("stacktrace") } } - "test" - } else "") + "\n 1 分钟内发送 stacktrace 以获取堆栈信息" + } else "" + ) throw throwable } diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt index 5d313721d..4880efd3a 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt @@ -58,6 +58,9 @@ public interface CommandManager { * @return * 若已有重名指令, 且 [override] 为 `false`, 返回 `false`; * 若已有重名指令, 但 [override] 为 `true`, 覆盖原有指令并返回 `true`. + * + * + * 注意: [内建指令][BuiltInCommands] 也可以被覆盖. */ public fun Command.register(override: Boolean = false): Boolean diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManagerImpl.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManagerImpl.kt index 1b0d03e51..dc7d7433d 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManagerImpl.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManagerImpl.kt @@ -19,6 +19,8 @@ import net.mamoe.mirai.event.Listener import net.mamoe.mirai.event.subscribeAlways import net.mamoe.mirai.message.MessageEvent import net.mamoe.mirai.message.data.MessageChain +import net.mamoe.mirai.message.data.MessageContent +import net.mamoe.mirai.message.data.content import java.util.concurrent.locks.ReentrantLock internal object CommandManagerImpl : CommandManager, CoroutineScope by CoroutineScope(MiraiConsole.job) { @@ -60,7 +62,7 @@ internal object CommandManagerImpl : CommandManager, CoroutineScope by Coroutine concurrency = Listener.ConcurrencyKind.CONCURRENT, priority = Listener.EventPriority.HIGH ) { - if (this.sender.asCommandSender().executeCommand(message) != null) { + if (this.toCommandSender().executeCommand(message) != null) { intercept() } } @@ -129,7 +131,8 @@ internal object CommandManagerImpl : CommandManager, CoroutineScope by Coroutine override suspend fun CommandSender.executeCommand(message: MessageChain): Command? { if (message.isEmpty()) return null - return matchAndExecuteCommandInternal(message, message[0].toString().substringBefore(' ')) + val msg = message.filterIsInstance() + return matchAndExecuteCommandInternal(msg, msg[0].content.substringBefore(' ')) } override suspend fun Command.execute(sender: CommandSender, args: MessageChain, checkPermission: Boolean) { diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandPermissionDeniedException.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandPermissionDeniedException.kt index df43f6241..512b90900 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandPermissionDeniedException.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandPermissionDeniedException.kt @@ -10,9 +10,10 @@ package net.mamoe.mirai.console.command import net.mamoe.mirai.console.command.Command.Companion.primaryName +import net.mamoe.mirai.console.command.CommandManager.INSTANCE.executeCommand /** - * 在 [executeCommand] 中, [CommandSender] 未拥有 [Command.permission] 所要求的权限时抛出的异常. + * 在 [CommandManager.executeCommand] 中, [CommandSender] 未拥有 [Command.permission] 所要求的权限时抛出的异常. * * 总是作为 [CommandExecutionException.cause]. */ diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/RawCommand.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/RawCommand.kt index fe6d3337d..14590c53e 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/RawCommand.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/RawCommand.kt @@ -12,7 +12,7 @@ package net.mamoe.mirai.console.command /** * 无参数解析, 接收原生参数的指令. */ -public abstract class RawCommand( +public abstract class RawCommand @JvmOverloads constructor( public override val owner: CommandOwner, public override vararg val names: String, public override val usage: String = "", diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/SimpleCommand.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/SimpleCommand.kt index 12c27a023..55900a418 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/SimpleCommand.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/SimpleCommand.kt @@ -17,13 +17,40 @@ package net.mamoe.mirai.console.command -import net.mamoe.mirai.console.command.description.CommandArgumentContext -import net.mamoe.mirai.console.command.description.CommandArgumentContextAware -import net.mamoe.mirai.console.command.description.EmptyCommandArgumentContext -import net.mamoe.mirai.console.command.description.plus +import net.mamoe.mirai.console.command.description.* import net.mamoe.mirai.console.internal.command.AbstractReflectionCommand import net.mamoe.mirai.console.internal.command.SimpleCommandSubCommandAnnotationResolver +/** + * 简单指令. 参数支持自动解析. [CommandArgumentParser] + * + * Kotlin 实现: + * ``` + * object MySimpleCommand : SimpleCommand( + * MyPlugin, "tell", + * description = "Message somebody", + * usage = "/tell " + * ) { + * @Handler + * suspend fun CommandSender.onCommand(target: User, message: String) { + * target.sendMessage(message) + * } + * } + * ``` + * + * Java 实现: + * ```java + * public final class MySimpleCommand extends SimpleCommand { + * private MySimpleCommand() { + * super(MyPlugin.INSTANCE, new String[]{ "tell" }, "Message somebody", "/tell ") + * } + * @Handler + * public void onCommand(CommandSender sender, User target, String message) { + * target.sendMessage(message) + * } + * } + * ``` + */ public abstract class SimpleCommand @JvmOverloads constructor( owner: CommandOwner, vararg names: String,