From 7fd5cfe3bb2b8a4a2c091da0268e933d5b77c569 Mon Sep 17 00:00:00 2001
From: ryoii <ryoii@foxmail.com>
Date: Mon, 25 May 2020 22:40:10 +0800
Subject: [PATCH] Low level api for request event again

---
 .../mirai/qqandroid/QQAndroidBot.common.kt    | 175 ++++++++++++------
 .../protocol/packet/chat/NewContact.kt        |  69 +++----
 .../kotlin/net.mamoe.mirai/lowLevelApi.kt     |  25 +++
 3 files changed, 166 insertions(+), 103 deletions(-)

diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt
index b430bb92a..4c26ee38c 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt
@@ -91,17 +91,13 @@ internal class QQAndroidBot constructor(
             "the request $event is outdated: You had already responded it on another device."
         }
 
-        network.run {
-            NewContact.SystemMsgNewFriend.Action(
-                bot.client,
-                event,
-                accept = true
-            ).sendWithoutExpect()
-            bot.friends.delegate.addLast(bot._lowLevelNewFriend(object : FriendInfo {
-                override val uin: Long get() = event.fromId
-                override val nick: String get() = event.fromNick
-            }))
-        }
+        _lowLevelSolveNewFriendRequestEvent(
+            eventId = event.eventId,
+            fromId = event.fromId,
+            fromNick = event.fromNick,
+            accept = true,
+            blackList = false
+        )
     }
 
     override suspend fun rejectNewFriendRequest(event: NewFriendRequestEvent, blackList: Boolean) {
@@ -117,14 +113,13 @@ internal class QQAndroidBot constructor(
             "the request $event is outdated: You had already responded it on another device."
         }
 
-        network.run {
-            NewContact.SystemMsgNewFriend.Action(
-                bot.client,
-                event,
-                accept = false,
-                blackList = blackList
-            ).sendWithoutExpect()
-        }
+        _lowLevelSolveNewFriendRequestEvent(
+            eventId = event.eventId,
+            fromId = event.fromId,
+            fromNick = event.fromNick,
+            accept = false,
+            blackList = blackList
+        )
     }
 
     @OptIn(LowLevelAPI::class)
@@ -139,21 +134,14 @@ internal class QQAndroidBot constructor(
             "the request $this is outdated: Another operator has already responded it."
         }
 
-        network.run {
-            NewContact.SystemMsgNewGroup.Action(
-                bot.client,
-                event,
-                accept = true
-            ).sendWithoutExpect()
-            event.group.members.delegate.addLast(event.group.newMember(object : MemberInfo {
-                override val nameCard: String get() = ""
-                override val permission: MemberPermission get() = MemberPermission.MEMBER
-                override val specialTitle: String get() = ""
-                override val muteTimestamp: Int get() = 0
-                override val uin: Long get() = event.fromId
-                override val nick: String get() = event.fromNick
-            }))
-        }
+        _lowLevelSolveMemberJoinRequestEvent(
+            eventId = event.eventId,
+            fromId = event.fromId,
+            fromNick = event.fromNick,
+            groupId = event.groupId,
+            accept = true,
+            blackList = false
+        )
     }
 
     @Suppress("DuplicatedCode")
@@ -167,14 +155,15 @@ internal class QQAndroidBot constructor(
         check(!event.group.members.contains(event.fromId)) {
             "the request $this is outdated: Another operator has already responded it."
         }
-        network.run {
-            NewContact.SystemMsgNewGroup.Action(
-                bot.client,
-                event,
-                accept = false,
-                blackList = blackList
-            ).sendWithoutExpect()
-        }
+
+        _lowLevelSolveMemberJoinRequestEvent(
+            eventId = event.eventId,
+            fromId = event.fromId,
+            fromNick = event.fromNick,
+            groupId = event.groupId,
+            accept = false,
+            blackList = blackList
+        )
     }
 
     private inline fun checkGroupPermission(eventBot: Bot, eventGroup: Group, eventName: () -> String) {
@@ -198,14 +187,15 @@ internal class QQAndroidBot constructor(
         check(event.responded.compareAndSet(false, true)) {
             "the request $this has already been responded"
         }
-        network.run {
-            NewContact.SystemMsgNewGroup.Action(
-                bot.client,
-                event,
-                accept = null,
-                blackList = blackList
-            ).sendWithoutExpect()
-        }
+
+        _lowLevelSolveMemberJoinRequestEvent(
+            eventId = event.eventId,
+            fromId = event.fromId,
+            fromNick = event.fromNick,
+            groupId = event.groupId,
+            accept = null,
+            blackList = blackList
+        )
     }
 
     override suspend fun acceptInvitedJoinGroupRequest(event: BotInvitedJoinGroupRequestEvent) =
@@ -224,13 +214,12 @@ internal class QQAndroidBot constructor(
             "the request $this is outdated: Bot has been already in the group."
         }
 
-        network.run {
-            NewContact.SystemMsgNewGroup.Action(
-                bot.client,
-                event,
-                accept = accept
-            ).sendWithoutExpect()
-        }
+        _lowLevelSolveBotInvitedJoinGroupRequestEvent(
+            eventId = event.eventId,
+            invitorId = event.invitorId,
+            groupId = event.groupId,
+            accept = accept
+        )
     }
 }
 
