From 5402505a8f48d447595c9dbed579693450c7b368 Mon Sep 17 00:00:00 2001 From: "jiahua.liu" Date: Tue, 25 Feb 2020 17:32:31 +0800 Subject: [PATCH 1/8] to merge --- .../mirai/console/plugins/ConfigSection.kt | 8 +- .../mamoe/mirai/console/plugins/PluginBase.kt | 11 +- .../mirai/imageplugin/ImageSenderMain.kt | 115 +++++++++++++----- .../mirai/imageplugin => resources}/Test.kt | 0 4 files changed, 98 insertions(+), 36 deletions(-) rename mirai-plugins/image-sender/src/main/{java/net/mamoe/mirai/imageplugin => resources}/Test.kt (100%) diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/ConfigSection.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/ConfigSection.kt index e80676438..ed52dae92 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/ConfigSection.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/ConfigSection.kt @@ -184,9 +184,11 @@ class WithDefaultWriteLoader( prop: KProperty<*> ): ReadWriteProperty { val defaultValue by lazy { defaultValue.invoke() } - config.setIfAbsent(prop.name, defaultValue) - if (save) { - config.save() + if (!config.contains(prop.name)) { + config[prop.name] = defaultValue + if (save) { + config.save() + } } return object : ReadWriteProperty { override fun getValue(thisRef: Any, property: KProperty<*>): T { diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt index 4d1bd6f07..0e3770dfc 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt @@ -90,15 +90,24 @@ abstract class PluginBase(coroutineContext: CoroutineContext) : CoroutineScope { fun getPluginManager() = PluginManager val logger: MiraiLogger by lazy { - DefaultLogger(pluginDescription.name) + SimpleLogger("Plugin ${pluginDescription.name}") { _, message, e -> + MiraiConsole.logger("[${pluginDescription.name}]", 0, message) + if (e != null) { + MiraiConsole.logger("[${pluginDescription.name}]", 0, e.toString()) + e.printStackTrace() + } + } } + fun getResources(fileName: String): InputStream? { return PluginManager.getFileInJarByName( this.pluginDescription.name, fileName ) } + + //fun getResourcesConfig() } class PluginDescription( diff --git a/mirai-plugins/image-sender/src/main/java/net/mamoe/mirai/imageplugin/ImageSenderMain.kt b/mirai-plugins/image-sender/src/main/java/net/mamoe/mirai/imageplugin/ImageSenderMain.kt index 2e575f86d..0bbb64fca 100644 --- a/mirai-plugins/image-sender/src/main/java/net/mamoe/mirai/imageplugin/ImageSenderMain.kt +++ b/mirai-plugins/image-sender/src/main/java/net/mamoe/mirai/imageplugin/ImageSenderMain.kt @@ -10,19 +10,29 @@ package net.mamoe.mirai.imageplugin import kotlinx.coroutines.* +import net.mamoe.mirai.console.MiraiConsole +import net.mamoe.mirai.console.command.registerCommand import net.mamoe.mirai.console.plugins.Config import net.mamoe.mirai.console.plugins.ConfigSection import net.mamoe.mirai.console.plugins.PluginBase +import net.mamoe.mirai.console.plugins.withDefaultWriteSave import net.mamoe.mirai.contact.Contact +import net.mamoe.mirai.contact.sendMessage import net.mamoe.mirai.event.events.BotOnlineEvent +import net.mamoe.mirai.event.events.MemberPermissionChangeEvent import net.mamoe.mirai.event.subscribeAlways +import net.mamoe.mirai.event.subscribeGroupMessages import net.mamoe.mirai.event.subscribeMessages import net.mamoe.mirai.message.data.Image +import net.mamoe.mirai.message.data.sendTo +import net.mamoe.mirai.message.upload import net.mamoe.mirai.message.uploadAsImage import net.mamoe.mirai.utils.MiraiExperimentalAPI import org.jsoup.Jsoup -import java.io.File -import java.net.URL +import java.awt.RenderingHints +import java.awt.image.BufferedImage +import javax.imageio.ImageIO + class ImageSenderMain : PluginBase() { @@ -30,42 +40,60 @@ class ImageSenderMain : PluginBase() { lateinit var normal: List lateinit var r18: List - @ExperimentalCoroutinesApi - @MiraiExperimentalAPI + + val config by lazy { + loadConfig("setting.yml") + } + + val Normal_Image_Trigger by config.withDefaultWriteSave { "色图" } + val R18_Image_Trigger by config.withDefaultWriteSave { "不够色" } + val Image_Resize_Max_Width_Height by config.withDefaultWriteSave { 800 } + + val groupsAllowNormal by lazy { + config.getLongList("Allow_Normal_Image_Groups").toMutableList() + } + + val groupsAllowR18 by lazy { + config.getLongList("Allow_R18_Image_Groups").toMutableList() + } + + override fun onDisable() { + config["Allow_R18_Image_Groups"] = groupsAllowR18 + config["Allow_Normal_Image_Groups"] = groupsAllowNormal + config.save() + } + override fun onEnable() { logger.info("Image Sender plugin enabled") - GlobalScope.subscribeAlways { + registerCommands() + subscribeAlways { logger.info("${this.bot.uin} login succeed, it will be controlled by Image Sender Plugin") - this.bot.subscribeMessages { - (contains("色图")) { - try { - with(normal.random()) { - getImage( - subject, this.getString("url"), this.getString("pid") - ).plus(this.getString("tags")).send() - } - } catch (e: Exception) { - reply(e.message ?: "unknown error") - } + this.bot.subscribeGroupMessages { + (contains(Normal_Image_Trigger)) { + sendImage(subject, normal.random()) } - - (contains("不够色")) { - try { - with(r18.random()) { - getImage( - subject, this.getString("url"), this.getString("pid") - ).plus(this.getString("tags")).send() - } - } catch (e: Exception) { - reply(e.message ?: "unknown error") - } + (contains(R18_Image_Trigger)) { + sendImage(subject, r18.random()) } } } } - suspend fun getImage(contact: Contact, url: String, pid: String): Image { - return withTimeoutOrNull(20 * 1000) { + private fun sendImage(contact: Contact, configSection: ConfigSection) { + launch { + try { + logger.info("正在推送图片") + getImage( + contact, configSection.getString("url"), configSection.getString("pid"), 800 + ).plus(configSection.getString("tags")).sendTo(contact) + } catch (e: Exception) { + contact.sendMessage(e.message ?: "unknown error") + } + } + } + + private suspend fun getImage(contact: Contact, url: String, pid: String, maxWidthOrHeight: Int): Image { + val bodyStream = withTimeoutOrNull(20 * 1000) { withContext(Dispatchers.IO) { Jsoup .connect(url) @@ -78,9 +106,30 @@ class ImageSenderMain : PluginBase() { .maxBodySize(100000000) .execute().also { check(it.statusCode() == 200) { "Failed to download image" } } } - }?.bodyStream()?.uploadAsImage(contact) ?: error("Unable to download image") + }?.bodyStream() ?: error("Failed to download image") + if (maxWidthOrHeight < 1) { + return bodyStream.uploadAsImage(contact) + } + val image = withContext(Dispatchers.IO) { + ImageIO.read(bodyStream) + } + if (image.width.coerceAtLeast(image.height) <= maxWidthOrHeight) { + return image.upload(contact) + } + val rate = (maxWidthOrHeight.toFloat() / image.width.coerceAtLeast(image.height)) + val newWidth = (image.width * rate).toInt() + val newHeight = (image.height * rate).toInt() + return withContext(Dispatchers.IO) { + val dimg = BufferedImage(newWidth, newHeight, image.type) + val g = dimg.createGraphics() + g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR) + g.drawImage(image, 0, 0, newWidth, newHeight, 0, 0, image.width, image.height, null) + g.dispose() + dimg + }.upload(contact) } + override fun onLoad() { logger.info("loading local image data") @@ -97,8 +146,10 @@ class ImageSenderMain : PluginBase() { logger.info("R18 * " + r18.size) } + fun registerCommands() { + registerCommand { - override fun onDisable() { - + } } + } \ No newline at end of file diff --git a/mirai-plugins/image-sender/src/main/java/net/mamoe/mirai/imageplugin/Test.kt b/mirai-plugins/image-sender/src/main/resources/Test.kt similarity index 100% rename from mirai-plugins/image-sender/src/main/java/net/mamoe/mirai/imageplugin/Test.kt rename to mirai-plugins/image-sender/src/main/resources/Test.kt From e42d7ff7a145cf7580fbdb129319d5c3f8ea4e03 Mon Sep 17 00:00:00 2001 From: "jiahua.liu" Date: Tue, 25 Feb 2020 17:52:25 +0800 Subject: [PATCH 2/8] add usage --- .../mamoe/mirai/console/command/Command.kt | 8 +++- .../mamoe/mirai/console/plugins/PluginBase.kt | 43 ++++++++++++++----- .../mirai/imageplugin/ImageSenderMain.kt | 2 +- 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt index 53e7f5175..bec68e608 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt @@ -156,6 +156,8 @@ interface Command { val name: String val alias: List val description: String + val usage: String + suspend fun onCommand(sender: CommandSender, args: List): Boolean fun register() } @@ -163,7 +165,8 @@ interface Command { abstract class BlockingCommand( override val name: String, override val alias: List = listOf(), - override val description: String = "" + override val description: String = "", + override val usage: String = "" ) : Command { /** * 最高优先级监听器 @@ -186,6 +189,7 @@ class AnonymousCommand internal constructor( override val name: String, override val alias: List, override val description: String, + override val usage: String = "", val onCommand: suspend CommandSender.(args: List) -> Boolean ) : Command { override suspend fun onCommand(sender: CommandSender, args: List): Boolean { @@ -201,6 +205,7 @@ class CommandBuilder internal constructor() { var name: String? = null var alias: List? = null var description: String = "" + var usage: String = "use /help for help" var onCommand: (suspend CommandSender.(args: List) -> Boolean)? = null fun onCommand(commandProcess: suspend CommandSender.(args: List) -> Boolean) { @@ -218,6 +223,7 @@ class CommandBuilder internal constructor() { name!!, alias!!, description, + usage, onCommand!! ).also { it.register() } } diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt index b77457782..e5e35c34e 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt @@ -31,6 +31,9 @@ abstract class PluginBase(coroutineContext: CoroutineContext) : CoroutineScope { private val supervisorJob = SupervisorJob() final override val coroutineContext: CoroutineContext = coroutineContext + supervisorJob + /** + * 插件被分配的data folder, 如果插件改名了 data folder 也会变 请注意 + */ val dataFolder: File by lazy { File(PluginManager.pluginsPath + pluginDescription.name).also { it.mkdir() } } @@ -68,12 +71,14 @@ abstract class PluginBase(coroutineContext: CoroutineContext) : CoroutineScope { this.onEnable() } - + /** + * 加载一个data folder中的Config + * 这个config是read-write的 + */ fun loadConfig(fileName: String): Config { - return Config.load(File(fileName)) + return Config.load(dataFolder.absolutePath + fileName) } - @JvmOverloads internal fun disable(throwable: CancellationException? = null) { this.coroutineContext[Job]!!.cancelChildren(throwable) @@ -87,7 +92,7 @@ abstract class PluginBase(coroutineContext: CoroutineContext) : CoroutineScope { this.onLoad() } - fun getPluginManager() = PluginManager + val pluginManager = PluginManager val logger: MiraiLogger by lazy { SimpleLogger("Plugin ${pluginDescription.name}") { _, message, e -> @@ -99,15 +104,31 @@ abstract class PluginBase(coroutineContext: CoroutineContext) : CoroutineScope { } } - + /** + * 加载一个插件jar, resources中的东西 + */ fun getResources(fileName: String): InputStream? { - return PluginManager.getFileInJarByName( - this.pluginDescription.name, - fileName - ) + return try { + this.javaClass.classLoader.getResourceAsStream(fileName) + } catch (e: Exception) { + PluginManager.getFileInJarByName( + this.pluginDescription.name, + fileName + ) + } + } + + /** + * 加载一个插件jar, resources中的Config + * 这个Config是read-only的 + */ + fun getResourcesConfig(fileName: String): Config { + if (fileName.contains(".")) { + error("Unknown Config Type") + } + return Config.load(getResources(fileName) ?: error("Config Not Found"), fileName.split(".")[1]) } - //fun getResourcesConfig() } class PluginDescription( @@ -370,7 +391,7 @@ object PluginManager { /** - * 根据插件名字找Jar resources中的文件 + * 根据插件名字找Jar中的文件 * null => 没找到 */ fun getFileInJarByName(pluginName: String, toFind: String): InputStream? { diff --git a/mirai-plugins/image-sender/src/main/java/net/mamoe/mirai/imageplugin/ImageSenderMain.kt b/mirai-plugins/image-sender/src/main/java/net/mamoe/mirai/imageplugin/ImageSenderMain.kt index 0bbb64fca..61e3e6ea4 100644 --- a/mirai-plugins/image-sender/src/main/java/net/mamoe/mirai/imageplugin/ImageSenderMain.kt +++ b/mirai-plugins/image-sender/src/main/java/net/mamoe/mirai/imageplugin/ImageSenderMain.kt @@ -134,7 +134,7 @@ class ImageSenderMain : PluginBase() { logger.info("loading local image data") try { - images = Config.load(getResources(fileName = "data.yml")!!, "yml") + images = getResourcesConfig("data.yml") } catch (e: Exception) { e.printStackTrace() logger.info("无法加载本地图片") From 4a02648102418bbe0f8638327469bf6d39307f6b Mon Sep 17 00:00:00 2001 From: "jiahua.liu" Date: Tue, 25 Feb 2020 17:53:47 +0800 Subject: [PATCH 3/8] fix typo --- .../main/kotlin/net/mamoe/mirai/console/command/Command.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt index bec68e608..d57d005d5 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt @@ -37,7 +37,7 @@ object CommandManager { val allNames = mutableListOf(command.name).also { it.addAll(command.alias) } allNames.forEach { if (registeredCommand.containsKey(it)) { - error("net.mamoe.mirai.Command Name(or Alias) $it is already registered, consider if same function plugin was installed") + error("Command Name(or Alias) $it is already registered, consider if same functional plugin was installed") } } allNames.forEach { @@ -214,7 +214,7 @@ class CommandBuilder internal constructor() { fun register(): Command { if (name == null || onCommand == null) { - error("net.mamoe.mirai.CommandBuilder not complete") + error("CommandBuilder not complete") } if (alias == null) { alias = listOf() From a126e3f6602e72ac30e5016e89bda0498cdeed80 Mon Sep 17 00:00:00 2001 From: "jiahua.liu" Date: Tue, 25 Feb 2020 17:55:17 +0800 Subject: [PATCH 4/8] print usage --- .../src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt | 2 +- .../src/main/kotlin/net/mamoe/mirai/console/command/Command.kt | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt index 5ee1b1b5b..4f634f5bc 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt @@ -159,7 +159,7 @@ object MiraiConsole { commandStr = "/$commandStr" } if (!CommandManager.runCommand(command.sender, commandStr)) { - logger("未知指令 $commandStr") + command.sender.sendMessage("未知指令 $commandStr") } } } diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt index d57d005d5..b95d35684 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt @@ -74,6 +74,8 @@ object CommandManager { ) ) { PluginManager.onCommand(this, args) + } else { + sender.sendMessage(this.usage) } } catch (e: Exception) { sender.sendMessage("在运行指令时出现了未知错误") From 9ff70b0dbbc3f704a058c80eec783069877e0ad4 Mon Sep 17 00:00:00 2001 From: "jiahua.liu" Date: Tue, 25 Feb 2020 18:01:10 +0800 Subject: [PATCH 5/8] fix command sender flush bug --- .../kotlin/net/mamoe/mirai/console/command/Command.kt | 9 +++++++-- .../net/mamoe/mirai/console/command/DefaultCommands.kt | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt index b95d35684..17bc58c21 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt @@ -106,13 +106,13 @@ interface CommandSender { } abstract class CommandSenderImpl : CommandSender { - private val builder = StringBuilder() + internal val builder = StringBuilder() override fun appendMessage(message: String) { builder.append(message).append("\n") } - internal suspend fun flushMessage() { + internal open suspend fun flushMessage() { if (!builder.isEmpty()) { sendMessage(builder.toString().removeSuffix("\n")) } @@ -127,6 +127,11 @@ object ConsoleCommandSender : CommandSenderImpl() { override suspend fun sendMessage(message: String) { MiraiConsole.logger("[Command]", 0, message) } + + override suspend fun flushMessage() { + super.flushMessage() + builder.clear() + } } open class ContactCommandSender(val contact: Contact) : CommandSenderImpl() { diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/DefaultCommands.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/DefaultCommands.kt index 6f13bd9b0..651eb423b 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/DefaultCommands.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/DefaultCommands.kt @@ -237,6 +237,7 @@ object DefaultCommands { onCommand { CommandManager.getCommands().let { var size = 0 + appendMessage("")//\n it.toSet().forEach { ++size appendMessage("-> " + it.name + " :" + it.description) From 7eb63321da27c64846a1de48391694e2cd9c2b1b Mon Sep 17 00:00:00 2001 From: "jiahua.liu" Date: Tue, 25 Feb 2020 18:09:30 +0800 Subject: [PATCH 6/8] update readme --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5e5c018f7..9d7f1b014 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,8 @@ TIM PC (2.3.2 版本,2019 年 8 月)协议的实现 (目前不再更新此协议,请关注上文的安卓协议) ## 加入开发 +### 基于mirai的项目-如其他语言的SDK, 功能的拓展(无排名) +- [mirai-native](https://github.com/iTXTech/mirai-native) 支持酷Q插件在mirai上运行 我们欢迎一切形式的贡献。 我们也期待有更多人能加入 `Mirai` 的开发。 @@ -102,8 +104,7 @@ TIM PC (2.3.2 版本,2019 年 8 月)协议的实现 特别感谢 [JetBrains](https://www.jetbrains.com/?from=mirai) 为开源项目提供免费的 [IntelliJ IDEA](https://www.jetbrains.com/idea/?from=mirai) 等 IDE 的授权 [](https://www.jetbrains.com/?from=mirai) -### 第三方类库 - +### 第三方类库(无排名) - [kotlin-stdlib](https://github.com/JetBrains/kotlin) - [kotlinx-coroutines](https://github.com/Kotlin/kotlinx.coroutines) - [kotlinx-io](https://github.com/Kotlin/kotlinx-io) From a1e262ce9b4adb77bbeb5977d6a35b8c985577f4 Mon Sep 17 00:00:00 2001 From: ryoii Date: Tue, 25 Feb 2020 23:25:22 +0800 Subject: [PATCH 7/8] Update README.md --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9d7f1b014..dd411b366 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,7 @@ logo
title - - + ---- [![Gitter](https://badges.gitter.im/mamoe/mirai.svg)](https://gitter.im/mamoe/mirai?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) @@ -90,7 +89,10 @@ TIM PC (2.3.2 版本,2019 年 8 月)协议的实现 ## 加入开发 ### 基于mirai的项目-如其他语言的SDK, 功能的拓展(无排名) + - [mirai-native](https://github.com/iTXTech/mirai-native) 支持酷Q插件在mirai上运行 +- [python-mirai](https://github.com/Chenwe-i-lin/python-mirai) 基于`Mirai-http-api`的 Mirai Framework for Python +- [node-mirai](https://github.com/RedBeanN/node-mirai) Mirai的NodeJs SDK 我们欢迎一切形式的贡献。 我们也期待有更多人能加入 `Mirai` 的开发。 @@ -134,16 +136,16 @@ TIM PC (2.3.2 版本,2019 年 8 月)协议的实现 ------ Copyright (C) 2019-2020 mamoe and Mirai contributors - + This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. - + You should have received a copy of the GNU Affero General Public License along with this program. If not, see . From c17361242ba1724e56a7602f3299dc5264575e87 Mon Sep 17 00:00:00 2001 From: ryoii Date: Wed, 26 Feb 2020 00:34:03 +0800 Subject: [PATCH 8/8] Http api automatic release AuthSession --- mirai-api-http/README_CH.md | 3 +- .../net/mamoe/mirai/api/http/Session.kt | 36 ++++++++++++++----- .../mirai/api/http/route/AuthRouteModule.kt | 5 +-- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/mirai-api-http/README_CH.md b/mirai-api-http/README_CH.md index ff595681d..05a7cd35e 100644 --- a/mirai-api-http/README_CH.md +++ b/mirai-api-http/README_CH.md @@ -116,7 +116,8 @@ fun main() { ``` 使用此方式释放session及其相关资源(Bot不会被释放) -**不使用的Session应当被释放,否则Session持续保存Bot收到的消息,将会导致内存泄露** +**不使用的Session应当被释放,否则Session持续保存Bot收到的消息** +**长时间(30分钟)未被使用的Session会被系统自动释放,以避免内存泄露** #### 请求: diff --git a/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/Session.kt b/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/Session.kt index 32f7aeeb4..3ab8d40c6 100644 --- a/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/Session.kt +++ b/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/Session.kt @@ -15,8 +15,7 @@ import net.mamoe.mirai.api.http.queue.MessageQueue import net.mamoe.mirai.event.Listener import net.mamoe.mirai.event.events.BotEvent import net.mamoe.mirai.event.subscribeAlways -import net.mamoe.mirai.event.subscribeMessages -import net.mamoe.mirai.message.MessagePacket +import net.mamoe.mirai.utils.currentTimeSeconds import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext @@ -57,7 +56,13 @@ internal object SessionManager { } } - operator fun get(sessionKey: String) = allSession[sessionKey] + fun createAuthedSession(bot: Bot, originKey: String): AuthedSession = AuthedSession(bot, originKey, EmptyCoroutineContext).also { session -> + closeSession(originKey) + allSession[originKey] = session + } + + operator fun get(sessionKey: String) = allSession[sessionKey]?.also { + if (it is AuthedSession) it.latestUsed = currentTimeSeconds } fun containSession(sessionKey: String): Boolean = allSession.containsKey(sessionKey) @@ -76,14 +81,12 @@ internal object SessionManager { * 需使用[SessionManager] */ abstract class Session internal constructor( - coroutineContext: CoroutineContext + coroutineContext: CoroutineContext, + val key: String = generateSessionKey() ) : CoroutineScope { val supervisorJob = SupervisorJob(coroutineContext[Job]) final override val coroutineContext: CoroutineContext = supervisorJob + coroutineContext - val key: String = generateSessionKey() - - internal open fun close() { supervisorJob.complete() } @@ -101,16 +104,33 @@ class TempSession internal constructor(coroutineContext: CoroutineContext) : Ses * 任何[TempSession]认证后转化为一个[AuthedSession] * 在这一步[AuthedSession]应该已经有assigned的bot */ -class AuthedSession internal constructor(val bot: Bot, coroutineContext: CoroutineContext) : Session(coroutineContext) { +class AuthedSession internal constructor(val bot: Bot, originKey: String, coroutineContext: CoroutineContext) : Session(coroutineContext, originKey) { + + companion object { + const val CHECK_TIME = 1800L // 1800s aka 30min + } val messageQueue = MessageQueue() private val _listener: Listener + private val releaseJob: Job //手动释放将会在下一次检查时回收Session + + internal var latestUsed = currentTimeSeconds init { _listener = bot.subscribeAlways{ this.run(messageQueue::add) } + releaseJob = launch { + while (true) { + delay(CHECK_TIME * 1000) + if (currentTimeSeconds - latestUsed >= CHECK_TIME) { + SessionManager.closeSession(this@AuthedSession) + break + } + } + } } override fun close() { + messageQueue.clear() _listener.complete() super.close() } diff --git a/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/route/AuthRouteModule.kt b/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/route/AuthRouteModule.kt index aa229181d..1d495a088 100644 --- a/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/route/AuthRouteModule.kt +++ b/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/route/AuthRouteModule.kt @@ -35,10 +35,7 @@ fun Application.authModule() { miraiVerify("/verify", verifiedSessionKey = false) { val bot = getBotOrThrow(it.qq) - with(SessionManager) { - closeSession(it.sessionKey) - allSession[it.sessionKey] = AuthedSession(bot, EmptyCoroutineContext) - } + SessionManager.createAuthedSession(bot, it.sessionKey) call.respondStateCode(StateCode.Success) }