mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-25 15:40:28 +08:00
Fix various bugs
This commit is contained in:
parent
c8854b3391
commit
74353d1aaf
@ -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
|
||||
}
|
||||
|
@ -58,6 +58,9 @@ public interface CommandManager {
|
||||
* @return
|
||||
* 若已有重名指令, 且 [override] 为 `false`, 返回 `false`;
|
||||
* 若已有重名指令, 但 [override] 为 `true`, 覆盖原有指令并返回 `true`.
|
||||
*
|
||||
*
|
||||
* 注意: [内建指令][BuiltInCommands] 也可以被覆盖.
|
||||
*/
|
||||
public fun Command.register(override: Boolean = false): Boolean
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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].
|
||||
*/
|
||||
|
@ -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>",
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user