Simplify files

This commit is contained in:
Him188 2020-12-01 12:38:02 +08:00
parent 3910044490
commit b55893ccb1
8 changed files with 155 additions and 296 deletions

View File

@ -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()
}
}
})
}
}

View File

@ -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 {

View File

@ -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)
*/

View File

@ -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()
}
}
})
}
}

View File

@ -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()
}
}
}

View File

@ -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() {