From 42bd8face75f3c75b60040c1e2300f9ee3e607a7 Mon Sep 17 00:00:00 2001 From: Him188 <Him188@mamoe.net> Date: Wed, 29 Jan 2020 19:17:13 +0800 Subject: [PATCH] Introduce typealias `TlvMap = MutableMap<Int, ByteArray>` --- .../protocol/packet/login/LoginPacket.kt | 66 +++++++++---------- .../net.mamoe.mirai/utils/io/InputUtils.kt | 15 ++++- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt index 0f3e4f45d..2bca35307 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt @@ -136,7 +136,6 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt tgtgtKey = client.tgtgtKey ) - //this.build().debugPrint("傻逼") t145(client.device.guid) t147(appId, client.apkVersionName, client.apkSignatureMd5) @@ -212,11 +211,10 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt sealed class LoginPacketResponse : Packet { - object Success : LoginPacketResponse(){ - override fun toString(): String { - return "LoginPacketResponse.Success" - } + object Success : LoginPacketResponse() { + override fun toString(): String = "LoginPacketResponse.Success" } + data class Error( val title: String, val message: String, @@ -228,25 +226,25 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt class Slider( val data: IoBuffer, val sign: ByteArray - ) : Captcha(){ - override fun toString(): String { - return "LoginPacketResponse.Captcha.Slider" - } + ) : Captcha() { + override fun toString(): String = "LoginPacketResponse.Captcha.Slider" } class Picture( val data: IoBuffer, val sign: ByteArray - ) : Captcha(){ - override fun toString(): String { - return "LoginPacketResponse.Captcha.Picture" - } + ) : Captcha() { + override fun toString(): String = "LoginPacketResponse.Captcha.Picture" } } - class UnsafeLogin(val url: String) : LoginPacketResponse() + class UnsafeLogin(val url: String) : LoginPacketResponse() { + override fun toString(): String = "LoginPacketResponse.UnsafeLogin" + } - class SMSVerifyCodeNeeded(val t174: ByteArray, val t402: ByteArray) : LoginPacketResponse() + class SMSVerifyCodeNeeded(val t174: ByteArray, val t402: ByteArray) : LoginPacketResponse() { + override fun toString(): String = "LoginPacketResponse.SMSVerifyCodeNeeded(t174=${t174.toUHexString()}, t402=${t402.toUHexString()})" + } } @InternalAPI @@ -266,12 +264,12 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt println("type=$type") discardExact(2) - val tlvMap: Map<Int, ByteArray> = this.readTLVMap() + val tlvMap: TlvMap = this.readTLVMap() return when (type.toInt()) { 0 -> onLoginSuccess(tlvMap, bot) 1, 15 -> onErrorMessage(tlvMap) 2 -> onSolveLoginCaptcha(tlvMap, bot) - -96 -> onUnsafeDeviceLogin(tlvMap, bot) + -96 -> onUnsafeDeviceLogin(tlvMap) -52 -> onSMSVerifyNeeded(tlvMap, bot) else -> error("unknown login result type: $type") } @@ -279,19 +277,19 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt private fun onSMSVerifyNeeded( - tlvMap: Map<Int, ByteArray>, + tlvMap: TlvMap, bot: QQAndroidBot ): LoginPacketResponse.SMSVerifyCodeNeeded { - bot.client.t104 = tlvMap[0x104]!! - return LoginPacketResponse.SMSVerifyCodeNeeded(tlvMap[0x174] ?: EMPTY_BYTE_ARRAY, tlvMap[0x402]!!) + bot.client.t104 = tlvMap[0x104] ?: error("cannot find tlv0x104") + return LoginPacketResponse.SMSVerifyCodeNeeded(tlvMap[0x174] ?: EMPTY_BYTE_ARRAY, tlvMap.getOrFail(0x402)) } - private fun onUnsafeDeviceLogin(tlvMap: Map<Int, ByteArray>, bot: QQAndroidBot): LoginPacketResponse.UnsafeLogin { - return LoginPacketResponse.UnsafeLogin(tlvMap[0x204]!!.toReadPacket().readRemainingBytes().encodeToString()) + private fun onUnsafeDeviceLogin(tlvMap: TlvMap): LoginPacketResponse.UnsafeLogin { + return LoginPacketResponse.UnsafeLogin(tlvMap.getOrFail(0x204).encodeToString()) } - private fun onErrorMessage(tlvMap: Map<Int, ByteArray>): LoginPacketResponse.Error { - return tlvMap[0x146]?.toReadPacket()?.run { + private fun onErrorMessage(tlvMap: TlvMap): LoginPacketResponse.Error { + return tlvMap[0x146]?.read { readShort() // ver readShort() // code @@ -305,17 +303,16 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt @InternalAPI @UseExperimental(MiraiDebugAPI::class) - private fun onSolveLoginCaptcha(tlvMap: Map<Int, ByteArray>, bot: QQAndroidBot): LoginPacketResponse. Captcha { - val client = bot.client + private fun onSolveLoginCaptcha(tlvMap: TlvMap, bot: QQAndroidBot): LoginPacketResponse.Captcha { // val ret = tlvMap[0x104]?.let { println(it.toUHexString()) } println() - val question = tlvMap[0x165] ?: error("CAPTCHA QUESTION UNKNOWN") + val question = tlvMap.getOrFail(0x165) { "CAPTCHA QUESTION UNKNOWN" } when (question[18].toInt()) { 0x36 -> { //图片验证 DebugLogger.debug("是一个图片验证码") - bot.client.t104 = tlvMap[0x104]!! - val imageData = tlvMap[0x105]!!.toReadPacket() + bot.client.t104 = tlvMap.getOrFail(0x104) + val imageData = tlvMap.getOrFail(0x105).toReadPacket() val signInfoLength = imageData.readShort() imageData.discardExact(2)//image Length val sign = imageData.readBytes(signInfoLength.toInt()) @@ -324,15 +321,12 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt sign = sign ) } - else -> { - error("UNKNOWN CAPTCHA QUESTION: $question") - } + else -> error("UNKNOWN CAPTCHA QUESTION: $question") } - return TODO() } @UseExperimental(MiraiDebugAPI::class) - private fun onLoginSuccess(tlvMap: Map<Int, ByteArray>, bot: QQAndroidBot): LoginPacketResponse.Success { + private fun onLoginSuccess(tlvMap: TlvMap, bot: QQAndroidBot): LoginPacketResponse.Success { val client = bot.client println("TLV KEYS: " + tlvMap.keys.joinToString { it.contentToString() }) @@ -536,7 +530,7 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt } - private fun Map<Int, ByteArray>.getOrEmpty(key: Int): ByteArray { + private fun TlvMap.getOrEmpty(key: Int): ByteArray { return this[key] ?: byteArrayOf() } @@ -615,7 +609,7 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt * 设置 [QQAndroidClient.uin] */ private fun QQAndroidClient.analysisTlv113(t113: ByteArray) = t113.read { - uin = readUInt().toLong() + _uin = readUInt().toLong() /* // nothing to do diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/InputUtils.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/InputUtils.kt index c5bf29291..23046d883 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/InputUtils.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/InputUtils.kt @@ -75,10 +75,21 @@ fun Input.readUShortLVByteArray(): ByteArray = this.readBytes(this.readUShort(). private inline fun <R> inline(block: () -> R): R = block() -fun Input.readTLVMap(tagSize: Int = 2): MutableMap<Int, ByteArray> = readTLVMap(true, tagSize) + +typealias TlvMap = MutableMap<Int, ByteArray> + +fun TlvMap.getOrFail(tag: Int): ByteArray { + return this[tag]?: error("cannot find tlv 0x${tag.toUHexString("")}($tag)") +} + +inline fun TlvMap.getOrFail(tag: Int, lazyMessage: (tag: Int) -> String): ByteArray { + return this[tag]?: error(lazyMessage(tag)) +} + +fun Input.readTLVMap(tagSize: Int = 2): TlvMap = readTLVMap(true, tagSize) @Suppress("DuplicatedCode") -fun Input.readTLVMap(expectingEOF: Boolean = true, tagSize: Int): MutableMap<Int, ByteArray> { +fun Input.readTLVMap(expectingEOF: Boolean = true, tagSize: Int): TlvMap { val map = mutableMapOf<Int, ByteArray>() var key = 0