Browse Source

[core] move sync controller in NewContact to specific notice processor

StageGuard 2 years ago
parent
commit
b449270fbc

+ 2 - 0
mirai-core/src/commonMain/kotlin/network/components/NoticeProcessorPipeline.kt

@@ -171,6 +171,7 @@ internal abstract class MixedNoticeProcessor : AnyNoticeProcessor() {
             is Structmsg.StructMsg -> processImpl(data)
             is RequestPushStatus -> processImpl(data)
             is DecodedNotifyMsgBody -> processImpl(data)
+            is Structmsg.RspSystemMsgNew -> processImpl(data)
         }
     }
 
@@ -183,4 +184,5 @@ internal abstract class MixedNoticeProcessor : AnyNoticeProcessor() {
     protected open suspend fun NoticePipelineContext.processImpl(data: RequestPushStatus) {}
 
     protected open suspend fun NoticePipelineContext.processImpl(data: DecodedNotifyMsgBody) {}
+    protected open suspend fun NoticePipelineContext.processImpl(data: Structmsg.RspSystemMsgNew) {}
 }

+ 37 - 17
mirai-core/src/commonMain/kotlin/network/notice/group/GroupOrMemberListNoticeProcessor.kt

@@ -25,12 +25,15 @@ import net.mamoe.mirai.internal.message.contextualBugReportException
 import net.mamoe.mirai.internal.network.components.ContactUpdater
 import net.mamoe.mirai.internal.network.components.MixedNoticeProcessor
 import net.mamoe.mirai.internal.network.components.NoticePipelineContext
+import net.mamoe.mirai.internal.network.components.SyncController.Companion.syncController
+import net.mamoe.mirai.internal.network.components.context
 import net.mamoe.mirai.internal.network.notice.decoders.DecodedNotifyMsgBody
 import net.mamoe.mirai.internal.network.protocol.data.jce.MsgType0x210
 import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
 import net.mamoe.mirai.internal.network.protocol.data.proto.OnlinePushTrans
 import net.mamoe.mirai.internal.network.protocol.data.proto.Structmsg
 import net.mamoe.mirai.internal.network.protocol.data.proto.Submsgtype0x44
+import net.mamoe.mirai.internal.network.protocol.packet.chat.NewContact
 import net.mamoe.mirai.internal.utils.io.serialization.loadAs
 import net.mamoe.mirai.internal.utils.parseToMessageDataList
 import net.mamoe.mirai.internal.utils.toMemberInfo
@@ -38,6 +41,7 @@ import net.mamoe.mirai.utils.MiraiLogger
 import net.mamoe.mirai.utils.context
 import net.mamoe.mirai.utils.read
 import net.mamoe.mirai.utils.structureToString
