From fb19c0af364bc739d7b4e08e4079bbfadf79eb0f Mon Sep 17 00:00:00 2001 From: Him188 Date: Tue, 7 Apr 2020 10:06:11 +0800 Subject: [PATCH] Support `MessageSource` in `MessageSource.originalMessage` --- .../qqandroid/message/MessageSourceImpl.kt | 43 ++++++++++++++++--- .../mirai/qqandroid/message/convension.kt | 24 +++++++---- .../packet/chat/receive/MessageSvc.kt | 2 +- .../packet/chat/receive/OnlinePush.kt | 2 +- 4 files changed, 56 insertions(+), 15 deletions(-) diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/MessageSourceImpl.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/MessageSourceImpl.kt index 95a2298b8..4f2f56fe3 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/MessageSourceImpl.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/MessageSourceImpl.kt @@ -38,7 +38,7 @@ import net.mamoe.mirai.utils.MiraiExperimentalAPI internal interface MessageSourceImpl { val sequenceId: Int - var isRecalledOrPlanned: Boolean + var isRecalledOrPlanned: Boolean // // TODO: 2020/4/7 实现 isRecalledOrPlanned } internal suspend inline fun MessageSource.ensureSequenceIdAvailable() { @@ -60,7 +60,13 @@ internal class MessageSourceFromFriendImpl( } override val id: Int get() = msg.msgBody.richText.attr!!.random override val time: Int get() = msg.msgHead.msgTime - override val originalMessage: MessageChain by lazy { msg.toMessageChain(bot, groupIdOrZero = 0, addSource = false) } + override val originalMessage: MessageChain by lazy { + msg.toMessageChain( + bot, + groupIdOrZero = 0, + onlineSource = false + ) + } override val target: Bot get() = bot override val sender: QQ get() = bot.getFriend(msg.msgHead.fromUin) @@ -121,7 +127,7 @@ internal class MessageSourceFromGroupImpl( msg.toMessageChain( bot, groupIdOrZero = group.id, - addSource = false + onlineSource = false ) } override val target: Bot get() = bot @@ -148,7 +154,34 @@ internal class MessageSourceFromGroupImpl( } } -internal class OfflineMessageSourceImpl( // from others' quotation +internal class OfflineMessageSourceImplByMsg( // from other sources' originalMessage + val delegate: MsgComm.Msg, + override val bot: Bot +) : OfflineMessageSource(), MessageSourceImpl { + override val kind: Kind = if (delegate.msgHead.groupInfo != null) Kind.GROUP else Kind.FRIEND + override val id: Int + get() = delegate.msgHead.msgUid.toInt() + override val time: Int + get() = delegate.msgHead.msgTime + override val fromId: Long + get() = delegate.msgHead.fromUin + override val targetId: Long + get() = delegate.msgHead.groupInfo?.groupCode ?: delegate.msgHead.toUin + override val originalMessage: MessageChain by lazy { + delegate.toMessageChain(bot, delegate.msgHead.groupInfo?.groupCode ?: 0, false) + } + override val sequenceId: Int + get() = delegate.msgHead.msgSeq + + private val isRecalled: AtomicBoolean = atomic(false) + override var isRecalledOrPlanned: Boolean + get() = isRecalled.value + set(value) { + isRecalled.value = value + } +} + +internal class OfflineMessageSourceImplBySourceMsg( // from others' quotation val delegate: ImMsgBody.SourceMsg, override val bot: Bot, groupIdOrZero: Long @@ -164,7 +197,7 @@ internal class OfflineMessageSourceImpl( // from others' quotation override val sequenceId: Int get() = delegate.origSeqs?.first() ?: error("cannot find sequenceId") override val time: Int get() = delegate.time - override val originalMessage: MessageChain by lazy { delegate.toMessageChain(bot, groupIdOrZero, false) } + override val originalMessage: MessageChain by lazy { delegate.toMessageChain(bot, groupIdOrZero) } /* override val id: Long get() = (delegate.origSeqs?.firstOrNull() diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/convension.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/convension.kt index 6d98293e1..0126697c3 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/convension.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/convension.kt @@ -42,7 +42,7 @@ internal fun MessageChain.toRichTextElems(forGroup: Boolean, withGeneralFlags: B if (this.anyIsInstance()) { when (val source = this[QuoteReply].source) { - is OfflineMessageSourceImpl -> elements.add(ImMsgBody.Elem(srcMsg = source.delegate)) + is OfflineMessageSourceImplBySourceMsg -> elements.add(ImMsgBody.Elem(srcMsg = source.delegate)) is MessageSourceToFriendImpl -> elements.add(ImMsgBody.Elem(srcMsg = source.toJceDataImplForFriend())) is MessageSourceToGroupImpl -> elements.add(ImMsgBody.Elem(srcMsg = source.toJceDataImplForGroup())) is MessageSourceFromFriendImpl -> elements.add(ImMsgBody.Elem(srcMsg = source.toJceDataImplForFriend())) @@ -179,16 +179,18 @@ private val PB_RESERVE_FOR_DOUTU = "78 00 90 01 01 F8 01 00 A0 02 00 C8 02 00".h private val PB_RESERVE_FOR_ELSE = "78 00 F8 01 00 C8 02 00".hexToBytes() @OptIn(ExperimentalUnsignedTypes::class, MiraiInternalAPI::class) -internal fun MsgComm.Msg.toMessageChain(bot: Bot, groupIdOrZero: Long, addSource: Boolean): MessageChain { +internal fun MsgComm.Msg.toMessageChain(bot: Bot, groupIdOrZero: Long, onlineSource: Boolean): MessageChain { val elements = this.msgBody.richText.elems return buildMessageChain(elements.size + 1) { - if (addSource) { + if (onlineSource) { if (groupIdOrZero != 0L) { +MessageSourceFromGroupImpl(bot, this@toMessageChain) } else { +MessageSourceFromFriendImpl(bot, this@toMessageChain) } + } else { + +OfflineMessageSourceImplByMsg(this@toMessageChain, bot) } elements.joinToMessageChain(groupIdOrZero, bot, this) }.cleanupRubbishMessageElements() @@ -197,13 +199,11 @@ internal fun MsgComm.Msg.toMessageChain(bot: Bot, groupIdOrZero: Long, addSource // These two functions have difference method signature, don't combine. @OptIn(ExperimentalUnsignedTypes::class, MiraiInternalAPI::class) -internal fun ImMsgBody.SourceMsg.toMessageChain(bot: Bot, groupIdOrZero: Long, withSource: Boolean): MessageChain { +internal fun ImMsgBody.SourceMsg.toMessageChain(bot: Bot, groupIdOrZero: Long): MessageChain { val elements = this.elems!! return buildMessageChain(elements.size + 1) { - if (withSource) { - +OfflineMessageSourceImpl(delegate = this@toMessageChain, bot = bot, groupIdOrZero = groupIdOrZero) - } + +OfflineMessageSourceImplBySourceMsg(delegate = this@toMessageChain, bot = bot, groupIdOrZero = groupIdOrZero) elements.joinToMessageChain(groupIdOrZero, bot, this) }.cleanupRubbishMessageElements() } @@ -260,7 +260,15 @@ internal fun List.joinToMessageChain(groupIdOrZero: Long, bot: B // (this._miraiContentToString()) this.forEach { when { - it.srcMsg != null -> message.add(QuoteReply(OfflineMessageSourceImpl(it.srcMsg, bot, groupIdOrZero))) + it.srcMsg != null -> message.add( + QuoteReply( + OfflineMessageSourceImplBySourceMsg( + it.srcMsg, + bot, + groupIdOrZero + ) + ) + ) it.notOnlineImage != null -> message.add(OnlineFriendImageImpl(it.notOnlineImage)) it.customFace != null -> message.add(OnlineGroupImageImpl(it.customFace)) it.face != null -> message.add(Face(it.face.index)) 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 dc0723269..37de31cd7 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 @@ -229,7 +229,7 @@ internal class MessageSvc { if (friend.lastMessageSequence.compareAndSet(instant, msg.msgHead.msgSeq)) { return@mapNotNull FriendMessage( friend, - msg.toMessageChain(bot, groupIdOrZero = 0, addSource = true) + msg.toMessageChain(bot, groupIdOrZero = 0, onlineSource = true) ) } } else return@mapNotNull null diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.kt index 6d8c205f5..430bcd127 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.kt @@ -84,7 +84,7 @@ internal class OnlinePush { return GroupMessage( senderName = pbPushMsg.msg.msgHead.groupInfo.groupCard, sender = group[pbPushMsg.msg.msgHead.fromUin], - message = pbPushMsg.msg.toMessageChain(bot, groupIdOrZero = group.id, addSource = true), + message = pbPushMsg.msg.toMessageChain(bot, groupIdOrZero = group.id, onlineSource = true), permission = when { flags and 16 != 0 -> MemberPermission.ADMINISTRATOR flags and 8 != 0 -> MemberPermission.OWNER