And Captcha

This commit is contained in:
jiahua.liu 2020-01-26 15:28:54 +08:00
parent d1c56633b8
commit 33f9b22380
4 changed files with 44 additions and 12 deletions

View File

@ -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("需要滑动验证码")

View File

@ -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(

View File

@ -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<PacketFactory<*>> by mutableListOf(
LoginPacket,
SvcReqRegisterPacket,
OnlinePush.PbPushGroupMsg
) {

View File

@ -26,6 +26,27 @@ import net.mamoe.mirai.utils.io.discardExact
@UseExperimental(ExperimentalUnsignedTypes::class)
internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("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<LoginPacket.LoginPacketResponse>("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<LoginPacket.LoginPacketResponse>("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")