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 {
// 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 Command.register(override: Boolean): Boolean = CommandManagerImpl.run { register(override) }
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.CommandSender
import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.message.data.SingleMessage
/**
* Java 用户添加协程帮助的 [Command].
@ -33,9 +32,9 @@ public interface JCommand : Command {
/**
* 在指令被执行时调用.
*
* @param args 指令参数. 数组元素类型可能是 [SingleMessage] [String]. 且已经以 ' ' 分割.
* @param args 精确的指令参数. [MessageChain] 每个元素代表一个精确的参数.
*
* @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 static final MyCompositeCommand INSTANCE = new MyCompositeCommand();
*
* public MyCompositeCommand() {
* private MyCompositeCommand() {
* super(MyPluginMain.INSTANCE, "manage") // "manage" 是主指令名
* }
*

View File

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

View File

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

View File

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