mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-10 18:40:15 +08:00
Review command
This commit is contained in:
parent
d10f2b4bea
commit
b9580ffcbd
@ -11,7 +11,6 @@
|
||||
|
||||
package net.mamoe.mirai.console.command
|
||||
|
||||
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.register
|
||||
import net.mamoe.mirai.console.command.descriptor.CommandArgumentContextAware
|
||||
import net.mamoe.mirai.console.command.descriptor.CommandSignatureVariant
|
||||
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
|
||||
@ -25,7 +24,7 @@ import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
||||
/**
|
||||
* 指令
|
||||
*
|
||||
* @see CommandManager.register 注册这个指令
|
||||
* @see CommandManager.registerCommand 注册这个指令
|
||||
*
|
||||
* @see RawCommand 无参数解析, 接收原生参数的指令
|
||||
* @see CompositeCommand 复合指令
|
||||
@ -52,7 +51,7 @@ public interface Command {
|
||||
public val secondaryNames: Array<out String>
|
||||
|
||||
/**
|
||||
*
|
||||
* 指令可能的参数列表.
|
||||
*/
|
||||
@ConsoleExperimentalApi("Property name is experimental")
|
||||
@ExperimentalCommandDescriptors
|
||||
@ -64,12 +63,12 @@ public interface Command {
|
||||
public val usage: String
|
||||
|
||||
/**
|
||||
* 指令描述, 用于显示在 [BuiltInCommands.HelpCommand]
|
||||
* 描述, 用于显示在 [BuiltInCommands.HelpCommand]
|
||||
*/
|
||||
public val description: String
|
||||
|
||||
/**
|
||||
* 此指令所分配的权限.
|
||||
* 为此指令分配的权限.
|
||||
*
|
||||
* ### 实现约束
|
||||
* - [Permission.id] 应由 [CommandOwner.permissionId] 创建. 因此保证相同的 [PermissionId.namespace]
|
||||
@ -82,6 +81,8 @@ public interface Command {
|
||||
*
|
||||
* 会影响聊天语境中的解析.
|
||||
*/
|
||||
@ExperimentalCommandDescriptors
|
||||
@ConsoleExperimentalApi
|
||||
public val prefixOptional: Boolean
|
||||
|
||||
/**
|
||||
@ -109,7 +110,7 @@ public interface Command {
|
||||
public fun checkCommandName(@ResolveContext(COMMAND_NAME) name: String) {
|
||||
when {
|
||||
name.isBlank() -> throw IllegalArgumentException("Command name should not be blank.")
|
||||
name.any { it.isWhitespace() } -> throw IllegalArgumentException("Spaces is not yet allowed in command name.")
|
||||
name.any { it.isWhitespace() } -> throw IllegalArgumentException("Spaces are not yet allowed in command name.")
|
||||
name.contains(':') -> throw IllegalArgumentException("':' is forbidden in command name.")
|
||||
name.contains('.') -> throw IllegalArgumentException("'.' is forbidden in command name.")
|
||||
}
|
||||
|
@ -20,27 +20,17 @@ import net.mamoe.mirai.console.command.CommandManager.INSTANCE.executeCommand
|
||||
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
|
||||
import net.mamoe.mirai.console.command.parse.CommandCall
|
||||
import net.mamoe.mirai.console.command.parse.CommandCallParser
|
||||
import net.mamoe.mirai.console.command.parse.CommandCallParser.Companion.parseCommandCall
|
||||
import net.mamoe.mirai.console.command.resolve.CommandCallResolver
|
||||
import net.mamoe.mirai.console.command.resolve.ResolvedCommandCall
|
||||
import net.mamoe.mirai.console.extensions.CommandCallResolverProvider
|
||||
import net.mamoe.mirai.console.internal.command.CommandManagerImpl
|
||||
import net.mamoe.mirai.console.internal.command.CommandManagerImpl.executeCommand
|
||||
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
|
||||
import net.mamoe.mirai.console.permission.PermissionService.Companion.testPermission
|
||||
import net.mamoe.mirai.console.internal.command.executeCommandImpl
|
||||
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
||||
import net.mamoe.mirai.message.data.*
|
||||
|
||||
/**
|
||||
* 指令管理器
|
||||
*/
|
||||
public interface CommandManager {
|
||||
/**
|
||||
* 获取已经注册了的属于这个 [CommandOwner] 的指令列表.
|
||||
*
|
||||
* @return 这一时刻的浅拷贝.
|
||||
*/
|
||||
public val CommandOwner.registeredCommands: List<Command>
|
||||
|
||||
/**
|
||||
* 获取所有已经注册了指令列表.
|
||||
*
|
||||
@ -54,9 +44,17 @@ public interface CommandManager {
|
||||
public val commandPrefix: String
|
||||
|
||||
/**
|
||||
* 取消注册所有属于 [this] 的指令
|
||||
* 获取已经注册了的属于这个 [CommandOwner] 的指令列表.
|
||||
*
|
||||
* @return 这一时刻的浅拷贝.
|
||||
*/
|
||||
public fun CommandOwner.unregisterAllCommands()
|
||||
public fun getRegisteredCommands(owner: CommandOwner): List<Command>
|
||||
|
||||
|
||||
/**
|
||||
* 取消注册所有属于 [owner] 的指令
|
||||
*/
|
||||
public fun unregisterAllCommands(owner: CommandOwner)
|
||||
|
||||
/**
|
||||
* 注册一个指令.
|
||||
@ -75,35 +73,31 @@ public interface CommandManager {
|
||||
*
|
||||
* 注意: [内建指令][BuiltInCommands] 也可以被覆盖.
|
||||
*/
|
||||
@JvmName("registerCommand")
|
||||
public fun Command.register(override: Boolean = false): Boolean
|
||||
public fun registerCommand(command: Command, override: Boolean = false): Boolean
|
||||
|
||||
/**
|
||||
* 查找并返回重名的指令. 返回重名指令.
|
||||
*/
|
||||
@JvmName("findCommandDuplicate")
|
||||
public fun Command.findDuplicate(): Command?
|
||||
public fun findDuplicateCommand(command: Command): Command?
|
||||
|
||||
/**
|
||||
* 取消注册这个指令.
|
||||
*
|
||||
* 若指令未注册, 返回 `false`.
|
||||
*/
|
||||
@JvmName("unregisterCommand")
|
||||
public fun Command.unregister(): Boolean
|
||||
public fun unregisterCommand(command: Command): Boolean
|
||||
|
||||
/**
|
||||
* 当 [this] 已经 [注册][register] 时返回 `true`
|
||||
* 当 [command] 已经 [注册][registerCommand] 时返回 `true`
|
||||
*/
|
||||
@JvmName("isCommandRegistered")
|
||||
public fun Command.isRegistered(): Boolean
|
||||
public fun isCommandRegistered(command: Command): Boolean
|
||||
|
||||
/**
|
||||
* 解析并执行一个指令.
|
||||
*
|
||||
* 如要避免参数解析, 请使用 [Command.onCommand]
|
||||
*
|
||||
* ### 指令解析流程
|
||||
* 1. [CommandCallParser] 将 [MessageChain] 解析为 [CommandCall]
|
||||
* 2. [CommandCallResolver] 将 [CommandCall] 解析为 []
|
||||
* 1. [message] 的第一个消息元素的 [内容][Message.contentToString] 被作为指令名, 在已注册指令列表中搜索. (包含 [Command.prefixOptional] 相关的处理)
|
||||
* 2. 参数语法分析.
|
||||
* 在当前的实现下, [message] 被以空格和 [SingleMessage] 分割.
|
||||
@ -112,7 +106,7 @@ public interface CommandManager {
|
||||
* 3. 参数解析. 各类型指令实现不同. 详见 [RawCommand], [CompositeCommand], [SimpleCommand]
|
||||
*
|
||||
* ### 扩展
|
||||
* 参数语法分析过程可能会被扩展, 插件可以自定义处理方式, 因此可能不会简单地使用空格分隔.
|
||||
* 参数语法分析过程可能会被扩展, 插件可以自定义处理方式 ([CommandCallParser]), 因此可能不会简单地使用空格分隔.
|
||||
*
|
||||
* @param message 一条完整的指令. 如 "/managers add 123456.123456"
|
||||
* @param checkPermission 为 `true` 时检查权限
|
||||
@ -120,42 +114,48 @@ public interface CommandManager {
|
||||
* @see CommandCallParser
|
||||
* @see CommandCallResolver
|
||||
*
|
||||
* @see CommandSender.executeCommand
|
||||
* @see Command.execute
|
||||
*
|
||||
* @return 执行结果
|
||||
*/
|
||||
@ExperimentalCommandDescriptors
|
||||
@JvmBlockingBridge
|
||||
@OptIn(ExperimentalCommandDescriptors::class)
|
||||
public suspend fun executeCommand(
|
||||
caller: CommandSender,
|
||||
message: Message,
|
||||
checkPermission: Boolean = true,
|
||||
): CommandExecuteResult {
|
||||
return executeCommandImpl(this, message, caller, checkPermission)
|
||||
return executeCommandImpl(message, caller, checkPermission)
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析并执行一个指令
|
||||
* 执行一个确切的指令
|
||||
*
|
||||
* @param message 一条完整的指令. 如 "/managers add 123456.123456"
|
||||
* @param checkPermission 为 `true` 时检查权限
|
||||
* @param command 目标指令
|
||||
* @param arguments 参数列表
|
||||
*
|
||||
* @return 执行结果
|
||||
* @see executeCommand
|
||||
* @see executeCommand 获取更多信息
|
||||
* @see Command.execute
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun CommandSender.executeCommand(
|
||||
message: String,
|
||||
checkPermission: Boolean = true,
|
||||
): CommandExecuteResult = executeCommand(this, PlainText(message).asMessageChain(), checkPermission)
|
||||
|
||||
@JvmName("resolveCall")
|
||||
@ConsoleExperimentalApi
|
||||
@JvmName("executeCommand")
|
||||
@ExperimentalCommandDescriptors
|
||||
public fun CommandCall.resolve(): ResolvedCommandCall? {
|
||||
GlobalComponentStorage.run {
|
||||
CommandCallResolverProvider.useExtensions { provider ->
|
||||
provider.instance.resolve(this@resolve)?.let { return it }
|
||||
}
|
||||
@JvmSynthetic
|
||||
public suspend fun executeCommand(
|
||||
sender: CommandSender,
|
||||
command: Command,
|
||||
arguments: Message = EmptyMessageChain,
|
||||
checkPermission: Boolean = true,
|
||||
): CommandExecuteResult {
|
||||
// TODO: 2020/10/18 net.mamoe.mirai.console.command.CommandManager.execute
|
||||
val chain = buildMessageChain {
|
||||
append(CommandManager.commandPrefix)
|
||||
append(command.primaryName)
|
||||
append(' ')
|
||||
append(arguments)
|
||||
}
|
||||
return null
|
||||
return CommandManager.executeCommand(sender, chain, checkPermission)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -170,78 +170,89 @@ public interface CommandManager {
|
||||
public fun matchCommand(commandName: String): Command?
|
||||
|
||||
public companion object INSTANCE : CommandManager by CommandManagerImpl {
|
||||
// TODO: 2020/8/20 https://youtrack.jetbrains.com/issue/KT-41191
|
||||
|
||||
/**
|
||||
* @see CommandManager.getRegisteredCommands
|
||||
*/
|
||||
@get:JvmName("registeredCommands0")
|
||||
@get:JvmSynthetic
|
||||
public inline val CommandOwner.registeredCommands: List<Command>
|
||||
get() = getRegisteredCommands(this)
|
||||
|
||||
override val CommandOwner.registeredCommands: List<Command> get() = CommandManagerImpl.run { this@registeredCommands.registeredCommands }
|
||||
override fun CommandOwner.unregisterAllCommands(): Unit = CommandManagerImpl.run { unregisterAllCommands() }
|
||||
override fun Command.register(override: Boolean): Boolean = CommandManagerImpl.run { register(override) }
|
||||
override fun Command.findDuplicate(): Command? = CommandManagerImpl.run { findDuplicate() }
|
||||
override fun Command.unregister(): Boolean = CommandManagerImpl.run { unregister() }
|
||||
override fun Command.isRegistered(): Boolean = CommandManagerImpl.run { isRegistered() }
|
||||
override val commandPrefix: String get() = CommandManagerImpl.commandPrefix
|
||||
override val allRegisteredCommands: List<Command>
|
||||
get() = CommandManagerImpl.allRegisteredCommands
|
||||
/**
|
||||
* @see CommandManager.registerCommand
|
||||
*/
|
||||
@JvmSynthetic
|
||||
public inline fun Command.register(override: Boolean = false): Boolean = registerCommand(this, override)
|
||||
|
||||
/**
|
||||
* @see CommandManager.unregisterCommand
|
||||
*/
|
||||
@JvmSynthetic
|
||||
public inline fun Command.unregister(): Boolean = unregisterCommand(this)
|
||||
|
||||
/**
|
||||
* @see CommandManager.isCommandRegistered
|
||||
*/
|
||||
@get:JvmSynthetic
|
||||
public inline val Command.isRegistered: Boolean
|
||||
get() = isCommandRegistered(this)
|
||||
|
||||
/**
|
||||
* @see CommandManager.unregisterAll
|
||||
*/
|
||||
@JvmSynthetic
|
||||
public inline fun CommandOwner.unregisterAll(): Unit = unregisterAllCommands(this)
|
||||
|
||||
/**
|
||||
* @see CommandManager.findDuplicate
|
||||
*/
|
||||
@JvmSynthetic
|
||||
public inline fun Command.findDuplicate(): Command? = findDuplicateCommand(this)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行一个确切的指令
|
||||
* @see executeCommand 获取更多信息
|
||||
* 解析并执行一个指令
|
||||
*
|
||||
* @param message 一条完整的指令. 如 "/managers add 123456.123456"
|
||||
* @param checkPermission 为 `true` 时检查权限
|
||||
*
|
||||
* @return 执行结果
|
||||
* @see executeCommand
|
||||
*/
|
||||
// @JvmBlockingBridge
|
||||
// @JvmName("executeCommand")
|
||||
public suspend fun Command.execute(
|
||||
sender: CommandSender,
|
||||
arguments: String = "",
|
||||
@JvmName("execute0")
|
||||
@ExperimentalCommandDescriptors
|
||||
@JvmSynthetic
|
||||
public suspend inline fun CommandSender.executeCommand(
|
||||
message: String,
|
||||
checkPermission: Boolean = true,
|
||||
): CommandExecuteResult = execute(sender, PlainText(arguments).asMessageChain(), checkPermission)
|
||||
): CommandExecuteResult = CommandManager.executeCommand(this, PlainText(message).asMessageChain(), checkPermission)
|
||||
|
||||
|
||||
/**
|
||||
* 执行一个确切的指令
|
||||
* @see executeCommand 获取更多信息
|
||||
*/
|
||||
// @JvmBlockingBridge
|
||||
// @JvmName("executeCommand")
|
||||
public suspend fun Command.execute(
|
||||
@JvmName("execute0")
|
||||
@ExperimentalCommandDescriptors
|
||||
@JvmSynthetic
|
||||
public suspend inline fun Command.execute(
|
||||
sender: CommandSender,
|
||||
arguments: Message = EmptyMessageChain,
|
||||
checkPermission: Boolean = true,
|
||||
): CommandExecuteResult {
|
||||
// TODO: 2020/10/18 net.mamoe.mirai.console.command.CommandManager.execute
|
||||
val chain = buildMessageChain {
|
||||
append(CommandManager.commandPrefix)
|
||||
append(this@execute.primaryName)
|
||||
append(' ')
|
||||
append(arguments)
|
||||
}
|
||||
return CommandManager.executeCommand(sender, chain, checkPermission)
|
||||
}
|
||||
|
||||
|
||||
// Don't move into CommandManager, compilation error / VerifyError
|
||||
@OptIn(ExperimentalCommandDescriptors::class)
|
||||
internal suspend fun executeCommandImpl(
|
||||
receiver: CommandManager,
|
||||
message: Message,
|
||||
caller: CommandSender,
|
||||
checkPermission: Boolean,
|
||||
): CommandExecuteResult = with(receiver) {
|
||||
val call = message.asMessageChain().parseCommandCall(caller) ?: return CommandExecuteResult.UnresolvedCall("")
|
||||
val resolved = call.resolve() ?: return CommandExecuteResult.UnresolvedCall(call.calleeName)
|
||||
|
||||
val command = resolved.callee
|
||||
|
||||
if (checkPermission && !command.permission.testPermission(caller)) {
|
||||
return CommandExecuteResult.PermissionDenied(command, call.calleeName)
|
||||
}
|
||||
|
||||
return try {
|
||||
resolved.calleeSignature.call(resolved)
|
||||
CommandExecuteResult.Success(resolved.callee, call.calleeName, EmptyMessageChain)
|
||||
} catch (e: Throwable) {
|
||||
CommandExecuteResult.ExecutionFailed(e, resolved.callee, call.calleeName, EmptyMessageChain)
|
||||
}
|
||||
}
|
||||
): CommandExecuteResult = CommandManager.executeCommand(sender, this, arguments, checkPermission)
|
||||
|
||||
/**
|
||||
* 执行一个确切的指令
|
||||
* @see executeCommand 获取更多信息
|
||||
*/
|
||||
@JvmName("execute0")
|
||||
@ExperimentalCommandDescriptors
|
||||
@JvmSynthetic
|
||||
public suspend inline fun Command.execute(
|
||||
sender: CommandSender,
|
||||
arguments: String = "",
|
||||
checkPermission: Boolean = true,
|
||||
): CommandExecuteResult = execute(sender, PlainText(arguments), checkPermission)
|
||||
|
@ -12,6 +12,8 @@ package net.mamoe.mirai.console.command.resolve
|
||||
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
|
||||
import net.mamoe.mirai.console.command.parse.CommandCall
|
||||
import net.mamoe.mirai.console.extensions.CommandCallResolverProvider
|
||||
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
|
||||
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
||||
|
||||
/**
|
||||
* The resolver converting a [CommandCall] into [ResolvedCommandCall] based on registered []
|
||||
@ -22,4 +24,18 @@ import net.mamoe.mirai.console.extensions.CommandCallResolverProvider
|
||||
@ExperimentalCommandDescriptors
|
||||
public interface CommandCallResolver {
|
||||
public fun resolve(call: CommandCall): ResolvedCommandCall?
|
||||
|
||||
public companion object {
|
||||
@JvmName("resolveCall")
|
||||
@ConsoleExperimentalApi
|
||||
@ExperimentalCommandDescriptors
|
||||
public fun CommandCall.resolve(): ResolvedCommandCall? {
|
||||
GlobalComponentStorage.run {
|
||||
CommandCallResolverProvider.useExtensions { provider ->
|
||||
provider.instance.resolve(this@resolve)?.let { return it }
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
@ -15,12 +15,19 @@ import kotlinx.coroutines.CoroutineScope
|
||||
import net.mamoe.mirai.console.MiraiConsole
|
||||
import net.mamoe.mirai.console.command.*
|
||||
import net.mamoe.mirai.console.command.Command.Companion.allNames
|
||||
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.findDuplicate
|
||||
import net.mamoe.mirai.console.command.CommandSender.Companion.toCommandSender
|
||||
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
|
||||
import net.mamoe.mirai.console.command.parse.CommandCallParser.Companion.parseCommandCall
|
||||
import net.mamoe.mirai.console.command.resolve.CommandCallResolver.Companion.resolve
|
||||
import net.mamoe.mirai.console.permission.PermissionService.Companion.testPermission
|
||||
import net.mamoe.mirai.console.util.CoroutineScopeUtils.childScope
|
||||
import net.mamoe.mirai.event.Listener
|
||||
import net.mamoe.mirai.event.subscribeAlways
|
||||
import net.mamoe.mirai.message.MessageEvent
|
||||
import net.mamoe.mirai.message.data.EmptyMessageChain
|
||||
import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.message.data.asMessageChain
|
||||
import net.mamoe.mirai.message.data.content
|
||||
import net.mamoe.mirai.utils.MiraiLogger
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
@ -94,64 +101,90 @@ internal object CommandManagerImpl : CommandManager, CoroutineScope by MiraiCons
|
||||
///// IMPL
|
||||
|
||||
|
||||
override val CommandOwner.registeredCommands: List<Command> get() = _registeredCommands.filter { it.owner == this }
|
||||
override fun getRegisteredCommands(owner: CommandOwner): List<Command> = _registeredCommands.filter { it.owner == owner }
|
||||
override val allRegisteredCommands: List<Command> get() = _registeredCommands.toList() // copy
|
||||
override val commandPrefix: String get() = "/"
|
||||
override fun CommandOwner.unregisterAllCommands() {
|
||||
for (registeredCommand in registeredCommands) {
|
||||
registeredCommand.unregister()
|
||||
override fun unregisterAllCommands(owner: CommandOwner) {
|
||||
for (registeredCommand in getRegisteredCommands(owner)) {
|
||||
unregisterCommand(registeredCommand)
|
||||
}
|
||||
}
|
||||
|
||||
override fun Command.register(override: Boolean): Boolean {
|
||||
if (this is CompositeCommand) {
|
||||
this.overloads // init lazy
|
||||
override fun registerCommand(command: Command, override: Boolean): Boolean {
|
||||
if (command is CompositeCommand) {
|
||||
command.overloads // init lazy
|
||||
}
|
||||
kotlin.runCatching {
|
||||
this.permission // init lazy
|
||||
this.secondaryNames // init lazy
|
||||
this.description // init lazy
|
||||
this.usage // init lazy
|
||||
command.permission // init lazy
|
||||
command.secondaryNames // init lazy
|
||||
command.description // init lazy
|
||||
command.usage // init lazy
|
||||
}.onFailure {
|
||||
throw IllegalStateException("Failed to init command ${this@register}.", it)
|
||||
throw IllegalStateException("Failed to init command ${command}.", it)
|
||||
}
|
||||
|
||||
modifyLock.withLock {
|
||||
this@CommandManagerImpl.modifyLock.withLock {
|
||||
if (!override) {
|
||||
if (findDuplicate() != null) return false
|
||||
if (command.findDuplicate() != null) return false
|
||||
}
|
||||
_registeredCommands.add(this@register)
|
||||
if (this.prefixOptional) {
|
||||
for (name in this.allNames) {
|
||||
this@CommandManagerImpl._registeredCommands.add(command)
|
||||
if (command.prefixOptional) {
|
||||
for (name in command.allNames) {
|
||||
val lowerCaseName = name.toLowerCase()
|
||||
optionalPrefixCommandMap[lowerCaseName] = this
|
||||
requiredPrefixCommandMap[lowerCaseName] = this
|
||||
this@CommandManagerImpl.optionalPrefixCommandMap[lowerCaseName] = command
|
||||
this@CommandManagerImpl.requiredPrefixCommandMap[lowerCaseName] = command
|
||||
}
|
||||
} else {
|
||||
for (name in this.allNames) {
|
||||
for (name in command.allNames) {
|
||||
val lowerCaseName = name.toLowerCase()
|
||||
optionalPrefixCommandMap.remove(lowerCaseName) // ensure resolution consistency
|
||||
requiredPrefixCommandMap[lowerCaseName] = this
|
||||
this@CommandManagerImpl.optionalPrefixCommandMap.remove(lowerCaseName) // ensure resolution consistency
|
||||
this@CommandManagerImpl.requiredPrefixCommandMap[lowerCaseName] = command
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
override fun Command.findDuplicate(): Command? =
|
||||
_registeredCommands.firstOrNull { it.allNames intersectsIgnoringCase this.allNames }
|
||||
override fun findDuplicateCommand(command: Command): Command? =
|
||||
_registeredCommands.firstOrNull { it.allNames intersectsIgnoringCase command.allNames }
|
||||
|
||||
override fun Command.unregister(): Boolean = modifyLock.withLock {
|
||||
if (this.prefixOptional) {
|
||||
this.allNames.forEach {
|
||||
override fun unregisterCommand(command: Command): Boolean = modifyLock.withLock {
|
||||
if (command.prefixOptional) {
|
||||
command.allNames.forEach {
|
||||
optionalPrefixCommandMap.remove(it.toLowerCase())
|
||||
}
|
||||
}
|
||||
this.allNames.forEach {
|
||||
command.allNames.forEach {
|
||||
requiredPrefixCommandMap.remove(it.toLowerCase())
|
||||
}
|
||||
_registeredCommands.remove(this)
|
||||
_registeredCommands.remove(command)
|
||||
}
|
||||
|
||||
override fun Command.isRegistered(): Boolean = this in _registeredCommands
|
||||
override fun isCommandRegistered(command: Command): Boolean = command in _registeredCommands
|
||||
}
|
||||
|
||||
|
||||
// Don't move into CommandManager, compilation error / VerifyError
|
||||
@OptIn(ExperimentalCommandDescriptors::class)
|
||||
internal suspend fun executeCommandImpl(
|
||||
message: Message,
|
||||
caller: CommandSender,
|
||||
checkPermission: Boolean,
|
||||
): CommandExecuteResult {
|
||||
val call = message.asMessageChain().parseCommandCall(caller) ?: return CommandExecuteResult.UnresolvedCall("")
|
||||
val resolved = call.resolve() ?: return CommandExecuteResult.UnresolvedCall(call.calleeName)
|
||||
|
||||
val command = resolved.callee
|
||||
|
||||
if (checkPermission && !command.permission.testPermission(caller)) {
|
||||
return CommandExecuteResult.PermissionDenied(command, call.calleeName)
|
||||
}
|
||||
|
||||
return try {
|
||||
resolved.calleeSignature.call(resolved)
|
||||
CommandExecuteResult.Success(resolved.callee, call.calleeName, EmptyMessageChain)
|
||||
} catch (e: Throwable) {
|
||||
CommandExecuteResult.ExecutionFailed(e, resolved.callee, call.calleeName, EmptyMessageChain)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,11 +16,11 @@ import kotlinx.coroutines.runBlocking
|
||||
import net.mamoe.mirai.console.MiraiConsole
|
||||
import net.mamoe.mirai.console.Testing
|
||||
import net.mamoe.mirai.console.Testing.withTesting
|
||||
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.executeCommand
|
||||
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.getRegisteredCommands
|
||||
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.register
|
||||
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.registeredCommands
|
||||
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.unregister
|
||||
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.registerCommand
|
||||
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.unregisterAllCommands
|
||||
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.unregisterCommand
|
||||
import net.mamoe.mirai.console.command.descriptor.CommandValueArgumentParser
|
||||
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
|
||||
import net.mamoe.mirai.console.command.descriptor.buildCommandArgumentContext
|
||||
@ -78,20 +78,20 @@ internal class TestCommand {
|
||||
@Test
|
||||
fun testRegister() {
|
||||
try {
|
||||
ConsoleCommandOwner.unregisterAllCommands() // builtins
|
||||
TestSimpleCommand.unregister()
|
||||
unregisterAllCommands(ConsoleCommandOwner) // builtins
|
||||
unregisterCommand(TestSimpleCommand)
|
||||
|
||||
assertTrue(TestCompositeCommand.register())
|
||||
assertFalse(TestCompositeCommand.register())
|
||||
|
||||
assertEquals(1, ConsoleCommandOwner.registeredCommands.size)
|
||||
assertEquals(1, getRegisteredCommands(ConsoleCommandOwner).size)
|
||||
|
||||
assertEquals(1, CommandManagerImpl._registeredCommands.size)
|
||||
assertEquals(2,
|
||||
CommandManagerImpl.requiredPrefixCommandMap.size,
|
||||
CommandManagerImpl.requiredPrefixCommandMap.entries.joinToString { it.toString() })
|
||||
} finally {
|
||||
TestCompositeCommand.unregister()
|
||||
unregisterCommand(TestCompositeCommand)
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ internal class TestCommand {
|
||||
}
|
||||
}
|
||||
|
||||
composite.register()
|
||||
registerCommand(composite)
|
||||
|
||||
println(composite.overloads.joinToString())
|
||||
|
||||
|
@ -10,13 +10,13 @@
|
||||
package net.mamoe.mirai.console.command
|
||||
|
||||
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.register
|
||||
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.unregister
|
||||
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.unregisterCommand
|
||||
|
||||
inline fun <T : Command, R> T.withRegistration(block: T.() -> R): R {
|
||||
this.register()
|
||||
try {
|
||||
return block()
|
||||
} finally {
|
||||
this.unregister()
|
||||
unregisterCommand(this)
|
||||
}
|
||||
}
|
@ -15,11 +15,7 @@ import kotlinx.coroutines.CoroutineName
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import net.mamoe.mirai.console.MiraiConsole
|
||||
import net.mamoe.mirai.console.command.BuiltInCommands
|
||||
import net.mamoe.mirai.console.command.CommandExecuteStatus
|
||||
import net.mamoe.mirai.console.command.CommandManager
|
||||
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.executeCommand
|
||||
import net.mamoe.mirai.console.command.ConsoleCommandSender
|
||||
import net.mamoe.mirai.console.command.*
|
||||
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
|
||||
import net.mamoe.mirai.console.terminal.noconsole.NoConsole
|
||||
import net.mamoe.mirai.console.util.ConsoleInternalApi
|
||||
|
Loading…
Reference in New Issue
Block a user