+import kotlin.math.max
 
 
 /**
@@ -197,19 +201,26 @@ internal class GroupOrMemberListNoticeProcessor(
     // Structmsg.StructMsg
     ///////////////////////////////////////////////////////////////////////////
 
-    override suspend fun NoticePipelineContext.processImpl(data: Structmsg.StructMsg) = data.msg.context {
-        if (this == null) return
+    override suspend fun NoticePipelineContext.processImpl(data: Structmsg.StructMsg) {
+        val systemMsg = data.msg ?: return
+        if (attributes[NewContact.SYSTEM_MSG_TYPE] != 1) return
+
+        if (data.msgTime <= bot.syncController.latestMsgNewGroupTime) return
+        if (!bot.syncController.syncNewGroup(data.msgSeq, data.msgTime)) return // duplicate
+
         markAsConsumed()
-        when (subType) {
+        var consumed = true
+
+        when (systemMsg.subType) {
             0 -> {
-                if (groupMsgType == 8) {
+                if (systemMsg.groupMsgType == 8) {
                     // #1388: 使用手机TIM邀请入群,我为管理员,成功邀请 bot 入群
 
                     // 能正常解析 BotInvitedJoinGroupRequestEvent 和 BotJoinGroupEvent.Active, 因此忽略该通知
                     return
                 } else {
                     throw contextualBugReportException(
-                        "解析 NewContact.SystemMsgNewGroup, subType=5, groupMsgType=$groupMsgType",
+                        "解析 NewContact.SystemMsgNewGroup, subType=5, groupMsgType=${systemMsg.groupMsgType}",
                         data.structureToString(),
                         null,
                         "并描述此时机器人是否被邀请加入群等其他",
@@ -218,26 +229,27 @@ internal class GroupOrMemberListNoticeProcessor(
             }
 
             // 处理被邀请入群 或 处理成员入群申请
-            1 -> when (groupMsgType) {
+            1 -> when (systemMsg.groupMsgType) {
                 1 -> {
                     // 成员申请入群
                     collected += MemberJoinRequestEvent(
-                        bot, data.msgSeq, msgAdditional,
-                        data.reqUin, groupCode, groupName, reqUinNick
+                        bot, data.msgSeq, systemMsg.msgAdditional,
+                        data.reqUin, systemMsg.groupCode, systemMsg.groupName, systemMsg.reqUinNick
                     )
                 }
                 2 -> {
                     // Bot 被邀请入群
                     collected += BotInvitedJoinGroupRequestEvent(
-                        bot, data.msgSeq, actionUin,
-                        groupCode, groupName, actionUinNick
+                        bot, data.msgSeq, systemMsg.actionUin,
+                        systemMsg.groupCode, systemMsg.groupName, systemMsg.actionUinNick
                     )
                 }
                 22 -> {
                     // 成员邀请入群
                     collected += MemberJoinRequestEvent(
-                        bot, data.msgSeq, msgAdditional,
-                        data.reqUin, groupCode, groupName, reqUinNick, actionUin
+                        bot, data.msgSeq, systemMsg.msgAdditional,
+                        data.reqUin, systemMsg.groupCode, systemMsg.groupName,
+                        systemMsg.reqUinNick, systemMsg.actionUin
                     )
                 }
                 else -> throw contextualBugReportException(
@@ -256,8 +268,8 @@ internal class GroupOrMemberListNoticeProcessor(
             3 -> { // 已被请他管理员处理
             }
             5 -> {
-                val group = bot.getGroup(groupCode) ?: return
-                when (groupMsgType) {
+                val group = bot.getGroup(systemMsg.groupCode) ?: return
+                when (systemMsg.groupMsgType) {
                     3 -> {
                         // https://github.com/mamoe/mirai/issues/651
                         // msgDescribe=将你设置为管理员
@@ -268,7 +280,7 @@ internal class GroupOrMemberListNoticeProcessor(
                         // 但无法获取是哪个成员.
                     }
                     7 -> { // 机器人被踢
-                        val operator = group[actionUin] ?: return
+                        val operator = group[systemMsg.actionUin] ?: return
                         collected += BotLeaveEvent.Kick(operator)
                     }
                     6 -> {
@@ -284,7 +296,7 @@ internal class GroupOrMemberListNoticeProcessor(
                     }
                     else -> {
                         throw contextualBugReportException(
-                            "解析 NewContact.SystemMsgNewGroup, subType=5, groupMsgType=$groupMsgType",
+                            "解析 NewContact.SystemMsgNewGroup, subType=5, groupMsgType=${systemMsg.groupMsgType}",
                             this.structureToString(),
                             null,
                             "并描述此时机器人是否被踢出群等",
@@ -292,7 +304,15 @@ internal class GroupOrMemberListNoticeProcessor(
                     }
                 }
             }
-            else -> markNotConsumed()
+            else -> {
+                consumed = false
+                markNotConsumed()
+            }
+        }
+
+        if (consumed) {
+            val latestTime = bot.syncController.latestMsgNewGroupTime
+            bot.syncController.latestMsgNewGroupTime = max(latestTime, data.msgTime)
         }
     }
 

+ 27 - 1
mirai-core/src/commonMain/kotlin/network/notice/priv/FriendNoticeProcessor.kt

@@ -21,11 +21,13 @@ import net.mamoe.mirai.internal.contact.toMiraiFriendInfo
 import net.mamoe.mirai.internal.network.components.MixedNoticeProcessor
 import net.mamoe.mirai.internal.network.components.NoticePipelineContext
 import net.mamoe.mirai.internal.network.components.NoticePipelineContext.Companion.msgInfo
+import net.mamoe.mirai.internal.network.components.SyncController.Companion.syncController
 import net.mamoe.mirai.internal.network.notice.NewContactSupport
 import net.mamoe.mirai.internal.network.notice.group.get
 import net.mamoe.mirai.internal.network.protocol.data.jce.MsgType0x210
 import net.mamoe.mirai.internal.network.protocol.data.proto.FrdSysMsg
 import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
+import net.mamoe.mirai.internal.network.protocol.data.proto.Structmsg
 import net.mamoe.mirai.internal.network.protocol.data.proto.Submsgtype0x115.SubMsgType0x115
 import net.mamoe.mirai.internal.network.protocol.data.proto.Submsgtype0x122
 import net.mamoe.mirai.internal.network.protocol.data.proto.Submsgtype0x27.SubMsgType0x27.*
@@ -36,10 +38,12 @@ import net.mamoe.mirai.internal.network.protocol.packet.list.FriendList.GetFrien
 import net.mamoe.mirai.internal.utils.io.ProtoBuf
 import net.mamoe.mirai.internal.utils.io.serialization.loadAs
 import net.mamoe.mirai.utils.*
+import kotlin.math.max
 
 /**
- * All [FriendEvent] except [FriendMessageEvent]
+ * All [FriendEvent] except [FriendMessageEvent], plus [NewFriendRequestEvent]
  *
+ * @see NewFriendRequestEvent
  * @see FriendInputStatusChangedEvent
  * @see FriendAddEvent
  * @see StrangerRelationChangeEvent.Friended
@@ -136,6 +140,28 @@ internal class FriendNoticeProcessor(
         }
     }
 
+    override suspend fun NoticePipelineContext.processImpl(data: Structmsg.StructMsg) {
+        if (attributes[NewContact.SYSTEM_MSG_TYPE] != 0) return
+        markAsConsumed()
+
+        if (data.msgTime <= bot.syncController.latestMsgNewFriendTime) return
+        if (!bot.syncController.syncNewFriend(data.msgSeq, data.msgTime)) return // duplicate
+
+        val systemMsg = data.msg ?: return
+
+        collected += NewFriendRequestEvent(
+            bot,
+            data.msgSeq,
+            systemMsg.msgAdditional,
+            data.reqUin,
+            systemMsg.groupCode,
+            systemMsg.reqUinNick,
+        )
+
+        val latestTime = bot.syncController.latestMsgNewFriendTime
+        bot.syncController.latestMsgNewFriendTime = max(latestTime, data.msgTime)
+    }
+
 
     @Serializable
     private class Wording(

+ 1 - 0
mirai-core/src/commonMain/kotlin/network/protocol/data/proto/StructMsg.kt

@@ -137,6 +137,7 @@ internal class Structmsg : ProtoBuf {
         @ProtoNumber(8) @JvmField val isGetFrdRibbon: Boolean = true,
         @ProtoNumber(9) @JvmField val isGetGrpRibbon: Boolean = true,
         @ProtoNumber(10) @JvmField val friendMsgTypeFlag: Long = 0L,
+        @ProtoNumber(11) @JvmField val reqMsgType: Int = 0
     ) : ProtoBuf
 
     @Serializable

+ 31 - 17
mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/NewContact.kt

@@ -25,6 +25,8 @@ import net.mamoe.mirai.internal.network.toPacket
 import net.mamoe.mirai.internal.utils.io.serialization.loadAs
 import net.mamoe.mirai.internal.utils.io.serialization.readProtoBuf
 import net.mamoe.mirai.internal.utils.io.serialization.writeProtoBuf
+import net.mamoe.mirai.utils.TypeKey
+import net.mamoe.mirai.utils.buildTypeSafeMap
 import kotlin.math.max
 
 internal class NewContact {
@@ -49,6 +51,7 @@ internal class NewContact {
                     isGetGrpRibbon = false,
                     msgNum = 20,
                     version = 1000,
+                    reqMsgType = 2,
                 ),
             )
         }
@@ -56,13 +59,14 @@ internal class NewContact {
 
         override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Packet {
             readProtoBuf(Structmsg.RspSystemMsgNew.serializer()).run {
-                return friendmsgs.filter {
+                return friendmsgs/*.filter {
                     it.msgTime >= bot.syncController.latestMsgNewFriendTime
-                }.mapNotNull { struct ->
-                    if (!bot.syncController.syncNewFriend(struct.msgSeq, struct.msgTime)) { // duplicate
+                }*/.mapNotNull { struct ->
+                    /*if (!bot.syncController.syncNewFriend(struct.msgSeq, struct.msgTime)) { // duplicate
                         return@mapNotNull null
-                    }
-                    struct.msg?.run {
+                    }*/
+
+                    /*struct.msg?.run {
                         NewFriendRequestEvent(
                             bot,
                             struct.msgSeq,
@@ -71,12 +75,13 @@ internal class NewContact {
                             groupCode,
                             reqUinNick,
                         )
-                    }
-                }.toPacket().also {
+                    }*/
+                    bot.processPacketThroughPipeline(struct, buildTypeSafeMap { set(SYSTEM_MSG_TYPE, 0) })
+                }.toPacket()/*.also {
                     bot.syncController.run {
                         latestMsgNewFriendTime = max(latestMsgNewFriendTime, friendmsgs.maxOfOrNull { it.msgTime } ?: 0)
                     }
-                }
+                }*/
             }
         }
 
