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 源时间
*/
@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.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<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.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<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.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<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)"

View File

@ -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(
<source name="${source.take(50)}" icon="" action="" appid="-1"/>
</msg>
""".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
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 <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")
internal suspend fun MessageSource.ensureSequenceIdAvailable() {
if (this is OnlineMessageSourceToGroupImpl) {

View File

@ -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