From 1169d7cf575cfecd81ba2984a243e18ef26ebda5 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Fri, 17 Feb 2023 23:27:32 +0800 Subject: [PATCH 01/13] [core] Fix quote replying; Fix message source time --- .../kotlin/message/data/MultiMsgUploader.kt | 2 +- .../impl/GeneralMessageSenderProtocol.kt | 25 ++++++++++++++++--- .../message/source/MessageSourceInternal.kt | 5 ++++ .../message/source/incomingSourceImpl.kt | 13 ++++++---- .../message/source/offlineSourceImpl.kt | 19 +++----------- .../message/source/outgoingSourceImpl.kt | 17 +++++++------ .../chat/receive/MessageSvc.PbSendMsg.kt | 8 +++--- .../impl/AbstractMessageProtocolTest.kt | 2 +- .../protocol/impl/QuoteReplyProtocolTest.kt | 20 +++++++-------- 9 files changed, 63 insertions(+), 48 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/message/data/MultiMsgUploader.kt b/mirai-core/src/commonMain/kotlin/message/data/MultiMsgUploader.kt index c1a3c9a64a1..6ccac0def1c 100644 --- a/mirai-core/src/commonMain/kotlin/message/data/MultiMsgUploader.kt +++ b/mirai-core/src/commonMain/kotlin/message/data/MultiMsgUploader.kt @@ -256,7 +256,7 @@ internal open class MultiMsgUploader( fromNick = pm.msg.senderName, msgSeq = pm.seq, msgTime = pm.msg.time, - msgUid = 0x01000000000000000L or pm.uid.toLongUnsigned(), + msgUid = 0x0100000000000000L or pm.uid.toLongUnsigned(), mutiltransHead = MsgComm.MutilTransHead( status = 0, msgId = 1, diff --git a/mirai-core/src/commonMain/kotlin/message/protocol/impl/GeneralMessageSenderProtocol.kt b/mirai-core/src/commonMain/kotlin/message/protocol/impl/GeneralMessageSenderProtocol.kt index fa8aba986a9..c6872f8c069 100644 --- a/mirai-core/src/commonMain/kotlin/message/protocol/impl/GeneralMessageSenderProtocol.kt +++ b/mirai-core/src/commonMain/kotlin/message/protocol/impl/GeneralMessageSenderProtocol.kt @@ -27,7 +27,9 @@ import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePipelin import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePipelineContext.Companion.components import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessageSender import net.mamoe.mirai.internal.message.protocol.serialization.MessageSerializer +import net.mamoe.mirai.internal.message.source.OutgoingMessageSourceInternal import net.mamoe.mirai.internal.message.source.createMessageReceipt +import net.mamoe.mirai.internal.network.components.ClockHolder.Companion.clock import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.MessageSvcPbSendMsg import net.mamoe.mirai.message.data.AtAll @@ -69,8 +71,15 @@ internal class GeneralMessageSenderProtocol : MessageProtocol(PRIORITY_GENERAL_S fragmented = step == SendMessageStep.FRAGMENTED || currentMessageChain.contains(ForceAsFragmentedMessage) ) { source = it } - if (sendAllPackets(bot, step, contact, packets)) { + var finalTime = bot.clock.server.currentTimeSeconds().toInt() + val sendPacketOk = sendAllPackets(bot, step, contact, packets) { idx, rsp -> + if (rsp is MessageSvcPbSendMsg.Response.SUCCESS) { + finalTime = rsp.sendTime + } + } + if (sendPacketOk) { val sourceAwait = source?.await() ?: error("Internal error: source is not initialized") + (sourceAwait as OutgoingMessageSourceInternal).time = finalTime sourceAwait.tryEnsureSequenceIdAvailable() collect(sourceAwait.createMessageReceipt(contact, true)) } @@ -83,14 +92,19 @@ internal class GeneralMessageSenderProtocol : MessageProtocol(PRIORITY_GENERAL_S bot: AbstractBot, step: SendMessageStep, contact: Contact, - packets: List + packets: List, + packetResponseConsumer: (Int, MessageSvcPbSendMsg.Response) -> Unit = { _, _ -> }, ): Boolean { if (!step.allowMultiplePackets && packets.size != 1) { throw IllegalStateException("Internal error: step $step doesn't allow multiple packets while found ${packets.size} ones.") } - packets.forEach { packet -> - if (!sendSinglePacket(bot, packet, step, contact)) return@sendAllPackets false + packets.forEachIndexed { index, packet -> + if (!sendSinglePacket( + bot, packet, step, contact, + index, packetResponseConsumer + ) + ) return@sendAllPackets false } return true @@ -101,12 +115,15 @@ internal class GeneralMessageSenderProtocol : MessageProtocol(PRIORITY_GENERAL_S packet: OutgoingPacket, step: SendMessageStep, contact: Contact, + index: Int, + packetResponseConsumer: (Int, MessageSvcPbSendMsg.Response) -> Unit, ): Boolean { val originalMessage = attributes[ORIGINAL_MESSAGE] val protocolStrategy = components[MessageProtocolStrategy] val finalMessage = currentMessageChain val resp = protocolStrategy.sendPacket(bot, packet) as MessageSvcPbSendMsg.Response + packetResponseConsumer(index, resp) if (resp is MessageSvcPbSendMsg.Response.MessageTooLarge) { logger.info { "STEP $step: message too large." } val next = step.nextStepOrNull() diff --git a/mirai-core/src/commonMain/kotlin/message/source/MessageSourceInternal.kt b/mirai-core/src/commonMain/kotlin/message/source/MessageSourceInternal.kt index 6af3ff68d07..1bfdc39ddfb 100644 --- a/mirai-core/src/commonMain/kotlin/message/source/MessageSourceInternal.kt +++ b/mirai-core/src/commonMain/kotlin/message/source/MessageSourceInternal.kt @@ -61,6 +61,11 @@ internal interface OutgoingMessageSourceInternal : MessageSourceInternal { * This 'overrides' [MessageSource.originalMessage]. */ var originalMessage: MessageChain + + /** + * This for patch outgoing message source to real time (from server) + */ + var time: Int } /** diff --git a/mirai-core/src/commonMain/kotlin/message/source/incomingSourceImpl.kt b/mirai-core/src/commonMain/kotlin/message/source/incomingSourceImpl.kt index eac8b5edb5d..bf65d3cf343 100644 --- a/mirai-core/src/commonMain/kotlin/message/source/incomingSourceImpl.kt +++ b/mirai-core/src/commonMain/kotlin/message/source/incomingSourceImpl.kt @@ -48,7 +48,7 @@ internal class OnlineMessageSourceFromFriendImpl( ) : OnlineMessageSource.Incoming.FromFriend(), IncomingMessageSourceInternal { object Serializer : KSerializer by MessageSourceSerializerImpl("OnlineMessageSourceFromFriend") - override val sequenceIds: IntArray = msg.mapToIntArray { it.msgHead.msgSeq } + override val sequenceIds: IntArray = msg.mapToIntArray { it.msgHead.msgSeq.and(0xFFFF) } private val _isRecalledOrPlanned = atomic(false) @@ -119,10 +119,12 @@ internal class OnlineMessageSourceFromStrangerImpl( private fun List.toJceDataPrivate(ids: IntArray): ImMsgBody.SourceMsg { val elements = flatMap { it.msgBody.richText.elems }.toMutableList().also { - if (it.last().elemFlags2 == null) it.add(ImMsgBody.Elem(elemFlags2 = ImMsgBody.ElemFlags2())) + if (it.lastOrNull()?.elemFlags2 == null) it.add(ImMsgBody.Elem(elemFlags2 = ImMsgBody.ElemFlags2())) } - first().msgHead.run { + val firstMsgMsgHead = first().msgHead + + firstMsgMsgHead.run { return ImMsgBody.SourceMsg( origSeqs = mapToIntArray { it.msgHead.msgSeq }, senderUin = fromUin, @@ -132,7 +134,7 @@ private fun List.toJceDataPrivate(ids: IntArray): ImMsgBody.SourceM type = 0, time = msgTime, pbReserve = SourceMsg.ResvAttr( - origUids = ids.map { it.toLong() and 0xFFFF_FFFF } + origUids = mutableListOf(firstMsgMsgHead.msgUid) ).toByteArray(SourceMsg.ResvAttr.serializer()), srcMsg = MsgComm.Msg( msgHead = MsgComm.MsgHead( @@ -142,7 +144,8 @@ private fun List.toJceDataPrivate(ids: IntArray): ImMsgBody.SourceM c2cCmd = c2cCmd, msgSeq = msgSeq, msgTime = msgTime, - msgUid = ids.single().toLong() and 0xFFFF_FFFF, // ok + msgUid = firstMsgMsgHead.msgUid, // ok +// msgUid = ids.single().toLong() and 0xFFFF_FFFF, // ok // groupInfo = MsgComm.GroupInfo(groupCode = msgHead.groupInfo.groupCode), isSrcMsg = true ), diff --git a/mirai-core/src/commonMain/kotlin/message/source/offlineSourceImpl.kt b/mirai-core/src/commonMain/kotlin/message/source/offlineSourceImpl.kt index ba05478a0ff..68d8e2dbe00 100644 --- a/mirai-core/src/commonMain/kotlin/message/source/offlineSourceImpl.kt +++ b/mirai-core/src/commonMain/kotlin/message/source/offlineSourceImpl.kt @@ -16,7 +16,6 @@ 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.network.protocol.data.proto.ImMsgBody import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm @@ -27,7 +26,6 @@ import net.mamoe.mirai.message.data.MessageSource import net.mamoe.mirai.message.data.MessageSourceKind import net.mamoe.mirai.message.data.OfflineMessageSource import net.mamoe.mirai.message.data.visitor.MessageVisitor -import net.mamoe.mirai.utils.EMPTY_BYTE_ARRAY import net.mamoe.mirai.utils.isSameType import net.mamoe.mirai.utils.mapToIntArray @@ -66,20 +64,9 @@ internal class OfflineMessageSourceImplData( override fun setRecalled(): Boolean = _isRecalledOrPlanned.compareAndSet(expect = false, update = true) override fun toJceData(): ImMsgBody.SourceMsg { - return jceData ?: ImMsgBody.SourceMsg( - origSeqs = sequenceIds, - senderUin = fromId, - toUin = 0, - flag = 1, - elems = originElems ?: MessageProtocolFacade.encode( - originalMessage, messageTarget = null, //forGroup = kind == MessageSourceKind.GROUP, - withGeneralFlags = false - ), - type = 0, - time = time, - pbReserve = EMPTY_BYTE_ARRAY, - srcMsg = EMPTY_BYTE_ARRAY - ).also { jceData = it } + jceData?.let { return it } + + return toJceDataImpl(null).also { jceData = it } } override fun equals(other: Any?): Boolean { diff --git a/mirai-core/src/commonMain/kotlin/message/source/outgoingSourceImpl.kt b/mirai-core/src/commonMain/kotlin/message/source/outgoingSourceImpl.kt index 4c789e83dda..646ada20a5d 100644 --- a/mirai-core/src/commonMain/kotlin/message/source/outgoingSourceImpl.kt +++ b/mirai-core/src/commonMain/kotlin/message/source/outgoingSourceImpl.kt @@ -38,14 +38,15 @@ import net.mamoe.mirai.utils.loadService import net.mamoe.mirai.utils.toLongUnsigned -private fun T.toJceDataImpl(subject: ContactOrBot?): ImMsgBody.SourceMsg +internal fun T.toJceDataImpl(subject: ContactOrBot?): ImMsgBody.SourceMsg where T : MessageSourceInternal, T : MessageSource { - val elements = MessageProtocolFacade.encode(originalMessage, subject, withGeneralFlags = true) + val elements = MessageProtocolFacade.encode(originalMessage, subject, withGeneralFlags = false) val pdReserve = SourceMsg.ResvAttr( - origUids = sequenceIds.zip(internalIds) - .map { (seq, internal) -> seq.toLong().shl(32) or internal.toLongUnsigned() } + origUids = internalIds.map { 0x100000000000000 or it.toLongUnsigned() } +// origUids = sequenceIds.zip(internalIds) +// .map { (seq, internal) -> seq.toLong().shl(32) or internal.toLongUnsigned() } ) return ImMsgBody.SourceMsg( @@ -85,7 +86,7 @@ private fun T.toJceDataImpl(subject: ContactOrBot?): ImMsgBody.SourceMsg internal class OnlineMessageSourceToFriendImpl( override val sequenceIds: IntArray, override val internalIds: IntArray, - override val time: Int, + override var time: Int, override var originalMessage: MessageChain, override val sender: Bot, override val target: Friend, @@ -119,7 +120,7 @@ internal class OnlineMessageSourceToFriendImpl( internal class OnlineMessageSourceToStrangerImpl( override val sequenceIds: IntArray, override val internalIds: IntArray, - override val time: Int, + override var time: Int, override var originalMessage: MessageChain, override val sender: Bot, override val target: Stranger, @@ -158,7 +159,7 @@ internal class OnlineMessageSourceToStrangerImpl( internal class OnlineMessageSourceToTempImpl( override val sequenceIds: IntArray, override val internalIds: IntArray, - override val time: Int, + override var time: Int, override var originalMessage: MessageChain, override val sender: Bot, override val target: Member, @@ -197,7 +198,7 @@ internal class OnlineMessageSourceToTempImpl( internal class OnlineMessageSourceToGroupImpl( coroutineScope: CoroutineScope, override val internalIds: IntArray, // aka random - override val time: Int, + override var time: Int, override var originalMessage: MessageChain, override val sender: Bot, override val target: Group, 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 f07f0fc7655..aa2655e2de5 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 @@ -49,8 +49,10 @@ import kotlin.random.Random internal object MessageSvcPbSendMsg : OutgoingPacketFactory("MessageSvc.PbSendMsg") { sealed class Response : Packet { - object SUCCESS : Response() { - override fun toString(): String = "MessageSvcPbSendMsg.Response.SUCCESS" + class SUCCESS( + val sendTime: Int, + ) : Response() { + override fun toString(): String = "MessageSvcPbSendMsg.Response.SUCCESS(time=$sendTime)" } object MessageTooLarge : Response() { @@ -486,7 +488,7 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory Response.SUCCESS + 0 -> Response.SUCCESS(response.sendTime) 10 -> Response.MessageTooLarge 32 -> Response.ServiceUnavailable else -> Response.Failed( diff --git a/mirai-core/src/commonTest/kotlin/message/protocol/impl/AbstractMessageProtocolTest.kt b/mirai-core/src/commonTest/kotlin/message/protocol/impl/AbstractMessageProtocolTest.kt index 0c2216869c8..1d2c10ef8bf 100644 --- a/mirai-core/src/commonTest/kotlin/message/protocol/impl/AbstractMessageProtocolTest.kt +++ b/mirai-core/src/commonTest/kotlin/message/protocol/impl/AbstractMessageProtocolTest.kt @@ -252,7 +252,7 @@ internal abstract class AbstractMessageProtocolTest : AbstractMockNetworkHandler open inner class TestMessageProtocolStrategy : MessageProtocolStrategy { override suspend fun sendPacket(bot: AbstractBot, packet: OutgoingPacket): Packet { assertEquals(0x123, packet.sequenceId) - return MessageSvcPbSendMsg.Response.SUCCESS + return MessageSvcPbSendMsg.Response.SUCCESS(123) } override suspend fun createPacketsForGeneralMessage( diff --git a/mirai-core/src/commonTest/kotlin/message/protocol/impl/QuoteReplyProtocolTest.kt b/mirai-core/src/commonTest/kotlin/message/protocol/impl/QuoteReplyProtocolTest.kt index 3020ef8685c..ee6e2bc8868 100644 --- a/mirai-core/src/commonTest/kotlin/message/protocol/impl/QuoteReplyProtocolTest.kt +++ b/mirai-core/src/commonTest/kotlin/message/protocol/impl/QuoteReplyProtocolTest.kt @@ -21,7 +21,6 @@ import net.mamoe.mirai.internal.testFramework.runDynamicTests import net.mamoe.mirai.internal.utils.runCoroutineInPlace import net.mamoe.mirai.message.data.* import net.mamoe.mirai.message.data.MessageSource.Key.quote -import net.mamoe.mirai.utils.EMPTY_BYTE_ARRAY import net.mamoe.mirai.utils.hexToBytes import kotlin.test.Test @@ -90,8 +89,9 @@ internal class QuoteReplyProtocolTest : AbstractMessageProtocolTest() { ), ), ), - srcMsg = EMPTY_BYTE_ARRAY - // mirai's OfflineMessageSource has no enough information to create 'srcMsg' + pbReserve = "18 AE FB A2 F7 86 80 80 80 01".hexToBytes(), + srcMsg = "0A 2C 08 B1 89 4B 10 DD F1 92 B7 07 18 09 20 0B 28 E7 8B FE FF FF FF FF FF FF 01 30 B2 85 AF 94 06 38 AE FB A2 F7 86 80 80 80 01 E0 01 01 1A 0D 0A 0B 12 05 0A 03 0A 01 61 12 02 4A 00".hexToBytes(), + toUin = 1994701021, ), ), net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem( @@ -192,8 +192,8 @@ internal class QuoteReplyProtocolTest : AbstractMessageProtocolTest() { ), ), ), - pbReserve = "18 BA 92 F1 A4 02".hexToBytes(), - srcMsg = "0A 20 08 B1 89 4B 10 B2 89 4B 18 A6 01 20 0B 28 8D F4 01 30 B0 A7 AF 94 06 38 BA 92 F1 A4 02 E0 01 01 1A 2D 0A 2B 12 05 0A 03 0A 01 61 12 00 12 1C AA 02 19 9A 01 16 78 00 C8 01 00 F0 01 00 F8 01 00 90 02 00 CA 04 00 D2 05 02 08 61 12 02 4A 00".hexToBytes(), + pbReserve = "18 BA 92 F1 A4 82 80 80 80 01".hexToBytes(), + srcMsg = "0A 24 08 B1 89 4B 10 B2 89 4B 18 A6 01 20 0B 28 8D F4 01 30 B0 A7 AF 94 06 38 BA 92 F1 A4 82 80 80 80 01 E0 01 01 1A 2D 0A 2B 12 05 0A 03 0A 01 61 12 00 12 1C AA 02 19 9A 01 16 78 00 C8 01 00 F0 01 00 F8 01 00 90 02 00 CA 04 00 D2 05 02 08 61 12 02 4A 00".hexToBytes(), toUin = 1230002, ), ), @@ -330,8 +330,9 @@ internal class QuoteReplyProtocolTest : AbstractMessageProtocolTest() { ), ), ), - srcMsg = EMPTY_BYTE_ARRAY - // mirai's OfflineMessageSource has no enough information to create 'srcMsg' + pbReserve = "18 AE FB A2 F7 86 80 80 80 01".hexToBytes(), + srcMsg = "0A 2C 08 B1 89 4B 10 DD F1 92 B7 07 18 09 20 0B 28 E7 8B FE FF FF FF FF FF FF 01 30 B2 85 AF 94 06 38 AE FB A2 F7 86 80 80 80 01 E0 01 01 1A 0D 0A 0B 12 05 0A 03 0A 01 61 12 02 4A 00".hexToBytes(), + toUin = 1994701021, ), ), net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem( @@ -430,9 +431,8 @@ internal class QuoteReplyProtocolTest : AbstractMessageProtocolTest() { ), ), ), - pbReserve = "18 BD F9 EF D7 06".hexToBytes(), - // srcMsg is available for online source - srcMsg = "0A 20 08 B1 89 4B 10 B2 89 4B 18 A6 01 20 0B 28 F6 F3 01 30 83 91 AF 94 06 38 BD F9 EF D7 06 E0 01 01 1A 2D 0A 2B 12 05 0A 03 0A 01 61 12 00 12 1C AA 02 19 9A 01 16 78 00 C8 01 00 F0 01 00 F8 01 00 90 02 00 CA 04 00 D2 05 02 08 4F 12 02 4A 00".hexToBytes(), + pbReserve = "18 BD F9 EF D7 86 80 80 80 01".hexToBytes(), + srcMsg = "0A 24 08 B1 89 4B 10 B2 89 4B 18 A6 01 20 0B 28 F6 F3 01 30 83 91 AF 94 06 38 BD F9 EF D7 86 80 80 80 01 E0 01 01 1A 2D 0A 2B 12 05 0A 03 0A 01 61 12 00 12 1C AA 02 19 9A 01 16 78 00 C8 01 00 F0 01 00 F8 01 00 90 02 00 CA 04 00 D2 05 02 08 4F 12 02 4A 00".hexToBytes(), toUin = 1230002, ), ), From 648997b5456d25dc75be2ec82f8068cc55ab1e15 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Fri, 17 Feb 2023 23:51:05 +0800 Subject: [PATCH 02/13] [core] Fix offline message source ids --- .../kotlin/message/source/offlineSourceImpl.kt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/message/source/offlineSourceImpl.kt b/mirai-core/src/commonMain/kotlin/message/source/offlineSourceImpl.kt index 68d8e2dbe00..7c233716f24 100644 --- a/mirai-core/src/commonMain/kotlin/message/source/offlineSourceImpl.kt +++ b/mirai-core/src/commonMain/kotlin/message/source/offlineSourceImpl.kt @@ -107,6 +107,15 @@ internal class OfflineMessageSourceImplData( } } +private fun IntArray.fixIds(kind: MessageSourceKind): IntArray { + if (kind == MessageSourceKind.FRIEND) { + for (idx in this.indices) { + this[idx] = this[idx].and(0xFFFF) + } + } + return this +} + internal fun OfflineMessageSourceImplData( bot: Bot, delegate: List, @@ -123,7 +132,7 @@ internal fun OfflineMessageSourceImplData( groupIdOrZero = head.groupInfo?.groupCode ?: 0, messageSourceKind = kind ), - ids = delegate.mapToIntArray { it.msgHead.msgSeq }, + ids = delegate.mapToIntArray { it.msgHead.msgSeq }.fixIds(kind), internalIds = delegate.mapToIntArray { it.msgHead.msgUid.toInt() }, botId = bot.id ).apply { @@ -161,7 +170,7 @@ internal fun OfflineMessageSourceImplData( ): OfflineMessageSourceImplData { return OfflineMessageSourceImplData( kind = messageSourceKind, - ids = delegate.origSeqs, + ids = delegate.origSeqs.fixIds(messageSourceKind), internalIds = delegate.pbReserve.loadAs(SourceMsg.ResvAttr.serializer()) .origUids?.mapToIntArray { it.toInt() } ?: intArrayOf(), time = delegate.time, From fe146000188c2626f8b9b3499f6dd28df43f215b Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Fri, 17 Feb 2023 23:51:28 +0800 Subject: [PATCH 03/13] [core] Private quote reply decode --- .../kotlin/message/source/offlineSourceImpl.kt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/message/source/offlineSourceImpl.kt b/mirai-core/src/commonMain/kotlin/message/source/offlineSourceImpl.kt index 7c233716f24..b429c320ce0 100644 --- a/mirai-core/src/commonMain/kotlin/message/source/offlineSourceImpl.kt +++ b/mirai-core/src/commonMain/kotlin/message/source/offlineSourceImpl.kt @@ -162,12 +162,21 @@ internal fun OfflineMessageSourceImplData( it.originalMessage // initialize lazy, to make isOriginalMessageInitialized true. } +@Suppress("LocalVariableName") internal fun OfflineMessageSourceImplData( delegate: ImMsgBody.SourceMsg, bot: Bot, - messageSourceKind: MessageSourceKind, - groupIdOrZero: Long, + _messageSourceKind: MessageSourceKind, + _groupIdOrZero: Long, ): OfflineMessageSourceImplData { + var messageSourceKind = _messageSourceKind + var groupIdOrZero = _groupIdOrZero + + if (messageSourceKind != MessageSourceKind.GROUP && delegate.troopName.isNotEmpty()) { // FROM GROUP: 单独回复 + messageSourceKind = MessageSourceKind.GROUP + groupIdOrZero = 0 + } + return OfflineMessageSourceImplData( kind = messageSourceKind, ids = delegate.origSeqs.fixIds(messageSourceKind), From ec5870e0b3d5b9637afca54bf231fdfb5b6524dc Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Sat, 18 Feb 2023 22:56:27 +0800 Subject: [PATCH 04/13] [core] Get group incoming message source raw data directly --- .../android/api/android.api | 4 ++-- .../compatibility-validation/jvm/api/jvm.api | 4 ++-- .../kotlin/message/data/OnlineMessageSource.kt | 5 +++-- .../message/source/incomingSourceImpl.kt | 18 +++++++++++------- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/mirai-core-api/compatibility-validation/android/api/android.api b/mirai-core-api/compatibility-validation/android/api/android.api index 9ea913c9504..1ccd73be6cc 100644 --- a/mirai-core-api/compatibility-validation/android/api/android.api +++ b/mirai-core-api/compatibility-validation/android/api/android.api @@ -4809,9 +4809,9 @@ public abstract class net/mamoe/mirai/message/data/OnlineMessageSource : net/mam public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming : net/mamoe/mirai/message/data/OnlineMessageSource { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Incoming$Key; - public final fun getFromId ()J + public fun getFromId ()J public abstract fun getSender ()Lnet/mamoe/mirai/contact/User; - public final fun getTargetId ()J + public fun getTargetId ()J } public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromFriend : net/mamoe/mirai/message/data/OnlineMessageSource$Incoming { diff --git a/mirai-core-api/compatibility-validation/jvm/api/jvm.api b/mirai-core-api/compatibility-validation/jvm/api/jvm.api index 3cf6ecb3983..9b3723b40fe 100644 --- a/mirai-core-api/compatibility-validation/jvm/api/jvm.api +++ b/mirai-core-api/compatibility-validation/jvm/api/jvm.api @@ -4809,9 +4809,9 @@ public abstract class net/mamoe/mirai/message/data/OnlineMessageSource : net/mam public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming : net/mamoe/mirai/message/data/OnlineMessageSource { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Incoming$Key; - public final fun getFromId ()J + public fun getFromId ()J public abstract fun getSender ()Lnet/mamoe/mirai/contact/User; - public final fun getTargetId ()J + public fun getTargetId ()J } public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromFriend : net/mamoe/mirai/message/data/OnlineMessageSource$Incoming { diff --git a/mirai-core-api/src/commonMain/kotlin/message/data/OnlineMessageSource.kt b/mirai-core-api/src/commonMain/kotlin/message/data/OnlineMessageSource.kt index 25fd4af8dec..95e3eb8e3a8 100644 --- a/mirai-core-api/src/commonMain/kotlin/message/data/OnlineMessageSource.kt +++ b/mirai-core-api/src/commonMain/kotlin/message/data/OnlineMessageSource.kt @@ -151,8 +151,9 @@ public sealed class OnlineMessageSource : MessageSource() { public sealed class Incoming : OnlineMessageSource() { public abstract override val sender: User - public final override val fromId: Long get() = sender.id - public final override val targetId: Long get() = target.id + /// NOTE: DONT use final to avoid contact not available + public override val fromId: Long get() = sender.id + public override val targetId: Long get() = target.id @NotStableForInheritance public abstract class FromFriend @MiraiInternalApi constructor() : Incoming() { diff --git a/mirai-core/src/commonMain/kotlin/message/source/incomingSourceImpl.kt b/mirai-core/src/commonMain/kotlin/message/source/incomingSourceImpl.kt index bf65d3cf343..95c38c85fb9 100644 --- a/mirai-core/src/commonMain/kotlin/message/source/incomingSourceImpl.kt +++ b/mirai-core/src/commonMain/kotlin/message/source/incomingSourceImpl.kt @@ -206,7 +206,7 @@ internal class OnlineMessageSourceFromTempImpl( @Serializable(OnlineMessageSourceFromGroupImpl.Serializer::class) internal class OnlineMessageSourceFromGroupImpl( override val bot: Bot, - msg: List, + private val msg: List, ) : OnlineMessageSource.Incoming.FromGroup(), IncomingMessageSourceInternal { object Serializer : KSerializer by MessageSourceSerializerImpl("OnlineMessageSourceFromGroupImpl") @@ -229,11 +229,8 @@ internal class OnlineMessageSourceFromGroupImpl( override val subject: GroupImpl by lazy { - val groupCode = msg.first().msgHead.groupInfo?.groupCode - ?: error("cannot find groupCode for OnlineMessageSourceFromGroupImpl. msg=${msg.structureToString()}") - - val group = bot.getGroup(groupCode)?.checkIsGroupImpl() - ?: error("cannot find group for OnlineMessageSourceFromGroupImpl. msg=${msg.structureToString()}") + val group = bot.getGroup(targetId)?.checkIsGroupImpl() + ?: error("cannot find group for OnlineMessageSourceFromGroupImpl. Use `source.targetId` to get group id. msg=${msg.structureToString()}") group } @@ -245,13 +242,20 @@ internal class OnlineMessageSourceFromGroupImpl( if (member != null) return@lazy member val anonymousInfo = msg.first().msgBody.richText.elems.firstOrNull { it.anonGroupMsg != null } - ?: error("cannot find member for OnlineMessageSourceFromGroupImpl. msg=${msg.structureToString()}") + ?: error("cannot find member for OnlineMessageSourceFromGroupImpl. Use `source.fromId` to get sender id. msg=${msg.structureToString()}") anonymousInfo.run { group.newAnonymous(anonGroupMsg!!.anonNick.decodeToString(), anonGroupMsg.anonId.encodeBase64()) } } + override val fromId: Long get() = msg.first().msgHead.fromUin + override val targetId: Long + get() { + return msg.first().msgHead.groupInfo?.groupCode + ?: error("cannot find groupCode for OnlineMessageSourceFromGroupImpl. msg=${msg.structureToString()}") + } + private val jceData: ImMsgBody.SourceMsg by lazy { ImMsgBody.SourceMsg( origSeqs = intArrayOf(msg.first().msgHead.msgSeq), From 00486e7900c150359f5222d1ed64eff6061d3dbf Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Sat, 18 Feb 2023 23:43:45 +0800 Subject: [PATCH 05/13] [core] Add internal message when failed to transform internal message to facade message --- .../kotlin/message/ReceiveMessageHandler.kt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/mirai-core/src/commonMain/kotlin/message/ReceiveMessageHandler.kt b/mirai-core/src/commonMain/kotlin/message/ReceiveMessageHandler.kt index c9f6a3ab085..f968140acee 100644 --- a/mirai-core/src/commonMain/kotlin/message/ReceiveMessageHandler.kt +++ b/mirai-core/src/commonMain/kotlin/message/ReceiveMessageHandler.kt @@ -24,6 +24,7 @@ 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.message.data.* +import net.mamoe.mirai.utils.structureToString import net.mamoe.mirai.utils.toLongUnsigned /** @@ -104,6 +105,24 @@ private fun List.toMessageChain( onlineSource: Boolean?, messageSourceKind: MessageSourceKind, facade: MessageProtocolFacade = MessageProtocolFacade, +): MessageChain { + try { + return toMessageChainImpl(bot, groupIdOrZero, onlineSource, messageSourceKind, facade) + } catch (e: Exception) { + throw IllegalStateException( + "Failed to transform internal message to facade message, msg=${this@toMessageChain.structureToString()}", + e + ) + } +} + + +private fun List.toMessageChainImpl( + bot: Bot, + groupIdOrZero: Long, + onlineSource: Boolean?, + messageSourceKind: MessageSourceKind, + facade: MessageProtocolFacade = MessageProtocolFacade, ): MessageChain { val messageList = this From 8c5a22a14e7966bb05a118704269426d2882180c Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Sat, 18 Feb 2023 23:44:48 +0800 Subject: [PATCH 06/13] [core] Try to fix rand id fetching --- .../roaming/AbstractRoamingMessages.kt | 3 ++- .../message/source/incomingSourceImpl.kt | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/contact/roaming/AbstractRoamingMessages.kt b/mirai-core/src/commonMain/kotlin/contact/roaming/AbstractRoamingMessages.kt index 962a706a7d0..a181ef7d93a 100644 --- a/mirai-core/src/commonMain/kotlin/contact/roaming/AbstractRoamingMessages.kt +++ b/mirai-core/src/commonMain/kotlin/contact/roaming/AbstractRoamingMessages.kt @@ -13,6 +13,7 @@ import net.mamoe.mirai.contact.Contact import net.mamoe.mirai.contact.roaming.RoamingMessage import net.mamoe.mirai.contact.roaming.RoamingMessages import net.mamoe.mirai.internal.contact.AbstractContact +import net.mamoe.mirai.internal.message.source.decodeRandom import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm import net.mamoe.mirai.utils.mapToIntArray import net.mamoe.mirai.utils.toLongUnsigned @@ -31,7 +32,7 @@ internal abstract class AbstractRoamingMessages : RoamingMessages { override val time: Long get() = message.msgHead.msgTime.toLongUnsigned() override val ids: IntArray by lazy { messages.mapToIntArray { it.msgHead.msgSeq } } override val internalIds: IntArray by lazy { - messages.mapToIntArray { it.msgBody.richText.attr?.random ?: 0 } // other client 消息的这个是0 + messages.mapToIntArray { it.decodeRandom() } } } } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/message/source/incomingSourceImpl.kt b/mirai-core/src/commonMain/kotlin/message/source/incomingSourceImpl.kt index 95c38c85fb9..378204765dd 100644 --- a/mirai-core/src/commonMain/kotlin/message/source/incomingSourceImpl.kt +++ b/mirai-core/src/commonMain/kotlin/message/source/incomingSourceImpl.kt @@ -56,9 +56,7 @@ internal class OnlineMessageSourceFromFriendImpl( override val isRecalledOrPlanned: Boolean get() = _isRecalledOrPlanned.value override fun setRecalled(): Boolean = _isRecalledOrPlanned.compareAndSet(expect = false, update = true) override val ids: IntArray get() = sequenceIds // msg.msgBody.richText.attr!!.random - override val internalIds: IntArray = msg.mapToIntArray { - it.msgBody.richText.attr?.random ?: 0 - } // other client 消息的这个是0 + override val internalIds: IntArray = msg.mapToIntArray { it.decodeRandom() } override val time: Int = msg.first().msgHead.msgTime override var originalMessageLazy = lazy { msg.toMessageChainNoSource(bot, 0, MessageSourceKind.FRIEND) @@ -95,9 +93,7 @@ internal class OnlineMessageSourceFromStrangerImpl( override fun setRecalled(): Boolean = _isRecalledOrPlanned.compareAndSet(expect = false, update = true) override val ids: IntArray get() = sequenceIds // msg.msgBody.richText.attr!!.random - override val internalIds: IntArray = msg.mapToIntArray { - it.msgBody.richText.attr?.random ?: 0 - } // other client 消息的这个是0 + override val internalIds: IntArray = msg.mapToIntArray { it.decodeRandom() } override val time: Int = msg.first().msgHead.msgTime override var originalMessageLazy = lazy { msg.toMessageChainNoSource(bot, 0, MessageSourceKind.STRANGER) @@ -159,6 +155,13 @@ private fun List.toJceDataPrivate(ids: IntArray): ImMsgBody.SourceM } } +internal fun MsgComm.Msg.decodeRandom(): Int { + msgBody.richText.attr?.random?.let { return it } + + // msg uin = 0x100000000000000 or rand.toLongUnsigned() + return msgHead.msgUid.toInt() +} + @Suppress("SERIALIZER_TYPE_INCOMPATIBLE") @Serializable(OnlineMessageSourceFromTempImpl.Serializer::class) internal class OnlineMessageSourceFromTempImpl( @@ -168,7 +171,7 @@ internal class OnlineMessageSourceFromTempImpl( object Serializer : KSerializer by MessageSourceSerializerImpl("OnlineMessageSourceFromTemp") override val sequenceIds: IntArray = msg.mapToIntArray { it.msgHead.msgSeq } - override val internalIds: IntArray = msg.mapToIntArray { it.msgBody.richText.attr!!.random } + override val internalIds: IntArray = msg.mapToIntArray { it.decodeRandom() } private val _isRecalledOrPlanned = atomic(false) @@ -217,7 +220,7 @@ internal class OnlineMessageSourceFromGroupImpl( override val isRecalledOrPlanned: Boolean get() = _isRecalledOrPlanned.value override fun setRecalled(): Boolean = _isRecalledOrPlanned.compareAndSet(expect = false, update = true) override val sequenceIds: IntArray = msg.mapToIntArray { it.msgHead.msgSeq } - override val internalIds: IntArray = msg.mapToIntArray { it.msgBody.richText.attr!!.random } + override val internalIds: IntArray = msg.mapToIntArray { it.decodeRandom() } override val ids: IntArray get() = sequenceIds override val time: Int = msg.first().msgHead.msgTime override var originalMessageLazy = lazy { From 07164cc79bab8293421250914deea821b6b46375 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Sun, 19 Feb 2023 12:57:16 +0800 Subject: [PATCH 07/13] [core] Fix group roaming message fetching --- .../kotlin/contact/roaming/RoamingMessagesImplGroup.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/contact/roaming/RoamingMessagesImplGroup.kt b/mirai-core/src/commonMain/kotlin/contact/roaming/RoamingMessagesImplGroup.kt index 677c3f2b83d..6331708e658 100644 --- a/mirai-core/src/commonMain/kotlin/contact/roaming/RoamingMessagesImplGroup.kt +++ b/mirai-core/src/commonMain/kotlin/contact/roaming/RoamingMessagesImplGroup.kt @@ -12,12 +12,12 @@ package net.mamoe.mirai.internal.contact.roaming import kotlinx.coroutines.flow.* import net.mamoe.mirai.contact.roaming.RoamingMessageFilter import net.mamoe.mirai.internal.contact.CommonGroupImpl -import net.mamoe.mirai.internal.message.getMessageSourceKindFromC2cCmdOrNull import net.mamoe.mirai.internal.message.toMessageChainOnline import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm import net.mamoe.mirai.internal.network.protocol.packet.chat.TroopManagement import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.MessageSvcPbGetGroupMsg import net.mamoe.mirai.message.data.MessageChain +import net.mamoe.mirai.message.data.MessageSourceKind internal class RoamingMessagesImplGroup( override val contact: CommonGroupImpl @@ -56,12 +56,11 @@ internal class RoamingMessagesImplGroup( emitAll( resp.msgElem.asSequence() - .filter { getMessageSourceKindFromC2cCmdOrNull(it.msgHead.c2cCmd) != null } // ignore unsupported messages .filter { it.time in timeStart..timeEnd } - .sortedByDescending { it.time } // Ensure caller receiver newer messages first + .sortedByDescending { it.msgHead.msgSeq } // Ensure caller receiver newer messages first .filter { filter.apply(it) } // Call filter after sort .asFlow() - .map { it.toMessageChainOnline(bot) } + .map { listOf(it).toMessageChainOnline(bot, contact.id, MessageSourceKind.GROUP) } ) currentSeq = resp.msgElem.minBy { it.time }.msgHead.msgSeq From 275d9f8f6e95237206be5241e5a65e11b3156859 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Sun, 19 Feb 2023 22:39:46 +0800 Subject: [PATCH 08/13] [core] Fix replying unavailable member's message --- .../protocol/impl/QuoteReplyProtocol.kt | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/message/protocol/impl/QuoteReplyProtocol.kt b/mirai-core/src/commonMain/kotlin/message/protocol/impl/QuoteReplyProtocol.kt index ec516245fb3..ad4eda88e19 100644 --- a/mirai-core/src/commonMain/kotlin/message/protocol/impl/QuoteReplyProtocol.kt +++ b/mirai-core/src/commonMain/kotlin/message/protocol/impl/QuoteReplyProtocol.kt @@ -157,17 +157,27 @@ internal class QuoteReplyProtocol : MessageProtocol(PRIORITY_METADATA) { markAsConsumed() collect(ImMsgBody.Elem(srcMsg = source.toJceData())) if (sourceCommon.kind == MessageSourceKind.GROUP) { - if (source is OnlineMessageSource.Incoming.FromGroup) { - val sender0 = source.sender - if (sender0 !is AnonymousMember) { - processAlso(At(sender0)) + + @Suppress("RemoveExplicitTypeArguments") + val needPlusAt = sequence { + if (source is OnlineMessageSource.Incoming.FromGroup) { + try { + val sender0 = source.sender + yield(sender0 !is AnonymousMember) + } catch (_: IllegalStateException) { + // Member not available now + } } + + yield(sourceCommon.fromId != 80000000L) + } + + if (needPlusAt.first()) { + processAlso(At(sourceCommon.fromId)) + // transformOneMessage(PlainText(" ")) // removed by https://github.com/mamoe/mirai/issues/524 // 发送 QuoteReply 消息时无可避免的产生多余空格 #524 - } else if (sourceCommon.fromId != 80000000L) { - // https://github.com/mamoe/mirai/issues/2501 OfflineMessageSource quote replying - processAlso(At(sourceCommon.fromId)) } } } From 8d9c820a92c0ce84e5bd8c646e70b19e76399bd8 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Sat, 18 Mar 2023 23:18:09 +0800 Subject: [PATCH 09/13] [core] Fix group roaming message fetching --- .../kotlin/contact/roaming/RoamingMessagesImplGroup.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/contact/roaming/RoamingMessagesImplGroup.kt b/mirai-core/src/commonMain/kotlin/contact/roaming/RoamingMessagesImplGroup.kt index 6331708e658..db3310bc5e3 100644 --- a/mirai-core/src/commonMain/kotlin/contact/roaming/RoamingMessagesImplGroup.kt +++ b/mirai-core/src/commonMain/kotlin/contact/roaming/RoamingMessagesImplGroup.kt @@ -30,6 +30,7 @@ internal class RoamingMessagesImplGroup( filter: RoamingMessageFilter? ): Flow { var currentSeq: Int = getLastMsgSeq() ?: return emptyFlow() + var lastOfferedSeq = -1 return flow { while (true) { @@ -52,10 +53,14 @@ internal class RoamingMessagesImplGroup( val maxTime = messageTimeSequence.max() - if (maxTime < timeStart) break // we have fetched all messages + + // we have fetched all messages + // note: maxTime = 0 means all fetched messages were recalled + if (maxTime < timeStart && maxTime != 0) break emitAll( resp.msgElem.asSequence() + .filter { lastOfferedSeq == -1 || it.msgHead.msgSeq < lastOfferedSeq } .filter { it.time in timeStart..timeEnd } .sortedByDescending { it.msgHead.msgSeq } // Ensure caller receiver newer messages first .filter { filter.apply(it) } // Call filter after sort @@ -63,7 +68,8 @@ internal class RoamingMessagesImplGroup( .map { listOf(it).toMessageChainOnline(bot, contact.id, MessageSourceKind.GROUP) } ) - currentSeq = resp.msgElem.minBy { it.time }.msgHead.msgSeq + currentSeq = resp.msgElem.first().msgHead.msgSeq + lastOfferedSeq = currentSeq } } } From b8321870aaa840674dff8d43e12f9d2db86a74ba Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Tue, 21 Mar 2023 23:08:06 +0800 Subject: [PATCH 10/13] [core] Code style & comments update --- .../kotlin/contact/roaming/RoamingMessagesImplGroup.kt | 2 +- .../protocol/impl/GeneralMessageSenderProtocol.kt | 9 ++++----- .../kotlin/message/protocol/impl/QuoteReplyProtocol.kt | 10 ++++------ 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/contact/roaming/RoamingMessagesImplGroup.kt b/mirai-core/src/commonMain/kotlin/contact/roaming/RoamingMessagesImplGroup.kt index db3310bc5e3..4745b299085 100644 --- a/mirai-core/src/commonMain/kotlin/contact/roaming/RoamingMessagesImplGroup.kt +++ b/mirai-core/src/commonMain/kotlin/contact/roaming/RoamingMessagesImplGroup.kt @@ -62,7 +62,7 @@ internal class RoamingMessagesImplGroup( resp.msgElem.asSequence() .filter { lastOfferedSeq == -1 || it.msgHead.msgSeq < lastOfferedSeq } .filter { it.time in timeStart..timeEnd } - .sortedByDescending { it.msgHead.msgSeq } // Ensure caller receiver newer messages first + .sortedByDescending { it.msgHead.msgSeq } // Ensure caller receives newer messages first .filter { filter.apply(it) } // Call filter after sort .asFlow() .map { listOf(it).toMessageChainOnline(bot, contact.id, MessageSourceKind.GROUP) } diff --git a/mirai-core/src/commonMain/kotlin/message/protocol/impl/GeneralMessageSenderProtocol.kt b/mirai-core/src/commonMain/kotlin/message/protocol/impl/GeneralMessageSenderProtocol.kt index c6872f8c069..3d0029abb39 100644 --- a/mirai-core/src/commonMain/kotlin/message/protocol/impl/GeneralMessageSenderProtocol.kt +++ b/mirai-core/src/commonMain/kotlin/message/protocol/impl/GeneralMessageSenderProtocol.kt @@ -71,6 +71,7 @@ internal class GeneralMessageSenderProtocol : MessageProtocol(PRIORITY_GENERAL_S fragmented = step == SendMessageStep.FRAGMENTED || currentMessageChain.contains(ForceAsFragmentedMessage) ) { source = it } + // Patch time to be actual server time var finalTime = bot.clock.server.currentTimeSeconds().toInt() val sendPacketOk = sendAllPackets(bot, step, contact, packets) { idx, rsp -> if (rsp is MessageSvcPbSendMsg.Response.SUCCESS) { @@ -102,8 +103,7 @@ internal class GeneralMessageSenderProtocol : MessageProtocol(PRIORITY_GENERAL_S packets.forEachIndexed { index, packet -> if (!sendSinglePacket( bot, packet, step, contact, - index, packetResponseConsumer - ) + ) { packetResponseConsumer(index, it) } ) return@sendAllPackets false } @@ -115,15 +115,14 @@ internal class GeneralMessageSenderProtocol : MessageProtocol(PRIORITY_GENERAL_S packet: OutgoingPacket, step: SendMessageStep, contact: Contact, - index: Int, - packetResponseConsumer: (Int, MessageSvcPbSendMsg.Response) -> Unit, + packetResponseConsumer: (MessageSvcPbSendMsg.Response) -> Unit, ): Boolean { val originalMessage = attributes[ORIGINAL_MESSAGE] val protocolStrategy = components[MessageProtocolStrategy] val finalMessage = currentMessageChain val resp = protocolStrategy.sendPacket(bot, packet) as MessageSvcPbSendMsg.Response - packetResponseConsumer(index, resp) + packetResponseConsumer(resp) if (resp is MessageSvcPbSendMsg.Response.MessageTooLarge) { logger.info { "STEP $step: message too large." } val next = step.nextStepOrNull() diff --git a/mirai-core/src/commonMain/kotlin/message/protocol/impl/QuoteReplyProtocol.kt b/mirai-core/src/commonMain/kotlin/message/protocol/impl/QuoteReplyProtocol.kt index ad4eda88e19..b73cfa4539a 100644 --- a/mirai-core/src/commonMain/kotlin/message/protocol/impl/QuoteReplyProtocol.kt +++ b/mirai-core/src/commonMain/kotlin/message/protocol/impl/QuoteReplyProtocol.kt @@ -157,22 +157,20 @@ internal class QuoteReplyProtocol : MessageProtocol(PRIORITY_METADATA) { markAsConsumed() collect(ImMsgBody.Elem(srcMsg = source.toJceData())) if (sourceCommon.kind == MessageSourceKind.GROUP) { - - @Suppress("RemoveExplicitTypeArguments") - val needPlusAt = sequence { + fun isPlusNeed(): Boolean { if (source is OnlineMessageSource.Incoming.FromGroup) { try { val sender0 = source.sender - yield(sender0 !is AnonymousMember) + return sender0 !is AnonymousMember } catch (_: IllegalStateException) { // Member not available now } } - yield(sourceCommon.fromId != 80000000L) + return sourceCommon.fromId != 80000000L // #2501 } - if (needPlusAt.first()) { + if (isPlusNeed()) { processAlso(At(sourceCommon.fromId)) // transformOneMessage(PlainText(" ")) From 89fa2f7ffb406ea2e7ea9d3465fe13e4f55c7dcf Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Fri, 24 Mar 2023 00:33:09 +0800 Subject: [PATCH 11/13] [core] Fix private message source target --- .../android/api/android.api | 21 ++-- .../compatibility-validation/jvm/api/jvm.api | 21 ++-- .../message/data/OnlineMessageSource.kt | 57 +++++++++-- .../message/source/incomingSourceImpl.kt | 96 +++++++++++++++++-- 4 files changed, 157 insertions(+), 38 deletions(-) diff --git a/mirai-core-api/compatibility-validation/android/api/android.api b/mirai-core-api/compatibility-validation/android/api/android.api index 1ccd73be6cc..1cbb1f9fc05 100644 --- a/mirai-core-api/compatibility-validation/android/api/android.api +++ b/mirai-core-api/compatibility-validation/android/api/android.api @@ -4817,10 +4817,9 @@ public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromFriend : net/mamoe/mirai/message/data/OnlineMessageSource$Incoming { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromFriend$Key; public abstract fun getSender ()Lnet/mamoe/mirai/contact/Friend; - public synthetic fun getSubject ()Lnet/mamoe/mirai/contact/Contact; - public final fun getSubject ()Lnet/mamoe/mirai/contact/Friend; - public final fun getTarget ()Lnet/mamoe/mirai/Bot; - public synthetic fun getTarget ()Lnet/mamoe/mirai/contact/ContactOrBot; + public abstract fun getSubject ()Lnet/mamoe/mirai/contact/Friend; + public final synthetic fun getTarget ()Lnet/mamoe/mirai/Bot; + public abstract fun getTarget ()Lnet/mamoe/mirai/contact/ContactOrBot; public final fun toString ()Ljava/lang/String; } @@ -4844,10 +4843,9 @@ public final class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$Fro public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromStranger : net/mamoe/mirai/message/data/OnlineMessageSource$Incoming { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromStranger$Key; public abstract fun getSender ()Lnet/mamoe/mirai/contact/Stranger; - public synthetic fun getSubject ()Lnet/mamoe/mirai/contact/Contact; - public final fun getSubject ()Lnet/mamoe/mirai/contact/Stranger; - public final fun getTarget ()Lnet/mamoe/mirai/Bot; - public synthetic fun getTarget ()Lnet/mamoe/mirai/contact/ContactOrBot; + public abstract fun getSubject ()Lnet/mamoe/mirai/contact/Stranger; + public final synthetic fun getTarget ()Lnet/mamoe/mirai/Bot; + public abstract fun getTarget ()Lnet/mamoe/mirai/contact/ContactOrBot; public final fun toString ()Ljava/lang/String; } @@ -4858,10 +4856,9 @@ public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$ public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromTemp$Key; public final fun getGroup ()Lnet/mamoe/mirai/contact/Group; public abstract fun getSender ()Lnet/mamoe/mirai/contact/Member; - public synthetic fun getSubject ()Lnet/mamoe/mirai/contact/Contact; - public final fun getSubject ()Lnet/mamoe/mirai/contact/Member; - public final fun getTarget ()Lnet/mamoe/mirai/Bot; - public synthetic fun getTarget ()Lnet/mamoe/mirai/contact/ContactOrBot; + public abstract fun getSubject ()Lnet/mamoe/mirai/contact/Member; + public final synthetic fun getTarget ()Lnet/mamoe/mirai/Bot; + public abstract fun getTarget ()Lnet/mamoe/mirai/contact/ContactOrBot; public final fun toString ()Ljava/lang/String; } diff --git a/mirai-core-api/compatibility-validation/jvm/api/jvm.api b/mirai-core-api/compatibility-validation/jvm/api/jvm.api index 9b3723b40fe..60293e0b71f 100644 --- a/mirai-core-api/compatibility-validation/jvm/api/jvm.api +++ b/mirai-core-api/compatibility-validation/jvm/api/jvm.api @@ -4817,10 +4817,9 @@ public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromFriend : net/mamoe/mirai/message/data/OnlineMessageSource$Incoming { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromFriend$Key; public abstract fun getSender ()Lnet/mamoe/mirai/contact/Friend; - public synthetic fun getSubject ()Lnet/mamoe/mirai/contact/Contact; - public final fun getSubject ()Lnet/mamoe/mirai/contact/Friend; - public final fun getTarget ()Lnet/mamoe/mirai/Bot; - public synthetic fun getTarget ()Lnet/mamoe/mirai/contact/ContactOrBot; + public abstract fun getSubject ()Lnet/mamoe/mirai/contact/Friend; + public final synthetic fun getTarget ()Lnet/mamoe/mirai/Bot; + public abstract fun getTarget ()Lnet/mamoe/mirai/contact/ContactOrBot; public final fun toString ()Ljava/lang/String; } @@ -4844,10 +4843,9 @@ public final class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$Fro public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromStranger : net/mamoe/mirai/message/data/OnlineMessageSource$Incoming { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromStranger$Key; public abstract fun getSender ()Lnet/mamoe/mirai/contact/Stranger; - public synthetic fun getSubject ()Lnet/mamoe/mirai/contact/Contact; - public final fun getSubject ()Lnet/mamoe/mirai/contact/Stranger; - public final fun getTarget ()Lnet/mamoe/mirai/Bot; - public synthetic fun getTarget ()Lnet/mamoe/mirai/contact/ContactOrBot; + public abstract fun getSubject ()Lnet/mamoe/mirai/contact/Stranger; + public final synthetic fun getTarget ()Lnet/mamoe/mirai/Bot; + public abstract fun getTarget ()Lnet/mamoe/mirai/contact/ContactOrBot; public final fun toString ()Ljava/lang/String; } @@ -4858,10 +4856,9 @@ public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$ public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromTemp$Key; public final fun getGroup ()Lnet/mamoe/mirai/contact/Group; public abstract fun getSender ()Lnet/mamoe/mirai/contact/Member; - public synthetic fun getSubject ()Lnet/mamoe/mirai/contact/Contact; - public final fun getSubject ()Lnet/mamoe/mirai/contact/Member; - public final fun getTarget ()Lnet/mamoe/mirai/Bot; - public synthetic fun getTarget ()Lnet/mamoe/mirai/contact/ContactOrBot; + public abstract fun getSubject ()Lnet/mamoe/mirai/contact/Member; + public final synthetic fun getTarget ()Lnet/mamoe/mirai/Bot; + public abstract fun getTarget ()Lnet/mamoe/mirai/contact/ContactOrBot; public final fun toString ()Ljava/lang/String; } diff --git a/mirai-core-api/src/commonMain/kotlin/message/data/OnlineMessageSource.kt b/mirai-core-api/src/commonMain/kotlin/message/data/OnlineMessageSource.kt index 95e3eb8e3a8..3dc0502e078 100644 --- a/mirai-core-api/src/commonMain/kotlin/message/data/OnlineMessageSource.kt +++ b/mirai-core-api/src/commonMain/kotlin/message/data/OnlineMessageSource.kt @@ -149,6 +149,9 @@ public sealed class OnlineMessageSource : MessageSource() { * 接收到的一条消息的 [MessageSource] */ public sealed class Incoming : OnlineMessageSource() { + /** + * 当 [sender] 为 [bot] 自身时为 bot 的对应表示 (如: [Bot.asFriend], [Bot.asStranger], [Group.botAsMember]) + */ public abstract override val sender: User /// NOTE: DONT use final to avoid contact not available @@ -160,9 +163,21 @@ public sealed class OnlineMessageSource : MessageSource() { public companion object Key : AbstractPolymorphicMessageKey(Incoming, { it.safeCast() }) + public abstract override val subject: Friend + + /** + * 当 [sender] 为 [bot] 自身时为 [Bot.asFriend] + */ public abstract override val sender: Friend - public final override val subject: Friend get() = sender - public final override val target: Bot get() = sender.bot + public abstract override val target: ContactOrBot + + @JvmName("getTarget") + @Deprecated("For ABI compatibility", level = DeprecationLevel.HIDDEN) + public fun getTargetLegacy(): Bot { + if (targetId == bot.id) return subject.bot + + error("Message target isn't bot; $this") + } final override fun toString(): String { return "[mirai:source:ids=${ids.contentToString()}, internalIds=${internalIds.contentToString()}, from friend $fromId to $targetId at $time]" @@ -174,10 +189,23 @@ public sealed class OnlineMessageSource : MessageSource() { public companion object Key : AbstractPolymorphicMessageKey(Incoming, { it.safeCast() }) + /** + * 当 [sender] 为 [bot] 自身时为 [Group.botAsMember] + */ public abstract override val sender: Member - public inline val group: Group get() = sender.group - public final override val subject: Member get() = sender - public final override val target: Bot get() = sender.bot + public abstract override val subject: Member + public abstract override val target: ContactOrBot + + public inline val group: Group get() = subject.group + + @JvmName("getTarget") + @Deprecated("For ABI compatibility", level = DeprecationLevel.HIDDEN) + public fun getTargetLegacy(): Bot { + if (targetId == bot.id) return subject.bot + + error("Message target isn't bot; $this") + } + final override fun toString(): String { return "[mirai:source:ids=${ids.contentToString()}, internalIds=${internalIds.contentToString()}, from group temp $fromId to $targetId at $time]" } @@ -188,9 +216,21 @@ public sealed class OnlineMessageSource : MessageSource() { public companion object Key : AbstractPolymorphicMessageKey(Incoming, { it.safeCast() }) + /** + * 当 [sender] 为 [bot] 自身时为 [Bot.asStranger] + */ public abstract override val sender: Stranger - public final override val subject: Stranger get() = sender - public final override val target: Bot get() = sender.bot + + public abstract override val subject: Stranger + public abstract override val target: ContactOrBot + + @JvmName("getTarget") + @Deprecated("For ABI compatibility", level = DeprecationLevel.HIDDEN) + public fun getTargetLegacy(): Bot { + if (targetId == bot.id) return subject.bot + + error("Message target isn't bot; $this") + } final override fun toString(): String { return "[mirai:source:ids=${ids.contentToString()}, internalIds=${internalIds.contentToString()}, from stranger $fromId to $targetId at $time]" @@ -202,6 +242,9 @@ public sealed class OnlineMessageSource : MessageSource() { public companion object Key : AbstractPolymorphicMessageKey(Incoming, { it.safeCast() }) + /** + * 当 [sender] 为 [bot] 自身时为 [Group.botAsMember] + */ public abstract override val sender: Member public override val subject: Group get() = sender.group public final override val target: Group get() = subject diff --git a/mirai-core/src/commonMain/kotlin/message/source/incomingSourceImpl.kt b/mirai-core/src/commonMain/kotlin/message/source/incomingSourceImpl.kt index 378204765dd..1f34a3f7731 100644 --- a/mirai-core/src/commonMain/kotlin/message/source/incomingSourceImpl.kt +++ b/mirai-core/src/commonMain/kotlin/message/source/incomingSourceImpl.kt @@ -16,6 +16,7 @@ import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializable import kotlinx.serialization.Transient import net.mamoe.mirai.Bot +import net.mamoe.mirai.contact.ContactOrBot import net.mamoe.mirai.contact.Friend import net.mamoe.mirai.contact.Member import net.mamoe.mirai.contact.Stranger @@ -44,7 +45,7 @@ import net.mamoe.mirai.utils.structureToString @Serializable(OnlineMessageSourceFromFriendImpl.Serializer::class) internal class OnlineMessageSourceFromFriendImpl( override val bot: Bot, - msg: List, + private val msg: List, ) : OnlineMessageSource.Incoming.FromFriend(), IncomingMessageSourceInternal { object Serializer : KSerializer by MessageSourceSerializerImpl("OnlineMessageSourceFromFriend") @@ -65,7 +66,35 @@ internal class OnlineMessageSourceFromFriendImpl( override val isOriginalMessageInitialized: Boolean get() = originalMessageLazy.isInitialized() - override val sender: Friend = bot.getFriendOrFail(msg.first().msgHead.fromUin) + override val sender: Friend by lazy { + if (fromId == bot.id) { + bot.asFriend + } else { + bot.getFriendOrFail(fromId) + } + } + + override val subject: Friend by lazy { + if (fromId == bot.id) { + bot.getFriendOrFail(targetId) + } else { + bot.getFriendOrFail(fromId) + } + } + override val fromId: Long + get() = msg.first().msgHead.fromUin + + override val targetId: Long + get() = msg.first().msgHead.toUin + + override val target: ContactOrBot by lazy { + if (fromId == bot.id) { + bot.getFriendOrFail(targetId) + } else { + bot + } + } + private val jceData: ImMsgBody.SourceMsg by lazy { msg.toJceDataPrivate(internalIds) } @@ -80,7 +109,7 @@ internal class OnlineMessageSourceFromFriendImpl( @Serializable(OnlineMessageSourceFromStrangerImpl.Serializer::class) internal class OnlineMessageSourceFromStrangerImpl( override val bot: Bot, - msg: List, + private val msg: List, ) : OnlineMessageSource.Incoming.FromStranger(), IncomingMessageSourceInternal { object Serializer : KSerializer by MessageSourceSerializerImpl("OnlineMessageSourceFromStranger") @@ -102,7 +131,35 @@ internal class OnlineMessageSourceFromStrangerImpl( override val isOriginalMessageInitialized: Boolean get() = originalMessageLazy.isInitialized() - override val sender: Stranger = bot.getStrangerOrFail(msg.first().msgHead.fromUin) + override val sender: Stranger by lazy { + if (fromId == bot.id) { + bot.asStranger + } else { + bot.getStrangerOrFail(fromId) + } + } + + override val subject: Stranger by lazy { + if (fromId == bot.id) { + bot.getStrangerOrFail(targetId) + } else { + bot.getStrangerOrFail(fromId) + } + } + + override val fromId: Long + get() = msg.first().msgHead.fromUin + + override val targetId: Long + get() = msg.first().msgHead.toUin + + override val target: ContactOrBot by lazy { + if (fromId == bot.id) { + bot.getStrangerOrFail(targetId) + } else { + bot + } + } private val jceData: ImMsgBody.SourceMsg by lazy { msg.toJceDataPrivate(internalIds) } @@ -166,7 +223,7 @@ internal fun MsgComm.Msg.decodeRandom(): Int { @Serializable(OnlineMessageSourceFromTempImpl.Serializer::class) internal class OnlineMessageSourceFromTempImpl( override val bot: Bot, - msg: List, + private val msg: List, ) : OnlineMessageSource.Incoming.FromTemp(), IncomingMessageSourceInternal { object Serializer : KSerializer by MessageSourceSerializerImpl("OnlineMessageSourceFromTemp") @@ -188,15 +245,40 @@ internal class OnlineMessageSourceFromTempImpl( override val isOriginalMessageInitialized: Boolean get() = originalMessageLazy.isInitialized() - override val sender: Member = with(msg.first().msgHead) { + @Suppress("PropertyName") + private val _group = with(msg.first().msgHead) { // it must be uin, see #1410 // corresponding test: net.mamoe.mirai.internal.notice.processors.MessageTest.group temp message test 2 // search for group code also is for tests. code may be passed as uin in tests. // clashing is unlikely possible in real time, so it would not be a problem. - bot.asQQAndroidBot().getGroupByUinOrCodeOrFail(c2cTmpMsgHead!!.groupUin).getOrFail(fromUin) + bot.asQQAndroidBot().getGroupByUinOrCodeOrFail(c2cTmpMsgHead!!.groupUin) + } + + override val sender: Member by lazy { + _group.getOrFail(fromId) + } + + override val target: ContactOrBot by lazy { + if (fromId == botId) { + _group.getOrFail(targetId) + } else bot } + override val subject: Member by lazy { + if (fromId == botId) { + _group.getOrFail(targetId) + } else { + _group.getOrFail(fromId) + } + } + + override val fromId: Long + get() = msg.first().msgHead.fromUin + override val targetId: Long + get() = msg.first().msgHead.toUin + + private val jceData: ImMsgBody.SourceMsg by lazy { msg.toJceDataPrivate(internalIds) } override fun toJceData(): ImMsgBody.SourceMsg = jceData From 9c77c22b3276be0f3a6ab732e6a936f7fdbb0a54 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Fri, 24 Mar 2023 12:18:53 +0800 Subject: [PATCH 12/13] [core] Mock private message source implementation --- .../src/internal/contact/MockFriendImpl.kt | 2 +- .../src/internal/contact/MockStrangerImpl.kt | 2 +- .../src/internal/msgsrc/OnlineMsgSrc.kt | 27 ++++++++++++++++--- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/mirai-core-mock/src/internal/contact/MockFriendImpl.kt b/mirai-core-mock/src/internal/contact/MockFriendImpl.kt index 1d51ed53307..5f0f022f7c6 100644 --- a/mirai-core-mock/src/internal/contact/MockFriendImpl.kt +++ b/mirai-core-mock/src/internal/contact/MockFriendImpl.kt @@ -124,7 +124,7 @@ internal class MockFriendImpl( override suspend fun says(message: MessageChain): MessageChain { val src = newMsgSrc(true, message) { ids, internalIds, time -> - OnlineMsgSrcFromFriend(ids, internalIds, time, message, bot, this) + OnlineMsgSrcFromFriend(ids, internalIds, time, message, bot, this, bot) } val msg = src.withMessage(message) FriendMessageEvent(this, msg, src.time).broadcast() diff --git a/mirai-core-mock/src/internal/contact/MockStrangerImpl.kt b/mirai-core-mock/src/internal/contact/MockStrangerImpl.kt index 77e4d496c5c..076e46e3019 100644 --- a/mirai-core-mock/src/internal/contact/MockStrangerImpl.kt +++ b/mirai-core-mock/src/internal/contact/MockStrangerImpl.kt @@ -87,7 +87,7 @@ internal class MockStrangerImpl( override suspend fun says(message: MessageChain): MessageChain { val src = newMsgSrc(true, message) { ids, internalIds, time -> - OnlineMsgSrcFromStranger(ids, internalIds, time, message, bot, this) + OnlineMsgSrcFromStranger(ids, internalIds, time, message, bot, this, bot) } val msg = src.withMessage(message) StrangerMessageEvent(this, msg, src.time).broadcast() diff --git a/mirai-core-mock/src/internal/msgsrc/OnlineMsgSrc.kt b/mirai-core-mock/src/internal/msgsrc/OnlineMsgSrc.kt index 32fe770b694..8dc774a5410 100644 --- a/mirai-core-mock/src/internal/msgsrc/OnlineMsgSrc.kt +++ b/mirai-core-mock/src/internal/msgsrc/OnlineMsgSrc.kt @@ -23,6 +23,7 @@ import net.mamoe.mirai.message.MessageSerializers import net.mamoe.mirai.message.data.* import net.mamoe.mirai.mock.internal.contact.AbstractMockContact import net.mamoe.mirai.mock.internal.contact.MockImage +import net.mamoe.mirai.utils.cast import net.mamoe.mirai.utils.currentTimeSeconds internal fun registerMockMsgSerializers() { @@ -174,10 +175,17 @@ internal class OnlineMsgSrcFromFriend( override val time: Int, override val originalMessage: MessageChain, override val bot: Bot, - override val sender: Friend + override val sender: Friend, + override val target: ContactOrBot, ) : OnlineMessageSource.Incoming.FromFriend() { override val isOriginalMessageInitialized: Boolean get() = true + override val subject: Friend + get() { + if (target is Bot) return sender + return target.cast() + } + object Serializer : KSerializer by MessageSourceSerializerImpl("Mock_OnlineMessageSourceFromFriend") } @@ -189,10 +197,17 @@ internal class OnlineMsgSrcFromStranger( override val time: Int, override val originalMessage: MessageChain, override val bot: Bot, - override val sender: Stranger + override val sender: Stranger, + override val target: ContactOrBot, ) : OnlineMessageSource.Incoming.FromStranger() { override val isOriginalMessageInitialized: Boolean get() = true + override val subject: Stranger + get() { + if (target is Bot) return sender + return target.cast() + } + object Serializer : KSerializer by MessageSourceSerializerImpl( "Mock_OnlineMessageSourceFromStranger" ) @@ -206,9 +221,15 @@ internal class OnlineMsgSrcFromTemp( override val time: Int, override val originalMessage: MessageChain, override val bot: Bot, - override val sender: Member + override val sender: Member, + override val target: ContactOrBot, ) : OnlineMessageSource.Incoming.FromTemp() { override val isOriginalMessageInitialized: Boolean get() = true + override val subject: Member + get() { + if (target is Bot) return sender + return target.cast() + } object Serializer : KSerializer by MessageSourceSerializerImpl("Mock_OnlineMessageSourceFromTemp") From 893fb3e9f653623056f9c4bff73b4dac957cd2a2 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Fri, 24 Mar 2023 16:27:47 +0800 Subject: [PATCH 13/13] [core] Make `MessageSource.kind` a member not extension --- .../android/api/android.api | 13 +++++-- .../compatibility-validation/jvm/api/jvm.api | 13 +++++-- .../kotlin/message/data/MessageSource.kt | 35 +++++++++---------- .../message/data/OfflineMessageSource.kt | 2 +- .../message/data/OnlineMessageSource.kt | 16 +++++++++ 5 files changed, 56 insertions(+), 23 deletions(-) diff --git a/mirai-core-api/compatibility-validation/android/api/android.api b/mirai-core-api/compatibility-validation/android/api/android.api index 1cbb1f9fc05..3e2d2df899d 100644 --- a/mirai-core-api/compatibility-validation/android/api/android.api +++ b/mirai-core-api/compatibility-validation/android/api/android.api @@ -4540,6 +4540,7 @@ public abstract class net/mamoe/mirai/message/data/MessageSource : net/mamoe/mir public abstract fun getIds ()[I public abstract fun getInternalIds ()[I public final fun getKey ()Lnet/mamoe/mirai/message/data/MessageKey; + public abstract fun getKind ()Lnet/mamoe/mirai/message/data/MessageSourceKind; public abstract fun getOriginalMessage ()Lnet/mamoe/mirai/message/data/MessageChain; public abstract fun getTargetId ()J public abstract fun getTime ()I @@ -4666,8 +4667,8 @@ public final class net/mamoe/mirai/message/data/MessageUtils { public static final synthetic fun getContent (Lnet/mamoe/mirai/message/data/Message;)Ljava/lang/String; public static final synthetic fun getIds (Lnet/mamoe/mirai/message/data/MessageChain;)[I public static final synthetic fun getInternalId (Lnet/mamoe/mirai/message/data/MessageChain;)[I - public static final fun getKind (Lnet/mamoe/mirai/message/data/MessageSource;)Lnet/mamoe/mirai/message/data/MessageSourceKind; - public static final fun getKind (Lnet/mamoe/mirai/message/data/OnlineMessageSource;)Lnet/mamoe/mirai/message/data/MessageSourceKind; + public static final synthetic fun getKind (Lnet/mamoe/mirai/message/data/MessageSource;)Lnet/mamoe/mirai/message/data/MessageSourceKind; + public static final synthetic fun getKind (Lnet/mamoe/mirai/message/data/OnlineMessageSource;)Lnet/mamoe/mirai/message/data/MessageSourceKind; public static final synthetic fun getLengthDuration (Lnet/mamoe/mirai/message/data/OnlineAudio;)J public static final synthetic fun getOrFail (Lnet/mamoe/mirai/message/data/MessageChain;Lnet/mamoe/mirai/message/data/MessageKey;Lkotlin/jvm/functions/Function1;)Lnet/mamoe/mirai/message/data/SingleMessage; public static synthetic fun getOrFail$default (Lnet/mamoe/mirai/message/data/MessageChain;Lnet/mamoe/mirai/message/data/MessageKey;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lnet/mamoe/mirai/message/data/SingleMessage; @@ -4816,6 +4817,7 @@ public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromFriend : net/mamoe/mirai/message/data/OnlineMessageSource$Incoming { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromFriend$Key; + public final fun getKind ()Lnet/mamoe/mirai/message/data/MessageSourceKind; public abstract fun getSender ()Lnet/mamoe/mirai/contact/Friend; public abstract fun getSubject ()Lnet/mamoe/mirai/contact/Friend; public final synthetic fun getTarget ()Lnet/mamoe/mirai/Bot; @@ -4829,6 +4831,7 @@ public final class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$Fro public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromGroup : net/mamoe/mirai/message/data/OnlineMessageSource$Incoming { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromGroup$Key; public final fun getGroup ()Lnet/mamoe/mirai/contact/Group; + public final fun getKind ()Lnet/mamoe/mirai/message/data/MessageSourceKind; public abstract fun getSender ()Lnet/mamoe/mirai/contact/Member; public synthetic fun getSubject ()Lnet/mamoe/mirai/contact/Contact; public fun getSubject ()Lnet/mamoe/mirai/contact/Group; @@ -4842,6 +4845,7 @@ public final class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$Fro public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromStranger : net/mamoe/mirai/message/data/OnlineMessageSource$Incoming { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromStranger$Key; + public final fun getKind ()Lnet/mamoe/mirai/message/data/MessageSourceKind; public abstract fun getSender ()Lnet/mamoe/mirai/contact/Stranger; public abstract fun getSubject ()Lnet/mamoe/mirai/contact/Stranger; public final synthetic fun getTarget ()Lnet/mamoe/mirai/Bot; @@ -4855,6 +4859,7 @@ public final class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$Fro public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromTemp : net/mamoe/mirai/message/data/OnlineMessageSource$Incoming { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromTemp$Key; public final fun getGroup ()Lnet/mamoe/mirai/contact/Group; + public final fun getKind ()Lnet/mamoe/mirai/message/data/MessageSourceKind; public abstract fun getSender ()Lnet/mamoe/mirai/contact/Member; public abstract fun getSubject ()Lnet/mamoe/mirai/contact/Member; public final synthetic fun getTarget ()Lnet/mamoe/mirai/Bot; @@ -4884,6 +4889,7 @@ public final class net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$Key public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToFriend : net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToFriend$Key; + public final fun getKind ()Lnet/mamoe/mirai/message/data/MessageSourceKind; public synthetic fun getSubject ()Lnet/mamoe/mirai/contact/Contact; public final fun getSubject ()Lnet/mamoe/mirai/contact/Friend; public abstract fun getTarget ()Lnet/mamoe/mirai/contact/Friend; @@ -4895,6 +4901,7 @@ public final class net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToF public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToGroup : net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToGroup$Key; + public final fun getKind ()Lnet/mamoe/mirai/message/data/MessageSourceKind; public synthetic fun getSubject ()Lnet/mamoe/mirai/contact/Contact; public final fun getSubject ()Lnet/mamoe/mirai/contact/Group; public abstract fun getTarget ()Lnet/mamoe/mirai/contact/Group; @@ -4906,6 +4913,7 @@ public final class net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToG public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToStranger : net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToStranger$Key; + public final fun getKind ()Lnet/mamoe/mirai/message/data/MessageSourceKind; public synthetic fun getSubject ()Lnet/mamoe/mirai/contact/Contact; public final fun getSubject ()Lnet/mamoe/mirai/contact/Stranger; public abstract fun getTarget ()Lnet/mamoe/mirai/contact/Stranger; @@ -4918,6 +4926,7 @@ public final class net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToS public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToTemp : net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToTemp$Key; public final fun getGroup ()Lnet/mamoe/mirai/contact/Group; + public final fun getKind ()Lnet/mamoe/mirai/message/data/MessageSourceKind; public synthetic fun getSubject ()Lnet/mamoe/mirai/contact/Contact; public final fun getSubject ()Lnet/mamoe/mirai/contact/Member; public abstract fun getTarget ()Lnet/mamoe/mirai/contact/Member; diff --git a/mirai-core-api/compatibility-validation/jvm/api/jvm.api b/mirai-core-api/compatibility-validation/jvm/api/jvm.api index 60293e0b71f..9edc7b3cd70 100644 --- a/mirai-core-api/compatibility-validation/jvm/api/jvm.api +++ b/mirai-core-api/compatibility-validation/jvm/api/jvm.api @@ -4540,6 +4540,7 @@ public abstract class net/mamoe/mirai/message/data/MessageSource : net/mamoe/mir public abstract fun getIds ()[I public abstract fun getInternalIds ()[I public final fun getKey ()Lnet/mamoe/mirai/message/data/MessageKey; + public abstract fun getKind ()Lnet/mamoe/mirai/message/data/MessageSourceKind; public abstract fun getOriginalMessage ()Lnet/mamoe/mirai/message/data/MessageChain; public abstract fun getTargetId ()J public abstract fun getTime ()I @@ -4666,8 +4667,8 @@ public final class net/mamoe/mirai/message/data/MessageUtils { public static final synthetic fun getContent (Lnet/mamoe/mirai/message/data/Message;)Ljava/lang/String; public static final synthetic fun getIds (Lnet/mamoe/mirai/message/data/MessageChain;)[I public static final synthetic fun getInternalId (Lnet/mamoe/mirai/message/data/MessageChain;)[I - public static final fun getKind (Lnet/mamoe/mirai/message/data/MessageSource;)Lnet/mamoe/mirai/message/data/MessageSourceKind; - public static final fun getKind (Lnet/mamoe/mirai/message/data/OnlineMessageSource;)Lnet/mamoe/mirai/message/data/MessageSourceKind; + public static final synthetic fun getKind (Lnet/mamoe/mirai/message/data/MessageSource;)Lnet/mamoe/mirai/message/data/MessageSourceKind; + public static final synthetic fun getKind (Lnet/mamoe/mirai/message/data/OnlineMessageSource;)Lnet/mamoe/mirai/message/data/MessageSourceKind; public static final synthetic fun getLengthDuration (Lnet/mamoe/mirai/message/data/OnlineAudio;)J public static final synthetic fun getOrFail (Lnet/mamoe/mirai/message/data/MessageChain;Lnet/mamoe/mirai/message/data/MessageKey;Lkotlin/jvm/functions/Function1;)Lnet/mamoe/mirai/message/data/SingleMessage; public static synthetic fun getOrFail$default (Lnet/mamoe/mirai/message/data/MessageChain;Lnet/mamoe/mirai/message/data/MessageKey;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lnet/mamoe/mirai/message/data/SingleMessage; @@ -4816,6 +4817,7 @@ public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromFriend : net/mamoe/mirai/message/data/OnlineMessageSource$Incoming { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromFriend$Key; + public final fun getKind ()Lnet/mamoe/mirai/message/data/MessageSourceKind; public abstract fun getSender ()Lnet/mamoe/mirai/contact/Friend; public abstract fun getSubject ()Lnet/mamoe/mirai/contact/Friend; public final synthetic fun getTarget ()Lnet/mamoe/mirai/Bot; @@ -4829,6 +4831,7 @@ public final class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$Fro public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromGroup : net/mamoe/mirai/message/data/OnlineMessageSource$Incoming { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromGroup$Key; public final fun getGroup ()Lnet/mamoe/mirai/contact/Group; + public final fun getKind ()Lnet/mamoe/mirai/message/data/MessageSourceKind; public abstract fun getSender ()Lnet/mamoe/mirai/contact/Member; public synthetic fun getSubject ()Lnet/mamoe/mirai/contact/Contact; public fun getSubject ()Lnet/mamoe/mirai/contact/Group; @@ -4842,6 +4845,7 @@ public final class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$Fro public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromStranger : net/mamoe/mirai/message/data/OnlineMessageSource$Incoming { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromStranger$Key; + public final fun getKind ()Lnet/mamoe/mirai/message/data/MessageSourceKind; public abstract fun getSender ()Lnet/mamoe/mirai/contact/Stranger; public abstract fun getSubject ()Lnet/mamoe/mirai/contact/Stranger; public final synthetic fun getTarget ()Lnet/mamoe/mirai/Bot; @@ -4855,6 +4859,7 @@ public final class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$Fro public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromTemp : net/mamoe/mirai/message/data/OnlineMessageSource$Incoming { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Incoming$FromTemp$Key; public final fun getGroup ()Lnet/mamoe/mirai/contact/Group; + public final fun getKind ()Lnet/mamoe/mirai/message/data/MessageSourceKind; public abstract fun getSender ()Lnet/mamoe/mirai/contact/Member; public abstract fun getSubject ()Lnet/mamoe/mirai/contact/Member; public final synthetic fun getTarget ()Lnet/mamoe/mirai/Bot; @@ -4884,6 +4889,7 @@ public final class net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$Key public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToFriend : net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToFriend$Key; + public final fun getKind ()Lnet/mamoe/mirai/message/data/MessageSourceKind; public synthetic fun getSubject ()Lnet/mamoe/mirai/contact/Contact; public final fun getSubject ()Lnet/mamoe/mirai/contact/Friend; public abstract fun getTarget ()Lnet/mamoe/mirai/contact/Friend; @@ -4895,6 +4901,7 @@ public final class net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToF public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToGroup : net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToGroup$Key; + public final fun getKind ()Lnet/mamoe/mirai/message/data/MessageSourceKind; public synthetic fun getSubject ()Lnet/mamoe/mirai/contact/Contact; public final fun getSubject ()Lnet/mamoe/mirai/contact/Group; public abstract fun getTarget ()Lnet/mamoe/mirai/contact/Group; @@ -4906,6 +4913,7 @@ public final class net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToG public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToStranger : net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToStranger$Key; + public final fun getKind ()Lnet/mamoe/mirai/message/data/MessageSourceKind; public synthetic fun getSubject ()Lnet/mamoe/mirai/contact/Contact; public final fun getSubject ()Lnet/mamoe/mirai/contact/Stranger; public abstract fun getTarget ()Lnet/mamoe/mirai/contact/Stranger; @@ -4918,6 +4926,7 @@ public final class net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToS public abstract class net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToTemp : net/mamoe/mirai/message/data/OnlineMessageSource$Outgoing { public static final field Key Lnet/mamoe/mirai/message/data/OnlineMessageSource$Outgoing$ToTemp$Key; public final fun getGroup ()Lnet/mamoe/mirai/contact/Group; + public final fun getKind ()Lnet/mamoe/mirai/message/data/MessageSourceKind; public synthetic fun getSubject ()Lnet/mamoe/mirai/contact/Contact; public final fun getSubject ()Lnet/mamoe/mirai/contact/Member; public abstract fun getTarget ()Lnet/mamoe/mirai/contact/Member; diff --git a/mirai-core-api/src/commonMain/kotlin/message/data/MessageSource.kt b/mirai-core-api/src/commonMain/kotlin/message/data/MessageSource.kt index 682404e57e2..1f165944096 100644 --- a/mirai-core-api/src/commonMain/kotlin/message/data/MessageSource.kt +++ b/mirai-core-api/src/commonMain/kotlin/message/data/MessageSource.kt @@ -207,6 +207,13 @@ public sealed class MessageSource : Message, MessageMetadata, ConstrainSingle { */ public abstract val isOriginalMessageInitialized: Boolean + /** + * 消息种类 + * + * @since 2.15 + */ + public abstract val kind: MessageSourceKind + public abstract override fun toString(): String @MiraiInternalApi @@ -376,26 +383,18 @@ public enum class MessageSourceKind { STRANGER } -/** - * 获取 [MessageSourceKind] +/* + public static final net.mamoe.mirai.message.data.MessageSourceKind getKind(net.mamoe.mirai.message.data.MessageSource); + public static final net.mamoe.mirai.message.data.MessageSourceKind getKind(net.mamoe.mirai.message.data.OnlineMessageSource); */ -public val MessageSource.kind: MessageSourceKind - get() = when (this) { - is OnlineMessageSource -> kind - is OfflineMessageSource -> kind - } +@JvmName("getKind") +@Deprecated("For ABI compatibility", level = DeprecationLevel.HIDDEN) +public fun getKindLegacy(source: MessageSource): MessageSourceKind = source.kind + +@JvmName("getKind") +@Deprecated("For ABI compatibility", level = DeprecationLevel.HIDDEN) +public fun getKindLegacy(source: OnlineMessageSource): MessageSourceKind = source.kind -/** - * 获取 [MessageSourceKind] - */ -public val OnlineMessageSource.kind: MessageSourceKind - get() = when (subject) { - is Group -> MessageSourceKind.GROUP - is Friend -> MessageSourceKind.FRIEND - is Member -> MessageSourceKind.TEMP - is Stranger -> MessageSourceKind.STRANGER - else -> error("Internal error: OnlineMessageSource.kind reached an unexpected clause, subject=$subject") - } // For MessageChain, no need to expose to Java. diff --git a/mirai-core-api/src/commonMain/kotlin/message/data/OfflineMessageSource.kt b/mirai-core-api/src/commonMain/kotlin/message/data/OfflineMessageSource.kt index a9bd126a15c..3719c3debbb 100644 --- a/mirai-core-api/src/commonMain/kotlin/message/data/OfflineMessageSource.kt +++ b/mirai-core-api/src/commonMain/kotlin/message/data/OfflineMessageSource.kt @@ -37,7 +37,7 @@ public abstract class OfflineMessageSource : MessageSource() { /** * 消息种类 */ - public abstract val kind: MessageSourceKind + public abstract override val kind: MessageSourceKind final override fun toString(): String { return "[mirai:source:ids=${ids.contentToString()}, internalIds=${internalIds.contentToString()}, from $fromId to $targetId at $time]" diff --git a/mirai-core-api/src/commonMain/kotlin/message/data/OnlineMessageSource.kt b/mirai-core-api/src/commonMain/kotlin/message/data/OnlineMessageSource.kt index 3dc0502e078..19590bbacf5 100644 --- a/mirai-core-api/src/commonMain/kotlin/message/data/OnlineMessageSource.kt +++ b/mirai-core-api/src/commonMain/kotlin/message/data/OnlineMessageSource.kt @@ -101,6 +101,8 @@ public sealed class OnlineMessageSource : MessageSource() { public abstract override val target: Friend public final override val subject: Friend get() = target + final override val kind: MessageSourceKind get() = MessageSourceKind.FRIEND + final override fun toString(): String { return "[mirai:source:ids=${ids.contentToString()}, internalIds=${internalIds.contentToString()}, from $fromId to friend $targetId at $time]" } @@ -114,6 +116,8 @@ public sealed class OnlineMessageSource : MessageSource() { public abstract override val target: Stranger public final override val subject: Stranger get() = target + final override val kind: MessageSourceKind get() = MessageSourceKind.STRANGER + final override fun toString(): String { return "[mirai:source:ids=${ids.contentToString()}, internalIds=${internalIds.contentToString()}, from $fromId to stranger $targetId at $time]" } @@ -127,6 +131,8 @@ public sealed class OnlineMessageSource : MessageSource() { public val group: Group get() = target.group public final override val subject: Member get() = target + final override val kind: MessageSourceKind get() = MessageSourceKind.TEMP + final override fun toString(): String { return "[mirai:source:ids=${ids.contentToString()}, internalIds=${internalIds.contentToString()}, from $fromId to group temp $targetId at $time]" } @@ -139,6 +145,8 @@ public sealed class OnlineMessageSource : MessageSource() { public abstract override val target: Group public final override val subject: Group get() = target + final override val kind: MessageSourceKind get() = MessageSourceKind.GROUP + final override fun toString(): String { return "[mirai:source:ids=${ids.contentToString()}, internalIds=${internalIds.contentToString()}, from $fromId to group $targetId at $time]" } @@ -179,6 +187,8 @@ public sealed class OnlineMessageSource : MessageSource() { error("Message target isn't bot; $this") } + final override val kind: MessageSourceKind get() = MessageSourceKind.FRIEND + final override fun toString(): String { return "[mirai:source:ids=${ids.contentToString()}, internalIds=${internalIds.contentToString()}, from friend $fromId to $targetId at $time]" } @@ -206,6 +216,8 @@ public sealed class OnlineMessageSource : MessageSource() { error("Message target isn't bot; $this") } + final override val kind: MessageSourceKind get() = MessageSourceKind.TEMP + final override fun toString(): String { return "[mirai:source:ids=${ids.contentToString()}, internalIds=${internalIds.contentToString()}, from group temp $fromId to $targetId at $time]" } @@ -232,6 +244,8 @@ public sealed class OnlineMessageSource : MessageSource() { error("Message target isn't bot; $this") } + final override val kind: MessageSourceKind get() = MessageSourceKind.STRANGER + final override fun toString(): String { return "[mirai:source:ids=${ids.contentToString()}, internalIds=${internalIds.contentToString()}, from stranger $fromId to $targetId at $time]" } @@ -250,6 +264,8 @@ public sealed class OnlineMessageSource : MessageSource() { public final override val target: Group get() = subject public inline val group: Group get() = subject + final override val kind: MessageSourceKind get() = MessageSourceKind.GROUP + final override fun toString(): String { return "[mirai:source:ids=${ids.contentToString()}, internalIds=${internalIds.contentToString()}, from group $fromId to $targetId at $time]" }