Do light refine after constructing MessageReceipt, fix #1371

This commit is contained in:
Him188 2021-06-29 18:05:03 +08:00
parent a4b62b0909
commit 91a9e63877
7 changed files with 83 additions and 21 deletions

View File

@ -40,7 +40,10 @@ import net.mamoe.mirai.utils.MiraiInternalApi
* @see MessageReceipt.sourceTime 源时间 * @see MessageReceipt.sourceTime 源时间
*/ */
@JvmBlockingBridge @JvmBlockingBridge
public open class MessageReceipt<out C : Contact> @MiraiInternalApi constructor( public open class MessageReceipt<out C : Contact>
@MiraiInternalApi
@Deprecated("Do not call it directly", level = DeprecationLevel.ERROR)
constructor(
/** /**
* 指代发送出去的消息. * 指代发送出去的消息.
*/ */

View File

@ -21,7 +21,10 @@ import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.MemberInfo import net.mamoe.mirai.data.MemberInfo
import net.mamoe.mirai.event.broadcast import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.* 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.OnlineMessageSourceToTempImpl
import net.mamoe.mirai.internal.message.createMessageReceipt
import net.mamoe.mirai.internal.network.protocol.packet.chat.TroopManagement import net.mamoe.mirai.internal.network.protocol.packet.chat.TroopManagement
import net.mamoe.mirai.message.MessageReceipt import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.data.Message import net.mamoe.mirai.message.data.Message
@ -61,7 +64,10 @@ internal class NormalMemberImpl constructor(
} }
private fun MessageReceipt<User>.convert(): MessageReceipt<NormalMemberImpl> { private fun MessageReceipt<User>.convert(): MessageReceipt<NormalMemberImpl> {
return MessageReceipt(OnlineMessageSourceToTempImpl(source, this@NormalMemberImpl), this@NormalMemberImpl) return OnlineMessageSourceToTempImpl(source, this@NormalMemberImpl).createMessageReceipt(
this@NormalMemberImpl,
doLightRefine = false //we've already did
)
} }

View File

@ -17,6 +17,7 @@ import net.mamoe.mirai.event.nextEventOrNull
import net.mamoe.mirai.internal.MiraiImpl import net.mamoe.mirai.internal.MiraiImpl
import net.mamoe.mirai.internal.asQQAndroidBot import net.mamoe.mirai.internal.asQQAndroidBot
import net.mamoe.mirai.internal.message.* 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.Packet
import net.mamoe.mirai.internal.network.QQAndroidClient import net.mamoe.mirai.internal.network.QQAndroidClient
import net.mamoe.mirai.internal.network.components.MessageSvcSyncer import net.mamoe.mirai.internal.network.components.MessageSvcSyncer
@ -188,7 +189,7 @@ internal abstract class SendMessageHandler<C : Contact> {
) )
} }
return MessageReceipt(sourceAwait, contact) return sourceAwait.createMessageReceipt(contact, true)
} }
} }

View File

