Fix commands

This commit is contained in:
Him188 2020-09-18 23:26:16 +08:00
parent 5a34d58975
commit f40dd189f2
6 changed files with 27 additions and 21 deletions

View File

@ -157,7 +157,7 @@ public interface CommandManager {
public companion object INSTANCE : CommandManager by CommandManagerImpl { public companion object INSTANCE : CommandManager by CommandManagerImpl {
// TODO: 2020/8/20 https://youtrack.jetbrains.com/issue/KT-41191 // TODO: 2020/8/20 https://youtrack.jetbrains.com/issue/KT-41191
override val CommandOwner.registeredCommands: List<Command> get() = CommandManagerImpl.run { registeredCommands } override val CommandOwner.registeredCommands: List<Command> get() = CommandManagerImpl.run { this@registeredCommands.registeredCommands }
override fun CommandOwner.unregisterAllCommands(): Unit = CommandManagerImpl.run { unregisterAllCommands() } override fun CommandOwner.unregisterAllCommands(): Unit = CommandManagerImpl.run { unregisterAllCommands() }
override fun Command.register(override: Boolean): Boolean = CommandManagerImpl.run { register(override) } override fun Command.register(override: Boolean): Boolean = CommandManagerImpl.run { register(override) }
override fun Command.findDuplicate(): Command? = CommandManagerImpl.run { findDuplicate() } override fun Command.findDuplicate(): Command? = CommandManagerImpl.run { findDuplicate() }

View File

@ -16,7 +16,6 @@ import net.mamoe.mirai.console.command.CommandManager
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.executeCommand import net.mamoe.mirai.console.command.CommandManager.INSTANCE.executeCommand
import net.mamoe.mirai.console.command.CommandSender import net.mamoe.mirai.console.command.CommandSender
import net.mamoe.mirai.message.data.MessageChain import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.message.data.SingleMessage
/** /**
* Java 用户添加协程帮助的 [Command]. * Java 用户添加协程帮助的 [Command].
@ -33,9 +32,9 @@ public interface JCommand : Command {
/** /**
* 在指令被执行时调用. * 在指令被执行时调用.
* *
* @param args 指令参数. 数组元素类型可能是 [SingleMessage] [String]. 且已经以 ' ' 分割. * @param args 精确的指令参数. [MessageChain] 每个元素代表一个精确的参数.
* *
* @see CommandManager.executeCommand 查看更多信息 * @see CommandManager.executeCommand 查看更多信息
*/ */
public fun onCommand(sender: CommandSender, args: MessageChain) // overrides bridge public fun onCommand(sender: CommandSender, args: MessageChain) // overrides blocking bridge
} }

View File

@ -24,7 +24,7 @@ import net.mamoe.mirai.console.permission.Permission
* public final class MyCompositeCommand extends CompositeCommand { * public final class MyCompositeCommand extends CompositeCommand {
* public static final MyCompositeCommand INSTANCE = new MyCompositeCommand(); * public static final MyCompositeCommand INSTANCE = new MyCompositeCommand();
* *
* public MyCompositeCommand() { * private MyCompositeCommand() {
* super(MyPluginMain.INSTANCE, "manage") // "manage" 是主指令名 * super(MyPluginMain.INSTANCE, "manage") // "manage" 是主指令名
* } * }
* *

View File

@ -20,6 +20,7 @@ import net.mamoe.mirai.console.permission.Permission
* Java 实现: * Java 实现:
* ```java * ```java
* public final class MySimpleCommand extends JSimpleCommand { * public final class MySimpleCommand extends JSimpleCommand {
* public static final MySimpleCommand INSTANCE = new MySimpleCommand();
* private MySimpleCommand() { * private MySimpleCommand() {
* super(MyPlugin.INSTANCE, "tell") * super(MyPlugin.INSTANCE, "tell")
* // 可选设置如下属性 * // 可选设置如下属性

View File

@ -14,6 +14,7 @@ import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.command.* import net.mamoe.mirai.console.command.*
import net.mamoe.mirai.console.command.Command.Companion.allNames
import net.mamoe.mirai.console.command.CommandSender.Companion.toCommandSender import net.mamoe.mirai.console.command.CommandSender.Companion.toCommandSender
import net.mamoe.mirai.event.Listener import net.mamoe.mirai.event.Listener
import net.mamoe.mirai.event.subscribeAlways import net.mamoe.mirai.event.subscribeAlways
@ -30,8 +31,9 @@ internal object CommandManagerImpl : CommandManager, CoroutineScope by Coroutine
MiraiConsole.createLogger("command") MiraiConsole.createLogger("command")
} }
@Suppress("ObjectPropertyName")
@JvmField @JvmField
internal val registeredCommands: MutableList<Command> = mutableListOf() internal val _registeredCommands: MutableList<Command> = mutableListOf()
@JvmField @JvmField
internal val requiredPrefixCommandMap: MutableMap<String, Command> = mutableMapOf() internal val requiredPrefixCommandMap: MutableMap<String, Command> = mutableMapOf()
@ -88,8 +90,8 @@ internal object CommandManagerImpl : CommandManager, CoroutineScope by Coroutine
///// IMPL ///// IMPL
override val CommandOwner.registeredCommands: List<Command> get() = CommandManagerImpl.registeredCommands.filter { it.owner == this } override val CommandOwner.registeredCommands: List<Command> get() = _registeredCommands.filter { it.owner == this }
override val allRegisteredCommands: List<Command> get() = registeredCommands.toList() // copy override val allRegisteredCommands: List<Command> get() = _registeredCommands.toList() // copy
override val commandPrefix: String get() = "/" override val commandPrefix: String get() = "/"
override fun CommandOwner.unregisterAllCommands() { override fun CommandOwner.unregisterAllCommands() {
for (registeredCommand in registeredCommands) { for (registeredCommand in registeredCommands) {
@ -99,24 +101,28 @@ internal object CommandManagerImpl : CommandManager, CoroutineScope by Coroutine
override fun Command.register(override: Boolean): Boolean { override fun Command.register(override: Boolean): Boolean {
if (this is CompositeCommand) this.subCommands // init lazy if (this is CompositeCommand) this.subCommands // init lazy
this.permission // init lazy kotlin.runCatching {
this.secondaryNames // init lazy this.permission // init lazy
this.description // init lazy this.secondaryNames // init lazy
this.usage // init lazy this.description // init lazy
this.usage // init lazy
}.onFailure {
throw IllegalStateException("Failed to init command ${this@register}.", it)
}
modifyLock.withLock { modifyLock.withLock {
if (!override) { if (!override) {
if (findDuplicate() != null) return false if (findDuplicate() != null) return false
} }
registeredCommands.add(this@register) _registeredCommands.add(this@register)
if (this.prefixOptional) { if (this.prefixOptional) {
for (name in this.secondaryNames) { for (name in this.allNames) {
val lowerCaseName = name.toLowerCase() val lowerCaseName = name.toLowerCase()
optionalPrefixCommandMap[lowerCaseName] = this optionalPrefixCommandMap[lowerCaseName] = this
requiredPrefixCommandMap[lowerCaseName] = this requiredPrefixCommandMap[lowerCaseName] = this
} }
} else { } else {
for (name in this.secondaryNames) { for (name in this.allNames) {
val lowerCaseName = name.toLowerCase() val lowerCaseName = name.toLowerCase()
optionalPrefixCommandMap.remove(lowerCaseName) // ensure resolution consistency optionalPrefixCommandMap.remove(lowerCaseName) // ensure resolution consistency
requiredPrefixCommandMap[lowerCaseName] = this requiredPrefixCommandMap[lowerCaseName] = this
@ -127,21 +133,21 @@ internal object CommandManagerImpl : CommandManager, CoroutineScope by Coroutine
} }
override fun Command.findDuplicate(): Command? = override fun Command.findDuplicate(): Command? =
registeredCommands.firstOrNull { it.secondaryNames intersectsIgnoringCase this.secondaryNames } _registeredCommands.firstOrNull { it.allNames intersectsIgnoringCase this.allNames }
override fun Command.unregister(): Boolean = modifyLock.withLock { override fun Command.unregister(): Boolean = modifyLock.withLock {
if (this.prefixOptional) { if (this.prefixOptional) {
this.secondaryNames.forEach { this.allNames.forEach {
optionalPrefixCommandMap.remove(it) optionalPrefixCommandMap.remove(it)
} }
} }
this.secondaryNames.forEach { this.allNames.forEach {
requiredPrefixCommandMap.remove(it) requiredPrefixCommandMap.remove(it)
} }
registeredCommands.remove(this) _registeredCommands.remove(this)
} }
override fun Command.isRegistered(): Boolean = this in registeredCommands override fun Command.isRegistered(): Boolean = this in _registeredCommands
override suspend fun Command.execute( override suspend fun Command.execute(
sender: CommandSender, sender: CommandSender,

View File

@ -79,7 +79,7 @@ internal class TestCommand {
assertEquals(1, ConsoleCommandOwner.registeredCommands.size) assertEquals(1, ConsoleCommandOwner.registeredCommands.size)
assertEquals(1, CommandManagerImpl.registeredCommands.size) assertEquals(1, CommandManagerImpl._registeredCommands.size)
assertEquals(2, CommandManagerImpl.requiredPrefixCommandMap.size) assertEquals(2, CommandManagerImpl.requiredPrefixCommandMap.size)
} finally { } finally {
TestCompositeCommand.unregister() TestCompositeCommand.unregister()