diff --git a/docs/Events.md b/docs/Events.md index 96fedfe12..6efb758e7 100644 --- a/docs/Events.md +++ b/docs/Events.md @@ -106,9 +106,7 @@ channel = channel.parentJob(job) 在 Kotlin,可以使用如下扩展快速在 GlobalEventChannel 创建一个指定协程作用域下的事件通道。 > ```kotlin -> ```kotlin -> > fun CoroutineScope.globalEventChannel(coroutineContext: CoroutineContext = EmptyCoroutineContext): EventChannel = GlobalEventChannel.parentScope(this, coroutineContext) -> > ``` +> fun CoroutineScope.globalEventChannel(coroutineContext: CoroutineContext = EmptyCoroutineContext): EventChannel = GlobalEventChannel.parentScope(this, coroutineContext) > ``` ```kotlin @@ -467,4 +465,4 @@ reply("复读模式结束") > 下一步,[Messages](Messages.md) > -> [回到 Mirai 文档索引](README.md) \ No newline at end of file +> [回到 Mirai 文档索引](README.md) diff --git a/mirai-core-api/src/commonMain/kotlin/utils/LoginSolver.kt b/mirai-core-api/src/commonMain/kotlin/utils/LoginSolver.kt index 75e3264b0..66f92789a 100644 --- a/mirai-core-api/src/commonMain/kotlin/utils/LoginSolver.kt +++ b/mirai-core-api/src/commonMain/kotlin/utils/LoginSolver.kt @@ -174,9 +174,9 @@ public class StandardCharImageLoginSolver @JvmOverloads constructor( override suspend fun onSolveSliderCaptcha(bot: Bot, url: String): String = loginSolverLock.withLock { val logger = loggerSupplier(bot) - 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 { "[SliderCaptcha] 需要滑动验证码, 请在浏览器中打开以下链接并完成验证码, 完成后请输入提示 ticket." } + logger.info { "[SliderCaptcha] Slider captcha required, please open the following link in any browser and solve the captcha. Type ticket here after completion." } + logger.info { "[SliderCaptcha] @see 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 429488cd4..732957955 100644 --- a/mirai-core-api/src/commonMain/kotlin/utils/SwingSolver.kt +++ b/mirai-core-api/src/commonMain/kotlin/utils/SwingSolver.kt @@ -35,20 +35,17 @@ public object SwingSolver : LoginSolver() { } } - public override suspend fun onSolveSliderCaptcha(bot: Bot, url: String): String { + public override suspend fun onSolveSliderCaptcha(bot: Bot, url: String): String? { return openWindow("Mirai SliderCaptcha(${bot.id})") { - JLabel(""" + 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)) - }.onFailure { - JTextField(url).last() - } - } + @see: https://github.com/project-mirai/mirai-login-solver-selenium + """.trimIndent() + ).append() + JTextField(url).last() + }.takeIf { it.isNotEmpty() } } public override suspend fun onSolveUnsafeDeviceLoginVerify(bot: Bot, url: String): String { diff --git a/mirai-core-api/src/commonMain/kotlin/utils/internal/SeleniumLoginSolverSupport.kt b/mirai-core-api/src/commonMain/kotlin/utils/internal/SeleniumLoginSolverSupport.kt index fe850956a..ebe1bd41b 100644 --- a/mirai-core-api/src/commonMain/kotlin/utils/internal/SeleniumLoginSolverSupport.kt +++ b/mirai-core-api/src/commonMain/kotlin/utils/internal/SeleniumLoginSolverSupport.kt @@ -10,13 +10,19 @@ package net.mamoe.mirai.utils.internal import net.mamoe.mirai.utils.LoginSolver +import net.mamoe.mirai.utils.MiraiLogger internal val SeleniumLoginSolver: LoginSolver? by lazy { - runCatching { + try { Class.forName("net.mamoe.mirai.selenium.SeleniumLoginSolver") .getMethod("getInstance") .invoke(null) as? LoginSolver - }.getOrNull() + } catch (ignore: ClassNotFoundException) { + null + } catch (error: Throwable) { + MiraiLogger.TopLevel.warning("Error in loading mirai-login-solver-selenium, skip", error) + null + } } // null -> 该情况为 user 确认能自己传入 ticket, 不需要 Selenium 的帮助 diff --git a/mirai-core/build.gradle.kts b/mirai-core/build.gradle.kts index 8c5189d6d..a1daebef2 100644 --- a/mirai-core/build.gradle.kts +++ b/mirai-core/build.gradle.kts @@ -121,7 +121,7 @@ kotlin { jvmTest { dependencies { implementation("org.pcap4j:pcap4j-distribution:1.8.2") - implementation("net.mamoe:mirai-login-solver-selenium:1.0-dev-5") + implementation("net.mamoe:mirai-login-solver-selenium:1.0-dev-9") } } } diff --git a/mirai-core/src/commonMain/kotlin/network/QQAndroidBotNetworkHandler.kt b/mirai-core/src/commonMain/kotlin/network/QQAndroidBotNetworkHandler.kt index 342188dc1..5d0a0c8bb 100644 --- a/mirai-core/src/commonMain/kotlin/network/QQAndroidBotNetworkHandler.kt +++ b/mirai-core/src/commonMain/kotlin/network/QQAndroidBotNetworkHandler.kt @@ -207,7 +207,19 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo } ) } - val ticket = loginSolverNotNull().onSolveSliderCaptcha(bot, response.url).orEmpty() + val ticket = try { + loginSolverNotNull().onSolveSliderCaptcha(bot, response.url) + ?.takeIf { it.isNotEmpty() } + ?: return closeEverythingAndRelogin(host, port, cause, step) + } catch (lfe: LoginFailedException) { + throw lfe + } catch (error: Throwable) { + if (step == 0) { + logger.warning(error) + return closeEverythingAndRelogin(host, port, error, 1) + } + throw error + } response = WtLogin.Login.SubCommand2.SubmitSliderCaptcha(bot.client, ticket).sendAndExpect() continue@mainloop }