mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-08 22:09:50 +08:00
Add docs, rearrange implementations
This commit is contained in:
parent
716e3ade48
commit
09524da1e9
@ -24,10 +24,7 @@ import kotlinx.serialization.UnstableDefault
|
|||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonConfiguration
|
import kotlinx.serialization.json.JsonConfiguration
|
||||||
import kotlinx.serialization.json.int
|
import kotlinx.serialization.json.int
|
||||||
import net.mamoe.mirai.Bot
|
import net.mamoe.mirai.*
|
||||||
import net.mamoe.mirai.BotImpl
|
|
||||||
import net.mamoe.mirai.LowLevelAPI
|
|
||||||
import net.mamoe.mirai.ThisApiMustBeUsedInWithConnectionLockBlock
|
|
||||||
import net.mamoe.mirai.contact.*
|
import net.mamoe.mirai.contact.*
|
||||||
import net.mamoe.mirai.data.*
|
import net.mamoe.mirai.data.*
|
||||||
import net.mamoe.mirai.event.broadcast
|
import net.mamoe.mirai.event.broadcast
|
||||||
@ -82,10 +79,18 @@ internal class QQAndroidBot constructor(
|
|||||||
|
|
||||||
@OptIn(LowLevelAPI::class)
|
@OptIn(LowLevelAPI::class)
|
||||||
override suspend fun acceptNewFriendRequest(event: NewFriendRequestEvent) {
|
override suspend fun acceptNewFriendRequest(event: NewFriendRequestEvent) {
|
||||||
|
check(event.bot === this) {
|
||||||
|
"the request $event is from Bot ${event.bot.id} but you are responding with bot ${this.id}"
|
||||||
|
}
|
||||||
|
|
||||||
check(event.responded.compareAndSet(false, true)) {
|
check(event.responded.compareAndSet(false, true)) {
|
||||||
"the request $this has already been responded"
|
"the request $this has already been responded"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check(!friends.contains(event.fromId)) {
|
||||||
|
"the request $event is outdated: You had already responded it on another device."
|
||||||
|
}
|
||||||
|
|
||||||
network.run {
|
network.run {
|
||||||
NewContact.SystemMsgNewFriend.Action(
|
NewContact.SystemMsgNewFriend.Action(
|
||||||
bot.client,
|
bot.client,
|
||||||
@ -100,8 +105,16 @@ internal class QQAndroidBot constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun rejectNewFriendRequest(event: NewFriendRequestEvent, blackList: Boolean) {
|
override suspend fun rejectNewFriendRequest(event: NewFriendRequestEvent, blackList: Boolean) {
|
||||||
|
check(event.bot === this) {
|
||||||
|
"the request $event is from Bot ${event.bot.id} but you are responding with bot ${this.id}"
|
||||||
|
}
|
||||||
|
|
||||||
check(event.responded.compareAndSet(false, true)) {
|
check(event.responded.compareAndSet(false, true)) {
|
||||||
"the request $this has already been responded"
|
"the request $event has already been responded"
|
||||||
|
}
|
||||||
|
|
||||||
|
check(!friends.contains(event.fromId)) {
|
||||||
|
"the request $event is outdated: You had already responded it on another device."
|
||||||
}
|
}
|
||||||
|
|
||||||
network.run {
|
network.run {
|
||||||
@ -116,10 +129,16 @@ internal class QQAndroidBot constructor(
|
|||||||
|
|
||||||
@OptIn(LowLevelAPI::class)
|
@OptIn(LowLevelAPI::class)
|
||||||
override suspend fun acceptMemberJoinRequest(event: MemberJoinRequestEvent) {
|
override suspend fun acceptMemberJoinRequest(event: MemberJoinRequestEvent) {
|
||||||
|
@Suppress("DuplicatedCode")
|
||||||
|
checkGroupPermission(event.bot, event.group) { event::class.simpleName ?: "<anonymous class>" }
|
||||||
check(event.responded.compareAndSet(false, true)) {
|
check(event.responded.compareAndSet(false, true)) {
|
||||||
"the request $this has already been responded"
|
"the request $this has already been responded"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check(!event.group.members.contains(event.fromId)) {
|
||||||
|
"the request $this is outdated: Another operator has already responded it."
|
||||||
|
}
|
||||||
|
|
||||||
network.run {
|
network.run {
|
||||||
NewContact.SystemMsgNewGroup.Action(
|
NewContact.SystemMsgNewGroup.Action(
|
||||||
bot.client,
|
bot.client,
|
||||||
@ -137,11 +156,17 @@ internal class QQAndroidBot constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("DuplicatedCode")
|
||||||
@OptIn(LowLevelAPI::class)
|
@OptIn(LowLevelAPI::class)
|
||||||
override suspend fun rejectMemberJoinRequest(event: MemberJoinRequestEvent, blackList: Boolean) {
|
override suspend fun rejectMemberJoinRequest(event: MemberJoinRequestEvent, blackList: Boolean) {
|
||||||
|
checkGroupPermission(event.bot, event.group) { event::class.simpleName ?: "<anonymous class>" }
|
||||||
check(event.responded.compareAndSet(false, true)) {
|
check(event.responded.compareAndSet(false, true)) {
|
||||||
"the request $this has already been responded"
|
"the request $this has already been responded"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check(!event.group.members.contains(event.fromId)) {
|
||||||
|
"the request $this is outdated: Another operator has already responded it."
|
||||||
|
}
|
||||||
network.run {
|
network.run {
|
||||||
NewContact.SystemMsgNewGroup.Action(
|
NewContact.SystemMsgNewGroup.Action(
|
||||||
bot.client,
|
bot.client,
|
||||||
@ -152,7 +177,22 @@ internal class QQAndroidBot constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inline fun checkGroupPermission(eventBot: Bot, eventGroup: Group, eventName: () -> String) {
|
||||||
|
val group = this.getGroupOrNull(eventGroup.id)
|
||||||
|
?: kotlin.run {
|
||||||
|
if (this == eventBot) {
|
||||||
|
error("A ${eventName()} is outdated. Group ${eventGroup.id} not found for bot ${this.id}. " +
|
||||||
|
"This is because bot isn't in the group anymore")
|
||||||
|
} else {
|
||||||
|
error("A ${eventName()} is from bot ${eventBot.id}, but you are trying to respond it using bot ${this.id} who isn't a member of the group ${eventGroup.id}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
group.checkBotPermissionOperator()
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun ignoreMemberJoinRequest(event: MemberJoinRequestEvent, blackList: Boolean) {
|
override suspend fun ignoreMemberJoinRequest(event: MemberJoinRequestEvent, blackList: Boolean) {
|
||||||
|
checkGroupPermission(event.bot, event.group) { event::class.simpleName ?: "<anonymous class>" }
|
||||||
check(event.responded.compareAndSet(false, true)) {
|
check(event.responded.compareAndSet(false, true)) {
|
||||||
"the request $this has already been responded"
|
"the request $this has already been responded"
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ import kotlin.jvm.JvmSynthetic
|
|||||||
@OptIn(MiraiInternalAPI::class)
|
@OptIn(MiraiInternalAPI::class)
|
||||||
open class MessageReceipt<out C : Contact>(
|
open class MessageReceipt<out C : Contact>(
|
||||||
/**
|
/**
|
||||||
* 指代发送出去的消息
|
* 指代发送出去的消息.
|
||||||
*/
|
*/
|
||||||
val source: OnlineMessageSource.Outgoing,
|
val source: OnlineMessageSource.Outgoing,
|
||||||
/**
|
/**
|
||||||
|
@ -12,11 +12,9 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.message.data
|
package net.mamoe.mirai.message.data
|
||||||
|
|
||||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
|
||||||
import net.mamoe.mirai.utils.SinceMirai
|
import net.mamoe.mirai.utils.SinceMirai
|
||||||
import kotlin.jvm.JvmMultifileClass
|
import kotlin.jvm.JvmMultifileClass
|
||||||
import kotlin.jvm.JvmName
|
import kotlin.jvm.JvmName
|
||||||
import kotlin.jvm.JvmSynthetic
|
|
||||||
|
|
||||||
private const val displayA = "@全体成员"
|
private const val displayA = "@全体成员"
|
||||||
|
|
||||||
@ -50,15 +48,6 @@ object AtAll :
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 自动为消息补充 " "
|
// 自动为消息补充 " "
|
||||||
@OptIn(MiraiInternalAPI::class)
|
|
||||||
@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
|
|
||||||
@Suppress("INAPPLICABLE_JVM_NAME", "EXPOSED_FUNCTION_RETURN_TYPE")
|
|
||||||
@JvmName("followedBy")
|
|
||||||
@JvmSynthetic
|
|
||||||
override fun followedBy1(tail: Message): CombinedMessage {
|
|
||||||
return followedByInternalForBinaryCompatibility(tail)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun followedBy(tail: Message): MessageChain {
|
override fun followedBy(tail: Message): MessageChain {
|
||||||
if (tail is PlainText && tail.stringValue.startsWith(' ')) {
|
if (tail is PlainText && tail.stringValue.startsWith(' ')) {
|
||||||
return super.followedBy(tail)
|
return super.followedBy(tail)
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@file:Suppress("unused", "NOTHING_TO_INLINE")
|
@file:Suppress("unused", "NOTHING_TO_INLINE")
|
||||||
|
@file:JvmMultifileClass
|
||||||
|
@file:JvmName("MessageUtils") // since 0.39.1
|
||||||
|
|
||||||
package net.mamoe.mirai.message.data
|
package net.mamoe.mirai.message.data
|
||||||
|
|
||||||
@ -15,10 +17,7 @@ import net.mamoe.mirai.message.data.PokeMessage.Types
|
|||||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||||
import net.mamoe.mirai.utils.SinceMirai
|
import net.mamoe.mirai.utils.SinceMirai
|
||||||
import kotlin.jvm.JvmField
|
import kotlin.jvm.*
|
||||||
import kotlin.jvm.JvmName
|
|
||||||
import kotlin.jvm.JvmStatic
|
|
||||||
import kotlin.jvm.JvmSynthetic
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一些特殊的消息
|
* 一些特殊的消息
|
||||||
|
@ -19,7 +19,6 @@ import net.mamoe.mirai.Bot
|
|||||||
import net.mamoe.mirai.BotImpl
|
import net.mamoe.mirai.BotImpl
|
||||||
import net.mamoe.mirai.contact.Contact
|
import net.mamoe.mirai.contact.Contact
|
||||||
import net.mamoe.mirai.contact.Group
|
import net.mamoe.mirai.contact.Group
|
||||||
import net.mamoe.mirai.utils.ExternalImage
|
|
||||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||||
import net.mamoe.mirai.utils.PlannedRemoval
|
import net.mamoe.mirai.utils.PlannedRemoval
|
||||||
import net.mamoe.mirai.utils.SinceMirai
|
import net.mamoe.mirai.utils.SinceMirai
|
||||||
@ -38,7 +37,7 @@ import kotlin.jvm.JvmSynthetic
|
|||||||
*
|
*
|
||||||
* ### [toString] 和 [contentToString]
|
* ### [toString] 和 [contentToString]
|
||||||
* - [toString] 固定返回 `[mirai:image:<ID>]` 格式字符串, 其中 `<ID>` 代表 [imageId].
|
* - [toString] 固定返回 `[mirai:image:<ID>]` 格式字符串, 其中 `<ID>` 代表 [imageId].
|
||||||
* - [contentToString] 固定返回 `"[图片]"`
|
* - [contentToString] 固定返回 ```"[图片]"```
|
||||||
*
|
*
|
||||||
* ### 上传和发送图片
|
* ### 上传和发送图片
|
||||||
* @see Contact.uploadImage 上传 [图片文件][ExternalImage] 并得到 [Image] 消息
|
* @see Contact.uploadImage 上传 [图片文件][ExternalImage] 并得到 [Image] 消息
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@file:Suppress("MemberVisibilityCanBePrivate", "unused", "EXPERIMENTAL_API_USAGE", "NOTHING_TO_INLINE")
|
@file:Suppress("MemberVisibilityCanBePrivate", "unused", "EXPERIMENTAL_API_USAGE", "NOTHING_TO_INLINE")
|
||||||
|
@file:JvmMultifileClass
|
||||||
|
@file:JvmName("MessageUtils")
|
||||||
|
|
||||||
package net.mamoe.mirai.message.data
|
package net.mamoe.mirai.message.data
|
||||||
|
|
||||||
@ -17,6 +19,7 @@ import net.mamoe.mirai.message.data.Message.Key
|
|||||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||||
import net.mamoe.mirai.utils.PlannedRemoval
|
import net.mamoe.mirai.utils.PlannedRemoval
|
||||||
import net.mamoe.mirai.utils.SinceMirai
|
import net.mamoe.mirai.utils.SinceMirai
|
||||||
|
import kotlin.jvm.JvmMultifileClass
|
||||||
import kotlin.jvm.JvmName
|
import kotlin.jvm.JvmName
|
||||||
import kotlin.jvm.JvmSynthetic
|
import kotlin.jvm.JvmSynthetic
|
||||||
|
|
||||||
@ -313,6 +316,8 @@ interface SingleMessage : Message, CharSequence, Comparable<String> {
|
|||||||
/**
|
/**
|
||||||
* 消息元数据, 即不含内容的元素.
|
* 消息元数据, 即不含内容的元素.
|
||||||
*
|
*
|
||||||
|
* 所有子类的 [contentToString] 都应该返回空字符串.
|
||||||
|
*
|
||||||
* @see MessageSource 消息源
|
* @see MessageSource 消息源
|
||||||
* @see QuoteReply 引用回复
|
* @see QuoteReply 引用回复
|
||||||
* @see CustomMessageMetadata 自定义元数据
|
* @see CustomMessageMetadata 自定义元数据
|
||||||
@ -328,11 +333,12 @@ interface MessageMetadata : SingleMessage {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 约束一个 [MessageChain] 中只存在这一种类型的元素. 新元素将会替换旧元素, 保持原顺序.
|
* 约束一个 [MessageChain] 中只存在这一种类型的元素. 新元素将会替换旧元素, 保持原顺序.
|
||||||
|
*
|
||||||
* 实现此接口的元素将会在连接时自动处理替换.
|
* 实现此接口的元素将会在连接时自动处理替换.
|
||||||
*/
|
*/
|
||||||
@SinceMirai("0.34.0")
|
@SinceMirai("0.34.0")
|
||||||
interface ConstrainSingle<out M : Message> : MessageMetadata {
|
interface ConstrainSingle<out M : Message> : MessageMetadata {
|
||||||
val key: Message.Key<M>
|
val key: Key<M>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -142,9 +142,7 @@ inline fun MessageChain.allContent(block: (MessageContent) -> Boolean): Boolean
|
|||||||
this.forEach {
|
this.forEach {
|
||||||
if (it !is MessageMetadata) {
|
if (it !is MessageMetadata) {
|
||||||
check(it is MessageContent) { "internal error: Message must be either MessageMetaData or MessageContent" }
|
check(it is MessageContent) { "internal error: Message must be either MessageMetaData or MessageContent" }
|
||||||
if (!block(it)) {
|
if (!block(it)) return false
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -158,9 +156,7 @@ inline fun MessageChain.noneContent(block: (MessageContent) -> Boolean): Boolean
|
|||||||
this.forEach {
|
this.forEach {
|
||||||
if (it !is MessageMetadata) {
|
if (it !is MessageMetadata) {
|
||||||
check(it is MessageContent) { "internal error: Message must be either MessageMetaData or MessageContent" }
|
check(it is MessageContent) { "internal error: Message must be either MessageMetaData or MessageContent" }
|
||||||
if (block(it)) {
|
if (block(it)) return false
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -29,6 +29,25 @@ import kotlin.jvm.JvmSynthetic
|
|||||||
/**
|
/**
|
||||||
* 消息源, 它存在于 [MessageChain] 中, 用于表示这个消息的来源.
|
* 消息源, 它存在于 [MessageChain] 中, 用于表示这个消息的来源.
|
||||||
*
|
*
|
||||||
|
*
|
||||||
|
* ### 组成
|
||||||
|
* MessageSource 由 metadata (元数据), form & target, content 组成
|
||||||
|
*
|
||||||
|
* #### metadata
|
||||||
|
* - [id] 消息 id (序列号)
|
||||||
|
* - [internalId] 消息内部 id
|
||||||
|
* - [time] 时间
|
||||||
|
*
|
||||||
|
* 官方客户端通过 metadata 这三个数据定位消息, 撤回和引用回复都是如此.
|
||||||
|
*
|
||||||
|
* #### form & target
|
||||||
|
* - [fromId] 消息发送人
|
||||||
|
* - [targetId] 消息发送目标
|
||||||
|
*
|
||||||
|
* #### content
|
||||||
|
* - [originalMessage] 消息内容
|
||||||
|
*
|
||||||
|
*
|
||||||
* 消息源可用于 [引用回复][QuoteReply] 或 [撤回][Bot.recall].
|
* 消息源可用于 [引用回复][QuoteReply] 或 [撤回][Bot.recall].
|
||||||
*
|
*
|
||||||
* @see Bot.recall 撤回一条消息
|
* @see Bot.recall 撤回一条消息
|
||||||
@ -52,50 +71,74 @@ sealed class MessageSource : Message, MessageMetadata, ConstrainSingle<MessageSo
|
|||||||
abstract val bot: Bot
|
abstract val bot: Bot
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 消息 id.
|
* 消息 id (序列号).
|
||||||
* 此值在同一会话中唯一且有顺序.
|
**
|
||||||
|
* #### 值域
|
||||||
|
* 值的范围约为 [UShort] 的范围.
|
||||||
|
*
|
||||||
|
* #### 顺序
|
||||||
|
* 群消息的 id 由服务器维护. 好友消息的 id 由 mirai 维护.
|
||||||
|
*
|
||||||
|
* - 在同一个群的消息中此值随每条消息递增 1.
|
||||||
|
* - 在好友消息中无法保证每次都递增 1. 也可能会产生大幅跳过的情况.
|
||||||
*/
|
*/
|
||||||
abstract val id: Int
|
abstract val id: Int
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内部 id, 仅用于 [Bot.constructMessageSource]
|
* 内部 id. 仅用于协议模块使用.
|
||||||
* 值没有顺序, 也可能为 0, 取决于服务器是否提供.
|
|
||||||
* 在事件中和在引用中无法保证同一条消息的 [internalId] 相同.
|
|
||||||
*
|
*
|
||||||
* 仅用于协议实现.
|
* 在撤回消息和引用回复时均需使用此 id.
|
||||||
|
*
|
||||||
|
* 值没有顺序, 也可能为 0, 取决于服务器是否提供.
|
||||||
|
*
|
||||||
|
* 在事件中和在引用中无法保证同一条消息的 [internalId] 相同.
|
||||||
*/
|
*/
|
||||||
@SinceMirai("0.39.0")
|
@SinceMirai("0.39.0")
|
||||||
abstract val internalId: Int
|
abstract val internalId: Int
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送时间时间戳, 单位为秒.
|
* 发送时间时间戳, 单位为秒.
|
||||||
* 撤回好友消息时需要
|
*
|
||||||
|
* 时间戳可能来自服务器, 也可能来自 mirai, 且无法保证两者时间同步.
|
||||||
|
*
|
||||||
|
* 撤回消息时需要此值.
|
||||||
*/
|
*/
|
||||||
abstract val time: Int
|
abstract val time: Int
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送人.
|
* 发送人.
|
||||||
* 当 [OnlineMessageSource.Outgoing] 时为 [机器人][Bot.id]
|
*
|
||||||
* 当 [OnlineMessageSource.Incoming] 时为发信 [目标好友][QQ.id] 或 [群][Group.id]
|
* - 当 [OnlineMessageSource.Outgoing] 时为 [机器人][Bot.id]
|
||||||
* 当 [OfflineMessageSource] 时为 [机器人][Bot.id], 发信 [目标好友][QQ.id] 或 [群][Group.id] (取决于 [OfflineMessageSource.kind])
|
* - 当 [OnlineMessageSource.Incoming] 时为发信 [目标好友][QQ.id] 或 [群][Group.id]
|
||||||
|
* - 当 [OfflineMessageSource] 时为 [机器人][Bot.id], 发信 [目标好友][QQ.id] 或 [群][Group.id] (取决于 [OfflineMessageSource.kind])
|
||||||
*/
|
*/
|
||||||
abstract val fromId: Long
|
abstract val fromId: Long
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送目标.
|
* 消息发送目标.
|
||||||
* 当 [OnlineMessageSource.Outgoing] 时为发信 [目标好友][QQ.id] 或 [群][Group.id] 或 [临时消息][Member.id]
|
*
|
||||||
* 当 [OnlineMessageSource.Incoming] 时为 [机器人][Bot.id]
|
* - 当 [OnlineMessageSource.Outgoing] 时为发信 [目标好友][QQ.id] 或 [群][Group.id] 或 [临时消息][Member.id]
|
||||||
* 当 [OfflineMessageSource] 时为 [机器人][Bot.id], 发信 [目标好友][QQ.id] 或 [群][Group.id] 或 [临时消息][Member.id] (取决于 [OfflineMessageSource.kind])
|
* - 当 [OnlineMessageSource.Incoming] 时为 [机器人][Bot.id]
|
||||||
|
* - 当 [OfflineMessageSource] 时为 [机器人][Bot.id], 发信 [目标好友][QQ.id] 或 [群][Group.id] 或 [临时消息][Member.id] (取决于 [OfflineMessageSource.kind])
|
||||||
*/
|
*/
|
||||||
abstract val targetId: Long // groupCode / friendUin / memberUin
|
abstract val targetId: Long // groupCode / friendUin / memberUin
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 原消息内容.
|
* 原消息内容.
|
||||||
|
*
|
||||||
|
* 此属性是 **lazy** 的: 它只会在第一次调用时初始化, 因为需要反序列化服务器发来的整个包, 相当于接收了一条新消息.
|
||||||
*/
|
*/
|
||||||
@LazyProperty
|
@LazyProperty
|
||||||
abstract val originalMessage: MessageChain
|
abstract val originalMessage: MessageChain
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回 `"[mirai:source:$id,$internalId]"`
|
||||||
|
*/
|
||||||
final override fun toString(): String = "[mirai:source:$id,$internalId]"
|
final override fun toString(): String = "[mirai:source:$id,$internalId]"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回空字符串, 因 [MessageMetadata] 的约束.
|
||||||
|
*/
|
||||||
final override fun contentToString(): String = ""
|
final override fun contentToString(): String = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +148,8 @@ sealed class MessageSource : Message, MessageMetadata, ConstrainSingle<MessageSo
|
|||||||
* 拥有对象化的 [sender], [target], 也可以直接 [recall] 和 [quote]
|
* 拥有对象化的 [sender], [target], 也可以直接 [recall] 和 [quote]
|
||||||
*
|
*
|
||||||
* ### 来源
|
* ### 来源
|
||||||
* **必定是一个发出去的消息或接收到的消息的 [MessageChain] 中的一个元数据 [MessageMetadata].**
|
* - 当 bot 主动发送消息时, 产生 (由协议模块主动构造) [OnlineMessageSource.Outgoing]
|
||||||
|
* - 当 bot 接收消息时, 产生 (由协议模块根据服务器的提供的信息构造) [OnlineMessageSource.Incoming]
|
||||||
*
|
*
|
||||||
* #### 机器人主动发送消息
|
* #### 机器人主动发送消息
|
||||||
* 当机器人 [主动发出消息][Member.sendMessage], 将会得到一个 [消息回执][MessageReceipt].
|
* 当机器人 [主动发出消息][Member.sendMessage], 将会得到一个 [消息回执][MessageReceipt].
|
||||||
@ -115,6 +159,8 @@ sealed class MessageSource : Message, MessageMetadata, ConstrainSingle<MessageSo
|
|||||||
* 当机器人接收一条消息 [ContactMessage], 这条消息包含一个 [内向消息源][OnlineMessageSource.Incoming], 代表着接收到的这条消息的来源.
|
* 当机器人接收一条消息 [ContactMessage], 这条消息包含一个 [内向消息源][OnlineMessageSource.Incoming], 代表着接收到的这条消息的来源.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
* ### 实现
|
||||||
|
* 此类的所有子类都有协议模块实现. 不要自行实现它们, 否则将无法发送
|
||||||
*
|
*
|
||||||
* @see OnlineMessageSource.toOffline 转为 [OfflineMessageSource]
|
* @see OnlineMessageSource.toOffline 转为 [OfflineMessageSource]
|
||||||
*/
|
*/
|
||||||
@ -144,7 +190,7 @@ sealed class OnlineMessageSource : MessageSource() {
|
|||||||
abstract val subject: Contact
|
abstract val subject: Contact
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 由 [机器人主动发送消息][Contact.sendMessage] 产生的 [MessageSource]
|
* 由 [机器人主动发送消息][Contact.sendMessage] 产生的 [MessageSource], 可通过 [MessageReceipt] 获得.
|
||||||
*/
|
*/
|
||||||
sealed class Outgoing : OnlineMessageSource() {
|
sealed class Outgoing : OnlineMessageSource() {
|
||||||
companion object Key : Message.Key<Outgoing> {
|
companion object Key : Message.Key<Outgoing> {
|
||||||
@ -266,6 +312,8 @@ sealed class OnlineMessageSource : MessageSource() {
|
|||||||
/**
|
/**
|
||||||
* 由一条消息中的 [QuoteReply] 得到的 [MessageSource].
|
* 由一条消息中的 [QuoteReply] 得到的 [MessageSource].
|
||||||
* 此消息源可能来自一条与机器人无关的消息. 因此无法提供对象化的 `sender` 或 `target` 获取.
|
* 此消息源可能来自一条与机器人无关的消息. 因此无法提供对象化的 `sender` 或 `target` 获取.
|
||||||
|
*
|
||||||
|
* @see buildMessageSource 构建一个 [OfflineMessageSource]
|
||||||
*/
|
*/
|
||||||
@SinceMirai("0.33.0")
|
@SinceMirai("0.33.0")
|
||||||
abstract class OfflineMessageSource : MessageSource() {
|
abstract class OfflineMessageSource : MessageSource() {
|
||||||
@ -290,6 +338,9 @@ abstract class OfflineMessageSource : MessageSource() {
|
|||||||
// final override fun toString(): String = "OfflineMessageSource(sender=$senderId, target=$targetId)"
|
// final override fun toString(): String = "OfflineMessageSource(sender=$senderId, target=$targetId)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否是发送给群, 或从群接收的消息的消息源
|
||||||
|
*/
|
||||||
// inline for future removal
|
// inline for future removal
|
||||||
inline fun MessageSource.isAboutGroup(): Boolean {
|
inline fun MessageSource.isAboutGroup(): Boolean {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
@ -298,6 +349,9 @@ inline fun MessageSource.isAboutGroup(): Boolean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否是发送给临时会话, 或从临时会话接收的消息的消息源
|
||||||
|
*/
|
||||||
inline fun MessageSource.isAboutTemp(): Boolean {
|
inline fun MessageSource.isAboutTemp(): Boolean {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is OnlineMessageSource -> subject is Member
|
is OnlineMessageSource -> subject is Member
|
||||||
@ -305,6 +359,9 @@ inline fun MessageSource.isAboutTemp(): Boolean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否是发送给好友, 或从好友接收的消息的消息源
|
||||||
|
*/
|
||||||
// inline for future removal
|
// inline for future removal
|
||||||
inline fun MessageSource.isAboutFriend(): Boolean {
|
inline fun MessageSource.isAboutFriend(): Boolean {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
@ -315,6 +372,7 @@ inline fun MessageSource.isAboutFriend(): Boolean {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 引用这条消息
|
* 引用这条消息
|
||||||
|
* @see QuoteReply
|
||||||
*/
|
*/
|
||||||
fun MessageSource.quote(): QuoteReply {
|
fun MessageSource.quote(): QuoteReply {
|
||||||
@OptIn(MiraiInternalAPI::class)
|
@OptIn(MiraiInternalAPI::class)
|
||||||
@ -323,17 +381,37 @@ fun MessageSource.quote(): QuoteReply {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 引用这条消息
|
* 引用这条消息
|
||||||
|
* @see QuoteReply
|
||||||
*/
|
*/
|
||||||
fun MessageChain.quote(): QuoteReply {
|
fun MessageChain.quote(): QuoteReply {
|
||||||
@OptIn(MiraiInternalAPI::class)
|
@OptIn(MiraiInternalAPI::class)
|
||||||
return QuoteReply(this.source as? OnlineMessageSource ?: error("only online messages can be quoted"))
|
return QuoteReply(this.source as? OnlineMessageSource ?: error("only online messages can be quoted"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 撤回这条消息. 可撤回自己 2 分钟内发出的消息, 和任意时间的群成员的消息.
|
||||||
|
*
|
||||||
|
* [Bot] 撤回自己的消息不需要权限.
|
||||||
|
* [Bot] 撤回群员的消息需要管理员权限.
|
||||||
|
*
|
||||||
|
* @throws PermissionDeniedException 当 [Bot] 无权限操作时
|
||||||
|
* @throws IllegalStateException 当这条消息已经被撤回时 (仅同步主动操作)
|
||||||
|
*
|
||||||
|
* @see Bot.recall
|
||||||
|
*/
|
||||||
@JvmSynthetic
|
@JvmSynthetic
|
||||||
suspend inline fun MessageSource.recall() = bot.recall(this)
|
suspend inline fun MessageSource.recall() = bot.recall(this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 撤回这条消息
|
* 在一段时间后撤回这条消息. 可撤回自己 2 分钟内发出的消息, 和任意时间的群成员的消息.
|
||||||
|
*
|
||||||
|
* [Bot] 撤回自己的消息不需要权限.
|
||||||
|
* [Bot] 撤回群员的消息需要管理员权限.
|
||||||
|
*
|
||||||
|
* @throws PermissionDeniedException 当 [Bot] 无权限操作时
|
||||||
|
* @throws IllegalStateException 当这条消息已经被撤回时 (仅同步主动操作)
|
||||||
|
*
|
||||||
|
* @see Bot.recall
|
||||||
*/
|
*/
|
||||||
@JvmSynthetic
|
@JvmSynthetic
|
||||||
inline fun MessageSource.recallIn(
|
inline fun MessageSource.recallIn(
|
||||||
@ -345,7 +423,7 @@ inline fun MessageSource.recallIn(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 消息 id.
|
* 消息 id.
|
||||||
* 仅从服务器接收的消息才可以获取 id
|
* 仅从服务器接收的消息才可以获取
|
||||||
*
|
*
|
||||||
* @see MessageSource.id
|
* @see MessageSource.id
|
||||||
*/
|
*/
|
||||||
@ -353,6 +431,36 @@ inline fun MessageSource.recallIn(
|
|||||||
inline val MessageChain.id: Int
|
inline val MessageChain.id: Int
|
||||||
get() = this.source.id
|
get() = this.source.id
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息内部 id.
|
||||||
|
* 仅从服务器接收的消息才可以获取
|
||||||
|
*
|
||||||
|
* @see MessageSource.id
|
||||||
|
*/
|
||||||
|
@get:JvmSynthetic
|
||||||
|
inline val MessageChain.internalId: Int
|
||||||
|
get() = this.source.internalId
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息时间.
|
||||||
|
* 仅从服务器接收的消息才可以获取
|
||||||
|
*
|
||||||
|
* @see MessageSource.id
|
||||||
|
*/
|
||||||
|
@get:JvmSynthetic
|
||||||
|
inline val MessageChain.time: Int
|
||||||
|
get() = this.source.time
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息内部 id.
|
||||||
|
* 仅从服务器接收的消息才可以获取
|
||||||
|
*
|
||||||
|
* @see MessageSource.id
|
||||||
|
*/
|
||||||
|
@get:JvmSynthetic
|
||||||
|
inline val MessageChain.bot: Bot
|
||||||
|
get() = this.source.bot
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取这条消息源
|
* 获取这条消息源
|
||||||
* 仅从服务器接收的消息才可以获取消息源
|
* 仅从服务器接收的消息才可以获取消息源
|
||||||
@ -361,9 +469,31 @@ inline val MessageChain.id: Int
|
|||||||
inline val MessageChain.source: MessageSource
|
inline val MessageChain.source: MessageSource
|
||||||
get() = this[MessageSource]
|
get() = this[MessageSource]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 撤回这条消息. 可撤回自己 2 分钟内发出的消息, 和任意时间的群成员的消息.
|
||||||
|
*
|
||||||
|
* [Bot] 撤回自己的消息不需要权限.
|
||||||
|
* [Bot] 撤回群员的消息需要管理员权限.
|
||||||
|
*
|
||||||
|
* @throws PermissionDeniedException 当 [Bot] 无权限操作时
|
||||||
|
* @throws IllegalStateException 当这条消息已经被撤回时 (仅同步主动操作)
|
||||||
|
*
|
||||||
|
* @see Bot.recall
|
||||||
|
*/
|
||||||
@JvmSynthetic
|
@JvmSynthetic
|
||||||
suspend inline fun MessageChain.recall() = this.source.recall()
|
suspend inline fun MessageChain.recall() = this.source.recall()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在一段时间后撤回这条消息. 可撤回自己 2 分钟内发出的消息, 和任意时间的群成员的消息.
|
||||||
|
*
|
||||||
|
* [Bot] 撤回自己的消息不需要权限.
|
||||||
|
* [Bot] 撤回群员的消息需要管理员权限.
|
||||||
|
*
|
||||||
|
* @throws PermissionDeniedException 当 [Bot] 无权限操作时
|
||||||
|
* @throws IllegalStateException 当这条消息已经被撤回时 (仅同步主动操作)
|
||||||
|
*
|
||||||
|
* @see Bot.recall
|
||||||
|
*/
|
||||||
@JvmSynthetic
|
@JvmSynthetic
|
||||||
inline fun MessageChain.recallIn(
|
inline fun MessageChain.recallIn(
|
||||||
millis: Long,
|
millis: Long,
|
||||||
|
@ -25,6 +25,9 @@ import kotlin.jvm.JvmMultifileClass
|
|||||||
import kotlin.jvm.JvmName
|
import kotlin.jvm.JvmName
|
||||||
import kotlin.jvm.JvmSynthetic
|
import kotlin.jvm.JvmSynthetic
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将在线消息源转换为离线消息源.
|
||||||
|
*/
|
||||||
@SinceMirai("0.39.0")
|
@SinceMirai("0.39.0")
|
||||||
@JvmName("toOfflineMessageSource")
|
@JvmName("toOfflineMessageSource")
|
||||||
fun OnlineMessageSource.toOffline(): OfflineMessageSource =
|
fun OnlineMessageSource.toOffline(): OfflineMessageSource =
|
||||||
@ -60,6 +63,14 @@ interface MessageSourceAmender {
|
|||||||
var internalId: Int
|
var internalId: Int
|
||||||
|
|
||||||
var originalMessage: MessageChain
|
var originalMessage: MessageChain
|
||||||
|
|
||||||
|
/** 从另一个 [MessageSource] 中复制 [id], [internalId], [time]*/
|
||||||
|
@SinceMirai("0.39.2")
|
||||||
|
fun metadataFrom(another: MessageSource) {
|
||||||
|
this.id = another.id
|
||||||
|
this.internalId = another.internalId
|
||||||
|
this.time = another.time
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@ package net.mamoe.mirai.message.data
|
|||||||
|
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import net.mamoe.mirai.Bot
|
import net.mamoe.mirai.Bot
|
||||||
import net.mamoe.mirai.message.MessageReceipt
|
|
||||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||||
import net.mamoe.mirai.utils.SinceMirai
|
import net.mamoe.mirai.utils.SinceMirai
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
@ -29,10 +28,19 @@ import kotlin.jvm.JvmSynthetic
|
|||||||
/**
|
/**
|
||||||
* 引用回复.
|
* 引用回复.
|
||||||
*
|
*
|
||||||
* 可以引用一条群消息并发送给一个好友, 或是引用好友消息发送给群.
|
* 支持引用任何一条消息发送给任何人.
|
||||||
* 可以引用自己发出的消息. 详见 [MessageReceipt.quote]
|
|
||||||
*
|
*
|
||||||
* @see MessageSource 获取更多信息
|
* #### [source] 的类型:
|
||||||
|
* - 在发送引用回复时, [source] 类型为 [OnlineMessageSource] 或 [OfflineMessageSource]
|
||||||
|
* - 在接收引用回复时, [source] 类型一定为 [OfflineMessageSource]
|
||||||
|
*
|
||||||
|
* #### 原消息内容
|
||||||
|
* 引用回复的原消息内容完全由 [source] 中 [MessageSource.originalMessage] 控制, 客户端不会自行寻找原消息.
|
||||||
|
*
|
||||||
|
* #### 客户端内跳转
|
||||||
|
* 客户端在跳转原消息时, 会通过 [MessageSource.id] 等 metadata
|
||||||
|
*
|
||||||
|
* @see MessageSource 获取有关消息源的更多信息
|
||||||
*/
|
*/
|
||||||
@OptIn(MiraiExperimentalAPI::class)
|
@OptIn(MiraiExperimentalAPI::class)
|
||||||
@SinceMirai("0.33.0")
|
@SinceMirai("0.33.0")
|
||||||
@ -50,26 +58,52 @@ class QuoteReply(val source: MessageSource) : Message, MessageMetadata, Constrai
|
|||||||
override fun hashCode(): Int = source.hashCode()
|
override fun hashCode(): Int = source.hashCode()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see MessageSource.id
|
||||||
|
*/
|
||||||
@get:JvmSynthetic
|
@get:JvmSynthetic
|
||||||
inline val QuoteReply.id: Int
|
inline val QuoteReply.id: Int
|
||||||
get() = source.id
|
get() = source.id
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see MessageSource.internalId
|
||||||
|
*/
|
||||||
|
@SinceMirai("0.39.2")
|
||||||
|
@get:JvmSynthetic
|
||||||
|
inline val QuoteReply.internalId: Int
|
||||||
|
get() = source.internalId
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see MessageSource.fromId
|
||||||
|
*/
|
||||||
@get:JvmSynthetic
|
@get:JvmSynthetic
|
||||||
inline val QuoteReply.fromId: Long
|
inline val QuoteReply.fromId: Long
|
||||||
get() = source.fromId
|
get() = source.fromId
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see MessageSource.targetId
|
||||||
|
*/
|
||||||
@get:JvmSynthetic
|
@get:JvmSynthetic
|
||||||
inline val QuoteReply.targetId: Long
|
inline val QuoteReply.targetId: Long
|
||||||
get() = source.targetId
|
get() = source.targetId
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see MessageSource.originalMessage
|
||||||
|
*/
|
||||||
@get:JvmSynthetic
|
@get:JvmSynthetic
|
||||||
inline val QuoteReply.originalMessage: MessageChain
|
inline val QuoteReply.originalMessage: MessageChain
|
||||||
get() = source.originalMessage
|
get() = source.originalMessage
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see MessageSource.time
|
||||||
|
*/
|
||||||
@get:JvmSynthetic
|
@get:JvmSynthetic
|
||||||
inline val QuoteReply.time: Int
|
inline val QuoteReply.time: Int
|
||||||
get() = source.time
|
get() = source.time
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see MessageSource.bot
|
||||||
|
*/
|
||||||
@get:JvmSynthetic
|
@get:JvmSynthetic
|
||||||
inline val QuoteReply.bot: Bot
|
inline val QuoteReply.bot: Bot
|
||||||
get() = source.bot
|
get() = source.bot
|
||||||
@ -78,6 +112,9 @@ inline val QuoteReply.bot: Bot
|
|||||||
@JvmSynthetic
|
@JvmSynthetic
|
||||||
suspend inline fun QuoteReply.recall() = this.source.recall()
|
suspend inline fun QuoteReply.recall() = this.source.recall()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在一段时间后撤回这条消息.
|
||||||
|
*/
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
inline fun QuoteReply.recallIn(
|
inline fun QuoteReply.recallIn(
|
||||||
millis: Long,
|
millis: Long,
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:JvmName("HummerMessageKt")
|
||||||
|
@file:Suppress("NOTHING_TO_INLINE")
|
||||||
|
|
||||||
|
package net.mamoe.mirai.message.data
|
||||||
|
|
||||||
|
import net.mamoe.mirai.utils.PlannedRemoval
|
||||||
|
import net.mamoe.mirai.utils.SinceMirai
|
||||||
|
import kotlin.jvm.JvmName
|
||||||
|
import kotlin.jvm.JvmSynthetic
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
因为文件改名为做的兼容
|
||||||
|
*/
|
||||||
|
|
||||||
|
@PlannedRemoval("1.0.0")
|
||||||
|
@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||||
|
@JvmName("flash")
|
||||||
|
@SinceMirai("0.33.0")
|
||||||
|
inline fun Image.flash2(): FlashImage = FlashImage(this)
|
||||||
|
|
||||||
|
@PlannedRemoval("1.0.0")
|
||||||
|
@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||||
|
@JvmName("flash")
|
||||||
|
@JvmSynthetic
|
||||||
|
@SinceMirai("0.33.0")
|
||||||
|
inline fun GroupImage.flash2(): GroupFlashImage = FlashImage(this) as GroupFlashImage
|
||||||
|
|
||||||
|
@PlannedRemoval("1.0.0")
|
||||||
|
@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||||
|
@JvmName("flash")
|
||||||
|
@JvmSynthetic
|
||||||
|
@SinceMirai("0.33.0")
|
||||||
|
inline fun FriendImage.flash2(): FriendFlashImage = FlashImage(this) as FriendFlashImage
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:JvmName("MessageKt")
|
||||||
|
@file:Suppress("NOTHING_TO_INLINE")
|
||||||
|
|
||||||
|
package net.mamoe.mirai.message.data
|
||||||
|
|
||||||
|
import net.mamoe.mirai.utils.PlannedRemoval
|
||||||
|
import kotlin.jvm.JvmName
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
因为文件改名为做的兼容
|
||||||
|
*/
|
||||||
|
|
||||||
|
@PlannedRemoval("1.0.0")
|
||||||
|
@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||||
|
@JvmName("isPlain")
|
||||||
|
inline fun Message.isPlain2(): Boolean = this is PlainText
|
||||||
|
|
||||||
|
@PlannedRemoval("1.0.0")
|
||||||
|
@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||||
|
@JvmName("isNotPlain")
|
||||||
|
inline fun Message.isNotPlain2(): Boolean = this !is PlainText
|
||||||
|
|
||||||
|
@PlannedRemoval("1.0.0")
|
||||||
|
@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||||
|
@JvmName("repeat")
|
||||||
|
// inline: for future removal
|
||||||
|
inline fun Message.repeat2(count: Int): MessageChain {
|
||||||
|
if (this is ConstrainSingle<*>) {
|
||||||
|
// fast-path
|
||||||
|
return this.asMessageChain()
|
||||||
|
}
|
||||||
|
return buildMessageChain(count) {
|
||||||
|
add(this@repeat2)
|
||||||
|
}
|
||||||
|
}
|
@ -42,6 +42,8 @@ inline fun buildMessageChain(initialSize: Int, block: MessageChainBuilder.() ->
|
|||||||
/**
|
/**
|
||||||
* [MessageChain] 构建器.
|
* [MessageChain] 构建器.
|
||||||
* 多个连续的 [String] 会被连接为单个 [PlainText] 以优化性能.
|
* 多个连续的 [String] 会被连接为单个 [PlainText] 以优化性能.
|
||||||
|
*
|
||||||
|
*
|
||||||
* **注意:** 无并发安全性.
|
* **注意:** 无并发安全性.
|
||||||
*
|
*
|
||||||
* @see buildMessageChain 推荐使用
|
* @see buildMessageChain 推荐使用
|
||||||
@ -91,6 +93,7 @@ open class MessageChainBuilder private constructor(
|
|||||||
return addAll(elements.flatten())
|
return addAll(elements.flatten())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmSynthetic
|
||||||
operator fun Message.unaryPlus() {
|
operator fun Message.unaryPlus() {
|
||||||
checkBuilt()
|
checkBuilt()
|
||||||
flushCache()
|
flushCache()
|
||||||
@ -98,22 +101,26 @@ open class MessageChainBuilder private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JvmSynthetic
|
||||||
operator fun String.unaryPlus() {
|
operator fun String.unaryPlus() {
|
||||||
checkBuilt()
|
checkBuilt()
|
||||||
add(this)
|
add(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmSynthetic // they should use add
|
||||||
operator fun plusAssign(plain: String) {
|
operator fun plusAssign(plain: String) {
|
||||||
checkBuilt()
|
checkBuilt()
|
||||||
withCache { append(plain) }
|
withCache { append(plain) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmSynthetic // they should use add
|
||||||
operator fun plusAssign(message: Message) {
|
operator fun plusAssign(message: Message) {
|
||||||
checkBuilt()
|
checkBuilt()
|
||||||
flushCache()
|
flushCache()
|
||||||
this.add(message)
|
this.add(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmSynthetic // they should use add
|
||||||
operator fun plusAssign(message: SingleMessage) { // avoid resolution ambiguity
|
operator fun plusAssign(message: SingleMessage) { // avoid resolution ambiguity
|
||||||
checkBuilt()
|
checkBuilt()
|
||||||
flushCache()
|
flushCache()
|
||||||
@ -125,6 +132,7 @@ open class MessageChainBuilder private constructor(
|
|||||||
withCache { append(plain) }
|
withCache { append(plain) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmSynthetic // they should use add
|
||||||
operator fun plusAssign(charSequence: CharSequence) {
|
operator fun plusAssign(charSequence: CharSequence) {
|
||||||
checkBuilt()
|
checkBuilt()
|
||||||
withCache { append(charSequence) }
|
withCache { append(charSequence) }
|
||||||
|
@ -311,9 +311,11 @@ internal class SingleMessageChainImpl constructor(
|
|||||||
|
|
||||||
|
|
||||||
@SharedImmutable
|
@SharedImmutable
|
||||||
|
@get:JvmSynthetic
|
||||||
internal val EMPTY_BYTE_ARRAY = ByteArray(0)
|
internal val EMPTY_BYTE_ARRAY = ByteArray(0)
|
||||||
|
|
||||||
|
|
||||||
|
@JvmSynthetic
|
||||||
@Suppress("NOTHING_TO_INLINE") // no stack waste
|
@Suppress("NOTHING_TO_INLINE") // no stack waste
|
||||||
internal inline fun Char.hexDigitToByte(): Int {
|
internal inline fun Char.hexDigitToByte(): Int {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
@ -324,6 +326,7 @@ internal inline fun Char.hexDigitToByte(): Int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmSynthetic
|
||||||
internal fun String.skipToSecondHyphen(): Int {
|
internal fun String.skipToSecondHyphen(): Int {
|
||||||
var count = 0
|
var count = 0
|
||||||
this.forEachIndexed { index, c ->
|
this.forEachIndexed { index, c ->
|
||||||
@ -332,6 +335,7 @@ internal fun String.skipToSecondHyphen(): Int {
|
|||||||
error("cannot find two hyphens")
|
error("cannot find two hyphens")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmSynthetic
|
||||||
internal fun String.imageIdToMd5(offset: Int): ByteArray {
|
internal fun String.imageIdToMd5(offset: Int): ByteArray {
|
||||||
val result = ByteArray(16)
|
val result = ByteArray(16)
|
||||||
var cur = 0
|
var cur = 0
|
||||||
|
Loading…
Reference in New Issue
Block a user