@@ -719,6 +708,78 @@ internal abstract class QQAndroidBotBase constructor(
         }
     }
 
+
+    @LowLevelAPI
+    @MiraiExperimentalAPI
+    override suspend fun _lowLevelSolveNewFriendRequestEvent(eventId: Long, fromId: Long, fromNick: String, accept: Boolean, blackList: Boolean) {
+        network.apply {
+            NewContact.SystemMsgNewFriend.Action(
+                bot.client,
+                eventId = eventId,
+                fromId = fromId,
+                accept = accept,
+                blackList = blackList
+            ).sendWithoutExpect()
+            bot.friends.delegate.addLast(bot._lowLevelNewFriend(object : FriendInfo {
+                override val uin: Long get() = fromId
+                override val nick: String get() = fromNick
+            }))
+        }
+    }
+
+    @LowLevelAPI
+    @MiraiExperimentalAPI
+    override suspend fun _lowLevelSolveBotInvitedJoinGroupRequestEvent(
+        eventId: Long,
+        invitorId: Long,
+        groupId: Long,
+        accept: Boolean
+    ) {
+        network.run {
+            NewContact.SystemMsgNewGroup.Action(
+                bot.client,
+                eventId = eventId,
+                fromId = invitorId,
+                groupId = groupId,
+                isInvited = true,
+                accept = accept
+            ).sendWithoutExpect()
+        }
+    }
+
+    @LowLevelAPI
+    @MiraiExperimentalAPI
+    override suspend fun _lowLevelSolveMemberJoinRequestEvent(
+        eventId: Long,
+        fromId: Long,
+        fromNick: String,
+        groupId: Long,
+        accept: Boolean?,
+        blackList: Boolean
+    ) {
+        network.apply {
+            NewContact.SystemMsgNewGroup.Action(
+                bot.client,
+                eventId = eventId,
+                fromId = fromId,
+                groupId = groupId,
+                isInvited = false,
+                accept = accept,
+                blackList = blackList
+            ).sendWithoutExpect()
+            groups[groupId].apply {
+                members.delegate.addLast(newMember(object : MemberInfo {
+                    override val nameCard: String get() = ""
+                    override val permission: MemberPermission get() = MemberPermission.MEMBER
+                    override val specialTitle: String get() = ""
+                    override val muteTimestamp: Int get() = 0
+                    override val uin: Long get() = fromId
+                    override val nick: String get() = fromNick
+                }))
+            }
+        }
+    }
+
     @Suppress("DEPRECATION", "OverridingDeprecatedMember")
     override suspend fun queryImageUrl(image: Image): String = when (image) {
         is OnlineFriendImageImpl -> image.originUrl
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/NewContact.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/NewContact.kt
index 2875b96e6..727213afe 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/NewContact.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/NewContact.kt
@@ -13,7 +13,6 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat
 
 import kotlinx.io.core.ByteReadPacket
 import kotlinx.io.core.readBytes
-import net.mamoe.mirai.contact.Group
 import net.mamoe.mirai.event.events.*
 import net.mamoe.mirai.getGroupOrNull
 import net.mamoe.mirai.qqandroid.QQAndroidBot
@@ -58,17 +57,15 @@ internal class NewContact {
         override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): NewFriendRequestEvent? {
             readBytes().loadAs(Structmsg.RspSystemMsgNew.serializer()).run {
                 val struct = friendmsgs?.firstOrNull()
-                return if (struct == null) null else {
-                    struct.msg?.run {
-                        NewFriendRequestEvent(
-                            bot,
-                            struct.msgSeq,
-                            msgAdditional,
-                            struct.reqUin,
-                            groupCode,
-                            reqUinNick
-                        )
-                    }
+                return struct?.msg?.run {
+                    NewFriendRequestEvent(
+                        bot,
+                        struct.msgSeq,
+                        msgAdditional,
+                        struct.reqUin,
+                        groupCode,
+                        reqUinNick
+                    )
                 }
             }
         }
@@ -77,7 +74,8 @@ internal class NewContact {
 
             operator fun invoke(
                 client: QQAndroidClient,
-                event: NewFriendRequestEvent,
+                eventId: Long,
+                fromId: Long,
                 accept: Boolean,
                 blackList: Boolean = false
             ) =
@@ -92,8 +90,8 @@ internal class NewContact {
                                 remark = "",
                                 blacklist = !accept && blackList
                             ),
-                            msgSeq = event.eventId,
-                            reqUin = event.fromId,
+                            msgSeq = eventId,
+                            reqUin = fromId,
                             srcId = 6,
                             subSrcId = 7,
                             subType = 1
@@ -147,7 +145,7 @@ internal class NewContact {
             readBytes().loadAs(Structmsg.RspSystemMsgNew.serializer()).run {
                 val struct = groupmsgs?.firstOrNull()
 
-                return if (struct == null) null else struct.msg?.run<Structmsg.SystemMsg, Packet> {
+                return struct?.msg?.run<Structmsg.SystemMsg, Packet> {
                     //this.soutv("SystemMsg")
                     when (subType) {
                         1 -> { //管理员邀请
@@ -200,7 +198,10 @@ internal class NewContact {
 
             operator fun invoke(
                 client: QQAndroidClient,
-                event: MemberJoinRequestEvent,
+                eventId: Long,
+                fromId: Long,
+                groupId: Long,
+                isInvited: Boolean,
                 accept: Boolean?,
                 blackList: Boolean = false
             ) =
@@ -214,41 +215,17 @@ internal class NewContact {
                                     true -> 11 // accept
                                     false -> 12 // reject
                                 },
-                                groupCode = event.groupId,
+                                groupCode = groupId,
                                 msg = "",
                                 remark = "",
                                 blacklist = blackList
                             ),
-                            groupMsgType = 1,
+                            groupMsgType = if (isInvited) 2 else 1,
                             language = 1000,
-                            msgSeq = event.eventId,
-                            reqUin = event.fromId,
+                            msgSeq = eventId,
+                            reqUin = fromId,
                             srcId = 3,
-                            subSrcId = 31,
-                            subType = 1
-                        )
-                    )
-                }
-
-            operator fun invoke(
-                client: QQAndroidClient,
-                event: BotInvitedJoinGroupRequestEvent,
-                accept: Boolean
-            ) =
-                buildOutgoingUniPacket(client) {
-                    writeProtoBuf(
-                        Structmsg.ReqSystemMsgAction.serializer(),
-                        Structmsg.ReqSystemMsgAction(
-                            actionInfo = Structmsg.SystemMsgActionInfo(
-                                type = if (accept) 11 else 12,
-                                groupCode = Group.calculateGroupCodeByGroupUin(event.groupId)
-                            ),
-                            groupMsgType = 2,
-                            language = 1000,
-                            msgSeq = event.eventId,
-                            reqUin = event.invitorId,
-                            srcId = 3,
-                            subSrcId = 10016,
+                            subSrcId = if (isInvited) 10016 else 31,
                             subType = 1
                         )
                     )
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/lowLevelApi.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/lowLevelApi.kt
index 89597d4ca..00be90391 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/lowLevelApi.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/lowLevelApi.kt
@@ -13,6 +13,9 @@ import kotlinx.coroutines.Job
 import net.mamoe.mirai.contact.Friend
 import net.mamoe.mirai.contact.Group
 import net.mamoe.mirai.data.*
+import net.mamoe.mirai.event.events.BotInvitedJoinGroupRequestEvent
+import net.mamoe.mirai.event.events.MemberJoinRequestEvent
+import net.mamoe.mirai.event.events.NewFriendRequestEvent
 import net.mamoe.mirai.utils.MiraiExperimentalAPI
 import net.mamoe.mirai.utils.WeakRef
 
@@ -113,4 +116,26 @@ interface LowLevelBotAPIAccessor {
     @LowLevelAPI
     @MiraiExperimentalAPI
     suspend fun _lowLevelGetGroupActiveData(groupId: Long): GroupActiveData
+
+
+    /**
+     * 处理一个账号请求添加机器人为好友的事件
+     */
+    @LowLevelAPI
+    @MiraiExperimentalAPI
+    suspend fun _lowLevelSolveNewFriendRequestEvent(eventId: Long, fromId: Long, fromNick: String, accept: Boolean, blackList: Boolean)
+
+    /**
+     * 处理被邀请加入一个群请求事件
+     */
+    @LowLevelAPI
+    @MiraiExperimentalAPI
+    suspend fun _lowLevelSolveBotInvitedJoinGroupRequestEvent(eventId: Long, invitorId: Long, groupId: Long, accept: Boolean)
+
+    /**
+     * 处理账号请求加入群事件
+     */
+    @LowLevelAPI
+    @MiraiExperimentalAPI
+    suspend fun _lowLevelSolveMemberJoinRequestEvent(eventId: Long, fromId: Long, fromNick: String, groupId: Long, accept: Boolean?, blackList: Boolean)
 }