Fix LoginSolver choosing, add NoStandardInputForCaptchaException

This commit is contained in:
Him188 2020-04-25 15:28:26 +08:00
parent 79dd1354f6
commit 781dd721d1
4 changed files with 23 additions and 14 deletions

View File

@ -36,6 +36,12 @@ class WrongPasswordException(message: String?) : LoginFailedException(true, mess
*/ */
class NoServerAvailableException(override val cause: Throwable?) : LoginFailedException(false, "no server available") class NoServerAvailableException(override val cause: Throwable?) : LoginFailedException(false, "no server available")
/**
* 无标准输入或 Kotlin 不支持此输入.
*/
class NoStandardInputForCaptchaException(override val cause: Throwable?) :
LoginFailedException(true, "no standard input for captcha")
/** /**
* 需要短信验证时抛出. mirai 目前还不支持短信验证. * 需要短信验证时抛出. mirai 目前还不支持短信验证.
*/ */

View File

@ -22,7 +22,7 @@ import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlinx.io.core.use import kotlinx.io.core.use
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import java.awt.Desktop import net.mamoe.mirai.network.NoStandardInputForCaptchaException
import java.awt.Image import java.awt.Image
import java.awt.image.BufferedImage import java.awt.image.BufferedImage
import java.io.File import java.io.File
@ -32,6 +32,9 @@ import kotlin.coroutines.CoroutineContext
actual typealias Throws = kotlin.jvm.Throws actual typealias Throws = kotlin.jvm.Throws
/**
* 自动选择 [SwingSolver] [StandardCharImageLoginSolver]
*/
@MiraiExperimentalAPI @MiraiExperimentalAPI
class DefaultLoginSolver( class DefaultLoginSolver(
val input: suspend () -> String, val input: suspend () -> String,
@ -40,10 +43,10 @@ class DefaultLoginSolver(
private val delegate: LoginSolver private val delegate: LoginSolver
init { init {
if (WindowHelperJvm.isDesktopSupport) { if (WindowHelperJvm.isDesktopSupported) {
delegate = SwingSolver delegate = SwingSolver
} else { } else {
delegate = DefaultLoginSolverImpl(input, overrideLogger) delegate = StandardCharImageLoginSolver(input, overrideLogger)
} }
} }
@ -60,9 +63,15 @@ class DefaultLoginSolver(
} }
} }
/**
* 使用字符图片展示验证码, 使用 [input] 获取输入, 使用 [overrideLogger] 输出
*/
@MiraiExperimentalAPI @MiraiExperimentalAPI
class DefaultLoginSolverImpl( class StandardCharImageLoginSolver(
input: suspend () -> String, input: suspend () -> String,
/**
* `null` 时使用 [Bot.logger]
*/
private val overrideLogger: MiraiLogger? = null private val overrideLogger: MiraiLogger? = null
) : LoginSolver() { ) : LoginSolver() {
private val input: suspend () -> String = suspend { private val input: suspend () -> String = suspend {
@ -135,16 +144,9 @@ actual abstract class LoginSolver {
actual abstract suspend fun onSolveUnsafeDeviceLoginVerify(bot: Bot, url: String): String? actual abstract suspend fun onSolveUnsafeDeviceLoginVerify(bot: Bot, url: String): String?
actual companion object { actual companion object {
actual val Default: LoginSolver actual val Default: LoginSolver =
@OptIn(MiraiExperimentalAPI::class) @OptIn(MiraiExperimentalAPI::class)
get() { DefaultLoginSolver({ readLine() ?: throw NoStandardInputForCaptchaException(null) })
if (Desktop.isDesktopSupported()) {
return SwingSolver
}
return DefaultLoginSolverImpl(input = {
withContext(Dispatchers.IO) { readLine() } ?: error("No standard input")
})
}
} }
} }

View File

@ -20,6 +20,7 @@ import javax.swing.JTextField
/** /**
* @author Karlatemp <karlatemp@vip.qq.com> <https://github.com/Karlatemp> * @author Karlatemp <karlatemp@vip.qq.com> <https://github.com/Karlatemp>
*/ */
@SinceMirai("0.39.2")
@MiraiExperimentalAPI @MiraiExperimentalAPI
object SwingSolver : LoginSolver() { object SwingSolver : LoginSolver() {
override suspend fun onSolvePicCaptcha(bot: Bot, data: ByteArray): String? { override suspend fun onSolvePicCaptcha(bot: Bot, data: ByteArray): String? {

View File

@ -25,7 +25,7 @@ import javax.swing.JTextField
// 隔离类代码 // 隔离类代码
internal object WindowHelperJvm { internal object WindowHelperJvm {
internal val isDesktopSupport: Boolean = internal val isDesktopSupported: Boolean =
kotlin.runCatching { kotlin.runCatching {
Desktop.isDesktopSupported() Desktop.isDesktopSupported()
}.getOrElse { }.getOrElse {