From 7e8737693010f55b2ee1901668be3c8544a5fab9 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 30 Apr 2022 17:44:38 +0100 Subject: [PATCH] Move toMessageChain and toRichTextElems to MessageProtocolFacade --- .../kotlin/contact/SendMessageHandler.kt | 2 +- .../kotlin/message/ReceiveMessageHandler.kt | 17 +-- .../kotlin/message/data/MultiMsgUploader.kt | 10 +- .../kotlin/message/messageToElems.kt | 31 ------ .../protocol/MessageDecoderPipelineImpl.kt | 19 ++-- .../protocol/MessageEncoderPipeline.kt | 3 + .../protocol/MessageEncoderPipelineImpl.kt | 15 +-- .../message/protocol/MessageProtocolFacade.kt | 100 ++++++++++++++++-- .../message/source/offlineSourceImpl.kt | 6 +- .../message/source/outgoingSourceImpl.kt | 6 +- .../kotlin/network/protocol/data/proto/Msg.kt | 6 +- .../network/protocol/packet/chat/MultiMsg.kt | 14 +-- .../chat/receive/MessageSvc.PbSendMsg.kt | 22 +++- .../kotlin/pipeline/ProcessorPipeline.kt | 14 ++- .../kotlin/utils/contentToString.kt | 10 ++ 15 files changed, 174 insertions(+), 101 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/contact/SendMessageHandler.kt b/mirai-core/src/commonMain/kotlin/contact/SendMessageHandler.kt index a1d93448f..c0c753c3c 100644 --- a/mirai-core/src/commonMain/kotlin/contact/SendMessageHandler.kt +++ b/mirai-core/src/commonMain/kotlin/contact/SendMessageHandler.kt @@ -298,7 +298,7 @@ internal abstract class SendMessageHandler { /** * 处理需要 `suspend` 操作的消息转换. 这个转换只会在发送消息时进行, 而不会在处理合并转发 [net.mamoe.mirai.internal.network.protocol.packet.chat.calculateValidationData] 等其他操作时进行. - * 在发包前还会进行最后的 [net.mamoe.mirai.internal.message.toRichTextElems] 转换, 这个转换会为所有操作使用. + * 在发包前还会进行最后的 [net.mamoe.mirai.internal.message.protocol.MessageProtocolFacade.encode] 转换, 这个转换会为所有操作使用. * * - [ForwardMessage] -> [ForwardMessageInternal] (by uploading through highway) * - ... any others for future diff --git a/mirai-core/src/commonMain/kotlin/message/ReceiveMessageHandler.kt b/mirai-core/src/commonMain/kotlin/message/ReceiveMessageHandler.kt index 5c4ac4064..669d15c43 100644 --- a/mirai-core/src/commonMain/kotlin/message/ReceiveMessageHandler.kt +++ b/mirai-core/src/commonMain/kotlin/message/ReceiveMessageHandler.kt @@ -17,18 +17,13 @@ import net.mamoe.mirai.internal.message.ReceiveMessageTransformer.joinToMessageC import net.mamoe.mirai.internal.message.ReceiveMessageTransformer.toAudio import net.mamoe.mirai.internal.message.data.LongMessageInternal import net.mamoe.mirai.internal.message.data.OnlineAudioImpl -import net.mamoe.mirai.internal.message.protocol.MessageDecoderContext.Companion.BOT -import net.mamoe.mirai.internal.message.protocol.MessageDecoderContext.Companion.GROUP_ID -import net.mamoe.mirai.internal.message.protocol.MessageDecoderContext.Companion.MESSAGE_SOURCE_KIND import net.mamoe.mirai.internal.message.protocol.MessageProtocolFacade import net.mamoe.mirai.internal.message.protocol.impl.PokeMessageProtocol.Companion.UNSUPPORTED_POKE_MESSAGE_PLAIN import net.mamoe.mirai.internal.message.protocol.impl.RichMessageProtocol.Companion.UNSUPPORTED_MERGED_MESSAGE_PLAIN import net.mamoe.mirai.internal.message.source.* import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm -import net.mamoe.mirai.internal.utils.runCoroutineInPlace import net.mamoe.mirai.message.data.* -import net.mamoe.mirai.utils.buildTypeSafeMap import net.mamoe.mirai.utils.toLongUnsigned /** @@ -155,17 +150,7 @@ internal object ReceiveMessageTransformer { bot: Bot, builder: MessageChainBuilder, ) { - val pipeline = MessageProtocolFacade.decoderPipeline - - val attributes = buildTypeSafeMap { - set(BOT, bot) - set(MESSAGE_SOURCE_KIND, messageSourceKind) - set(GROUP_ID, groupIdOrZero) - } - - runCoroutineInPlace { - elements.forEach { builder.addAll(pipeline.process(it, attributes)) } - } + return MessageProtocolFacade.decode(elements, groupIdOrZero, messageSourceKind, bot, builder) } fun MessageChainBuilder.compressContinuousPlainText() { diff --git a/mirai-core/src/commonMain/kotlin/message/data/MultiMsgUploader.kt b/mirai-core/src/commonMain/kotlin/message/data/MultiMsgUploader.kt index 62ade5d5d..c0ebd538a 100644 --- a/mirai-core/src/commonMain/kotlin/message/data/MultiMsgUploader.kt +++ b/mirai-core/src/commonMain/kotlin/message/data/MultiMsgUploader.kt @@ -12,8 +12,8 @@ package net.mamoe.mirai.internal.message.data import io.ktor.utils.io.core.* import net.mamoe.mirai.internal.contact.SendMessageHandler import net.mamoe.mirai.internal.contact.takeSingleContent +import net.mamoe.mirai.internal.message.protocol.MessageProtocolFacade import net.mamoe.mirai.internal.message.source.MessageSourceInternal -import net.mamoe.mirai.internal.message.toRichTextElems import net.mamoe.mirai.internal.network.QQAndroidClient import net.mamoe.mirai.internal.network.highway.Highway import net.mamoe.mirai.internal.network.highway.ResourceKind @@ -164,11 +164,11 @@ internal open class MultiMsgUploader( ), msgBody = ImMsgBody.MsgBody( richText = ImMsgBody.RichText( - elems = msgChain.toRichTextElems( - handler.contact, + elems = MessageProtocolFacade.encode( + msgChain, messageTarget = handler.contact, withGeneralFlags = false, - isForward = true, - ).toMutableList() + isForward = true + ) ) ) ) diff --git a/mirai-core/src/commonMain/kotlin/message/messageToElems.kt b/mirai-core/src/commonMain/kotlin/message/messageToElems.kt index 3b8392d3b..085488175 100644 --- a/mirai-core/src/commonMain/kotlin/message/messageToElems.kt +++ b/mirai-core/src/commonMain/kotlin/message/messageToElems.kt @@ -9,39 +9,8 @@ package net.mamoe.mirai.internal.message -import net.mamoe.mirai.contact.ContactOrBot -import net.mamoe.mirai.internal.message.protocol.MessageEncoderContext -import net.mamoe.mirai.internal.message.protocol.MessageProtocolFacade -import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody -import net.mamoe.mirai.internal.utils.runCoroutineInPlace -import net.mamoe.mirai.message.data.MessageChain import net.mamoe.mirai.message.data.PlainText -import net.mamoe.mirai.utils.buildTypeSafeMap internal val UNSUPPORTED_VOICE_MESSAGE_PLAIN = PlainText("收到语音消息,你需要升级到最新版QQ才能接收,升级地址https://im.qq.com") -@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") -internal fun MessageChain.toRichTextElems( - messageTarget: ContactOrBot?, - withGeneralFlags: Boolean, - isForward: Boolean = false, -): MutableList { - val originalMessage = this - val pipeline = MessageProtocolFacade.encoderPipeline - - val attributes = buildTypeSafeMap { - set(MessageEncoderContext.CONTACT, messageTarget) - set(MessageEncoderContext.ORIGINAL_MESSAGE, originalMessage) - set(MessageEncoderContext.ADD_GENERAL_FLAGS, withGeneralFlags) - set(MessageEncoderContext.IS_FORWARD, isForward) - } - - val builder = ArrayList(originalMessage.size) - - runCoroutineInPlace { - originalMessage.forEach { builder.addAll(pipeline.process(it, attributes)) } - } - - return builder -} diff --git a/mirai-core/src/commonMain/kotlin/message/protocol/MessageDecoderPipelineImpl.kt b/mirai-core/src/commonMain/kotlin/message/protocol/MessageDecoderPipelineImpl.kt index f096a06e9..bc206dd38 100644 --- a/mirai-core/src/commonMain/kotlin/message/protocol/MessageDecoderPipelineImpl.kt +++ b/mirai-core/src/commonMain/kotlin/message/protocol/MessageDecoderPipelineImpl.kt @@ -13,20 +13,13 @@ import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody import net.mamoe.mirai.internal.pipeline.AbstractProcessorPipeline import net.mamoe.mirai.internal.pipeline.PipelineConfiguration import net.mamoe.mirai.message.data.Message -import net.mamoe.mirai.utils.MiraiLogger -import net.mamoe.mirai.utils.TypeSafeMap -import net.mamoe.mirai.utils.systemProp -import net.mamoe.mirai.utils.withSwitch - -private val defaultTraceLogging: MiraiLogger by lazy { - MiraiLogger.Factory.create(MessageDecoderPipelineImpl::class, "MessageDecoderPipeline") - .withSwitch(systemProp("mirai.message.decoder.pipeline.log.full", false)) -} +import net.mamoe.mirai.utils.* internal open class MessageDecoderPipelineImpl : AbstractProcessorPipeline( PipelineConfiguration(stopWhenConsumed = true), + @OptIn(TestOnly::class) defaultTraceLogging ), MessageDecoderPipeline { @@ -34,4 +27,12 @@ internal open class MessageDecoderPipelineImpl : inner class MessageDecoderContextImpl(attributes: TypeSafeMap) : MessageDecoderContext, BaseContextImpl(attributes) override fun createContext(attributes: TypeSafeMap): MessageDecoderContext = MessageDecoderContextImpl(attributes) + + companion object { + @TestOnly + val defaultTraceLogging: MiraiLoggerWithSwitch by lazy { + MiraiLogger.Factory.create(MessageDecoderPipelineImpl::class, "MessageDecoderPipeline") + .withSwitch(systemProp("mirai.message.decoder.pipeline.log.full", false)) + } + } } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/message/protocol/MessageEncoderPipeline.kt b/mirai-core/src/commonMain/kotlin/message/protocol/MessageEncoderPipeline.kt index cef36070e..5b975297f 100644 --- a/mirai-core/src/commonMain/kotlin/message/protocol/MessageEncoderPipeline.kt +++ b/mirai-core/src/commonMain/kotlin/message/protocol/MessageEncoderPipeline.kt @@ -19,12 +19,14 @@ import net.mamoe.mirai.message.data.MessageChain import net.mamoe.mirai.message.data.SingleMessage import net.mamoe.mirai.utils.TypeKey import net.mamoe.mirai.utils.uncheckedCast +import kotlin.coroutines.RestrictsSuspension import kotlin.reflect.KClass internal interface MessageEncoderPipeline : ProcessorPipeline, SingleMessage, ImMsgBody.Elem> { } +@RestrictsSuspension internal interface MessageEncoderContext : ProcessorPipelineContext { /** @@ -72,6 +74,7 @@ internal class MessageEncoderProcessor( ) : Processor { override suspend fun process(context: MessageEncoderContext, data: SingleMessage) { if (elementType.isInstance(data)) { + @Suppress("ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL") encoder.run { context.process(data.uncheckedCast()) } // TODO: 2022/4/27 handle exceptions } diff --git a/mirai-core/src/commonMain/kotlin/message/protocol/MessageEncoderPipelineImpl.kt b/mirai-core/src/commonMain/kotlin/message/protocol/MessageEncoderPipelineImpl.kt index 19f97a3f4..bbf24555e 100644 --- a/mirai-core/src/commonMain/kotlin/message/protocol/MessageEncoderPipelineImpl.kt +++ b/mirai-core/src/commonMain/kotlin/message/protocol/MessageEncoderPipelineImpl.kt @@ -15,19 +15,16 @@ import net.mamoe.mirai.internal.pipeline.PipelineConfiguration import net.mamoe.mirai.message.data.SingleMessage import net.mamoe.mirai.utils.* -private val defaultTraceLogging: MiraiLogger by lazy { - MiraiLogger.Factory.create(MessageEncoderPipelineImpl::class, "MessageEncoderPipeline") - .withSwitch(systemProp("mirai.message.encoder.pipeline.log.full", false)) -} internal open class MessageEncoderPipelineImpl : AbstractProcessorPipeline, MessageEncoderContext, SingleMessage, ImMsgBody.Elem>( PipelineConfiguration(stopWhenConsumed = true), + @OptIn(TestOnly::class) defaultTraceLogging ), MessageEncoderPipeline { - inner class MessageEncoderContextImpl(attributes: TypeSafeMap) : MessageEncoderContext, + private inner class MessageEncoderContextImpl(attributes: TypeSafeMap) : MessageEncoderContext, BaseContextImpl(attributes) { override var generalFlags: ImMsgBody.Elem by lateinitMutableProperty { ImMsgBody.Elem(generalFlags = ImMsgBody.GeneralFlags(pbReserve = PB_RESERVE_FOR_ELSE)) @@ -36,7 +33,13 @@ internal open class MessageEncoderPipelineImpl : override fun createContext(attributes: TypeSafeMap): MessageEncoderContext = MessageEncoderContextImpl(attributes) - private companion object { + companion object { private val PB_RESERVE_FOR_ELSE = "78 00 F8 01 00 C8 02 00".hexToBytes() + + @TestOnly + val defaultTraceLogging: MiraiLoggerWithSwitch by lazy { + MiraiLogger.Factory.create(MessageEncoderPipelineImpl::class, "MessageEncoderPipeline") + .withSwitch(systemProp("mirai.message.encoder.pipeline.log.full", false)) + } } } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/message/protocol/MessageProtocolFacade.kt b/mirai-core/src/commonMain/kotlin/message/protocol/MessageProtocolFacade.kt index 678f7cf2c..c51f50f8e 100644 --- a/mirai-core/src/commonMain/kotlin/message/protocol/MessageProtocolFacade.kt +++ b/mirai-core/src/commonMain/kotlin/message/protocol/MessageProtocolFacade.kt @@ -9,7 +9,14 @@ package net.mamoe.mirai.internal.message.protocol -import net.mamoe.mirai.message.data.SingleMessage +import net.mamoe.mirai.Bot +import net.mamoe.mirai.contact.ContactOrBot +import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody +import net.mamoe.mirai.internal.utils.runCoroutineInPlace +import net.mamoe.mirai.message.data.* +import net.mamoe.mirai.message.data.visitor.RecursiveMessageVisitor +import net.mamoe.mirai.message.data.visitor.accept +import net.mamoe.mirai.utils.buildTypeSafeMap import java.util.* import kotlin.reflect.KClass @@ -18,32 +25,105 @@ internal interface MessageProtocolFacade { val decoderPipeline: MessageDecoderPipeline val loaded: List + fun encode( + chain: MessageChain, + messageTarget: ContactOrBot?, // for At.display, QuoteReply, Image, and more. + withGeneralFlags: Boolean, // important for RichMessages, may also be helpful for others + isForward: Boolean = false, // is inside forward, for At.display + ): List + + fun decode( + elements: List, + groupIdOrZero: Long, + messageSourceKind: MessageSourceKind, + bot: Bot, + builder: MessageChainBuilder, + ) + + fun decode( + elements: List, + groupIdOrZero: Long, + messageSourceKind: MessageSourceKind, + bot: Bot, + ): MessageChain = buildMessageChain { decode(elements, groupIdOrZero, messageSourceKind, bot, this) } + companion object INSTANCE : MessageProtocolFacade by MessageProtocolFacadeImpl() } -internal class MessageProtocolFacadeImpl : MessageProtocolFacade { +internal class MessageProtocolFacadeImpl( + protocols: Iterable = ServiceLoader.load(MessageProtocol::class.java) +) : MessageProtocolFacade { override val encoderPipeline: MessageEncoderPipeline = MessageEncoderPipelineImpl() override val decoderPipeline: MessageDecoderPipeline = MessageDecoderPipelineImpl() - override val loaded: List = initialize() - - private fun initialize(): List { - val instances = ServiceLoader.load(MessageProtocol::class.java).iterator().asSequence() + override val loaded: List = kotlin.run { + val instances: PriorityQueue = protocols .toCollection(PriorityQueue(MessageProtocol.PriorityComparator.reversed())) - for (instance in instances) { instance.collectProcessors(object : ProcessorCollector() { override fun add(encoder: MessageEncoder, elementType: KClass) { - encoderPipeline.registerProcessor(MessageEncoderProcessor(encoder, elementType)) + this@MessageProtocolFacadeImpl.encoderPipeline.registerProcessor( + MessageEncoderProcessor( + encoder, + elementType + ) + ) } override fun add(decoder: MessageDecoder) { - decoderPipeline.registerProcessor(MessageDecoderProcessor(decoder)) + this@MessageProtocolFacadeImpl.decoderPipeline.registerProcessor(MessageDecoderProcessor(decoder)) } }) } + instances.toList() + } - return instances.toList() + override fun encode( + chain: MessageChain, + messageTarget: ContactOrBot?, + withGeneralFlags: Boolean, + isForward: Boolean + ): List { + val pipeline = encoderPipeline + + val attributes = buildTypeSafeMap { + set(MessageEncoderContext.CONTACT, messageTarget) + set(MessageEncoderContext.ORIGINAL_MESSAGE, chain) + set(MessageEncoderContext.ADD_GENERAL_FLAGS, withGeneralFlags) + set(MessageEncoderContext.IS_FORWARD, isForward) + } + + val builder = ArrayList(chain.size) + + chain.accept(object : RecursiveMessageVisitor() { + override fun visitSingleMessage(message: SingleMessage, data: Unit) { + runCoroutineInPlace { + builder.addAll(pipeline.process(message, attributes)) + } + } + }) + + return builder + } + + override fun decode( + elements: List, + groupIdOrZero: Long, + messageSourceKind: MessageSourceKind, + bot: Bot, + builder: MessageChainBuilder + ) { + val pipeline = decoderPipeline + + val attributes = buildTypeSafeMap { + set(MessageDecoderContext.BOT, bot) + set(MessageDecoderContext.MESSAGE_SOURCE_KIND, messageSourceKind) + set(MessageDecoderContext.GROUP_ID, groupIdOrZero) + } + + runCoroutineInPlace { + elements.forEach { builder.addAll(pipeline.process(it, attributes)) } + } } } diff --git a/mirai-core/src/commonMain/kotlin/message/source/offlineSourceImpl.kt b/mirai-core/src/commonMain/kotlin/message/source/offlineSourceImpl.kt index ce8f9e2b3..3d7129d80 100644 --- a/mirai-core/src/commonMain/kotlin/message/source/offlineSourceImpl.kt +++ b/mirai-core/src/commonMain/kotlin/message/source/offlineSourceImpl.kt @@ -14,8 +14,8 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.Transient import net.mamoe.mirai.Bot import net.mamoe.mirai.internal.message.MessageSourceSerializerImpl +import net.mamoe.mirai.internal.message.protocol.MessageProtocolFacade import net.mamoe.mirai.internal.message.toMessageChainNoSource -import net.mamoe.mirai.internal.message.toRichTextElems import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm import net.mamoe.mirai.internal.network.protocol.data.proto.SourceMsg @@ -64,8 +64,8 @@ internal class OfflineMessageSourceImplData( senderUin = fromId, toUin = 0, flag = 1, - elems = originElems ?: originalMessage.toRichTextElems( - null, //forGroup = kind == MessageSourceKind.GROUP, + elems = originElems ?: MessageProtocolFacade.encode( + originalMessage, messageTarget = null, //forGroup = kind == MessageSourceKind.GROUP, withGeneralFlags = false ), type = 0, diff --git a/mirai-core/src/commonMain/kotlin/message/source/outgoingSourceImpl.kt b/mirai-core/src/commonMain/kotlin/message/source/outgoingSourceImpl.kt index b4f8b1d36..6f60c2dd9 100644 --- a/mirai-core/src/commonMain/kotlin/message/source/outgoingSourceImpl.kt +++ b/mirai-core/src/commonMain/kotlin/message/source/outgoingSourceImpl.kt @@ -20,7 +20,7 @@ import net.mamoe.mirai.event.GlobalEventChannel import net.mamoe.mirai.event.syncFromEvent import net.mamoe.mirai.internal.contact.uin import net.mamoe.mirai.internal.message.MessageSourceSerializerImpl -import net.mamoe.mirai.internal.message.toRichTextElems +import net.mamoe.mirai.internal.message.protocol.MessageProtocolFacade import net.mamoe.mirai.internal.network.notice.group.GroupMessageProcessor.SendGroupMessageReceipt import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm @@ -37,7 +37,7 @@ import java.util.concurrent.atomic.AtomicBoolean private fun T.toJceDataImpl(subject: ContactOrBot?): ImMsgBody.SourceMsg where T : MessageSourceInternal, T : MessageSource { - val elements = originalMessage.toRichTextElems(subject, withGeneralFlags = true) + val elements = MessageProtocolFacade.encode(originalMessage, subject, withGeneralFlags = true) val pdReserve = SourceMsg.ResvAttr( origUids = sequenceIds.zip(internalIds) @@ -215,7 +215,7 @@ internal class OnlineMessageSourceToGroupImpl( suspend fun ensureSequenceIdAvailable() = kotlin.run { sequenceIdDeferred.await() } private val jceData: ImMsgBody.SourceMsg by lazy { - val elements = originalMessage.toRichTextElems(subject, withGeneralFlags = true) + val elements = MessageProtocolFacade.encode(originalMessage, subject, withGeneralFlags = true) ImMsgBody.SourceMsg( origSeqs = sequenceIds, senderUin = fromId, diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/Msg.kt b/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/Msg.kt index c76a7d8ca..024acbb75 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/Msg.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/Msg.kt @@ -14,7 +14,7 @@ import kotlinx.serialization.protobuf.ProtoIntegerType import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoType import net.mamoe.mirai.internal.utils.io.ProtoBuf -import net.mamoe.mirai.internal.utils.structureToString +import net.mamoe.mirai.internal.utils.structureToStringIfAvailable import net.mamoe.mirai.utils.EMPTY_BYTE_ARRAY @Serializable @@ -383,7 +383,7 @@ internal class ImMsgBody : ProtoBuf { @ProtoNumber(53) @JvmField val commonElem: CommonElem? = null, ) : ProtoBuf { override fun toString(): String { - return this.structureToString() + return this.structureToStringIfAvailable() ?: super.toString() } } @@ -937,7 +937,7 @@ internal class ImMsgBody : ProtoBuf { @Serializable internal class RichText( @ProtoNumber(1) @JvmField val attr: Attr? = null, - @ProtoNumber(2) @JvmField val elems: MutableList = mutableListOf(), + @ProtoNumber(2) @JvmField val elems: List = listOf(), @ProtoNumber(3) @JvmField val notOnlineFile: NotOnlineFile? = null, @ProtoNumber(4) @JvmField val ptt: Ptt? = null, @ProtoNumber(5) @JvmField val tmpPtt: TmpPtt? = null, diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/MultiMsg.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/MultiMsg.kt index 3e17eae39..503b78b37 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/MultiMsg.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/MultiMsg.kt @@ -15,8 +15,8 @@ import kotlinx.io.core.ByteReadPacket import net.mamoe.mirai.internal.QQAndroidBot import net.mamoe.mirai.internal.contact.SendMessageHandler import net.mamoe.mirai.internal.message.contextualBugReportException +import net.mamoe.mirai.internal.message.protocol.MessageProtocolFacade import net.mamoe.mirai.internal.message.source.MessageSourceInternal -import net.mamoe.mirai.internal.message.toRichTextElems import net.mamoe.mirai.internal.network.Packet import net.mamoe.mirai.internal.network.QQAndroidClient import net.mamoe.mirai.internal.network.components.PacketCodec @@ -86,12 +86,12 @@ internal fun Collection.calculateValidationData( ), msgBody = ImMsgBody.MsgBody( richText = ImMsgBody.RichText( - elems = chain.messageChain.toMessageChain() - .toRichTextElems( - handler.contact, - withGeneralFlags = false, - isForward = true, - ).toMutableList() + elems = MessageProtocolFacade.encode( + chain.messageChain.toMessageChain(), + handler.contact, + withGeneralFlags = false, + isForward = true + ) ) ) ) diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbSendMsg.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbSendMsg.kt index 4e1310604..a419ee744 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbSendMsg.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbSendMsg.kt @@ -22,11 +22,11 @@ import net.mamoe.mirai.internal.contact.groupCode import net.mamoe.mirai.internal.contact.uin import net.mamoe.mirai.internal.message.data.ForwardMessageInternal import net.mamoe.mirai.internal.message.data.toPtt +import net.mamoe.mirai.internal.message.protocol.MessageProtocolFacade import net.mamoe.mirai.internal.message.source.OnlineMessageSourceToFriendImpl import net.mamoe.mirai.internal.message.source.OnlineMessageSourceToGroupImpl import net.mamoe.mirai.internal.message.source.OnlineMessageSourceToStrangerImpl import net.mamoe.mirai.internal.message.source.OnlineMessageSourceToTempImpl -import net.mamoe.mirai.internal.message.toRichTextElems import net.mamoe.mirai.internal.network.Packet import net.mamoe.mirai.internal.network.QQAndroidClient import net.mamoe.mirai.internal.network.components.ClockHolder.Companion.clock @@ -198,7 +198,7 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory ImMsgBody.MsgBody( richText = ImMsgBody.RichText( - elems = subChain.toRichTextElems(messageTarget = targetFriend, withGeneralFlags = true), + elems = MessageProtocolFacade.encode( + subChain, + messageTarget = targetFriend, + withGeneralFlags = true + ), ptt = subChain.findPtt(), ), ) @@ -345,7 +349,11 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory ImMsgBody.MsgBody( richText = ImMsgBody.RichText( - elems = subChain.toRichTextElems(messageTarget = targetGroup, withGeneralFlags = true), + elems = MessageProtocolFacade.encode( + subChain, + messageTarget = targetGroup, + withGeneralFlags = true + ), ptt = subChain.findPtt(), ), diff --git a/mirai-core/src/commonMain/kotlin/pipeline/ProcessorPipeline.kt b/mirai-core/src/commonMain/kotlin/pipeline/ProcessorPipeline.kt index b58eee9de..03954302a 100644 --- a/mirai-core/src/commonMain/kotlin/pipeline/ProcessorPipeline.kt +++ b/mirai-core/src/commonMain/kotlin/pipeline/ProcessorPipeline.kt @@ -14,6 +14,7 @@ import net.mamoe.mirai.internal.network.components.NoticeProcessor import net.mamoe.mirai.utils.* import java.io.Closeable import java.util.* +import java.util.concurrent.ConcurrentLinkedDeque import java.util.concurrent.ConcurrentLinkedQueue internal interface Processor, D> : PipelineConsumptionMarker { @@ -31,7 +32,9 @@ internal interface ProcessorPipeline

() + override val processors = ConcurrentLinkedDeque

() override fun registerProcessor(processor: P): ProcessorPipeline.DisposableRegistry { processors.add(processor) @@ -162,6 +165,13 @@ protected constructor( } } + override fun registerBefore(processor: P): ProcessorPipeline.DisposableRegistry { + processors.addFirst(processor) + return ProcessorPipeline.DisposableRegistry { + processors.remove(processor) + } + } + protected abstract fun createContext(attributes: TypeSafeMap): C abstract inner class BaseContextImpl( diff --git a/mirai-core/src/commonMain/kotlin/utils/contentToString.kt b/mirai-core/src/commonMain/kotlin/utils/contentToString.kt index 02d122b1b..f04998fca 100644 --- a/mirai-core/src/commonMain/kotlin/utils/contentToString.kt +++ b/mirai-core/src/commonMain/kotlin/utils/contentToString.kt @@ -16,7 +16,15 @@ import net.mamoe.mirai.utils.debug import net.mamoe.mirai.utils.loadService +/** + * Do not call this inside [Any.toString]. [StackOverflowError] may happen. Call [structureToStringIfAvailable] instead. + */ internal fun Any?.structureToString(): String = StructureToStringTransformer.instance.transform(this) +internal fun Any?.structureToStringIfAvailable(): String? { + return if (StructureToStringTransformer.available) { + StructureToStringTransformer.instance.transform(this) + } else null +} private val SoutvLogger: MiraiLogger by lazy { MiraiLogger.Factory.create( @@ -40,6 +48,8 @@ internal fun interface StructureToStringTransformer { val instance by lazy { loadService(StructureToStringTransformer::class) { ObjectToStringStructureToStringTransformer() } } + + val available = instance !is ObjectToStringStructureToStringTransformer } }