[core] change bodyType to encryptMethod

This commit is contained in:
Karlatemp 2023-06-16 14:57:30 +08:00
parent 2eb313ba69
commit 67dd471fdb
No known key found for this signature in database
GPG Key ID: BA173CA2B9956C59
12 changed files with 100 additions and 67 deletions

View File

@ -74,67 +74,100 @@ internal class IncomingPacket private constructor(
}
}
internal enum class PacketEncryptType {
NoEncrypt { // 0x00
override fun defaultKey(client: QQAndroidClient): ByteArray = NO_ENCRYPT
},
D2 { //0x01
override fun defaultKey(client: QQAndroidClient): ByteArray {
return client.wLoginSigInfo.d2Key
}
},
Empty { // 16 zeros,// 0x02
override fun defaultKey(client: QQAndroidClient): ByteArray {
return KEY_16_ZEROS
}
},
;
inline val codec: Byte get() = ordinal.toByte()
abstract fun defaultKey(client: QQAndroidClient): ByteArray
}
@Suppress("DuplicatedCode")
internal inline fun <R : Packet?> OutgoingPacketFactory<R>.buildOutgoingUniPacket(
internal fun <R : Packet?> buildRawUniPacket(
client: QQAndroidClient,
bodyType: Byte = 1, // 1: PB?
remark: String? = this.commandName,
commandName: String = this.commandName,
key: ByteArray = client.wLoginSigInfo.d2Key,
encryptMethod: PacketEncryptType = PacketEncryptType.D2,
remark: String?,
commandName: String,
key: ByteArray = encryptMethod.defaultKey(client),
extraData: ByteReadPacket = BRP_STUB,
uin: String = client.uin.toString(),
sequenceId: Int = client.nextSsoSequenceId(),
crossinline body: BytePacketBuilder.(sequenceId: Int) -> Unit
body: BytePacketBuilder.(sequenceId: Int) -> Unit
): OutgoingPacketWithRespType<R> {
return OutgoingPacketWithRespType(remark, commandName, sequenceId, buildPacket {
writeIntLVPacket(lengthOffset = { it + 4 }) {
writeInt(0x0B)
writeByte(bodyType)
writeInt(0x0B) // req type simple
writeByte(encryptMethod.codec)
writeInt(sequenceId)
writeByte(0)
client.uin.toString().let {
uin.let {
writeInt(it.length + 4)
writeText(it)
}
encryptAndWrite(key) {
if (encryptMethod === PacketEncryptType.NoEncrypt) {
writeUniPacket(commandName, client.outgoingPacketSessionId, extraData) {
body(sequenceId)
}
} else {
encryptAndWrite(key) {
writeUniPacket(commandName, client.outgoingPacketSessionId, extraData) {
body(sequenceId)
}
}
}
}
})
}
@Suppress("DuplicatedCode")
internal inline fun <R : Packet?> OutgoingPacketFactory<R>.buildOutgoingUniPacket(
client: QQAndroidClient,
encryptMethod: PacketEncryptType = PacketEncryptType.D2,
remark: String? = this.commandName,
commandName: String = this.commandName,
key: ByteArray = encryptMethod.defaultKey(client),
extraData: ByteReadPacket = BRP_STUB,
uin: String = client.uin.toString(),
sequenceId: Int = client.nextSsoSequenceId(),
noinline body: BytePacketBuilder.(sequenceId: Int) -> Unit
): OutgoingPacketWithRespType<R> =
buildRawUniPacket(client, encryptMethod, remark, commandName, key, extraData, uin, sequenceId, body)
internal inline fun <R : Packet?> IncomingPacketFactory<R>.buildResponseUniPacket(
client: QQAndroidClient,
bodyType: Byte = 1, // 1: PB?
name: String? = this.responseCommandName,
encryptMethod: PacketEncryptType = PacketEncryptType.D2, // 1: PB?
remark: String? = this.responseCommandName,
commandName: String = this.responseCommandName,
key: ByteArray = client.wLoginSigInfo.d2Key,
key: ByteArray = encryptMethod.defaultKey(client),
extraData: ByteReadPacket = BRP_STUB,
sequenceId: Int = client.nextSsoSequenceId(),
crossinline body: BytePacketBuilder.(sequenceId: Int) -> Unit = {}
): OutgoingPacketWithRespType<R> {
@Suppress("DuplicatedCode")
return OutgoingPacketWithRespType(name, commandName, sequenceId, buildPacket {
writeIntLVPacket(lengthOffset = { it + 4 }) {
writeInt(0x0B)
writeByte(bodyType)
writeInt(sequenceId)
writeByte(0)
client.uin.toString().let {
writeInt(it.length + 4)
writeText(it)
}
encryptAndWrite(key) {
writeUniPacket(commandName, client.outgoingPacketSessionId, extraData) {
body(sequenceId)
}
}
}
})
}
noinline body: BytePacketBuilder.(sequenceId: Int) -> Unit = {}
): OutgoingPacketWithRespType<R> = buildRawUniPacket(
client = client,
encryptMethod = encryptMethod,
remark = remark,
commandName = commandName,
key = key,
extraData = extraData,
sequenceId = sequenceId,
body = body
)
private inline fun BytePacketBuilder.writeUniPacket(
@ -169,26 +202,28 @@ internal val NO_ENCRYPT: ByteArray = ByteArray(0)
/**
* com.tencent.qphone.base.util.CodecWarpper#encodeRequest(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, byte[], int, int, java.lang.String, byte, byte, byte, byte[], byte[], boolean)
*/
internal inline fun <R : Packet?> OutgoingPacketFactory<R>.buildLoginOutgoingPacket(
internal fun <R : Packet?> OutgoingPacketFactory<R>.buildLoginOutgoingPacket(
client: QQAndroidClient,
bodyType: Byte,
encryptMethod: PacketEncryptType,
uin: String = client.uin.toString(),
extraData: ByteArray = EMPTY_BYTE_ARRAY,
extraData: ByteArray = if (encryptMethod == PacketEncryptType.D2) client.wLoginSigInfo.d2.data else EMPTY_BYTE_ARRAY,
remark: String? = null,
commandName: String = this.commandName,
key: ByteArray = KEY_16_ZEROS,
crossinline body: BytePacketBuilder.(sequenceId: Int) -> Unit
key: ByteArray = encryptMethod.defaultKey(client),
body: BytePacketBuilder.(sequenceId: Int) -> Unit
): OutgoingPacketWithRespType<R> {
val sequenceId: Int = client.nextSsoSequenceId()
return OutgoingPacketWithRespType(remark, commandName, sequenceId, buildPacket {
writeIntLVPacket(lengthOffset = { it + 4 }) {
writeInt(0x00_00_00_0A)
writeByte(bodyType)
extraData.let {
writeInt(0x00_00_00_0A) // packet login
writeByte(encryptMethod.codec) // encrypt type
extraData.let { // actually d2 key if encryptMethod = d2
writeInt(it.size + 4)
writeFully(it)
}
writeByte(0x00)
uin.let {
@ -196,7 +231,7 @@ internal inline fun <R : Packet?> OutgoingPacketFactory<R>.buildLoginOutgoingPac
writeText(it)
}
if (key === NO_ENCRYPT) {
if (encryptMethod == PacketEncryptType.NoEncrypt) {
body(sequenceId)
} else {
encryptAndWrite(key) { body(sequenceId) }

View File

@ -42,7 +42,7 @@ internal class FriendList {
targetGroupUin: Long,
targetGroupCode: Long,
nextUin: Long = 0
) = buildOutgoingUniPacket(client, bodyType = 1, key = client.wLoginSigInfo.d2Key) {
) = buildOutgoingUniPacket(client) {
writeJceStruct(
RequestPacket.serializer(),
RequestPacket(
@ -91,7 +91,7 @@ internal class FriendList {
operator fun invoke(
client: QQAndroidClient
) = buildOutgoingUniPacket(client, bodyType = 1, key = client.wLoginSigInfo.d2Key) {
) = buildOutgoingUniPacket(client) {
writeJceStruct(
RequestPacket.serializer(),
RequestPacket(
@ -134,7 +134,7 @@ internal class FriendList {
operator fun invoke(
client: QQAndroidClient,
friend: Friend
) = buildOutgoingUniPacket(client, bodyType = 1, key = client.wLoginSigInfo.d2Key) {
) = buildOutgoingUniPacket(client) {
writeJceStruct(
RequestPacket.serializer(),
RequestPacket(
@ -188,7 +188,7 @@ internal class FriendList {
fun forSingleFriend(
client: QQAndroidClient,
uin: Long
) = buildOutgoingUniPacket(client, bodyType = 1, key = client.wLoginSigInfo.d2Key) {
) = buildOutgoingUniPacket(client) {
writeJceStruct(
RequestPacket.serializer(),
RequestPacket(
@ -237,7 +237,7 @@ internal class FriendList {
friendListCount: Int,
groupListStartIndex: Int,
groupListCount: Int
) = buildOutgoingUniPacket(client, bodyType = 1, key = client.wLoginSigInfo.d2Key) {
) = buildOutgoingUniPacket(client) {
writeJceStruct(
RequestPacket.serializer(),
RequestPacket(

View File

@ -13,8 +13,8 @@ import io.ktor.utils.io.core.*
import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.internal.network.Packet
import net.mamoe.mirai.internal.network.QQAndroidClient
import net.mamoe.mirai.internal.network.protocol.packet.NO_ENCRYPT
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacketFactory
import net.mamoe.mirai.internal.network.protocol.packet.PacketEncryptType
import net.mamoe.mirai.internal.network.protocol.packet.buildLoginOutgoingPacket
import net.mamoe.mirai.internal.network.protocol.packet.writeSsoPacket
import net.mamoe.mirai.internal.network.subAppId
@ -28,7 +28,7 @@ internal class Heartbeat {
operator fun invoke(
client: QQAndroidClient
) = buildLoginOutgoingPacket(client, 0, key = NO_ENCRYPT) {
) = buildLoginOutgoingPacket(client, encryptMethod = PacketEncryptType.NoEncrypt) {
writeSsoPacket(client, client.subAppId, commandName, sequenceId = it) {
}

View File

@ -78,7 +78,7 @@ internal class StatSvc {
operator fun invoke(
client: QQAndroidClient
) = buildLoginOutgoingPacket(client, 1) {
) = buildLoginOutgoingPacket(client, PacketEncryptType.D2) {
writeProtoBuf(
StatSvcGetOnline.ReqBody.serializer(), StatSvcGetOnline.ReqBody(
uin = client.uin,
@ -112,9 +112,7 @@ internal class StatSvc {
client: QQAndroidClient
) = buildLoginOutgoingPacket(
client,
bodyType = 1,
extraData = client.wLoginSigInfo.d2.data,
key = client.wLoginSigInfo.d2Key
encryptMethod = PacketEncryptType.D2
) {
writeSsoPacket(client, client.subAppId, commandName, sequenceId = it) {
@ -205,7 +203,7 @@ internal class StatSvc {
applyAction: SvcReqRegister.() -> Unit = {}
) = buildLoginOutgoingPacket(
client,
bodyType = 1,
encryptMethod = PacketEncryptType.D2,
extraData = client.wLoginSigInfo.d2.data,
key = client.wLoginSigInfo.d2Key,
remark = name,

View File

@ -115,7 +115,7 @@ internal class WtLogin {
object SubCommand17 {
operator fun invoke(
client: QQAndroidClient
) = buildLoginOutgoingPacket(client, bodyType = 2) { sequenceId ->
) = buildLoginOutgoingPacket(client, encryptMethod = PacketEncryptType.Empty) { sequenceId ->
writeSsoPacket(
client,
client.subAppId,
@ -669,7 +669,7 @@ internal class WtLogin {
size: Int,
margin: Int,
ecLevel: Int
) = TransEmp.buildLoginOutgoingPacket(client, bodyType = 2, uin = "") { sequenceId ->
) = TransEmp.buildLoginOutgoingPacket(client, encryptMethod = PacketEncryptType.Empty, uin = "") { sequenceId ->
writeSsoPacket(client, client.subAppId, TransEmp.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(client, uin = 0, commandId = 0x812) {
val code2dPacket = buildCode2dPacket(0, 0, 0x31) {
@ -742,7 +742,7 @@ internal class WtLogin {
fun QueryQRCodeStatus(
client: QQAndroidClient,
sig: ByteArray,
) = TransEmp.buildLoginOutgoingPacket(client, bodyType = 2, uin = "") { sequenceId ->
) = TransEmp.buildLoginOutgoingPacket(client, encryptMethod = PacketEncryptType.Empty, uin = "") { sequenceId ->
writeSsoPacket(client, client.subAppId, TransEmp.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(client, uin = 0, commandId = 0x812) {
val code2dPacket = buildCode2dPacket(1, 0, 0x12) {

View File

@ -30,7 +30,7 @@ internal object WtLogin10 : WtLoginExt {
mainSigMap: Int = client.mainSigMap,
remark: String = "10:fast-login",
) = WtLogin.ExchangeEmp.buildLoginOutgoingPacket(
client, bodyType = 2, key = ByteArray(16), remark = remark
client, encryptMethod = PacketEncryptType.Empty, remark = remark
) { sequenceId ->
writeSsoPacket(
client,

View File

@ -27,7 +27,7 @@ internal object WtLogin15 : WtLoginExt {
operator fun invoke(
client: QQAndroidClient,
) = WtLogin.ExchangeEmp.buildOutgoingUniPacket(
client, bodyType = 2, key = ByteArray(16), remark = "15:refresh-keys"
client, encryptMethod = PacketEncryptType.Empty, remark = "15:refresh-keys"
) { sequenceId ->
// writeSsoPacket(client, client.subAppId, WtLogin.ExchangeEmp.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(

View File

@ -20,7 +20,7 @@ internal object WtLogin2 : WtLoginExt {
fun SubmitSliderCaptcha(
client: QQAndroidClient,
ticket: String
) = WtLogin.Login.buildLoginOutgoingPacket(client, bodyType = 2, remark = "2:submit-slider") { sequenceId ->
) = WtLogin.Login.buildLoginOutgoingPacket(client, encryptMethod = PacketEncryptType.Empty, remark = "2:submit-slider") { sequenceId ->
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(client, commandId = 0x0810) {
writeShort(2) // subCommand
@ -50,7 +50,7 @@ internal object WtLogin2 : WtLoginExt {
client: QQAndroidClient,
captchaSign: ByteArray,
captchaAnswer: String
) = WtLogin.Login.buildLoginOutgoingPacket(client, bodyType = 2, remark = "2:submit-captcha") { sequenceId ->
) = WtLogin.Login.buildLoginOutgoingPacket(client, encryptMethod = PacketEncryptType.Empty, remark = "2:submit-captcha") { sequenceId ->
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(client, commandId = 0x0810) {
writeShort(2) // subCommand

View File

@ -21,7 +21,7 @@ import net.mamoe.mirai.utils._writeTlvMap
internal object WtLogin20 : WtLoginExt {
operator fun invoke(
client: QQAndroidClient
) = WtLogin.Login.buildLoginOutgoingPacket(client, bodyType = 2, remark = "20:dev-lock") { sequenceId ->
) = WtLogin.Login.buildLoginOutgoingPacket(client, encryptMethod = PacketEncryptType.Empty, remark = "20:dev-lock") { sequenceId ->
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(client, commandId = 0x0810) {
writeShort(20) // subCommand

View File

@ -26,7 +26,7 @@ internal object WtLogin7 : WtLoginExt {
t174: ByteArray,
code: String
) = WtLogin.Login.buildLoginOutgoingPacket(
client, bodyType = 2, remark = "7:submit-sms"
client, encryptMethod = PacketEncryptType.Empty, remark = "7:submit-sms"
) { sequenceId ->
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(client, commandId = 0x0810) {

View File

@ -29,7 +29,7 @@ internal object WtLogin8 : WtLoginExt {
client: QQAndroidClient,
t174: ByteArray
) = WtLogin.Login.buildLoginOutgoingPacket(
client, bodyType = 2, remark = "8:request-sms"
client, encryptMethod = PacketEncryptType.Empty, remark = "8:request-sms"
) { sequenceId ->
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(client, commandId = 0x0810) {

View File

@ -25,7 +25,7 @@ internal object WtLogin9 : WtLoginExt {
passwordMd5: ByteArray,
allowSlider: Boolean
) = WtLogin.Login.buildLoginOutgoingPacket(
client, bodyType = 2, remark = "9:password-login"
client, encryptMethod = PacketEncryptType.Empty, remark = "9:password-login"
) { sequenceId ->
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(client, commandId = 0x0810) {
@ -154,7 +154,7 @@ internal object WtLogin9 : WtLoginExt {
client: QQAndroidClient,
data: QRCodeLoginData,
) = WtLogin.Login.buildLoginOutgoingPacket(
client, bodyType = 2, remark = "9:qrcode-login"
client, encryptMethod = PacketEncryptType.Empty, remark = "9:qrcode-login"
) { sequenceId ->
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(client, commandId = 0x0810) {