diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt index 87ca42707..e29066fbf 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt @@ -37,6 +37,13 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler is Captcha -> when (response) { is Captcha.Picture -> { bot.logger.info("需要图片验证码") + var result = bot.configuration.captchaSolver.invoke(bot, response.data) + if (result === null || result.length != 4) { + //refresh captcha + result = "ABCD" + } + bot.logger.info("提交验证码") + LoginPacket.SubCommand2(bot.client, response.sign, result) } is Captcha.Slider -> { bot.logger.info("需要滑动验证码") diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidClient.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidClient.kt index ebd42bdaa..4c7d99cec 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidClient.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidClient.kt @@ -46,6 +46,7 @@ internal open class QQAndroidClient( @MiraiInternalAPI("Be careful. Do not use the id in BotAccount. use client.uin instead") val account: BotAccount, + val ecdh: ECDH = ECDH(), val device: DeviceInfo = SystemDeviceInfo(context), bot: QQAndroidBot @@ -160,6 +161,8 @@ internal open class QQAndroidClient( lateinit var mainDisplayName: ByteArray var transportSequenceId = 1 + + lateinit var t104: ByteArray } class ReserveUinInfo( diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt index 57934f72f..fbed60855 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt @@ -8,7 +8,7 @@ import net.mamoe.mirai.qqandroid.network.io.JceInput import net.mamoe.mirai.qqandroid.network.protocol.jce.RequestPacket import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.OnlinePush import net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket -import net.mamoe.mirai.qqandroid.network.protocol.packet.login.SvcReqRegisterPacket +//import net.mamoe.mirai.qqandroid.network.protocol.packet.login.SvcReqRegisterPacket import net.mamoe.mirai.utils.DefaultLogger import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.cryptor.adjustToPublicKey @@ -50,7 +50,6 @@ internal val PacketLogger: MiraiLogger = DefaultLogger("Packet") @UseExperimental(ExperimentalUnsignedTypes::class) internal object KnownPacketFactories : List> by mutableListOf( LoginPacket, - SvcReqRegisterPacket, OnlinePush.PbPushGroupMsg ) { 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 507e59188..4e13c2542 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 @@ -26,6 +26,27 @@ import net.mamoe.mirai.utils.io.discardExact @UseExperimental(ExperimentalUnsignedTypes::class) internal object LoginPacket : PacketFactory("wtlogin.login") { + object SubCommand2 { + private const val appId = 16L + private const val subAppId = 537062845L + + @UseExperimental(MiraiInternalAPI::class) + operator fun invoke( + client: QQAndroidClient, + captchaSign: ByteArray, + captchaAnswer: String + ): OutgoingPacket = buildLoginOutgoingPacket(client, bodyType = 2) { sequenceId -> + writeSsoPacket(client, subAppId, commandName, sequenceId = sequenceId) { + writeOicqRequestPacket(client, EncryptMethodECDH7(client.ecdh), 0x0810) { + t2(captchaAnswer, captchaSign, 0) + t8(2052) + t104(client.t104) + t116(150470524, 66560) + } + } + } + } + object SubCommand9 { private const val appId = 16L private const val subAppId = 537062845L @@ -180,12 +201,16 @@ internal object LoginPacket : PacketFactory("wt ) : LoginPacketResponse() sealed class Captcha : LoginPacketResponse() { + lateinit var answer: String + class Slider( - val data: IoBuffer + val data: IoBuffer, + val sign: ByteArray ) : Captcha() class Picture( - val data: IoBuffer + val data: IoBuffer, + val sign: ByteArray ) : Captcha() } } @@ -240,17 +265,15 @@ internal object LoginPacket : PacketFactory("wt "36" -> { //图片验证 DebugLogger.debug("是一个图片验证码") + bot.client.t104 = tlvMap[0x104]!! val imageData = tlvMap[0x105]!!.toReadPacket() - println(tlvMap[0x105]!!.toUHexString()) val signInfoLength = imageData.readShort() - val picLength = imageData.readShort() + imageData.discardExact(2)//image Length val sign = imageData.readBytes(signInfoLength.toInt()) - val tv104 = tlvMap[0x104]!! - val ssoSign = // - bot.configuration.captchaSolver.invoke( - bot, - imageData.readRemainingBytes().toIoBuffer() - ) + return LoginPacketResponse.Captcha.Picture( + data = imageData.readRemainingBytes().toIoBuffer(), + sign = sign + ) } else -> { error("UNKNOWN CAPTCHA QUESTION: $question")