From 8e3fb15556c8afb217c709103ab788d1fbaa214b Mon Sep 17 00:00:00 2001 From: mzdluo123 Date: Fri, 21 Aug 2020 17:57:34 +0800 Subject: [PATCH] Fix receiving messages repeatedly --- .../network/protocol/data/proto/MsgSvc.kt | 2 +- .../chat/receive/MessageSvc.PbGetMsg.kt | 67 ++++++++++++++----- 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgSvc.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgSvc.kt index 0f07c98a5..f357e0af6 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgSvc.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgSvc.kt @@ -19,7 +19,7 @@ internal class MsgSvc : ProtoBuf { @ProtoNumber(1) @JvmField val result: Int = 0, @ProtoNumber(2) @JvmField val errmsg: String = "", @ProtoNumber(3) @JvmField val syncCookie: ByteArray? = EMPTY_BYTE_ARRAY, - @ProtoNumber(4) @JvmField val syncFlag: SyncFlag, + @ProtoNumber(4) @JvmField val syncFlag: SyncFlag = SyncFlag.CONTINUE, @ProtoNumber(5) @JvmField val uinPairMsgs: List? = null, @ProtoNumber(6) @JvmField val bindUin: Long = 0L, @ProtoNumber(7) @JvmField val msgRspType: Int = 0, diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt index 41ace422f..6eed3e4c6 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt @@ -14,6 +14,7 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive import kotlinx.atomicfu.loop import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.* +import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.discardExact @@ -43,6 +44,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.GroupInfoImpl import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.NewContact import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList +import net.mamoe.mirai.qqandroid.utils._miraiContentToString import net.mamoe.mirai.qqandroid.utils.io.serialization.readProtoBuf import net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf import net.mamoe.mirai.qqandroid.utils.read @@ -56,6 +58,12 @@ import net.mamoe.mirai.utils.warning * 获取好友消息和消息记录 */ internal object MessageSvcPbGetMsg : OutgoingPacketFactory("MessageSvc.PbGetMsg") { + + + private val msgUidQueue = ArrayDeque() + private val msgUidSet = hashSetOf() + private val msgQueueMutex = Mutex() + @Suppress("SpellCheckingInspection") operator fun invoke( client: QQAndroidClient, @@ -114,8 +122,9 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory { + bot.client.c2cMessageSync.syncCookie = resp.syncCookie + bot.client.c2cMessageSync.pubAccountCookie = resp.pubAccountCookie + } + 1 -> { + bot.client.c2cMessageSync.syncCookie = resp.syncCookie + } + 2 -> { + bot.client.c2cMessageSync.pubAccountCookie = resp.pubAccountCookie + + } + } + +// bot.logger.debug(resp.msgRspType._miraiContentToString()) +// bot.logger.debug(resp.syncCookie._miraiContentToString()) - bot.client.c2cMessageSync.syncCookie = resp.syncCookie - bot.client.c2cMessageSync.pubAccountCookie = resp.pubAccountCookie bot.client.c2cMessageSync.msgCtrlBuf = resp.msgCtrlBuf if (resp.uinPairMsgs == null) { @@ -151,10 +174,21 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory msg.msgHead.msgTime > it.lastReadTime.toLong() and 4294967295L } }.also { MessageSvcPbDeleteMsg.delete(bot, it) // 删除消息 - // todo 实现一个锁来防止重复收到消息 } .mapNotNull { msg -> + msgQueueMutex.lock() + val msgUid = msg.msgHead.msgUid + if (msgUidSet.size > 50) { + msgUidSet.remove(msgUidQueue.removeFirst()) + } + if (!msgUidSet.add(msgUid)) { + msgQueueMutex.unlock() + return@mapNotNull null + } + msgQueueMutex.unlock() + msgUidQueue.addLast(msgUid) + suspend fun createGroupForBot(groupUin: Long): Group? { val group = bot.getGroupByUinOrNull(groupUin) if (group != null) { @@ -294,18 +328,15 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory { // friend ptt @@ -387,7 +418,7 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory() } return @@ -398,7 +429,7 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory() } return