From be91d6078af6a8afb0d8677aafede21be19df1f3 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 18 Jan 2020 21:41:40 +0800 Subject: [PATCH] update --- .../net/mamoe/mirai/plugin/PluginBase.kt | 117 +++++++----------- 1 file changed, 44 insertions(+), 73 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 0b92a2938..7b5957e33 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,17 +1,17 @@ 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.net.URLClassLoader import java.util.jar.JarFile abstract class PluginBase constructor() { + val dataFolder: File by lazy { + File(PluginManager.pluginsPath + pluginDescription.name).also { it.mkdir() } + } open fun onLoad() { @@ -25,38 +25,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,//插件的依赖 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 { @@ -103,7 +92,7 @@ class PluginDescription( } -class PluginClassLoader(file: File, parent: ClassLoader) : URLClassLoader(arrayOf(file.toURI().toURL()), parent) { +internal class PluginClassLoader(file: File, parent: ClassLoader) : URLClassLoader(arrayOf(file.toURI().toURL()), parent) { override fun findClass(moduleName: String?, name: String?): Class<*> { return super.findClass(name) } @@ -129,29 +118,18 @@ object PluginManager { val pluginsLocation: MutableMap = 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] = file - } + 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] = file } } } @@ -166,7 +144,7 @@ object PluginManager { return } - existDepends.add(target.pluginName) + existDepends.add(target.name) if (needDepends.any { existDepends.contains(it) }) { target.noCircularDepend = false @@ -191,58 +169,51 @@ object PluginManager { 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 { - if (!pluginsFound.containsKey(it)) { - return false.also { _ -> - logger.error("Failed to load plugin " + description.pluginName + " because it need " + it + " as dependency") - } + description.depends.forEach { dependent -> + if (!pluginsFound.containsKey(dependent)) { + logger.error("Failed to load plugin " + description.name + " because it need " + dependent + " as dependency") + return false } - val depend = pluginsFound[it]!! + val depend = pluginsFound[dependent]!! //还没有加载 - if (!depend.loaded) { - if (!loadPlugin(pluginsFound[it]!!)) { - return false.also { _ -> - logger.error("Failed to load plugin " + description.pluginName + " because " + it + " as dependency failed to load") - } - } + if (!depend.loaded && !loadPlugin(pluginsFound[dependent]!!)) { + logger.error("Failed to load plugin " + description.name + " because " + dependent + " as dependency failed to load") + return false } } //在这里所有的depends都已经加载了 //real load - logger.info("loading plugin " + description.pluginName) + logger.info("loading plugin " + description.name) try { val pluginClass = - PluginClassLoader((pluginsLocation[description.pluginName]!!), this.javaClass.classLoader) - .loadClass(description.pluginBasePath) + PluginClassLoader((pluginsLocation[description.name]!!), this.javaClass.classLoader) + .loadClass(description.basePath) return try { val subClass = pluginClass.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 } }