mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-31 11:30:16 +08:00
Disable SliderCaptcha. #745
This commit is contained in:
parent
dffade2a92
commit
5db71cd299
@ -61,6 +61,11 @@ public class NoStandardInputForCaptchaException @MiraiInternalApi constructor(
|
||||
@MiraiExperimentalApi("Will be removed when SMS login is supported")
|
||||
public class UnsupportedSMSLoginException(message: String?) : LoginFailedException(true, message)
|
||||
|
||||
/**
|
||||
* 无法完成滑块验证
|
||||
*/
|
||||
public class NotSupportedSliderCaptchaException(message: String?) : LoginFailedException(true, message)
|
||||
|
||||
/**
|
||||
* 非 mirai 实现的异常
|
||||
*/
|
||||
|
@ -45,6 +45,10 @@ public abstract class LoginSolver {
|
||||
*/
|
||||
public abstract suspend fun onSolvePicCaptcha(bot: Bot, data: ByteArray): String?
|
||||
|
||||
// TODO: 2020-12-24 滑动验证码支持
|
||||
@MiraiInternalApi
|
||||
public open val isSliderCaptchaSupport: Boolean get() = false
|
||||
|
||||
/**
|
||||
* 处理滑动验证码.
|
||||
* 返回 null 以表示无法处理验证码, 将会刷新验证码或重试登录.
|
||||
@ -89,6 +93,7 @@ public abstract class LoginSolver {
|
||||
public fun getDefault(): LoginSolver = Default
|
||||
?: error("LoginSolver is not provided by default on your platform. Please specify by BotConfiguration.loginSolver")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -93,7 +93,7 @@ internal class QQAndroidBot constructor(
|
||||
@Throws(LoginFailedException::class) // only
|
||||
override suspend fun relogin(cause: Throwable?) {
|
||||
client.useNextServers { host, port ->
|
||||
network.closeEverythingAndRelogin(host, port, cause)
|
||||
network.closeEverythingAndRelogin(host, port, cause, 0)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ internal abstract class BotNetworkHandler : CoroutineScope {
|
||||
*/
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@MiraiInternalApi
|
||||
abstract suspend fun closeEverythingAndRelogin(host: String, port: Int, cause: Throwable? = null)
|
||||
abstract suspend fun closeEverythingAndRelogin(host: String, port: Int, cause: Throwable? = null, step: Int)
|
||||
|
||||
/**
|
||||
* 初始化获取好友列表等值.
|
||||
|
@ -40,10 +40,7 @@ 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.utils.*
|
||||
import net.mamoe.mirai.internal.utils.io.readPacketExact
|
||||
import net.mamoe.mirai.network.ForceOfflineException
|
||||
import net.mamoe.mirai.network.RetryLaterException
|
||||
import net.mamoe.mirai.network.UnsupportedSMSLoginException
|
||||
import net.mamoe.mirai.network.WrongPasswordException
|
||||
import net.mamoe.mirai.network.*
|
||||
import net.mamoe.mirai.utils.*
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
@ -114,10 +111,14 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
|
||||
}.also { heartbeatJob = it }
|
||||
}
|
||||
|
||||
|
||||
override suspend fun closeEverythingAndRelogin(host: String, port: Int, cause: Throwable?) {
|
||||
// @param step
|
||||
// 0 -> 初始状态, 其他函数调用应永远传入 0
|
||||
// 1 -> 代表滑块验证已禁用
|
||||
override suspend fun closeEverythingAndRelogin(host: String, port: Int, cause: Throwable?, step: Int) {
|
||||
heartbeatJob?.cancel(CancellationException("relogin", cause))
|
||||
heartbeatJob?.join()
|
||||
_packetReceiverJob?.cancel(CancellationException("relogin", cause))
|
||||
_packetReceiverJob?.join()
|
||||
if (::channel.isInitialized) {
|
||||
// if (channel.isOpen) {
|
||||
// kotlin.runCatching {
|
||||
@ -161,14 +162,20 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
|
||||
return this
|
||||
}
|
||||
|
||||
val isSliderCaptchaSupport = bot.configuration.loginSolver?.isSliderCaptchaSupport ?: false
|
||||
val allowSlider = isSliderCaptchaSupport
|
||||
|| bot.configuration.protocol == BotConfiguration.MiraiProtocol.ANDROID_PHONE
|
||||
|| step == 0
|
||||
|
||||
fun loginSolverNotNull() = bot.configuration.loginSolver.notnull()
|
||||
|
||||
var response: WtLogin.Login.LoginPacketResponse = WtLogin.Login.SubCommand9(bot.client).sendAndExpect()
|
||||
var response: WtLogin.Login.LoginPacketResponse =
|
||||
WtLogin.Login.SubCommand9(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).sendAndExpect()
|
||||
response = WtLogin.Login.SubCommand9(bot.client, allowSlider).sendAndExpect()
|
||||
}
|
||||
|
||||
is WtLogin.Login.LoginPacketResponse.Captcha -> when (response) {
|
||||
@ -183,6 +190,21 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
|
||||
continue@mainloop
|
||||
}
|
||||
is WtLogin.Login.LoginPacketResponse.Captcha.Slider -> {
|
||||
if (!isSliderCaptchaSupport) {
|
||||
if (step == 0) {
|
||||
return closeEverythingAndRelogin(host, port, cause, 1)
|
||||
}
|
||||
throw NotSupportedSliderCaptchaException(
|
||||
buildString {
|
||||
append("Mirai 无法完成滑块验证.")
|
||||
if (allowSlider) {
|
||||
append(" 使用协议 ")
|
||||
append(bot.configuration.protocol)
|
||||
append(" 强制要求滑块验证, 请更换协议后重试")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
val ticket = loginSolverNotNull().onSolveSliderCaptcha(bot, response.url).orEmpty()
|
||||
response = WtLogin.Login.SubCommand2.SubmitSliderCaptcha(bot.client, ticket).sendAndExpect()
|
||||
continue@mainloop
|
||||
@ -193,7 +215,13 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
|
||||
if (response.message.contains("0x9a")) { //Error(title=登录失败, message=请你稍后重试。(0x9a), errorInfo=)
|
||||
throw RetryLaterException()
|
||||
}
|
||||
throw WrongPasswordException(response.toString())
|
||||
val msg = response.toString()
|
||||
throw WrongPasswordException(buildString(capacity = msg.length) {
|
||||
append(msg)
|
||||
if (msg.contains("当前上网环境异常")) { // Error(title=禁止登录, message=当前上网环境异常,请更换网络环境或在常用设备上登录或稍后再试。, errorInfo=)
|
||||
append(", tips=若频繁出现, 请尝试开启设备锁")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
is WtLogin.Login.LoginPacketResponse.DeviceLockLogin -> {
|
||||
|
@ -123,12 +123,13 @@ internal class WtLogin {
|
||||
private const val appId = 16L
|
||||
|
||||
operator fun invoke(
|
||||
client: QQAndroidClient
|
||||
client: QQAndroidClient,
|
||||
allowSlider: Boolean
|
||||
): OutgoingPacket = buildLoginOutgoingPacket(client, bodyType = 2) { sequenceId ->
|
||||
writeSsoPacket(client, client.subAppId, commandName, sequenceId = sequenceId) {
|
||||
writeOicqRequestPacket(client, EncryptMethodECDH(client.ecdh), 0x0810) {
|
||||
writeShort(9) // subCommand
|
||||
writeShort(0x18) // count of TLVs, probably ignored by server?
|
||||
writeShort(if (allowSlider) 0x18 else 0x17) // count of TLVs, probably ignored by server?
|
||||
//writeShort(LoginType.PASSWORD.value.toShort())
|
||||
|
||||
t18(appId, client.appClientVersion, client.uin)
|
||||
@ -231,7 +232,9 @@ internal class WtLogin {
|
||||
t187(client.device.macAddress)
|
||||
t188(client.device.androidId)
|
||||
t194(client.device.imsiMd5)
|
||||
if (allowSlider) {
|
||||
t191()
|
||||
}
|
||||
|
||||
/*
|
||||
t201(N = byteArrayOf())*/
|
||||
|
Loading…
Reference in New Issue
Block a user