mirror of
https://github.com/mamoe/mirai.git
synced 2025-04-17 09:09:23 +08:00
Tlv writer (#2569)
* [core] TlvMapWriter * [core] bind tlv writing with writer * [core] Add checking to avoid wrong nest writing * [core] Drop Int.invoke * [core] Merge with dev * [core] Update style
This commit is contained in:
parent
48db1a022f
commit
434ef0cc39
mirai-core-utils/src
mirai-core/src/commonMain/kotlin/network/protocol/packet
@ -75,82 +75,6 @@ public inline fun ByteReadPacket.readPacketExact(
|
||||
): ByteReadPacket = this.readBytes(n).toReadPacket()
|
||||
|
||||
|
||||
public typealias TlvMap = MutableMap<Int, ByteArray>
|
||||
|
||||
public inline fun TlvMap.getOrFail(tag: Int): ByteArray {
|
||||
return this[tag] ?: error("cannot find tlv 0x${tag.toUHexString("")}($tag)")
|
||||
}
|
||||
|
||||
public inline fun TlvMap.getOrFail(tag: Int, lazyMessage: (tag: Int) -> String): ByteArray {
|
||||
return this[tag] ?: error(lazyMessage(tag))
|
||||
}
|
||||
|
||||
@Suppress("FunctionName")
|
||||
public inline fun Input._readTLVMap(tagSize: Int = 2, suppressDuplication: Boolean = true): TlvMap =
|
||||
_readTLVMap(true, tagSize, suppressDuplication)
|
||||
|
||||
@Suppress("DuplicatedCode", "FunctionName")
|
||||
public fun Input._readTLVMap(
|
||||
expectingEOF: Boolean = true,
|
||||
tagSize: Int,
|
||||
suppressDuplication: Boolean = true
|
||||
): TlvMap {
|
||||
val map = mutableMapOf<Int, ByteArray>()
|
||||
var key = 0
|
||||
|
||||
while (kotlin.run {
|
||||
try {
|
||||
key = when (tagSize) {
|
||||
1 -> readUByte().toInt()
|
||||
2 -> readUShort().toInt()
|
||||
4 -> readUInt().toInt()
|
||||
else -> error("Unsupported tag size: $tagSize")
|
||||
}
|
||||
} catch (e: Exception) { // java.nio.BufferUnderflowException is not a EOFException...
|
||||
if (expectingEOF) {
|
||||
return map
|
||||
}
|
||||
throw e
|
||||
}
|
||||
key
|
||||
}.toUByte() != UByte.MAX_VALUE) {
|
||||
|
||||
if (map.containsKey(key)) {
|
||||
@Suppress("ControlFlowWithEmptyBody")
|
||||
if (!suppressDuplication) {
|
||||
/*
|
||||
@Suppress("DEPRECATION")
|
||||
MiraiLogger.error(
|
||||
@Suppress("IMPLICIT_CAST_TO_ANY")
|
||||
"""
|
||||
Error readTLVMap:
|
||||
duplicated key ${when (tagSize) {
|
||||
1 -> key.toByte()
|
||||
2 -> key.toShort()
|
||||
4 -> key
|
||||
else -> error("unreachable")
|
||||
}.contentToString()}
|
||||
map=${map.contentToString()}
|
||||
duplicating value=${this.readUShortLVByteArray().toUHexString()}
|
||||
""".trimIndent()
|
||||
)*/
|
||||
} else {
|
||||
this.discardExact(this.readShort().toInt() and 0xffff)
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
map[key] = this.readBytes(readUShort().toInt())
|
||||
} catch (e: Exception) { // BufferUnderflowException, java.io.EOFException
|
||||
// if (expectingEOF) {
|
||||
// return map
|
||||
// }
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
return map
|
||||
}
|
||||
|
||||
public fun Input.readAllText(): String = Charsets.UTF_8.newDecoder().decode(this)
|
||||
|
||||
public inline fun Input.readString(length: Int, charset: Charset = Charsets.UTF_8): String =
|
||||
|
225
mirai-core-utils/src/commonMain/kotlin/TlvMap.kt
Normal file
225
mirai-core-utils/src/commonMain/kotlin/TlvMap.kt
Normal file
@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright 2019-2023 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/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import io.ktor.utils.io.core.*
|
||||
import kotlin.jvm.JvmField
|
||||
|
||||
public typealias TlvMap = MutableMap<Int, ByteArray>
|
||||
|
||||
public fun TlvMap(): TlvMap = linkedMapOf()
|
||||
|
||||
@Suppress("FunctionName")
|
||||
public fun Output._writeTlvMap(
|
||||
tagSize: Int,
|
||||
includeCount: Boolean = true,
|
||||
map: TlvMap,
|
||||
) {
|
||||
if (includeCount) {
|
||||
when (tagSize) {
|
||||
1 -> writeByte(map.size.toByte())
|
||||
2 -> writeShort(map.size.toShort())
|
||||
4 -> writeInt(map.size)
|
||||
else -> error("Unsupported tag size: $tagSize")
|
||||
}
|
||||
}
|
||||
|
||||
map.forEach { (key, value) ->
|
||||
when (tagSize) {
|
||||
1 -> writeByte(key.toByte())
|
||||
2 -> writeShort(key.toShort())
|
||||
4 -> writeInt(key)
|
||||
else -> error("Unsupported tag size: $tagSize")
|
||||
}
|
||||
|
||||
writeShort(value.size.toShort())
|
||||
writeFully(value)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
public class TlvMapWriter
|
||||
internal constructor(
|
||||
private val tagSize: Int,
|
||||
) {
|
||||
@JvmField
|
||||
internal val buffer = BytePacketBuilder()
|
||||
|
||||
@JvmField
|
||||
internal var counter: Int = 0
|
||||
|
||||
@PublishedApi
|
||||
@JvmField
|
||||
internal var isWriting: Boolean = false
|
||||
|
||||
private fun writeKey(key: Int) {
|
||||
when (tagSize) {
|
||||
1 -> buffer.writeByte(key.toByte())
|
||||
2 -> buffer.writeShort(key.toShort())
|
||||
4 -> buffer.writeInt(key)
|
||||
else -> error("Unsupported tag size: $tagSize")
|
||||
}
|
||||
counter++
|
||||
}
|
||||
|
||||
@PublishedApi
|
||||
internal fun ensureNotWriting() {
|
||||
if (isWriting) error("Cannot write a new Tlv when writing Tlv")
|
||||
}
|
||||
|
||||
public fun tlv(key: Int, data: ByteArray) {
|
||||
ensureNotWriting()
|
||||
tlv0(key, data)
|
||||
}
|
||||
|
||||
|
||||
private fun tlv0(key: Int, data: ByteArray) {
|
||||
writeKey(key)
|
||||
buffer.writeShort(data.size.toShort())
|
||||
buffer.writeFully(data)
|
||||
// println("Writing [${key.toUHexString()}](${data.size}) => " + data.toUHexString())
|
||||
}
|
||||
|
||||
public fun tlv(key: Int, data: ByteReadPacket) {
|
||||
ensureNotWriting()
|
||||
tlv0(key, data)
|
||||
}
|
||||
|
||||
|
||||
@PublishedApi
|
||||
internal fun tlv0(key: Int, data: ByteReadPacket) {
|
||||
writeKey(key)
|
||||
buffer.writeShort(data.remaining.toShort())
|
||||
|
||||
// println("Writing [${key.toUHexString()}](${data.remaining}) => " + data.copy()
|
||||
// .use { d1 -> d1.readBytes().toUHexString() })
|
||||
|
||||
buffer.writePacket(data)
|
||||
}
|
||||
|
||||
|
||||
public inline fun tlv(
|
||||
key: Int,
|
||||
crossinline builder: BytePacketBuilder.() -> Unit,
|
||||
) {
|
||||
ensureNotWriting()
|
||||
try {
|
||||
isWriting = true
|
||||
buildPacket(builder).use { tlv0(key, it) }
|
||||
} finally {
|
||||
isWriting = false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public fun Output._writeTlvMap(
|
||||
tagSize: Int = 2,
|
||||
includeCount: Boolean = true,
|
||||
block: TlvMapWriter.() -> Unit
|
||||
) {
|
||||
val writer = TlvMapWriter(tagSize)
|
||||
try {
|
||||
block(writer)
|
||||
if (includeCount) {
|
||||
when (tagSize) {
|
||||
1 -> writeByte(writer.counter.toByte())
|
||||
2 -> writeShort(writer.counter.toShort())
|
||||
4 -> writeInt(writer.counter)
|
||||
else -> error("Unsupported tag size: $tagSize")
|
||||
}
|
||||
}
|
||||
writer.buffer.build().use {
|
||||
// println(it.copy().use { it.readBytes().toUHexString() })
|
||||
|
||||
writePacket(it)
|
||||
}
|
||||
} finally {
|
||||
writer.buffer.release()
|
||||
}
|
||||
}
|
||||
|
||||
public fun TlvMap.getOrFail(tag: Int): ByteArray {
|
||||
return this[tag] ?: error("cannot find tlv 0x${tag.toUHexString("")}($tag)")
|
||||
}
|
||||
|
||||
public fun TlvMap.getOrFail(tag: Int, lazyMessage: (tag: Int) -> String): ByteArray {
|
||||
return this[tag] ?: error(lazyMessage(tag))
|
||||
}
|
||||
|
||||
@Suppress("FunctionName")
|
||||
public fun Input._readTLVMap(tagSize: Int = 2, suppressDuplication: Boolean = true): TlvMap =
|
||||
_readTLVMap(true, tagSize, suppressDuplication)
|
||||
|
||||
@Suppress("DuplicatedCode", "FunctionName")
|
||||
public fun Input._readTLVMap(
|
||||
expectingEOF: Boolean = true,
|
||||
tagSize: Int,
|
||||
suppressDuplication: Boolean = true
|
||||
): TlvMap {
|
||||
val map = linkedMapOf<Int, ByteArray>()
|
||||
var key = 0
|
||||
|
||||
while (kotlin.run {
|
||||
try {
|
||||
key = when (tagSize) {
|
||||
1 -> readUByte().toInt()
|
||||
2 -> readUShort().toInt()
|
||||
4 -> readUInt().toInt()
|
||||
else -> error("Unsupported tag size: $tagSize")
|
||||
}
|
||||
} catch (e: Exception) { // java.nio.BufferUnderflowException is not a EOFException...
|
||||
if (expectingEOF) {
|
||||
return map
|
||||
}
|
||||
throw e
|
||||
}
|
||||
key
|
||||
}.toUByte() != UByte.MAX_VALUE) {
|
||||
|
||||
if (map.containsKey(key)) {
|
||||
// println("reading ${key.toUHexString()}")
|
||||
|
||||
if (!suppressDuplication) {
|
||||
/*
|
||||
@Suppress("DEPRECATION")
|
||||
MiraiLogger.error(
|
||||
@Suppress("IMPLICIT_CAST_TO_ANY")
|
||||
"""
|
||||
Error readTLVMap:
|
||||
duplicated key ${when (tagSize) {
|
||||
1 -> key.toByte()
|
||||
2 -> key.toShort()
|
||||
4 -> key
|
||||
else -> error("unreachable")
|
||||
}.contentToString()}
|
||||
map=${map.contentToString()}
|
||||
duplicating value=${this.readUShortLVByteArray().toUHexString()}
|
||||
""".trimIndent()
|
||||
)*/
|
||||
} else {
|
||||
this.discardExact(this.readShort().toInt() and 0xffff)
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
val len = readUShort().toInt()
|
||||
val data = this.readBytes(len)
|
||||
// println("Writing [${key.toUHexString()}]($len) => ${data.toUHexString()}")
|
||||
map[key] = data
|
||||
} catch (e: Exception) { // BufferUnderflowException, java.io.EOFException
|
||||
// if (expectingEOF) {
|
||||
// return map
|
||||
// }
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
return map
|
||||
}
|
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2019-2023 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/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import io.ktor.utils.io.core.*
|
||||
import kotlin.random.Random
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertContentEquals
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
internal class TlvMapTest {
|
||||
private fun dumpTlvMap(map: TlvMap) = buildString {
|
||||
append("tlvMap {\n")
|
||||
map.forEach { (k, v) ->
|
||||
append(" ").append(k.toUHexString()).append(" = ").append(v.toUHexString()).append("\n")
|
||||
}
|
||||
append("}")
|
||||
}
|
||||
|
||||
private fun assertTlvMapEquals(
|
||||
expected: TlvMap, actual: TlvMap,
|
||||
) {
|
||||
assertEquals(expected.size, actual.size, "map size not match")
|
||||
|
||||
expected.keys.forEach { key ->
|
||||
assertTrue("Missing key[$key] in actual") { actual.containsKey(key) }
|
||||
}
|
||||
actual.keys.forEach { key ->
|
||||
assertTrue("Missing key[$key] in expected") { expected.containsKey(key) }
|
||||
}
|
||||
|
||||
expected.forEach { (key, value) ->
|
||||
assertContentEquals(value, actual[key])
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTlvWriterNoLength() {
|
||||
testTlvWriter(true)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTlvWriterWithCount() {
|
||||
testTlvWriter(false)
|
||||
}
|
||||
|
||||
private fun testTlvWriter(withCount: Boolean) {
|
||||
repeat(500) {
|
||||
val tlvMap = TlvMap()
|
||||
val rand = buildPacket {
|
||||
_writeTlvMap(Short.SIZE_BYTES, includeCount = withCount) {
|
||||
|
||||
repeat(Random.nextInt().and(0xFF).coerceAtLeast(20)) {
|
||||
val nextKey = Random.nextInt().and(0xFF0)
|
||||
if (!tlvMap.containsKey(nextKey)) {
|
||||
val randData = ByteArray(Random.nextInt().and(0xFFF))
|
||||
Random.nextBytes(randData)
|
||||
|
||||
tlvMap[nextKey] = randData
|
||||
|
||||
tlv(nextKey, randData)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}.also { pkg ->
|
||||
if (withCount) pkg.discardExact(2)
|
||||
}._readTLVMap()
|
||||
|
||||
try {
|
||||
assertTlvMapEquals(tlvMap, rand)
|
||||
} catch (e: Throwable) {
|
||||
|
||||
println("gen: " + dumpTlvMap(tlvMap))
|
||||
println("read: " + dumpTlvMap(rand))
|
||||
|
||||
throw e
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTlvWriterWithCounter() {
|
||||
val expected = buildPacket {
|
||||
writeShort(4) // count of TLVs
|
||||
|
||||
writeShort(0x01)
|
||||
writeHexWithLength("66ccff")
|
||||
|
||||
writeShort(0x04)
|
||||
writeHexWithLength("114514")
|
||||
|
||||
writeShort(0x19)
|
||||
writeHexWithLength("198100")
|
||||
|
||||
writeShort(0x233)
|
||||
writeHexWithLength("666666")
|
||||
}.readBytes()
|
||||
|
||||
val actual = buildPacket {
|
||||
_writeTlvMap {
|
||||
tlv(0x001) { writeHex("66ccff") }
|
||||
tlv(0x004) { writeHex("114514") }
|
||||
tlv(0x019) { writeHex("198100") }
|
||||
tlv(0x233) { writeHex("666666") }
|
||||
|
||||
println("counter = $counter")
|
||||
}
|
||||
}.readBytes()
|
||||
|
||||
println(expected.toUHexString())
|
||||
println(actual.toUHexString())
|
||||
|
||||
assertContentEquals(expected, actual)
|
||||
}
|
||||
|
||||
private fun Output.writeHex(data: String) {
|
||||
writeFully(data.hexToBytes())
|
||||
}
|
||||
|
||||
private fun Output.writeHexWithLength(data: String) {
|
||||
val hxd = data.hexToBytes()
|
||||
writeShort(hxd.size.toShort())
|
||||
writeFully(hxd)
|
||||
}
|
||||
}
|
@ -49,40 +49,38 @@ internal fun TlvMap.smartToString(leadingLineBreak: Boolean = true, sorted: Bool
|
||||
@JvmInline
|
||||
internal value class Tlv(val value: ByteArray)
|
||||
|
||||
internal fun BytePacketBuilder.t1(uin: Long, ip: ByteArray) {
|
||||
internal fun TlvMapWriter.t1(uin: Long, ip: ByteArray) {
|
||||
require(ip.size == 4) { "ip.size must == 4" }
|
||||
writeShort(0x1)
|
||||
writeShortLVPacket {
|
||||
|
||||
tlv(0x01) {
|
||||
writeShort(1) // _ip_ver
|
||||
writeInt(Random.nextInt())
|
||||
writeInt(uin.toInt())
|
||||
writeInt(currentTimeSeconds().toInt())
|
||||
writeFully(ip)
|
||||
writeShort(0)
|
||||
} shouldEqualsTo 20
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t2(captchaCode: String, captchaToken: ByteArray, sigVer: Short = 0) {
|
||||
writeShort(0x2)
|
||||
writeShortLVPacket {
|
||||
internal fun TlvMapWriter.t2(captchaCode: String, captchaToken: ByteArray, sigVer: Short = 0) {
|
||||
tlv(0x02) {
|
||||
writeShort(sigVer)
|
||||
writeShortLVString(captchaCode)
|
||||
writeShortLVByteArray(captchaToken)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t8(
|
||||
internal fun TlvMapWriter.t8(
|
||||
localId: Int = 2052
|
||||
) {
|
||||
writeShort(0x8)
|
||||
writeShortLVPacket {
|
||||
tlv(0x08) {
|
||||
writeShort(0)
|
||||
writeInt(localId) // localId
|
||||
writeShort(0)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t16(
|
||||
internal fun TlvMapWriter.t16(
|
||||
ssoVersion: Int,
|
||||
subAppId: Long,
|
||||
guid: ByteArray,
|
||||
@ -90,8 +88,7 @@ internal fun BytePacketBuilder.t16(
|
||||
apkVersionName: ByteArray,
|
||||
apkSignatureMd5: ByteArray
|
||||
) {
|
||||
writeShort(0x16)
|
||||
writeShortLVPacket {
|
||||
tlv(0x16) {
|
||||
writeInt(ssoVersion)
|
||||
writeInt(16)
|
||||
writeInt(subAppId.toInt())
|
||||
@ -102,14 +99,13 @@ internal fun BytePacketBuilder.t16(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t18(
|
||||
internal fun TlvMapWriter.t18(
|
||||
appId: Long,
|
||||
appClientVersion: Int = 0,
|
||||
uin: Long,
|
||||
constant1_always_0: Int = 0
|
||||
) {
|
||||
writeShort(0x18)
|
||||
writeShortLVPacket {
|
||||
tlv(0x18) {
|
||||
writeShort(1) //_ping_version
|
||||
writeInt(0x00_00_06_00) //_sso_version=1536
|
||||
writeInt(appId.toInt())
|
||||
@ -117,10 +113,10 @@ internal fun BytePacketBuilder.t18(
|
||||
writeInt(uin.toInt())
|
||||
writeShort(constant1_always_0.toShort())
|
||||
writeShort(0)
|
||||
} shouldEqualsTo 22
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t1b(
|
||||
internal fun TlvMapWriter.t1b(
|
||||
micro: Int = 0,
|
||||
version: Int = 0,
|
||||
size: Int = 3,
|
||||
@ -129,8 +125,7 @@ internal fun BytePacketBuilder.t1b(
|
||||
ecLevel: Int = 2,
|
||||
hint: Int = 2
|
||||
) {
|
||||
writeShort(0x1b)
|
||||
writeShortLVPacket {
|
||||
tlv(0x1b) {
|
||||
writeInt(micro)
|
||||
writeInt(version)
|
||||
writeInt(size)
|
||||
@ -142,11 +137,10 @@ internal fun BytePacketBuilder.t1b(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t1d(
|
||||
internal fun TlvMapWriter.t1d(
|
||||
miscBitmap: Int,
|
||||
) {
|
||||
writeShort(0x1d)
|
||||
writeShortLVPacket {
|
||||
tlv(0x1d) {
|
||||
writeByte(1)
|
||||
writeInt(miscBitmap)
|
||||
writeInt(0)
|
||||
@ -155,7 +149,7 @@ internal fun BytePacketBuilder.t1d(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t1f(
|
||||
internal fun TlvMapWriter.t1f(
|
||||
isRoot: Boolean = false,
|
||||
osName: ByteArray,
|
||||
osVersion: ByteArray,
|
||||
@ -163,8 +157,7 @@ internal fun BytePacketBuilder.t1f(
|
||||
apn: ByteArray,
|
||||
networkType: Short = 2,
|
||||
) {
|
||||
writeShort(0x1f)
|
||||
writeShortLVPacket {
|
||||
tlv(0x1f) {
|
||||
writeByte(if (isRoot) 1 else 0)
|
||||
writeShortLVByteArray(osName)
|
||||
writeShortLVByteArray(osVersion)
|
||||
@ -175,23 +168,21 @@ internal fun BytePacketBuilder.t1f(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t33(
|
||||
internal fun TlvMapWriter.t33(
|
||||
guid: ByteArray,
|
||||
) {
|
||||
writeShort(0x33)
|
||||
writeShortLVByteArray(guid)
|
||||
tlv(0x33, guid)
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t35(
|
||||
internal fun TlvMapWriter.t35(
|
||||
productType: Int
|
||||
) {
|
||||
writeShort(0x35)
|
||||
writeShortLVPacket {
|
||||
tlv(0x35) {
|
||||
writeInt(productType)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t106(
|
||||
internal fun TlvMapWriter.t106(
|
||||
client: QQAndroidClient,
|
||||
appId: Long = 16L,
|
||||
passwordMd5: ByteArray,
|
||||
@ -213,11 +204,10 @@ internal fun BytePacketBuilder.t106(
|
||||
)
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t106(
|
||||
internal fun TlvMapWriter.t106(
|
||||
encryptA1: ByteArray
|
||||
) {
|
||||
writeShort(0x106)
|
||||
writeShortLVPacket {
|
||||
tlv(0x106) {
|
||||
writeFully(encryptA1)
|
||||
}
|
||||
}
|
||||
@ -225,7 +215,7 @@ internal fun BytePacketBuilder.t106(
|
||||
/**
|
||||
* A1
|
||||
*/
|
||||
internal fun BytePacketBuilder.t106(
|
||||
internal fun TlvMapWriter.t106(
|
||||
appId: Long = 16L,
|
||||
subAppId: Long,
|
||||
appClientVersion: Int = 0,
|
||||
@ -240,12 +230,11 @@ internal fun BytePacketBuilder.t106(
|
||||
loginType: LoginType,
|
||||
ssoVersion: Int,
|
||||
) {
|
||||
writeShort(0x106)
|
||||
passwordMd5.requireSize(16)
|
||||
tgtgtKey.requireSize(16)
|
||||
guid?.requireSize(16)
|
||||
|
||||
writeShortLVPacket {
|
||||
tlv(0x106) {
|
||||
encryptAndWrite(
|
||||
(passwordMd5 + ByteArray(4) + (salt.takeIf { it != 0L } ?: uin).toInt()
|
||||
.toByteArray()).md5()
|
||||
@ -287,13 +276,12 @@ internal fun BytePacketBuilder.t106(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t116(
|
||||
internal fun TlvMapWriter.t116(
|
||||
miscBitmap: Int,
|
||||
subSigMap: Int,
|
||||
appIdList: LongArray = longArrayOf(1600000226L)
|
||||
) {
|
||||
writeShort(0x116)
|
||||
writeShortLVPacket {
|
||||
tlv(0x116) {
|
||||
writeByte(0) // _ver
|
||||
writeInt(miscBitmap) // 184024956
|
||||
writeInt(subSigMap) // 66560
|
||||
@ -305,131 +293,122 @@ internal fun BytePacketBuilder.t116(
|
||||
}
|
||||
|
||||
|
||||
internal fun BytePacketBuilder.t100(
|
||||
internal fun TlvMapWriter.t100(
|
||||
appId: Long = 16,
|
||||
subAppId: Long,
|
||||
appClientVersion: Int,
|
||||
ssoVersion: Int,
|
||||
mainSigMap: Int
|
||||
) {
|
||||
writeShort(0x100)
|
||||
writeShortLVPacket {
|
||||
tlv(0x100) {
|
||||
writeShort(1)//db_buf_ver
|
||||
writeInt(ssoVersion)//sso_ver
|
||||
writeInt(appId.toInt())
|
||||
writeInt(subAppId.toInt())
|
||||
writeInt(appClientVersion)
|
||||
writeInt(mainSigMap) // sigMap, 34869472?
|
||||
} shouldEqualsTo 22
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t10a(
|
||||
internal fun TlvMapWriter.t10a(
|
||||
tgt: ByteArray,
|
||||
) {
|
||||
writeShort(0x10a)
|
||||
writeShortLVPacket {
|
||||
tlv(0x10a) {
|
||||
writeFully(tgt)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal fun BytePacketBuilder.t107(
|
||||
internal fun TlvMapWriter.t107(
|
||||
picType: Int,
|
||||
capType: Int = 0,
|
||||
picSize: Int = 0,
|
||||
retType: Int = 1
|
||||
) {
|
||||
writeShort(0x107)
|
||||
writeShortLVPacket {
|
||||
tlv(0x107) {
|
||||
writeShort(picType.toShort())
|
||||
writeByte(capType.toByte())
|
||||
writeShort(picSize.toShort())
|
||||
writeByte(retType.toByte())
|
||||
} shouldEqualsTo 6
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t108(
|
||||
internal fun TlvMapWriter.t108(
|
||||
ksid: ByteArray
|
||||
) {
|
||||
// require(ksid.size == 16) { "ksid should length 16" }
|
||||
writeShort(0x108)
|
||||
writeShortLVPacket {
|
||||
tlv(0x108) {
|
||||
writeFully(ksid)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t104(
|
||||
internal fun TlvMapWriter.t104(
|
||||
t104Data: ByteArray
|
||||
) {
|
||||
writeShort(0x104)
|
||||
writeShortLVPacket {
|
||||
tlv(0x104) {
|
||||
writeFully(t104Data)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t547(
|
||||
internal fun TlvMapWriter.t547(
|
||||
t547Data: ByteArray
|
||||
) {
|
||||
writeShort(0x547)
|
||||
writeShortLVPacket {
|
||||
tlv(0x547) {
|
||||
writeFully(t547Data)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t174(
|
||||
internal fun TlvMapWriter.t174(
|
||||
t174Data: ByteArray
|
||||
) {
|
||||
writeShort(0x174)
|
||||
writeShortLVPacket {
|
||||
tlv(0x174) {
|
||||
writeFully(t174Data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal fun BytePacketBuilder.t17a(
|
||||
internal fun TlvMapWriter.t17a(
|
||||
value: Int = 0
|
||||
) {
|
||||
writeShort(0x17a)
|
||||
writeShortLVPacket {
|
||||
tlv(0x17a) {
|
||||
writeInt(value)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t197() {
|
||||
writeShort(0x197)
|
||||
writeFully(byteArrayOf(0, 1, 0))
|
||||
internal fun TlvMapWriter.t197() {
|
||||
tlv(0x197) {
|
||||
writeByte(0)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t198() {
|
||||
writeShort(0x198)
|
||||
writeFully(byteArrayOf(0, 1, 0))
|
||||
internal fun TlvMapWriter.t198() {
|
||||
tlv(0x198) {
|
||||
writeByte(0)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t19e(
|
||||
internal fun TlvMapWriter.t19e(
|
||||
value: Int = 0
|
||||
) {
|
||||
writeShort(0x19e)
|
||||
writeShortLVPacket {
|
||||
tlv(0x19e) {
|
||||
writeShort(1)
|
||||
writeByte(value.toByte())
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t17c(
|
||||
internal fun TlvMapWriter.t17c(
|
||||
t17cData: ByteArray
|
||||
) {
|
||||
writeShort(0x17c)
|
||||
writeShortLVPacket {
|
||||
tlv(0x17c) {
|
||||
writeShort(t17cData.size.toShort())
|
||||
writeFully(t17cData)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t401(
|
||||
internal fun TlvMapWriter.t401(
|
||||
t401Data: ByteArray
|
||||
) {
|
||||
writeShort(0x401)
|
||||
writeShortLVPacket {
|
||||
tlv(0x401) {
|
||||
writeFully(t401Data)
|
||||
}
|
||||
}
|
||||
@ -437,35 +416,32 @@ internal fun BytePacketBuilder.t401(
|
||||
/**
|
||||
* @param apkId application.getPackageName().getBytes()
|
||||
*/
|
||||
internal fun BytePacketBuilder.t142(
|
||||
internal fun TlvMapWriter.t142(
|
||||
apkId: ByteArray
|
||||
) {
|
||||
writeShort(0x142)
|
||||
writeShortLVPacket {
|
||||
tlv(0x142) {
|
||||
writeShort(0) //_version
|
||||
writeShortLVByteArrayLimitedLength(apkId, 32)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t143(
|
||||
internal fun TlvMapWriter.t143(
|
||||
d2: ByteArray
|
||||
) {
|
||||
writeShort(0x143)
|
||||
writeShortLVPacket {
|
||||
tlv(0x143) {
|
||||
writeFully(d2)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t112(
|
||||
internal fun TlvMapWriter.t112(
|
||||
nonNumberUin: ByteArray
|
||||
) {
|
||||
writeShort(0x112)
|
||||
writeShortLVPacket {
|
||||
tlv(0x112) {
|
||||
writeFully(nonNumberUin)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t144(
|
||||
internal fun TlvMapWriter.t144(
|
||||
client: QQAndroidClient
|
||||
) {
|
||||
return t144(
|
||||
@ -488,7 +464,7 @@ internal fun BytePacketBuilder.t144(
|
||||
)
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t144(
|
||||
internal fun TlvMapWriter.t144(
|
||||
// t109
|
||||
androidId: ByteArray,
|
||||
|
||||
@ -515,34 +491,32 @@ internal fun BytePacketBuilder.t144(
|
||||
// encrypt
|
||||
tgtgtKey: ByteArray
|
||||
) {
|
||||
writeShort(0x144)
|
||||
writeShortLVPacket {
|
||||
tlv(0x144) {
|
||||
encryptAndWrite(tgtgtKey) {
|
||||
writeShort(5) // tlv count
|
||||
t109(androidId)
|
||||
t52d(androidDevInfo)
|
||||
t124(osType, osVersion, networkType, simInfo, unknown, apn)
|
||||
t128(isGuidFromFileNull, isGuidAvailable, isGuidChanged, guidFlag, buildModel, guid, buildBrand)
|
||||
t16e(buildModel)
|
||||
_writeTlvMap {
|
||||
t109(androidId)
|
||||
t52d(androidDevInfo)
|
||||
t124(osType, osVersion, networkType, simInfo, unknown, apn)
|
||||
t128(isGuidFromFileNull, isGuidAvailable, isGuidChanged, guidFlag, buildModel, guid, buildBrand)
|
||||
t16e(buildModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal fun BytePacketBuilder.t109(
|
||||
internal fun TlvMapWriter.t109(
|
||||
androidId: ByteArray
|
||||
) {
|
||||
writeShort(0x109)
|
||||
writeShortLVPacket {
|
||||
tlv(0x109) {
|
||||
writeFully(androidId.md5())
|
||||
} shouldEqualsTo 16
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t52d(
|
||||
internal fun TlvMapWriter.t52d(
|
||||
androidDevInfo: ByteArray // oicq.wlogin_sdk.tools.util#get_android_dev_info
|
||||
) {
|
||||
writeShort(0x52d)
|
||||
writeShortLVPacket {
|
||||
tlv(0x52d) {
|
||||
writeFully(androidDevInfo)
|
||||
|
||||
// 0A 07 75 6E 6B 6E 6F 77 6E 12 7E 4C 69 6E 75 78 20 76 65 72 73 69 6F 6E 20 34 2E 39 2E 33 31 20 28 62 75 69 6C 64 40 42 75 69 6C 64 32 29 20 28 67 63 63 20 76 65 72 73 69 6F 6E 20 34 2E 39 20 32 30 31 35 30 31 32 33 20 28 70 72 65 72 65 6C 65 61 73 65 29 20 28 47 43 43 29 20 29 20 23 31 20 53 4D 50 20 50 52 45 45 4D 50 54 20 54 68 75 20 44 65 63 20 31 32 20 31 35 3A 33 30 3A 35 35 20 49 53 54 20 32 30 31 39 1A 03 52 45 4C 22 03 33 32 37 2A 41 4F 6E 65 50 6C 75 73 2F 4F 6E 65 50 6C 75 73 35 2F 4F 6E 65 50 6C 75 73 35 3A 37 2E 31 2E 31 2F 4E 4D 46 32 36 58 2F 31 30 31 37 31 36 31 37 3A 75 73 65 72 2F 72 65 6C 65 61 73 65 2D 6B 65 79 73 32 24 36 63 39 39 37 36 33 66 2D 66 62 34 32 2D 34 38 38 31 2D 62 37 32 65 2D 63 37 61 61 38 61 36 63 31 63 61 34 3A 10 65 38 63 37 30 35 34 64 30 32 66 33 36 33 64 30 42 0A 6E 6F 20 6D 65 73 73 61 67 65 4A 03 33 32 37
|
||||
@ -550,7 +524,7 @@ internal fun BytePacketBuilder.t52d(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t124(
|
||||
internal fun TlvMapWriter.t124(
|
||||
osType: ByteArray = "android".toByteArray(),
|
||||
osVersion: ByteArray, // Build.VERSION.RELEASE.toByteArray()
|
||||
networkType: NetworkType, //oicq.wlogin_sdk.tools.util#get_network_type
|
||||
@ -558,8 +532,7 @@ internal fun BytePacketBuilder.t124(
|
||||
address: ByteArray, // always new byte[0]
|
||||
apn: ByteArray = "wifi".toByteArray() // oicq.wlogin_sdk.tools.util#get_apn_string
|
||||
) {
|
||||
writeShort(0x124)
|
||||
writeShortLVPacket {
|
||||
tlv(0x124) {
|
||||
writeShortLVByteArrayLimitedLength(osType, 16)
|
||||
writeShortLVByteArrayLimitedLength(osVersion, 16)
|
||||
writeShort(networkType.value.toShort())
|
||||
@ -569,7 +542,7 @@ internal fun BytePacketBuilder.t124(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t128(
|
||||
internal fun TlvMapWriter.t128(
|
||||
isGuidFromFileNull: Boolean = false, // 保存到文件的 GUID 是否为 null
|
||||
isGuidAvailable: Boolean = true, // GUID 是否可用(计算/读取成功)
|
||||
isGuidChanged: Boolean = false, // GUID 是否有变动
|
||||
@ -610,8 +583,7 @@ internal fun BytePacketBuilder.t128(
|
||||
guid: ByteArray,
|
||||
buildBrand: ByteArray // android.os.Build.BRAND
|
||||
) {
|
||||
writeShort(0x128)
|
||||
writeShortLVPacket {
|
||||
tlv(0x128) {
|
||||
writeShort(0)
|
||||
writeByte(isGuidFromFileNull.toByte())
|
||||
writeByte(isGuidAvailable.toByte())
|
||||
@ -623,71 +595,64 @@ internal fun BytePacketBuilder.t128(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t16e(
|
||||
internal fun TlvMapWriter.t16e(
|
||||
buildModel: ByteArray
|
||||
) {
|
||||
writeShort(0x16e)
|
||||
writeShortLVPacket {
|
||||
tlv(0x16e) {
|
||||
writeFully(buildModel)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t145(
|
||||
internal fun TlvMapWriter.t145(
|
||||
guid: ByteArray
|
||||
) {
|
||||
writeShort(0x145)
|
||||
writeShortLVPacket {
|
||||
tlv(0x145) {
|
||||
writeFully(guid)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t147(
|
||||
internal fun TlvMapWriter.t147(
|
||||
appId: Long,
|
||||
apkVersionName: ByteArray,
|
||||
apkSignatureMd5: ByteArray
|
||||
) {
|
||||
writeShort(0x147)
|
||||
writeShortLVPacket {
|
||||
tlv(0x147) {
|
||||
writeInt(appId.toInt())
|
||||
writeShortLVByteArrayLimitedLength(apkVersionName, 32)
|
||||
writeShortLVByteArrayLimitedLength(apkSignatureMd5, 32)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t166(
|
||||
internal fun TlvMapWriter.t166(
|
||||
imageType: Int
|
||||
) {
|
||||
writeShort(0x166)
|
||||
writeShortLVPacket {
|
||||
tlv(0x166) {
|
||||
writeByte(imageType.toByte())
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t16a(
|
||||
internal fun TlvMapWriter.t16a(
|
||||
noPicSig: ByteArray // unknown source
|
||||
) {
|
||||
writeShort(0x16a)
|
||||
writeShortLVPacket {
|
||||
tlv(0x16a) {
|
||||
writeFully(noPicSig)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t154(
|
||||
internal fun TlvMapWriter.t154(
|
||||
ssoSequenceId: Int // starts from 0
|
||||
) {
|
||||
writeShort(0x154)
|
||||
writeShortLVPacket {
|
||||
tlv(0x154) {
|
||||
writeInt(ssoSequenceId)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t141(
|
||||
internal fun TlvMapWriter.t141(
|
||||
simInfo: ByteArray,
|
||||
networkType: NetworkType,
|
||||
apn: ByteArray
|
||||
) {
|
||||
writeShort(0x141)
|
||||
writeShortLVPacket {
|
||||
tlv(0x141) {
|
||||
writeShort(1) // version
|
||||
writeShortLVByteArray(simInfo)
|
||||
writeShort(networkType.value.toShort())
|
||||
@ -695,7 +660,7 @@ internal fun BytePacketBuilder.t141(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t511(
|
||||
internal fun TlvMapWriter.t511(
|
||||
domains: List<String> = listOf(
|
||||
"tenpay.com",
|
||||
"openmobile.qq.com",
|
||||
@ -713,8 +678,7 @@ internal fun BytePacketBuilder.t511(
|
||||
"mma.qq.com",
|
||||
)
|
||||
) {
|
||||
writeShort(0x511)
|
||||
writeShortLVPacket {
|
||||
tlv(0x511) {
|
||||
val list = domains.filter { it.isNotEmpty() }
|
||||
writeShort(list.size.toShort())
|
||||
list.forEach { element ->
|
||||
@ -737,24 +701,22 @@ internal fun BytePacketBuilder.t511(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t172(
|
||||
internal fun TlvMapWriter.t172(
|
||||
rollbackSig: ByteArray // 由服务器发来的 tlv_t172 获得
|
||||
) {
|
||||
writeShort(0x172)
|
||||
writeShortLVPacket {
|
||||
tlv(0x172) {
|
||||
writeFully(rollbackSig)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t185() {
|
||||
writeShort(0x185)
|
||||
writeShortLVPacket {
|
||||
internal fun TlvMapWriter.t185() {
|
||||
tlv(0x185) {
|
||||
writeByte(1)
|
||||
writeByte(1)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t400(
|
||||
internal fun TlvMapWriter.t400(
|
||||
/**
|
||||
* if (var1[2] != null && var1[2].length > 0) {
|
||||
this._G = (byte[])var1[2].clone();
|
||||
@ -768,8 +730,7 @@ internal fun BytePacketBuilder.t400(
|
||||
subAppId: Long,
|
||||
randomSeed: ByteArray
|
||||
) {
|
||||
writeShort(0x400)
|
||||
writeShortLVPacket {
|
||||
tlv(0x400) {
|
||||
encryptAndWrite(g) {
|
||||
writeByte(1) // version
|
||||
writeLong(uin)
|
||||
@ -784,62 +745,56 @@ internal fun BytePacketBuilder.t400(
|
||||
}
|
||||
|
||||
|
||||
internal fun BytePacketBuilder.t187(
|
||||
internal fun TlvMapWriter.t187(
|
||||
macAddress: ByteArray
|
||||
) {
|
||||
writeShort(0x187)
|
||||
writeShortLVPacket {
|
||||
tlv(0x187) {
|
||||
writeFully(macAddress.md5()) // may be md5
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal fun BytePacketBuilder.t188(
|
||||
internal fun TlvMapWriter.t188(
|
||||
androidId: ByteArray
|
||||
) {
|
||||
writeShort(0x188)
|
||||
writeShortLVPacket {
|
||||
tlv(0x188) {
|
||||
writeFully(androidId.md5())
|
||||
} shouldEqualsTo 16
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t193(
|
||||
internal fun TlvMapWriter.t193(
|
||||
ticket: String
|
||||
) {
|
||||
writeShort(0x193)
|
||||
writeShortLVPacket {
|
||||
tlv(0x193) {
|
||||
writeFully(ticket.toByteArray())
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t194(
|
||||
internal fun TlvMapWriter.t194(
|
||||
imsiMd5: ByteArray
|
||||
) {
|
||||
imsiMd5 requireSize 16
|
||||
|
||||
writeShort(0x194)
|
||||
writeShortLVPacket {
|
||||
tlv(0x194) {
|
||||
writeFully(imsiMd5)
|
||||
} shouldEqualsTo 16
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t191(
|
||||
internal fun TlvMapWriter.t191(
|
||||
K: Int = 0x82
|
||||
) {
|
||||
writeShort(0x191)
|
||||
writeShortLVPacket {
|
||||
tlv(0x191) {
|
||||
writeByte(K.toByte())
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t201(
|
||||
internal fun TlvMapWriter.t201(
|
||||
L: ByteArray = byteArrayOf(), // unknown
|
||||
channelId: ByteArray = byteArrayOf(),
|
||||
clientType: ByteArray = "qq".toByteArray(),
|
||||
N: ByteArray
|
||||
) {
|
||||
writeShort(0x201)
|
||||
writeShortLVPacket {
|
||||
tlv(0x201) {
|
||||
writeShortLVByteArray(L)
|
||||
writeShortLVByteArray(channelId)
|
||||
writeShortLVByteArray(clientType)
|
||||
@ -847,73 +802,66 @@ internal fun BytePacketBuilder.t201(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t202(
|
||||
internal fun TlvMapWriter.t202(
|
||||
wifiBSSID: ByteArray,
|
||||
wifiSSID: ByteArray
|
||||
) {
|
||||
writeShort(0x202)
|
||||
writeShortLVPacket {
|
||||
tlv(0x202) {
|
||||
writeShortLVByteArrayLimitedLength(wifiBSSID, 16)
|
||||
writeShortLVByteArrayLimitedLength(wifiSSID, 32)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t177(
|
||||
internal fun TlvMapWriter.t177(
|
||||
buildTime: Long = 1571193922L, // wtLogin BuildTime
|
||||
buildVersion: String = "6.0.0.2413" // wtLogin SDK Version
|
||||
) {
|
||||
writeShort(0x177)
|
||||
writeShortLVPacket {
|
||||
tlv(0x177) {
|
||||
writeByte(1)
|
||||
writeInt(buildTime.toInt())
|
||||
writeShortLVString(buildVersion)
|
||||
} // shouldEqualsTo 0x11
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t516( // 1302
|
||||
internal fun TlvMapWriter.t516( // 1302
|
||||
sourceType: Int = 0 // always 0
|
||||
) {
|
||||
writeShort(0x516)
|
||||
writeShortLVPacket {
|
||||
tlv(0x516) {
|
||||
writeInt(sourceType)
|
||||
} shouldEqualsTo 4
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t521( // 1313
|
||||
internal fun TlvMapWriter.t521( // 1313
|
||||
productType: Int = 0, // coz setProductType is never used
|
||||
unknown: Short = 0 // const
|
||||
) {
|
||||
writeShort(0x521)
|
||||
writeShortLVPacket {
|
||||
tlv(0x521) {
|
||||
writeInt(productType)
|
||||
writeShort(unknown)
|
||||
} shouldEqualsTo 6
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t52c(
|
||||
internal fun TlvMapWriter.t52c(
|
||||
// ?
|
||||
) {
|
||||
writeShort(0x52c)
|
||||
writeShortLVPacket {
|
||||
tlv(0x52c) {
|
||||
writeByte(1)
|
||||
writeLong(-1)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t536( // 1334
|
||||
internal fun TlvMapWriter.t536( // 1334
|
||||
loginExtraData: ByteArray
|
||||
) {
|
||||
writeShort(0x536)
|
||||
writeShortLVPacket {
|
||||
tlv(0x536) {
|
||||
writeFully(loginExtraData)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t536( // 1334
|
||||
internal fun TlvMapWriter.t536( // 1334
|
||||
loginExtraData: Collection<LoginExtraData>
|
||||
) {
|
||||
writeShort(0x536)
|
||||
writeShortLVPacket {
|
||||
tlv(0x536) {
|
||||
//com.tencent.loginsecsdk.ProtocolDet#packExtraData
|
||||
writeByte(1) // const
|
||||
writeByte(loginExtraData.size.toByte()) // data count
|
||||
@ -923,45 +871,44 @@ internal fun BytePacketBuilder.t536( // 1334
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t525(
|
||||
internal fun TlvMapWriter.t525(
|
||||
loginExtraData: Collection<LoginExtraData>,
|
||||
) {
|
||||
writeShort(0x525)
|
||||
writeShortLVPacket {
|
||||
writeShort(1)
|
||||
t536(loginExtraData)
|
||||
tlv(0x525) {
|
||||
_writeTlvMap {
|
||||
t536(loginExtraData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t525(
|
||||
internal fun TlvMapWriter.t525(
|
||||
t536: ByteReadPacket = buildPacket {
|
||||
t536(buildPacket {
|
||||
//com.tencent.loginsecsdk.ProtocolDet#packExtraData
|
||||
writeByte(1) // const
|
||||
writeByte(0) // data count
|
||||
}.readBytes())
|
||||
_writeTlvMap(includeCount = false) {
|
||||
t536(buildPacket {
|
||||
//com.tencent.loginsecsdk.ProtocolDet#packExtraData
|
||||
writeByte(1) // const
|
||||
writeByte(0) // data count
|
||||
}.readBytes())
|
||||
}
|
||||
}
|
||||
) {
|
||||
writeShort(0x525)
|
||||
writeShortLVPacket {
|
||||
tlv(0x525) {
|
||||
writeShort(1)
|
||||
writePacket(t536)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t544( // 1334
|
||||
internal fun TlvMapWriter.t544( // 1334
|
||||
) {
|
||||
writeShort(0x544)
|
||||
writeShortLVPacket {
|
||||
tlv(0x544) {
|
||||
writeFully(byteArrayOf(0, 0, 0, 11)) // means native throws exception
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.t318(
|
||||
internal fun TlvMapWriter.t318(
|
||||
tgtQR: ByteArray // unknown
|
||||
) {
|
||||
writeShort(0x318)
|
||||
writeShortLVPacket {
|
||||
tlv(0x318) {
|
||||
writeFully(tgtQR)
|
||||
}
|
||||
}
|
||||
|
@ -125,20 +125,21 @@ internal class WtLogin {
|
||||
) {
|
||||
writeOicqRequestPacket(client, commandId = 0x0810) {
|
||||
writeShort(17) // subCommand
|
||||
writeShort(12)
|
||||
t100(16, client.subAppId, client.appClientVersion, client.ssoVersion, client.mainSigMap)
|
||||
t108(client.ksid)
|
||||
t109(client.device.androidId)
|
||||
t8(2052)
|
||||
t142(client.apkId)
|
||||
t145(client.device.guid)
|
||||
t154(0)
|
||||
// 需要 t112, 但在实现 QR 时删除了 phoneNumber
|
||||
// t112(client.account.phoneNumber.encodeToByteArray())
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
t521()
|
||||
t52c()
|
||||
t52d(client.device.generateDeviceInfoData())
|
||||
_writeTlvMap {
|
||||
t100(16, client.subAppId, client.appClientVersion, client.ssoVersion, client.mainSigMap)
|
||||
t108(client.ksid)
|
||||
t109(client.device.androidId)
|
||||
t8(2052)
|
||||
t142(client.apkId)
|
||||
t145(client.device.guid)
|
||||
t154(0)
|
||||
// 需要 t112, 但在实现 QR 时删除了 phoneNumber
|
||||
//t112(client.account.phoneNumber.encodeToByteArray())
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
t521()
|
||||
t52c()
|
||||
t52d(client.device.generateDeviceInfoData())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -677,53 +678,54 @@ internal class WtLogin {
|
||||
writeByte(8)
|
||||
writeShortLVPacket { }
|
||||
|
||||
writeShort(6)
|
||||
t16(
|
||||
client.ssoVersion,
|
||||
client.subAppId,
|
||||
client.device.guid,
|
||||
client.apkId,
|
||||
client.apkVersionName,
|
||||
client.apkSignatureMd5
|
||||
)
|
||||
t1b(
|
||||
size = size,
|
||||
margin = margin,
|
||||
ecLevel = ecLevel
|
||||
)
|
||||
t1d(client.miscBitMap)
|
||||
|
||||
val protocol = client.bot.configuration.protocol
|
||||
when (protocol) {
|
||||
BotConfiguration.MiraiProtocol.MACOS -> t1f(
|
||||
false,
|
||||
"Mac OSX".toByteArray(),
|
||||
"10".toByteArray(),
|
||||
"mac carrier".toByteArray(),
|
||||
client.device.apn,
|
||||
2
|
||||
_writeTlvMap {
|
||||
t16(
|
||||
client.ssoVersion,
|
||||
client.subAppId,
|
||||
client.device.guid,
|
||||
client.apkId,
|
||||
client.apkVersionName,
|
||||
client.apkSignatureMd5
|
||||
)
|
||||
|
||||
BotConfiguration.MiraiProtocol.ANDROID_WATCH -> t1f(
|
||||
false,
|
||||
client.device.osType,
|
||||
"7.1.2".toByteArray(),
|
||||
"China Mobile GSM".toByteArray(),
|
||||
client.device.apn,
|
||||
2
|
||||
t1b(
|
||||
size = size,
|
||||
margin = margin,
|
||||
ecLevel = ecLevel
|
||||
)
|
||||
t1d(client.miscBitMap)
|
||||
|
||||
else -> error("protocol $protocol doesn't support qrcode login.")
|
||||
}
|
||||
|
||||
t33(client.device.guid)
|
||||
t35(
|
||||
val protocol = client.bot.configuration.protocol
|
||||
when (protocol) {
|
||||
BotConfiguration.MiraiProtocol.MACOS -> 5
|
||||
BotConfiguration.MiraiProtocol.ANDROID_WATCH -> 8
|
||||
else -> error("assertion")
|
||||
BotConfiguration.MiraiProtocol.MACOS -> t1f(
|
||||
false,
|
||||
"Mac OSX".toByteArray(),
|
||||
"10".toByteArray(),
|
||||
"mac carrier".toByteArray(),
|
||||
client.device.apn,
|
||||
2
|
||||
)
|
||||
|
||||
BotConfiguration.MiraiProtocol.ANDROID_WATCH -> t1f(
|
||||
false,
|
||||
client.device.osType,
|
||||
"7.1.2".toByteArray(),
|
||||
"China Mobile GSM".toByteArray(),
|
||||
client.device.apn,
|
||||
2
|
||||
)
|
||||
|
||||
else -> error("protocol $protocol doesn't support qrcode login.")
|
||||
}
|
||||
)
|
||||
|
||||
t33(client.device.guid)
|
||||
t35(
|
||||
when (protocol) {
|
||||
BotConfiguration.MiraiProtocol.MACOS -> 5
|
||||
BotConfiguration.MiraiProtocol.ANDROID_WATCH -> 8
|
||||
else -> error("assertion")
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
writeByte(0)
|
||||
writeShort(code2dPacket.remaining.toShort())
|
||||
|
@ -16,6 +16,7 @@ import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
|
||||
import net.mamoe.mirai.internal.utils.GuidSource
|
||||
import net.mamoe.mirai.internal.utils.MacOrAndroidIdChangeFlag
|
||||
import net.mamoe.mirai.internal.utils.guidFlag
|
||||
import net.mamoe.mirai.utils._writeTlvMap
|
||||
import net.mamoe.mirai.utils.generateDeviceInfoData
|
||||
import net.mamoe.mirai.utils.md5
|
||||
import net.mamoe.mirai.utils.toReadPacket
|
||||
@ -44,45 +45,47 @@ internal object WtLogin10 : WtLoginExt {
|
||||
0x0810
|
||||
) {
|
||||
writeShort(11) // subCommand
|
||||
writeShort(18)
|
||||
t100(appId, subAppId, client.appClientVersion, client.ssoVersion, mainSigMap)
|
||||
t10a(client.wLoginSigInfo.tgt)
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
t108(client.ksid)
|
||||
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.wLoginSigInfo.d2Key.md5()
|
||||
)
|
||||
//t112(client.account.phoneNumber.encodeToByteArray())
|
||||
t143(client.wLoginSigInfo.d2.data)
|
||||
t142(client.apkId)
|
||||
t154(sequenceId)
|
||||
t18(appId, uin = client.uin)
|
||||
t141(client.device.simInfo, client.networkType, client.device.apn)
|
||||
t8(2052)
|
||||
//t511()
|
||||
t147(appId, client.apkVersionName, client.apkSignatureMd5)
|
||||
t177(client.buildTime, client.sdkVersion)
|
||||
t187(client.device.macAddress)
|
||||
t188(client.device.androidId)
|
||||
t194(client.device.imsiMd5)
|
||||
t511()
|
||||
t202(client.device.wifiBSSID, client.device.wifiSSID)
|
||||
//t544()
|
||||
|
||||
_writeTlvMap(Short.SIZE_BYTES) {
|
||||
t100(appId, subAppId, client.appClientVersion, client.ssoVersion, mainSigMap)
|
||||
t10a(client.wLoginSigInfo.tgt)
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
t108(client.ksid)
|
||||
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.wLoginSigInfo.d2Key.md5()
|
||||
)
|
||||
//t112(client.account.phoneNumber.encodeToByteArray())
|
||||
t143(client.wLoginSigInfo.d2.data)
|
||||
t142(client.apkId)
|
||||
t154(sequenceId)
|
||||
t18(appId, uin = client.uin)
|
||||
t141(client.device.simInfo, client.networkType, client.device.apn)
|
||||
t8(2052)
|
||||
//t511()
|
||||
t147(appId, client.apkVersionName, client.apkSignatureMd5)
|
||||
t177(client.buildTime, client.sdkVersion)
|
||||
t187(client.device.macAddress)
|
||||
t188(client.device.androidId)
|
||||
t194(client.device.imsiMd5)
|
||||
t511()
|
||||
t202(client.device.wifiBSSID, client.device.wifiSSID)
|
||||
//t544()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import io.ktor.utils.io.core.*
|
||||
import net.mamoe.mirai.internal.network.*
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.*
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
|
||||
import net.mamoe.mirai.utils._writeTlvMap
|
||||
import kotlin.math.abs
|
||||
import kotlin.random.Random
|
||||
|
||||
@ -36,7 +37,8 @@ internal object WtLogin15 : WtLoginExt {
|
||||
commandId = 0x0810
|
||||
) {
|
||||
writeShort(subCommand) // subCommand
|
||||
writeShort(24)
|
||||
|
||||
_writeTlvMap {
|
||||
|
||||
|
||||
// writeFully(("00 18 00 16 00 01 00 00 06 00 00 00 00 10 00 00 00 00 76 E4 B8 DD 00 00 00 00 00 01 00 14 00 01 5A 11 60 11 76 E4 B8 DD 60 0D 44 35 90 E8 11 1B 00 00 " +
|
||||
@ -51,11 +53,11 @@ internal object WtLogin15 : WtLoginExt {
|
||||
// "").hexToBytes())
|
||||
// return@writeOicqRequestPacket
|
||||
|
||||
t18(appId, uin = client.uin)
|
||||
t1(client.uin, ByteArray(4))
|
||||
t18(appId, uin = client.uin)
|
||||
t1(client.uin, ByteArray(4))
|
||||
|
||||
// t106(client = client)
|
||||
t106(client.wLoginSigInfo.encryptA1!!)
|
||||
// t106(client = client)
|
||||
t106(client.wLoginSigInfo.encryptA1!!)
|
||||
// kotlin.run {
|
||||
// val key = (client.account.passwordMd5 + ByteArray(4) + client.uin.toInt().toByteArray()).md5()
|
||||
// kotlin.runCatching {
|
||||
@ -63,67 +65,68 @@ internal object WtLogin15 : WtLoginExt {
|
||||
// }.soutv("DEC") // success
|
||||
// }
|
||||
|
||||
// val a1 = kotlin.runCatching {
|
||||
// TEA.decrypt(encryptA1, buildPacket {
|
||||
// writeFully(client.device.guid)
|
||||
// writeFully(client.dpwd)
|
||||
// writeFully(client.randSeed)
|
||||
// }.readBytes().md5())
|
||||
// }.recoverCatching {
|
||||
// client.tryDecryptOrNull(encryptA1) { it }!!
|
||||
// }.getOrElse {
|
||||
// encryptA1.soutv("ENCRYPT A1")
|
||||
// client.soutv("CLIENT")
|
||||
// // exitProcess(1)
|
||||
// // error("Failed to decrypt A1")
|
||||
// encryptA1
|
||||
// }
|
||||
// val a1 = kotlin.runCatching {
|
||||
// TEA.decrypt(encryptA1, buildPacket {
|
||||
// writeFully(client.device.guid)
|
||||
// writeFully(client.dpwd)
|
||||
// writeFully(client.randSeed)
|
||||
// }.readBytes().md5())
|
||||
// }.recoverCatching {
|
||||
// client.tryDecryptOrNull(encryptA1) { it }!!
|
||||
// }.getOrElse {
|
||||
// encryptA1.soutv("ENCRYPT A1")
|
||||
// client.soutv("CLIENT")
|
||||
// // exitProcess(1)
|
||||
// // error("Failed to decrypt A1")
|
||||
// encryptA1
|
||||
// }
|
||||
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
//t116(0x08F7FF7C, 0x00010400)
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
//t116(0x08F7FF7C, 0x00010400)
|
||||
|
||||
//t100(appId, client.subAppId, client.appClientVersion, client.ssoVersion, client.mainSigMap)
|
||||
//t100(appId, 1, client.appClientVersion, client.ssoVersion, mainSigMap = 1048768)
|
||||
t100(appId, 2, client.appClientVersion, client.ssoVersion, client.mainSigMap)
|
||||
//t100(appId, client.subAppId, client.appClientVersion, client.ssoVersion, client.mainSigMap)
|
||||
//t100(appId, 1, client.appClientVersion, client.ssoVersion, mainSigMap = 1048768)
|
||||
t100(appId, 2, client.appClientVersion, client.ssoVersion, client.mainSigMap)
|
||||
|
||||
t107(0)
|
||||
t107(0)
|
||||
|
||||
//t108(client.ksid) // 第一次 exchange 没有 108
|
||||
t144(client)
|
||||
t142(client.apkId)
|
||||
t145(client.device.guid)
|
||||
//t108(client.ksid) // 第一次 exchange 没有 108
|
||||
t144(client)
|
||||
t142(client.apkId)
|
||||
t145(client.device.guid)
|
||||
|
||||
val noPicSig =
|
||||
client.wLoginSigInfo.noPicSig ?: error("Internal error: doing exchange emp 15 while noPicSig=null")
|
||||
t16a(noPicSig)
|
||||
val noPicSig =
|
||||
client.wLoginSigInfo.noPicSig ?: error("Internal error: doing exchange emp 15 while noPicSig=null")
|
||||
t16a(noPicSig)
|
||||
|
||||
t154(0)
|
||||
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)
|
||||
t154(0)
|
||||
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)
|
||||
|
||||
// new
|
||||
t400(
|
||||
g = client.G,
|
||||
uin = client.uin,
|
||||
guid = client.device.guid,
|
||||
dpwd = client.dpwd,
|
||||
appId = 1,
|
||||
subAppId = 16,
|
||||
randomSeed = client.randSeed
|
||||
)
|
||||
// new
|
||||
t400(
|
||||
g = client.G,
|
||||
uin = client.uin,
|
||||
guid = client.device.guid,
|
||||
dpwd = client.dpwd,
|
||||
appId = 1,
|
||||
subAppId = 16,
|
||||
randomSeed = client.randSeed
|
||||
)
|
||||
|
||||
t187(client.device.macAddress)
|
||||
t188(client.device.androidId)
|
||||
t194(client.device.imsiMd5)
|
||||
t202(client.device.wifiBSSID, client.device.wifiSSID)
|
||||
t516()
|
||||
t187(client.device.macAddress)
|
||||
t188(client.device.androidId)
|
||||
t194(client.device.imsiMd5)
|
||||
t202(client.device.wifiBSSID, client.device.wifiSSID)
|
||||
t516()
|
||||
|
||||
t521() // new
|
||||
t525(client.loginExtraData) // new
|
||||
//t544() // new
|
||||
t521() // new
|
||||
t525(client.loginExtraData) // new
|
||||
//t544() // new
|
||||
}
|
||||
}
|
||||
|
||||
// }
|
||||
|
@ -16,6 +16,7 @@ import net.mamoe.mirai.internal.network.protocol.packet.*
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
|
||||
import net.mamoe.mirai.internal.network.subAppId
|
||||
import net.mamoe.mirai.internal.network.subSigMap
|
||||
import net.mamoe.mirai.utils._writeTlvMap
|
||||
|
||||
|
||||
internal object WtLogin2 : WtLoginExt {
|
||||
@ -26,19 +27,13 @@ internal object WtLogin2 : WtLoginExt {
|
||||
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
|
||||
writeOicqRequestPacket(client, commandId = 0x0810) {
|
||||
writeShort(2) // subCommand
|
||||
writeShort(
|
||||
if (client.t547 == null) {
|
||||
4
|
||||
} else {
|
||||
5
|
||||
}
|
||||
) // count of TLVs
|
||||
t193(ticket)
|
||||
t8(2052)
|
||||
t104(client.t104)
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
client.t547?.let {
|
||||
t547(it)
|
||||
|
||||
_writeTlvMap {
|
||||
t193(ticket)
|
||||
t8(2052)
|
||||
t104(client.t104)
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
client.t547?.let { t547(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -52,19 +47,13 @@ internal object WtLogin2 : WtLoginExt {
|
||||
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
|
||||
writeOicqRequestPacket(client, commandId = 0x0810) {
|
||||
writeShort(2) // subCommand
|
||||
writeShort(
|
||||
if (client.t547 == null) {
|
||||
4
|
||||
} else {
|
||||
5
|
||||
}
|
||||
) // count of TLVs
|
||||
t2(captchaAnswer, captchaSign, 0)
|
||||
t8(2052)
|
||||
t104(client.t104)
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
client.t547?.let {
|
||||
t547(it)
|
||||
|
||||
_writeTlvMap {
|
||||
t2(captchaAnswer, captchaSign, 0)
|
||||
t8(2052)
|
||||
t104(client.t104)
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
client.t547?.let { t547(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import net.mamoe.mirai.internal.network.protocol.packet.*
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
|
||||
import net.mamoe.mirai.internal.network.subAppId
|
||||
import net.mamoe.mirai.internal.network.subSigMap
|
||||
import net.mamoe.mirai.utils._writeTlvMap
|
||||
|
||||
internal object WtLogin20 : WtLoginExt {
|
||||
operator fun invoke(
|
||||
@ -24,11 +25,12 @@ internal object WtLogin20 : WtLoginExt {
|
||||
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
|
||||
writeOicqRequestPacket(client, commandId = 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.G) // (client.device.guid + "stMNokHgxZUGhsYp".toByteArray() + t402).md5()
|
||||
_writeTlvMap {
|
||||
t8(2052)
|
||||
t104(client.t104)
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
t401(client.G) // (client.device.guid + "stMNokHgxZUGhsYp".toByteArray() + t402).md5()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
|
||||
import net.mamoe.mirai.internal.network.subAppId
|
||||
import net.mamoe.mirai.internal.network.subSigMap
|
||||
import net.mamoe.mirai.utils.DeviceVerificationRequests
|
||||
import net.mamoe.mirai.utils._writeTlvMap
|
||||
|
||||
/**
|
||||
* Submit SMS.
|
||||
@ -33,15 +34,17 @@ internal object WtLogin7 : WtLoginExt {
|
||||
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
|
||||
writeOicqRequestPacket(client, commandId = 0x0810) {
|
||||
writeShort(7) // subCommand
|
||||
writeShort(7) // count of TLVs
|
||||
|
||||
t8(2052)
|
||||
t104(client.t104)
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
t174(client.t174 ?: t174)
|
||||
t17c(code.encodeToByteArray())
|
||||
t401(client.G)
|
||||
t198()
|
||||
_writeTlvMap {
|
||||
|
||||
t8(2052)
|
||||
t104(client.t104)
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
t174(client.t174 ?: t174)
|
||||
t17c(code.encodeToByteArray())
|
||||
t401(client.G)
|
||||
t198()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
|
||||
import net.mamoe.mirai.internal.network.subAppId
|
||||
import net.mamoe.mirai.internal.network.subSigMap
|
||||
import net.mamoe.mirai.utils.DeviceVerificationRequests
|
||||
import net.mamoe.mirai.utils._writeTlvMap
|
||||
|
||||
/**
|
||||
* Request SMS.
|
||||
@ -33,14 +34,17 @@ internal object WtLogin8 : WtLoginExt {
|
||||
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
|
||||
writeOicqRequestPacket(client, commandId = 0x0810) {
|
||||
writeShort(subCommand) // subCommand
|
||||
writeShort(6) // count of TLVs
|
||||
|
||||
t8(2052)
|
||||
t104(client.t104)
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
t174(t174)
|
||||
t17a(9)
|
||||
t197()
|
||||
_writeTlvMap {
|
||||
|
||||
t8(2052)
|
||||
t104(client.t104)
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
t174(t174)
|
||||
t17a(9)
|
||||
t197()
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import io.ktor.utils.io.core.*
|
||||
import net.mamoe.mirai.internal.network.*
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.*
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
|
||||
import net.mamoe.mirai.utils._writeTlvMap
|
||||
|
||||
internal object WtLogin9 : WtLoginExt {
|
||||
private const val appId = 16L
|
||||
@ -35,19 +36,21 @@ internal object WtLogin9 : WtLoginExt {
|
||||
if (useEncryptA1AndNoPicSig) {
|
||||
tlvCount++;
|
||||
}
|
||||
writeShort(tlvCount.toShort()) // count of TLVs, probably ignored by server?
|
||||
// writeShort(tlvCount.toShort()) // count of TLVs, probably ignored by server?
|
||||
//writeShort(LoginType.PASSWORD.value.toShort())
|
||||
|
||||
t18(appId, client.appClientVersion, client.uin)
|
||||
t1(client.uin, client.device.ipAddress)
|
||||
_writeTlvMap {
|
||||
|
||||
if (useEncryptA1AndNoPicSig) {
|
||||
t106(client.wLoginSigInfo.encryptA1!!)
|
||||
} else {
|
||||
t106(client, appId, passwordMd5)
|
||||
}
|
||||
t18(appId, client.appClientVersion, client.uin)
|
||||
t1(client.uin, client.device.ipAddress)
|
||||
|
||||
/* // from GetStWithPasswd
|
||||
if (useEncryptA1AndNoPicSig) {
|
||||
t106(client.wLoginSigInfo.encryptA1!!)
|
||||
} else {
|
||||
t106(client, appId, passwordMd5)
|
||||
}
|
||||
|
||||
/* // from GetStWithPasswd
|
||||
int mMiscBitmap = this.mMiscBitmap;
|
||||
if (t.uinDeviceToken) {
|
||||
mMiscBitmap = (this.mMiscBitmap | 0x2000000);
|
||||
@ -57,65 +60,66 @@ internal object WtLogin9 : WtLoginExt {
|
||||
// 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())
|
||||
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)
|
||||
// t108(byteArrayOf())
|
||||
// ignored: t104()
|
||||
t142(client.apkId)
|
||||
|
||||
// if login with non-number uin
|
||||
// t112()
|
||||
t144(client)
|
||||
// if login with non-number uin
|
||||
// t112()
|
||||
t144(client)
|
||||
|
||||
//this.build().debugPrint("傻逼")
|
||||
t145(client.device.guid)
|
||||
t147(appId, client.apkVersionName, client.apkSignatureMd5)
|
||||
//this.build().debugPrint("傻逼")
|
||||
t145(client.device.guid)
|
||||
t147(appId, client.apkVersionName, client.apkSignatureMd5)
|
||||
|
||||
/*
|
||||
/*
|
||||
if (client.miscBitMap and 0x80 != 0) {
|
||||
t166(1)
|
||||
}
|
||||
*/
|
||||
if (useEncryptA1AndNoPicSig) {
|
||||
t16a(client.wLoginSigInfo.noPicSig!!)
|
||||
}
|
||||
if (useEncryptA1AndNoPicSig) {
|
||||
t16a(client.wLoginSigInfo.noPicSig!!)
|
||||
}
|
||||
|
||||
t154(sequenceId)
|
||||
t141(client.device.simInfo, client.networkType, client.device.apn)
|
||||
t8(2052)
|
||||
t154(sequenceId)
|
||||
t141(client.device.simInfo, client.networkType, client.device.apn)
|
||||
t8(2052)
|
||||
|
||||
t511()
|
||||
t511()
|
||||
|
||||
// ignored t172 because rollbackSig is null
|
||||
// ignored t185 because loginType is not SMS
|
||||
// ignored t400 because of first login
|
||||
// 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()
|
||||
}
|
||||
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)
|
||||
t202(client.device.wifiBSSID, client.device.wifiSSID)
|
||||
|
||||
t177(
|
||||
buildTime = client.buildTime,
|
||||
buildVersion = client.sdkVersion,
|
||||
)
|
||||
t516()
|
||||
t521()
|
||||
t177(
|
||||
buildTime = client.buildTime,
|
||||
buildVersion = client.sdkVersion,
|
||||
)
|
||||
t516()
|
||||
t521()
|
||||
|
||||
t525()
|
||||
// this.build().debugPrint("傻逼")
|
||||
t525()
|
||||
// this.build().debugPrint("傻逼")
|
||||
|
||||
// ignored t318 because not logging in by QR
|
||||
// ignored t318 because not logging in by QR
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -130,44 +134,46 @@ internal object WtLogin9 : WtLoginExt {
|
||||
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
|
||||
writeOicqRequestPacket(client, commandId = 0x0810) {
|
||||
writeShort(9) // subCommand
|
||||
writeShort(0x19) // count of TLVs, probably ignored by server?
|
||||
// writeShort(0x19) // count of TLVs, probably ignored by server?
|
||||
|
||||
t18(appId, client.appClientVersion, client.uin)
|
||||
t1(client.uin, client.device.ipAddress)
|
||||
_writeTlvMap {
|
||||
t18(appId, client.appClientVersion, client.uin)
|
||||
t1(client.uin, client.device.ipAddress)
|
||||
|
||||
t106(data.tmpPwd)
|
||||
t106(data.tmpPwd)
|
||||
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
t100(appId, client.subAppId, client.appClientVersion, client.ssoVersion, client.mainSigMap)
|
||||
t107(0)
|
||||
t108(client.device.imei.toByteArray())
|
||||
t116(client.miscBitMap, client.subSigMap)
|
||||
t100(appId, client.subAppId, client.appClientVersion, client.ssoVersion, client.mainSigMap)
|
||||
t107(0)
|
||||
t108(client.device.imei.toByteArray())
|
||||
|
||||
t142(client.apkId)
|
||||
t142(client.apkId)
|
||||
|
||||
t144(client)
|
||||
t144(client)
|
||||
|
||||
t145(client.device.guid)
|
||||
t147(appId, client.apkVersionName, client.apkSignatureMd5)
|
||||
t145(client.device.guid)
|
||||
t147(appId, client.apkVersionName, client.apkSignatureMd5)
|
||||
|
||||
t16a(data.noPicSig)
|
||||
t16a(data.noPicSig)
|
||||
|
||||
t154(sequenceId)
|
||||
t141(client.device.simInfo, client.networkType, client.device.apn)
|
||||
t8(2052)
|
||||
t154(sequenceId)
|
||||
t141(client.device.simInfo, client.networkType, client.device.apn)
|
||||
t8(2052)
|
||||
|
||||
t511()
|
||||
t511()
|
||||
|
||||
t187(client.device.macAddress)
|
||||
t188(client.device.androidId)
|
||||
t194(client.device.imsiMd5)
|
||||
t191(0x00)
|
||||
t187(client.device.macAddress)
|
||||
t188(client.device.androidId)
|
||||
t194(client.device.imsiMd5)
|
||||
t191(0x00)
|
||||
|
||||
t202(client.device.wifiBSSID, client.device.wifiSSID)
|
||||
t202(client.device.wifiBSSID, client.device.wifiSSID)
|
||||
|
||||
t177(client.buildTime, client.sdkVersion)
|
||||
t516()
|
||||
t521(8)
|
||||
t318(data.tgtQR)
|
||||
t177(client.buildTime, client.sdkVersion)
|
||||
t516()
|
||||
t521(8)
|
||||
t318(data.tgtQR)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,19 +86,18 @@ internal interface WtLoginExt { // so as not to register to global extension
|
||||
|
||||
return buildPacket {
|
||||
writeByte(64)
|
||||
writeShort(4)
|
||||
|
||||
// TLV
|
||||
writeShort(0x106)
|
||||
writeShortLVByteArray(t106)
|
||||
_writeTlvMap {
|
||||
|
||||
writeShort(0x10c)
|
||||
writeShortLVByteArray(t10c)
|
||||
// TLV
|
||||
tlv(0x106, t106)
|
||||
|
||||
writeShort(0x16a)
|
||||
writeShortLVByteArray(t16a)
|
||||
tlv(0x10c, t10c)
|
||||
|
||||
t145(device.guid)
|
||||
tlv(0x16a, t16a)
|
||||
|
||||
t145(device.guid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user