From 93ddbc75106ee8c0aad37dd3fac08ff72a86a313 Mon Sep 17 00:00:00 2001 From: Him188 <Him188@mamoe.net> Date: Sat, 18 Jan 2020 21:00:21 +0800 Subject: [PATCH 1/4] Specify lambda arg name --- .../kotlin/net/mamoe/mirai/plugin/PluginBase.kt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/PluginBase.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/PluginBase.kt index d1ca57074..f14a5b699 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/PluginBase.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/PluginBase.kt @@ -158,25 +158,25 @@ object PluginManager{ fun loadPlugin(description: PluginDescription):Boolean{ - if(!description.noCircularDepend){ + if (!description.noCircularDepend) { return false.also { logger.error("Failed to load plugin " + description.pluginName + " because it has circular dependency") } } //load depends first - description.depends.forEach{ - if(!pluginsFound.containsKey(it)){ + description.depends.forEach { dependent -> + if (!pluginsFound.containsKey(dependent)) { return false.also { _ -> - logger.error("Failed to load plugin " + description.pluginName + " because it need " + it + " as dependency") + logger.error("Failed to load plugin " + description.pluginName + " because it need " + dependent + " as dependency") } } - val depend = pluginsFound[it]!! + val depend = pluginsFound[dependent]!! //还没有加载 - if(!depend.loaded) { - if (!loadPlugin(pluginsFound[it]!!)) { + if (!depend.loaded) { + if (!loadPlugin(pluginsFound[dependent]!!)) { return false.also { _ -> - logger.error("Failed to load plugin " + description.pluginName + " because " + it + " as dependency failed to load") + logger.error("Failed to load plugin " + description.pluginName + " because " + dependent + " as dependency failed to load") } } } From bbe3bf65ea21e2d31f5e220acbde731c5e0e4474 Mon Sep 17 00:00:00 2001 From: Him188 <Him188@mamoe.net> Date: Sat, 18 Jan 2020 21:03:09 +0800 Subject: [PATCH 2/4] Remove iml --- mirai-plugins/image-sender/image-sender.iml | 15 --------------- mirai-plugins/mirai-plugins.iml | 12 ------------ 2 files changed, 27 deletions(-) delete mode 100644 mirai-plugins/image-sender/image-sender.iml delete mode 100644 mirai-plugins/mirai-plugins.iml diff --git a/mirai-plugins/image-sender/image-sender.iml b/mirai-plugins/image-sender/image-sender.iml deleted file mode 100644 index 110223128..000000000 --- a/mirai-plugins/image-sender/image-sender.iml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<module type="JAVA_MODULE" version="4"> - <component name="NewModuleRootManager" inherit-compiler-output="true"> - <exclude-output /> - <content url="file://$MODULE_DIR$"> - <sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" /> - <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> - <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> - </content> - <orderEntry type="inheritedJdk" /> - <orderEntry type="sourceFolder" forTests="false" /> - <orderEntry type="library" name="KotlinJavaRuntime (3)" level="project" /> - <orderEntry type="module" module-name="mirai-console_main" /> - </component> -</module> \ No newline at end of file diff --git a/mirai-plugins/mirai-plugins.iml b/mirai-plugins/mirai-plugins.iml deleted file mode 100644 index 245d3429f..000000000 --- a/mirai-plugins/mirai-plugins.iml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<module type="JAVA_MODULE" version="4"> - <component name="NewModuleRootManager" inherit-compiler-output="true"> - <exclude-output /> - <content url="file://$MODULE_DIR$"> - <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> - </content> - <orderEntry type="inheritedJdk" /> - <orderEntry type="sourceFolder" forTests="false" /> - <orderEntry type="library" name="KotlinJavaRuntime" level="project" /> - </component> -</module> \ No newline at end of file From fc99e9722340d779d9b831157e88df153605a6c5 Mon Sep 17 00:00:00 2001 From: Him188 <Him188@mamoe.net> Date: Sat, 18 Jan 2020 21:17:47 +0800 Subject: [PATCH 3/4] update --- mirai-console/build.gradle | 3 +- mirai-console/src/main/kotlin/MiraiConsole.kt | 45 +++--- .../net/mamoe/mirai/plugin/PluginBase.kt | 142 +++++++----------- 3 files changed, 76 insertions(+), 114 deletions(-) diff --git a/mirai-console/build.gradle b/mirai-console/build.gradle index 158cbd8aa..6136f6a9d 100644 --- a/mirai-console/build.gradle +++ b/mirai-console/build.gradle @@ -3,7 +3,8 @@ apply plugin: "java" dependencies { api project(':mirai-core') - runtimeOnly files(':mirai-core-timpc') + api project(':mirai-core-timpc') + runtimeOnly files('../mirai-core-timpc/build/classes/kotlin/jvm/main') runtimeOnly files('../mirai-core/build/classes/kotlin/jvm/main') // classpath is not set correctly by IDE } diff --git a/mirai-console/src/main/kotlin/MiraiConsole.kt b/mirai-console/src/main/kotlin/MiraiConsole.kt index e6288891e..76b305e38 100644 --- a/mirai-console/src/main/kotlin/MiraiConsole.kt +++ b/mirai-console/src/main/kotlin/MiraiConsole.kt @@ -18,34 +18,27 @@ fun main() { println("\"login qqnumber qqpassword \" to login a bot") println("\"login qq号 qq密码 \" 来登陆一个BOT") + thread { processNextCommandLine() } - thread { - loop@ while (true) { - var command = readLine() - if (command != null) { - var commandArgs = command.split(" ") - when (commandArgs[0]) { - "login" -> { - if (commandArgs.size < 3) { - println("\"login qqnumber qqpassword \" to login a bot") - println("\"login qq号 qq密码 \" 来登陆一个BOT") - continue@loop - } - val qqNumber = commandArgs[1].toLong() - val qqPassword = commandArgs[2] - println("login...") - GlobalScope.launch { - Bot(qqNumber, qqPassword) - } - } - } + PluginManager.loadPlugins() +} + +tailrec fun processNextCommandLine() { + val commandArgs = readLine()?.split(" ") ?: return + when (commandArgs[0]) { + "login" -> { + if (commandArgs.size < 3) { + println("\"login qqnumber qqpassword \" to login a bot") + println("\"login qq号 qq密码 \" 来登录一个BOT") + return processNextCommandLine() + } + val qqNumber = commandArgs[1].toLong() + val qqPassword = commandArgs[2] + println("login...") + GlobalScope.launch { + Bot(qqNumber, qqPassword) } } } - - PluginManager.loadPlugins() - - + return processNextCommandLine() } - - diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/PluginBase.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/PluginBase.kt index 7ca1403fe..80fa63eb9 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/PluginBase.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/PluginBase.kt @@ -1,16 +1,16 @@ package net.mamoe.mirai.plugin import net.mamoe.mirai.utils.DefaultLogger -import java.io.BufferedReader +import net.mamoe.mirai.utils.io.encodeToString import java.io.File -import java.io.InputStream -import java.io.InputStreamReader -import java.net.JarURLConnection import java.net.URL import java.util.jar.JarFile abstract class PluginBase constructor() { + val dataFolder by lazy { + File(PluginManager.pluginsPath + pluginDescription.name).also { it.mkdir() } + } open fun onLoad() { @@ -24,38 +24,27 @@ abstract class PluginBase constructor() { } - fun getPluginManager(): PluginManager { - return PluginManager - } - private lateinit var pluginDescription: PluginDescription internal fun init(pluginDescription: PluginDescription) { this.pluginDescription = pluginDescription this.onLoad() } - - fun getDataFolder(): File { - return File(PluginManager.pluginsPath + pluginDescription.pluginName).also { - it.mkdirs() - } - } - } class PluginDescription( - val pluginName: String, - val pluginAuthor: String, - val pluginBasePath: String, - val pluginVersion: String, - val pluginInfo: String, + val name: String, + val author: String, + val basePath: String, + val version: String, + val info: String, val depends: List<String>,//插件的依赖 internal var loaded: Boolean = false, internal var noCircularDepend: Boolean = true ) { override fun toString(): String { - return "name: $pluginName\nauthor: $pluginAuthor\npath: $pluginBasePath\nver: $pluginVersion\ninfo: $pluginInfo\ndepends: $depends" + return "name: $name\nauthor: $author\npath: $basePath\nver: $version\ninfo: $info\ndepends: $depends" } companion object { @@ -69,11 +58,11 @@ class PluginDescription( var version = "1.0.0" val depends = mutableListOf<String>(); - content.forEach{ + content.forEach { val line = it.trim() val lowercaseLine = line.toLowerCase() - if(it.contains(":")) { - when{ + if (it.contains(":")) { + when { lowercaseLine.startsWith("name") -> { name = line.substringAfter(":").trim() } @@ -83,26 +72,26 @@ class PluginDescription( lowercaseLine.startsWith("info") || lowercaseLine.startsWith("information") -> { info = line.substringAfter(":").trim() } - lowercaseLine.startsWith("main") || lowercaseLine.startsWith("path") || lowercaseLine.startsWith( - "basepath" - ) -> { + lowercaseLine.startsWith("main") || + lowercaseLine.startsWith("path") || + lowercaseLine.startsWith("basepath") -> { basePath = line.substringAfter(":").trim() } lowercaseLine.startsWith("version") || lowercaseLine.startsWith("ver") -> { version = line.substringAfter(":").trim() } } - }else if(line.startsWith("-")){ + } else if (line.startsWith("-")) { depends.add(line.substringAfter("-").trim()) } } - return PluginDescription(name,author,basePath,version,info,depends) + return PluginDescription(name, author, basePath, version, info, depends) } } } -object PluginManager{ +object PluginManager { internal val pluginsPath = System.getProperty("user.dir") + "/plugins/".replace("//", "/").also { File(it).mkdirs() } @@ -113,49 +102,37 @@ object PluginManager{ private val nameToPluginBaseMap: MutableMap<String, PluginBase> = mutableMapOf() - /** * 尝试加载全部插件 */ - fun loadPlugins(){ + fun loadPlugins() { val pluginsFound: MutableMap<String, PluginDescription> = mutableMapOf() val pluginsLocation: MutableMap<String, JarFile> = mutableMapOf() File(pluginsPath).listFiles()?.forEach { file -> - if (file != null) { - if (file.extension == "jar") { - val jar = JarFile(file) - val pluginYml = - jar.entries().asSequence().filter { it.name.toLowerCase().contains("plugin.yml") }.firstOrNull() - if (pluginYml == null) { - logger.info("plugin.yml not found in jar " + jar.name + ", it will not be consider as a Plugin") - } else { - val url = URL("jar:file:" + file.absoluteFile + "!/" + pluginYml.name) - val jarConnection: JarURLConnection = url - .openConnection() as JarURLConnection - val inputStream: InputStream = jarConnection.getInputStream() - val br = BufferedReader(InputStreamReader(inputStream, "UTF-8")) - var con: String? - val sb = StringBuffer() - while (br.readLine().also { con = it } != null) { - sb.append(con).append("\n") - } - val description = PluginDescription.readFromContent(sb.toString()) - println(description) - pluginsFound[description.pluginName] = description - pluginsLocation[description.pluginName] = jar - } + if (file != null && file.extension == "jar") { + val jar = JarFile(file) + val pluginYml = + jar.entries().asSequence().filter { it.name.toLowerCase().contains("plugin.yml") }.firstOrNull() + if (pluginYml == null) { + logger.info("plugin.yml not found in jar " + jar.name + ", it will not be consider as a Plugin") + } else { + val description = + PluginDescription.readFromContent(URL("jar:file:" + file.absoluteFile + "!/" + pluginYml.name).openConnection().inputStream.readAllBytes().encodeToString()) + println(description) + pluginsFound[description.name] = description + pluginsLocation[description.name] = jar } } } - fun checkNoCircularDepends (target:PluginDescription, needDepends: List<String>,existDepends: MutableList<String>) { + fun checkNoCircularDepends(target: PluginDescription, needDepends: List<String>, existDepends: MutableList<String>) { if (!target.noCircularDepend) { return } - existDepends.add(target.pluginName) + existDepends.add(target.name) if (needDepends.any { existDepends.contains(it) }) { target.noCircularDepend = false @@ -172,65 +149,58 @@ object PluginManager{ pluginsFound.values.forEach { - checkNoCircularDepends(it,it.depends, mutableListOf()) + checkNoCircularDepends(it, it.depends, mutableListOf()) } //load - fun loadPlugin(description: PluginDescription):Boolean{ + fun loadPlugin(description: PluginDescription): Boolean { if (!description.noCircularDepend) { - return false.also { - logger.error("Failed to load plugin " + description.pluginName + " because it has circular dependency") - } + logger.error("Failed to load plugin " + description.name + " because it has circular dependency") + return false } //load depends first - description.depends.forEach { dependent -> - if (!pluginsFound.containsKey(dependent)) { - return false.also { _ -> - logger.error("Failed to load plugin " + description.pluginName + " because it need " + dependent + " as dependency") - } + description.depends.forEach { dependentName -> + val dependent = pluginsFound[dependentName] + if (dependent == null) { + logger.error("Failed to load plugin " + description.name + " because it need " + dependentName + " as dependency") + return false } - val depend = pluginsFound[dependent]!! //还没有加载 - if (!depend.loaded) { - if (!loadPlugin(pluginsFound[dependent]!!)) { - return false.also { _ -> - logger.error("Failed to load plugin " + description.pluginName + " because " + dependent + " as dependency failed to load") - } - } + if (!dependent.loaded && !loadPlugin(dependent)) { + logger.error("Failed to load plugin " + description.name + " because " + dependentName + " as dependency failed to load") + return false } } //在这里所有的depends都已经加载了 //real load - logger.info("loading plugin " + description.pluginName) + logger.info("loading plugin " + description.name) try { - this.javaClass.classLoader.loadClass(description.pluginBasePath) + this.javaClass.classLoader.loadClass(description.basePath) return try { val subClass = javaClass.asSubclass(PluginBase::class.java) val plugin: PluginBase = subClass.getDeclaredConstructor().newInstance() description.loaded = true - logger.info("successfully loaded plugin " + description.pluginName) - logger.info(description.pluginInfo) + logger.info("successfully loaded plugin " + description.name) + logger.info(description.info) - nameToPluginBaseMap[description.pluginName] = plugin + nameToPluginBaseMap[description.name] = plugin plugin.init(description) true } catch (e: ClassCastException) { - false.also { - logger.error("failed to load plugin " + description.pluginName + " , Main class does not extends PluginBase ") - } + logger.error("failed to load plugin " + description.name + " , Main class does not extends PluginBase ") + false } } catch (e: ClassNotFoundException) { e.printStackTrace() - return false.also { - logger.error("failed to load plugin " + description.pluginName + " , Main class not found under " + description.pluginBasePath) - } + logger.error("failed to load plugin " + description.name + " , Main class not found under " + description.basePath) + return false } } @@ -240,8 +210,6 @@ object PluginManager{ } - - } From 4f305ebd58f233f845badca465e72607fbdbd5b0 Mon Sep 17 00:00:00 2001 From: Him188 <Him188@mamoe.net> Date: Sat, 18 Jan 2020 21:18:11 +0800 Subject: [PATCH 4/4] update --- .../src/main/kotlin/net/mamoe/mirai/plugin/PluginBase.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/PluginBase.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/PluginBase.kt index 80fa63eb9..e75037179 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/PluginBase.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/PluginBase.kt @@ -115,7 +115,7 @@ object PluginManager { val pluginYml = jar.entries().asSequence().filter { it.name.toLowerCase().contains("plugin.yml") }.firstOrNull() if (pluginYml == null) { - logger.info("plugin.yml not found in jar " + jar.name + ", it will not be consider as a Plugin") + logger.info("plugin.yml not found in jar " + jar.name + ", it will not be considered as a Plugin") } else { val description = PluginDescription.readFromContent(URL("jar:file:" + file.absoluteFile + "!/" + pluginYml.name).openConnection().inputStream.readAllBytes().encodeToString())