@ -28,6 +28,7 @@ import net.mamoe.mirai.event.events.StrangerMessagePostSendEvent
import net.mamoe.mirai.event.events.StrangerMessagePreSendEvent import net.mamoe.mirai.event.events.StrangerMessagePreSendEvent
import net.mamoe.mirai.internal.QQAndroidBot import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.internal.message.OnlineMessageSourceToStrangerImpl 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.internal.network.protocol.packet.list.StrangerList
import net.mamoe.mirai.message.MessageReceipt import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.data.Message import net.mamoe.mirai.message.data.Message
@ -78,7 +79,10 @@ internal class StrangerImpl(
} }
private fun MessageReceipt<User>.convert(): MessageReceipt<StrangerImpl> { private fun MessageReceipt<User>.convert(): MessageReceipt<StrangerImpl> {
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)" override fun toString(): String = "Stranger($id)"

View File

@ -13,7 +13,9 @@ import net.mamoe.mirai.Bot
import net.mamoe.mirai.Mirai import net.mamoe.mirai.Mirai
import net.mamoe.mirai.internal.MiraiImpl import net.mamoe.mirai.internal.MiraiImpl
import net.mamoe.mirai.internal.asQQAndroidBot 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.internal.network.protocol.data.proto.MsgTransmit
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.data.* import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.utils.safeCast import net.mamoe.mirai.utils.safeCast
@ -43,10 +45,20 @@ internal data class ForwardMessageInternal(
* not null means nested and need [ForwardMessageInternal.MsgTransmits] in [RefineContext] * not null means nested and need [ForwardMessageInternal.MsgTransmits] in [RefineContext]
*/ */
val fileName: String?, val fileName: String?,
/**
* For light refine before constructing [MessageReceipt].
* See [OutgoingMessageSourceInternal] for more details.
*/
val origin: ForwardMessage? = null,
) : AbstractServiceMessage(), ) : AbstractServiceMessage(),
RefinableMessage { RefinableMessage {
override val serviceId: Int get() = 35 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 { override suspend fun refine(bot: Bot, context: MessageChain, refineContext: RefineContext): Message {
bot.asQQAndroidBot() bot.asQQAndroidBot()
@ -75,28 +87,28 @@ internal data class ForwardMessageInternal(
return MessageOrigin( return MessageOrigin(
SimpleServiceMessage(serviceId, content), SimpleServiceMessage(serviceId, content),
null, // Nested don't have resource id null, // Nested don't have resource id
MessageOriginKind.FORWARD MessageOriginKind.FORWARD,
) + ForwardMessage( ) + ForwardMessage(
preview = preview, preview = preview,
title = title, title = title,
brief = brief, brief = brief,
source = source, source = source,
summary = summary.trim(), summary = summary.trim(),
nodeList = MiraiImpl.run { transmits.toForwardMessageNodes(bot, refineContext) } nodeList = getMiraiImpl().run { transmits.toForwardMessageNodes(bot, refineContext) },
) )
} }
return MessageOrigin( return MessageOrigin(
SimpleServiceMessage(serviceId, content), SimpleServiceMessage(serviceId, content),
resId, resId,
MessageOriginKind.FORWARD MessageOriginKind.FORWARD,
) + ForwardMessage( ) + ForwardMessage(
preview = preview, preview = preview,
title = title, title = title,
brief = brief, brief = brief,
source = source, source = source,
summary = summary.trim(), summary = summary.trim(),
nodeList = Mirai.downloadForwardMessage(bot, resId!!) nodeList = Mirai.downloadForwardMessage(bot, resId!!),
) )
} }
@ -178,5 +190,5 @@ internal fun RichMessage.Key.forwardMessage(
<source name="${source.take(50)}" icon="" action="" appid="-1"/> <source name="${source.take(50)}" icon="" action="" appid="-1"/>
</msg> </msg>
""".trimIndent().replace("\n", " ").trim() """.trimIndent().replace("\n", " ").trim()
return ForwardMessageInternal(template, resId, null) return ForwardMessageInternal(template, resId, null, forwardMessage)
} }

View File

