From f69c41f64e42cb2df345dc6cf54cf7383106aa45 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sun, 23 Aug 2020 17:43:40 +0800 Subject: [PATCH] Extract Java implementations to java package. Update docs --- .../mamoe/mirai/console/command/Command.kt | 7 +- .../mirai/console/command/CompositeCommand.kt | 74 ++-------------- .../mamoe/mirai/console/command/RawCommand.kt | 69 +-------------- .../mirai/console/command/SimpleCommand.kt | 46 ++-------- .../mirai/console/command/java/JCommand.kt | 40 +++++++++ .../console/command/java/JCompositeCommand.kt | 85 +++++++++++++++++++ .../mirai/console/command/java/JRawCommand.kt | 84 ++++++++++++++++++ .../console/command/java/JSimpleCommand.kt | 54 ++++++++++++ 8 files changed, 284 insertions(+), 175 deletions(-) create mode 100644 backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/java/JCommand.kt create mode 100644 backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/java/JCompositeCommand.kt create mode 100644 backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/java/JRawCommand.kt create mode 100644 backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/java/JSimpleCommand.kt diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt index b2082d66c..32d19b777 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt @@ -14,6 +14,7 @@ package net.mamoe.mirai.console.command import net.mamoe.kjbb.JvmBlockingBridge import net.mamoe.mirai.console.command.CommandManager.INSTANCE.executeCommand import net.mamoe.mirai.console.command.CommandManager.INSTANCE.register +import net.mamoe.mirai.console.command.java.JCommand import net.mamoe.mirai.console.internal.command.isValidSubName import net.mamoe.mirai.message.data.SingleMessage @@ -25,15 +26,19 @@ import net.mamoe.mirai.message.data.SingleMessage * @see RawCommand 无参数解析, 接收原生参数的指令 * @see CompositeCommand 复合指令 * @see SimpleCommand 简单的, 支持参数自动解析的指令 + * + * @see JCommand 为 Java 用户添加协程帮助的 [Command] */ public interface Command { /** * 指令名. 需要至少有一个元素. 所有元素都不能带有空格 + * + * @see Command.primaryName 获取主要指令名 */ public val names: Array /** - * 用法说明, 用于发送给用户 + * 用法说明, 用于发送给用户. 一般 [usage] 包含 [description]. */ public val usage: String diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CompositeCommand.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CompositeCommand.kt index d08d98d60..4f01895e4 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CompositeCommand.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CompositeCommand.kt @@ -82,6 +82,12 @@ public abstract class CompositeCommand( overrideContext: CommandArgumentContext = EmptyCommandArgumentContext ) : Command, AbstractReflectionCommand(owner, names, description, permission, prefixOptional), CommandArgumentContextAware { + + /** + * 自动根据带有 [SubCommand] 注解的函数签名生成 [usage]. 也可以被覆盖. + */ + public override val usage: String get() = super.usage + /** * [CommandArgumentParser] 的环境 */ @@ -126,71 +132,3 @@ public abstract class CompositeCommand( } -/** - * 复合指令. 指令注册时候会通过反射构造指令解析器. - * - * 示例: - * ``` - * public final class MyCompositeCommand extends CompositeCommand { - * public static final MyCompositeCommand INSTANCE = new MyCompositeCommand(); - * - * public MyCompositeCommand() { - * super(MyPluginMain.INSTANCE, "manage") // "manage" 是主指令名 - * } - * - * // [参数智能解析] - * // - * // - * // 在控制台执行 "/manage <群号>.<群员> <持续时间>", - * // 或在聊天群内发送 "/manage <@一个群员> <持续时间>", - * // 或在聊天群内发送 "/manage <目标群员的群名> <持续时间>", - * // 或在聊天群内发送 "/manage <目标群员的账号> <持续时间>" - * // 时调用这个函数 - * @SubCommand - * public void mute(CommandSender sender, Member target, int duration) { // 通过 /manage mute 调用. - * sender.sendMessage("/manage mute 被调用了, 参数为: " + target + ", " + duration); - * - * - * String result; - * try { - * result = target.mute(duration).toString(); - * } catch(Exception e) { - * result = ExceptionsKt.stackTraceToString(e); - * } - * - * sender.sendMessage("结果: " + result) - * } - * - * @SubCommand - * public void list(CommandSender sender) { // 执行 "/manage list" 时调用这个方法 - * sender.sendMessage("/manage list 被调用了") - * } - * - * // 支持 Image 类型, 需在聊天中执行此指令. - * @SubCommand - * public void test(CommandSender sender, Image image) { // 执行 "/manage test <一张图片>" 时调用这个方法 - * sender.sendMessage("/manage image 被调用了, 图片是 " + image.imageId) - * } - * } - * ``` - * - * @see buildCommandArgumentContext - */ -@ConsoleExperimentalAPI -public abstract class JCompositeCommand( - owner: CommandOwner, - vararg names: String -) : CompositeCommand(owner, *names) { - /** 指令描述, 用于显示在 [BuiltInCommands.Help] */ - public final override var description: String = "" - protected set - - /** 指令权限 */ - public final override var permission: CommandPermission = CommandPermission.Default - protected set - - /** 为 `true` 时表示 [指令前缀][CommandManager.commandPrefix] 可选 */ - public final override var prefixOptional: Boolean = false - protected set - -} \ No newline at end of file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/RawCommand.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/RawCommand.kt index 23ae60fc3..dfbecbe81 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/RawCommand.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/RawCommand.kt @@ -11,10 +11,9 @@ package net.mamoe.mirai.console.command -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext import net.mamoe.mirai.console.command.CommandManager.INSTANCE.execute import net.mamoe.mirai.console.command.CommandManager.INSTANCE.executeCommand +import net.mamoe.mirai.console.command.java.JRawCommand import net.mamoe.mirai.message.data.SingleMessage /** @@ -56,69 +55,3 @@ public abstract class RawCommand( } -/** - * 供 Java 用户继承 - * - * 请在构造时设置相关属性. - * - * ```java - * public final class MyCommand extends JRawCommand { - * public static final MyCommand INSTANCE = new MyCommand(); - * private MyCommand () { - * super(MyPluginMain.INSTANCE, "test") - * // 可选设置如下属性 - * setUsage("/test") - * setDescription("这是一个测试指令") - * setPermission(CommandPermission.Operator.INSTANCE) - * setPrefixOptional(true) - * } - * - * @Override - * public void onCommand(@NotNull CommandSender sender, @NotNull args: Object[]) { - * // 处理指令 - * } - * } - * ``` - * - * @see RawCommand - */ -public abstract class JRawCommand( - /** - * 指令拥有者. - * @see CommandOwner - */ - public override val owner: CommandOwner, - /** 指令名. 需要至少有一个元素. 所有元素都不能带有空格 */ - public override vararg val names: String -) : Command { - /** 用法说明, 用于发送给用户 */ - public override var usage: String = "" - protected set - - /** 指令描述, 用于显示在 [BuiltInCommands.Help] */ - public final override var description: String = "" - protected set - - /** 指令权限 */ - public final override var permission: CommandPermission = CommandPermission.Default - protected set - - /** 为 `true` 时表示 [指令前缀][CommandManager.commandPrefix] 可选 */ - public final override var prefixOptional: Boolean = false - protected set - - /** - * 在指令被执行时调用. - * - * @param args 指令参数. 数组元素类型可能是 [SingleMessage] 或 [String]. 且已经以 ' ' 分割. - * - * @see CommandManager.execute 查看更多信息 - */ - @Suppress("INAPPLICABLE_JVM_NAME") - @JvmName("onCommand") - public abstract fun onCommand(sender: CommandSender, args: Array) - - public final override suspend fun CommandSender.onCommand(args: Array) { - withContext(Dispatchers.IO) { onCommand(this@onCommand, args) } - } -} \ No newline at end of file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/SimpleCommand.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/SimpleCommand.kt index eeb432cc7..e31a13a45 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/SimpleCommand.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/SimpleCommand.kt @@ -19,6 +19,7 @@ package net.mamoe.mirai.console.command import net.mamoe.mirai.console.command.CommandManager.INSTANCE.executeCommand import net.mamoe.mirai.console.command.description.* +import net.mamoe.mirai.console.command.java.JSimpleCommand import net.mamoe.mirai.console.internal.command.AbstractReflectionCommand import net.mamoe.mirai.console.internal.command.SimpleCommandSubCommandAnnotationResolver @@ -55,14 +56,19 @@ public abstract class SimpleCommand( ) : Command, AbstractReflectionCommand(owner, names, description, permission, prefixOptional), CommandArgumentContextAware { - public override val usage: String - get() = super.usage + /** + * 自动根据带有 [Handler] 注解的函数签名生成 [usage]. 也可以被覆盖. + */ + public override val usage: String get() = super.usage /** * 标注指令处理器 */ protected annotation class Handler + /** + * 指令参数环境. 默认为 [CommandArgumentContext.Builtins] `+` `overrideContext` + */ public override val context: CommandArgumentContext = CommandArgumentContext.Builtins + overrideContext public final override suspend fun CommandSender.onCommand(args: Array) { @@ -81,39 +87,3 @@ public abstract class SimpleCommand( get() = SimpleCommandSubCommandAnnotationResolver } -/** - * Java 实现: - * ```java - * public final class MySimpleCommand extends JSimpleCommand { - * private MySimpleCommand() { - * super(MyPlugin.INSTANCE, "tell") - * // 可选设置如下属性 - * setDescription("这是一个测试指令") - * setUsage("/tell ") // 如不设置则自动根据带有 @Handler 的方法生成 - * setPermission(CommandPermission.Operator.INSTANCE) - * setPrefixOptional(true) - * } - * - * @Handler - * public void onCommand(CommandSender sender, User target, String message) { - * target.sendMessage(message) - * } - * } - * ``` - * - * @see SimpleCommand - * @see [CommandManager.executeCommand] - */ -public abstract class JSimpleCommand( - owner: CommandOwner, - vararg names: String -) : SimpleCommand(owner, *names) { - public override var description: String = super.description - protected set - public override var permission: CommandPermission = super.permission - protected set - public override var prefixOptional: Boolean = super.prefixOptional - protected set - public override var context: CommandArgumentContext = super.context - protected set -} \ No newline at end of file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/java/JCommand.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/java/JCommand.kt new file mode 100644 index 000000000..3ff1276e5 --- /dev/null +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/java/JCommand.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2019-2020 Mamoe Technologies and contributors. + * + * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions 许可证的约束, 可以在以下链接找到该许可证. + * Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions license that can be found via the following link. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.console.command.java + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import net.mamoe.mirai.console.command.Command +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.SingleMessage + +/** + * 为 Java 用户添加协程帮助的 [Command]. + * + * 注意, [JSimpleCommand], [JCompositeCommand], [JRawCommand] 都不实现这个接口. [JCommand] 只设计为 Java 使用者自己实现 [Command] 相关内容. + * + * @see Command + */ +public interface JCommand : Command { + public override suspend fun CommandSender.onCommand(args: Array) { + withContext(Dispatchers.IO) { onCommand(this@onCommand, args) } + } + + /** + * 在指令被执行时调用. + * + * @param args 指令参数. 数组元素类型可能是 [SingleMessage] 或 [String]. 且已经以 ' ' 分割. + * + * @see CommandManager.executeCommand 查看更多信息 + */ + public fun onCommand(sender: CommandSender, args: Array) // overrides bridge +} \ No newline at end of file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/java/JCompositeCommand.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/java/JCompositeCommand.kt new file mode 100644 index 000000000..af39fc738 --- /dev/null +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/java/JCompositeCommand.kt @@ -0,0 +1,85 @@ +/* + * Copyright 2019-2020 Mamoe Technologies and contributors. + * + * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions 许可证的约束, 可以在以下链接找到该许可证. + * Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions license that can be found via the following link. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.console.command.java + +import net.mamoe.mirai.console.command.CommandOwner +import net.mamoe.mirai.console.command.CommandPermission +import net.mamoe.mirai.console.command.CompositeCommand +import net.mamoe.mirai.console.command.description.buildCommandArgumentContext +import net.mamoe.mirai.console.util.ConsoleExperimentalAPI + +/** + * 复合指令. 指令注册时候会通过反射构造指令解析器. + * + * 示例: + * ``` + * public final class MyCompositeCommand extends CompositeCommand { + * public static final MyCompositeCommand INSTANCE = new MyCompositeCommand(); + * + * public MyCompositeCommand() { + * super(MyPluginMain.INSTANCE, "manage") // "manage" 是主指令名 + * } + * + * // [参数智能解析] + * // + * // + * // 在控制台执行 "/manage <群号>.<群员> <持续时间>", + * // 或在聊天群内发送 "/manage <@一个群员> <持续时间>", + * // 或在聊天群内发送 "/manage <目标群员的群名> <持续时间>", + * // 或在聊天群内发送 "/manage <目标群员的账号> <持续时间>" + * // 时调用这个函数 + * @SubCommand + * public void mute(CommandSender sender, Member target, int duration) { // 通过 /manage mute 调用. + * sender.sendMessage("/manage mute 被调用了, 参数为: " + target + ", " + duration); + * + * + * String result; + * try { + * result = target.mute(duration).toString(); + * } catch(Exception e) { + * result = ExceptionsKt.stackTraceToString(e); + * } + * + * sender.sendMessage("结果: " + result) + * } + * + * @SubCommand + * public void list(CommandSender sender) { // 执行 "/manage list" 时调用这个方法 + * sender.sendMessage("/manage list 被调用了") + * } + * + * // 支持 Image 类型, 需在聊天中执行此指令. + * @SubCommand + * public void test(CommandSender sender, Image image) { // 执行 "/manage test <一张图片>" 时调用这个方法 + * sender.sendMessage("/manage image 被调用了, 图片是 " + image.imageId) + * } + * } + * ``` + * + * @see buildCommandArgumentContext + */ +@ConsoleExperimentalAPI +public abstract class JCompositeCommand( + owner: CommandOwner, + vararg names: String +) : CompositeCommand(owner, *names) { + /** 指令描述, 用于显示在 [BuiltInCommands.Help] */ + public final override var description: String = "" + protected set + + /** 指令权限 */ + public final override var permission: CommandPermission = CommandPermission.Default + protected set + + /** 为 `true` 时表示 [指令前缀][CommandManager.commandPrefix] 可选 */ + public final override var prefixOptional: Boolean = false + protected set + +} \ No newline at end of file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/java/JRawCommand.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/java/JRawCommand.kt new file mode 100644 index 000000000..79083f095 --- /dev/null +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/java/JRawCommand.kt @@ -0,0 +1,84 @@ +/* + * Copyright 2019-2020 Mamoe Technologies and contributors. + * + * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions 许可证的约束, 可以在以下链接找到该许可证. + * Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions license that can be found via the following link. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.console.command.java + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import net.mamoe.mirai.console.command.Command +import net.mamoe.mirai.console.command.CommandOwner +import net.mamoe.mirai.console.command.CommandPermission +import net.mamoe.mirai.console.command.CommandSender + +/** + * 供 Java 用户继承 + * + * 请在构造时设置相关属性. + * + * ```java + * public final class MyCommand extends JRawCommand { + * public static final MyCommand INSTANCE = new MyCommand(); + * private MyCommand() { + * super(MyPluginMain.INSTANCE, "test") + * // 可选设置如下属性 + * setUsage("/test") + * setDescription("这是一个测试指令") + * setPermission(CommandPermission.Operator.INSTANCE) + * setPrefixOptional(true) + * } + * + * @Override + * public void onCommand(@NotNull CommandSender sender, @NotNull args: Object[]) { + * // 处理指令 + * } + * } + * ``` + * + * @see JRawCommand + */ +public abstract class JRawCommand( + /** + * 指令拥有者. + * @see CommandOwner + */ + public override val owner: CommandOwner, + /** 指令名. 需要至少有一个元素. 所有元素都不能带有空格 */ + public override vararg val names: String +) : Command { + /** 用法说明, 用于发送给用户 */ + public override var usage: String = "" + protected set + + /** 指令描述, 用于显示在 [BuiltInCommands.Help] */ + public final override var description: String = "" + protected set + + /** 指令权限 */ + public final override var permission: CommandPermission = CommandPermission.Default + protected set + + /** 为 `true` 时表示 [指令前缀][CommandManager.commandPrefix] 可选 */ + public final override var prefixOptional: Boolean = false + protected set + + /** + * 在指令被执行时调用. + * + * @param args 指令参数. 数组元素类型可能是 [SingleMessage] 或 [String]. 且已经以 ' ' 分割. + * + * @see CommandManager.execute 查看更多信息 + */ + @Suppress("INAPPLICABLE_JVM_NAME") + @JvmName("onCommand") + public abstract fun onCommand(sender: CommandSender, args: Array) + + public final override suspend fun CommandSender.onCommand(args: Array) { + withContext(Dispatchers.IO) { onCommand(this@onCommand, args) } + } +} \ No newline at end of file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/java/JSimpleCommand.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/java/JSimpleCommand.kt new file mode 100644 index 000000000..2f6716ad2 --- /dev/null +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/java/JSimpleCommand.kt @@ -0,0 +1,54 @@ +/* + * Copyright 2019-2020 Mamoe Technologies and contributors. + * + * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions 许可证的约束, 可以在以下链接找到该许可证. + * Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions license that can be found via the following link. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.console.command.java + +import net.mamoe.mirai.console.command.CommandManager +import net.mamoe.mirai.console.command.CommandManager.INSTANCE.executeCommand +import net.mamoe.mirai.console.command.CommandOwner +import net.mamoe.mirai.console.command.CommandPermission +import net.mamoe.mirai.console.command.SimpleCommand +import net.mamoe.mirai.console.command.description.CommandArgumentContext + +/** + * Java 实现: + * ```java + * public final class MySimpleCommand extends JSimpleCommand { + * private MySimpleCommand() { + * super(MyPlugin.INSTANCE, "tell") + * // 可选设置如下属性 + * setDescription("这是一个测试指令") + * setUsage("/tell ") // 如不设置则自动根据带有 @Handler 的方法生成 + * setPermission(CommandPermission.Operator.INSTANCE) + * setPrefixOptional(true) + * } + * + * @Handler + * public void onCommand(CommandSender sender, User target, String message) { + * target.sendMessage(message) + * } + * } + * ``` + * + * @see SimpleCommand + * @see [CommandManager.executeCommand] + */ +public abstract class JSimpleCommand( + owner: CommandOwner, + vararg names: String +) : SimpleCommand(owner, *names) { + public override var description: String = super.description + protected set + public override var permission: CommandPermission = super.permission + protected set + public override var prefixOptional: Boolean = super.prefixOptional + protected set + public override var context: CommandArgumentContext = super.context + protected set +} \ No newline at end of file