Commit 424c9bb2 authored by jiahua.liu's avatar jiahua.liu

Friend List Complete

parent 722422d4
......@@ -23,6 +23,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.StatSvc
import net.mamoe.mirai.utils.LockFreeLinkedList
import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.cryptor.contentToString
import net.mamoe.mirai.utils.getValue
import net.mamoe.mirai.utils.io.*
import net.mamoe.mirai.utils.unsafeWeakRef
......@@ -104,16 +105,24 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
override suspend fun init() {
delay(5000)
bot.logger.info("开始加载好友信息")
this@QQAndroidBotNetworkHandler.subscribeAlways<ForceOfflineEvent> {
if (this@QQAndroidBotNetworkHandler.bot == this.bot) {
close()
}
}
/*
* 开始加载Contact表
* */
try {
bot.logger.info("开始加载组信息")
val troopData = FriendList.GetTroopListSimplify(
bot.client
).sendAndExpect<FriendList.GetTroopListSimplify.Response>(10000)
println(troopData.contentToString())
} catch (e: Exception) {
bot.logger.info("加载组信息失败|一般这是由于加载过于频繁导致/将以热加载方式加载群列表")
}
try {
bot.logger.info("开始加载好友信息")
var currentFriendCount = 0
var totalFriendCount: Short
while (true) {
......@@ -127,6 +136,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
timeoutMillis = 8000,
retry = 5
)
totalFriendCount = data.totalFriendCount
data.friendList.forEach {
// atomic add
......@@ -141,14 +151,11 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
delay(200)
}
bot.logger.info("好友信息加载完成, 共 ${currentFriendCount}个")
} catch (e: Exception) {
bot.logger.info("加载好友信息失败|一般这是由于加载过于频繁导致/将以热加载方式加载好友列表")
}
//发送事件
/**
val data = FriendList.GetTroopList(
bot.client
).sendAndExpect<FriendList.GetTroopList.Response>(100000)
println(data.contentToString())
*/
}
/**
......
......@@ -105,3 +105,15 @@ internal class stLevelRankPair(
@SerialId(0) val dwLevel: Long? = null,
@SerialId(1) val rank: String? = ""
) : JceStruct
@Serializable
internal class GetTroopMemberListReq(
@SerialId(0) val uin: Long,
@SerialId(1) val groupCode: Long,
@SerialId(2) val nextUin: Long,
@SerialId(3) val groupUin: Long,
@SerialId(4) val version: Long? = null,
@SerialId(5) val reqType: Long? = null,
@SerialId(6) val getListAppointTime: Long? = null,
@SerialId(7) val richCardNameVer: Byte? = null
) : JceStruct
\ No newline at end of file
......@@ -67,7 +67,7 @@ internal object KnownPacketFactories : List<PacketFactory<*>> by mutableListOf(
MessageSvc.PushForceOffline,
MessageSvc.PbSendMsg,
FriendList.GetFriendGroupList,
FriendList.GetTroopList
FriendList.GetTroopListSimplify
) {
// SvcReqMSFLoginNotify 自己的其他设备上限
// MessageSvc.PushReaded 电脑阅读了别人的消息, 告知手机
......
package net.mamoe.mirai.qqandroid.network.protocol.packet.list
import kotlinx.io.core.ByteReadPacket
import net.mamoe.mirai.contact.GroupId
import net.mamoe.mirai.contact.toInternalId
import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.qqandroid.QQAndroidBot
import net.mamoe.mirai.qqandroid.io.serialization.decodeUniPacket
......@@ -9,20 +11,18 @@ import net.mamoe.mirai.qqandroid.io.serialization.toByteArray
import net.mamoe.mirai.qqandroid.io.serialization.writeJceStruct
import net.mamoe.mirai.qqandroid.network.QQAndroidClient
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.*
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.FriendInfo
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.GetFriendListReq
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.GetFriendListResp
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.GetTroopListReqV2Simplify
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.GroupInfo
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPacket
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.Vec0xd50
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.Vec0xd6b
import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
import net.mamoe.mirai.qqandroid.network.protocol.packet.PacketFactory
import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList.GetFriendGroupList.decode
import net.mamoe.mirai.utils.cryptor.contentToString
import net.mamoe.mirai.utils.io.debugPrint
import net.mamoe.mirai.utils.io.discardExact
import net.mamoe.mirai.utils.io.readRemainingBytes
import net.mamoe.mirai.utils.io.toUHexString
......@@ -30,23 +30,38 @@ import net.mamoe.mirai.utils.io.toUHexString
internal class FriendList {
/**
* Get Troop List不一定会得到服务器的回应 据推测与群数量有关
* 因此 应对timeout方法做出处理
* timeout时间应不小于 8s?
*
*/
internal object GetTroopList :
PacketFactory<GetTroopList.Response>("friendlist.GetTroopListReqV2") {
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): GetTroopList.Response {
debugPrint()
this.discardExact(4)
val res = this.decodeUniPacket(GetTroopListRespV2.serializer())
println(res.contentToString())
return Response(
internal object GetTroopMemberList :
PacketFactory<GetTroopMemberList.Response>("friendlist.GetTroopMemberListReq") {
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): GetTroopMemberList.Response {
TODO()
}
operator fun invoke(
client: QQAndroidClient,
targetGroupId: Long,
nextUin: Long = 0
): OutgoingPacket {
return buildOutgoingUniPacket(client, bodyType = 1, key = client.wLoginSigInfo.d2Key) {
writeJceStruct(
RequestPacket.serializer(),
RequestPacket(
sFuncName = "GetTroopMemberListReq",
sServantName = "mqq.IMService.FriendListServiceServantObj",
iVersion = 3,
sBuffer = jceRequestSBuffer(
"GTML",
GetTroopMemberListReq.serializer(),
GetTroopMemberListReq(
uin = client.uin,
groupCode = GroupId(targetGroupId).toInternalId().value,
groupUin = targetGroupId,
nextUin = 0,
reqType = 0
)
)
)
)
}
}
class Response(
......@@ -55,6 +70,22 @@ internal class FriendList {
override fun toString(): String = "FriendList.GetFriendGroupList.Response"
}
}
internal object GetTroopListSimplify :
PacketFactory<GetTroopListSimplify.Response>("friendlist.GetTroopListReqV2") {
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): GetTroopListSimplify.Response {
this.discardExact(4)
val res = this.decodeUniPacket(GetTroopListRespV2.serializer())
return Response(res.vecTroopList.orEmpty())
}
class Response(
val groups: List<stTroopNum>
) : Packet {
override fun toString(): String = "FriendList.GetFriendGroupList.Response"
}
operator fun invoke(
client: QQAndroidClient
): OutgoingPacket {
......@@ -67,18 +98,18 @@ internal class FriendList {
iVersion = 3,
cPacketType = 0x00,
iMessageType = 0x00000,
iRequestId = 1921334513,
sBuffer = jceRequestSBuffer(
"GetTroopListReqV2Simplify",
GetTroopListReqV2Simplify.serializer(),
GetTroopListReqV2Simplify(
uin = client.uin,
getMSFMsgFlag = 0, // const
groupFlagExt = 1,// const
shVersion = 7, // const
getMSFMsgFlag = 0,
groupFlagExt = 1,
shVersion = 7,
dwCompanyId = 0,
versionNum = 1, // const
vecGroupInfo = listOf(),
getLongGroupName = 1// const
versionNum = 1,
getLongGroupName = 1
)
)
)
......@@ -87,6 +118,7 @@ internal class FriendList {
}
}
internal object GetFriendGroupList : PacketFactory<GetFriendGroupList.Response>("friendlist.getFriendGroupList") {
class Response(
val totalFriendCount: Short,
val friendList: List<FriendInfo>
......@@ -119,24 +151,25 @@ internal class FriendList {
iVersion = 3,
cPacketType = 0x003,
iMessageType = 0x00000,
iRequestId = 1921334514,
sBuffer = jceRequestSBuffer(
"FL",
GetFriendListReq.serializer(),
GetFriendListReq(
reqtype = 3,
ifReflush = if (friendListStartIndex == 0) {
1
} else {
ifReflush = if (friendListStartIndex <= 0) {
0
} else {
1
},
uin = client.uin,
startIndex = friendListStartIndex.toShort(),
getfriendCount = friendListCount.toShort(),
groupid = 0,
ifGetGroupInfo = if (friendListStartIndex == 0) {
1
} else {
ifGetGroupInfo = if (groupListCount <= 0) {
0
} else {
1
},
groupstartIndex = groupListStartIndex.toByte(),
getgroupCount = groupListCount.toByte(),
......@@ -147,7 +180,7 @@ internal class FriendList {
eAppType = 0,
ifGetBothFlag = 0,
ifGetDOVId = 0,
vec0xd6bReq = Vec0xd6b.ReqBody().toByteArray(Vec0xd6b.ReqBody.serializer()),
vec0xd6bReq = EMPTY_BYTE_ARRAY,
vec0xd50Req = Vec0xd50.ReqBody(
appid = 10002L,
reqKsingSwitch = 1,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment