Update README

This commit is contained in:
Him188 2020-09-04 10:57:32 +08:00
parent 53c0cf63fd
commit 6713ba9a19
3 changed files with 167 additions and 7 deletions

View File

@ -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)

View File

@ -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

View File

@ -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 是内部实现,不公开
}
```