From 6713ba9a1912e5acf1f732df740e1de87f4288c4 Mon Sep 17 00:00:00 2001 From: Him188 <Him188@mamoe.net> Date: Fri, 4 Sep 2020 10:57:32 +0800 Subject: [PATCH] Update README --- .../mirai/console/command/TestCommand.kt | 9 +- docs/Commands.md | 102 ++++++++++++++++++ docs/README.md | 63 ++++++++++- 3 files changed, 167 insertions(+), 7 deletions(-) diff --git a/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/command/TestCommand.kt b/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/command/TestCommand.kt index 82ab87faf..988e94ca5 100644 --- a/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/command/TestCommand.kt +++ b/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/command/TestCommand.kt @@ -27,10 +27,7 @@ import net.mamoe.mirai.console.command.description.buildCommandArgumentContext import net.mamoe.mirai.console.initTestEnvironment import net.mamoe.mirai.console.internal.command.CommandManagerImpl import net.mamoe.mirai.console.internal.command.flattenCommandComponents -import net.mamoe.mirai.message.data.Image -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.message.data.* import org.junit.jupiter.api.AfterAll import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.Test @@ -48,7 +45,7 @@ object TestCompositeCommand : CompositeCommand( object TestSimpleCommand : RawCommand(owner, "testSimple", "tsS") { - override suspend fun CommandSender.onCommand(args: Array<out Any>) { + override suspend fun CommandSender.onCommand(args: MessageChain) { Testing.ok(args) } } @@ -100,7 +97,7 @@ internal class TestCommand { fun `test flattenCommandArgs`() { val result = arrayOf("test", image).flattenCommandComponents().toTypedArray() - assertEquals("test", result[0]) + assertEquals("test", result[0].content) assertSame(image, result[1]) assertEquals(2, result.size) diff --git a/docs/Commands.md b/docs/Commands.md index e69de29bb..5025307d0 100644 --- a/docs/Commands.md +++ b/docs/Commands.md @@ -0,0 +1,102 @@ +# Mirai Console Backend - Commands + +## [`Command`] + +>「指令」:目前通常是 "/commandName arg1 arg2 arg3" 格式的消息。在将来可能会被扩展 + +```kotlin +interface Command { + val names: Array<out String> + val usage: String + val description: String + val permission: CommandPermission + val prefixOptional: Boolean + val owner: CommandOwner + suspend fun CommandSender.onCommand(args: MessageChain) +} +``` + +每一条指令都被抽象成 [`Command`]。 + +### 执行指令 + +指令既可以在代码执行,也可以在消息环境中执行。 + +#### 在 [`CommandManager`] 执行指令 + +##### Kotlin +通过扩展: +- `suspend fun Command.execute(CommandSender, )` +- `suspend fun CommandSender.execute` + +### 指令参数 + +指令的参数允许 `SingleMessage`,即包含 `At`, `Image`, `PlainText` 等。 + + +### [`RawCommand`] + + +## [`CommandManager`] +上面已经提到可以在 [`CommandManager`] 执行指令。[`CommandManager`] 持有已经注册的指令列表,源码内有详细注释,此处不过多赘述。 + +## [`CommandSender`] +指令发送者。 + +### 必要性 + +`Contact` + +[`Plugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/Plugin.kt +[`PluginDescription`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/PluginDescription.kt +[`PluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginLoader.kt +[`PluginManager`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginManager.kt +[`JarPluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JarPluginLoader.kt +[`JvmPlugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPlugin.kt +[`JvmPluginDescription`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginDescription.kt +[`AbstractJvmPlugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/AbstractJvmPlugin.kt +[`KotlinPlugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/KotlinPlugin.kt +[`JavaPlugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JavaPlugin.kt + + +[`Value`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/Value.kt +[`PluginData`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginData.kt +[`AbstractPluginData`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/AbstractPluginData.kt +[`AutoSavePluginData`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/AutoSavePluginData.kt +[`AutoSavePluginConfig`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/AutoSavePluginConfig.kt +[`PluginConfig`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginConfig.kt +[`PluginDataStorage`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginDataStorage.kt +[`MultiFilePluginDataStorage`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginDataStorage.kt#L116 +[`MemoryPluginDataStorage`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginDataStorage.kt#L100 +[`AutoSavePluginDataHolder`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginDataHolder.kt#L45 +[`PluginDataHolder`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginDataHolder.kt +[`PluginDataExtensions`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginDataExtensions.kt + +[`MiraiConsole`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt +[`MiraiConsoleImplementation`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleImplementation.kt +<!--[MiraiConsoleFrontEnd]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleFrontEnd.kt--> + +[`Command`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt +[`AbstractCommand`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt#L90 +[`CompositeCommand`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CompositeCommand.kt +[`SimpleCommand`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/SimpleCommand.kt +[`RawCommand`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/RawCommand.kt +[`CommandManager`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt +[`CommandSender`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandSender.kt + +[`BotManager`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/BotManager.kt +[`Annotations`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/Annotations.kt +[`ConsoleInput`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/ConsoleInput.kt +[`JavaPluginScheduler`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JavaPluginScheduler.kt +[`ResourceContainer`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/ResourceContainer.kt +[`PluginFileExtensions`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginFileExtensions.kt + +[Kotlin]: https://www.kotlincn.net/ +[Java]: https://www.java.com/zh_CN/ +[JVM]: https://zh.wikipedia.org/zh-cn/Java%E8%99%9A%E6%8B%9F%E6%9C%BA +[JAR]: https://zh.wikipedia.org/zh-cn/JAR_(%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F) + +[为什么不支持热加载和卸载插件?]: QA.md#为什么不支持热加载和卸载插件 +[使用 AutoService]: QA.md#使用-autoservice + + diff --git a/docs/README.md b/docs/README.md index abd4be00f..58b35321e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -25,7 +25,7 @@ - **[Java 中调用 Kotlin](https://www.kotlincn.net/docs/reference/java-to-kotlin-interop.html)** - 至少能使用 Java 或 Kotlin 一种一门语言解决问题 - 了解 JVM 和 Java 等同类编程语言的关系 - +- 对于 Kotlin 使用者,请熟知 [Kotlin `1.4` 版本带来的新特性](#mirai-console-使用的-kotlin-14-版本的新特性) ## 目录 ### 后端插件开发基础 @@ -55,3 +55,64 @@ [`PluginDataStorage`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginDataStorage.kt [`BotManager`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/BotManager.kt [`Command`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt + + +## 附录 + +### Java 用户的使用指南 + +- Java 中的「方法」在 Kotlin 中均被成为「函数」。 +- Kotlin 默认的访问权限是 `public`。如 Kotlin `class Test` 相当于 Java 的 `public class Test {}` +- Kotlin 的函数定义 `fun test(int: Int): String` 相当于 Java 的方法定义 `public String test(int int)` + +### 在 Java 使用 Mirai Console 中的 Kotlin `suspend` 函数 + +#### 什么是 `suspend` 函数 + +`suspend` 函数中文是「挂起函数」,是 Kotlin 「[协程](https://www.kotlincn.net/docs/reference/coroutines/coroutines-guide.html)」的一部分。 + +Kotlin 协程是语言级特性,函数的修饰符 `suspend` 会在编译阶段被处理。 + +对于一个挂起函数: +```kotlin +suspend fun test(): String +``` + +它会被编译为 `public Object test(Continuation<String> $completion)`。 + +这是因为 Kotlin 对所有挂起函数都有这样的内部变化,并在编译时实现了协程的一些特性。 + +Java 用户无法调用这样的方法,因为 `Continuation` 的实现很复杂。 + +Mamoe 为此开发了 Kotlin 编译器插件 [Kotlin Jvm Blocking Bridge](https://github.com/mamoe/kotlin-jvm-blocking-bridge),通过 `@JvmBlockingBridge` 注解,在编译期额外生成一个供 Java 使用的方法,让 Java 用户可以使用拥有源码内相同的函数签名的方法。 + +要获取详细信息,参考 [Kotlin Jvm Blocking Bridge 编译器插件](https://github.com/mamoe/kotlin-jvm-blocking-bridge/blob/master/README-chs.md#%E7%BC%96%E8%AF%91%E5%99%A8%E6%8F%92%E4%BB%B6) + +### Mirai Console 使用的 Kotlin `1.4` 版本的新特性 + +在官方文档的 [语言特性与改进](https://www.kotlincn.net/docs/reference/whatsnew14.html#%E8%AF%AD%E8%A8%80%E7%89%B9%E6%80%A7%E4%B8%8E%E6%94%B9%E8%BF%9B) 基础上,Mirai Console 的一些设计基于 Kotlin 1.4 的更多新特性。 + +#### `object` 内的扩展函数的自动引用 +对于如下定义: +```kotlin +package org.example +object Obj { + fun String.foo() +} +``` +在 Kotlin `1.3`,要调用 `foo`,必须使用: +```kotlin +Obj.run { + "str".foo() +} +``` +因为 IDE 不会自动为 `String.foo` 添加 `import`。 + +Kotlin `1.4` 解决了这个问题。在使用 `"str".foo` 时 Kotlin 会自动添加 `org.example.Obj.foo` 的引用。 + +Mirai Console 很多单例对象都设计为 `interface + companion object INSTANCE` 的接口与实现模式,需要这样的新特性。例如: +```kotlin +interface MiraiConsole { + companion object INSTANCE : MiraiConsole by MiraiConsoleImpl // MiraiConsoleImpl 是内部实现,不公开 +} +``` \ No newline at end of file