mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-27 00:30:17 +08:00
Update docs
This commit is contained in:
parent
373830440d
commit
e8c0ef192c
73
docs/Bots.md
73
docs/Bots.md
@ -9,6 +9,8 @@
|
||||
|
||||
一个机器人被以 `Bot` 对象描述。mirai 的交互入口点是 `Bot`。`Bot` 只可通过 [`BotFactory`](../mirai-core-api/src/commonMain/kotlin/BotFactory.kt#L22-L87) 内的 `newBot` 方法获得:
|
||||
|
||||
> 你现在还不需要知道 `Bot` 可以干什么。
|
||||
|
||||
```kotlin
|
||||
interface BotFactory {
|
||||
fun newBot(qq: Long, password: String, configuration: BotConfiguration): Bot
|
||||
@ -29,6 +31,8 @@ val bot = BotFactory.newBot( )
|
||||
Bot bot = BotFactory.INSTANCE.newBot( );
|
||||
```
|
||||
|
||||
> Scala 使用者请查看 [#834](https://github.com/mamoe/mirai/issues/834)
|
||||
|
||||
### 配置 Bot
|
||||
可以切换使用的协议、控制日志输出等。
|
||||
|
||||
@ -47,19 +51,31 @@ Bot bot = BotFactory.INSTANCE.newBot(qq, password, new BotConfiguration() {{
|
||||
}})
|
||||
```
|
||||
|
||||
下文示例代码都要放入 `// config` 中。
|
||||
下文示例代码都要放入 `// 配置` 中。
|
||||
|
||||
|
||||
### 常用配置
|
||||
> 可在 [BotConfiguration.kt](../mirai-core-api/src/commonMain/kotlin/utils/BotConfiguration.kt#L23) 查看完整配置列表
|
||||
|
||||
#### 设备信息
|
||||
Bot 默认使用全随机的设备信息。在更换账号地点时候使用随机设备信息可能会导致无法登录。
|
||||
### 常用配置
|
||||
|
||||
#### 修改运行目录
|
||||
默认为 `File(".")`
|
||||
|
||||
要使用 `deviceInfo.json` 存储设备信息:
|
||||
```
|
||||
fileBasedDeviceInfo() // "myDeviceInfo.json"
|
||||
fileBasedDeviceInfo("myDeviceInfo.json") // "myDeviceInfo.json"
|
||||
// Kotlin
|
||||
workingDir = File("C:/mirai")
|
||||
|
||||
// Java
|
||||
setWorkingDir(File("C:/mirai"))
|
||||
```
|
||||
|
||||
#### 设备信息
|
||||
Bot 默认使用全随机的设备信息。**在更换账号地点时候使用随机设备信息可能会导致无法登录**,当然,**成功登录时使用的设备信息也可以保存后在新的设备使用**。
|
||||
|
||||
要使用 `device.json` 存储设备信息:
|
||||
```
|
||||
fileBasedDeviceInfo() // 存储为 "device.json"
|
||||
// 或
|
||||
fileBasedDeviceInfo("myDeviceInfo.json") // 存储为 "myDeviceInfo.json"
|
||||
```
|
||||
|
||||
要自定义设备信息:
|
||||
@ -76,7 +92,7 @@ setDeviceInfo(bot -> /* create device info */)
|
||||
#### 切换登录协议
|
||||
Mirai 支持多种登录协议:`ANDROID_PHONE`,`ANDROID_PAD`,`ANDROID_WATCH`,默认使用 `ANDROID_PHONE`。
|
||||
|
||||
若登录失败,可尝试切换协议。但注意,部分功能在部分协议上不受支持,详见源码内注释。
|
||||
若登录失败,可尝试切换协议。**但注意部分功能在部分协议上不受支持**,详见源码内注释。
|
||||
|
||||
要切换协议:
|
||||
```
|
||||
@ -93,7 +109,10 @@ Bot 有两个日志类别,`Bot` 或 `Net`。`Bot` 为通常日志,如收到
|
||||
重定向日志到文件:
|
||||
```
|
||||
redirectBotLogToFile()
|
||||
redirectBotLogToDirectory()
|
||||
|
||||
redirectNetworkLogToFile()
|
||||
redirectNetworkLogToDirectory()
|
||||
```
|
||||
|
||||
手动覆盖日志:
|
||||
@ -107,11 +126,17 @@ setNetworkLoggerSupplier(bot -> /* create logger */)
|
||||
setBotLoggerSupplier(bot -> /* create logger */)
|
||||
```
|
||||
|
||||
关闭日志:
|
||||
```
|
||||
noNetworkLog()
|
||||
noBotLog()
|
||||
```
|
||||
|
||||
#### 覆盖登录解决器
|
||||
在遇到验证码时,Mirai 会寻找 `LoginSolver` 以解决验证码。
|
||||
Mirai 会使用 `LoginSolver` 解决验证码。
|
||||
|
||||
- 在 Android 需要手动提供 `LoginSolver`
|
||||
- 在 JVM, Mirai 会根据环境支持情况选择 Swing/CLI 实现
|
||||
- 在 JVM, Mirai 会根据环境支持情况选择 Swing/CLI 实现,通常不需要手动提供
|
||||
|
||||
覆盖默认的 `LoginSolver`:
|
||||
```
|
||||
@ -122,35 +147,35 @@ loginSolver = YourLoginSolver
|
||||
setLoginSolver(new YourLoginSolver())
|
||||
```
|
||||
|
||||
要获取更多有关验证码解决器的信息,查看 [LoginSolver.kt](../mirai-core-api/src/commonMain/kotlin/utils/LoginSolver.kt#L32)
|
||||
> 要获取更多有关 `LoginSolver` 的信息,查看 [LoginSolver.kt](../mirai-core-api/src/commonMain/kotlin/utils/LoginSolver.kt#L32)
|
||||
|
||||
### 获取当前所有 `Bot` 实例
|
||||
|
||||
在登录后,`Bot` 实例会被自动记录。可在 `Bot.instances` 获取到当前在线的所有 `Bot` 列表。当 `Bot` 离线,其实例就会被删除。
|
||||
在登录后 `Bot` 实例会被自动记录。可在 `Bot.instances` 获取到当前**在线**的所有 `Bot` 列表。
|
||||
|
||||
## 2. 登录
|
||||
|
||||
创建 `Bot` 后不会自动登录,需要手动调用其 `login()` 方法。在 Kotlin 还可以使用 `Bot.alsoLogin()` 扩展,相当于 `bot.apply { login() }`。
|
||||
创建 `Bot` 后不会自动登录,需要手动调用其 `login()` 方法。只需要调用一次 `login()` 即可,`Bot` 掉线时会自动重连。
|
||||
|
||||
### 处理滑动验证码
|
||||
|
||||
由于服务器正在大力推广滑块验证码,登录时可能需要解决滑动验证码。部分账号可以跳过滑块验证码直接重新登录,服务器就会要求图片验证码。
|
||||
[project-mirai/mirai-login-solver-selenium]: https://github.com/project-mirai/mirai-login-solver-selenium
|
||||
|
||||
处理验证码需要浏览器支持,可在 [project-mirai/mirai-login-solver-selenium](https://github.com/project-mirai/mirai-login-solver-selenium) 查看详细处理方案。
|
||||
服务器正在大力推广滑块验证码。
|
||||
|
||||
部分账号可以跳过滑块验证码,Mirai 会自动尝试。
|
||||
若你的账号无法跳过验证,可在 [project-mirai/mirai-login-solver-selenium] 查看处理方案。
|
||||
|
||||
### 常见登录失败原因
|
||||
|
||||
| 错误信息 | 可能的原因 | 可能的解决方案 |
|
||||
|:--------------|:---------|:----------------------|
|
||||
| 当前版本过低 | 密码错误 | 检查密码 |
|
||||
| 当前上网环境异常 | 设备锁 | 开启或关闭设备锁后重试登录 |
|
||||
| 错误信息 | 可能的原因 | 可能的解决方案 |
|
||||
|:--------------|:---------------|:----------------------|
|
||||
| 当前版本过低 | 密码错误 | 检查密码 |
|
||||
| 当前上网环境异常 | 设备锁 | 开启或关闭设备锁后重试登录 |
|
||||
| 禁止登录 | 需要处理滑块验证码 | [project-mirai/mirai-login-solver-selenium] |
|
||||
|
||||
若以上方案无法解决问题,请尝试 [切换登录协议](#切换登录协议) 和 **[处理滑动验证码](#处理滑动验证码)**。
|
||||
|
||||
### 重新登录
|
||||
|
||||
可以再次调用 `Bot.login()` 以重新登录 `Bot`。这一般没有必要——`Bot` 运行时会自动与服务器同步事件(如群成员变化,好友数量变化)。
|
||||
|
||||
|
||||
> 下一步,[Contacts](Contacts.md)
|
||||
>
|
||||
|
@ -3,10 +3,11 @@
|
||||
[![](https://mermaid.ink/img/eyJjb2RlIjoiY2xhc3NEaWFncmFtXG5cbmNsYXNzIEJvdCB7XG4gICAgK2ZyaWVuZHM6IENvbnRhY3RMaXN0XG4gICAgK2dyb3VwczogQ29udGFjdExpc3RcbiAgICArZ2V0RnJpZW5kKExvbmcpIEZyaWVuZD9cbiAgICArZ2V0RnJpZW5kT3JOdWxsKExvbmcpIEZyaWVuZFxuICAgICtnZXRHcm91cChMb25nKSBHcm91cD9cbiAgICArZ2V0R3JvdXBPckZhaWwoTG9uZykgR3JvdXBcbiAgICArbG9naW4oKVxuICAgICtjbG9zZSgpXG59XG5cbmNsYXNzIENvbnRhY3RPckJvdCB7XG4gICAgK2lkOiBJbnRcbiAgICArYXZhdGFyVXJsOiBTdHJpbmdcbn1cblxuY2xhc3MgVXNlck9yQm90IHtcbiAgICArbnVkZ2UoKSBOdWRnZVxufVxuXG5jbGFzcyBDb250YWN0IHtcbiAgICArYm90OiBCb3RcbiAgICArc2VuZE1lc3NhZ2UoTWVzc2FnZSkgTWVzc2FnZVJlY2VpcHRcbiAgICArc2VuZE1lc3NhZ2UoU3RyaW5nKSBNZXNzYWdlUmVjZWlwdFxuICAgICt1cGxvYWRJbWFnZShFeHRlcm5hbEltYWdlKSBJbWFnZVxufVxuXG5jbGFzcyBVc2VyIHtcbiAgICArbmljazogU3RyaW5nXG4gICAgK3JlbWFyazogU3RyaW5nXG59XG5cbmNsYXNzIEdyb3VwIHtcbiAgICArbWVtYmVyczogQ29udGFjdExpc3RcbiAgICArbmFtZTogU3RyaW5nXG4gICAgK3NldHRpbmdzOiBHcm91cFNldHRpbmdzXG4gICAgK293bmVyOiBOb3JtYWxNZW1iZXJcbiAgICArYm90TXV0ZVJlbWFpbmluZzogTG9uZ1xuICAgICtib3RQZXJtaXNzaW9uOiBNZW1iZXJQZXJtaXNzaW9uXG4gICAgK3F1aXQoKSBCb29sZWFuXG4gICAgK3VwbG9hZFZvaWNlKCkgVm9pY2Vcbn1cblxuY2xhc3MgTm9ybWFsTWVtYmVyIHtcbiAgICArbXV0ZSgpXG4gICAgK2tpY2soKVxufVxuXG5jbGFzcyBBbm9ueW1vdXNNZW1iZXIge1xuICAgICthbm9ueW1vdXNJZDogU3RyaW5nXG59XG5cbmNsYXNzIE1lbWJlciB7XG4gICAgK2dyb3VwOiBHcm91cFxufVxuXG5Db250YWN0T3JCb3Q8fC0tQ29udGFjdFxuQ29udGFjdE9yQm90PHwtLVVzZXJPckJvdFxuXG5Vc2VyT3JCb3Q8fC0tQm90XG5Vc2VyT3JCb3Q8fC0tVXNlclxuXG5Db250YWN0PHwtLVVzZXJcbkNvbnRhY3Q8fC0tR3JvdXBcblxuVXNlcjx8LS1NZW1iZXJcblVzZXI8fC0tRnJpZW5kXG5cbk1lbWJlcjx8LS1Ob3JtYWxNZW1iZXJcbk1lbWJlcjx8LS1Bbm9ueW1vdXNNZW1iZXIiLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9LCJ1cGRhdGVFZGl0b3IiOmZhbHNlfQ)](https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiY2xhc3NEaWFncmFtXG5cbmNsYXNzIEJvdCB7XG4gICAgK2ZyaWVuZHM6IENvbnRhY3RMaXN0XG4gICAgK2dyb3VwczogQ29udGFjdExpc3RcbiAgICArZ2V0RnJpZW5kKExvbmcpIEZyaWVuZD9cbiAgICArZ2V0RnJpZW5kT3JOdWxsKExvbmcpIEZyaWVuZFxuICAgICtnZXRHcm91cChMb25nKSBHcm91cD9cbiAgICArZ2V0R3JvdXBPckZhaWwoTG9uZykgR3JvdXBcbiAgICArbG9naW4oKVxuICAgICtjbG9zZSgpXG59XG5cbmNsYXNzIENvbnRhY3RPckJvdCB7XG4gICAgK2lkOiBJbnRcbiAgICArYXZhdGFyVXJsOiBTdHJpbmdcbn1cblxuY2xhc3MgVXNlck9yQm90IHtcbiAgICArbnVkZ2UoKSBOdWRnZVxufVxuXG5jbGFzcyBDb250YWN0IHtcbiAgICArYm90OiBCb3RcbiAgICArc2VuZE1lc3NhZ2UoTWVzc2FnZSkgTWVzc2FnZVJlY2VpcHRcbiAgICArc2VuZE1lc3NhZ2UoU3RyaW5nKSBNZXNzYWdlUmVjZWlwdFxuICAgICt1cGxvYWRJbWFnZShFeHRlcm5hbEltYWdlKSBJbWFnZVxufVxuXG5jbGFzcyBVc2VyIHtcbiAgICArbmljazogU3RyaW5nXG4gICAgK3JlbWFyazogU3RyaW5nXG59XG5cbmNsYXNzIEdyb3VwIHtcbiAgICArbWVtYmVyczogQ29udGFjdExpc3RcbiAgICArbmFtZTogU3RyaW5nXG4gICAgK3NldHRpbmdzOiBHcm91cFNldHRpbmdzXG4gICAgK293bmVyOiBOb3JtYWxNZW1iZXJcbiAgICArYm90TXV0ZVJlbWFpbmluZzogTG9uZ1xuICAgICtib3RQZXJtaXNzaW9uOiBNZW1iZXJQZXJtaXNzaW9uXG4gICAgK3F1aXQoKSBCb29sZWFuXG4gICAgK3VwbG9hZFZvaWNlKCkgVm9pY2Vcbn1cblxuY2xhc3MgTm9ybWFsTWVtYmVyIHtcbiAgICArbXV0ZSgpXG4gICAgK2tpY2soKVxufVxuXG5jbGFzcyBBbm9ueW1vdXNNZW1iZXIge1xuICAgICthbm9ueW1vdXNJZDogU3RyaW5nXG59XG5cbmNsYXNzIE1lbWJlciB7XG4gICAgK2dyb3VwOiBHcm91cFxufVxuXG5Db250YWN0T3JCb3Q8fC0tQ29udGFjdFxuQ29udGFjdE9yQm90PHwtLVVzZXJPckJvdFxuXG5Vc2VyT3JCb3Q8fC0tQm90XG5Vc2VyT3JCb3Q8fC0tVXNlclxuXG5Db250YWN0PHwtLVVzZXJcbkNvbnRhY3Q8fC0tR3JvdXBcblxuVXNlcjx8LS1NZW1iZXJcblVzZXI8fC0tRnJpZW5kXG5cbk1lbWJlcjx8LS1Ob3JtYWxNZW1iZXJcbk1lbWJlcjx8LS1Bbm9ueW1vdXNNZW1iZXIiLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9LCJ1cGRhdGVFZGl0b3IiOmZhbHNlfQ)
|
||||
|
||||
|
||||
基于面向对象的设计,可直接获取 `Contact` 的属性如 `nick`,`permission`。
|
||||
|
||||
要主动发送一条消息,调用 `Contact.sendMessage()` 即可。
|
||||
要主动发送一条消息,调用 `Contact.sendMessage()` 即可*(后文介绍)*。
|
||||
|
||||
可通过 `Bot.getFriend` 或 `Bot.getGroup` 获取相关对象,也可以通过事件获取。
|
||||
可通过 `Bot.getFriend` 或 `Bot.getGroup` 获取相关对象,也可以通过事件获取*(后文介绍)*。
|
||||
|
||||
> 下一步,[Events](Events.md)
|
||||
>
|
||||
|
@ -5,7 +5,7 @@
|
||||
- [事件系统](#事件系统)
|
||||
- [事件通道](#事件通道)
|
||||
- [通道操作](#通道操作)
|
||||
- [缩窄(过滤)](#缩窄过滤)
|
||||
- [过滤](#过滤)
|
||||
- [添加 `CoroutineContext`](#添加-coroutinecontext)
|
||||
- [限制作用域](#限制作用域)
|
||||
- [链式调用](#链式调用)
|
||||
@ -22,7 +22,7 @@
|
||||
|
||||
## 事件系统
|
||||
|
||||
Mirai 以事件驱动,使用者需要监听如 `收到消息`,`收到入群申请` 等事件。
|
||||
Mirai 以事件驱动。
|
||||
|
||||
[`Event`]: ../mirai-core-api/src/commonMain/kotlin/event/Event.kt#L21-L62
|
||||
|
||||
@ -39,13 +39,13 @@ Mirai 以事件驱动,使用者需要监听如 `收到消息`,`收到入群
|
||||
|
||||
[事件通道][`EventChannel`]是监听事件的入口。 **在不同的事件通道中可以监听到不同类型的事件**。
|
||||
|
||||
> 对通道的转换操作可以在使用时查看源码内注释 ([`EventChannel`])。
|
||||
|
||||
### 获取事件通道
|
||||
|
||||
`GlobalEventChannel` 是最大的通道:所有的事件都可以在 `GlobalEventChannel` 监听到。**因此,`GlobalEventChannel` 会包含来自所有 `Bot` 实例的事件。**
|
||||
[`GlobalEventChannel`]: ../mirai-core-api/src/commonMain/kotlin/event/GlobalEventChannel.kt
|
||||
|
||||
通常不会直接使用 `GlobalEventChannel`,而是使用经过 [通道操作](#通道操作) 操作的子通道。
|
||||
[`GlobalEventChannel`] 是最大的通道:所有的事件都可以在 [`GlobalEventChannel`] 监听到。**因此,[`GlobalEventChannel`] 会包含来自所有 `Bot` 实例的事件。**
|
||||
|
||||
通常不会直接使用 [`GlobalEventChannel`],而是使用经过 [通道操作](#通道操作) 操作的子通道。
|
||||
|
||||
> 回到 [目录](#目录)
|
||||
|
||||
@ -55,7 +55,7 @@ Mirai 以事件驱动,使用者需要监听如 `收到消息`,`收到入群
|
||||
|
||||
**一个通道的属性都是*不变的*:每个转换操作都会创建一个新的通道而不会修改原通道。**
|
||||
|
||||
### 缩窄(过滤)
|
||||
### 过滤
|
||||
|
||||
`GlobalEventChannel` 包含任何 `Event`,可以通过 `EventChannel.filter` 过滤得到一个只包含期望的事件的 `EventChannel`。
|
||||
|
||||
@ -68,11 +68,13 @@ EventChannel channel = GlobalEventChannel.INSTANCE.filter(ev -> ev instanceof Bo
|
||||
|
||||
> 回到 [通道操作](#通道操作)
|
||||
|
||||
> 你可以选择跳过下文介绍的协程属性和作用域,直接阅读 [在 `EventChannel` 监听事件](#在-eventchannel-监听事件)
|
||||
|
||||
### 添加 `CoroutineContext`
|
||||
|
||||
一个通道持有属性 `defaultCoroutineContext`,将会自动添加给每个事件监听器(见后文)。
|
||||
|
||||
可以为通道添加一些 `CoroutineContext`,如 `CoroutineExceptionHandler`。
|
||||
可以为通道添加一些 `CoroutineContext`,如 `CoroutineExceptionHandler`(用于处理监听时产生的异常)。
|
||||
```kotlin
|
||||
channel.exceptionHandler { exception ->
|
||||
logger.error(exception)
|
||||
@ -171,7 +173,7 @@ bot.eventChannel.subscribeAlways(GroupMessageEvent.class, event -> {
|
||||
})
|
||||
```
|
||||
|
||||
> 有关监听事件的实现细节可在使用时查看源码内注释。
|
||||
> 实现细节可查看源码内注释。
|
||||
|
||||
|
||||
> 回到 [目录](#目录)
|
||||
@ -180,25 +182,21 @@ bot.eventChannel.subscribeAlways(GroupMessageEvent.class, event -> {
|
||||
|
||||
监听都需要在*事件通道*中进行。如下几种方法都本质上会调用上述 `EventChannel.subscribe` 等方法。
|
||||
|
||||
- [使用 `ListenerHost` 监听事件](#使用-eventhandler-注解标注的方法监听事件)
|
||||
- [使用 `@EventHandler` 注解标注的方法监听事件](#使用-eventhandler-注解标注的方法监听事件)
|
||||
- [在 Kotlin 使用 DSL 监听事件](#在-kotlin-使用-dsl-监听事件)
|
||||
|
||||
### 使用 `@EventHandler` 注解标注的方法监听事件
|
||||
|
||||
标注一个函数(方法)为事件监听器。mirai 通过反射获取他们并为之注册事件。
|
||||
|
||||
> 详见 [EventHandler](../mirai-core-api/src/commonMain/kotlin/event/JvmMethodListeners.kt#L22-L144)
|
||||
|
||||
- [Kotlin 函数](#kotlin-函数)
|
||||
- [Java 方法](#java-方法)
|
||||
|
||||
#### Kotlin 函数
|
||||
|
||||
Kotlin 函数要求:
|
||||
- 接收者 (英 receiver) 和函数参数: 所标注的 Kotlin 函数必须至少拥有一个接收者或一个函数参数, 或二者都具有. 接收者和函数参数的类型必须相同 (如果二者都存在)
|
||||
- 接收者和函数参数: 所标注的 Kotlin 函数必须至少拥有一个接收者或一个函数参数, 或二者都具有. 接收者和函数参数的类型必须相同 (如果二者都存在)
|
||||
接收者或函数参数的类型都必须为 `Event` 或其子类.
|
||||
- 返回值: 为 `Unit` 或不指定返回值时将注册为 `EventChannel.subscribeAlways`, 为 `ListeningStatus` 时将注册为 `EventChannel.subscribe`.
|
||||
任何其他类型的返回值将会在注册时抛出异常.
|
||||
|
||||
所有 Kotlin 非 `suspend` 的函数都将会在 `Dispatchers.IO` 中调用
|
||||
|
||||
@ -266,14 +264,14 @@ eventChannel.registerListenerHost(MyEvents)
|
||||
|
||||
#### Java 方法
|
||||
|
||||
所有 Java 方法都会在 `Dispatchers.IO` 中调用,因此在 Java 可以调用阻塞方法。
|
||||
所有 Java 方法都会在 `Dispatchers.IO` 中调用,因此在 Java 也可以调用阻塞方法。
|
||||
|
||||
支持的方法类型:
|
||||
```
|
||||
// T 表示任何 Event 类型.
|
||||
void onEvent(T)
|
||||
Void onEvent(T)
|
||||
ListeningStatus onEvent(T) // 返回 null 时将抛出异常
|
||||
ListeningStatus onEvent(T) // 禁止返回 null
|
||||
```
|
||||
|
||||
Java 使用示例:
|
||||
@ -356,13 +354,13 @@ eventChannel.subscribeMessages {
|
||||
> 回到 [目录](#目录)
|
||||
|
||||
## 工具函数(Kotlin)
|
||||
|
||||
*可能需要较好的 Kotlin 技能才能理解以下内容。*
|
||||
> *可能需要较好的 Kotlin 技能才能理解以下内容。*
|
||||
> **可以[跳过本节](# )**
|
||||
|
||||
基于 Kotlin 协程特性,mirai 提供 `
|
||||
|
||||
### 线性同步(`syncFromEvent`)
|
||||
[linear.kt](../mirai-core-api/src/commonMain/kotlin/event/linear.kt)
|
||||
[syncFromEvent.kt](../mirai-core-api/src/commonMain/kotlin/event/syncFromEvent.kt)
|
||||
|
||||
挂起协程并获取下一个戳 Bot 的对象:
|
||||
```kotlin
|
||||
@ -462,6 +460,7 @@ reply("复读模式结束")
|
||||
|
||||
> 回到 [目录](#目录)
|
||||
|
||||
######
|
||||
|
||||
> 下一步,[Messages](Messages.md)
|
||||
>
|
||||
|
@ -10,19 +10,19 @@
|
||||
- [由 `CodableMessage` 取得 mirai 码字符串](#由-codablemessage-取得-mirai-码字符串)
|
||||
- [由 mirai 码字符串取得 `MessageChain` 实例](#由-mirai-码字符串取得-messagechain-实例)
|
||||
- [消息链](#消息链)
|
||||
- [发送消息](#发送消息)
|
||||
- [构造消息链](#构造消息链)
|
||||
- [元素唯一性](#元素唯一性)
|
||||
- [获取消息链中的消息元素](#获取消息链中的消息元素)
|
||||
|
||||
## 消息系统
|
||||
|
||||
在 Contacts 章节提到,要发送消息,使用 `Contact.sendMessage(Message)`。
|
||||
在 Contacts 章节提到,要发送消息,使用 `Contact.sendMessage(Message)`。`Message` 架构如下图所示。
|
||||
|
||||
[![](https://mermaid.ink/img/eyJjb2RlIjoiY2xhc3NEaWFncmFtXG5cbmNsYXNzIE1lc3NhZ2VDaGFpblxuTWVzc2FnZUNoYWluIDogTGlzdH5TaW5nbGVNZXNzYWdlflxuXG5NZXNzYWdlPHwtLU1lc3NhZ2VDaGFpblxuTWVzc2FnZTx8LS1TaW5nbGVNZXNzYWdlXG5cbk1lc3NhZ2VDaGFpbiBvLS0gU2luZ2xlTWVzc2FnZVxuXG5TaW5nbGVNZXNzYWdlPHwtLU1lc3NhZ2VDb250ZW50XG5TaW5nbGVNZXNzYWdlPHwtLU1lc3NhZ2VNZXRhZGF0YVxuXG4iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9LCJ1cGRhdGVFZGl0b3IiOmZhbHNlfQ)](https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiY2xhc3NEaWFncmFtXG5cbmNsYXNzIE1lc3NhZ2VDaGFpblxuTWVzc2FnZUNoYWluIDogTGlzdH5TaW5nbGVNZXNzYWdlflxuXG5NZXNzYWdlPHwtLU1lc3NhZ2VDaGFpblxuTWVzc2FnZTx8LS1TaW5nbGVNZXNzYWdlXG5cbk1lc3NhZ2VDaGFpbiBvLS0gU2luZ2xlTWVzc2FnZVxuXG5TaW5nbGVNZXNzYWdlPHwtLU1lc3NhZ2VDb250ZW50XG5TaW5nbGVNZXNzYWdlPHwtLU1lc3NhZ2VNZXRhZGF0YVxuXG4iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9LCJ1cGRhdGVFZGl0b3IiOmZhbHNlfQ)
|
||||
|
||||
`SingleMessage` 表示单个消息元素,`MessageChain`(消息链) 是 `List<SingleMessage>`。主动发送的消息和从服务器接收消息都是 `MessageChain`。
|
||||
|
||||
mirai 提供大量消息链的扩展:[MessageChain.kt](../mirai-core-api/src/commonMain/kotlin/message/data/MessageChain.kt#L59)。
|
||||
|
||||
> 回到 [目录](#目录)
|
||||
|
||||
@ -130,6 +130,7 @@ at.toMiraiCode() // 结果为 `[mirai:at:123]`
|
||||
| [`PokeMessage`] | `[mirai:poke:$name,$pokeType,$id]` |
|
||||
| [`VipFace`] | `[mirai:vipface:${kind.id},${kind.name},$count]` |
|
||||
| [`LightApp`] | `[mirai:app:$content]` |
|
||||
| [`SimpleServiceMessage`] | `[mirai:service:$serviceId,$content]` |
|
||||
|
||||
### 由 mirai 码字符串取得 `MessageChain` 实例
|
||||
|
||||
@ -150,6 +151,8 @@ MessageChain chain = MiraiCode.parseMiraiCode("[mirai:atall]");
|
||||
|
||||
前文已经介绍消息链,这里介绍消息链的使用。
|
||||
|
||||
### 发送消息
|
||||
|
||||
在 [Contacts 章节](Contacts.md) 提到,要发送消息使用 `Contact.sendMessage`。`Contact.sendMessage` 的定义是:
|
||||
```kotlin
|
||||
suspend fun sendMessage(message: Message): MessageReceipt<Contact>
|
||||
@ -226,7 +229,7 @@ MessageChain chain = new MessageChainBuilder()
|
||||
### 元素唯一性
|
||||
|
||||
[`MessageKey`]: ../mirai-core-api/src/commonMain/kotlin/message/data/MessageKey.kt
|
||||
[`ConstrainSingle`]: ../mirai-core-api/src/commonMain/kotlin/message/data/Message.kt#L350-L370
|
||||
[`ConstrainSingle`]: ../mirai-core-api/src/commonMain/kotlin/message/data/Message.kt#L273-L287
|
||||
[`HummerMessage`]: ../mirai-core-api/src/commonMain/kotlin/message/data/HummerMessage.kt
|
||||
|
||||
部分元素只能单一存在于消息链中。这样的元素实现接口 [`ConstrainSingle`]。
|
||||
@ -270,7 +273,7 @@ val image: Image? = chain.filterIsInstance<Image>().firstOrNull()
|
||||
Image image = (Image) chain.stream().filter(Image.class::isInstance).findFirst().orElse(null);
|
||||
```
|
||||
|
||||
在 Kotlin 要获取第一个指定类型实例还可以使用扩展。
|
||||
在 Kotlin 要获取第一个指定类型实例还可以使用快捷扩展。
|
||||
```kotlin
|
||||
val image: Image? = chain.findIsInstance<Image>()
|
||||
val image: Image = chain.firstIsInstance<Image>() // 不存在时 NoSuchElementException
|
||||
|
@ -23,7 +23,7 @@ import kotlin.coroutines.EmptyCoroutineContext
|
||||
*
|
||||
* ### Kotlin 函数
|
||||
* Kotlin 函数要求:
|
||||
* - 接收者 (英 receiver) 和函数参数: 所标注的 Kotlin 函数必须至少拥有一个接收者或一个函数参数, 或二者都具有. 接收者和函数参数的类型必须相同 (如果二者都存在)
|
||||
* - 接收者和函数参数: 所标注的 Kotlin 函数必须至少拥有一个接收者或一个函数参数, 或二者都具有. 接收者和函数参数的类型必须相同 (如果二者都存在)
|
||||
* 接收者或函数参数的类型都必须为 [Event] 或其子类.
|
||||
* - 返回值: 为 [Unit] 或不指定返回值时将注册为 [EventChannel.subscribeAlways], 为 [ListeningStatus] 时将注册为 [EventChannel.subscribe].
|
||||
* 任何其他类型的返回值将会在注册时抛出异常.
|
||||
@ -108,7 +108,7 @@ import kotlin.coroutines.EmptyCoroutineContext
|
||||
* // T 表示任何 Event 类型.
|
||||
* void onEvent(T)
|
||||
* Void onEvent(T)
|
||||
* @NotNull ListeningStatus onEvent(T) // 返回 null 时将抛出异常
|
||||
* @NotNull ListeningStatus onEvent(T) // 禁止返回 null
|
||||
* ```
|
||||
*
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user