diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extension/Extension.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extension/Extension.kt index 50930174b..0f1963954 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extension/Extension.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extension/Extension.kt @@ -11,6 +11,7 @@ package net.mamoe.mirai.console.extension import net.mamoe.mirai.console.extensions.PermissionServiceProvider import net.mamoe.mirai.console.extensions.PluginLoaderProvider +import net.mamoe.mirai.console.extensions.SingletonExtensionSelector import net.mamoe.mirai.console.util.ConsoleExperimentalAPI /** @@ -28,6 +29,8 @@ public interface FunctionExtension : Extension /** * 为某单例服务注册的 [Extension]. * + * 若同时有多个实例可用, 将会使用 [SingletonExtensionSelector.selectSingleton] 选择 + * * @see PermissionServiceProvider */ @ConsoleExperimentalAPI diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/PermissionServiceProvider.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/PermissionServiceProvider.kt index 7dfaa5e39..8a7a415e3 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/PermissionServiceProvider.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/PermissionServiceProvider.kt @@ -5,12 +5,14 @@ import net.mamoe.mirai.console.extension.SingletonExtension import net.mamoe.mirai.console.extension.SingletonExtensionPoint import net.mamoe.mirai.console.permission.ExperimentalPermission import net.mamoe.mirai.console.permission.PermissionService -import net.mamoe.mirai.console.plugin.description.PluginKind +import net.mamoe.mirai.console.plugin.description.PluginLoadPriority /** * [权限服务][PermissionService] 提供器. * - * 此扩展可由 [PluginKind.LOADER] 和 [PluginKind.HIGH_PRIORITY_EXTENSIONS] 插件提供 + * 当插件注册 [PermissionService] 后, 默认会使用插件的 [PermissionService]. + * + * 此扩展可由 [PluginLoadPriority.BEFORE_EXTENSIONS] 和 [PluginLoadPriority.ON_EXTENSIONS] 插件提供 */ @ExperimentalPermission public interface PermissionServiceProvider : SingletonExtension> { diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/PluginLoaderProvider.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/PluginLoaderProvider.kt index 5b5016de9..0905229a5 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/PluginLoaderProvider.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/PluginLoaderProvider.kt @@ -3,12 +3,12 @@ package net.mamoe.mirai.console.extensions import net.mamoe.mirai.console.extension.AbstractExtensionPoint import net.mamoe.mirai.console.extension.InstanceExtension import net.mamoe.mirai.console.plugin.PluginLoader -import net.mamoe.mirai.console.plugin.description.PluginKind +import net.mamoe.mirai.console.plugin.description.PluginLoadPriority /** * 提供扩展 [PluginLoader] * - * 此扩展可由 [PluginKind.LOADER] 插件提供 + * 此扩展可由 [PluginLoadPriority.BEFORE_EXTENSIONS] 插件提供 */ public interface PluginLoaderProvider : InstanceExtension> { public companion object ExtensionPoint : AbstractExtensionPoint(PluginLoaderProvider::class) diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/SingletonExtensionSelector.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/SingletonExtensionSelector.kt index fce60e204..fdaf4a2c5 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/SingletonExtensionSelector.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/SingletonExtensionSelector.kt @@ -12,7 +12,7 @@ package net.mamoe.mirai.console.extensions import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.extension.* import net.mamoe.mirai.console.internal.extensions.BuiltInSingletonExtensionSelector -import net.mamoe.mirai.console.plugin.description.PluginKind +import net.mamoe.mirai.console.plugin.description.PluginLoadPriority import net.mamoe.mirai.console.plugin.name import net.mamoe.mirai.utils.info import kotlin.reflect.KClass @@ -22,7 +22,7 @@ import kotlin.reflect.KClass * * 如有多个 [SingletonExtensionSelector] 注册, 将会停止服务器. * - * 此扩展可由 [PluginKind.LOADER] 和 [PluginKind.HIGH_PRIORITY_EXTENSIONS] 插件提供 + * 此扩展可由 [PluginLoadPriority.BEFORE_EXTENSIONS] 插件提供 */ public interface SingletonExtensionSelector : FunctionExtension { diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/MiraiConsoleImplementationBridge.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/MiraiConsoleImplementationBridge.kt index 9649308c2..8f7c529c9 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/MiraiConsoleImplementationBridge.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/MiraiConsoleImplementationBridge.kt @@ -126,20 +126,12 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI val pluginLoadSession: PluginManagerImpl.PluginLoadSession - phase `load plugin provider plugins and high priority extension plugins`@{ + phase `load BEFORE_EXTENSIONS plugins`@{ PluginManager // init mainLogger.verbose { "Loading PluginLoader provider plugins..." } PluginManagerImpl.loadEnablePluginProviderPlugins() mainLogger.verbose { "${PluginManager.plugins.size} such plugin(s) loaded." } - - mainLogger.verbose { "Scanning high-priority extension and normal plugins..." } - pluginLoadSession = PluginManagerImpl.scanPluginsUsingPluginLoadersIncludingThoseFromPluginLoaderProvider() - mainLogger.verbose { "${pluginLoadSession.allKindsOfPlugins.size} plugin(s) found." } - - mainLogger.verbose { "Loading Extension provider plugins..." } - PluginManagerImpl.loadEnableHighPriorityExtensionPlugins(pluginLoadSession) - mainLogger.verbose { "${PluginManager.plugins.size} such plugin(s) loaded." } } phase `load SingletonExtensionSelector`@{ @@ -149,6 +141,16 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI } } + phase `load ON_EXTENSIONS plugins`@{ + mainLogger.verbose { "Scanning high-priority extension and normal plugins..." } + pluginLoadSession = PluginManagerImpl.scanPluginsUsingPluginLoadersIncludingThoseFromPluginLoaderProvider() + mainLogger.verbose { "${pluginLoadSession.allKindsOfPlugins.size} plugin(s) found." } + + mainLogger.verbose { "Loading Extension provider plugins..." } + PluginManagerImpl.loadEnableHighPriorityExtensionPlugins(pluginLoadSession) + mainLogger.verbose { "${PluginManager.plugins.size} such plugin(s) loaded." } + } + phase `load PermissionService`@{ mainLogger.verbose { "Loading PermissionService..." } PermissionService.INSTANCE.let { ps -> @@ -169,7 +171,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI CommandManagerImpl.commandListener // start } - phase `load normal plugins`@{ + phase `load AFTER_EXTENSION plugins`@{ mainLogger.verbose { "Loading normal plugins..." } val count = PluginManagerImpl.loadEnableNormalPlugins(pluginLoadSession) mainLogger.verbose { "$count normal plugin(s) loaded." } diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/plugin/PluginManagerImpl.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/plugin/PluginManagerImpl.kt index bdef81153..160df275a 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/plugin/PluginManagerImpl.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/plugin/PluginManagerImpl.kt @@ -22,7 +22,7 @@ import net.mamoe.mirai.console.internal.data.mkdir import net.mamoe.mirai.console.plugin.* import net.mamoe.mirai.console.plugin.description.PluginDependency import net.mamoe.mirai.console.plugin.description.PluginDescription -import net.mamoe.mirai.console.plugin.description.PluginKind +import net.mamoe.mirai.console.plugin.description.PluginLoadPriority import net.mamoe.mirai.console.plugin.jvm.JvmPlugin import net.mamoe.mirai.console.util.CoroutineScopeUtils.childScope import net.mamoe.mirai.utils.info @@ -131,7 +131,7 @@ internal object PluginManagerImpl : PluginManager, CoroutineScope by MiraiConsol internal fun loadEnableHighPriorityExtensionPlugins(session: PluginLoadSession): Int { loadersLock.withLock { session.allKindsOfPlugins.flatMap { it.second } - .filter { it.kind == PluginKind.HIGH_PRIORITY_EXTENSIONS } + .filter { it.loadPriority == PluginLoadPriority.ON_EXTENSIONS } .sortByDependencies() .also { it.loadAndEnableAllInOrder() } .let { return it.size } @@ -142,7 +142,7 @@ internal object PluginManagerImpl : PluginManager, CoroutineScope by MiraiConsol internal fun loadEnableNormalPlugins(session: PluginLoadSession): Int { loadersLock.withLock { session.allKindsOfPlugins.flatMap { it.second } - .filter { it.kind == PluginKind.NORMAL } + .filter { it.loadPriority == PluginLoadPriority.AFTER_EXTENSIONS } .sortByDependencies() .also { it.loadAndEnableAllInOrder() } .let { return it.size } @@ -191,7 +191,8 @@ internal object PluginManagerImpl : PluginManager, CoroutineScope by MiraiConsol loader as PluginLoader descriptions.forEach(PluginManagerImpl::checkPluginDescription) - descriptions.filter { it.kind == PluginKind.LOADER }.sortByDependencies().loadAndEnableAllInOrder() + descriptions.filter { it.loadPriority == PluginLoadPriority.BEFORE_EXTENSIONS }.sortByDependencies() + .loadAndEnableAllInOrder() } .flatMap { it.second.asSequence() } diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/Plugin.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/Plugin.kt index a9248bb7d..17155dcd3 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/Plugin.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/Plugin.kt @@ -18,7 +18,7 @@ import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.enable 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 -import net.mamoe.mirai.console.plugin.description.PluginKind +import net.mamoe.mirai.console.plugin.description.PluginLoadPriority import net.mamoe.mirai.console.plugin.jvm.JvmPlugin /** @@ -65,9 +65,9 @@ public inline val Plugin.name: String get() = this.description.name public inline val Plugin.version: Semver get() = this.description.version /** - * 获取 [PluginDescription.kind] + * 获取 [PluginDescription.loadPriority] */ -public inline val Plugin.kind: PluginKind get() = this.description.kind +public inline val Plugin.loadPriority: PluginLoadPriority get() = this.description.loadPriority /** * 获取 [PluginDescription.info] diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/PluginDescription.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/PluginDescription.kt index 6ef60f81a..c11f4d565 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/PluginDescription.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/PluginDescription.kt @@ -23,9 +23,9 @@ public interface PluginDescription { /** * 插件类型. 将会决定加载顺序 * - * @see PluginKind + * @see PluginLoadPriority */ - public val kind: PluginKind + public val loadPriority: PluginLoadPriority /** * 插件 ID, 必须全英文, 仅允许英文字母, '-', '_', '.'. diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/PluginKind.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/PluginLoadPriority.kt similarity index 56% rename from backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/PluginKind.kt rename to backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/PluginLoadPriority.kt index fce47b97b..8f49d63e8 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/PluginKind.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/PluginLoadPriority.kt @@ -14,39 +14,46 @@ import kotlinx.serialization.builtins.serializer import net.mamoe.mirai.console.extension.Extension import net.mamoe.mirai.console.extensions.BotConfigurationAlterer import net.mamoe.mirai.console.extensions.PermissionServiceProvider +import net.mamoe.mirai.console.extensions.PluginLoaderProvider +import net.mamoe.mirai.console.extensions.SingletonExtensionSelector import net.mamoe.mirai.console.internal.data.map -import net.mamoe.mirai.console.plugin.PluginLoader -import net.mamoe.mirai.console.plugin.description.PluginKind.* +import net.mamoe.mirai.console.plugin.description.PluginLoadPriority.* /** * 插件类型. * - * 插件类型将影响加载顺序: [LOADER] -> [HIGH_PRIORITY_EXTENSIONS] -> [NORMAL]. + * 插件类型将影响加载顺序: [BEFORE_EXTENSIONS] -> [ON_EXTENSIONS] -> [AFTER_EXTENSIONS]. * - * 依赖解决过程与插件类型有很大关联. 在一个较早的阶段, 只会解决在此阶段加载的插件. 意味着 [LOADER] 不允许依赖一个 [NORMAL] 类型的插件. + * 依赖解决过程与插件类型有很大关联. 在一个较早的阶段, 只会解决在此阶段加载的插件. 意味着 [BEFORE_EXTENSIONS] 不允许依赖一个 [AFTER_EXTENSIONS] 类型的插件. */ -public enum class PluginKind { - /** 表示此插件提供一个 [PluginLoader], 也可以同时提供其他 [Extension] 应最早被加载 */ - LOADER, +public enum class PluginLoadPriority { + /** + * 表示此插件最早被加载. 在 Console 启动时的第一初始化阶段就会加载这些插件. + * + * 一般只有提供 [PluginLoaderProvider] 或 [SingletonExtensionSelector] 的插件才需要在此阶段加载. + */ + BEFORE_EXTENSIONS, /** - * 表示此插件提供一些高优先级的 [Extension], 应在加载其他 [NORMAL] 类型插件前加载 + * 表示此插件提供一些高优先级的 [Extension], 应在加载其他 [AFTER_EXTENSIONS] 类型插件前加载 * * 高优先级的 [Extension] 通常是覆盖 Console 内置的部分服务的扩展. 如 [PermissionServiceProvider]. * - * 一些普通的 [Extension], 如 [BotConfigurationAlterer], 也可以使用 [NORMAL] 类型插件注册. + * 一些普通的 [Extension], 如 [BotConfigurationAlterer], 也可以使用 [AFTER_EXTENSIONS] 类型插件注册. */ - HIGH_PRIORITY_EXTENSIONS, + ON_EXTENSIONS, - /** 表示此插件为一个通常的插件, 按照正常的依赖关系加载. */ - NORMAL; + /** + * 表示此插件为一个通常的插件, 在扩展处理完毕后加载. + */ + AFTER_EXTENSIONS; - public object AsStringSerializer : KSerializer by String.serializer().map( + public object AsStringSerializer : KSerializer by String.serializer().map( serializer = { it.name }, deserializer = { str -> values().firstOrNull { it.name.equals(str, ignoreCase = true) - } ?: NORMAL + } ?: AFTER_EXTENSIONS } ) } \ No newline at end of file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginDescription.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginDescription.kt index 363f356df..64be7d2a9 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginDescription.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginDescription.kt @@ -14,7 +14,7 @@ package net.mamoe.mirai.console.plugin.jvm import com.vdurmont.semver4j.Semver import net.mamoe.mirai.console.plugin.description.PluginDependency import net.mamoe.mirai.console.plugin.description.PluginDescription -import net.mamoe.mirai.console.plugin.description.PluginKind +import net.mamoe.mirai.console.plugin.description.PluginLoadPriority import kotlin.internal.LowPriorityInOverloadResolution /** @@ -82,7 +82,7 @@ public class JvmPluginDescriptionBuilder( private var author: String = "" private var info: String = "" private var dependencies: MutableSet = mutableSetOf() - private var kind: PluginKind = PluginKind.NORMAL + private var loadPriority: PluginLoadPriority = PluginLoadPriority.AFTER_EXTENSIONS @ILoveKuriyamaMiraiForever public fun name(value: String): JvmPluginDescriptionBuilder = apply { this.name = value.trim() } @@ -104,17 +104,19 @@ public class JvmPluginDescriptionBuilder( public fun info(value: String): JvmPluginDescriptionBuilder = apply { this.info = value.trimIndent() } @ILoveKuriyamaMiraiForever - public fun kind(value: PluginKind): JvmPluginDescriptionBuilder = apply { this.kind = value } + public fun kind(value: PluginLoadPriority): JvmPluginDescriptionBuilder = apply { this.loadPriority = value } @ILoveKuriyamaMiraiForever - public fun normalPlugin(): JvmPluginDescriptionBuilder = apply { this.kind = PluginKind.NORMAL } + public fun normalPlugin(): JvmPluginDescriptionBuilder = + apply { this.loadPriority = PluginLoadPriority.AFTER_EXTENSIONS } @ILoveKuriyamaMiraiForever - public fun loaderProviderPlugin(): JvmPluginDescriptionBuilder = apply { this.kind = PluginKind.LOADER } + public fun loaderProviderPlugin(): JvmPluginDescriptionBuilder = + apply { this.loadPriority = PluginLoadPriority.BEFORE_EXTENSIONS } @ILoveKuriyamaMiraiForever public fun highPriorityExtensionsPlugin(): JvmPluginDescriptionBuilder = - apply { this.kind = PluginKind.HIGH_PRIORITY_EXTENSIONS } + apply { this.loadPriority = PluginLoadPriority.ON_EXTENSIONS } @ILoveKuriyamaMiraiForever public fun dependsOn( @@ -152,7 +154,7 @@ public class JvmPluginDescriptionBuilder( @Suppress("DEPRECATION_ERROR") public fun build(): JvmPluginDescription = - SimpleJvmPluginDescription(name, version, id, author, info, dependencies, kind) + SimpleJvmPluginDescription(name, version, id, author, info, dependencies, loadPriority) @Retention(AnnotationRetention.SOURCE) @DslMarker @@ -192,7 +194,7 @@ public data class SimpleJvmPluginDescription public override val author: String = "", public override val info: String = "", public override val dependencies: Set = setOf(), - public override val kind: PluginKind = PluginKind.NORMAL, + public override val loadPriority: PluginLoadPriority = PluginLoadPriority.AFTER_EXTENSIONS, ) : JvmPluginDescription { @Deprecated( @@ -214,8 +216,8 @@ public data class SimpleJvmPluginDescription author: String = "", info: String = "", dependencies: Set = setOf(), - kind: PluginKind = PluginKind.NORMAL, - ) : this(name, Semver(version, Semver.SemverType.LOOSE), id, author, info, dependencies, kind) + loadPriority: PluginLoadPriority = PluginLoadPriority.AFTER_EXTENSIONS, + ) : this(name, Semver(version, Semver.SemverType.LOOSE), id, author, info, dependencies, loadPriority) init { require(!name.contains(':')) { "':' is forbidden in plugin name" } @@ -240,8 +242,8 @@ public fun JvmPluginDescription( author: String = "", info: String = "", dependencies: Set = setOf(), - kind: PluginKind = PluginKind.NORMAL -): JvmPluginDescription = SimpleJvmPluginDescription(name, version, id, author, info, dependencies, kind) + loadPriority: PluginLoadPriority = PluginLoadPriority.AFTER_EXTENSIONS +): JvmPluginDescription = SimpleJvmPluginDescription(name, version, id, author, info, dependencies, loadPriority) @Deprecated( "JvmPluginDescription 没有构造器. 请使用 SimpleJvmPluginDescription.", @@ -260,5 +262,5 @@ public fun JvmPluginDescription( author: String = "", info: String = "", dependencies: Set = setOf(), - kind: PluginKind = PluginKind.NORMAL -): JvmPluginDescription = SimpleJvmPluginDescription(name, version, id, author, info, dependencies, kind) + loadPriority: PluginLoadPriority = PluginLoadPriority.AFTER_EXTENSIONS +): JvmPluginDescription = SimpleJvmPluginDescription(name, version, id, author, info, dependencies, loadPriority)