diff --git a/mirai-core-api/src/commonMain/kotlin/utils/SwingSolver.kt b/mirai-core-api/src/commonMain/kotlin/utils/SwingSolver.kt index f0ee954da..d674c8703 100644 --- a/mirai-core-api/src/commonMain/kotlin/utils/SwingSolver.kt +++ b/mirai-core-api/src/commonMain/kotlin/utils/SwingSolver.kt @@ -38,12 +38,18 @@ public object SwingSolver : LoginSolver() { public override suspend fun onSolveSliderCaptcha(bot: Bot, url: String): String { return openWindow("Mirai SliderCaptcha(${bot.id})") { JLabel("需要滑动验证码, 完成后请关闭该窗口").append() - Desktop.getDesktop().browse(URI(url)) + // Try to open browser safely. #694 + kotlin.runCatching { + Desktop.getDesktop().browse(URI(url)) + }.onFailure { + JTextField(url).last() + } } } public override suspend fun onSolveUnsafeDeviceLoginVerify(bot: Bot, url: String): String { - return openWindow("Mirai UnsafeDeviceLoginVerify(${bot.id})") { + val title = "Mirai UnsafeDeviceLoginVerify(${bot.id})" + return openWindow(title) { JLabel( """ <html> @@ -53,13 +59,15 @@ public object SwingSolver : LoginSolver() { 成功后请关闭该窗口 """.trimIndent() ).append() - HyperLinkLabel(url, "设备锁验证").last() + HyperLinkLabel(url, "设备锁验证", title).last() } } } // 隔离类代码 +// 在 jvm 中, 使用 WindowHelperJvm 不会加载 SwingSolverKt +// 不会触发各种 NoDefClassError @Suppress("DEPRECATION") internal object WindowHelperJvm { internal val isDesktopSupported: Boolean = kotlin.run { @@ -122,19 +130,23 @@ internal class WindowInitializer(private val initializer: WindowInitializer.(JFr } } -internal val windowIcon: BufferedImage? by lazy { +internal val windowImage: BufferedImage? by lazy { WindowHelperJvm::class.java.getResourceAsStream("project-mirai.png")?.use { ImageIO.read(it) } } +internal val windowIcon: Icon? by lazy { + windowImage?.let(::ImageIcon) +} + internal suspend fun openWindow(title: String = "", initializer: WindowInitializer.(JFrame) -> Unit = {}): String { return openWindow(title, WindowInitializer(initializer)) } internal suspend fun openWindow(title: String = "", initializer: WindowInitializer = WindowInitializer {}): String { val frame = JFrame() - frame.iconImage = windowIcon + frame.iconImage = windowImage frame.minimumSize = Dimension(228, 62) // From Windows 10 val value = JTextField() val def = CompletableDeferred<String>() @@ -176,18 +188,33 @@ internal suspend fun openWindow(title: String = "", initializer: WindowInitializ } /** - * 构造方法中url指代用户需要点击的链接, text为显示的提示内容 + * @param url 打开的链接 + * @param text 显示的提示内容 + * @param fallbackTitle 无法打开链接时的提醒窗口标题 */ -internal class HyperLinkLabel constructor(url: String, text: String) : JLabel() { +internal class HyperLinkLabel constructor( + url: String, + text: String, + fallbackTitle: String +) : JLabel() { init { super.setText("<html><a href='$url'>$text</a></html>") addMouseListener(object : MouseAdapter() { override fun mouseClicked(e: MouseEvent) { + // Try to open browser safely. #694 try { Desktop.getDesktop().browse(URI(url)) } catch (ex: Exception) { - ex.printStackTrace() + JOptionPane.showInputDialog( + this@HyperLinkLabel, + "Mirai 无法直接打开浏览器, 请手动复制以下 URL 打开", + fallbackTitle, + JOptionPane.WARNING_MESSAGE, + windowIcon, + null, + url + ) } } })