fix group related

This commit is contained in:
jiahua.liu 2020-02-03 00:47:23 +08:00
parent 6b698ef4d4
commit 9ebd716823
12 changed files with 37 additions and 104 deletions

View File

@ -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(

View File

@ -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 {

View File

@ -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 {

View File

@ -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(

View File

@ -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) {

View File

@ -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]

View File

@ -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)

View File

@ -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] 时将会更新这个值.
@ -67,13 +65,3 @@ interface Group : Contact, CoroutineScope {
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]
*/

View File

@ -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
}
)
}

View File

@ -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)
}

View File

@ -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())

View File

@ -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) {