Fix various bugs

This commit is contained in:
Him188 2020-08-22 01:38:32 +08:00
parent c8854b3391
commit 74353d1aaf
6 changed files with 57 additions and 61 deletions

View File

@ -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
}

View File

@ -58,6 +58,9 @@ public interface CommandManager {
* @return
* 若已有重名指令, [override] `false`, 返回 `false`;
* 若已有重名指令, [override] `true`, 覆盖原有指令并返回 `true`.
*
*
* 注意: [内建指令][BuiltInCommands] 也可以被覆盖.
*/
public fun Command.register(override: Boolean = false): Boolean

View File

@ -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<MessageContent>()
return matchAndExecuteCommandInternal(msg, msg[0].content.substringBefore(' '))
}
override suspend fun Command.execute(sender: CommandSender, args: MessageChain, checkPermission: Boolean) {

View File

@ -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].
*/

View File

@ -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 = "<no usages given>",

View File

@ -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 <target> <message>"
* ) {
* @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 <target> <message>")
* }
* @Handler
* public void onCommand(CommandSender sender, User target, String message) {
* target.sendMessage(message)
* }
* }
* ```
*/
public abstract class SimpleCommand @JvmOverloads constructor(
owner: CommandOwner,
vararg names: String,