Commit be91d607 authored by Him188's avatar Him188

update

parent 06685158
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<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 {
......@@ -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<String, File> = 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
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment