diff --git a/mirai-console/backend/integration-test/testers/plugin-can-depends-on-mirai-console/resources/META-INF/services/net.mamoe.mirai.console.plugin.jvm.JvmPlugin b/mirai-console/backend/integration-test/testers/plugin-can-depends-on-mirai-console/resources/META-INF/services/net.mamoe.mirai.console.plugin.jvm.JvmPlugin new file mode 100644 index 0000000000..ecc1fbb453 --- /dev/null +++ b/mirai-console/backend/integration-test/testers/plugin-can-depends-on-mirai-console/resources/META-INF/services/net.mamoe.mirai.console.plugin.jvm.JvmPlugin @@ -0,0 +1,10 @@ +# +# Copyright 2019-2023 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/dev/LICENSE +# + +net.mamoe.console.itest.plugincandependsonmiraiconsole.PluginCanDependsOnMiraiConsole diff --git a/mirai-console/backend/integration-test/testers/plugin-can-depends-on-mirai-console/src/PluginCanDependsOnMiraiConsole.kt b/mirai-console/backend/integration-test/testers/plugin-can-depends-on-mirai-console/src/PluginCanDependsOnMiraiConsole.kt new file mode 100644 index 0000000000..9f10428fdb --- /dev/null +++ b/mirai-console/backend/integration-test/testers/plugin-can-depends-on-mirai-console/src/PluginCanDependsOnMiraiConsole.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2019-2023 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/dev/LICENSE + */ + +package net.mamoe.console.itest.plugincandependsonmiraiconsole + +import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription +import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin + +internal object PluginCanDependsOnMiraiConsole : KotlinPlugin( + JvmPluginDescription("net.mamoe.tester.plugin-can-depends-mirai-console", "1.0.0") { + dependsOn("net.mamoe.mirai-console") + } +) { + +} \ No newline at end of file diff --git a/mirai-console/backend/mirai-console/src/command/BuiltInCommands.kt b/mirai-console/backend/mirai-console/src/command/BuiltInCommands.kt index 6ced703cea..c2a27bb9d8 100644 --- a/mirai-console/backend/mirai-console/src/command/BuiltInCommands.kt +++ b/mirai-console/backend/mirai-console/src/command/BuiltInCommands.kt @@ -39,6 +39,7 @@ import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage import net.mamoe.mirai.console.internal.permission.BuiltInPermissionService import net.mamoe.mirai.console.internal.permission.getPermittedPermissionsAndSource import net.mamoe.mirai.console.internal.plugin.JvmPluginInternal +import net.mamoe.mirai.console.internal.plugin.MiraiConsoleAsPlugin import net.mamoe.mirai.console.internal.pluginManagerImpl import net.mamoe.mirai.console.internal.util.runIgnoreException import net.mamoe.mirai.console.permission.Permission @@ -633,10 +634,15 @@ public object BuiltInCommands { reset().append("\n\n") append("Plugins: ") - if (MiraiConsole.pluginManagerImpl.resolvedPlugins.isEmpty()) { + + val resolvedPlugins = MiraiConsole.pluginManagerImpl.resolvedPlugins.asSequence() + .filter { it !is MiraiConsoleAsPlugin } // skip mirai-console in status + .toList() + + if (resolvedPlugins.isEmpty()) { gray().append("") } else { - MiraiConsole.pluginManagerImpl.resolvedPlugins.joinTo(this) { plugin -> + resolvedPlugins.joinTo(this) { plugin -> if (plugin.isEnabled) { green().append(plugin.name).reset().append(" v").gold() } else { diff --git a/mirai-console/backend/mirai-console/src/internal/plugin/BuiltInJvmPluginLoaderImpl.kt b/mirai-console/backend/mirai-console/src/internal/plugin/BuiltInJvmPluginLoaderImpl.kt index 60e22af294..15ac1bad39 100644 --- a/mirai-console/backend/mirai-console/src/internal/plugin/BuiltInJvmPluginLoaderImpl.kt +++ b/mirai-console/backend/mirai-console/src/internal/plugin/BuiltInJvmPluginLoaderImpl.kt @@ -287,7 +287,7 @@ internal class BuiltInJvmPluginLoaderImpl( return filePlugins.toSet().map { it.second } } - private val loadedPlugins = ConcurrentHashMap() + private val loadedPlugins = ConcurrentHashMap() private fun Path.moveNameFolder(plugin: JvmPlugin) { val nameFolder = this.resolve(plugin.description.name).toFile() @@ -324,8 +324,8 @@ internal class BuiltInJvmPluginLoaderImpl( override fun load(plugin: JvmPlugin) { ensureActive() - if (loadedPlugins.put(plugin, Unit) != null) { - error("Plugin '${plugin.name}' is already loaded and cannot be reloaded.") + if (loadedPlugins.put(plugin.id, plugin) != null) { + error("Plugin '${plugin.id}' is already loaded and cannot be reloaded.") } logger.verbose { "Loading plugin ${plugin.description.smartToString()}" } runCatching { diff --git a/mirai-console/backend/mirai-console/src/internal/plugin/MiraiConsoleAsPlugin.kt b/mirai-console/backend/mirai-console/src/internal/plugin/MiraiConsoleAsPlugin.kt new file mode 100644 index 0000000000..db027795fb --- /dev/null +++ b/mirai-console/backend/mirai-console/src/internal/plugin/MiraiConsoleAsPlugin.kt @@ -0,0 +1,72 @@ +/* + * Copyright 2019-2023 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/dev/LICENSE + */ + +package net.mamoe.mirai.console.internal.plugin + +import net.mamoe.mirai.console.command.ConsoleCommandOwner +import net.mamoe.mirai.console.internal.MiraiConsoleBuildConstants +import net.mamoe.mirai.console.permission.Permission +import net.mamoe.mirai.console.permission.PermissionId +import net.mamoe.mirai.console.plugin.Plugin +import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.description +import net.mamoe.mirai.console.plugin.description.PluginDependency +import net.mamoe.mirai.console.plugin.description.PluginDescription +import net.mamoe.mirai.console.plugin.loader.PluginLoader +import net.mamoe.mirai.console.util.SemVersion + +internal object MiraiConsoleAsPlugin : Plugin { + // MiraiConsole always enabled + override val isEnabled: Boolean get() = true + + override val loader: PluginLoader<*, *> get() = TheLoader + + override val parentPermission: Permission + get() = ConsoleCommandOwner.parentPermission + + override fun permissionId(name: String): PermissionId { + return ConsoleCommandOwner.permissionId(name) + } + + internal object TheLoader : PluginLoader { + override fun listPlugins(): List = listOf(MiraiConsoleAsPlugin) + + override fun disable(plugin: Plugin) { + // noop + } + + override fun enable(plugin: Plugin) { + // noop + } + + override fun load(plugin: Plugin) { + // noop + } + + override fun getPluginDescription(plugin: Plugin): PluginDescription { + if (plugin !== MiraiConsoleAsPlugin) { + error("loader not match with " + plugin.description.id) + } + return TheDescription + } + } + + internal object TheDescription : PluginDescription { + override val id: String get() = "net.mamoe.mirai-console" + override val name: String get() = "Console" + override val author: String get() = "Mamoe Technologies" + override val version: SemVersion get() = MiraiConsoleBuildConstants.version + override val info: String get() = "" + override val dependencies: Set get() = setOf() + + + override fun toString(): String { + return "PluginDescription[ mirai-console ]" + } + } +} \ No newline at end of file diff --git a/mirai-console/backend/mirai-console/src/internal/plugin/PluginManagerImpl.kt b/mirai-console/backend/mirai-console/src/internal/plugin/PluginManagerImpl.kt index abe666e8f8..0cb215d6ea 100644 --- a/mirai-console/backend/mirai-console/src/internal/plugin/PluginManagerImpl.kt +++ b/mirai-console/backend/mirai-console/src/internal/plugin/PluginManagerImpl.kt @@ -20,6 +20,7 @@ import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage import net.mamoe.mirai.console.plugin.NotYetLoadedPlugin import net.mamoe.mirai.console.plugin.Plugin import net.mamoe.mirai.console.plugin.PluginManager +import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.description import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.safeLoader import net.mamoe.mirai.console.plugin.description.PluginDependency import net.mamoe.mirai.console.plugin.description.PluginDescription @@ -88,6 +89,8 @@ internal class PluginManagerImpl( } } } + + resolvedPlugins.add(MiraiConsoleAsPlugin) } // region LOADING @@ -207,6 +210,8 @@ internal class PluginManagerImpl( @Throws(PluginResolutionException::class) private fun List.sortByDependencies(): List { + val alreadyLoadedPlugins = resolvedPlugins.asSequence().map { it.description }.toList() // snapshot + val originPluginDescriptions = this@sortByDependencies val pending2BeResolved = originPluginDescriptions.toMutableList() val resolved = ArrayList(pending2BeResolved.size) @@ -252,6 +257,8 @@ internal class PluginManagerImpl( pending2BeResolved.forEach { pluginDesc -> val missed = pluginDesc.dependencies.filter { dependency -> val resolvedDep = originPluginDescriptions.findDependency(dependency) + ?: alreadyLoadedPlugins.findDependency(dependency) + if (resolvedDep != null) { resolvedDep.checkSatisfies(dependency, pluginDesc) false diff --git a/mirai-console/backend/mirai-console/src/plugin/description/PluginDescription.kt b/mirai-console/backend/mirai-console/src/plugin/description/PluginDescription.kt index 472aa32086..51de93b255 100644 --- a/mirai-console/backend/mirai-console/src/plugin/description/PluginDescription.kt +++ b/mirai-console/backend/mirai-console/src/plugin/description/PluginDescription.kt @@ -104,6 +104,8 @@ public interface PluginDescription { /** * 此插件依赖的其他插件, 将会在这些插件加载之后加载此插件 * + * 特别的, 可以使用 `net.mamoe.mirai-console` 作为插件 id 限制 mirai-console 版本 (自 2.16.0 后) + * * @see PluginDependency */ public val dependencies: Set diff --git a/mirai-console/backend/mirai-console/test/testFramework/test/FrameworkInstanceTest.kt b/mirai-console/backend/mirai-console/test/testFramework/test/FrameworkInstanceTest.kt index 20424bcbe1..d28b9ad281 100644 --- a/mirai-console/backend/mirai-console/test/testFramework/test/FrameworkInstanceTest.kt +++ b/mirai-console/backend/mirai-console/test/testFramework/test/FrameworkInstanceTest.kt @@ -18,11 +18,11 @@ class FrameworkInstanceTest : AbstractConsoleInstanceTest() { @Test fun testConsole1() { - assertEquals(0, PluginManager.plugins.size) + assertEquals(1, PluginManager.plugins.size) } @Test fun testConsole2() { - assertEquals(0, PluginManager.plugins.size) + assertEquals(1, PluginManager.plugins.size) } } \ No newline at end of file