From 10ef21dd9114b7c7304e56c8c29d50c5ce1ebc38 Mon Sep 17 00:00:00 2001
From: Him188 <Him188@mamoe.net>
Date: Thu, 14 Jan 2021 12:38:13 +0800
Subject: [PATCH] Simplify internal implementation

---
 .../kotlin/contact/GroupSettingsImpl.kt       | 108 +++++++--------
 .../network/protocol/data/proto/OIDB.kt       |  78 +++++------
 .../protocol/packet/chat/TroopManagement.kt   | 125 +++---------------
 3 files changed, 103 insertions(+), 208 deletions(-)

diff --git a/mirai-core/src/commonMain/kotlin/contact/GroupSettingsImpl.kt b/mirai-core/src/commonMain/kotlin/contact/GroupSettingsImpl.kt
index a685d5e8d..aca57a747 100644
--- a/mirai-core/src/commonMain/kotlin/contact/GroupSettingsImpl.kt
+++ b/mirai-core/src/commonMain/kotlin/contact/GroupSettingsImpl.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2020 Mamoe Technologies and contributors.
+ * Copyright 2019-2021 Mamoe Technologies and contributors.
  *
  *  此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  *  Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -14,12 +14,15 @@ import net.mamoe.mirai.contact.GroupSettings
 import net.mamoe.mirai.contact.MemberPermission
 import net.mamoe.mirai.contact.checkBotPermission
 import net.mamoe.mirai.data.GroupInfo
+import net.mamoe.mirai.event.Event
 import net.mamoe.mirai.event.broadcast
 import net.mamoe.mirai.event.events.GroupAllowMemberInviteEvent
 import net.mamoe.mirai.event.events.GroupEntranceAnnouncementChangeEvent
 import net.mamoe.mirai.event.events.GroupMuteAllEvent
 import net.mamoe.mirai.event.events.GroupNameChangeEvent
