mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-08 20:17:00 +08:00
Extract login subcommands to simplify WtLogin, add exchange_emp, #833
This commit is contained in:
parent
3098a7d953
commit
bb348930d8
@ -121,7 +121,7 @@ kotlin {
|
||||
jvmTest {
|
||||
dependencies {
|
||||
implementation("org.pcap4j:pcap4j-distribution:1.8.2")
|
||||
implementation("net.mamoe:mirai-login-solver-selenium:1.0-dev-14")
|
||||
// implementation("net.mamoe:mirai-login-solver-selenium:1.0-dev-14")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,9 @@ import net.mamoe.mirai.internal.network.protocol.packet.login.ConfigPushSvc
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.Heartbeat
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.StatSvc
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin.WtLogin2
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin.WtLogin20
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin.WtLogin9
|
||||
import net.mamoe.mirai.internal.utils.*
|
||||
import net.mamoe.mirai.network.*
|
||||
import net.mamoe.mirai.utils.*
|
||||
@ -175,12 +178,12 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
|
||||
fun loginSolverNotNull() = bot.configuration.loginSolver.notnull()
|
||||
|
||||
var response: WtLogin.Login.LoginPacketResponse =
|
||||
WtLogin.Login.SubCommand9(bot.client, allowSlider).sendAndExpect()
|
||||
WtLogin9(bot.client, allowSlider).sendAndExpect()
|
||||
mainloop@ while (true) {
|
||||
when (response) {
|
||||
is WtLogin.Login.LoginPacketResponse.UnsafeLogin -> {
|
||||
loginSolverNotNull().onSolveUnsafeDeviceLoginVerify(bot, response.url)
|
||||
response = WtLogin.Login.SubCommand9(bot.client, allowSlider).sendAndExpect()
|
||||
response = WtLogin9(bot.client, allowSlider).sendAndExpect()
|
||||
}
|
||||
|
||||
is WtLogin.Login.LoginPacketResponse.Captcha -> when (response) {
|
||||
@ -190,7 +193,7 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
|
||||
//refresh captcha
|
||||
result = "ABCD"
|
||||
}
|
||||
response = WtLogin.Login.SubCommand2.SubmitPictureCaptcha(bot.client, response.sign, result)
|
||||
response = WtLogin2.SubmitPictureCaptcha(bot.client, response.sign, result)
|
||||
.sendAndExpect()
|
||||
continue@mainloop
|
||||
}
|
||||
@ -224,7 +227,7 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
|
||||
}
|
||||
throw error
|
||||
}
|
||||
response = WtLogin.Login.SubCommand2.SubmitSliderCaptcha(bot.client, ticket).sendAndExpect()
|
||||
response = WtLogin2.SubmitSliderCaptcha(bot.client, ticket).sendAndExpect()
|
||||
continue@mainloop
|
||||
}
|
||||
}
|
||||
@ -243,7 +246,7 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
|
||||
}
|
||||
|
||||
is WtLogin.Login.LoginPacketResponse.DeviceLockLogin -> {
|
||||
response = WtLogin.Login.SubCommand20(
|
||||
response = WtLogin20(
|
||||
bot.client,
|
||||
response.t402
|
||||
).sendAndExpect()
|
||||
|
@ -307,6 +307,11 @@ internal open class QQAndroidClient(
|
||||
var reserveUinInfo: ReserveUinInfo? = null
|
||||
lateinit var wLoginSigInfo: WLoginSigInfo
|
||||
var tlv113: ByteArray? = null
|
||||
|
||||
/**
|
||||
* from tlvMap119
|
||||
*/
|
||||
var tlv16a: ByteArray? = null
|
||||
lateinit var qrPushSig: ByteArray
|
||||
|
||||
lateinit var mainDisplayName: ByteArray
|
||||
@ -373,6 +378,9 @@ internal class LoginExtraData(
|
||||
internal class WLoginSigInfo(
|
||||
val uin: Long,
|
||||
val encryptA1: ByteArray?, // sigInfo[0]
|
||||
/**
|
||||
* WARNING, please check [QQAndroidClient.tlv16a]
|
||||
*/
|
||||
val noPicSig: ByteArray?, // sigInfo[1]
|
||||
val G: ByteArray, // sigInfo[2]
|
||||
val dpwd: ByteArray,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
@ -122,6 +122,7 @@ internal val PacketLogger: MiraiLoggerWithSwitch by lazy {
|
||||
internal object KnownPacketFactories {
|
||||
object OutgoingFactories : List<OutgoingPacketFactory<*>> by mutableListOf(
|
||||
WtLogin.Login,
|
||||
WtLogin.ExchangeEmp,
|
||||
StatSvc.Register,
|
||||
StatSvc.GetOnlineStatus,
|
||||
StatSvc.GetDevLoginInfo,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
@ -15,10 +15,16 @@ import kotlinx.io.core.BytePacketBuilder
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.toByteArray
|
||||
import kotlinx.io.core.writeFully
|
||||
import net.mamoe.mirai.internal.network.QQAndroidClient
|
||||
import net.mamoe.mirai.internal.network.guid
|
||||
import net.mamoe.mirai.internal.network.protocol.LoginType
|
||||
import net.mamoe.mirai.internal.utils.GuidSource
|
||||
import net.mamoe.mirai.internal.utils.MacOrAndroidIdChangeFlag
|
||||
import net.mamoe.mirai.internal.utils.NetworkType
|
||||
import net.mamoe.mirai.internal.utils.guidFlag
|
||||
import net.mamoe.mirai.internal.utils.io.*
|
||||
import net.mamoe.mirai.utils.currentTimeMillis
|
||||
import net.mamoe.mirai.utils.generateDeviceInfoData
|
||||
import net.mamoe.mirai.utils.md5
|
||||
import net.mamoe.mirai.utils.toByteArray
|
||||
import kotlin.random.Random
|
||||
@ -79,6 +85,26 @@ internal fun BytePacketBuilder.t18(
|
||||
} shouldEqualsTo 22
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t106(
|
||||
appId: Long = 16L,
|
||||
client: QQAndroidClient
|
||||
) {
|
||||
return t106(
|
||||
appId,
|
||||
client.subAppId /* maybe 1*/,
|
||||
client.appClientVersion,
|
||||
client.uin,
|
||||
true,
|
||||
client.account.passwordMd5,
|
||||
0,
|
||||
client.uin.toByteArray(),
|
||||
client.tgtgtKey,
|
||||
true,
|
||||
client.device.guid,
|
||||
LoginType.PASSWORD,
|
||||
client.ssoVersion
|
||||
)
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t106(
|
||||
appId: Long = 16L,
|
||||
@ -291,6 +317,29 @@ internal fun BytePacketBuilder.t112(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t144(
|
||||
client: QQAndroidClient
|
||||
) {
|
||||
return t144(
|
||||
androidId = client.device.androidId,
|
||||
androidDevInfo = client.device.generateDeviceInfoData(),
|
||||
osType = client.device.osType,
|
||||
osVersion = client.device.version.release,
|
||||
networkType = client.networkType,
|
||||
simInfo = client.device.simInfo,
|
||||
unknown = byteArrayOf(),
|
||||
apn = client.device.apn,
|
||||
isGuidFromFileNull = false,
|
||||
isGuidAvailable = true,
|
||||
isGuidChanged = false,
|
||||
guidFlag = guidFlag(GuidSource.FROM_STORAGE, MacOrAndroidIdChangeFlag(0)),
|
||||
buildModel = client.device.model,
|
||||
guid = client.device.guid,
|
||||
buildBrand = client.device.brand,
|
||||
tgtgtKey = client.tgtgtKey
|
||||
)
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t144(
|
||||
// t109
|
||||
androidId: ByteArray,
|
||||
@ -499,7 +548,22 @@ internal fun BytePacketBuilder.t141(
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t511(
|
||||
domains: List<String>
|
||||
domains: List<String> = listOf(
|
||||
"tenpay.com",
|
||||
"openmobile.qq.com",
|
||||
"docs.qq.com",
|
||||
"connect.qq.com",
|
||||
"qzone.qq.com",
|
||||
"vip.qq.com",
|
||||
"gamecenter.qq.com",
|
||||
"qun.qq.com",
|
||||
"game.qq.com",
|
||||
"qqweb.qq.com",
|
||||
"office.qq.com",
|
||||
"ti.qq.com",
|
||||
"mail.qq.com",
|
||||
"mma.qq.com",
|
||||
)
|
||||
) {
|
||||
writeShort(0x511)
|
||||
writeShortLVPacket {
|
||||
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin
|
||||
|
||||
import net.mamoe.mirai.internal.network.QQAndroidClient
|
||||
import net.mamoe.mirai.internal.network.guid
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.*
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
|
||||
|
||||
internal object WtLogin15 : WtLoginExt {
|
||||
private const val subCommand = 15.toShort()
|
||||
|
||||
private const val appId = 16L
|
||||
|
||||
operator fun invoke(
|
||||
client: QQAndroidClient,
|
||||
) = WtLogin.ExchangeEmp.buildLoginOutgoingPacket(client, bodyType = 2) { sequenceId ->
|
||||
writeSsoPacket(client, client.subAppId, WtLogin.ExchangeEmp.commandName, sequenceId = sequenceId) {
|
||||
writeOicqRequestPacket(client, EncryptMethodECDH(client.ecdh), 0x0810) {
|
||||
writeShort(subCommand) // subCommand
|
||||
writeShort(21)
|
||||
|
||||
t18(16, uin = client.uin)
|
||||
t1(client.uin, client.device.ipAddress)
|
||||
t106(appId, client)
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
t100(appId, client.subAppId, client.appClientVersion, client.ssoVersion, client.mainSigMap)
|
||||
t107(0)
|
||||
t142(client.apkId)
|
||||
t144(client)
|
||||
t145(client.device.guid)
|
||||
t16a(client.tlv16a ?: byteArrayOf()) // new
|
||||
t154(sequenceId)
|
||||
t141(client.device.simInfo, client.networkType, client.device.apn)
|
||||
t8(2052)
|
||||
t511()
|
||||
t147(appId, client.apkVersionName, client.apkSignatureMd5)
|
||||
t177(buildTime = client.buildTime, buildVersion = client.sdkVersion)
|
||||
t187(client.device.macAddress)
|
||||
t188(client.device.androidId)
|
||||
t194(client.device.imsiMd5)
|
||||
t202(client.device.wifiBSSID, client.device.wifiSSID)
|
||||
t516()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2020 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin
|
||||
|
||||
import net.mamoe.mirai.internal.network.QQAndroidClient
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.*
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
|
||||
|
||||
|
||||
internal object WtLogin2 : WtLoginExt {
|
||||
fun SubmitSliderCaptcha(
|
||||
client: QQAndroidClient,
|
||||
ticket: String
|
||||
): OutgoingPacket = WtLogin.Login.buildLoginOutgoingPacket(client, bodyType = 2) { sequenceId ->
|
||||
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
|
||||
writeOicqRequestPacket(client, EncryptMethodECDH(client.ecdh), 0x0810) {
|
||||
writeShort(2) // subCommand
|
||||
writeShort(4) // count of TLVs
|
||||
t193(ticket)
|
||||
t8(2052)
|
||||
t104(client.t104)
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun SubmitPictureCaptcha(
|
||||
client: QQAndroidClient,
|
||||
captchaSign: ByteArray,
|
||||
captchaAnswer: String
|
||||
): OutgoingPacket = WtLogin.Login.buildLoginOutgoingPacket(client, bodyType = 2) { sequenceId ->
|
||||
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
|
||||
writeOicqRequestPacket(client, EncryptMethodECDH(client.ecdh), 0x0810) {
|
||||
writeShort(2) // subCommand
|
||||
writeShort(4) // count of TLVs
|
||||
t2(captchaAnswer, captchaSign, 0)
|
||||
t8(2052)
|
||||
t104(client.t104)
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2020 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin
|
||||
|
||||
import kotlinx.io.core.toByteArray
|
||||
import net.mamoe.mirai.internal.network.QQAndroidClient
|
||||
import net.mamoe.mirai.internal.network.guid
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.*
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
|
||||
import net.mamoe.mirai.utils.md5
|
||||
|
||||
internal object WtLogin20 : WtLoginExt {
|
||||
operator fun invoke(
|
||||
client: QQAndroidClient,
|
||||
t402: ByteArray
|
||||
): OutgoingPacket = WtLogin.Login.buildLoginOutgoingPacket(client, bodyType = 2) { sequenceId ->
|
||||
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
|
||||
writeOicqRequestPacket(client, EncryptMethodECDH(client.ecdh), 0x0810) {
|
||||
writeShort(20) // subCommand
|
||||
writeShort(4) // count of TLVs, probably ignored by server?
|
||||
t8(2052)
|
||||
t104(client.t104)
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
t401((client.device.guid + "stMNokHgxZUGhsYp".toByteArray() + t402).md5())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin
|
||||
|
||||
import kotlinx.io.core.buildPacket
|
||||
import kotlinx.io.core.readBytes
|
||||
import kotlinx.io.core.toByteArray
|
||||
import net.mamoe.mirai.internal.network.QQAndroidClient
|
||||
import net.mamoe.mirai.internal.network.guid
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.*
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
|
||||
|
||||
internal object WtLogin9 : WtLoginExt {
|
||||
private const val appId = 16L
|
||||
|
||||
operator fun invoke(
|
||||
client: QQAndroidClient,
|
||||
allowSlider: Boolean
|
||||
): OutgoingPacket = WtLogin.Login.buildLoginOutgoingPacket(client, bodyType = 2) { sequenceId ->
|
||||
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
|
||||
writeOicqRequestPacket(client, EncryptMethodECDH(client.ecdh), 0x0810) {
|
||||
writeShort(9) // subCommand
|
||||
writeShort(if (allowSlider) 0x18 else 0x17) // count of TLVs, probably ignored by server?
|
||||
//writeShort(LoginType.PASSWORD.value.toShort())
|
||||
|
||||
t18(appId, client.appClientVersion, client.uin)
|
||||
t1(client.uin, client.device.ipAddress)
|
||||
t106(appId, client)
|
||||
|
||||
/* // from GetStWithPasswd
|
||||
int mMiscBitmap = this.mMiscBitmap;
|
||||
if (t.uinDeviceToken) {
|
||||
mMiscBitmap = (this.mMiscBitmap | 0x2000000);
|
||||
}
|
||||
|
||||
|
||||
// defaults true
|
||||
if (ConfigManager.get_loginWithPicSt()) appIdList = longArrayOf(1600000226L)
|
||||
*/
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
t100(appId, client.subAppId, client.appClientVersion, client.ssoVersion, client.mainSigMap)
|
||||
t107(0)
|
||||
t108(client.device.imei.toByteArray())
|
||||
|
||||
// t108(byteArrayOf())
|
||||
// ignored: t104()
|
||||
t142(client.apkId)
|
||||
|
||||
// if login with non-number uin
|
||||
// t112()
|
||||
t144(client)
|
||||
|
||||
//this.build().debugPrint("傻逼")
|
||||
t145(client.device.guid)
|
||||
t147(appId, client.apkVersionName, client.apkSignatureMd5)
|
||||
|
||||
/*
|
||||
if (client.miscBitMap and 0x80 != 0) {
|
||||
t166(1)
|
||||
}
|
||||
*/
|
||||
|
||||
// ignored t16a because array5 is null
|
||||
|
||||
t154(sequenceId)
|
||||
t141(client.device.simInfo, client.networkType, client.device.apn)
|
||||
t8(2052)
|
||||
|
||||
t511()
|
||||
|
||||
// ignored t172 because rollbackSig is null
|
||||
// ignored t185 because loginType is not SMS
|
||||
// ignored t400 because of first login
|
||||
|
||||
t187(client.device.macAddress)
|
||||
t188(client.device.androidId)
|
||||
t194(client.device.imsiMd5)
|
||||
if (allowSlider) {
|
||||
t191()
|
||||
}
|
||||
|
||||
/*
|
||||
t201(N = byteArrayOf())*/
|
||||
|
||||
t202(client.device.wifiBSSID, client.device.wifiSSID)
|
||||
|
||||
t177(
|
||||
buildTime = client.buildTime,
|
||||
buildVersion = client.sdkVersion,
|
||||
)
|
||||
t516()
|
||||
t521()
|
||||
|
||||
t525(buildPacket {
|
||||
t536(buildPacket {
|
||||
//com.tencent.loginsecsdk.ProtocolDet#packExtraData
|
||||
writeByte(1) // const
|
||||
writeByte(0) // data count
|
||||
}.readBytes())
|
||||
})
|
||||
// this.build().debugPrint("傻逼")
|
||||
|
||||
// ignored t318 because not logging in by QR
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright 2020 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin
|
||||
|
||||
import kotlinx.io.core.*
|
||||
import net.mamoe.mirai.internal.network.LoginExtraData
|
||||
import net.mamoe.mirai.internal.network.QQAndroidClient
|
||||
import net.mamoe.mirai.internal.network.guid
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.Tlv
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.t145
|
||||
import net.mamoe.mirai.internal.network.readUShortLVByteArray
|
||||
import net.mamoe.mirai.internal.utils.io.writeShortLVByteArray
|
||||
import net.mamoe.mirai.utils.*
|
||||
|
||||
|
||||
internal inline fun WtLoginExt.analysisTlv0x531(
|
||||
t531: ByteArray,
|
||||
handler: (a1: ByteArray, noPicSig: ByteArray) -> Unit
|
||||
) {
|
||||
val map = t531.toReadPacket().withUse { _readTLVMap() }
|
||||
|
||||
val t106 = map[0x106]
|
||||
val t16a = map[0x16a]
|
||||
val t113 = map[0x113]
|
||||
val t10c = map[0x10c]
|
||||
|
||||
if (t106 != null && t16a != null && t113 != null && t10c != null) {
|
||||
handler(t106 + t10c, t16a)
|
||||
}
|
||||
}
|
||||
|
||||
internal interface WtLoginExt { // so as not to register to global extension
|
||||
|
||||
fun onErrorMessage(tlvMap: TlvMap): WtLogin.Login.LoginPacketResponse.Error? {
|
||||
return tlvMap[0x149]?.read {
|
||||
discardExact(2) //type
|
||||
val title: String = readUShortLVString()
|
||||
val content: String = readUShortLVString()
|
||||
val otherInfo: String = readUShortLVString()
|
||||
|
||||
WtLogin.Login.LoginPacketResponse.Error(title, content, otherInfo)
|
||||
} ?: tlvMap[0x146]?.read {
|
||||
discardExact(2) // ver
|
||||
discardExact(2) // code
|
||||
|
||||
val title = readUShortLVString()
|
||||
val message = readUShortLVString()
|
||||
val errorInfo = readUShortLVString()
|
||||
|
||||
WtLogin.Login.LoginPacketResponse.Error(title, message, errorInfo)
|
||||
}
|
||||
}
|
||||
|
||||
fun TlvMap.getOrEmpty(key: Int): ByteArray {
|
||||
return this[key] ?: byteArrayOf()
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws error
|
||||
*/
|
||||
fun QQAndroidClient.parseWFastLoginInfoDataOutA1(t169: ByteArray): ByteReadPacket {
|
||||
val map = t169.toReadPacket().withUse { _readTLVMap() }
|
||||
|
||||
val t106 = map[0x106]
|
||||
val t10c = map[0x10c]
|
||||
val t16a = map[0x16a]
|
||||
|
||||
check(t106 != null) { "getWFastLoginInfoDataOutA1: Cannot find tlv 0x106!!" }
|
||||
check(t10c != null) { "getWFastLoginInfoDataOutA1: Cannot find tlv 0x10c!!" }
|
||||
check(t16a != null) { "getWFastLoginInfoDataOutA1: Cannot find tlv 0x16a!!" }
|
||||
|
||||
return buildPacket {
|
||||
writeByte(64)
|
||||
writeShort(4)
|
||||
|
||||
// TLV
|
||||
writeShort(0x106)
|
||||
writeShortLVByteArray(t106)
|
||||
|
||||
writeShort(0x10c)
|
||||
writeShortLVByteArray(t10c)
|
||||
|
||||
writeShort(0x16a)
|
||||
writeShortLVByteArray(t16a)
|
||||
|
||||
t145(device.guid)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* login extra data
|
||||
*/
|
||||
fun QQAndroidClient.analysisTlv537(t537: ByteArray) = t537.read {
|
||||
//discardExact(2)
|
||||
loginExtraData = LoginExtraData( // args are to correct order
|
||||
uin = readUInt().toLong(),
|
||||
ip = readBytes(readByte().toInt() and 0xff),
|
||||
time = readInt(), // correct
|
||||
version = readInt()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* pwd flag
|
||||
*/
|
||||
fun QQAndroidClient.analysisTlv186(t186: ByteArray) = t186.read {
|
||||
discardExact(1)
|
||||
pwdFlag = readByte().toInt() == 1
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 [QQAndroidClient.uin]
|
||||
*/
|
||||
fun QQAndroidClient.analysisTlv113(t113: ByteArray) = t113.read {
|
||||
_uin = readUInt().toLong()
|
||||
|
||||
/*
|
||||
// nothing to do
|
||||
|
||||
if (!asyncContext.ifQQLoginInQim(class_1048.productType)) {
|
||||
this.field_61436.method_62330(this.field_61436.field_63973, this.field_61436.uin);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 [QQAndroidClient.timeDifference] 和 [QQAndroidClient.ipFromT149]
|
||||
*/
|
||||
fun QQAndroidClient.analysisTlv130(t130: ByteArray) = t130.read {
|
||||
discardExact(2)
|
||||
timeDifference = readUInt().toLong() - currentTimeSeconds()
|
||||
ipFromT149 = readBytes(4)
|
||||
}
|
||||
|
||||
fun QQAndroidClient.analysisTlv150(t150: ByteArray) {
|
||||
this.t150 = Tlv(t150)
|
||||
}
|
||||
|
||||
fun QQAndroidClient.analysisTlv161(t161: ByteArray) {
|
||||
val tlv = t161.toReadPacket().apply { discardExact(2) }.withUse { _readTLVMap() }
|
||||
|
||||
tlv[0x173]?.let { analysisTlv173(it) }
|
||||
tlv[0x17f]?.let { analysisTlv17f(it) }
|
||||
tlv[0x172]?.let { rollbackSig = it }
|
||||
}
|
||||
|
||||
/**
|
||||
* server host
|
||||
*/
|
||||
fun QQAndroidClient.analysisTlv173(t173: ByteArray) {
|
||||
t173.read {
|
||||
val type = readByte()
|
||||
val host = readUShortLVString()
|
||||
val port = readShort()
|
||||
|
||||
bot.logger.warning("服务器: host=$host, port=$port, type=$type")
|
||||
// SEE oicq_request.java at method analysisT173
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ipv6 address
|
||||
*/
|
||||
fun QQAndroidClient.analysisTlv17f(t17f: ByteArray) {
|
||||
t17f.read {
|
||||
val type = readByte()
|
||||
val host = readUShortLVString()
|
||||
val port = readShort()
|
||||
|
||||
bot.logger.warning("服务器 ipv6: host=$host, port=$port, type=$type")
|
||||
// SEE oicq_request.java at method analysisT17f
|
||||
}
|
||||
}
|
||||
|
||||
fun Input.readUShortLVString(): String = String(this.readUShortLVByteArray())
|
||||
}
|
Loading…
Reference in New Issue
Block a user