mirror of
https://github.com/mamoe/mirai.git
synced 2025-04-24 20:43:33 +08:00
Fix FriendListPacket.kt
This commit is contained in:
parent
8ae506223c
commit
1924c59f55
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid
@ -8,6 +8,8 @@ import kotlinx.serialization.modules.EmptyModule
|
||||
import kotlinx.serialization.modules.SerialModule
|
||||
import net.mamoe.mirai.qqandroid.io.JceStruct
|
||||
import net.mamoe.mirai.qqandroid.io.ProtoBuf
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestDataVersion3
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPacket
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.withUse
|
||||
import net.mamoe.mirai.utils.io.readIoBuffer
|
||||
import net.mamoe.mirai.utils.io.readString
|
||||
@ -25,6 +27,19 @@ enum class JceCharset(val kotlinCharset: Charset) {
|
||||
UTF8(Charset.forName("UTF8"))
|
||||
}
|
||||
|
||||
private val JCE_STRUCT_HEAD_OF_TAG_0 = byteArrayOf(0x0A)
|
||||
private val JCE_STRUCT_TAIL_OF_TAG_0 = byteArrayOf(0x0B)
|
||||
|
||||
/**
|
||||
* 构造 [RequestPacket] 的 [RequestPacket.sBuffer]
|
||||
*/
|
||||
fun <T : JceStruct> jceRequestSBuffer(name: String, serializer: SerializationStrategy<T>, jceStruct: T): ByteArray {
|
||||
return RequestDataVersion3(
|
||||
mapOf(
|
||||
name to JCE_STRUCT_HEAD_OF_TAG_0 + jceStruct.toByteArray(serializer) + JCE_STRUCT_TAIL_OF_TAG_0
|
||||
)
|
||||
).toByteArray(RequestDataVersion3.serializer())
|
||||
}
|
||||
|
||||
internal fun getSerialId(desc: SerialDescriptor, index: Int): Int? = desc.findAnnotation<SerialId>(index)?.id
|
||||
|
||||
@ -152,7 +167,7 @@ class Jce private constructor(private val charset: JceCharset, context: SerialMo
|
||||
this.writeHead(STRUCT_END, 0)
|
||||
}
|
||||
} else if (value is ProtoBuf) {
|
||||
this.encodeTaggedByteArray(popTag(), net.mamoe.mirai.qqandroid.io.serialization.ProtoBufWithNullableSupport.dump(value))
|
||||
this.encodeTaggedByteArray(popTag(), ProtoBufWithNullableSupport.dump(value))
|
||||
} else {
|
||||
serializer.serialize(this, value)
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.KnownPacketFactories
|
||||
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.PacketLogger
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendListPacket
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket.LoginPacketResponse.*
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.StatSvc
|
||||
@ -88,19 +87,6 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
||||
|
||||
println("d2key=${bot.client.wLoginSigInfo.d2Key.toUHexString()}")
|
||||
StatSvc.Register(bot.client).sendAndExpect<StatSvc.Register.Response>()
|
||||
println("登陆完成 开始尝试获取friendList")
|
||||
println("登陆完成 开始尝试获取friendList")
|
||||
println("登陆完成 开始尝试获取friendList")
|
||||
println("登陆完成 开始尝试获取friendList")
|
||||
println("登陆完成 开始尝试获取friendList")
|
||||
FriendListPacket(
|
||||
bot.client,
|
||||
0,
|
||||
20,
|
||||
0,
|
||||
0
|
||||
).sendAndExpect<FriendListPacket.GetFriendListResponse>()
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -23,7 +23,7 @@ class RequestPacket(
|
||||
|
||||
@Serializable
|
||||
class RequestDataVersion3(
|
||||
@SerialId(0) val map: Map<String, ByteArray>
|
||||
@SerialId(0) val map: Map<String, ByteArray> // 注意: ByteArray 不能直接放序列化的 JceStruct!! 要放类似 RequestDataStructSvcReqRegister 的
|
||||
) : JceStruct
|
||||
|
||||
@Serializable
|
||||
|
@ -9,6 +9,7 @@ import net.mamoe.mirai.qqandroid.io.serialization.loadAs
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPacket
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.OnlinePush
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList
|
||||
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.DefaultLogger
|
||||
@ -63,7 +64,8 @@ internal object KnownPacketFactories : List<PacketFactory<*>> by mutableListOf(
|
||||
MessageSvc.PushNotify,
|
||||
MessageSvc.PbGetMsg,
|
||||
MessageSvc.PushForceOffline,
|
||||
MessageSvc.PbSendMsg
|
||||
MessageSvc.PbSendMsg,
|
||||
FriendList.GetFriendGroupList
|
||||
) {
|
||||
// SvcReqMSFLoginNotify 自己的其他设备上限
|
||||
// MessageSvc.PushReaded 电脑阅读了别人的消息, 告知手机
|
||||
|
@ -2,7 +2,6 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
|
||||
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.discardExact
|
||||
import kotlinx.io.core.writeFully
|
||||
import net.mamoe.mirai.data.MultiPacket
|
||||
import net.mamoe.mirai.data.Packet
|
||||
import net.mamoe.mirai.message.FriendMessage
|
||||
@ -26,8 +25,6 @@ import net.mamoe.mirai.qqandroid.utils.toRichTextElems
|
||||
import net.mamoe.mirai.utils.cryptor.contentToString
|
||||
import net.mamoe.mirai.utils.io.hexToBytes
|
||||
import net.mamoe.mirai.utils.io.toReadPacket
|
||||
import kotlin.math.absoluteValue
|
||||
import kotlin.random.Random
|
||||
|
||||
class MessageSvc {
|
||||
/**
|
||||
@ -145,11 +142,11 @@ class MessageSvc {
|
||||
richText = ImMsgBody.RichText(
|
||||
elems = message.toRichTextElems()
|
||||
)
|
||||
),
|
||||
msgSeq = 17041,
|
||||
msgRand = Random.nextInt().absoluteValue,
|
||||
syncCookie = client.c2cMessageSync.syncCookie.takeIf { it.isNotEmpty() } ?: "08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00".hexToBytes(),
|
||||
msgVia = 1
|
||||
)
|
||||
// msgSeq = 17041,
|
||||
// msgRand = Random.nextInt().absoluteValue,
|
||||
// syncCookie = client.c2cMessageSync.syncCookie.takeIf { it.isNotEmpty() } ?: "08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00".hexToBytes(),
|
||||
// msgVia = 1
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -3,54 +3,51 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.list
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import net.mamoe.mirai.data.Packet
|
||||
import net.mamoe.mirai.qqandroid.QQAndroidBot
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.jceRequestSBuffer
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.toByteArray
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.writeJceStruct
|
||||
import net.mamoe.mirai.qqandroid.io.writeJcePacket
|
||||
import net.mamoe.mirai.qqandroid.network.QQAndroidClient
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.GetFriendListReq
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestDataStructSvcReqRegister
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestDataVersion3
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPacket
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.GetImgUrlReq
|
||||
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.*
|
||||
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.chat.image.ImageDownPacket
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket
|
||||
|
||||
|
||||
internal object FriendListPacket :
|
||||
PacketFactory<FriendListPacket.GetFriendListResponse>("friendlist.getFriendGroupList") {
|
||||
internal class FriendList {
|
||||
|
||||
class GetFriendListResponse() : Packet
|
||||
internal object GetFriendGroupList : PacketFactory<GetFriendGroupList.Response>("friendlist.getFriendGroupList") {
|
||||
|
||||
class Response : Packet
|
||||
|
||||
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): GetFriendListResponse {
|
||||
println("aaaa")
|
||||
return GetFriendListResponse()
|
||||
}
|
||||
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
|
||||
println("aaaa")
|
||||
return Response()
|
||||
}
|
||||
|
||||
operator fun invoke(
|
||||
client: QQAndroidClient,
|
||||
friendListStartIndex: Int,
|
||||
friendListCount: Int,
|
||||
groupListStartIndex: Int,
|
||||
groupListCount: Int
|
||||
): OutgoingPacket {
|
||||
return buildOutgoingUniPacket(client, key = client.wLoginSigInfo.d2Key) {
|
||||
writeJceStruct(
|
||||
RequestPacket.serializer(),
|
||||
RequestPacket(
|
||||
sFuncName = "GetFriendListReq",
|
||||
sServantName = "mqq.IMService.FriendListServiceServantObj",
|
||||
iVersion = 3,
|
||||
cPacketType = 0x003,
|
||||
iMessageType = 0x00000,
|
||||
iRequestId = 1921334514,
|
||||
sBuffer = RequestDataVersion3(
|
||||
mapOf(
|
||||
"FL" to GetFriendListReq(
|
||||
operator fun invoke(
|
||||
client: QQAndroidClient,
|
||||
friendListStartIndex: Int,
|
||||
friendListCount: Int,
|
||||
groupListStartIndex: Int,
|
||||
groupListCount: Int
|
||||
): OutgoingPacket {
|
||||
return buildOutgoingUniPacket(client, bodyType = 1, key = client.wLoginSigInfo.d2Key) {
|
||||
writeJceStruct(
|
||||
RequestPacket.serializer(),
|
||||
RequestPacket(
|
||||
sFuncName = "GetFriendListReq",
|
||||
sServantName = "mqq.IMService.FriendListServiceServantObj",
|
||||
iVersion = 3,
|
||||
cPacketType = 0x003,
|
||||
iMessageType = 0x00000,
|
||||
iRequestId = 1921334514,
|
||||
sBuffer = jceRequestSBuffer(
|
||||
"FL",
|
||||
GetFriendListReq.serializer(),
|
||||
GetFriendListReq(
|
||||
reqtype = 3,
|
||||
ifReflush = if (friendListStartIndex <= 0) {
|
||||
0
|
||||
@ -84,13 +81,11 @@ internal object FriendListPacket :
|
||||
reqMutualmarkAlienation = 1
|
||||
).toByteArray(Vec0xd50.ReqBody.serializer()),
|
||||
vecSnsTypelist = listOf(13580L, 13581L, 13582L)
|
||||
).toByteArray(GetFriendListReq.serializer())
|
||||
)
|
||||
)
|
||||
).toByteArray(RequestDataVersion3.serializer())
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -4,11 +4,9 @@ import kotlinx.io.core.ByteReadPacket
|
||||
import net.mamoe.mirai.data.Packet
|
||||
import net.mamoe.mirai.qqandroid.QQAndroidBot
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.ProtoBufWithNullableSupport
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.toByteArray
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.jceRequestSBuffer
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.writeJceStruct
|
||||
import net.mamoe.mirai.qqandroid.network.QQAndroidClient
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestDataStructSvcReqRegister
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestDataVersion3
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPacket
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.SvcReqRegister
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
|
||||
@ -61,67 +59,65 @@ class StatSvc {
|
||||
RequestPacket(
|
||||
sServantName = "PushService",
|
||||
sFuncName = "SvcReqRegister",
|
||||
sBuffer = RequestDataVersion3(
|
||||
mapOf(
|
||||
"SvcReqRegister" to RequestDataStructSvcReqRegister(
|
||||
SvcReqRegister(
|
||||
cConnType = 0,
|
||||
lBid = 1 or 2 or 4,
|
||||
lUin = client.uin,
|
||||
iStatus = client.onlineStatus.id,
|
||||
bKikPC = 0, // 是否把 PC 踢下线
|
||||
bKikWeak = 0,
|
||||
timeStamp = 0,
|
||||
// timeStamp = currentTimeSeconds // millis or seconds??
|
||||
iLargeSeq = 1551, // ?
|
||||
bOpenPush = 1,
|
||||
iLocaleID = 2052,
|
||||
bRegType =
|
||||
(if (regPushReason == RegPushReason.appRegister ||
|
||||
regPushReason == RegPushReason.fillRegProxy ||
|
||||
regPushReason == RegPushReason.createDefaultRegInfo ||
|
||||
regPushReason == RegPushReason.setOnlineStatus
|
||||
) 0 else 1).toByte(),
|
||||
bIsSetStatus = if (regPushReason == RegPushReason.setOnlineStatus) 1 else 0,
|
||||
iOSVersion = client.device.version.sdk.toLong(),
|
||||
cNetType = if (client.networkType == NetworkType.WIFI) 1 else 0,
|
||||
vecGuid = client.device.guid,
|
||||
strDevName = client.device.model.encodeToString(),
|
||||
strDevType = client.device.model.encodeToString(),
|
||||
strOSVer = client.device.version.release.encodeToString(),
|
||||
sBuffer = jceRequestSBuffer(
|
||||
"SvcReqRegister",
|
||||
SvcReqRegister.serializer(),
|
||||
SvcReqRegister(
|
||||
cConnType = 0,
|
||||
lBid = 1 or 2 or 4,
|
||||
lUin = client.uin,
|
||||
iStatus = client.onlineStatus.id,
|
||||
bKikPC = 0, // 是否把 PC 踢下线
|
||||
bKikWeak = 0,
|
||||
timeStamp = 0,
|
||||
// timeStamp = currentTimeSeconds // millis or seconds??
|
||||
iLargeSeq = 1551, // ?
|
||||
bOpenPush = 1,
|
||||
iLocaleID = 2052,
|
||||
bRegType =
|
||||
(if (regPushReason == RegPushReason.appRegister ||
|
||||
regPushReason == RegPushReason.fillRegProxy ||
|
||||
regPushReason == RegPushReason.createDefaultRegInfo ||
|
||||
regPushReason == RegPushReason.setOnlineStatus
|
||||
) 0 else 1).toByte(),
|
||||
bIsSetStatus = if (regPushReason == RegPushReason.setOnlineStatus) 1 else 0,
|
||||
iOSVersion = client.device.version.sdk.toLong(),
|
||||
cNetType = if (client.networkType == NetworkType.WIFI) 1 else 0,
|
||||
vecGuid = client.device.guid,
|
||||
strDevName = client.device.model.encodeToString(),
|
||||
strDevType = client.device.model.encodeToString(),
|
||||
strOSVer = client.device.version.release.encodeToString(),
|
||||
|
||||
uOldSSOIp = 0,
|
||||
uNewSSOIp = localIpAddress().split(".").foldIndexed(0L) { index: Int, acc: Long, s: String ->
|
||||
acc or ((s.toLong() shl (index * 16)))
|
||||
},
|
||||
strVendorName = "MIUI",
|
||||
strVendorOSName = "?ONEPLUS A5000_23_17",
|
||||
// register 时还需要
|
||||
/*
|
||||
var44.uNewSSOIp = field_127445;
|
||||
var44.uOldSSOIp = field_127444;
|
||||
var44.strVendorName = ROMUtil.getRomName();
|
||||
var44.strVendorOSName = ROMUtil.getRomVersion(20);
|
||||
*/
|
||||
bytes_0x769_reqbody = ProtoBufWithNullableSupport.dump(
|
||||
Oidb0x769.RequestBody.serializer(), Oidb0x769.RequestBody(
|
||||
rpt_config_list = listOf(
|
||||
Oidb0x769.ConfigSeq(
|
||||
type = 46,
|
||||
version = 0
|
||||
),
|
||||
Oidb0x769.ConfigSeq(
|
||||
type = 283,
|
||||
version = 0
|
||||
)
|
||||
)
|
||||
uOldSSOIp = 0,
|
||||
uNewSSOIp = localIpAddress().split(".").foldIndexed(0L) { index: Int, acc: Long, s: String ->
|
||||
acc or ((s.toLong() shl (index * 16)))
|
||||
},
|
||||
strVendorName = "MIUI",
|
||||
strVendorOSName = "?ONEPLUS A5000_23_17",
|
||||
// register 时还需要
|
||||
/*
|
||||
var44.uNewSSOIp = field_127445;
|
||||
var44.uOldSSOIp = field_127444;
|
||||
var44.strVendorName = ROMUtil.getRomName();
|
||||
var44.strVendorOSName = ROMUtil.getRomVersion(20);
|
||||
*/
|
||||
bytes_0x769_reqbody = ProtoBufWithNullableSupport.dump(
|
||||
Oidb0x769.RequestBody.serializer(), Oidb0x769.RequestBody(
|
||||
rpt_config_list = listOf(
|
||||
Oidb0x769.ConfigSeq(
|
||||
type = 46,
|
||||
version = 0
|
||||
),
|
||||
Oidb0x769.ConfigSeq(
|
||||
type = 283,
|
||||
version = 0
|
||||
)
|
||||
),
|
||||
bSetMute = 0
|
||||
)
|
||||
)
|
||||
).toByteArray(RequestDataStructSvcReqRegister.serializer())
|
||||
),
|
||||
bSetMute = 0
|
||||
)
|
||||
).toByteArray(RequestDataVersion3.serializer())
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user