Bläddra i källkod

Fix sequenceId for FriendMessage

Him188 6 år sedan
förälder
incheckning
6cbc69cd68

+ 1 - 1
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt

@@ -542,7 +542,7 @@ internal class GroupImpl(
         if (event.isCancelled) {
             throw EventCancelledException("cancelled by FriendMessageSendEvent")
         }
-        lateinit var source: MessageSvc.PbSendMsg.MessageSourceFromSend
+        lateinit var source: MessageSvc.PbSendMsg.MessageSourceFromSendGroup
         bot.network.run {
             val response: MessageSvc.PbSendMsg.Response = MessageSvc.PbSendMsg.ToGroup(
                 bot.client,

+ 7 - 1
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt

@@ -129,9 +129,15 @@ internal abstract class QQAndroidBotBase constructor(
         source.ensureSequenceIdAvailable()
 
         network.run {
-            val response: PbMessageSvc.PbMsgWithDraw.Response =
+            val response: PbMessageSvc.PbMsgWithDraw.Response = if (source.groupId == 0L) {
+                PbMessageSvc.PbMsgWithDraw.Friend(bot.client, source.senderId, source.sequenceId, source.messageRandom, source.time)
+                    .sendAndExpect()
+            } else {
+
                 PbMessageSvc.PbMsgWithDraw.Group(bot.client, source.groupId, source.sequenceId, source.messageRandom)
                     .sendAndExpect()
+            }
+
             check(response is PbMessageSvc.PbMsgWithDraw.Response.Success) { "Failed to recall message #${source.sequenceId}: $response" }
         }
     }

+ 29 - 0
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/PbMessageSvc.kt

@@ -71,6 +71,35 @@ internal class PbMessageSvc {
             )
         }
 
+        fun Friend(
+            client: QQAndroidClient,
+            toUin: Long,
+            messageSequenceId: Int, // 56639
+            messageRandom: Int, // 921878719
+            time: Long,
+            messageType: Int = 0
+        ): OutgoingPacket = buildOutgoingUniPacket(client) {
+            writeProtoBuf(
+                MsgSvc.PbMsgWithDrawReq.serializer(),
+                MsgSvc.PbMsgWithDrawReq(
+                    c2cWithDraw = listOf(
+                        MsgSvc.PbC2CMsgWithDrawReq(
+                            subCmd = 1,
+                            msgInfo = listOf(
+                                MsgSvc.PbC2CMsgWithDrawReq.MsgInfo(
+                                    fromUin = client.bot.uin,
+                                    toUin = toUin,
+                                    msgSeq = messageSequenceId,
+                                    msgUid = messageRandom.toLong() and 0xffffffff,
+                                    msgTime = time and 0xffffffff
+                                )
+                            )
+                        )
+                    )
+                )
+            )
+        }
+
         override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
             val resp = readProtoBuf(MsgSvc.PbMsgWithDrawResp.serializer())
             resp.groupWithDraw?.firstOrNull()?.let {

+ 32 - 11
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt

@@ -269,7 +269,28 @@ internal class MessageSvc {
             }
         }
 
-        internal class MessageSourceFromSend(
+        internal class MessageSourceFromSendFriend(
+            val messageRandom: Int,
+            override val time: Long,
+            override val senderId: Long,
+            override val groupId: Long,
+            val sequenceId: Int
+        ) : MessageSource {
+            @UseExperimental(ExperimentalCoroutinesApi::class)
+            override val id: Long
+                get() = sequenceId.toLong().shl(32) or
+                        messageRandom.toLong().and(0xFFFFFFFF)
+
+            override suspend fun ensureSequenceIdAvailable() {
+                // nothing to do
+            }
+
+            override fun toString(): String {
+                return ""
+            }
+        }
+
+        internal class MessageSourceFromSendGroup(
             val messageRandom: Int,
             override val time: Long,
             override val senderId: Long,
@@ -286,7 +307,7 @@ internal class MessageSvc {
             @UseExperimental(MiraiExperimentalAPI::class)
             fun startWaitingSequenceId(contact: Contact) {
                 sequenceIdDeferred = contact.subscribingGetAsync<OnlinePush.PbPushGroupMsg.SendGroupMessageReceipt, Int>(timeoutMillis = 3000) {
-                    if (it.messageRandom == [email protected]) {
+                    if (it.messageRandom == this@MessageSourceFromSendGroup.messageRandom) {
                         it.sequenceId
                     } else null
                 }
@@ -305,14 +326,14 @@ internal class MessageSvc {
             client: QQAndroidClient,
             toUin: Long,
             message: MessageChain,
-            crossinline sourceCallback: (MessageSource) -> Unit
+            crossinline sourceCallback: (MessageSourceFromSendFriend) -> Unit
         ): OutgoingPacket {
-            val source = MessageSourceFromSend(
+            val source = MessageSourceFromSendFriend(
                 messageRandom = Random.nextInt().absoluteValue,
                 senderId = client.uin,
                 time = currentTimeSeconds + client.timeDifference,
-                groupId = 0//
-                //   sourceMessage = message
+                groupId = 0,
+                sequenceId = client.atomicNextMessageSequenceId()
             )
             sourceCallback(source)
             return ToFriend(client, toUin, message, source)
@@ -326,7 +347,7 @@ internal class MessageSvc {
             client: QQAndroidClient,
             toUin: Long,
             message: MessageChain,
-            source: MessageSourceFromSend
+            source: MessageSourceFromSendFriend
         ): OutgoingPacket = buildOutgoingUniPacket(client) {
             ///writeFully("0A 08 0A 06 08 89 FC A6 8C 0B 12 06 08 01 10 00 18 00 1A 1F 0A 1D 12 08 0A 06 0A 04 F0 9F 92 A9 12 11 AA 02 0E 88 01 00 9A 01 08 78 00 F8 01 00 C8 02 00 20 9B 7A 28 F4 CA 9B B8 03 32 34 08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00 40 01".hexToBytes())
 
@@ -340,7 +361,7 @@ internal class MessageSvc {
                             elems = message.toRichTextElems(false)
                         )
                     ),
-                    msgSeq = client.atomicNextMessageSequenceId(),
+                    msgSeq = source.sequenceId,
                     msgRand = source.messageRandom,
                     syncCookie = SyncCookie(time = source.time).toByteArray(SyncCookie.serializer())
                     // msgVia = 1
@@ -353,10 +374,10 @@ internal class MessageSvc {
             client: QQAndroidClient,
             groupCode: Long,
             message: MessageChain,
-            sourceCallback: (MessageSourceFromSend) -> Unit
+            sourceCallback: (MessageSourceFromSendGroup) -> Unit
         ): OutgoingPacket {
 
-            val source = MessageSourceFromSend(
+            val source = MessageSourceFromSendGroup(
                 messageRandom = Random.nextInt().absoluteValue,
                 senderId = client.uin,
                 time = currentTimeSeconds + client.timeDifference,
@@ -375,7 +396,7 @@ internal class MessageSvc {
             client: QQAndroidClient,
             groupCode: Long,
             message: MessageChain,
-            source: MessageSourceFromSend
+            source: MessageSourceFromSendGroup
         ): OutgoingPacket = buildOutgoingUniPacket(client) {
             ///writeFully("0A 08 0A 06 08 89 FC A6 8C 0B 12 06 08 01 10 00 18 00 1A 1F 0A 1D 12 08 0A 06 0A 04 F0 9F 92 A9 12 11 AA 02 0E 88 01 00 9A 01 08 78 00 F8 01 00 C8 02 00 20 9B 7A 28 F4 CA 9B B8 03 32 34 08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00 40 01".hexToBytes())
 

+ 3 - 7
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageReceipt.kt

@@ -78,13 +78,9 @@ open class MessageReceipt<C : Contact>(
     fun recallIn(millis: Long): Job {
         @Suppress("BooleanLiteralArgument")
         if (_isRecalled.compareAndSet(false, true)) {
-            when (val contact = target) {
-                is Group -> {
-                    return contact.bot.recallIn(source, millis)
-                }
-                is QQ -> {
-                    TODO()
-                }
+            return when (val contact = target) {
+                is QQ,
+                is Group -> contact.bot.recallIn(source, millis)
                 else -> error("Unknown contact type")
             }
         } else error("message is already or planned to be recalled")