mirror of
https://github.com/mamoe/mirai.git
synced 2024-12-31 07:29:45 +08:00
Simplify files
This commit is contained in:
parent
3910044490
commit
b55893ccb1
@ -1,35 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import java.awt.Desktop
|
||||
import java.awt.event.MouseAdapter
|
||||
import java.awt.event.MouseEvent
|
||||
import java.net.URI
|
||||
import javax.swing.JLabel
|
||||
|
||||
/**
|
||||
* 构造方法中url指代用户需要点击的链接, text为显示的提示内容
|
||||
*/
|
||||
internal class HyperLinkLabel constructor(url: String, text: String) : JLabel() {
|
||||
init {
|
||||
super.setText("<html><a href='$url'>$text</a></html>")
|
||||
addMouseListener(object : MouseAdapter() {
|
||||
|
||||
override fun mouseClicked(e: MouseEvent) {
|
||||
try {
|
||||
Desktop.getDesktop().browse(URI(url))
|
||||
} catch (ex: Exception) {
|
||||
ex.printStackTrace()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ package net.mamoe.mirai.utils
|
||||
import net.mamoe.mirai.utils.internal.logging.JdkLogger
|
||||
import net.mamoe.mirai.utils.internal.logging.Log4jLogger
|
||||
import net.mamoe.mirai.utils.internal.logging.Slf4jLogger
|
||||
|
||||
public object LoggerAdapters {
|
||||
@JvmStatic
|
||||
public fun java.util.logging.Logger.asMiraiLogger(): MiraiLogger {
|
||||
|
@ -1,98 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
@file:Suppress("unused", "NOTHING_TO_INLINE")
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
/*
|
||||
|
||||
/**
|
||||
* SoftRef that `getValue` for delegation throws an [IllegalStateException] if the referent is released by GC. Therefore it returns notnull value only
|
||||
*/
|
||||
class UnsafeSoftRef<T>(private val softRef: SoftRef<T>) {
|
||||
fun get(): T = softRef.get() ?: error("SoftRef is released")
|
||||
fun clear() = softRef.clear()
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides delegate value.
|
||||
*
|
||||
* ```kotlin
|
||||
* val bot: Bot by param.unsafeSoftRef()
|
||||
* ```
|
||||
*/
|
||||
@JvmSynthetic
|
||||
inline operator fun <T> UnsafeSoftRef<T>.getValue(thisRef: Any?, property: KProperty<*>): T = get()
|
||||
|
||||
/**
|
||||
* Soft Reference.
|
||||
* On JVM, it is implemented as a typealias referring to `SoftReference` from JDK.
|
||||
*
|
||||
* Details:
|
||||
* On JVM, instances of objects are stored in the JVM Heap and are accessed via references.
|
||||
* GC(garbage collection) can automatically collect and release the memory used by objects that are not directly referred by any other.
|
||||
* [SoftRef] will keep the reference until JVM run out of memory.
|
||||
*
|
||||
* @see softRef provides a SoftRef
|
||||
* @see unsafeSoftRef provides a UnsafeSoftRef
|
||||
*/
|
||||
expect class SoftRef<T>(referent: T) {
|
||||
fun get(): T?
|
||||
fun clear()
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that the property is delegated by a [SoftRef]
|
||||
*
|
||||
* @see softRef
|
||||
*/
|
||||
@Target(AnnotationTarget.PROPERTY)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class SoftRefProperty
|
||||
|
||||
/**
|
||||
* Provides a soft reference to [this]
|
||||
* The `getValue` for delegation returns [this] when [this] is not released by GC
|
||||
*/
|
||||
@JvmSynthetic
|
||||
inline fun <T> T.softRef(): SoftRef<T> = SoftRef(this)
|
||||
|
||||
/**
|
||||
* Constructs an unsafe inline delegate for [this]
|
||||
*/
|
||||
@JvmSynthetic
|
||||
inline fun <T> SoftRef<T>.unsafe(): UnsafeSoftRef<T> = UnsafeSoftRef(this)
|
||||
|
||||
/**
|
||||
* Provides a soft reference to [this].
|
||||
* The `getValue` for delegation throws an [IllegalStateException] if the referent is released by GC. Therefore it returns notnull value only
|
||||
*
|
||||
* **UNSTABLE API**: It is strongly suggested not to use this api
|
||||
*/
|
||||
@JvmSynthetic
|
||||
inline fun <T> T.unsafeSoftRef(): UnsafeSoftRef<T> = UnsafeSoftRef(this.softRef())
|
||||
|
||||
/**
|
||||
* Provides delegate value.
|
||||
*
|
||||
* ```kotlin
|
||||
* val bot: Bot? by param.softRef()
|
||||
* ```
|
||||
*/
|
||||
@JvmSynthetic
|
||||
inline operator fun <T> SoftRef<T>.getValue(thisRef: Any?, property: KProperty<*>): T? = this.get()
|
||||
|
||||
/**
|
||||
* Call the block if the referent is absent
|
||||
*/
|
||||
@JvmSynthetic
|
||||
inline fun <T, R> SoftRef<T>.ifAbsent(block: (T) -> R): R? = this.get()?.let(block)
|
||||
|
||||
*/
|
@ -9,37 +9,40 @@
|
||||
|
||||
package utils
|
||||
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.utils.HyperLinkLabel
|
||||
import net.mamoe.mirai.utils.LoginSolver
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalApi
|
||||
import net.mamoe.mirai.utils.openWindow
|
||||
import java.awt.Desktop
|
||||
import java.net.URI
|
||||
import javax.imageio.ImageIO
|
||||
import javax.swing.ImageIcon
|
||||
import javax.swing.JLabel
|
||||
|
||||
/**
|
||||
* @author Karlatemp <karlatemp@vip.qq.com> <https://github.com/Karlatemp>
|
||||
*/
|
||||
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.utils.*
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Desktop
|
||||
import java.awt.Dimension
|
||||
import java.awt.Toolkit
|
||||
import java.awt.event.*
|
||||
import java.awt.image.BufferedImage
|
||||
import java.net.URI
|
||||
import javax.imageio.ImageIO
|
||||
import javax.swing.*
|
||||
|
||||
@MiraiExperimentalApi
|
||||
public object SwingSolver : LoginSolver() {
|
||||
public override suspend fun onSolvePicCaptcha(bot: Bot, data: ByteArray): String? {
|
||||
public override suspend fun onSolvePicCaptcha(bot: Bot, data: ByteArray): String {
|
||||
return openWindow("Mirai PicCaptcha(${bot.id})") {
|
||||
val image = ImageIO.read(data.inputStream())
|
||||
JLabel(ImageIcon(image)).append()
|
||||
}
|
||||
}
|
||||
|
||||
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("需要滑动验证码, 完成后请关闭该窗口").append()
|
||||
Desktop.getDesktop().browse(URI(url))
|
||||
}
|
||||
}
|
||||
|
||||
public override suspend fun onSolveUnsafeDeviceLoginVerify(bot: Bot, url: String): String? {
|
||||
public override suspend fun onSolveUnsafeDeviceLoginVerify(bot: Bot, url: String): String {
|
||||
return openWindow("Mirai UnsafeDeviceLoginVerify(${bot.id})") {
|
||||
JLabel(
|
||||
"""
|
||||
@ -53,4 +56,140 @@ public object SwingSolver : LoginSolver() {
|
||||
HyperLinkLabel(url, "设备锁验证").last()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 隔离类代码
|
||||
@Suppress("DEPRECATION")
|
||||
internal object WindowHelperJvm {
|
||||
internal val isDesktopSupported: Boolean = kotlin.run {
|
||||
if (System.getProperty("mirai.no-desktop") === null) {
|
||||
kotlin.runCatching {
|
||||
Class.forName("java.awt.Desktop")
|
||||
Class.forName("java.awt.Toolkit")
|
||||
}.onFailure { return@run false } // Android OS
|
||||
kotlin.runCatching {
|
||||
Toolkit.getDefaultToolkit()
|
||||
}.onFailure { // AWT Error, #270
|
||||
return@run false
|
||||
}
|
||||
kotlin.runCatching {
|
||||
Desktop.isDesktopSupported().also { stat ->
|
||||
if (stat) {
|
||||
MiraiLogger.info(
|
||||
"""
|
||||
Mirai 正在使用桌面环境,
|
||||
如果你正在使用SSH, 或无法访问桌面等,
|
||||
请将 `mirai.no-desktop` 添加到 JVM 系统属性中 (-Dmirai.no-desktop)
|
||||
然后重启 Mirai
|
||||
""".trimIndent()
|
||||
)
|
||||
MiraiLogger.info(
|
||||
"""
|
||||
Mirai using DesktopCaptcha System.
|
||||
If you are running on SSH, cannot access desktop or more.
|
||||
Please add `mirai.no-desktop` to JVM properties (-Dmirai.no-desktop)
|
||||
Then restart mirai
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
}.getOrElse {
|
||||
// Should not happen
|
||||
MiraiLogger.warning("Exception in checking desktop support.", it)
|
||||
false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class WindowInitializer(private val initializer: WindowInitializer.(JFrame) -> Unit) {
|
||||
private lateinit var frame0: JFrame
|
||||
val frame: JFrame get() = frame0
|
||||
fun java.awt.Component.append() {
|
||||
frame.add(this, BorderLayout.NORTH)
|
||||
}
|
||||
|
||||
fun java.awt.Component.last() {
|
||||
frame.add(this)
|
||||
}
|
||||
|
||||
internal fun init(frame: JFrame) {
|
||||
this.frame0 = frame
|
||||
initializer(frame)
|
||||
}
|
||||
}
|
||||
|
||||
internal val windowIcon: BufferedImage? by lazy {
|
||||
WindowHelperJvm::class.java.getResourceAsStream("project-mirai.png")?.use {
|
||||
ImageIO.read(it)
|
||||
}
|
||||
}
|
||||
|
||||
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.minimumSize = Dimension(228, 62) // From Windows 10
|
||||
val value = JTextField()
|
||||
val def = CompletableDeferred<String>()
|
||||
value.addKeyListener(object : KeyListener {
|
||||
override fun keyTyped(e: KeyEvent?) {
|
||||
}
|
||||
|
||||
override fun keyPressed(e: KeyEvent?) {
|
||||
when (e!!.keyCode) {
|
||||
27, 10 -> {
|
||||
def.complete(value.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun keyReleased(e: KeyEvent?) {
|
||||
}
|
||||
})
|
||||
frame.layout = BorderLayout(10, 5)
|
||||
frame.add(value, BorderLayout.SOUTH)
|
||||
initializer.init(frame)
|
||||
|
||||
frame.pack()
|
||||
frame.defaultCloseOperation = JFrame.DISPOSE_ON_CLOSE
|
||||
frame.addWindowListener(object : WindowAdapter() {
|
||||
override fun windowClosing(e: WindowEvent?) {
|
||||
def.complete(value.text)
|
||||
}
|
||||
})
|
||||
frame.setLocationRelativeTo(null)
|
||||
frame.title = title
|
||||
frame.isVisible = true
|
||||
|
||||
return def.await().trim().also {
|
||||
SwingUtilities.invokeLater {
|
||||
frame.dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造方法中url指代用户需要点击的链接, text为显示的提示内容
|
||||
*/
|
||||
internal class HyperLinkLabel constructor(url: String, text: String) : JLabel() {
|
||||
init {
|
||||
super.setText("<html><a href='$url'>$text</a></html>")
|
||||
addMouseListener(object : MouseAdapter() {
|
||||
|
||||
override fun mouseClicked(e: MouseEvent) {
|
||||
try {
|
||||
Desktop.getDesktop().browse(URI(url))
|
||||
} catch (ex: Exception) {
|
||||
ex.printStackTrace()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,145 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
/**
|
||||
* @author Karlatemp <karlatemp@vip.qq.com> <https://github.com/Karlatemp>
|
||||
*/
|
||||
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Desktop
|
||||
import java.awt.Dimension
|
||||
import java.awt.Toolkit
|
||||
import java.awt.event.KeyEvent
|
||||
import java.awt.event.KeyListener
|
||||
import java.awt.event.WindowAdapter
|
||||
import java.awt.event.WindowEvent
|
||||
import java.awt.image.BufferedImage
|
||||
import javax.imageio.ImageIO
|
||||
import javax.swing.JFrame
|
||||
import javax.swing.JTextField
|
||||
import javax.swing.SwingUtilities
|
||||
|
||||
// 隔离类代码
|
||||
@Suppress("DEPRECATION")
|
||||
internal object WindowHelperJvm {
|
||||
internal val isDesktopSupported: Boolean = kotlin.run {
|
||||
if (System.getProperty("mirai.no-desktop") === null) {
|
||||
kotlin.runCatching {
|
||||
Class.forName("java.awt.Desktop")
|
||||
Class.forName("java.awt.Toolkit")
|
||||
}.onFailure { return@run false } // Android OS
|
||||
kotlin.runCatching {
|
||||
Toolkit.getDefaultToolkit()
|
||||
}.onFailure { // AWT Error, #270
|
||||
return@run false
|
||||
}
|
||||
kotlin.runCatching {
|
||||
Desktop.isDesktopSupported().also { stat ->
|
||||
if (stat) {
|
||||
MiraiLogger.info(
|
||||
"""
|
||||
Mirai 正在使用桌面环境,
|
||||
如果你正在使用SSH, 或无法访问桌面等,
|
||||
请将 `mirai.no-desktop` 添加到 JVM 系统属性中 (-Dmirai.no-desktop)
|
||||
然后重启 Mirai
|
||||
""".trimIndent()
|
||||
)
|
||||
MiraiLogger.info(
|
||||
"""
|
||||
Mirai using DesktopCaptcha System.
|
||||
If you are running on SSH, cannot access desktop or more.
|
||||
Please add `mirai.no-desktop` to JVM properties (-Dmirai.no-desktop)
|
||||
Then restart mirai
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
}.getOrElse {
|
||||
// Should not happen
|
||||
MiraiLogger.warning("Exception in checking desktop support.", it)
|
||||
false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class WindowInitializer(private val initializer: WindowInitializer.(JFrame) -> Unit) {
|
||||
private lateinit var frame0: JFrame
|
||||
val frame: JFrame get() = frame0
|
||||
fun java.awt.Component.append() {
|
||||
frame.add(this, BorderLayout.NORTH)
|
||||
}
|
||||
|
||||
fun java.awt.Component.last() {
|
||||
frame.add(this)
|
||||
}
|
||||
|
||||
internal fun init(frame: JFrame) {
|
||||
this.frame0 = frame
|
||||
initializer(frame)
|
||||
}
|
||||
}
|
||||
|
||||
internal val windowIcon: BufferedImage? by lazy {
|
||||
WindowHelperJvm::class.java.getResourceAsStream("project-mirai.png")?.use {
|
||||
ImageIO.read(it)
|
||||
}
|
||||
}
|
||||
|
||||
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.minimumSize = Dimension(228, 62) // From Windows 10
|
||||
val value = JTextField()
|
||||
val def = CompletableDeferred<String>()
|
||||
value.addKeyListener(object : KeyListener {
|
||||
override fun keyTyped(e: KeyEvent?) {
|
||||
}
|
||||
|
||||
override fun keyPressed(e: KeyEvent?) {
|
||||
when (e!!.keyCode) {
|
||||
27, 10 -> {
|
||||
def.complete(value.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun keyReleased(e: KeyEvent?) {
|
||||
}
|
||||
})
|
||||
frame.layout = BorderLayout(10, 5)
|
||||
frame.add(value, BorderLayout.SOUTH)
|
||||
initializer.init(frame)
|
||||
|
||||
frame.pack()
|
||||
frame.defaultCloseOperation = JFrame.DISPOSE_ON_CLOSE
|
||||
frame.addWindowListener(object : WindowAdapter() {
|
||||
override fun windowClosing(e: WindowEvent?) {
|
||||
def.complete(value.text)
|
||||
}
|
||||
})
|
||||
frame.setLocationRelativeTo(null)
|
||||
frame.title = title
|
||||
frame.isVisible = true
|
||||
|
||||
return def.await().trim().also {
|
||||
SwingUtilities.invokeLater {
|
||||
frame.dispose()
|
||||
}
|
||||
}
|
||||
}
|
@ -18,7 +18,6 @@ import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.buildPacket
|
||||
import kotlinx.io.core.use
|
||||
import net.mamoe.mirai.Mirai
|
||||
import net.mamoe.mirai.event.*
|
||||
import net.mamoe.mirai.event.events.BotOfflineEvent
|
||||
@ -47,8 +46,6 @@ import net.mamoe.mirai.network.UnsupportedSMSLoginException
|
||||
import net.mamoe.mirai.network.WrongPasswordException
|
||||
import net.mamoe.mirai.utils.*
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.jvm.JvmField
|
||||
import kotlin.jvm.Volatile
|
||||
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bot: QQAndroidBot) : BotNetworkHandler() {
|
||||
|
Loading…
Reference in New Issue
Block a user