From 9ebd71682353342203ea9e538c33ba2a859c48d5 Mon Sep 17 00:00:00 2001
From: "jiahua.liu" <n@mamoe.net>
Date: Mon, 3 Feb 2020 00:47:23 +0800
Subject: [PATCH] fix group related

---
 .../net/mamoe/mirai/qqandroid/ContactImpl.kt  |  5 +-
 .../net/mamoe/mirai/qqandroid/QQAndroidBot.kt | 16 +++----
 .../network/QQAndroidBotNetworkHandler.kt     | 12 ++++-
 .../chat/receive/OnlinePush.PbPushGroupMsg.kt |  2 +-
 .../protocol/packet/list/FriendListPacket.kt  |  1 +
 .../commonMain/kotlin/net.mamoe.mirai/Bot.kt  | 14 +-----
 .../net.mamoe.mirai/contact/ContactList.kt    |  8 +++-
 .../kotlin/net.mamoe.mirai/contact/Group.kt   | 20 ++------
 .../contact/GroupIdConvertions.kt             | 46 -------------------
 .../net.mamoe.mirai/message/MessagePacket.kt  |  4 --
 .../net.mamoe.mirai/utils/io/InputUtils.kt    |  8 +---
 .../net.mamoe.mirai/utils/io/OutputUtils.kt   |  5 +-
 12 files changed, 37 insertions(+), 104 deletions(-)
 delete mode 100644 mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/GroupIdConvertions.kt

diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
index 836267354..24ba4bcd7 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
@@ -74,13 +74,14 @@ internal class MemberImpl(
 
 @UseExperimental(MiraiInternalAPI::class)
 internal class GroupImpl(
-    bot: QQAndroidBot, override val coroutineContext: CoroutineContext, override val id: Long,
+    bot: QQAndroidBot, override val coroutineContext: CoroutineContext,
+    override val id: Long,
+    override val groupCode: Long,
     override var name: String,
     override var announcement: String,
     override var members: ContactList<Member>
 ) : ContactImpl(), Group {
     override lateinit var owner: Member
-    override val internalId: GroupInternalId = GroupId(id).toInternalId()
 
     override fun getMember(id: Long): Member =
         members.delegate.filteringGetOrAdd(
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
index ffe4fca15..71c823dad 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
@@ -12,6 +12,7 @@ import net.mamoe.mirai.utils.BotConfiguration
 import net.mamoe.mirai.utils.Context
 import net.mamoe.mirai.utils.LockFreeLinkedList
 import net.mamoe.mirai.utils.MiraiInternalAPI
+import net.mamoe.mirai.utils.io.getRandomByteArray
 import kotlin.coroutines.CoroutineContext
 
 @UseExperimental(MiraiInternalAPI::class)
@@ -41,18 +42,13 @@ internal abstract class QQAndroidBotBase constructor(
 
     override val groups: ContactList<Group> = ContactList(LockFreeLinkedList())
 
-    override suspend fun getGroup(id: GroupId): Group {
-        return groups.delegate.getOrNull(id.value) ?: throw NoSuchElementException("Can not found group ${id.value}")
+    override fun getGroupByID(id: Long): Group {
+        return groups.delegate.getOrNull(id) ?: throw NoSuchElementException("Can not found group with ID=${id}")
     }
 
-    override suspend fun getGroup(internalId: GroupInternalId): Group {
-        with(internalId.toId().value) {
-            return groups.delegate.getOrNull(this) ?: throw NoSuchElementException("Can not found group $this")
-        }
-    }
-
-    override suspend fun getGroup(id: Long): Group {
-        return groups.delegate.getOrNull(id) ?: throw NoSuchElementException("Can not found group $id")
+    override fun getGroupByGroupCode(groupCode: Long): Group {
+        return groups.delegate.filterGetOrNull { it.groupCode == groupCode }
+            ?: throw NoSuchElementException("Can not found group with GroupCode=${groupCode}")
     }
 
     override suspend fun addFriend(id: Long, message: String?, remark: String?): AddFriendResult {
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
index 38500a5a6..cca99ee6d 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
@@ -162,12 +162,19 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
             troopData.groups.forEach {
                 val contactList = ContactList(LockFreeLinkedList<Member>())
                 val group =
-                    GroupImpl(bot, EmptyCoroutineContext, it.groupUin, it.groupName!!, it.groupMemo!!, contactList)
+                    GroupImpl(
+                        bot,
+                        EmptyCoroutineContext,
+                        it.groupUin,
+                        it.groupCode,
+                        it.groupName!!,
+                        it.groupMemo!!,
+                        contactList
+                    )
                 group.owner =
                     MemberImpl(QQImpl(bot, EmptyCoroutineContext, it.dwGroupOwnerUin!!), group, EmptyCoroutineContext)
                 toGet[group] = contactList
                 bot.groups.delegate.addLast(group)
-                println(it.groupUin.toString() + " - " + it.groupCode)
             }
             toGet.forEach {
                 try {
@@ -192,6 +199,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
             val data = FriendList.GetTroopMemberList(
                 bot.client,
                 group.id,
+                group.groupCode,
                 nextUin
             ).sendAndExpect<FriendList.GetTroopMemberList.Response>(timeoutMillis = 3000)
             data.members.forEach {
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt
index 67d03a3b2..b304e304d 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt
@@ -25,7 +25,7 @@ internal class OnlinePush {
 
             val extraInfo: ImMsgBody.ExtraInfo? = pbPushMsg.msg.msgBody.richText.elems.firstOrNull { it.extraInfo != null }?.extraInfo
 
-            val group = bot.getGroup(pbPushMsg.msg.msgHead.groupInfo!!.groupCode)
+            val group = bot.getGroupByGroupCode(pbPushMsg.msg.msgHead.groupInfo!!.groupCode)
 
             val flags = extraInfo?.flags ?: 0
             return GroupMessage(
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/list/FriendListPacket.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/list/FriendListPacket.kt
index fcc03f9eb..accc02357 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/list/FriendListPacket.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/list/FriendListPacket.kt
@@ -36,6 +36,7 @@ internal class FriendList {
         operator fun invoke(
             client: QQAndroidClient,
             targetGroupId: Long,
+            targetGroupCode: Long,
             nextUin: Long = 0
         ): OutgoingPacket {
             return buildOutgoingUniPacket(client, bodyType = 1, key = client.wLoginSigInfo.d2Key) {
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
index 417c682ec..409512892 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
@@ -67,19 +67,14 @@ abstract class Bot : CoroutineScope {
      * 获取缓存的群对象. 若没有对应的缓存, 则会线程安全地创建一个.
      * 若 [id] 无效, 将会抛出 [GroupNotFoundException]
      */
-    abstract suspend fun getGroup(id: GroupId): Group
+    abstract fun getGroupByID(id: Long): Group
 
     /**
      * 获取缓存的群对象. 若没有对应的缓存, 则会线程安全地创建一个.
      * 若 [internalId] 无效, 将会抛出 [GroupNotFoundException]
      */
-    abstract suspend fun getGroup(internalId: GroupInternalId): Group
+    abstract fun getGroupByGroupCode(groupCode: Long): Group
 
-    /**
-     * 获取缓存的群对象. 若没有对应的缓存, 则会线程安全地创建一个.
-     * 若 [id] 无效, 将会抛出 [GroupNotFoundException]
-     */
-    abstract suspend fun getGroup(id: Long): Group
 
     // endregion
 
@@ -132,11 +127,6 @@ abstract class Bot : CoroutineScope {
     fun Int.qq(): QQ = getQQ(this.toLong())
     fun Long.qq(): QQ = getQQ(this)
 
-    suspend inline fun Int.group(): Group = getGroup(this.toLong())
-    suspend inline fun Long.group(): Group = getGroup(this)
-    suspend inline fun GroupInternalId.group(): Group = getGroup(this)
-    suspend inline fun GroupId.group(): Group = getGroup(this)
-
 
     /**
      * 需要调用者自行 close [output]
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/ContactList.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/ContactList.kt
index 2b1365daa..4156953ff 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/ContactList.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/ContactList.kt
@@ -45,4 +45,10 @@ fun <C : Contact> LockFreeLinkedList<C>.getOrNull(id: Long): C? {
     return null
 }
 
-fun <C : Contact> LockFreeLinkedList<C>.getOrAdd(id: Long, supplier: () -> C): C = filteringGetOrAdd({ it.id == id }, supplier)
+inline fun <C : Contact> LockFreeLinkedList<C>.filterGetOrNull(filter: (C) -> Boolean): C? {
+    forEach { if (filter(it)) return it }
+    return null
+}
+
+fun <C : Contact> LockFreeLinkedList<C>.getOrAdd(id: Long, supplier: () -> C): C =
+    filteringGetOrAdd({ it.id == id }, supplier)
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
index 693466638..9120fd5ca 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
@@ -12,16 +12,14 @@ import net.mamoe.mirai.utils.coerceAtLeastOrFail
  *
  * Group UIN 与 Group Code 并不是同一个值.
  * Group Code是在客户端显示的code
- * Group Uin是QQ内部的群ID
+ * Group Uin是QQ内部的群ID[在Mirai中则为 id]
+ * 但是有的时候 两个是相同的value
  * 在网络调用层 Code与Uin会被混用
  * 但在开发层 你应该只关注Group Code
  */
 interface Group : Contact, CoroutineScope {
-    /**
-     * 内部 ID. 内部 ID 为 [GroupId] 的映射
-     */
-    val internalId: GroupInternalId
 
+    val groupCode: Long
     /**
      * 群主 (同步事件更新)
      * 进行 [updateGroupInfo] 时将会更新这个值.
@@ -66,14 +64,4 @@ interface Group : Contact, CoroutineScope {
     suspend fun quit(): Boolean
 
     fun toFullString(): String = "Group(id=${this.id}, name=$name, owner=${owner.id}, members=${members.idContentString})"
-}
-
-/**
- * 一般的用户可见的 ID.
- * 在 TIM/QQ 客户端中所看到的的号码均是这个 ID.
- *
- * 注: 在引用群 ID 时, 只应使用 [GroupId] 或 [GroupInternalId] 类型 (内联类无性能损失), 而不能使用 [UInt].
- *
- * @see GroupInternalId.toId 由 [GroupInternalId] 转换为 [GroupId]
- * @see GroupId.toInternalId 由 [GroupId] 转换为 [GroupInternalId]
- */
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/GroupIdConvertions.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/GroupIdConvertions.kt
deleted file mode 100644
index 3bc10dd2c..000000000
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/GroupIdConvertions.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS")
-
-package net.mamoe.mirai.contact
-
-fun GroupId.toInternalId(): GroupInternalId {
-    if (this.value <= 10.0e6) {
-        return GroupInternalId(this.value)
-    }
-    val stringValue = this.value.toString()
-
-    fun plusLeft(leftIncrement: Int, rightLength: Int): String =
-        stringValue.let { (it.dropLast(rightLength).toLong() + leftIncrement).toString() + it.takeLast(rightLength) }
-
-    return GroupInternalId(
-        when (stringValue.dropLast(6).toInt()) {
-            in 1..10 -> plusLeft(202, 6)
-            in 11..19 -> plusLeft(469, 6)
-            in 20..66 -> plusLeft(208, 7)
-            in 67..156 -> plusLeft(1943, 6)
-            in 157..209 -> plusLeft(199, 7)
-            in 210..309 -> plusLeft(389, 7)
-            in 310..499 -> plusLeft(349, 7)
-            else -> null
-        }?.toLong() ?: this.value
-    )
-}
-
-fun GroupInternalId.toId(): GroupId = with(value.toString()) {
-    if (value < 10.0e6) {
-        return GroupId(value)
-    }
-    val left = this.dropLast(6).toLong()
-
-    return GroupId(
-        when (left.toInt()) {
-            in 203..212 -> ((left - 202).toString() + this.takeLast(6).toInt().toString()).toLong()
-            in 480..488 -> ((left - 469).toString() + this.takeLast(6).toInt().toString()).toLong()
-            in 2100..2146 -> ((left.toString().take(3).toLong() - 208).toString() + this.takeLast(7).toInt().toString()).toLong()
-            in 2010..2099 -> ((left - 1943).toString() + this.takeLast(6).toInt().toString()).toLong()
-            in 2147..2199 -> ((left.toString().take(3).toLong() - 199).toString() + this.takeLast(7).toInt().toString()).toLong()
-            in 4100..4199 -> ((left.toString().take(3).toLong() - 389).toString() + this.takeLast(7).toInt().toString()).toLong()
-            in 3800..3989 -> ((left.toString().take(3).toLong() - 349).toString() + this.takeLast(7).toInt().toString()).toLong()
-            else -> value
-        }
-    )
-}
\ No newline at end of file
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
index 721b57942..8745f1564 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
@@ -79,8 +79,4 @@ abstract class MessagePacketBase<TSender : QQ, TSubject : Contact>(_bot: Bot) :
     fun Int.qq(): QQ = bot.getQQ(this.coerceAtLeastOrFail(0).toLong())
     fun Long.qq(): QQ = bot.getQQ(this.coerceAtLeastOrFail(0))
 
-    suspend inline fun Int.group(): Group = bot.getGroup(this.coerceAtLeastOrFail(0).toLong())
-    suspend inline fun Long.group(): Group = bot.getGroup(this.coerceAtLeastOrFail(0))
-    suspend inline fun GroupId.group(): Group = bot.getGroup(this)
-    suspend inline fun GroupInternalId.group(): Group = bot.getGroup(this)
 }
\ No newline at end of file
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/InputUtils.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/InputUtils.kt
index 5b87a8c70..1a0527a9f 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/InputUtils.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/InputUtils.kt
@@ -7,10 +7,6 @@ import kotlinx.io.charsets.Charset
 import kotlinx.io.charsets.Charsets
 import kotlinx.io.core.*
 import kotlinx.io.pool.useInstance
-import net.mamoe.mirai.contact.GroupId
-import net.mamoe.mirai.contact.GroupInternalId
-import net.mamoe.mirai.contact.groupId
-import net.mamoe.mirai.contact.groupInternalId
 import net.mamoe.mirai.utils.assertUnreachable
 import net.mamoe.mirai.utils.cryptor.contentToString
 import kotlin.jvm.JvmName
@@ -70,8 +66,8 @@ fun Input.readIP(): String = buildString(4 + 3) {
 
 fun Input.readQQ(): Long = this.readUInt().toLong()
 fun Input.readGroup(): Long = this.readUInt().toLong()
-fun Input.readGroupId(): GroupId = this.readUInt().toLong().groupId()
-fun Input.readGroupInternalId(): GroupInternalId = this.readUInt().toLong().groupInternalId()
+fun Input.readGroupId(): Long = this.readUInt().toLong()
+fun Input.readGroupCode(): Long = this.readUInt().toLong()
 
 fun Input.readUVarIntLVString(): String = String(this.readUVarIntByteArray())
 
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/OutputUtils.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/OutputUtils.kt
index b4c00ebf3..6f940b792 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/OutputUtils.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/OutputUtils.kt
@@ -4,8 +4,6 @@ package net.mamoe.mirai.utils.io
 
 import kotlinx.io.core.*
 import kotlinx.io.pool.useInstance
-import net.mamoe.mirai.contact.GroupId
-import net.mamoe.mirai.contact.GroupInternalId
 import net.mamoe.mirai.utils.Tested
 import net.mamoe.mirai.utils.coerceAtMostOrFail
 import net.mamoe.mirai.utils.cryptor.encryptBy
@@ -23,8 +21,7 @@ fun BytePacketBuilder.writeZero(count: Int) {
 fun BytePacketBuilder.writeRandom(length: Int) = repeat(length) { this.writeByte(Random.Default.nextInt(255).toByte()) }
 
 fun BytePacketBuilder.writeQQ(qq: Long) = this.writeUInt(qq.toUInt()) // same bit rep.
-fun BytePacketBuilder.writeGroup(groupId: GroupId) = this.writeUInt(groupId.value.toUInt())
-fun BytePacketBuilder.writeGroup(groupInternalId: GroupInternalId) = this.writeUInt(groupInternalId.value.toUInt())
+fun BytePacketBuilder.writeGroup(groupId: Long) = this.writeUInt(groupId.toUInt())
 
 fun BytePacketBuilder.writeShortLVByteArrayLimitedLength(array: ByteArray, maxLength: Int) {
     if (array.size <= maxLength) {