-import net.mamoe.mirai.internal.network.protocol.packet.chat.TroopManagement
+import net.mamoe.mirai.internal.network.QQAndroidClient
+import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket
+import net.mamoe.mirai.internal.network.protocol.packet.chat.TroopManagement.GroupOperation
 
 @Suppress("SetterBackingFieldAssignment")
 internal class GroupSettingsImpl(
@@ -27,24 +30,31 @@ internal class GroupSettingsImpl(
     groupInfo: GroupInfo,
 ) : GroupSettings {
 
+    private inline fun <T> GroupImpl.setImpl(
+        newValue: T,
+        getter: () -> T,
+        setter: (T) -> Unit,
+        crossinline packetConstructor: (client: QQAndroidClient, groupCode: Long, newValue: T) -> OutgoingPacket,
+        crossinline eventConstructor: (old: T) -> Event
+    ) {
+        checkBotPermission(MemberPermission.ADMINISTRATOR)
+        val oldValue = getter()
+        setter(newValue)
+        launch {
+            bot.network.run {
+                packetConstructor(bot.client, id, newValue).sendWithoutExpect()
+            }
+            eventConstructor(oldValue).broadcast()
+        }
+    }
+
+
     internal var nameField: String = groupInfo.name
     var name: String
         get() = nameField
-        set(newValue) = with(group) {
-            checkBotPermission(MemberPermission.ADMINISTRATOR)
-            if (nameField != newValue) {
-                val oldValue = nameField
-                nameField = newValue
-                launch {
-                    bot.network.run {
-                        TroopManagement.GroupOperation.name(
-                            client = bot.client,
-                            groupCode = id,
-                            newName = newValue
-                        ).sendWithoutExpect()
-                    }
-                    GroupNameChangeEvent(oldValue, newValue, group, null).broadcast()
-                }
+        set(newValue) {
+            group.setImpl(newValue, { nameField }, { nameField = it }, GroupOperation::name) {
+                GroupNameChangeEvent(it, newValue, group, null)
             }
         }
 
@@ -54,42 +64,26 @@ internal class GroupSettingsImpl(
     @Deprecated("Don't use public var internally", level = DeprecationLevel.HIDDEN)
     override var entranceAnnouncement: String
         get() = _entranceAnnouncement
-        set(newValue) = with(group) {
-            checkBotPermission(MemberPermission.ADMINISTRATOR)
-            //if (_announcement != newValue) {
-            val oldValue = _entranceAnnouncement
-            _entranceAnnouncement = newValue
-            launch {
-                bot.network.run {
-                    TroopManagement.GroupOperation.memo(
-                        client = bot.client,
-                        groupCode = id,
-                        newMemo = newValue
-                    ).sendWithoutExpect()
-                }
-                GroupEntranceAnnouncementChangeEvent(oldValue, newValue, group, null).broadcast()
+        set(newValue) {
+            group.setImpl(newValue, { _entranceAnnouncement }, { _entranceAnnouncement = it }, GroupOperation::memo) {
+                GroupEntranceAnnouncementChangeEvent(it, newValue, group, null)
             }
-            //}
         }
 
+    private var isAllowMemberInviteField: Boolean = groupInfo.allowMemberInvite
+
     @Deprecated("Don't use public var internally", level = DeprecationLevel.HIDDEN)
-    override var isAllowMemberInvite: Boolean = groupInfo.allowMemberInvite
-        set(newValue) = with(group) {
-            checkBotPermission(MemberPermission.ADMINISTRATOR)
-            //if (_allowMemberInvite != newValue) {
-            val oldValue = field
-            field = newValue
-            launch {
-                bot.network.run {
-                    TroopManagement.GroupOperation.allowMemberInvite(
-                        client = bot.client,
-                        groupCode = id,
-                        switch = newValue
-                    ).sendWithoutExpect()
-                }
-                GroupAllowMemberInviteEvent(oldValue, newValue, group, null).broadcast()
+    override var isAllowMemberInvite: Boolean
+        get() = isAllowMemberInviteField
+        set(newValue) {
+            group.setImpl(
+                newValue,
+                { isAllowMemberInviteField },
+                { isAllowMemberInviteField = it },
+                GroupOperation::allowMemberInvite
+            ) {
+                GroupAllowMemberInviteEvent(it, newValue, group, null)
             }
-            //}
         }
 
     internal var isAnonymousChatEnabledField: Boolean = groupInfo.allowAnonymousChat
@@ -115,21 +109,9 @@ internal class GroupSettingsImpl(
     @Deprecated("Don't use public var internally", level = DeprecationLevel.HIDDEN)
     override var isMuteAll: Boolean
         get() = isMuteAllField
-        set(newValue) = with(group) {
-            checkBotPermission(MemberPermission.ADMINISTRATOR)
-            //if (_muteAll != newValue) {
-            val oldValue = isMuteAllField
-            isMuteAllField = newValue
-            launch {
-                bot.network.run {
-                    TroopManagement.GroupOperation.muteAll(
-                        client = bot.client,
-                        groupCode = id,
-                        switch = newValue
-                    ).sendWithoutExpect()
-                }
-                GroupMuteAllEvent(oldValue, newValue, group, null).broadcast()
+        set(newValue) {
+            group.setImpl(newValue, { isMuteAllField }, { isMuteAllField = it }, GroupOperation::muteAll) {
+                GroupMuteAllEvent(it, newValue, group, null)
             }
-            //}
         }
 }
\ No newline at end of file
diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/OIDB.kt b/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/OIDB.kt
index 4bfa883cf..cc975285d 100644
--- a/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/OIDB.kt
+++ b/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/OIDB.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2020 Mamoe Technologies and contributors.
+ * Copyright 2019-2021 Mamoe Technologies and contributors.
  *
  *  此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  *  Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -398,44 +398,44 @@ internal class Oidb0x89a : ProtoBuf {
 
     @Serializable
     internal class Groupinfo(
-        @ProtoNumber(1) @JvmField val groupExtAdmNum: Int? = null,
-        @ProtoNumber(2) @JvmField val flag: Int? = null,
-        @ProtoNumber(3) @JvmField val ingGroupName: ByteArray? = null,
-        @ProtoNumber(4) @JvmField val ingGroupMemo: ByteArray? = null,
-        @ProtoNumber(5) @JvmField val ingGroupFingerMemo: ByteArray? = null,
-        @ProtoNumber(6) @JvmField val ingGroupAioSkinUrl: ByteArray? = null,
-        @ProtoNumber(7) @JvmField val ingGroupBoardSkinUrl: ByteArray? = null,
-        @ProtoNumber(8) @JvmField val ingGroupCoverSkinUrl: ByteArray? = null,
-        @ProtoNumber(9) @JvmField val groupGrade: Int? = null,
-        @ProtoNumber(10) @JvmField val activeMemberNum: Int? = null,
-        @ProtoNumber(11) @JvmField val certificationType: Int? = null,
-        @ProtoNumber(12) @JvmField val ingCertificationText: ByteArray? = null,
-        @ProtoNumber(13) @JvmField val ingGroupRichFingerMemo: ByteArray? = null,
-        @ProtoNumber(14) @JvmField val stGroupNewguidelines: GroupNewGuidelinesInfo? = null,
-        @ProtoNumber(15) @JvmField val groupFace: Int? = null,
-        @ProtoNumber(16) @JvmField val addOption: Int? = null,
-        @ProtoNumber(17) @JvmField val shutupTime: Int? = null,
-        @ProtoNumber(18) @JvmField val groupTypeFlag: Int? = null,
-        @ProtoNumber(19) @JvmField val stringGroupTag: List<ByteArray> = emptyList(),
-        @ProtoNumber(20) @JvmField val msgGroupGeoInfo: GroupGeoInfo? = null,
-        @ProtoNumber(21) @JvmField val groupClassExt: Int? = null,
-        @ProtoNumber(22) @JvmField val ingGroupClassText: ByteArray? = null,
-        @ProtoNumber(23) @JvmField val appPrivilegeFlag: Int? = null,
-        @ProtoNumber(24) @JvmField val appPrivilegeMask: Int? = null,
-        @ProtoNumber(25) @JvmField val stGroupExInfo: GroupExInfoOnly? = null,
-        @ProtoNumber(26) @JvmField val groupSecLevel: Int? = null,
-        @ProtoNumber(27) @JvmField val groupSecLevelInfo: Int? = null,
-        @ProtoNumber(28) @JvmField val subscriptionUin: Long? = null,
-        @ProtoNumber(29) @JvmField val allowMemberInvite: Int? = null,
-        @ProtoNumber(30) @JvmField val ingGroupQuestion: ByteArray? = null,
-        @ProtoNumber(31) @JvmField val ingGroupAnswer: ByteArray? = null,
-        @ProtoNumber(32) @JvmField val groupFlagext3: Int? = null,
-        @ProtoNumber(33) @JvmField val groupFlagext3Mask: Int? = null,
-        @ProtoNumber(34) @JvmField val groupOpenAppid: Int? = null,
-        @ProtoNumber(35) @JvmField val noFingerOpenFlag: Int? = null,
-        @ProtoNumber(36) @JvmField val noCodeFingerOpenFlag: Int? = null,
-        @ProtoNumber(37) @JvmField val rootId: Long? = null,
-        @ProtoNumber(38) @JvmField val msgLimitFrequency: Int? = null
+        @ProtoNumber(1) @JvmField var groupExtAdmNum: Int? = null,
+        @ProtoNumber(2) @JvmField var flag: Int? = null,
+        @ProtoNumber(3) @JvmField var ingGroupName: ByteArray? = null,
+        @ProtoNumber(4) @JvmField var ingGroupMemo: ByteArray? = null,
+        @ProtoNumber(5) @JvmField var ingGroupFingerMemo: ByteArray? = null,
+        @ProtoNumber(6) @JvmField var ingGroupAioSkinUrl: ByteArray? = null,
+        @ProtoNumber(7) @JvmField var ingGroupBoardSkinUrl: ByteArray? = null,
+        @ProtoNumber(8) @JvmField var ingGroupCoverSkinUrl: ByteArray? = null,
+        @ProtoNumber(9) @JvmField var groupGrade: Int? = null,
+        @ProtoNumber(10) @JvmField var activeMemberNum: Int? = null,
+        @ProtoNumber(11) @JvmField var certificationType: Int? = null,
+        @ProtoNumber(12) @JvmField var ingCertificationText: ByteArray? = null,
+        @ProtoNumber(13) @JvmField var ingGroupRichFingerMemo: ByteArray? = null,
+        @ProtoNumber(14) @JvmField var stGroupNewguidelines: GroupNewGuidelinesInfo? = null,
+        @ProtoNumber(15) @JvmField var groupFace: Int? = null,
+        @ProtoNumber(16) @JvmField var addOption: Int? = null,
+        @ProtoNumber(17) @JvmField var shutupTime: Int? = null,
+        @ProtoNumber(18) @JvmField var groupTypeFlag: Int? = null,
+        @ProtoNumber(19) @JvmField var stringGroupTag: List<ByteArray> = emptyList(),
+        @ProtoNumber(20) @JvmField var msgGroupGeoInfo: GroupGeoInfo? = null,
+        @ProtoNumber(21) @JvmField var groupClassExt: Int? = null,
+        @ProtoNumber(22) @JvmField var ingGroupClassText: ByteArray? = null,
+        @ProtoNumber(23) @JvmField var appPrivilegeFlag: Int? = null,
+        @ProtoNumber(24) @JvmField var appPrivilegeMask: Int? = null,
+        @ProtoNumber(25) @JvmField var stGroupExInfo: GroupExInfoOnly? = null,
+        @ProtoNumber(26) @JvmField var groupSecLevel: Int? = null,
+        @ProtoNumber(27) @JvmField var groupSecLevelInfo: Int? = null,
+        @ProtoNumber(28) @JvmField var subscriptionUin: Long? = null,
+        @ProtoNumber(29) @JvmField var allowMemberInvite: Int? = null,
+        @ProtoNumber(30) @JvmField var ingGroupQuestion: ByteArray? = null,
+        @ProtoNumber(31) @JvmField var ingGroupAnswer: ByteArray? = null,
+        @ProtoNumber(32) @JvmField var groupFlagext3: Int? = null,
+        @ProtoNumber(33) @JvmField var groupFlagext3Mask: Int? = null,
+        @ProtoNumber(34) @JvmField var groupOpenAppid: Int? = null,
+        @ProtoNumber(35) @JvmField var noFingerOpenFlag: Int? = null,
+        @ProtoNumber(36) @JvmField var noCodeFingerOpenFlag: Int? = null,
+        @ProtoNumber(37) @JvmField var rootId: Long? = null,
+        @ProtoNumber(38) @JvmField var msgLimitFrequency: Int? = null
     ) : ProtoBuf
 
     @Serializable
diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/TroopManagement.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/TroopManagement.kt
index cbd92f541..d02fc28cd 100644
--- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/TroopManagement.kt
+++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/TroopManagement.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2020 Mamoe Technologies and contributors.
+ * Copyright 2019-2021 Mamoe Technologies and contributors.
  *
  *  此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  *  Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -193,14 +193,20 @@ internal class TroopManagement {
     }
 
     internal object GroupOperation : OutgoingPacketFactory<GroupOperation.Response>("OidbSvc.0x89a_0") {
-        override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
-            return Response
-        }
+        override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response = Response
 
         fun muteAll(
             client: QQAndroidClient,
             groupCode: Long,
             switch: Boolean
+        ): OutgoingPacket = impl(client, groupCode) {
+            shutupTime = if (switch) 1 else 0
+        }
+
+        private inline fun impl(
+            client: QQAndroidClient,
+            groupCode: Long,
+            info: Oidb0x89a.Groupinfo.() -> Unit
         ): OutgoingPacket {
             return buildOutgoingUniPacket(client) {
                 writeProtoBuf(
@@ -209,138 +215,45 @@ internal class TroopManagement {
                         command = 2202,
                         bodybuffer = Oidb0x89a.ReqBody(
                             groupCode = groupCode,
-                            stGroupInfo = Oidb0x89a.Groupinfo(
-                                shutupTime = if (switch) {
-                                    1
-                                } else {
-                                    0
-                                }
-                            )
+                            stGroupInfo = Oidb0x89a.Groupinfo().apply(info)
                         ).toByteArray(Oidb0x89a.ReqBody.serializer())
                     )
                 )
             }
         }
-//
-//        fun confessTalk(
-//            client: QQAndroidClient,
-//            groupCode: Long,
-//            switch: Boolean
-//        ): OutgoingPacket {
-//            return buildOutgoingUniPacket(client) {
-//                writeProtoBuf(
-//                    OidbSso.OIDBSSOPkg.serializer(),
-//                    OidbSso.OIDBSSOPkg(
-//                        command = 2202,
-//                        bodybuffer = Oidb0x89a.ReqBody(
-//                            groupCode = groupCode,
-//                            stGroupInfo = Oidb0x89a.Groupinfo(
-//                                groupFlagext3Mask = 8192,
-//                                groupFlagext3 = if (switch) {
-//                                    0
-//                                } else {
-//                                    8192
-//                                }
-//                            )
-//                        ).toByteArray(Oidb0x89a.ReqBody.serializer())
-//                    )
-//                )
-//            }
-//        }
 
         fun autoApprove(
             client: QQAndroidClient,
             groupCode: Long,
             switch: Boolean
-        ): OutgoingPacket {
-            return buildOutgoingUniPacket(client) {
-                writeProtoBuf(
-                    OidbSso.OIDBSSOPkg.serializer(),
-                    OidbSso.OIDBSSOPkg(
-                        command = 2202,
-                        bodybuffer = Oidb0x89a.ReqBody(
-                            groupCode = groupCode,
-                            stGroupInfo = Oidb0x89a.Groupinfo(
-                                groupFlagext3 = if (switch) {
-                                    0x00100000
-                                } else {
-                                    0x00000000
-                                }//暂时无效
-                            )
-                        ).toByteArray(Oidb0x89a.ReqBody.serializer())
-                    )
-                )
-            }
+        ): OutgoingPacket = impl(client, groupCode) {
+            groupFlagext3 = if (switch) 0x00100000 else 0x00000000//暂时无效
         }
 
         fun name(
             client: QQAndroidClient,
             groupCode: Long,
             newName: String
-        ): OutgoingPacket {
-            return buildOutgoingUniPacket(client) {
-                writeProtoBuf(
-                    OidbSso.OIDBSSOPkg.serializer(),
-                    OidbSso.OIDBSSOPkg(
-                        command = 2202,
-                        bodybuffer = Oidb0x89a.ReqBody(
-                            groupCode = groupCode,
-                            stGroupInfo = Oidb0x89a.Groupinfo(
-                                ingGroupName = newName.toByteArray()
-                            )
-                        ).toByteArray(Oidb0x89a.ReqBody.serializer())
-                    )
-                )
-            }
+        ): OutgoingPacket = impl(client, groupCode) {
+            ingGroupName = newName.toByteArray()
         }
 
         fun memo(
             client: QQAndroidClient,
             groupCode: Long,
             newMemo: String
-        ): OutgoingPacket {
-            return buildOutgoingUniPacket(client) {
-                writeProtoBuf(
-                    OidbSso.OIDBSSOPkg.serializer(),
-                    OidbSso.OIDBSSOPkg(
-                        command = 2202,
-                        bodybuffer = Oidb0x89a.ReqBody(
-                            groupCode = groupCode,
-                            stGroupInfo = Oidb0x89a.Groupinfo(
-                                ingGroupMemo = newMemo.toByteArray()
-                            )
-                        ).toByteArray(Oidb0x89a.ReqBody.serializer())
-                    )
-                )
-            }
+        ): OutgoingPacket = impl(client, groupCode) {
+            ingGroupMemo = newMemo.toByteArray()
         }
 
         fun allowMemberInvite(
             client: QQAndroidClient,
             groupCode: Long,
             switch: Boolean
-        ): OutgoingPacket {
-            return buildOutgoingUniPacket(client) {
-                writeProtoBuf(
-                    OidbSso.OIDBSSOPkg.serializer(),
-                    OidbSso.OIDBSSOPkg(
-                        command = 2202,
-                        bodybuffer = Oidb0x89a.ReqBody(
-                            groupCode = groupCode,
-                            stGroupInfo = Oidb0x89a.Groupinfo(
-                                allowMemberInvite = if (switch) {
-                                    1
-                                } else {
-                                    0
-                                }
-                            )
-                        ).toByteArray(Oidb0x89a.ReqBody.serializer())
-                    )
-                )
-            }
+        ): OutgoingPacket = impl(client, groupCode) {
+            allowMemberInvite = if (switch) 1 else 0
         }
 
-
         object Response : Packet {
             override fun toString(): String {
                 return "TroopManagement.GroupOperation.Response"