@@ -152,19 +157,22 @@ internal class NewContact {
 
 
         override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Packet {
+            val resp = readBytes().loadAs(Structmsg.RspSystemMsgNew.serializer())
+
+
             return readBytes().loadAs(Structmsg.RspSystemMsgNew.serializer()).run {
-                groupmsgs.filter {
+                groupmsgs/*.filter {
                     it.msgTime >= bot.syncController.latestMsgNewGroupTime
-                }.mapNotNull { struct ->
-                    if (!bot.syncController.syncNewGroup(struct.msgSeq, struct.msgTime)) { // duplicate
+                }*/.mapNotNull { struct ->
+                    /*if (!bot.syncController.syncNewGroup(struct.msgSeq, struct.msgTime)) { // duplicate
                         return@mapNotNull null
-                    }
-                    bot.processPacketThroughPipeline(struct)
-                }.toPacket().also {
+                    }*/
+                    bot.processPacketThroughPipeline(struct, buildTypeSafeMap { set(SYSTEM_MSG_TYPE, 1) })
+                }.toPacket()/*.also {
                     bot.syncController.run {
                         latestMsgNewGroupTime = max(latestMsgNewGroupTime, groupmsgs.maxOfOrNull { it.msgTime } ?: 0)
                     }
-                }
+                }*/
             }
         }
 
@@ -179,8 +187,7 @@ internal class NewContact {
                 accept: Boolean?,
                 blackList: Boolean = false,
                 message: String = "",
-            ) =
-                buildOutgoingUniPacket(client) {
+            ) = buildOutgoingUniPacket(client) {
                     writeProtoBuf(
                         Structmsg.ReqSystemMsgAction.serializer(),
                         Structmsg.ReqSystemMsgAction(
@@ -209,4 +216,11 @@ internal class NewContact {
             override suspend fun ByteReadPacket.decode(bot: QQAndroidBot) = null
         }
     }
+
+    internal companion object {
+        /**
+         * friend = 0, group = 1
+         */
+        internal val SYSTEM_MSG_TYPE = TypeKey<Int>("SystemMsgType")
+    }
 }