From b70bf5e042bc6dda1332be7e8a597d767e8765d5 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 22 Feb 2020 21:47:02 +0800 Subject: [PATCH] Rewrite `recall` and `MessageSource.id` --- .../mirai/api/http/data/common/MessageDTO.kt | 2 +- .../net/mamoe/mirai/qqandroid/ContactImpl.kt | 4 +- .../net/mamoe/mirai/qqandroid/QQAndroidBot.kt | 19 ++++++++- .../qqandroid/message/MessageSourceFromMsg.kt | 18 +++++--- .../packet/chat/receive/MessageSvc.kt | 27 ++++++------ .../commonMain/kotlin/net.mamoe.mirai/Bot.kt | 6 ++- .../kotlin/net.mamoe.mirai/contact/Contact.kt | 42 +++++++++++++++++++ .../net.mamoe.mirai/message/GroupMessage.kt | 18 +++++--- .../net.mamoe.mirai/message/MessageReceipt.kt | 10 +++-- .../message/data/MessageSource.kt | 39 ++++++++++++----- 10 files changed, 141 insertions(+), 44 deletions(-) diff --git a/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/data/common/MessageDTO.kt b/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/data/common/MessageDTO.kt index a4a30d82f..a66b42fd6 100644 --- a/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/data/common/MessageDTO.kt +++ b/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/data/common/MessageDTO.kt @@ -99,7 +99,7 @@ fun MessageChain.toDTOChain() = mutableListOf(this[MessageSource].toDTO()).apply fun MessageChainDTO.toMessageChain(contact: Contact) = MessageChain().apply { this@toMessageChain.forEach { add(it.toMessage(contact)) } } -internal fun MessageSource.calMessageId() = (messageUid.toLong() shl 32) or (sequenceId.toLong() and 0xFFFFFFFF) +internal fun MessageSource.calMessageId() = (messageRandom.toLong() shl 32) or (sequenceId.toLong() and 0xFFFFFFFF) @UseExperimental(ExperimentalUnsignedTypes::class) fun Message.toDTO() = when (this) { diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt index d2b80a21b..8d1c88117 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt @@ -79,7 +79,7 @@ internal class QQImpl( ) { source = it }.sendAndExpect() is MessageSvc.PbSendMsg.Response.SUCCESS ) { "send message failed" } } - return MessageReceipt(message, source, this) + return MessageReceipt(source, this) } override suspend fun uploadImage(image: ExternalImage): Image = try { @@ -553,7 +553,7 @@ internal class GroupImpl( source.startWaitingSequenceId(this) - return MessageReceipt(message, source, this) + return MessageReceipt(source, this) } override suspend fun uploadImage(image: ExternalImage): Image = try { diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt index 7b9c2326a..a7e2f8bd5 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt @@ -19,6 +19,8 @@ import net.mamoe.mirai.data.GroupInfo import net.mamoe.mirai.data.MemberInfo import net.mamoe.mirai.message.data.Image import net.mamoe.mirai.message.data.MessageSource +import net.mamoe.mirai.message.data.messageRandom +import net.mamoe.mirai.message.data.sequenceId import net.mamoe.mirai.qqandroid.network.QQAndroidBotNetworkHandler import net.mamoe.mirai.qqandroid.network.QQAndroidClient import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.GroupInfoImpl @@ -127,12 +129,27 @@ internal abstract class QQAndroidBotBase constructor( network.run { val response: PbMessageSvc.PbMsgWithDraw.Response = - PbMessageSvc.PbMsgWithDraw.Group(bot.client, source.groupId, source.sequenceId, source.messageUid) + PbMessageSvc.PbMsgWithDraw.Group(bot.client, source.groupId, source.sequenceId, source.messageRandom) .sendAndExpect() check(response is PbMessageSvc.PbMsgWithDraw.Response.Success) { "Failed to recall message #${source.sequenceId}: $response" } } } + override suspend fun recall(groupId: Long, senderId: Long, messageId: Long) { + if (senderId != uin) { + getGroup(groupId).checkBotPermissionOperator() + } + + val sequenceId = (messageId shr 32).toInt() + + network.run { + val response: PbMessageSvc.PbMsgWithDraw.Response = + PbMessageSvc.PbMsgWithDraw.Group(bot.client, groupId, sequenceId, messageId.toInt()) + .sendAndExpect() + check(response is PbMessageSvc.PbMsgWithDraw.Response.Success) { "Failed to recall message #$sequenceId: $response" } + } + } + override suspend fun Image.download(): ByteReadPacket { TODO("not implemented") } diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/MessageSourceFromMsg.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/MessageSourceFromMsg.kt index 44065d95b..ac8fa65ee 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/MessageSourceFromMsg.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/MessageSourceFromMsg.kt @@ -11,6 +11,7 @@ package net.mamoe.mirai.qqandroid.message import net.mamoe.mirai.contact.Group import net.mamoe.mirai.message.data.MessageSource +import net.mamoe.mirai.message.data.messageRandom import net.mamoe.mirai.qqandroid.io.serialization.loadAs import net.mamoe.mirai.qqandroid.io.serialization.toByteArray import net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody @@ -21,13 +22,16 @@ internal inline class MessageSourceFromServer( val delegate: ImMsgBody.SourceMsg ) : MessageSource { override val time: Long get() = delegate.time.toLong() and 0xFFFFFFFF - override val sequenceId: Int get() = delegate.origSeqs?.firstOrNull() ?: error("cannot find sequenceId from ImMsgBody.SourceMsg") + + override val id: Long + get() = (delegate.origSeqs?.firstOrNull() ?: error("cannot find sequenceId from ImMsgBody.SourceMsg")).toLong().shl(32) or + (delegate.pbReserve.loadAs(SourceMsg.ResvAttr.serializer()).origUids!!.toInt()).toLong().and(0xFFFFFFFF) + override suspend fun ensureSequenceIdAvailable() { // nothing to do } - override val messageUid: Int get() = delegate.pbReserve.loadAs(SourceMsg.ResvAttr.serializer()).origUids!!.toInt() // override val sourceMessage: MessageChain get() = delegate.toMessageChain() override val senderId: Long get() = delegate.senderUin override val groupId: Long get() = Group.calculateGroupCodeByGroupUin(delegate.toUin) @@ -39,12 +43,14 @@ internal inline class MessageSourceFromMsg( val delegate: MsgComm.Msg ) : MessageSource { override val time: Long get() = delegate.msgHead.msgTime.toLong() and 0xFFFFFFFF - override val sequenceId: Int get() = delegate.msgHead.msgSeq + override val id: Long + get() = delegate.msgHead.msgSeq.toLong().shl(32) or + delegate.msgBody.richText.attr!!.random.toLong().and(0xFFFFFFFF) + override suspend fun ensureSequenceIdAvailable() { // nothing to do } - override val messageUid: Int get() = delegate.msgBody.richText.attr!!.random // override val sourceMessage: MessageChain get() = delegate.toMessageChain() override val senderId: Long get() = delegate.msgHead.fromUin override val groupId: Long get() = delegate.msgHead.groupInfo!!.groupCode @@ -62,7 +68,7 @@ internal inline class MessageSourceFromMsg( type = 0, time = delegate.msgHead.msgTime, pbReserve = SourceMsg.ResvAttr( - origUids = messageUid.toLong() and 0xffFFffFF + origUids = messageRandom.toLong() and 0xffFFffFF ).toByteArray(SourceMsg.ResvAttr.serializer()), srcMsg = MsgComm.Msg( msgHead = MsgComm.MsgHead( @@ -72,7 +78,7 @@ internal inline class MessageSourceFromMsg( c2cCmd = delegate.msgHead.c2cCmd, msgSeq = delegate.msgHead.msgSeq, msgTime = delegate.msgHead.msgTime, - msgUid = messageUid.toLong() and 0xffFFffFF + msgUid = messageRandom.toLong() and 0xffFFffFF , // ok groupInfo = MsgComm.GroupInfo(groupCode = delegate.msgHead.groupInfo.groupCode), isSrcMsg = true diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt index 694dd7277..3054692fd 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt @@ -272,7 +272,7 @@ internal class MessageSvc { } internal class MessageSourceFromSend( - override val messageUid: Int, + val messageRandom: Int, override val time: Long, override val senderId: Long, override val groupId: Long// , @@ -280,19 +280,20 @@ internal class MessageSvc { ) : MessageSource { private lateinit var sequenceIdDeferred: Deferred + @UseExperimental(ExperimentalCoroutinesApi::class) + override val id: Long + get() = sequenceIdDeferred.getCompleted().toLong().shl(32) or + messageRandom.toLong().and(0xFFFFFFFF) + @UseExperimental(MiraiExperimentalAPI::class) fun startWaitingSequenceId(contact: Contact) { sequenceIdDeferred = contact.subscribingGetAsync { - if (it.messageRandom == messageUid) { + if (it.messageRandom == this@MessageSourceFromSend.messageRandom) { it.sequenceId } else null } } - @UseExperimental(ExperimentalCoroutinesApi::class) - override val sequenceId: Int - get() = sequenceIdDeferred.getCompleted() - override suspend fun ensureSequenceIdAvailable() { sequenceIdDeferred.join() } @@ -309,7 +310,7 @@ internal class MessageSvc { crossinline sourceCallback: (MessageSource) -> Unit ): OutgoingPacket { val source = MessageSourceFromSend( - messageUid = Random.nextInt().absoluteValue, + messageRandom = Random.nextInt().absoluteValue, senderId = client.uin, time = currentTimeSeconds + client.timeDifference, groupId = 0// @@ -327,7 +328,7 @@ internal class MessageSvc { client: QQAndroidClient, toUin: Long, message: MessageChain, - source: MessageSource + source: MessageSourceFromSend ): OutgoingPacket = buildOutgoingUniPacket(client) { ///writeFully("0A 08 0A 06 08 89 FC A6 8C 0B 12 06 08 01 10 00 18 00 1A 1F 0A 1D 12 08 0A 06 0A 04 F0 9F 92 A9 12 11 AA 02 0E 88 01 00 9A 01 08 78 00 F8 01 00 C8 02 00 20 9B 7A 28 F4 CA 9B B8 03 32 34 08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00 40 01".hexToBytes()) @@ -342,7 +343,7 @@ internal class MessageSvc { ) ), msgSeq = client.atomicNextMessageSequenceId(), - msgRand = source.messageUid, + msgRand = source.messageRandom, syncCookie = SyncCookie(time = source.time).toByteArray(SyncCookie.serializer()) // msgVia = 1 ) @@ -358,7 +359,7 @@ internal class MessageSvc { ): OutgoingPacket { val source = MessageSourceFromSend( - messageUid = Random.nextInt().absoluteValue, + messageRandom = Random.nextInt().absoluteValue, senderId = client.uin, time = currentTimeSeconds + client.timeDifference, groupId = groupCode//, @@ -372,11 +373,11 @@ internal class MessageSvc { * 发送群消息 */ @Suppress("FunctionName") - fun ToGroup( + private fun ToGroup( client: QQAndroidClient, groupCode: Long, message: MessageChain, - source: MessageSource + source: MessageSourceFromSend ): OutgoingPacket = buildOutgoingUniPacket(client) { ///writeFully("0A 08 0A 06 08 89 FC A6 8C 0B 12 06 08 01 10 00 18 00 1A 1F 0A 1D 12 08 0A 06 0A 04 F0 9F 92 A9 12 11 AA 02 0E 88 01 00 9A 01 08 78 00 F8 01 00 C8 02 00 20 9B 7A 28 F4 CA 9B B8 03 32 34 08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00 40 01".hexToBytes()) @@ -393,7 +394,7 @@ internal class MessageSvc { ) ), msgSeq = client.atomicNextMessageSequenceId(), - msgRand = source.messageUid, + msgRand = source.messageRandom, syncCookie = EMPTY_BYTE_ARRAY, msgVia = 1 ) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt index 24ea3516e..e5ecf61af 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt @@ -231,11 +231,13 @@ abstract class Bot : CoroutineScope { * [Bot] 撤回自己的消息不需要权限. * [Bot] 撤回群员的消息需要管理员权限. * + * @param messageId 即 [MessageSource.id] + * * @throws PermissionDeniedException 当 [Bot] 无权限操作时 * @see Bot.recall (扩展函数) 接受参数 [MessageChain] - * @see 更推荐说 + * @see recall 请优先使用这个函数 */ - abstract suspend fun recall(groupId: Long, messageSequenceId: Int, messageUid: Int) + abstract suspend fun recall(groupId: Long, senderId: Long, messageId: Long) @Deprecated("内存使用效率十分低下", ReplaceWith("this.download()"), DeprecationLevel.WARNING) @MiraiExperimentalAPI("未支持") diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt index a00d8021d..42b232bce 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt @@ -12,6 +12,7 @@ package net.mamoe.mirai.contact import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job import net.mamoe.mirai.Bot import net.mamoe.mirai.event.events.BeforeImageUploadEvent import net.mamoe.mirai.event.events.EventCancelledException @@ -20,8 +21,13 @@ import net.mamoe.mirai.event.events.MessageSendEvent.FriendMessageSendEvent import net.mamoe.mirai.event.events.MessageSendEvent.GroupMessageSendEvent import net.mamoe.mirai.message.MessageReceipt import net.mamoe.mirai.message.data.* +import net.mamoe.mirai.recall +import net.mamoe.mirai.recallIn import net.mamoe.mirai.utils.ExternalImage +import net.mamoe.mirai.utils.MiraiExperimentalAPI import net.mamoe.mirai.utils.WeakRefProperty +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext /** @@ -92,8 +98,44 @@ interface Contact : CoroutineScope { override fun toString(): String } +/** + * @see Bot.recall + */ +@MiraiExperimentalAPI +suspend inline fun Contact.recall(source: MessageChain) = this.bot.recall(source) + +/** + * @see Bot.recall + */ +suspend inline fun Contact.recall(source: MessageSource) = this.bot.recall(source) + +/** + * @see Bot.recallIn + */ +@MiraiExperimentalAPI +fun Contact.recallIn( + message: MessageChain, + millis: Long, + coroutineContext: CoroutineContext = EmptyCoroutineContext +): Job = this.bot.recallIn(message, millis, coroutineContext) + +/** + * @see Bot.recallIn + */ +fun Contact.recallIn( + source: MessageSource, + millis: Long, + coroutineContext: CoroutineContext = EmptyCoroutineContext +): Job = this.bot.recallIn(source, millis, coroutineContext) + +/** + * @see Contact.sendMessage + */ @Suppress("UNCHECKED_CAST") suspend inline fun C.sendMessage(message: Message): MessageReceipt = sendMessage(message.toChain()) as? MessageReceipt ?: error("Internal class cast mistake") +/** + * @see Contact.sendMessage + */ suspend inline fun C.sendMessage(plain: String): MessageReceipt = sendMessage(plain.toMessage()) \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/GroupMessage.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/GroupMessage.kt index 5752b8755..f30ee0a84 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/GroupMessage.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/GroupMessage.kt @@ -11,11 +11,16 @@ package net.mamoe.mirai.message import kotlinx.coroutines.Job import net.mamoe.mirai.Bot -import net.mamoe.mirai.contact.* +import net.mamoe.mirai.contact.Group +import net.mamoe.mirai.contact.Member +import net.mamoe.mirai.contact.MemberPermission import net.mamoe.mirai.event.Event import net.mamoe.mirai.message.data.Message import net.mamoe.mirai.message.data.MessageChain import net.mamoe.mirai.message.data.MessageSource +import net.mamoe.mirai.recall +import net.mamoe.mirai.recallIn +import net.mamoe.mirai.utils.MiraiExperimentalAPI import net.mamoe.mirai.utils.getValue import net.mamoe.mirai.utils.unsafeWeakRef import kotlin.jvm.JvmName @@ -59,10 +64,13 @@ class GroupMessage( @JvmName("reply2") suspend inline fun MessageChain.quoteReply(): MessageReceipt = quoteReply(this) - suspend inline fun MessageChain.recall() = group.recall(this) - suspend inline fun MessageSource.recall() = group.recall(this) - inline fun MessageSource.recallIn(delay: Long): Job = group.recallIn(this, delay) - inline fun MessageChain.recallIn(delay: Long): Job = group.recallIn(this, delay) + @MiraiExperimentalAPI + suspend inline fun MessageChain.recall() = bot.recall(this) + + suspend inline fun MessageSource.recall() = bot.recall(this) + inline fun MessageSource.recallIn(delay: Long): Job = bot.recallIn(this, delay) + @MiraiExperimentalAPI + inline fun MessageChain.recallIn(delay: Long): Job = bot.recallIn(this, delay) override fun toString(): String = "GroupMessage(group=${group.id}, senderName=$senderName, sender=${sender.id}, permission=${permission.name}, message=$message)" diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageReceipt.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageReceipt.kt index d760a88f9..46a666f54 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageReceipt.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageReceipt.kt @@ -12,8 +12,11 @@ package net.mamoe.mirai.message import kotlinx.atomicfu.atomic import kotlinx.coroutines.Job import net.mamoe.mirai.Bot -import net.mamoe.mirai.contact.* +import net.mamoe.mirai.contact.Contact +import net.mamoe.mirai.contact.Group +import net.mamoe.mirai.contact.QQ import net.mamoe.mirai.message.data.* +import net.mamoe.mirai.recallIn import net.mamoe.mirai.utils.MiraiExperimentalAPI import net.mamoe.mirai.utils.getValue import net.mamoe.mirai.utils.unsafeWeakRef @@ -27,7 +30,6 @@ import net.mamoe.mirai.utils.unsafeWeakRef * @see QQ.sendMessage 发送群消息, 返回回执(此对象) */ open class MessageReceipt( - val originalMessage: MessageChain, private val source: MessageSource, target: C ) { @@ -54,7 +56,7 @@ open class MessageReceipt( if (_isRecalled.compareAndSet(false, true)) { when (val contact = target) { is Group -> { - contact.recall(source) + contact.bot.recall(source) } is QQ -> { TODO() @@ -77,7 +79,7 @@ open class MessageReceipt( if (_isRecalled.compareAndSet(false, true)) { when (val contact = target) { is Group -> { - return contact.recallIn(source, millis) + return contact.bot.recallIn(source, millis) } is QQ -> { TODO() diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageSource.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageSource.kt index d7a047a30..e57f8711c 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageSource.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageSource.kt @@ -27,9 +27,11 @@ interface MessageSource : Message { companion object Key : Message.Key /** - * 序列号. 若是机器人发出去的消息, 请先 [确保 sequenceId 可用][ensureSequenceIdAvailable] + * 在 Mirai 中使用的 id. + * 高 32 位为 [sequenceId], + * 低 32 位为 [messageRandom] */ - val sequenceId: Int + val id: Long /** * 等待 [sequenceId] 获取, 确保其可用. @@ -38,11 +40,6 @@ interface MessageSource : Message { */ suspend fun ensureSequenceIdAvailable() - /** - * 实际上是个随机数, 但服务器确实是用它当做 uid - */ - val messageUid: Int - /** * 发送时间, 单位为秒 */ @@ -65,11 +62,33 @@ interface MessageSource : Message { } /** - * 消息唯一标识符. 实际上是个随机数, 但服务器确实是用它当做 uid + * 序列号. 若是机器人发出去的消息, 请先 [确保 sequenceId 可用][MessageSource.ensureSequenceIdAvailable] + * @see MessageSource.id */ -val MessageChain.messageUid get() = this[MessageSource].messageUid +val MessageSource.sequenceId: Int get() = (this.id shr 32).toInt() + +/** + * 消息随机数. 由服务器或客户端指定后不能更改. 它是消息 id 的一部分. + * @see MessageSource.id + */ +val MessageSource.messageRandom: Int get() = this.id.toInt() + +// For MessageChain + +/** + * 消息 id. + * @see MessageSource.id + */ +val MessageChain.id: Long get() = this[MessageSource].id /** * 消息序列号, 可能来自服务器也可以发送时赋值, 不唯一. + * @see MessageSource.id */ -val MessageChain.sequenceId get() = this[MessageSource].sequenceId \ No newline at end of file +val MessageChain.sequenceId: Int get() = this[MessageSource].sequenceId + +/** + * 消息随机数. 由服务器或客户端指定后不能更改. 它是消息 id 的一部分. + * @see MessageSource.id + */ +val MessageChain.messageRandom: Int get() = this[MessageSource].messageRandom