From aa289e932f19efd6e238b77a81696c3faf552441 Mon Sep 17 00:00:00 2001 From: Him188 Date: Wed, 24 Feb 2021 10:18:04 +0800 Subject: [PATCH] Multiplatform LoginSolver: - On JVM: Same behaviour as before - On Android: LoginSolver.Default returns `null` always --- .../kotlin/utils/LoginSolver.android.kt | 78 +++++++++++++++ .../commonMain/kotlin/utils/LoginSolver.kt | 25 ++--- .../jvmMain/kotlin/utils/LoginSolver.jvm.kt | 96 +++++++++++++++++++ .../kotlin/utils/SwingSolver.kt | 2 +- 4 files changed, 181 insertions(+), 20 deletions(-) create mode 100644 mirai-core-api/src/androidMain/kotlin/utils/LoginSolver.android.kt create mode 100644 mirai-core-api/src/jvmMain/kotlin/utils/LoginSolver.jvm.kt rename mirai-core-api/src/{commonMain => jvmMain}/kotlin/utils/SwingSolver.kt (99%) diff --git a/mirai-core-api/src/androidMain/kotlin/utils/LoginSolver.android.kt b/mirai-core-api/src/androidMain/kotlin/utils/LoginSolver.android.kt new file mode 100644 index 000000000..30e47b61a --- /dev/null +++ b/mirai-core-api/src/androidMain/kotlin/utils/LoginSolver.android.kt @@ -0,0 +1,78 @@ +/* + * Copyright 2019-2021 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/master/LICENSE + */ + + +package net.mamoe.mirai.utils + +import net.mamoe.mirai.Bot +import net.mamoe.mirai.internal.utils.isSliderCaptchaSupportKind +import net.mamoe.mirai.network.LoginFailedException +import net.mamoe.mirai.utils.LoginSolver.Companion.Default + + +/** + * 验证码, 设备锁解决器 + * + * @see Default + * @see BotConfiguration.loginSolver + */ +public actual abstract class LoginSolver public actual constructor() { + /** + * 处理图片验证码. + * + * 返回 `null` 以表示无法处理验证码, 将会刷新验证码或重试登录. + * 抛出一个 [LoginFailedException] 以正常地终止登录, 抛出任意其他 [Exception] 将视为异常终止 + * + * @throws LoginFailedException + */ + public actual abstract suspend fun onSolvePicCaptcha(bot: Bot, data: ByteArray): String? + + /** + * 为 `true` 表示支持滑动验证码, 遇到滑动验证码时 mirai 会请求 [onSolveSliderCaptcha]. + * 否则会跳过滑动验证码并告诉服务器此客户端不支持, 有可能导致登录失败 + */ + public actual open val isSliderCaptchaSupported: Boolean + get() = isSliderCaptchaSupportKind ?: true + + /** + * 处理滑动验证码. + * + * 返回 `null` 以表示无法处理验证码, 将会刷新验证码或重试登录. + * 抛出一个 [LoginFailedException] 以正常地终止登录, 抛出任意其他 [Exception] 将视为异常终止 + * + * @throws LoginFailedException + * @return 验证码解决成功后获得的 ticket. + */ + public actual abstract suspend fun onSolveSliderCaptcha(bot: Bot, url: String): String? + + /** + * 处理不安全设备验证. + * + * 返回值保留给将来使用. 目前在处理完成后返回任意内容 (包含 `null`) 均视为处理成功. + * 抛出一个 [LoginFailedException] 以正常地终止登录, 抛出任意其他 [Exception] 将视为异常终止. + * + * @return 任意内容. 返回值保留以供未来更新. + * @throws LoginFailedException + */ + public actual abstract suspend fun onSolveUnsafeDeviceLoginVerify(bot: Bot, url: String): String? + + public actual companion object { + /** + * 当前平台默认的 [LoginSolver]. Android 端没有默认验证码实现, [Default] 总为 `null`. + */ + @JvmField + public actual val Default: LoginSolver? = null + + @Suppress("unused") + @Deprecated("Binary compatibility", level = DeprecationLevel.HIDDEN) + public actual fun getDefault(): LoginSolver = Default + ?: error("LoginSolver is not provided by default on your platform. Please specify by BotConfiguration.loginSolver") + } + +} \ No newline at end of file diff --git a/mirai-core-api/src/commonMain/kotlin/utils/LoginSolver.kt b/mirai-core-api/src/commonMain/kotlin/utils/LoginSolver.kt index 6320f571a..b185e610a 100644 --- a/mirai-core-api/src/commonMain/kotlin/utils/LoginSolver.kt +++ b/mirai-core-api/src/commonMain/kotlin/utils/LoginSolver.kt @@ -18,8 +18,6 @@ import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withContext import net.mamoe.mirai.Bot -import net.mamoe.mirai.internal.utils.SeleniumLoginSolver -import net.mamoe.mirai.internal.utils.isSliderCaptchaSupportKind import net.mamoe.mirai.network.LoginFailedException import net.mamoe.mirai.network.NoStandardInputForCaptchaException import net.mamoe.mirai.utils.DeviceInfo.Companion.loadAsDeviceInfo @@ -38,7 +36,7 @@ import kotlin.coroutines.CoroutineContext * @see Default * @see BotConfiguration.loginSolver */ -public abstract class LoginSolver { +public expect abstract class LoginSolver() { /** * 处理图片验证码. * @@ -54,7 +52,6 @@ public abstract class LoginSolver { * 否则会跳过滑动验证码并告诉服务器此客户端不支持, 有可能导致登录失败 */ public open val isSliderCaptchaSupported: Boolean - get() = isSliderCaptchaSupportKind ?: true /** * 处理滑动验证码. @@ -83,29 +80,19 @@ public abstract class LoginSolver { * 当前平台默认的 [LoginSolver]。 * * 检测策略: - * 1. 检测 `android.util.Log`, 如果存在, 返回 `null`. + * 1. 若是 `mirai-core-api-android` 或 `android.util.Log` 存在, 返回 `null`. * 2. 检测 JVM 属性 `mirai.no-desktop`. 若存在, 返回 [StandardCharImageLoginSolver] - * 3. 检测 JVM 桌面环境, 若支持, 返回 [SwingSolver] + * 3. 检测 JVM 桌面环境, 若支持, 返回 `SwingSolver` * 4. 返回 [StandardCharImageLoginSolver] * - * @return [SwingSolver] 或 [StandardCharImageLoginSolver] 或 `null` + * @return `SwingSolver` 或 [StandardCharImageLoginSolver] 或 `null` */ @JvmField - public val Default: LoginSolver? = when (WindowHelperJvm.platformKind) { - WindowHelperJvm.PlatformKind.ANDROID -> null - WindowHelperJvm.PlatformKind.SWING -> { - when (isSliderCaptchaSupportKind) { - null, false -> SwingSolver - true -> SeleniumLoginSolver ?: SwingSolver - } - } - WindowHelperJvm.PlatformKind.CLI -> StandardCharImageLoginSolver() - } + public val Default: LoginSolver? @Suppress("unused") @Deprecated("Binary compatibility", level = DeprecationLevel.HIDDEN) - public fun getDefault(): LoginSolver = Default - ?: error("LoginSolver is not provided by default on your platform. Please specify by BotConfiguration.loginSolver") + public fun getDefault(): LoginSolver } } diff --git a/mirai-core-api/src/jvmMain/kotlin/utils/LoginSolver.jvm.kt b/mirai-core-api/src/jvmMain/kotlin/utils/LoginSolver.jvm.kt new file mode 100644 index 000000000..2c5c83eca --- /dev/null +++ b/mirai-core-api/src/jvmMain/kotlin/utils/LoginSolver.jvm.kt @@ -0,0 +1,96 @@ +/* + * Copyright 2019-2021 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/master/LICENSE + */ + + +package net.mamoe.mirai.utils + +import net.mamoe.mirai.Bot +import net.mamoe.mirai.internal.utils.SeleniumLoginSolver +import net.mamoe.mirai.internal.utils.isSliderCaptchaSupportKind +import net.mamoe.mirai.network.LoginFailedException +import net.mamoe.mirai.utils.LoginSolver.Companion.Default + + +/** + * 验证码, 设备锁解决器 + * + * @see Default + * @see BotConfiguration.loginSolver + */ +public actual abstract class LoginSolver public actual constructor() { + /** + * 处理图片验证码. + * + * 返回 `null` 以表示无法处理验证码, 将会刷新验证码或重试登录. + * 抛出一个 [LoginFailedException] 以正常地终止登录, 抛出任意其他 [Exception] 将视为异常终止 + * + * @throws LoginFailedException + */ + public actual abstract suspend fun onSolvePicCaptcha(bot: Bot, data: ByteArray): String? + + /** + * 为 `true` 表示支持滑动验证码, 遇到滑动验证码时 mirai 会请求 [onSolveSliderCaptcha]. + * 否则会跳过滑动验证码并告诉服务器此客户端不支持, 有可能导致登录失败 + */ + public actual open val isSliderCaptchaSupported: Boolean + get() = isSliderCaptchaSupportKind ?: true + + /** + * 处理滑动验证码. + * + * 返回 `null` 以表示无法处理验证码, 将会刷新验证码或重试登录. + * 抛出一个 [LoginFailedException] 以正常地终止登录, 抛出任意其他 [Exception] 将视为异常终止 + * + * @throws LoginFailedException + * @return 验证码解决成功后获得的 ticket. + */ + public actual abstract suspend fun onSolveSliderCaptcha(bot: Bot, url: String): String? + + /** + * 处理不安全设备验证. + * + * 返回值保留给将来使用. 目前在处理完成后返回任意内容 (包含 `null`) 均视为处理成功. + * 抛出一个 [LoginFailedException] 以正常地终止登录, 抛出任意其他 [Exception] 将视为异常终止. + * + * @return 任意内容. 返回值保留以供未来更新. + * @throws LoginFailedException + */ + public actual abstract suspend fun onSolveUnsafeDeviceLoginVerify(bot: Bot, url: String): String? + + public actual companion object { + /** + * 当前平台默认的 [LoginSolver]。 + * + * 检测策略: + * 1. 检测 `android.util.Log`, 如果存在, 返回 `null`. + * 2. 检测 JVM 属性 `mirai.no-desktop`. 若存在, 返回 [StandardCharImageLoginSolver] + * 3. 检测 JVM 桌面环境, 若支持, 返回 [SwingSolver] + * 4. 返回 [StandardCharImageLoginSolver] + * + * @return [SwingSolver] 或 [StandardCharImageLoginSolver] 或 `null` + */ + @JvmField + public actual val Default: LoginSolver? = when (WindowHelperJvm.platformKind) { + WindowHelperJvm.PlatformKind.ANDROID -> null + WindowHelperJvm.PlatformKind.SWING -> { + when (isSliderCaptchaSupportKind) { + null, false -> SwingSolver + true -> SeleniumLoginSolver ?: SwingSolver + } + } + WindowHelperJvm.PlatformKind.CLI -> StandardCharImageLoginSolver() + } + + @Suppress("unused") + @Deprecated("Binary compatibility", level = DeprecationLevel.HIDDEN) + public actual fun getDefault(): LoginSolver = Default + ?: error("LoginSolver is not provided by default on your platform. Please specify by BotConfiguration.loginSolver") + } + +} \ No newline at end of file diff --git a/mirai-core-api/src/commonMain/kotlin/utils/SwingSolver.kt b/mirai-core-api/src/jvmMain/kotlin/utils/SwingSolver.kt similarity index 99% rename from mirai-core-api/src/commonMain/kotlin/utils/SwingSolver.kt rename to mirai-core-api/src/jvmMain/kotlin/utils/SwingSolver.kt index 732957955..7c7e27ac4 100644 --- a/mirai-core-api/src/commonMain/kotlin/utils/SwingSolver.kt +++ b/mirai-core-api/src/jvmMain/kotlin/utils/SwingSolver.kt @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 Mamoe Technologies and contributors. + * Copyright 2019-2021 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.