mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-09 01:30:17 +08:00
Fix massive group list loading
This commit is contained in:
parent
4633803c55
commit
faf8002de9
@ -206,7 +206,7 @@ internal abstract class QQAndroidBotBase constructor(
|
|||||||
TroopManagement.GetGroupInfo(
|
TroopManagement.GetGroupInfo(
|
||||||
client = bot.client,
|
client = bot.client,
|
||||||
groupCode = groupCode
|
groupCode = groupCode
|
||||||
).sendAndExpect<GroupInfoImpl>(retry = 2)
|
).sendAndExpect<GroupInfoImpl>(retry = 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(LowLevelAPI::class)
|
@OptIn(LowLevelAPI::class)
|
||||||
@ -224,7 +224,7 @@ internal abstract class QQAndroidBotBase constructor(
|
|||||||
targetGroupUin = groupUin,
|
targetGroupUin = groupUin,
|
||||||
targetGroupCode = groupCode,
|
targetGroupCode = groupCode,
|
||||||
nextUin = nextUin
|
nextUin = nextUin
|
||||||
).sendAndExpect<FriendList.GetTroopMemberList.Response>(timeoutMillis = 3000)
|
).sendAndExpect<FriendList.GetTroopMemberList.Response>(retry = 3)
|
||||||
sequence += data.members.asSequence().map { troopMemberInfo ->
|
sequence += data.members.asSequence().map { troopMemberInfo ->
|
||||||
MemberInfoImpl(troopMemberInfo, ownerId)
|
MemberInfoImpl(troopMemberInfo, ownerId)
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
|||||||
_pendingEnabled.value = true
|
_pendingEnabled.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
coroutineScope {
|
supervisorScope {
|
||||||
launch {
|
launch {
|
||||||
lateinit var loadFriends: suspend () -> Unit
|
lateinit var loadFriends: suspend () -> Unit
|
||||||
// 不要用 fun, 不要 join declaration, 不要用 val, 编译失败警告
|
// 不要用 fun, 不要 join declaration, 不要用 val, 编译失败警告
|
||||||
@ -262,56 +262,60 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
|||||||
try {
|
try {
|
||||||
logger.info("开始加载群组列表与群成员列表")
|
logger.info("开始加载群组列表与群成员列表")
|
||||||
val troopListData = FriendList.GetTroopListSimplify(bot.client)
|
val troopListData = FriendList.GetTroopListSimplify(bot.client)
|
||||||
.sendAndExpect<FriendList.GetTroopListSimplify.Response>(retry = 2)
|
.sendAndExpect<FriendList.GetTroopListSimplify.Response>(retry = 3)
|
||||||
|
|
||||||
troopListData.groups.forEach { troopNum ->
|
troopListData.groups.chunked(100).forEach { chunk ->
|
||||||
// 别用 fun, 别 val, 编译失败警告
|
coroutineScope {
|
||||||
lateinit var loadGroup: suspend () -> Unit
|
chunk.forEach { troopNum ->
|
||||||
|
// 别用 fun, 别 val, 编译失败警告
|
||||||
|
lateinit var loadGroup: suspend () -> Unit
|
||||||
|
|
||||||
loadGroup = suspend {
|
loadGroup = suspend {
|
||||||
retryCatching(3) {
|
retryCatching(3) {
|
||||||
bot.groups.delegate.addLast(
|
bot.groups.delegate.addLast(
|
||||||
@Suppress("DuplicatedCode")
|
@Suppress("DuplicatedCode")
|
||||||
(GroupImpl(
|
(GroupImpl(
|
||||||
bot = bot,
|
bot = bot,
|
||||||
coroutineContext = bot.coroutineContext,
|
coroutineContext = bot.coroutineContext,
|
||||||
id = troopNum.groupCode,
|
id = troopNum.groupCode,
|
||||||
groupInfo = bot._lowLevelQueryGroupInfo(troopNum.groupCode).apply {
|
groupInfo = bot._lowLevelQueryGroupInfo(troopNum.groupCode).apply {
|
||||||
this as GroupInfoImpl
|
this as GroupInfoImpl
|
||||||
|
|
||||||
if (this.delegate.groupName == null) {
|
if (this.delegate.groupName == null) {
|
||||||
this.delegate.groupName = troopNum.groupName
|
this.delegate.groupName = troopNum.groupName
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.delegate.groupMemo == null) {
|
if (this.delegate.groupMemo == null) {
|
||||||
this.delegate.groupMemo = troopNum.groupMemo
|
this.delegate.groupMemo = troopNum.groupMemo
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.delegate.groupUin == null) {
|
if (this.delegate.groupUin == null) {
|
||||||
this.delegate.groupUin = troopNum.groupUin
|
this.delegate.groupUin = troopNum.groupUin
|
||||||
}
|
}
|
||||||
|
|
||||||
this.delegate.groupCode = troopNum.groupCode
|
this.delegate.groupCode = troopNum.groupCode
|
||||||
},
|
},
|
||||||
members = bot._lowLevelQueryGroupMemberList(
|
members = bot._lowLevelQueryGroupMemberList(
|
||||||
troopNum.groupUin,
|
troopNum.groupUin,
|
||||||
troopNum.groupCode,
|
troopNum.groupCode,
|
||||||
troopNum.dwGroupOwnerUin
|
troopNum.dwGroupOwnerUin
|
||||||
|
)
|
||||||
|
))
|
||||||
)
|
)
|
||||||
))
|
}.exceptionOrNull()?.let {
|
||||||
)
|
logger.error { "群${troopNum.groupCode}的列表拉取失败, 一段时间后将会重试" }
|
||||||
}.exceptionOrNull()?.let {
|
logger.error(it)
|
||||||
logger.error { "群${troopNum.groupCode}的列表拉取失败, 一段时间后将会重试" }
|
this@QQAndroidBotNetworkHandler.launch {
|
||||||
logger.error(it)
|
delay(10_000)
|
||||||
this@QQAndroidBotNetworkHandler.launch {
|
loadGroup()
|
||||||
delay(10_000)
|
}
|
||||||
|
}
|
||||||
|
Unit // 别删, 编译失败警告
|
||||||
|
}
|
||||||
|
launch {
|
||||||
loadGroup()
|
loadGroup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Unit // 别删, 编译失败警告
|
|
||||||
}
|
|
||||||
launch {
|
|
||||||
loadGroup()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.info { "群组列表与群成员加载完成, 共 ${troopListData.groups.size}个" }
|
logger.info { "群组列表与群成员加载完成, 共 ${troopListData.groups.size}个" }
|
||||||
@ -322,17 +326,18 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
withTimeoutOrNull(5000) {
|
supervisorScope {
|
||||||
lateinit var listener: Listener<PacketReceivedEvent>
|
withTimeoutOrNull(30000) {
|
||||||
listener = this.subscribeAlways {
|
lateinit var listener: Listener<PacketReceivedEvent>
|
||||||
if (it.packet is MessageSvc.PbGetMsg.GetMsgSuccess) {
|
listener = this.subscribeAlways {
|
||||||
listener.complete()
|
if (it.packet is MessageSvc.PbGetMsg.GetMsgSuccess) {
|
||||||
|
listener.complete()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
MessageSvc.PbGetMsg(bot.client, MsgSvc.SyncFlag.START, currentTimeSeconds).sendWithoutExpect()
|
|
||||||
} ?: error("timeout syncing friend message history")
|
|
||||||
|
|
||||||
|
MessageSvc.PbGetMsg(bot.client, MsgSvc.SyncFlag.START, currentTimeSeconds).sendAndExpect<Packet>()
|
||||||
|
} ?: error("timeout syncing friend message history")
|
||||||
|
}
|
||||||
bot.firstLoginSucceed = true
|
bot.firstLoginSucceed = true
|
||||||
|
|
||||||
_pendingEnabled.value = false
|
_pendingEnabled.value = false
|
||||||
|
@ -33,7 +33,7 @@ import net.mamoe.mirai.data.GroupInfo as MiraiGroupInfo
|
|||||||
@OptIn(LowLevelAPI::class)
|
@OptIn(LowLevelAPI::class)
|
||||||
internal class GroupInfoImpl(
|
internal class GroupInfoImpl(
|
||||||
internal val delegate: Oidb0x88d.GroupInfo
|
internal val delegate: Oidb0x88d.GroupInfo
|
||||||
) : MiraiGroupInfo, Packet {
|
) : MiraiGroupInfo, Packet, Packet.NoLog {
|
||||||
override val uin: Long get() = delegate.groupUin ?: error("cannot find groupUin")
|
override val uin: Long get() = delegate.groupUin ?: error("cannot find groupUin")
|
||||||
override val owner: Long get() = delegate.groupOwner ?: error("cannot find groupOwner")
|
override val owner: Long get() = delegate.groupOwner ?: error("cannot find groupOwner")
|
||||||
override val groupCode: Long get() = Group.calculateGroupCodeByGroupUin(uin)
|
override val groupCode: Long get() = Group.calculateGroupCodeByGroupUin(uin)
|
||||||
|
@ -35,11 +35,8 @@ import net.mamoe.mirai.qqandroid.network.protocol.data.proto.TroopTips0x857
|
|||||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.IncomingPacketFactory
|
import net.mamoe.mirai.qqandroid.network.protocol.packet.IncomingPacketFactory
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
|
import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.buildResponseUniPacket
|
import net.mamoe.mirai.qqandroid.network.protocol.packet.buildResponseUniPacket
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.MsgType0x210
|
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.onlinePush0x210.OnlinePush0x210Factory
|
|
||||||
import net.mamoe.mirai.qqandroid.utils.io.JceStruct
|
import net.mamoe.mirai.qqandroid.utils.io.JceStruct
|
||||||
import net.mamoe.mirai.qqandroid.utils.io.readString
|
import net.mamoe.mirai.qqandroid.utils.io.readString
|
||||||
import net.mamoe.mirai.qqandroid.utils.io.serialization.*
|
|
||||||
import net.mamoe.mirai.qqandroid.utils.io.serialization.decodeUniPacket
|
import net.mamoe.mirai.qqandroid.utils.io.serialization.decodeUniPacket
|
||||||
import net.mamoe.mirai.qqandroid.utils.io.serialization.jce.JceId
|
import net.mamoe.mirai.qqandroid.utils.io.serialization.jce.JceId
|
||||||
import net.mamoe.mirai.qqandroid.utils.io.serialization.jceRequestSBuffer
|
import net.mamoe.mirai.qqandroid.utils.io.serialization.jceRequestSBuffer
|
||||||
@ -310,7 +307,14 @@ internal class OnlinePush {
|
|||||||
}
|
}
|
||||||
0x10 -> {
|
0x10 -> {
|
||||||
val dataBytes = this.readBytes(26)
|
val dataBytes = this.readBytes(26)
|
||||||
val message = this.readString(this.readByte().toInt())
|
val size = this.readByte().toInt() // orthodox, don't `readUByte`
|
||||||
|
if (size < 0) {
|
||||||
|
error(
|
||||||
|
"negative array size: $size, remaining bytes=${this.readBytes()
|
||||||
|
.toUHexString()}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val message = this.readString(size)
|
||||||
// println(dataBytes.toUHexString())
|
// println(dataBytes.toUHexString())
|
||||||
|
|
||||||
if (dataBytes[0].toInt() != 59) {
|
if (dataBytes[0].toInt() != 59) {
|
||||||
|
@ -9,7 +9,7 @@ internal object ByteArrayPool : DefaultPool<ByteArray>(256) {
|
|||||||
/**
|
/**
|
||||||
* 每一个 [ByteArray] 的大小
|
* 每一个 [ByteArray] 的大小
|
||||||
*/
|
*/
|
||||||
const val BUFFER_SIZE: Int = 81920 / 2
|
const val BUFFER_SIZE: Int = 8192000
|
||||||
|
|
||||||
override fun produceInstance(): ByteArray = ByteArray(BUFFER_SIZE)
|
override fun produceInstance(): ByteArray = ByteArray(BUFFER_SIZE)
|
||||||
|
|
||||||
|
@ -150,8 +150,8 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
|
|||||||
suspend fun doInit() {
|
suspend fun doInit() {
|
||||||
tryNTimesOrException(2) {
|
tryNTimesOrException(2) {
|
||||||
if (it != 0) {
|
if (it != 0) {
|
||||||
delay(3000)
|
|
||||||
logger.warning("Init failed. Retrying in 3s...")
|
logger.warning("Init failed. Retrying in 3s...")
|
||||||
|
delay(3000)
|
||||||
}
|
}
|
||||||
_network.init()
|
_network.init()
|
||||||
}?.let {
|
}?.let {
|
||||||
|
Loading…
Reference in New Issue
Block a user