diff --git a/docs/FAQ.md b/docs/FAQ.md index 8ac209592..09adc4af3 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -32,6 +32,9 @@ mirai 已经可以用于各项工作,但我们并不保证完全的稳定。 请更换 OpenJDK。该问题是由于BouncyCastle在重打包后丢失Jar签名引起的。 ~~多发于Oracle JDK~~ +### 如何完成滑动验证码 +`@see` [mirai-login-solver-selenium](https://github.com/project-mirai/mirai-login-solver-selenium#mirai-login-solver-selenium) + ## 开发相关 > 欢迎帮助维护这个问题列表: 提交 PR 或者 issue. diff --git a/docs/mirai.md b/docs/mirai.md index 5f174b869..9ca1ac59b 100644 --- a/docs/mirai.md +++ b/docs/mirai.md @@ -29,6 +29,10 @@ mirai 项目整体由 核心 (`mirai-core`) 与 控制台(`mirai-console`) 组 - `mirai-serialization` 依赖 `mirai-core`, 是 mirai-core 的序列化支持模块. 提供 `Message` 类型的序列化支持与相关 [mirai 码](MiraiCodeSepecification.md) 支持. 此模块自 mirai `1.1.0` 起可用, 引用方法同 `mirai-core`. +- [`mirai-login-solver-selenium`](https://github.com/project-mirai/mirai-login-solver-selenium). + + `@see` [`mirai-login-solver-selenium/README.md`](https://github.com/project-mirai/mirai-login-solver-selenium#mirai-login-solver-selenium) + - [`mirai-console`](https://github.com/mamoe/mirai-console) 是基于 `mirai-core` 的, 支持插件加载, 指令系统, 和配置等的**控制台框架**. **注意: 此模块正在重写, 短时间内不可用** console 由 '后端' 和 '前端' 组成. diff --git a/mirai-core-api/src/commonMain/kotlin/utils/LoginSolver.kt b/mirai-core-api/src/commonMain/kotlin/utils/LoginSolver.kt index b18bc1635..8a6cbb6bd 100644 --- a/mirai-core-api/src/commonMain/kotlin/utils/LoginSolver.kt +++ b/mirai-core-api/src/commonMain/kotlin/utils/LoginSolver.kt @@ -22,6 +22,8 @@ import net.mamoe.mirai.network.LoginFailedException import net.mamoe.mirai.network.NoStandardInputForCaptchaException import net.mamoe.mirai.utils.LoginSolver.Companion.Default import net.mamoe.mirai.utils.StandardCharImageLoginSolver.Companion.createBlocking +import net.mamoe.mirai.utils.internal.SeleniumLoginSolver +import net.mamoe.mirai.utils.internal.isSliderCaptchaSupportKind import java.awt.Image import java.awt.image.BufferedImage import java.io.File @@ -45,9 +47,9 @@ public abstract class LoginSolver { */ public abstract suspend fun onSolvePicCaptcha(bot: Bot, data: ByteArray): String? - // TODO: 2020-12-24 滑动验证码支持 - @MiraiInternalApi - public open val isSliderCaptchaSupported: Boolean get() = false + @MiraiExperimentalApi + public open val isSliderCaptchaSupported: Boolean + get() = isSliderCaptchaSupportKind ?: false /** * 处理滑动验证码. @@ -84,7 +86,12 @@ public abstract class LoginSolver { @JvmField public val Default: LoginSolver? = when (WindowHelperJvm.platformKind) { WindowHelperJvm.PlatformKind.ANDROID -> null - WindowHelperJvm.PlatformKind.SWING -> SwingSolver + WindowHelperJvm.PlatformKind.SWING -> { + when (isSliderCaptchaSupportKind) { + null, false -> SwingSolver + true -> SeleniumLoginSolver ?: SwingSolver + } + } WindowHelperJvm.PlatformKind.CLI -> StandardCharImageLoginSolver() } @@ -161,8 +168,9 @@ public class StandardCharImageLoginSolver @JvmOverloads constructor( override suspend fun onSolveSliderCaptcha(bot: Bot, url: String): String = loginSolverLock.withLock { val logger = loggerSupplier(bot) - logger.info { "[SliderCaptcha] 需要滑动验证码, 请在任意浏览器中打开以下链接并完成验证码, 完成后请输入任意字符." } - logger.info { "[SliderCaptcha] Slider captcha required, please open the following link in any browser and solve the captcha. Type anything here after completion." } + logger.info { "[SliderCaptcha] 需要滑动验证码, 请在 Chrome 浏览器中打开以下链接并完成验证码, 完成后请输入提示 ticket." } + logger.info { "[SliderCaptcha] Slider captcha required, please open the following link in Chrome browser and solve the captcha. Type ticket here after completion." } + logger.info { "[SliderCaptcha] Chrome Extension: https://github.com/project-mirai/mirai-login-solver-selenium#%E4%B8%8B%E8%BD%BD-chrome-%E6%89%A9%E5%B1%95%E6%8F%92%E4%BB%B6" } logger.info(url) return input().also { logger.info { "[SliderCaptcha] 正在提交中..." } diff --git a/mirai-core-api/src/commonMain/kotlin/utils/SwingSolver.kt b/mirai-core-api/src/commonMain/kotlin/utils/SwingSolver.kt index 7a504d374..429488cd4 100644 --- a/mirai-core-api/src/commonMain/kotlin/utils/SwingSolver.kt +++ b/mirai-core-api/src/commonMain/kotlin/utils/SwingSolver.kt @@ -37,7 +37,11 @@ public object SwingSolver : LoginSolver() { public override suspend fun onSolveSliderCaptcha(bot: Bot, url: String): String { return openWindow("Mirai SliderCaptcha(${bot.id})") { - JLabel("需要滑动验证码, 完成后请关闭该窗口").append() + JLabel(""" + + 需要滑动验证码, 完成后请输入ticket
+ Chrome浏览器扩展下载: https://github.com/project-mirai/mirai-login-solver-selenium + """.trimIndent()).append() // Try to open browser safely. #694 kotlin.runCatching { Desktop.getDesktop().browse(URI(url)) diff --git a/mirai-core-api/src/commonMain/kotlin/utils/internal/SeleniumLoginSolverSupport.kt b/mirai-core-api/src/commonMain/kotlin/utils/internal/SeleniumLoginSolverSupport.kt new file mode 100644 index 000000000..fe850956a --- /dev/null +++ b/mirai-core-api/src/commonMain/kotlin/utils/internal/SeleniumLoginSolverSupport.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 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.internal + +import net.mamoe.mirai.utils.LoginSolver + +internal val SeleniumLoginSolver: LoginSolver? by lazy { + runCatching { + Class.forName("net.mamoe.mirai.selenium.SeleniumLoginSolver") + .getMethod("getInstance") + .invoke(null) as? LoginSolver + }.getOrNull() +} + +// null -> 该情况为 user 确认能自己传入 ticket, 不需要 Selenium 的帮助 +// true -> SeleniumLoginSolver 支持 +// false-> 无法提供默认滑块验证解决器 +internal val isSliderCaptchaSupportKind: Boolean? by lazy { + if (System.getProperty("mirai.slider.captcha.supported") != null) { + null + } else { + SeleniumLoginSolver != null + } +}