mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-03 15:10:14 +08:00
Add CommandContext and support retrieving original message chain from command, close #1835
This commit is contained in:
parent
586c61bbab
commit
eeb361358a
@ -171,6 +171,11 @@ public final class net/mamoe/mirai/console/command/Command$Companion {
|
||||
public final fun getAllNames (Lnet/mamoe/mirai/console/command/Command;)[Ljava/lang/String;
|
||||
}
|
||||
|
||||
public abstract interface class net/mamoe/mirai/console/command/CommandContext {
|
||||
public abstract fun getOriginalMessage ()Lnet/mamoe/mirai/message/data/MessageChain;
|
||||
public abstract fun getSender ()Lnet/mamoe/mirai/console/command/CommandSender;
|
||||
}
|
||||
|
||||
public abstract class net/mamoe/mirai/console/command/CommandExecuteResult {
|
||||
public abstract fun getCall ()Lnet/mamoe/mirai/console/command/parse/CommandCall;
|
||||
public abstract fun getCommand ()Lnet/mamoe/mirai/console/command/Command;
|
||||
@ -571,7 +576,8 @@ public abstract class net/mamoe/mirai/console/command/RawCommand : net/mamoe/mir
|
||||
public fun getPrimaryName ()Ljava/lang/String;
|
||||
public fun getSecondaryNames ()[Ljava/lang/String;
|
||||
public fun getUsage ()Ljava/lang/String;
|
||||
public abstract fun onCommand (Lnet/mamoe/mirai/console/command/CommandSender;Lnet/mamoe/mirai/message/data/MessageChain;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun onCommand (Lnet/mamoe/mirai/console/command/CommandContext;Lnet/mamoe/mirai/message/data/MessageChain;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun onCommand (Lnet/mamoe/mirai/console/command/CommandSender;Lnet/mamoe/mirai/message/data/MessageChain;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public abstract class net/mamoe/mirai/console/command/SimpleCommand : net/mamoe/mirai/console/command/AbstractCommand, net/mamoe/mirai/console/command/Command, net/mamoe/mirai/console/command/descriptor/CommandArgumentContextAware {
|
||||
@ -855,25 +861,28 @@ public abstract interface class net/mamoe/mirai/console/command/descriptor/Comma
|
||||
public abstract fun isOptional ()Z
|
||||
}
|
||||
|
||||
public final class net/mamoe/mirai/console/command/descriptor/CommandReceiverParameter : net/mamoe/mirai/console/command/descriptor/AbstractCommandParameter, net/mamoe/mirai/console/command/descriptor/CommandParameter {
|
||||
public abstract class net/mamoe/mirai/console/command/descriptor/CommandReceiverParameter : net/mamoe/mirai/console/command/descriptor/AbstractCommandParameter, net/mamoe/mirai/console/command/descriptor/CommandParameter {
|
||||
public static final field Companion Lnet/mamoe/mirai/console/command/descriptor/CommandReceiverParameter$Companion;
|
||||
public static final field NAME Ljava/lang/String;
|
||||
public fun <init> (ZLkotlin/reflect/KType;)V
|
||||
public final fun component1 ()Z
|
||||
public final fun component2 ()Lkotlin/reflect/KType;
|
||||
public final fun copy (ZLkotlin/reflect/KType;)Lnet/mamoe/mirai/console/command/descriptor/CommandReceiverParameter;
|
||||
public static synthetic fun copy$default (Lnet/mamoe/mirai/console/command/descriptor/CommandReceiverParameter;ZLkotlin/reflect/KType;ILjava/lang/Object;)Lnet/mamoe/mirai/console/command/descriptor/CommandReceiverParameter;
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public fun getName ()Ljava/lang/String;
|
||||
public fun getType ()Lkotlin/reflect/KType;
|
||||
public fun hashCode ()I
|
||||
public fun isOptional ()Z
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class net/mamoe/mirai/console/command/descriptor/CommandReceiverParameter$Companion {
|
||||
}
|
||||
|
||||
public final class net/mamoe/mirai/console/command/descriptor/CommandReceiverParameter$Context : net/mamoe/mirai/console/command/descriptor/CommandReceiverParameter {
|
||||
public fun <init> (ZLkotlin/reflect/KType;)V
|
||||
public synthetic fun <init> (ZLkotlin/reflect/KType;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public fun getType ()Lkotlin/reflect/KType;
|
||||
public fun isOptional ()Z
|
||||
}
|
||||
|
||||
public final class net/mamoe/mirai/console/command/descriptor/CommandReceiverParameter$Sender : net/mamoe/mirai/console/command/descriptor/CommandReceiverParameter {
|
||||
public fun <init> (ZLkotlin/reflect/KType;)V
|
||||
public fun getType ()Lkotlin/reflect/KType;
|
||||
public fun isOptional ()Z
|
||||
}
|
||||
|
||||
public class net/mamoe/mirai/console/command/descriptor/CommandResolutionException : java/lang/RuntimeException {
|
||||
public fun <init> ()V
|
||||
public fun <init> (Ljava/lang/String;)V
|
||||
@ -1118,6 +1127,7 @@ public abstract class net/mamoe/mirai/console/command/java/JRawCommand : net/mam
|
||||
public fun getPrimaryName ()Ljava/lang/String;
|
||||
public fun getSecondaryNames ()[Ljava/lang/String;
|
||||
public fun getUsage ()Ljava/lang/String;
|
||||
public fun onCommand (Lnet/mamoe/mirai/console/command/CommandContext;Lnet/mamoe/mirai/message/data/MessageChain;)V
|
||||
public fun onCommand (Lnet/mamoe/mirai/console/command/CommandSender;Lnet/mamoe/mirai/message/data/MessageChain;)V
|
||||
protected final fun setDescription (Ljava/lang/String;)V
|
||||
protected final fun setPermission (Lnet/mamoe/mirai/console/permission/Permission;)V
|
||||
@ -1145,13 +1155,15 @@ public abstract interface class net/mamoe/mirai/console/command/parse/CommandArg
|
||||
public abstract interface class net/mamoe/mirai/console/command/parse/CommandCall {
|
||||
public abstract fun getCalleeName ()Ljava/lang/String;
|
||||
public abstract fun getCaller ()Lnet/mamoe/mirai/console/command/CommandSender;
|
||||
public abstract fun getOriginalMessage ()Lnet/mamoe/mirai/message/data/MessageChain;
|
||||
public abstract fun getValueArguments ()Ljava/util/List;
|
||||
}
|
||||
|
||||
public final class net/mamoe/mirai/console/command/parse/CommandCallImpl : net/mamoe/mirai/console/command/parse/CommandCall {
|
||||
public fun <init> (Lnet/mamoe/mirai/console/command/CommandSender;Ljava/lang/String;Ljava/util/List;)V
|
||||
public fun <init> (Lnet/mamoe/mirai/console/command/CommandSender;Ljava/lang/String;Ljava/util/List;Lnet/mamoe/mirai/message/data/MessageChain;)V
|
||||
public fun getCalleeName ()Ljava/lang/String;
|
||||
public fun getCaller ()Lnet/mamoe/mirai/console/command/CommandSender;
|
||||
public fun getOriginalMessage ()Lnet/mamoe/mirai/message/data/MessageChain;
|
||||
public fun getValueArguments ()Ljava/util/List;
|
||||
}
|
||||
|
||||
@ -1234,6 +1246,7 @@ public abstract interface class net/mamoe/mirai/console/command/resolve/Resolved
|
||||
public abstract fun getCallee ()Lnet/mamoe/mirai/console/command/Command;
|
||||
public abstract fun getCalleeSignature ()Lnet/mamoe/mirai/console/command/descriptor/CommandSignature;
|
||||
public abstract fun getCaller ()Lnet/mamoe/mirai/console/command/CommandSender;
|
||||
public abstract fun getOriginalMessage ()Lnet/mamoe/mirai/message/data/MessageChain;
|
||||
public abstract fun getRawValueArguments ()Ljava/util/List;
|
||||
public abstract fun getResolvedValueArguments ()Ljava/util/List;
|
||||
}
|
||||
@ -1242,10 +1255,11 @@ public final class net/mamoe/mirai/console/command/resolve/ResolvedCommandCall$C
|
||||
}
|
||||
|
||||
public final class net/mamoe/mirai/console/command/resolve/ResolvedCommandCallImpl : net/mamoe/mirai/console/command/resolve/ResolvedCommandCall {
|
||||
public fun <init> (Lnet/mamoe/mirai/console/command/CommandSender;Lnet/mamoe/mirai/console/command/Command;Lnet/mamoe/mirai/console/command/descriptor/CommandSignature;Ljava/util/List;Lnet/mamoe/mirai/console/command/descriptor/CommandArgumentContext;)V
|
||||
public fun <init> (Lnet/mamoe/mirai/console/command/CommandSender;Lnet/mamoe/mirai/console/command/Command;Lnet/mamoe/mirai/console/command/descriptor/CommandSignature;Ljava/util/List;Lnet/mamoe/mirai/console/command/descriptor/CommandArgumentContext;Lnet/mamoe/mirai/message/data/MessageChain;)V
|
||||
public fun getCallee ()Lnet/mamoe/mirai/console/command/Command;
|
||||
public fun getCalleeSignature ()Lnet/mamoe/mirai/console/command/descriptor/CommandSignature;
|
||||
public fun getCaller ()Lnet/mamoe/mirai/console/command/CommandSender;
|
||||
public fun getOriginalMessage ()Lnet/mamoe/mirai/message/data/MessageChain;
|
||||
public fun getRawValueArguments ()Ljava/util/List;
|
||||
public fun getResolvedValueArguments ()Ljava/util/List;
|
||||
}
|
||||
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.console.command
|
||||
|
||||
import net.mamoe.mirai.message.data.MessageChain
|
||||
import net.mamoe.mirai.utils.NotStableForInheritance
|
||||
|
||||
/**
|
||||
* 指令执行环境
|
||||
* @since 2.12
|
||||
*/
|
||||
@NotStableForInheritance
|
||||
public interface CommandContext {
|
||||
/**
|
||||
* 指令发送者
|
||||
*/
|
||||
public val sender: CommandSender
|
||||
|
||||
/**
|
||||
* 触发指令的原消息链,包含元数据,也包含指令名。
|
||||
*
|
||||
* 示例内容:`messageChainOf(MessageSource(...), PlainText("/test"), PlainText("arg1"))`
|
||||
*/
|
||||
public val originalMessage: MessageChain
|
||||
}
|
||||
|
||||
internal class CommandContextImpl(
|
||||
override val sender: CommandSender,
|
||||
override val originalMessage: MessageChain
|
||||
) : CommandContext
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.console.command
|
||||
@ -66,6 +66,12 @@ import kotlin.annotation.AnnotationTarget.FUNCTION
|
||||
* sendMessage("/manage list 被调用了")
|
||||
* }
|
||||
*
|
||||
* @SubCommand
|
||||
* suspend fun CommandContext.repeat() {
|
||||
* // 使用 CommandContext 作为参数,
|
||||
* sendMessage("/manage list 被调用了")
|
||||
* }
|
||||
*
|
||||
* // 支持 Image 类型, 需在聊天中执行此指令.
|
||||
* @SubCommand
|
||||
* suspend fun UserCommandSender.test(image: Image) { // 执行 "/manage test <一张图片>" 时调用这个函数
|
||||
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.console.command
|
||||
@ -19,7 +19,6 @@ import net.mamoe.mirai.console.permission.Permission
|
||||
import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.message.data.MessageChain
|
||||
import net.mamoe.mirai.message.data.buildMessageChain
|
||||
import kotlin.reflect.typeOf
|
||||
|
||||
/**
|
||||
* 无参数解析, 接收原生参数的指令.
|
||||
@ -60,7 +59,7 @@ public abstract class RawCommand(
|
||||
@ExperimentalCommandDescriptors
|
||||
override val overloads: List<@JvmWildcard CommandSignature> = listOf(
|
||||
CommandSignatureImpl(
|
||||
receiverParameter = CommandReceiverParameter(false, typeOf<CommandSender>()),
|
||||
receiverParameter = CommandReceiverParameter.Context(false),
|
||||
valueParameters = listOf(
|
||||
AbstractCommandValueParameter.UserDefinedType.createRequired<Array<out Message>>(
|
||||
"args",
|
||||
@ -70,7 +69,8 @@ public abstract class RawCommand(
|
||||
) { call ->
|
||||
val sender = call.caller
|
||||
val arguments = call.rawValueArguments
|
||||
sender.onCommand(buildMessageChain { arguments.forEach { +it.value } })
|
||||
val context = CommandContextImpl(sender, call.originalMessage)
|
||||
context.onCommand(buildMessageChain { arguments.forEach { +it.value } })
|
||||
}
|
||||
)
|
||||
|
||||
@ -81,7 +81,21 @@ public abstract class RawCommand(
|
||||
*
|
||||
* @see CommandManager.executeCommand 查看更多信息
|
||||
*/
|
||||
public abstract suspend fun CommandSender.onCommand(args: MessageChain)
|
||||
public open suspend fun CommandSender.onCommand(args: MessageChain) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 在指令被执行时调用.
|
||||
*
|
||||
* @param args 指令参数.
|
||||
* @see CommandManager.executeCommand 查看更多信息
|
||||
*
|
||||
* @since 2.12
|
||||
*/
|
||||
public open suspend fun CommandContext.onCommand(args: MessageChain) {
|
||||
return sender.onCommand(args)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
@ -9,6 +9,7 @@
|
||||
|
||||
package net.mamoe.mirai.console.command.descriptor
|
||||
|
||||
import net.mamoe.mirai.console.command.CommandContext
|
||||
import net.mamoe.mirai.console.command.CommandSender
|
||||
import net.mamoe.mirai.console.command.descriptor.AbstractCommandValueParameter.UserDefinedType.Companion.createOptional
|
||||
import net.mamoe.mirai.console.command.descriptor.AbstractCommandValueParameter.UserDefinedType.Companion.createRequired
|
||||
@ -122,22 +123,50 @@ public sealed class ArgumentAcceptance(
|
||||
}
|
||||
|
||||
@ExperimentalCommandDescriptors
|
||||
public data class CommandReceiverParameter<T : CommandSender>(
|
||||
override val isOptional: Boolean,
|
||||
override val type: KType,
|
||||
public sealed class CommandReceiverParameter<T>(
|
||||
) : CommandParameter<T>, AbstractCommandParameter<T>() {
|
||||
override val name: String get() = NAME
|
||||
|
||||
init {
|
||||
val classifier = type.classifier
|
||||
require(classifier is KClass<*>) {
|
||||
"CommandReceiverParameter.type.classifier must be KClass."
|
||||
}
|
||||
require(classifier.isSubclassOf(CommandSender::class)) {
|
||||
"CommandReceiverParameter.type.classifier must be subclass of CommandSender."
|
||||
/**
|
||||
* @since 2.12
|
||||
*/
|
||||
@ExperimentalCommandDescriptors
|
||||
public class Sender(
|
||||
override val isOptional: Boolean,
|
||||
override val type: KType,
|
||||
) : CommandReceiverParameter<CommandSender>() {
|
||||
init {
|
||||
val classifier = type.classifier
|
||||
require(classifier is KClass<*>) {
|
||||
"CommandReceiverParameter.Sender.type.classifier must be KClass."
|
||||
}
|
||||
require(classifier.isSubclassOf(CommandSender::class)) {
|
||||
"CommandReceiverParameter.Sender.type.classifier must be subclass of CommandSender."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.12
|
||||
*/
|
||||
@ExperimentalCommandDescriptors
|
||||
public class Context(
|
||||
override val isOptional: Boolean,
|
||||
override val type: KType = typeOf<CommandContext>(),
|
||||
) : CommandReceiverParameter<CommandContext>() {
|
||||
init {
|
||||
val classifier = type.classifier
|
||||
require(classifier is KClass<*>) {
|
||||
"CommandReceiverParameter.Context.type.classifier must be KClass."
|
||||
}
|
||||
require(classifier.isSubclassOf(CommandContext::class)) {
|
||||
"CommandReceiverParameter.Context.type.classifier must be subclass of CommandContext."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override val name: String get() = NAME
|
||||
|
||||
|
||||
public companion object {
|
||||
public const val NAME: String = "<receiver>"
|
||||
}
|
||||
@ -221,7 +250,6 @@ public sealed class AbstractCommandValueParameter<T> : CommandValueParameter<T>,
|
||||
}
|
||||
|
||||
private companion object {
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
val STRING_TYPE = typeOf<String>()
|
||||
}
|
||||
}
|
||||
@ -251,13 +279,11 @@ public sealed class AbstractCommandValueParameter<T> : CommandValueParameter<T>,
|
||||
public companion object {
|
||||
@JvmStatic
|
||||
public inline fun <reified T : Any> createOptional(name: String, isVararg: Boolean): UserDefinedType<T> {
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
return UserDefinedType(name, true, isVararg, typeOf<T>())
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public inline fun <reified T : Any> createRequired(name: String, isVararg: Boolean): UserDefinedType<T> {
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
return UserDefinedType(name, false, isVararg, typeOf<T>())
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
@ -25,7 +25,7 @@ public interface CommandSignature {
|
||||
* 接收者参数, 为 [CommandSender] 子类
|
||||
*/
|
||||
@ConsoleExperimentalApi
|
||||
public val receiverParameter: CommandReceiverParameter<out CommandSender>?
|
||||
public val receiverParameter: CommandReceiverParameter<*>?
|
||||
|
||||
/**
|
||||
* 形式 值参数.
|
||||
@ -67,7 +67,7 @@ public abstract class AbstractCommandSignature : CommandSignature {
|
||||
|
||||
@ExperimentalCommandDescriptors
|
||||
public open class CommandSignatureImpl(
|
||||
override val receiverParameter: CommandReceiverParameter<out CommandSender>?,
|
||||
override val receiverParameter: CommandReceiverParameter<*>?,
|
||||
override val valueParameters: List<AbstractCommandValueParameter<*>>,
|
||||
private val onCall: suspend CommandSignatureImpl.(resolvedCommandCall: ResolvedCommandCall) -> Unit,
|
||||
) : CommandSignature, AbstractCommandSignature() {
|
||||
@ -79,7 +79,7 @@ public open class CommandSignatureImpl(
|
||||
@ConsoleExperimentalApi
|
||||
@ExperimentalCommandDescriptors
|
||||
public open class CommandSignatureFromKFunctionImpl(
|
||||
override val receiverParameter: CommandReceiverParameter<out CommandSender>?,
|
||||
override val receiverParameter: CommandReceiverParameter<*>?,
|
||||
override val valueParameters: List<AbstractCommandValueParameter<*>>,
|
||||
override val originFunction: KFunction<*>,
|
||||
private val onCall: suspend CommandSignatureFromKFunctionImpl.(resolvedCommandCall: ResolvedCommandCall) -> Unit,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
@ -20,7 +20,6 @@ import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.message.data.MessageChain
|
||||
import net.mamoe.mirai.message.data.buildMessageChain
|
||||
import net.mamoe.mirai.utils.runBIO
|
||||
import kotlin.reflect.typeOf
|
||||
|
||||
/**
|
||||
* 供 Java 用户继承
|
||||
@ -82,7 +81,7 @@ public abstract class JRawCommand
|
||||
@ExperimentalCommandDescriptors
|
||||
override val overloads: List<@JvmWildcard CommandSignature> = listOf(
|
||||
CommandSignatureImpl(
|
||||
receiverParameter = CommandReceiverParameter(false, typeOf<CommandSender>()),
|
||||
receiverParameter = CommandReceiverParameter.Context(false),
|
||||
valueParameters = listOf(
|
||||
AbstractCommandValueParameter.UserDefinedType.createRequired<Array<out Message>>(
|
||||
"args",
|
||||
@ -92,7 +91,12 @@ public abstract class JRawCommand
|
||||
) { call ->
|
||||
val sender = call.caller
|
||||
val arguments = call.rawValueArguments
|
||||
runBIO { onCommand(sender, buildMessageChain { arguments.forEach { +it.value } }) }
|
||||
runBIO {
|
||||
onCommand(
|
||||
CommandContextImpl(sender, call.originalMessage),
|
||||
buildMessageChain { arguments.forEach { +it.value } }
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@ -105,4 +109,16 @@ public abstract class JRawCommand
|
||||
* @since 2.8
|
||||
*/
|
||||
public open fun onCommand(sender: CommandSender, args: MessageChain) {}
|
||||
|
||||
/**
|
||||
* 在指令被执行时调用.
|
||||
*
|
||||
* @param args 指令参数.
|
||||
*
|
||||
* @see CommandManager.executeCommand 查看更多信息
|
||||
* @since 2.12
|
||||
*/
|
||||
public open fun onCommand(context: CommandContext, args: MessageChain) {
|
||||
onCommand(context.sender, args)
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
@ -50,6 +50,12 @@ public interface CommandCall {
|
||||
*/
|
||||
public val valueArguments: List<CommandValueArgument>
|
||||
|
||||
/**
|
||||
* Original message
|
||||
* @since 2.12
|
||||
*/
|
||||
public val originalMessage: MessageChain
|
||||
|
||||
// maybe add contextual arguments, i.e. from MessageMetadata
|
||||
}
|
||||
|
||||
@ -58,4 +64,5 @@ public class CommandCallImpl(
|
||||
override val caller: CommandSender,
|
||||
override val calleeName: String,
|
||||
override val valueArguments: List<CommandValueArgument>,
|
||||
override val originalMessage: MessageChain,
|
||||
) : CommandCall
|
@ -35,7 +35,8 @@ public object SpaceSeparatedCommandCallParser : CommandCallParser {
|
||||
return CommandCallImpl(
|
||||
caller = caller,
|
||||
calleeName = flatten.first().content,
|
||||
valueArguments = flatten.drop(1).map(::DefaultCommandValueArgument)
|
||||
valueArguments = flatten.drop(1).map(::DefaultCommandValueArgument),
|
||||
originalMessage = message
|
||||
)
|
||||
}
|
||||
}
|
@ -52,7 +52,8 @@ public object BuiltInCommandCallResolver : CommandCallResolver {
|
||||
callee,
|
||||
signature.signature,
|
||||
signature.zippedArguments.map { it.second },
|
||||
context ?: EmptyCommandArgumentContext
|
||||
context ?: EmptyCommandArgumentContext,
|
||||
call.originalMessage,
|
||||
)
|
||||
)
|
||||
}
|
||||
@ -101,14 +102,24 @@ public object BuiltInCommandCallResolver : CommandCallResolver {
|
||||
): ResolveData? {
|
||||
val signature = this
|
||||
val receiverParameter = signature.receiverParameter
|
||||
if (receiverParameter?.type?.classifierAsKClass()?.isInstance(caller) == false) {
|
||||
errorSink.reportUnmatched(
|
||||
UnmatchedCommandSignature(
|
||||
signature,
|
||||
FailureReason.InapplicableReceiverArgument(receiverParameter, caller)
|
||||
)
|
||||
)// not compatible receiver
|
||||
return null
|
||||
|
||||
if (receiverParameter != null) {
|
||||
when (receiverParameter) {
|
||||
is CommandReceiverParameter.Context -> {
|
||||
// accepts any sender
|
||||
}
|
||||
is CommandReceiverParameter.Sender -> {
|
||||
if (!receiverParameter.type.classifierAsKClass().isInstance(caller)) {
|
||||
errorSink.reportUnmatched(
|
||||
UnmatchedCommandSignature(
|
||||
signature,
|
||||
FailureReason.InapplicableReceiverArgument(receiverParameter, caller)
|
||||
)
|
||||
)// not compatible receiver
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val valueParameters = signature.valueParameters
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
@ -20,6 +20,7 @@ import net.mamoe.mirai.console.command.parse.mapToTypeOrNull
|
||||
import net.mamoe.mirai.console.internal.data.classifierAsKClass
|
||||
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
||||
import net.mamoe.mirai.console.util.cast
|
||||
import net.mamoe.mirai.message.data.MessageChain
|
||||
|
||||
/**
|
||||
* The resolved [CommandCall].
|
||||
@ -60,6 +61,11 @@ public interface ResolvedCommandCall {
|
||||
@ConsoleExperimentalApi
|
||||
public val resolvedValueArguments: List<ResolvedCommandValueArgument<*>>
|
||||
|
||||
/**
|
||||
* @since 2.12
|
||||
*/
|
||||
public val originalMessage: MessageChain
|
||||
|
||||
public companion object
|
||||
}
|
||||
|
||||
@ -94,6 +100,7 @@ public class ResolvedCommandCallImpl(
|
||||
override val calleeSignature: CommandSignature,
|
||||
override val rawValueArguments: List<CommandValueArgument>,
|
||||
private val context: CommandArgumentContext,
|
||||
override val originalMessage: MessageChain,
|
||||
) : ResolvedCommandCall {
|
||||
override val resolvedValueArguments: List<ResolvedCommandValueArgument<*>> by lazy {
|
||||
calleeSignature.valueParameters.zip(rawValueArguments).map { (parameter, argument) ->
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
@ -19,10 +19,7 @@ import net.mamoe.mirai.message.data.PlainText
|
||||
import net.mamoe.mirai.message.data.SingleMessage
|
||||
import net.mamoe.mirai.message.data.buildMessageChain
|
||||
import net.mamoe.mirai.utils.runBIO
|
||||
import kotlin.reflect.KFunction
|
||||
import kotlin.reflect.KParameter
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.reflect.KVisibility
|
||||
import kotlin.reflect.*
|
||||
import kotlin.reflect.full.*
|
||||
|
||||
|
||||
@ -130,7 +127,7 @@ public class IllegalCommandDeclarationException : Exception {
|
||||
@OptIn(ExperimentalCommandDescriptors::class)
|
||||
internal class CommandReflector(
|
||||
val command: Command,
|
||||
val annotationResolver: SubCommandAnnotationResolver,
|
||||
private val annotationResolver: SubCommandAnnotationResolver,
|
||||
) {
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
@ -143,8 +140,11 @@ internal class CommandReflector(
|
||||
private fun KFunction<*>.isSubCommandFunction(): Boolean = annotationResolver.hasAnnotation(command, this)
|
||||
private fun KFunction<*>.checkExtensionReceiver() {
|
||||
this.extensionReceiverParameter?.let { receiver ->
|
||||
if (receiver.type.classifierAsKClassOrNull()?.isSubclassOf(CommandSender::class) != true) {
|
||||
illegalDeclaration("Extension receiver parameter type is not subclass of CommandSender.")
|
||||
val classifier = receiver.type.classifierAsKClassOrNull()
|
||||
if (classifier != null) {
|
||||
if (!classifier.isSubclassOf(CommandSender::class) && !classifier.isSubclassOf(CommandContext::class)) {
|
||||
illegalDeclaration("Extension receiver parameter type is not subclass of CommandSender nor CommandContext.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -279,8 +279,8 @@ internal class CommandReflector(
|
||||
var receiverParameter = function.extensionReceiverParameter
|
||||
if (receiverParameter == null && valueParameters.isNotEmpty()) {
|
||||
val valueFirstParameter = valueParameters[0]
|
||||
if (valueFirstParameter.type.classifierAsKClassOrNull()
|
||||
?.isSubclassOf(CommandSender::class) == true
|
||||
val classifier = valueFirstParameter.type.classifierAsKClassOrNull()
|
||||
if (classifier != null && isAcceptableReceiverType(classifier)
|
||||
) {
|
||||
receiverParameter = valueFirstParameter
|
||||
valueParameters.removeAt(0)
|
||||
@ -317,14 +317,22 @@ internal class CommandReflector(
|
||||
}
|
||||
|
||||
if (receiverParameter != null) {
|
||||
check(receiverParameter.type.classifierAsKClass().isInstance(call.caller)) {
|
||||
"Bad command call resolved. " +
|
||||
"Function expects receiver parameter ${receiverParameter.type} whereas actual is ${call.caller::class}."
|
||||
|
||||
val receiverType = receiverParameter.type.classifierAsKClass()
|
||||
|
||||
if (receiverType.isSubclassOf(CommandContext::class)) {
|
||||
args[receiverParameter] = CommandContextImpl(call.caller, call.originalMessage)
|
||||
} else {
|
||||
check(receiverType.isInstance(call.caller)) {
|
||||
"Bad command call resolved. " +
|
||||
"Function expects receiver parameter ${receiverParameter.type} whereas actual is ${call.caller::class}."
|
||||
}
|
||||
args[receiverParameter] = call.caller
|
||||
}
|
||||
args[receiverParameter] = call.caller
|
||||
|
||||
}
|
||||
|
||||
// #341
|
||||
// mirai-console#341
|
||||
if (function.isSuspend) {
|
||||
function.callSuspendBy(args)
|
||||
} else {
|
||||
@ -334,18 +342,29 @@ internal class CommandReflector(
|
||||
}.toList()
|
||||
}
|
||||
|
||||
private fun isAcceptableReceiverType(classifier: KClass<Any>) =
|
||||
classifier.isSubclassOf(CommandSender::class) || classifier.isSubclassOf(CommandContext::class)
|
||||
|
||||
@Suppress("SameParameterValue")
|
||||
private fun <K, V> createMapEntry(key: K, value: V) = object : Map.Entry<K, V> {
|
||||
override val key: K get() = key
|
||||
override val value: V get() = value
|
||||
}
|
||||
|
||||
private fun KParameter.toCommandReceiverParameter(): CommandReceiverParameter<out CommandSender> {
|
||||
private fun KParameter.toCommandReceiverParameter(): CommandReceiverParameter<*> {
|
||||
check(!this.isVararg) { "Receiver cannot be vararg." }
|
||||
check(
|
||||
this.type.classifierAsKClass().isSubclassOf(CommandSender::class)
|
||||
) { "Receiver must be subclass of CommandSender" }
|
||||
|
||||
return CommandReceiverParameter(this.type.isMarkedNullable, this.type)
|
||||
val classifier = type.classifierAsKClass()
|
||||
return when {
|
||||
classifier.isSubclassOf(CommandSender::class) -> {
|
||||
CommandReceiverParameter.Sender(this.type.isMarkedNullable, this.type)
|
||||
}
|
||||
classifier.isSubclassOf(CommandContext::class) -> {
|
||||
CommandReceiverParameter.Context(this.type.isMarkedNullable, this.type)
|
||||
}
|
||||
else -> {
|
||||
throw IllegalArgumentException("Receiver must be subclass of CommandSender or CommandContext")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createStringConstantParameterForName(
|
||||
|
@ -16,4 +16,8 @@ import net.mamoe.mirai.console.testFramework.AbstractConsoleInstanceTest
|
||||
internal abstract class AbstractCommandTest : AbstractConsoleInstanceTest() {
|
||||
val dataScope get() = DataScope as ConsoleDataScopeImpl
|
||||
val consoleSender get() = ConsoleCommandSender
|
||||
|
||||
|
||||
open val sender: CommandSender get() = ConsoleCommandSender
|
||||
open val owner: CommandOwner get() = ConsoleCommandOwner
|
||||
}
|
@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalCommandDescriptors::class)
|
||||
@file:Suppress("unused", "UNUSED_PARAMETER")
|
||||
|
||||
package net.mamoe.mirai.console.command
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.mamoe.mirai.console.Testing
|
||||
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
|
||||
import net.mamoe.mirai.console.command.java.JCompositeCommand
|
||||
import net.mamoe.mirai.console.command.java.JRawCommand
|
||||
import net.mamoe.mirai.console.command.java.JSimpleCommand
|
||||
import net.mamoe.mirai.console.internal.data.classifierAsKClass
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.utils.safeCast
|
||||
import org.apache.commons.lang3.ArrayUtils.isSameType
|
||||
import org.junit.jupiter.api.DynamicTest
|
||||
import org.junit.jupiter.api.TestFactory
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
internal class CommandContextTest : AbstractCommandTest() {
|
||||
private class MyMetadata : MessageMetadata {
|
||||
override fun hashCode(): Int = javaClass.hashCode()
|
||||
override fun equals(other: Any?): Boolean = isSameType(this, other)
|
||||
|
||||
override fun toString(): String = "MyMetadata"
|
||||
|
||||
companion object Key : AbstractMessageKey<MyMetadata>({ it.safeCast() })
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// RawCommand
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@TestFactory
|
||||
fun `can execute with sender`(): List<DynamicTest> {
|
||||
return listOf(
|
||||
object : RawCommand(owner, "test") {
|
||||
override suspend fun CommandContext.onCommand(args: MessageChain) {
|
||||
Testing.ok(args)
|
||||
}
|
||||
} to "/test foo",
|
||||
object : SimpleCommand(owner, "test") {
|
||||
@Handler
|
||||
fun CommandContext.foo(arg: MessageChain) {
|
||||
Testing.ok(arg)
|
||||
}
|
||||
} to "/test foo",
|
||||
object : CompositeCommand(owner, "test") {
|
||||
@SubCommand
|
||||
fun CommandContext.sub(arg: MessageChain) {
|
||||
Testing.ok(arg)
|
||||
}
|
||||
} to "/test sub foo",
|
||||
|
||||
object : JRawCommand(owner, "test") {
|
||||
override fun onCommand(context: CommandContext, args: MessageChain) {
|
||||
Testing.ok(args)
|
||||
}
|
||||
} to "/test foo",
|
||||
object : JSimpleCommand(owner, "test") {
|
||||
@Handler
|
||||
fun foo(context: CommandContext, arg: MessageChain) {
|
||||
Testing.ok(arg)
|
||||
}
|
||||
} to "/test foo",
|
||||
object : JCompositeCommand(owner, "test") {
|
||||
@SubCommand
|
||||
fun sub(context: CommandContext, arg: MessageChain) {
|
||||
Testing.ok(arg)
|
||||
}
|
||||
} to "/test sub foo",
|
||||
).map { (instance, cmd) ->
|
||||
DynamicTest.dynamicTest(instance::class.supertypes.first().classifierAsKClass().simpleName) {
|
||||
runBlocking {
|
||||
instance.withRegistration {
|
||||
assertEquals(
|
||||
messageChainOf(PlainText("foo")),
|
||||
Testing.withTesting {
|
||||
assertSuccess(sender.executeCommand(cmd, checkPermission = false))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestFactory
|
||||
fun `RawCommand can execute and get original chain`(): List<DynamicTest> {
|
||||
return listOf(
|
||||
object : RawCommand(owner, "test") {
|
||||
override suspend fun CommandContext.onCommand(args: MessageChain) {
|
||||
Testing.ok(originalMessage)
|
||||
}
|
||||
} to "/test foo",
|
||||
object : SimpleCommand(owner, "test") {
|
||||
@Handler
|
||||
fun CommandContext.foo(arg: MessageChain) {
|
||||
Testing.ok(originalMessage)
|
||||
}
|
||||
} to "/test foo",
|
||||
object : CompositeCommand(owner, "test") {
|
||||
@SubCommand
|
||||
fun CommandContext.sub(arg: MessageChain) {
|
||||
Testing.ok(originalMessage)
|
||||
}
|
||||
} to "/test sub foo",
|
||||
|
||||
object : JRawCommand(owner, "test") {
|
||||
override fun onCommand(context: CommandContext, args: MessageChain) {
|
||||
Testing.ok(context.originalMessage)
|
||||
}
|
||||
} to "/test foo",
|
||||
object : JSimpleCommand(owner, "test") {
|
||||
@Handler
|
||||
fun foo(context: CommandContext, arg: MessageChain) {
|
||||
Testing.ok(context.originalMessage)
|
||||
}
|
||||
} to "/test foo",
|
||||
object : JCompositeCommand(owner, "test") {
|
||||
@SubCommand
|
||||
fun sub(context: CommandContext, arg: MessageChain) {
|
||||
Testing.ok(context.originalMessage)
|
||||
}
|
||||
} to "/test sub foo",
|
||||
).map { (instance, cmd) ->
|
||||
DynamicTest.dynamicTest(instance::class.supertypes.first().classifierAsKClass().simpleName) {
|
||||
runBlocking {
|
||||
instance.withRegistration {
|
||||
assertEquals(
|
||||
cmd,
|
||||
Testing.withTesting<MessageChain> {
|
||||
assertSuccess(sender.executeCommand(cmd, checkPermission = false))
|
||||
}.contentToString()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestFactory
|
||||
fun `can execute and get metadata`(): List<DynamicTest> {
|
||||
val metadata = MyMetadata()
|
||||
return listOf(
|
||||
object : RawCommand(owner, "test") {
|
||||
override suspend fun CommandContext.onCommand(args: MessageChain) {
|
||||
Testing.ok(originalMessage[MyMetadata])
|
||||
}
|
||||
} to messageChainOf(PlainText("/test"), metadata, PlainText("foo")),
|
||||
object : SimpleCommand(owner, "test") {
|
||||
@Handler
|
||||
fun CommandContext.foo(arg: MessageChain) {
|
||||
Testing.ok(originalMessage[MyMetadata])
|
||||
}
|
||||
} to messageChainOf(PlainText("/test"), metadata, PlainText("foo")),
|
||||
object : CompositeCommand(owner, "test") {
|
||||
@SubCommand
|
||||
fun CommandContext.sub(arg: MessageChain) {
|
||||
Testing.ok(originalMessage[MyMetadata])
|
||||
}
|
||||
} to messageChainOf(PlainText("/test"), PlainText("sub"), metadata, PlainText("foo")),
|
||||
|
||||
|
||||
object : JRawCommand(owner, "test") {
|
||||
override fun onCommand(context: CommandContext, args: MessageChain) {
|
||||
Testing.ok(context.originalMessage[MyMetadata])
|
||||
}
|
||||
} to messageChainOf(PlainText("/test"), metadata, PlainText("foo")),
|
||||
object : JSimpleCommand(owner, "test") {
|
||||
@Handler
|
||||
fun foo(context: CommandContext, arg: MessageChain) {
|
||||
Testing.ok(context.originalMessage[MyMetadata])
|
||||
}
|
||||
} to messageChainOf(PlainText("/test"), metadata, PlainText("foo")),
|
||||
object : JCompositeCommand(owner, "test") {
|
||||
@SubCommand
|
||||
fun sub(context: CommandContext, arg: MessageChain) {
|
||||
Testing.ok(context.originalMessage[MyMetadata])
|
||||
}
|
||||
} to messageChainOf(PlainText("/test"), PlainText("sub"), metadata, PlainText("foo")),
|
||||
).map { (instance, cmd) ->
|
||||
DynamicTest.dynamicTest(instance::class.supertypes.first().classifierAsKClass().simpleName) {
|
||||
runBlocking {
|
||||
instance.withRegistration {
|
||||
assertEquals(
|
||||
metadata,
|
||||
Testing.withTesting {
|
||||
assertSuccess(CommandManager.executeCommand(sender, cmd, checkPermission = false))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestFactory
|
||||
fun `RawCommand can execute and get chain including metadata`(): List<DynamicTest> {
|
||||
val metadata = MyMetadata()
|
||||
return listOf(
|
||||
object : RawCommand(owner, "test") {
|
||||
override suspend fun CommandContext.onCommand(args: MessageChain) {
|
||||
Testing.ok(originalMessage)
|
||||
}
|
||||
} to messageChainOf(PlainText("/test"), metadata, PlainText("foo")),
|
||||
object : SimpleCommand(owner, "test") {
|
||||
@Handler
|
||||
fun CommandContext.foo(arg: MessageChain) {
|
||||
Testing.ok(originalMessage)
|
||||
}
|
||||
} to messageChainOf(PlainText("/test"), metadata, PlainText("foo")),
|
||||
object : CompositeCommand(owner, "test") {
|
||||
@SubCommand
|
||||
fun CommandContext.sub(arg: MessageChain) {
|
||||
Testing.ok(originalMessage)
|
||||
}
|
||||
} to messageChainOf(PlainText("/test"), PlainText("sub"), metadata, PlainText("foo")),
|
||||
|
||||
|
||||
object : JRawCommand(owner, "test") {
|
||||
override fun onCommand(context: CommandContext, args: MessageChain) {
|
||||
Testing.ok(context.originalMessage)
|
||||
}
|
||||
} to messageChainOf(PlainText("/test"), metadata, PlainText("foo")),
|
||||
object : JSimpleCommand(owner, "test") {
|
||||
@Handler
|
||||
fun foo(context: CommandContext, arg: MessageChain) {
|
||||
Testing.ok(context.originalMessage)
|
||||
}
|
||||
} to messageChainOf(PlainText("/test"), metadata, PlainText("foo")),
|
||||
object : JCompositeCommand(owner, "test") {
|
||||
@SubCommand
|
||||
fun sub(context: CommandContext, arg: MessageChain) {
|
||||
Testing.ok(context.originalMessage)
|
||||
}
|
||||
} to messageChainOf(PlainText("/test"), PlainText("sub"), metadata, PlainText("foo")),
|
||||
).map { (instance, cmd) ->
|
||||
DynamicTest.dynamicTest(instance::class.supertypes.first().classifierAsKClass().simpleName) {
|
||||
runBlocking {
|
||||
instance.withRegistration {
|
||||
assertEquals(
|
||||
cmd,
|
||||
Testing.withTesting {
|
||||
assertSuccess(CommandManager.executeCommand(sender, cmd, checkPermission = false))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -156,7 +156,7 @@ class TestTemporalArgCommand : CompositeCommand(owner, "testtemporal") {
|
||||
}
|
||||
|
||||
private val sender get() = ConsoleCommandSender
|
||||
internal val owner get() = ConsoleCommandOwner
|
||||
private val owner get() = ConsoleCommandOwner
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_METHOD)
|
||||
@OptIn(ExperimentalCommandDescriptors::class)
|
||||
|
Loading…
Reference in New Issue
Block a user