@ -10,14 +10,19 @@
package net.mamoe.mirai.internal.message package net.mamoe.mirai.internal.message
import kotlinx.serialization.Transient 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.internal.network.protocol.data.proto.ImMsgBody
import net.mamoe.mirai.message.data.Message import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.data.MessageChain import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.message.data.MessageSource import net.mamoe.mirai.utils.cast
import net.mamoe.mirai.message.data.sourceOrNull
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
/**
* All [MessageSource] should implement this interface.
*/
internal interface MessageSourceInternal { internal interface MessageSourceInternal {
@Transient @Transient
val sequenceIds: IntArray // ids val sequenceIds: IntArray // ids
@ -35,6 +40,37 @@ internal interface MessageSourceInternal {
fun toJceData(): ImMsgBody.SourceMsg 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 <C : Contact> OnlineMessageSource.Outgoing.createMessageReceipt(
target: C,
doLightRefine: Boolean,
): MessageReceipt<C> {
if (doLightRefine) {
check(this is OutgoingMessageSourceInternal) { "Internal error: source !is OutgoingMessageSourceInternal" }
this.originalMessage = this.originalMessage.refineLight(bot)
}
return MessageReceipt(this, target)
}
@Suppress("RedundantSuspendModifier", "unused") @Suppress("RedundantSuspendModifier", "unused")
internal suspend fun MessageSource.ensureSequenceIdAvailable() { internal suspend fun MessageSource.ensureSequenceIdAvailable() {
if (this is OnlineMessageSourceToGroupImpl) { if (this is OnlineMessageSourceToGroupImpl) {

View File

@ -79,10 +79,10 @@ internal class OnlineMessageSourceToFriendImpl(
override val sequenceIds: IntArray, override val sequenceIds: IntArray,
override val internalIds: IntArray, override val internalIds: IntArray,
override val time: Int, override val time: Int,
override val originalMessage: MessageChain, override var originalMessage: MessageChain,
override val sender: Bot, override val sender: Bot,
override val target: Friend, override val target: Friend,
) : OnlineMessageSource.Outgoing.ToFriend(), MessageSourceInternal { ) : OnlineMessageSource.Outgoing.ToFriend(), MessageSourceInternal, OutgoingMessageSourceInternal {
object Serializer : MessageSourceSerializerImpl("OnlineMessageSourceToFriend") object Serializer : MessageSourceSerializerImpl("OnlineMessageSourceToFriend")
override val bot: Bot override val bot: Bot
@ -99,10 +99,10 @@ internal class OnlineMessageSourceToStrangerImpl(
override val sequenceIds: IntArray, override val sequenceIds: IntArray,
override val internalIds: IntArray, override val internalIds: IntArray,
override val time: Int, override val time: Int,
override val originalMessage: MessageChain, override var originalMessage: MessageChain,
override val sender: Bot, override val sender: Bot,
override val target: Stranger, override val target: Stranger,
) : OnlineMessageSource.Outgoing.ToStranger(), MessageSourceInternal { ) : OnlineMessageSource.Outgoing.ToStranger(), MessageSourceInternal, OutgoingMessageSourceInternal {
constructor( constructor(
delegate: Outgoing, delegate: Outgoing,
@ -125,10 +125,10 @@ internal class OnlineMessageSourceToTempImpl(
override val sequenceIds: IntArray, override val sequenceIds: IntArray,
override val internalIds: IntArray, override val internalIds: IntArray,
override val time: Int, override val time: Int,
override val originalMessage: MessageChain, override var originalMessage: MessageChain,
override val sender: Bot, override val sender: Bot,
override val target: Member, override val target: Member,
) : OnlineMessageSource.Outgoing.ToTemp(), MessageSourceInternal { ) : OnlineMessageSource.Outgoing.ToTemp(), MessageSourceInternal, OutgoingMessageSourceInternal {
constructor( constructor(
delegate: Outgoing, delegate: Outgoing,
target: Member, target: Member,
@ -150,11 +150,11 @@ internal class OnlineMessageSourceToGroupImpl(
coroutineScope: CoroutineScope, coroutineScope: CoroutineScope,
override val internalIds: IntArray, // aka random override val internalIds: IntArray, // aka random
override val time: Int, override val time: Int,
override val originalMessage: MessageChain, override var originalMessage: MessageChain,
override val sender: Bot, override val sender: Bot,
override val target: Group, override val target: Group,
providedSequenceIds: IntArray? = null, providedSequenceIds: IntArray? = null,
) : OnlineMessageSource.Outgoing.ToGroup(), MessageSourceInternal { ) : OnlineMessageSource.Outgoing.ToGroup(), MessageSourceInternal, OutgoingMessageSourceInternal {
object Serializer : MessageSourceSerializerImpl("OnlineMessageSourceToGroup") object Serializer : MessageSourceSerializerImpl("OnlineMessageSourceToGroup")
override val ids: IntArray override val ids: IntArray