diff --git a/mirai-core-api/src/commonMain/kotlin/message/MessageReceipt.kt b/mirai-core-api/src/commonMain/kotlin/message/MessageReceipt.kt index 626aa3ee1..d7ac48b33 100644 --- a/mirai-core-api/src/commonMain/kotlin/message/MessageReceipt.kt +++ b/mirai-core-api/src/commonMain/kotlin/message/MessageReceipt.kt @@ -40,7 +40,10 @@ import net.mamoe.mirai.utils.MiraiInternalApi * @see MessageReceipt.sourceTime 源时间 */ @JvmBlockingBridge -public open class MessageReceipt @MiraiInternalApi constructor( +public open class MessageReceipt +@MiraiInternalApi +@Deprecated("Do not call it directly", level = DeprecationLevel.ERROR) +constructor( /** * 指代发送出去的消息. */ diff --git a/mirai-core/src/commonMain/kotlin/contact/NormalMemberImpl.kt b/mirai-core/src/commonMain/kotlin/contact/NormalMemberImpl.kt index f2742eb17..e1e926055 100644 --- a/mirai-core/src/commonMain/kotlin/contact/NormalMemberImpl.kt +++ b/mirai-core/src/commonMain/kotlin/contact/NormalMemberImpl.kt @@ -21,7 +21,10 @@ import net.mamoe.mirai.contact.* import net.mamoe.mirai.data.MemberInfo import net.mamoe.mirai.event.broadcast import net.mamoe.mirai.event.events.* +import net.mamoe.mirai.internal.message.OnlineMessageSourceToGroupImpl +import net.mamoe.mirai.internal.message.OnlineMessageSourceToStrangerImpl import net.mamoe.mirai.internal.message.OnlineMessageSourceToTempImpl +import net.mamoe.mirai.internal.message.createMessageReceipt import net.mamoe.mirai.internal.network.protocol.packet.chat.TroopManagement import net.mamoe.mirai.message.MessageReceipt import net.mamoe.mirai.message.data.Message @@ -61,7 +64,10 @@ internal class NormalMemberImpl constructor( } private fun MessageReceipt.convert(): MessageReceipt { - return MessageReceipt(OnlineMessageSourceToTempImpl(source, this@NormalMemberImpl), this@NormalMemberImpl) + return OnlineMessageSourceToTempImpl(source, this@NormalMemberImpl).createMessageReceipt( + this@NormalMemberImpl, + doLightRefine = false //we've already did + ) } diff --git a/mirai-core/src/commonMain/kotlin/contact/SendMessageHandler.kt b/mirai-core/src/commonMain/kotlin/contact/SendMessageHandler.kt index 5cfb40ecc..34d581857 100644 --- a/mirai-core/src/commonMain/kotlin/contact/SendMessageHandler.kt +++ b/mirai-core/src/commonMain/kotlin/contact/SendMessageHandler.kt @@ -17,6 +17,7 @@ import net.mamoe.mirai.event.nextEventOrNull import net.mamoe.mirai.internal.MiraiImpl import net.mamoe.mirai.internal.asQQAndroidBot import net.mamoe.mirai.internal.message.* +import net.mamoe.mirai.internal.message.LightMessageRefiner.refineLight import net.mamoe.mirai.internal.network.Packet import net.mamoe.mirai.internal.network.QQAndroidClient import net.mamoe.mirai.internal.network.components.MessageSvcSyncer @@ -188,7 +189,7 @@ internal abstract class SendMessageHandler { ) } - return MessageReceipt(sourceAwait, contact) + return sourceAwait.createMessageReceipt(contact, true) } } diff --git a/mirai-core/src/commonMain/kotlin/contact/StrangerImpl.kt b/mirai-core/src/commonMain/kotlin/contact/StrangerImpl.kt index 3c14f304f..6600d8b56 100644 --- a/mirai-core/src/commonMain/kotlin/contact/StrangerImpl.kt +++ b/mirai-core/src/commonMain/kotlin/contact/StrangerImpl.kt @@ -28,6 +28,7 @@ import net.mamoe.mirai.event.events.StrangerMessagePostSendEvent import net.mamoe.mirai.event.events.StrangerMessagePreSendEvent import net.mamoe.mirai.internal.QQAndroidBot import net.mamoe.mirai.internal.message.OnlineMessageSourceToStrangerImpl +import net.mamoe.mirai.internal.message.createMessageReceipt import net.mamoe.mirai.internal.network.protocol.packet.list.StrangerList import net.mamoe.mirai.message.MessageReceipt import net.mamoe.mirai.message.data.Message @@ -78,7 +79,10 @@ internal class StrangerImpl( } private fun MessageReceipt.convert(): MessageReceipt { - return MessageReceipt(OnlineMessageSourceToStrangerImpl(source, this@StrangerImpl), this@StrangerImpl) + return OnlineMessageSourceToStrangerImpl(source, this@StrangerImpl).createMessageReceipt( + this@StrangerImpl, + doLightRefine = false //we've already did + ) } override fun toString(): String = "Stranger($id)" diff --git a/mirai-core/src/commonMain/kotlin/message/LongMessageInternal.kt b/mirai-core/src/commonMain/kotlin/message/LongMessageInternal.kt index 54c9fe5e9..1ca40bce2 100644 --- a/mirai-core/src/commonMain/kotlin/message/LongMessageInternal.kt +++ b/mirai-core/src/commonMain/kotlin/message/LongMessageInternal.kt @@ -13,7 +13,9 @@ import net.mamoe.mirai.Bot import net.mamoe.mirai.Mirai import net.mamoe.mirai.internal.MiraiImpl import net.mamoe.mirai.internal.asQQAndroidBot +import net.mamoe.mirai.internal.getMiraiImpl import net.mamoe.mirai.internal.network.protocol.data.proto.MsgTransmit +import net.mamoe.mirai.message.MessageReceipt import net.mamoe.mirai.message.data.* import net.mamoe.mirai.utils.safeCast @@ -43,10 +45,20 @@ internal data class ForwardMessageInternal( * not null means nested and need [ForwardMessageInternal.MsgTransmits] in [RefineContext] */ val fileName: String?, + + /** + * For light refine before constructing [MessageReceipt]. + * See [OutgoingMessageSourceInternal] for more details. + */ + val origin: ForwardMessage? = null, ) : AbstractServiceMessage(), RefinableMessage { override val serviceId: Int get() = 35 + override fun tryRefine(bot: Bot, context: MessageChain, refineContext: RefineContext): Message { + return origin ?: this + } + override suspend fun refine(bot: Bot, context: MessageChain, refineContext: RefineContext): Message { bot.asQQAndroidBot() @@ -75,28 +87,28 @@ internal data class ForwardMessageInternal( return MessageOrigin( SimpleServiceMessage(serviceId, content), null, // Nested don't have resource id - MessageOriginKind.FORWARD + MessageOriginKind.FORWARD, ) + ForwardMessage( preview = preview, title = title, brief = brief, source = source, summary = summary.trim(), - nodeList = MiraiImpl.run { transmits.toForwardMessageNodes(bot, refineContext) } + nodeList = getMiraiImpl().run { transmits.toForwardMessageNodes(bot, refineContext) }, ) } return MessageOrigin( SimpleServiceMessage(serviceId, content), resId, - MessageOriginKind.FORWARD + MessageOriginKind.FORWARD, ) + ForwardMessage( preview = preview, title = title, brief = brief, source = source, summary = summary.trim(), - nodeList = Mirai.downloadForwardMessage(bot, resId!!) + nodeList = Mirai.downloadForwardMessage(bot, resId!!), ) } @@ -178,5 +190,5 @@ internal fun RichMessage.Key.forwardMessage( """.trimIndent().replace("\n", " ").trim() - return ForwardMessageInternal(template, resId, null) + return ForwardMessageInternal(template, resId, null, forwardMessage) } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/message/MessageSourceInternal.kt b/mirai-core/src/commonMain/kotlin/message/MessageSourceInternal.kt index c7edd6b64..c74bbd46f 100644 --- a/mirai-core/src/commonMain/kotlin/message/MessageSourceInternal.kt +++ b/mirai-core/src/commonMain/kotlin/message/MessageSourceInternal.kt @@ -10,14 +10,19 @@ package net.mamoe.mirai.internal.message import kotlinx.serialization.Transient +import net.mamoe.mirai.contact.Contact +import net.mamoe.mirai.internal.contact.SendMessageHandler +import net.mamoe.mirai.internal.message.LightMessageRefiner.refineLight import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody -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.message.data.sourceOrNull +import net.mamoe.mirai.message.MessageReceipt +import net.mamoe.mirai.message.data.* +import net.mamoe.mirai.utils.cast import java.util.concurrent.atomic.AtomicBoolean +/** + * All [MessageSource] should implement this interface. + */ internal interface MessageSourceInternal { @Transient val sequenceIds: IntArray // ids @@ -35,6 +40,37 @@ internal interface MessageSourceInternal { fun toJceData(): ImMsgBody.SourceMsg } +/** + * All [OnlineMessageSource.Outgoing] should implement this interface. + */ +internal interface OutgoingMessageSourceInternal : MessageSourceInternal { + + // #1371: + // 问题是 `build` 得到的 `ForwardMessage` 会在 `transformSpecialMessages` + // 时上传并变成 `ForwardMessageInternal` 再传递给 factory 发送, 并以这个 internal 结果构造了 receipt. + + // 于是构造 receipt 后会进行 light refine 并更新这个属性. + + /** + * This 'overrides' [MessageSource.originalMessage]. + * + * @see SendMessageHandler.sendMessagePacket + */ + var originalMessage: MessageChain +} + +@Suppress("DEPRECATION_ERROR") +internal fun OnlineMessageSource.Outgoing.createMessageReceipt( + target: C, + doLightRefine: Boolean, +): MessageReceipt { + if (doLightRefine) { + check(this is OutgoingMessageSourceInternal) { "Internal error: source !is OutgoingMessageSourceInternal" } + this.originalMessage = this.originalMessage.refineLight(bot) + } + return MessageReceipt(this, target) +} + @Suppress("RedundantSuspendModifier", "unused") internal suspend fun MessageSource.ensureSequenceIdAvailable() { if (this is OnlineMessageSourceToGroupImpl) { diff --git a/mirai-core/src/commonMain/kotlin/message/outgoingSourceImpl.kt b/mirai-core/src/commonMain/kotlin/message/outgoingSourceImpl.kt index c09f2b1b9..6dc13b627 100644 --- a/mirai-core/src/commonMain/kotlin/message/outgoingSourceImpl.kt +++ b/mirai-core/src/commonMain/kotlin/message/outgoingSourceImpl.kt @@ -79,10 +79,10 @@ internal class OnlineMessageSourceToFriendImpl( override val sequenceIds: IntArray, override val internalIds: IntArray, override val time: Int, - override val originalMessage: MessageChain, + override var originalMessage: MessageChain, override val sender: Bot, override val target: Friend, -) : OnlineMessageSource.Outgoing.ToFriend(), MessageSourceInternal { +) : OnlineMessageSource.Outgoing.ToFriend(), MessageSourceInternal, OutgoingMessageSourceInternal { object Serializer : MessageSourceSerializerImpl("OnlineMessageSourceToFriend") override val bot: Bot @@ -99,10 +99,10 @@ internal class OnlineMessageSourceToStrangerImpl( override val sequenceIds: IntArray, override val internalIds: IntArray, override val time: Int, - override val originalMessage: MessageChain, + override var originalMessage: MessageChain, override val sender: Bot, override val target: Stranger, -) : OnlineMessageSource.Outgoing.ToStranger(), MessageSourceInternal { +) : OnlineMessageSource.Outgoing.ToStranger(), MessageSourceInternal, OutgoingMessageSourceInternal { constructor( delegate: Outgoing, @@ -125,10 +125,10 @@ internal class OnlineMessageSourceToTempImpl( override val sequenceIds: IntArray, override val internalIds: IntArray, override val time: Int, - override val originalMessage: MessageChain, + override var originalMessage: MessageChain, override val sender: Bot, override val target: Member, -) : OnlineMessageSource.Outgoing.ToTemp(), MessageSourceInternal { +) : OnlineMessageSource.Outgoing.ToTemp(), MessageSourceInternal, OutgoingMessageSourceInternal { constructor( delegate: Outgoing, target: Member, @@ -150,11 +150,11 @@ internal class OnlineMessageSourceToGroupImpl( coroutineScope: CoroutineScope, override val internalIds: IntArray, // aka random override val time: Int, - override val originalMessage: MessageChain, + override var originalMessage: MessageChain, override val sender: Bot, override val target: Group, providedSequenceIds: IntArray? = null, -) : OnlineMessageSource.Outgoing.ToGroup(), MessageSourceInternal { +) : OnlineMessageSource.Outgoing.ToGroup(), MessageSourceInternal, OutgoingMessageSourceInternal { object Serializer : MessageSourceSerializerImpl("OnlineMessageSourceToGroup") override val ids: IntArray