mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-19 14:44:48 +08:00
(ABI change) Rewrite ComponentStorage
: order extensions by property priority
. Remove builtinImplementations
and contribute them at the first initialization phase instead.
Close #1888, fix #1860. Add `ComponentStorageInternal` for frontend to provide components. Deprecate: - SingletonExtension - SingletonExtensionPoint - AbstractSingletonExtensionPoint - SingletonExtensionSelector - CommandCallInterceptorProviderImpl - CommandCallInterceptorProviderImplLazy - CommandCallParserProviderImpl - CommandCallParserProviderImplLazy - CommandCallResolverProviderImpl - CommandCallResolverProviderImplLazy ABI breaking change: - `PermissionServiceProvider`: supertype changed - `CommandCallResolverProvider.ExtensionPoint`: supertype changed - `PermissionServiceProvider.ExtensionPoint`: supertype changed
This commit is contained in:
parent
96e943c33f
commit
835059c44c
@ -162,7 +162,7 @@ public interface MiraiConsole : CoroutineScope {
|
|||||||
*
|
*
|
||||||
* 调用 [Bot.login] 可登录.
|
* 调用 [Bot.login] 可登录.
|
||||||
*
|
*
|
||||||
* @see Bot.botInstances 获取现有 [Bot] 实例列表
|
* @see Bot.instances 获取现有 [Bot] 实例列表
|
||||||
* @see BotConfigurationAlterer ExtensionPoint
|
* @see BotConfigurationAlterer ExtensionPoint
|
||||||
*/
|
*/
|
||||||
// don't static
|
// don't static
|
||||||
@ -225,11 +225,8 @@ public interface MiraiConsole : CoroutineScope {
|
|||||||
configuration()
|
configuration()
|
||||||
}
|
}
|
||||||
|
|
||||||
config = GlobalComponentStorage.run {
|
config = GlobalComponentStorage.foldExtensions(BotConfigurationAlterer, config) { acc, extension ->
|
||||||
BotConfigurationAlterer.foldExtensions(config) { acc, extension ->
|
extension.alterConfiguration(id, acc)
|
||||||
extension.alterConfiguration(id, acc)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return when (password) {
|
return when (password) {
|
||||||
|
@ -25,7 +25,6 @@ import net.mamoe.mirai.console.extension.ComponentStorage
|
|||||||
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
|
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
|
||||||
import net.mamoe.mirai.console.internal.command.CommandManagerImpl
|
import net.mamoe.mirai.console.internal.command.CommandManagerImpl
|
||||||
import net.mamoe.mirai.console.internal.data.builtins.ConsoleDataScopeImpl
|
import net.mamoe.mirai.console.internal.data.builtins.ConsoleDataScopeImpl
|
||||||
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
|
|
||||||
import net.mamoe.mirai.console.internal.logging.LoggerControllerImpl
|
import net.mamoe.mirai.console.internal.logging.LoggerControllerImpl
|
||||||
import net.mamoe.mirai.console.internal.plugin.BuiltInJvmPluginLoaderImpl
|
import net.mamoe.mirai.console.internal.plugin.BuiltInJvmPluginLoaderImpl
|
||||||
import net.mamoe.mirai.console.internal.pluginManagerImpl
|
import net.mamoe.mirai.console.internal.pluginManagerImpl
|
||||||
@ -317,6 +316,9 @@ public interface MiraiConsoleImplementation : CoroutineScope {
|
|||||||
@ConsoleFrontEndImplementation
|
@ConsoleFrontEndImplementation
|
||||||
public interface BackendAccess {
|
public interface BackendAccess {
|
||||||
// GlobalComponentStorage
|
// GlobalComponentStorage
|
||||||
|
/**
|
||||||
|
* 在 Mirai Console 第一个 phase 之后会包含内建 storages.
|
||||||
|
*/
|
||||||
public val globalComponentStorage: ComponentStorage
|
public val globalComponentStorage: ComponentStorage
|
||||||
|
|
||||||
// PluginManagerImpl.resolvedPlugins
|
// PluginManagerImpl.resolvedPlugins
|
||||||
@ -365,7 +367,7 @@ public interface MiraiConsoleImplementation : CoroutineScope {
|
|||||||
@ConsoleFrontEndImplementation
|
@ConsoleFrontEndImplementation
|
||||||
public companion object {
|
public companion object {
|
||||||
private val backendAccessInstance = object : BackendAccess {
|
private val backendAccessInstance = object : BackendAccess {
|
||||||
override val globalComponentStorage: ComponentStorage get() = GlobalComponentStorage
|
override val globalComponentStorage: ComponentStorage get() = getBridge().globalComponentStorage
|
||||||
override val resolvedPlugins: MutableList<Plugin> get() = MiraiConsole.pluginManagerImpl.resolvedPlugins
|
override val resolvedPlugins: MutableList<Plugin> get() = MiraiConsole.pluginManagerImpl.resolvedPlugins
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig
|
|||||||
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.*
|
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.*
|
||||||
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.PasswordKind.MD5
|
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.PasswordKind.MD5
|
||||||
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.PasswordKind.PLAIN
|
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.PasswordKind.PLAIN
|
||||||
|
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
|
||||||
import net.mamoe.mirai.console.internal.permission.BuiltInPermissionService
|
import net.mamoe.mirai.console.internal.permission.BuiltInPermissionService
|
||||||
import net.mamoe.mirai.console.internal.pluginManagerImpl
|
import net.mamoe.mirai.console.internal.pluginManagerImpl
|
||||||
import net.mamoe.mirai.console.internal.util.autoHexToBytes
|
import net.mamoe.mirai.console.internal.util.autoHexToBytes
|
||||||
@ -484,7 +485,7 @@ public object BuiltInCommands {
|
|||||||
lightYellow()
|
lightYellow()
|
||||||
"Built In Permission Service"
|
"Built In Permission Service"
|
||||||
} else {
|
} else {
|
||||||
val plugin = PermissionServiceProvider.providerPlugin
|
val plugin = GlobalComponentStorage.getPreferredExtension(PermissionServiceProvider).plugin
|
||||||
if (plugin == null) {
|
if (plugin == null) {
|
||||||
PermissionService.INSTANCE.toString()
|
PermissionService.INSTANCE.toString()
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
*
|
*
|
||||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
@ -44,10 +44,8 @@ public interface CommandCallParser {
|
|||||||
*/
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
public fun MessageChain.parseCommandCall(sender: CommandSender): CommandCall? {
|
public fun MessageChain.parseCommandCall(sender: CommandSender): CommandCall? {
|
||||||
GlobalComponentStorage.run {
|
GlobalComponentStorage.useEachExtensions(CommandCallParserProvider) { provider ->
|
||||||
CommandCallParserProvider.useExtensions { provider ->
|
provider.instance.parse(sender, this@parseCommandCall)?.let { return it }
|
||||||
provider.instance.parse(sender, this@parseCommandCall)?.let { return it }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
*
|
*
|
||||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
@ -12,7 +12,6 @@ package net.mamoe.mirai.console.command.parse
|
|||||||
import net.mamoe.mirai.console.command.CommandSender
|
import net.mamoe.mirai.console.command.CommandSender
|
||||||
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
|
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
|
||||||
import net.mamoe.mirai.console.extensions.CommandCallParserProvider
|
import net.mamoe.mirai.console.extensions.CommandCallParserProvider
|
||||||
import net.mamoe.mirai.console.extensions.CommandCallParserProviderImpl
|
|
||||||
import net.mamoe.mirai.console.internal.command.flattenCommandComponents
|
import net.mamoe.mirai.console.internal.command.flattenCommandComponents
|
||||||
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
||||||
import net.mamoe.mirai.message.data.MessageChain
|
import net.mamoe.mirai.message.data.MessageChain
|
||||||
@ -22,6 +21,13 @@ import net.mamoe.mirai.message.data.content
|
|||||||
@ConsoleExperimentalApi
|
@ConsoleExperimentalApi
|
||||||
@ExperimentalCommandDescriptors
|
@ExperimentalCommandDescriptors
|
||||||
public object SpaceSeparatedCommandCallParser : CommandCallParser {
|
public object SpaceSeparatedCommandCallParser : CommandCallParser {
|
||||||
|
|
||||||
|
@ConsoleExperimentalApi
|
||||||
|
@ExperimentalCommandDescriptors
|
||||||
|
public object Provider : CommandCallParserProvider {
|
||||||
|
override val instance: CommandCallParser get() = SpaceSeparatedCommandCallParser
|
||||||
|
}
|
||||||
|
|
||||||
override fun parse(caller: CommandSender, message: MessageChain): CommandCall? {
|
override fun parse(caller: CommandSender, message: MessageChain): CommandCall? {
|
||||||
val flatten = message.flattenCommandComponents().filterIsInstance<MessageContent>()
|
val flatten = message.flattenCommandComponents().filterIsInstance<MessageContent>()
|
||||||
if (flatten.isEmpty()) return null
|
if (flatten.isEmpty()) return null
|
||||||
@ -31,6 +37,4 @@ public object SpaceSeparatedCommandCallParser : CommandCallParser {
|
|||||||
valueArguments = flatten.drop(1).map(::DefaultCommandValueArgument)
|
valueArguments = flatten.drop(1).map(::DefaultCommandValueArgument)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
public object Provider : CommandCallParserProvider by CommandCallParserProviderImpl(SpaceSeparatedCommandCallParser)
|
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
*
|
*
|
||||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
@ -15,6 +15,7 @@ import net.mamoe.mirai.console.command.descriptor.ArgumentAcceptance.Companion.i
|
|||||||
import net.mamoe.mirai.console.command.parse.CommandCall
|
import net.mamoe.mirai.console.command.parse.CommandCall
|
||||||
import net.mamoe.mirai.console.command.parse.CommandValueArgument
|
import net.mamoe.mirai.console.command.parse.CommandValueArgument
|
||||||
import net.mamoe.mirai.console.command.parse.DefaultCommandValueArgument
|
import net.mamoe.mirai.console.command.parse.DefaultCommandValueArgument
|
||||||
|
import net.mamoe.mirai.console.extensions.CommandCallResolverProvider
|
||||||
import net.mamoe.mirai.console.internal.data.classifierAsKClass
|
import net.mamoe.mirai.console.internal.data.classifierAsKClass
|
||||||
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
||||||
import net.mamoe.mirai.console.util.safeCast
|
import net.mamoe.mirai.console.util.safeCast
|
||||||
@ -27,6 +28,11 @@ import net.mamoe.mirai.message.data.toMessageChain
|
|||||||
@ConsoleExperimentalApi
|
@ConsoleExperimentalApi
|
||||||
@ExperimentalCommandDescriptors
|
@ExperimentalCommandDescriptors
|
||||||
public object BuiltInCommandCallResolver : CommandCallResolver {
|
public object BuiltInCommandCallResolver : CommandCallResolver {
|
||||||
|
|
||||||
|
internal object Provider : CommandCallResolverProvider {
|
||||||
|
override val instance: CommandCallResolver = BuiltInCommandCallResolver
|
||||||
|
}
|
||||||
|
|
||||||
override fun resolve(call: CommandCall): CommandResolveResult {
|
override fun resolve(call: CommandCall): CommandResolveResult {
|
||||||
val callee = CommandManager.matchCommand(call.calleeName)
|
val callee = CommandManager.matchCommand(call.calleeName)
|
||||||
?: return CommandResolveResult(CommandExecuteResult.UnresolvedCommand(call))
|
?: return CommandResolveResult(CommandExecuteResult.UnresolvedCommand(call))
|
||||||
|
@ -66,15 +66,13 @@ public interface CommandCallInterceptor {
|
|||||||
*/
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
public fun Message.intercepted(caller: CommandSender): InterceptResult<Message> {
|
public fun Message.intercepted(caller: CommandSender): InterceptResult<Message> {
|
||||||
GlobalComponentStorage.run {
|
return GlobalComponentStorage.foldExtensions(CommandCallInterceptorProvider, this@intercepted) { acc, ext ->
|
||||||
return CommandCallInterceptorProvider.foldExtensions(this@intercepted) { acc, ext ->
|
val intercepted = ext.instance.interceptBeforeCall(acc, caller)
|
||||||
val intercepted = ext.instance.interceptBeforeCall(acc, caller)
|
intercepted?.fold(
|
||||||
intercepted?.fold(
|
onIntercepted = { return intercepted },
|
||||||
onIntercepted = { return intercepted },
|
otherwise = { it }
|
||||||
otherwise = { it }
|
) ?: acc
|
||||||
) ?: acc
|
}.let { InterceptResult(it) }
|
||||||
}.let { InterceptResult(it) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,15 +81,13 @@ public interface CommandCallInterceptor {
|
|||||||
*/
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
public fun CommandCall.intercepted(): InterceptResult<CommandCall> {
|
public fun CommandCall.intercepted(): InterceptResult<CommandCall> {
|
||||||
GlobalComponentStorage.run {
|
return GlobalComponentStorage.foldExtensions(CommandCallInterceptorProvider, this@intercepted) { acc, ext ->
|
||||||
return CommandCallInterceptorProvider.foldExtensions(this@intercepted) { acc, ext ->
|
val intercepted = ext.instance.interceptCall(acc)
|
||||||
val intercepted = ext.instance.interceptCall(acc)
|
intercepted?.fold(
|
||||||
intercepted?.fold(
|
onIntercepted = { return intercepted },
|
||||||
onIntercepted = { return intercepted },
|
otherwise = { it }
|
||||||
otherwise = { it }
|
) ?: acc
|
||||||
) ?: acc
|
}.let { InterceptResult(it) }
|
||||||
}.let { InterceptResult(it) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,15 +96,13 @@ public interface CommandCallInterceptor {
|
|||||||
*/
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
public fun ResolvedCommandCall.intercepted(): InterceptResult<ResolvedCommandCall> {
|
public fun ResolvedCommandCall.intercepted(): InterceptResult<ResolvedCommandCall> {
|
||||||
GlobalComponentStorage.run {
|
return GlobalComponentStorage.foldExtensions(CommandCallInterceptorProvider, this@intercepted) { acc, ext ->
|
||||||
return CommandCallInterceptorProvider.foldExtensions(this@intercepted) { acc, ext ->
|
val intercepted = ext.instance.interceptResolvedCall(acc)
|
||||||
val intercepted = ext.instance.interceptResolvedCall(acc)
|
intercepted?.fold(
|
||||||
intercepted?.fold(
|
onIntercepted = { return intercepted },
|
||||||
onIntercepted = { return intercepted },
|
otherwise = { it }
|
||||||
otherwise = { it }
|
) ?: acc
|
||||||
) ?: acc
|
}.let { InterceptResult(it) }
|
||||||
}.let { InterceptResult(it) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
*
|
*
|
||||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
@ -76,11 +76,9 @@ public interface CommandCallResolver {
|
|||||||
@ConsoleExperimentalApi
|
@ConsoleExperimentalApi
|
||||||
@ExperimentalCommandDescriptors
|
@ExperimentalCommandDescriptors
|
||||||
public fun CommandCall.resolve(): CommandResolveResult {
|
public fun CommandCall.resolve(): CommandResolveResult {
|
||||||
GlobalComponentStorage.run {
|
return GlobalComponentStorage.getExtensions(CommandCallResolverProvider).first()
|
||||||
val instance =
|
.extension.instance
|
||||||
CommandCallResolverProvider.findSingletonInstance(CommandCallResolverProvider.builtinImplementation)
|
.resolve(this@resolve)
|
||||||
return instance.resolve(this@resolve)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
*
|
*
|
||||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
@ -9,27 +9,99 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.console.extension
|
package net.mamoe.mirai.console.extension
|
||||||
|
|
||||||
|
import net.mamoe.mirai.console.ConsoleFrontEndImplementation
|
||||||
|
import net.mamoe.mirai.console.MiraiConsoleImplementation
|
||||||
import net.mamoe.mirai.console.plugin.Plugin
|
import net.mamoe.mirai.console.plugin.Plugin
|
||||||
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
|
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
|
||||||
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin.Companion.onLoad
|
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin.Companion.onLoad
|
||||||
|
import net.mamoe.mirai.utils.MiraiExperimentalApi
|
||||||
|
import java.util.stream.Stream
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 组件容器, 容纳 [Plugin] 注册的 [Extension].
|
* 组件容器, 容纳 [Plugin] 注册的 [Extension].
|
||||||
*
|
*
|
||||||
|
* 插件可在 [JvmPlugin.onLoad] 时提供扩展. 前端可在 [MiraiConsoleImplementation.BackendAccess.globalComponentStorage] 获取全局组件容器.
|
||||||
|
* 目前未允许获取全局组件容器. 如有需求请 [提交 issues](https://github.com/mamoe/mirai/issues/new/choose).
|
||||||
|
*
|
||||||
|
* 实现细节: 线程安全.
|
||||||
|
*
|
||||||
* @see Extension
|
* @see Extension
|
||||||
* @see JvmPlugin.onLoad
|
* @see JvmPlugin.onLoad
|
||||||
*/
|
*/
|
||||||
public interface ComponentStorage {
|
public interface ComponentStorage {
|
||||||
public fun <T : Extension> contribute(
|
|
||||||
extensionPoint: ExtensionPoint<T>,
|
|
||||||
plugin: Plugin,
|
|
||||||
extensionInstance: T,
|
|
||||||
)
|
|
||||||
|
|
||||||
public fun <T : Extension> contribute(
|
/**
|
||||||
extensionPoint: ExtensionPoint<T>,
|
* 注册一个扩展
|
||||||
|
*/
|
||||||
|
public fun <E : Extension> contribute(
|
||||||
|
extensionPoint: ExtensionPoint<E>,
|
||||||
plugin: Plugin,
|
plugin: Plugin,
|
||||||
lazyInstance: () -> T,
|
extensionInstance: E,
|
||||||
)
|
) // 2.11: E changed to T (only naming)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册一个扩展. [lazyInstance] 将会在 [getExtensions] 时才会计算.
|
||||||
|
*/
|
||||||
|
public fun <E : Extension> contribute(
|
||||||
|
extensionPoint: ExtensionPoint<E>,
|
||||||
|
plugin: Plugin,
|
||||||
|
lazyInstance: () -> E,
|
||||||
|
) // 2.11: E changed to T (only naming)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取优先级最高的 [ExtensionPoint] 扩展实例. 在未找到任何注册的实例时抛出 [NoSuchElementException].
|
||||||
|
*
|
||||||
|
* @since 2.11
|
||||||
|
*/
|
||||||
|
@MiraiExperimentalApi
|
||||||
|
public fun <E : Extension> getPreferredExtension(
|
||||||
|
extensionPoint: ExtensionPoint<E>,
|
||||||
|
): ExtensionRegistry<E> {
|
||||||
|
return getExtensions(extensionPoint).firstOrNull()
|
||||||
|
?: throw NoSuchElementException("No extension registered for $extensionPoint")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取注册的 [ExtensionPoint] 扩展实例列表. 返回的 [Sequence] 以 [Extension.priority] 倒序排序.
|
||||||
|
*
|
||||||
|
* @since 2.11
|
||||||
|
*/
|
||||||
|
public fun <E : Extension> getExtensions(
|
||||||
|
extensionPoint: ExtensionPoint<E>,
|
||||||
|
): Sequence<ExtensionRegistry<E>>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取注册的 [ExtensionPoint] 扩展实例列表. 返回的 [Stream] 以 [Extension.priority] 倒序排序.
|
||||||
|
*
|
||||||
|
* @since 2.11
|
||||||
|
*/
|
||||||
|
public fun <E : Extension> getExtensionsStream(
|
||||||
|
extensionPoint: ExtensionPoint<E>,
|
||||||
|
): Stream<ExtensionRegistry<E>>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 仅前端实现可用
|
||||||
|
*/
|
||||||
|
@ConsoleFrontEndImplementation
|
||||||
|
public interface ComponentStorageInternal : ComponentStorage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册一个由 Mirai Console 实现的扩展 (因此没有相关 [Plugin]). [lazyInstance] 将会在 [getExtensions] 时才会计算.
|
||||||
|
*/
|
||||||
|
public fun <E : Extension> contributeConsole(
|
||||||
|
extensionPoint: ExtensionPoint<E>,
|
||||||
|
lazyInstance: () -> E,
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册一个由 Mirai Console 实现的扩展 (因此没有相关 [Plugin]).
|
||||||
|
*/
|
||||||
|
public fun <E : Extension> contributeConsole(
|
||||||
|
extensionPoint: ExtensionPoint<E>,
|
||||||
|
instance: E,
|
||||||
|
) {
|
||||||
|
@Suppress("USELESS_CAST") // bug
|
||||||
|
contributeConsole(extensionPoint, { instance } as () -> E)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
*
|
*
|
||||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
@ -9,12 +9,15 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.console.extension
|
package net.mamoe.mirai.console.extension
|
||||||
|
|
||||||
|
import net.mamoe.mirai.console.command.parse.SpaceSeparatedCommandCallParser
|
||||||
import net.mamoe.mirai.console.extensions.PermissionServiceProvider
|
import net.mamoe.mirai.console.extensions.PermissionServiceProvider
|
||||||
import net.mamoe.mirai.console.extensions.PluginLoaderProvider
|
import net.mamoe.mirai.console.extensions.PluginLoaderProvider
|
||||||
import net.mamoe.mirai.console.extensions.SingletonExtensionSelector
|
import net.mamoe.mirai.console.extensions.SingletonExtensionSelector
|
||||||
import net.mamoe.mirai.console.extensions.SingletonExtensionSelector.ExtensionPoint.selectSingleton
|
import net.mamoe.mirai.console.extensions.SingletonExtensionSelector.ExtensionPoint.selectSingleton
|
||||||
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
|
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
|
||||||
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin.Companion.onLoad
|
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin.Companion.onLoad
|
||||||
|
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
||||||
|
import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表示一个扩展.
|
* 表示一个扩展.
|
||||||
@ -37,7 +40,18 @@ import net.mamoe.mirai.console.plugin.jvm.JvmPlugin.Companion.onLoad
|
|||||||
*
|
*
|
||||||
* @see ComponentStorage
|
* @see ComponentStorage
|
||||||
*/
|
*/
|
||||||
public interface Extension
|
public interface Extension {
|
||||||
|
/**
|
||||||
|
* 优先级. 越高越先使用. 内嵌的 [SpaceSeparatedCommandCallParser] 拥有优先级 0.
|
||||||
|
*
|
||||||
|
* 若两个 [InstanceExtension] 有相同的优先级, 将会优先使用内嵌的实现, 再按 [ComponentStorage.contribute] 顺序依次使用.
|
||||||
|
*
|
||||||
|
* @since 2.11
|
||||||
|
*/ // https://github.com/mamoe/mirai/issues/1860
|
||||||
|
@ConsoleExperimentalApi
|
||||||
|
public val priority: Int
|
||||||
|
get() = 0
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 增加一些函数 (方法)的扩展
|
* 增加一些函数 (方法)的扩展
|
||||||
@ -51,6 +65,8 @@ public interface FunctionExtension : Extension
|
|||||||
*
|
*
|
||||||
* @see PermissionServiceProvider
|
* @see PermissionServiceProvider
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Please use InstanceExtension instead.", replaceWith = ReplaceWith("InstanceExtension"))
|
||||||
|
@DeprecatedSinceMirai(warningSince = "2.11")
|
||||||
public interface SingletonExtension<T> : Extension {
|
public interface SingletonExtension<T> : Extension {
|
||||||
public val instance: T
|
public val instance: T
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
*
|
*
|
||||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
@ -12,13 +12,15 @@
|
|||||||
package net.mamoe.mirai.console.extension
|
package net.mamoe.mirai.console.extension
|
||||||
|
|
||||||
import net.mamoe.mirai.console.extensions.SingletonExtensionSelector
|
import net.mamoe.mirai.console.extensions.SingletonExtensionSelector
|
||||||
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
|
|
||||||
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
||||||
|
import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 由 [Extension] 的伴生对象实现.
|
* 表示一个扩展接入点(扩展类型). 在 Kotlin 由 [Extension] 的伴生对象实现, 在 Java 可通过静态字段提供.
|
||||||
|
*
|
||||||
|
* 在[注册扩展][ComponentStorage.contribute]时需要提供其 [ExtensionPoint], [ExtensionPoint] 也可以用于获取所有注册的扩展 ([ComponentStorage.getExtensions]).
|
||||||
*
|
*
|
||||||
* @see AbstractExtensionPoint
|
* @see AbstractExtensionPoint
|
||||||
*/
|
*/
|
||||||
@ -37,6 +39,8 @@ public abstract class AbstractExtensionPoint<T : Extension>(
|
|||||||
/**
|
/**
|
||||||
* 表示一个 [SingletonExtension] 的 [ExtensionPoint]
|
* 表示一个 [SingletonExtension] 的 [ExtensionPoint]
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Please use InstanceExtensionPoint instead.", replaceWith = ReplaceWith("InstanceExtensionPoint"))
|
||||||
|
@DeprecatedSinceMirai(warningSince = "2.11")
|
||||||
public interface SingletonExtensionPoint<T : SingletonExtension<*>> : ExtensionPoint<T>
|
public interface SingletonExtensionPoint<T : SingletonExtension<*>> : ExtensionPoint<T>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,34 +59,56 @@ public abstract class AbstractInstanceExtensionPoint<E : InstanceExtension<T>, T
|
|||||||
* @since 2.10
|
* @since 2.10
|
||||||
*/
|
*/
|
||||||
@ConsoleExperimentalApi
|
@ConsoleExperimentalApi
|
||||||
constructor(
|
public constructor(
|
||||||
extensionType: KClass<E>,
|
extensionType: KClass<E>
|
||||||
/**
|
|
||||||
* 内建的实现列表.
|
|
||||||
*/
|
|
||||||
@ConsoleExperimentalApi
|
|
||||||
public vararg val builtinImplementations: () -> E,
|
|
||||||
) : AbstractExtensionPoint<E>(extensionType) {
|
) : AbstractExtensionPoint<E>(extensionType) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 2.10
|
* @since 2.10
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(
|
||||||
|
"Default(builtin) implementations are not allowed any more. " +
|
||||||
|
"For plugin authors, provide them with lower priority when plugin being loaded(through the ComponentScope). " +
|
||||||
|
"For frontend implementers, provide them by `BackendAccess.globalComponentScope.contribute`. ",
|
||||||
|
replaceWith = ReplaceWith("AbstractInstanceExtensionPoint(extensionType)"),
|
||||||
|
level = DeprecationLevel.ERROR,
|
||||||
|
)
|
||||||
|
@DeprecatedSinceMirai(errorSince = "2.11") // for removal
|
||||||
@ConsoleExperimentalApi
|
@ConsoleExperimentalApi
|
||||||
public constructor(extensionType: KClass<E>) : this(
|
public constructor(
|
||||||
extensionType,
|
extensionType: KClass<E>,
|
||||||
builtinImplementations = arrayOf<() -> E>() as Array<out () -> E>
|
/**
|
||||||
) // to avoid resolution ambiguity
|
* 内建的实现列表.
|
||||||
|
*/
|
||||||
|
builtinImplementations: () -> E,
|
||||||
|
) : this(extensionType)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
@ConsoleExperimentalApi
|
@Deprecated(
|
||||||
|
"Default(builtin) implementations are not allowed any more. " +
|
||||||
|
"For plugin authors, provide them with lower priority when plugin being loaded(through the ComponentScope). " +
|
||||||
|
"For frontend implementers, provide them by `BackendAccess.globalComponentScope.contribute`. ",
|
||||||
|
replaceWith = ReplaceWith("AbstractInstanceExtensionPoint(extensionType)"),
|
||||||
|
level = DeprecationLevel.ERROR
|
||||||
|
)
|
||||||
|
@DeprecatedSinceMirai(errorSince = "2.11") // for removal
|
||||||
|
@ConsoleExperimentalApi // was experimental since 2.0
|
||||||
public constructor(extensionType: KClass<E>, vararg builtinImplementations: E) : this(
|
public constructor(extensionType: KClass<E>, vararg builtinImplementations: E) : this(
|
||||||
extensionType,
|
extensionType,
|
||||||
builtinImplementations = builtinImplementations.map { { it } }.toTypedArray()
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
"Please use AbstractInstanceExtensionPoint instead.",
|
||||||
|
replaceWith = ReplaceWith(
|
||||||
|
"AbstractInstanceExtension",
|
||||||
|
"net.mamoe.mirai.console.extension.AbstractInstanceExtensionPoint"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@DeprecatedSinceMirai(warningSince = "2.11")
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
public abstract class AbstractSingletonExtensionPoint<E : SingletonExtension<T>, T>
|
public abstract class AbstractSingletonExtensionPoint<E : SingletonExtension<T>, T>
|
||||||
/**
|
/**
|
||||||
* @since 2.10
|
* @since 2.10
|
||||||
@ -111,12 +137,6 @@ constructor(
|
|||||||
* 由 [SingletonExtensionSelector] 选择后的实例.
|
* 由 [SingletonExtensionSelector] 选择后的实例.
|
||||||
*/
|
*/
|
||||||
@ConsoleExperimentalApi
|
@ConsoleExperimentalApi
|
||||||
public open val selectedInstance: T by lazy {
|
public open val selectedInstance: T
|
||||||
GlobalComponentStorage.run {
|
get() = throw UnsupportedOperationException("SingletonExtension has been deprecated.")
|
||||||
this@AbstractSingletonExtensionPoint.findSingletonInstance(
|
|
||||||
extensionType,
|
|
||||||
builtinImplementation
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2022 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.extension
|
||||||
|
|
||||||
|
import net.mamoe.mirai.console.plugin.Plugin
|
||||||
|
import net.mamoe.mirai.utils.NotStableForInheritance
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一个已经注册的 [Extension]. 可通过 [ComponentStorage.getExtensions] 获得.
|
||||||
|
*
|
||||||
|
* @since 2.11
|
||||||
|
*/
|
||||||
|
@NotStableForInheritance
|
||||||
|
public interface ExtensionRegistry<E : Extension> {
|
||||||
|
/**
|
||||||
|
* 提供该 [ExtensionRegistry] 的插件. 若为 `null` 则表示由 Mirai Console 内置或者由前端实现.
|
||||||
|
*/
|
||||||
|
public val plugin: Plugin?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [Extension] 实例.
|
||||||
|
*/
|
||||||
|
public val extension: E
|
||||||
|
}
|
||||||
|
|
||||||
|
internal inline val <T> ExtensionRegistry<out InstanceExtension<T>>.instance get() = extension.instance
|
||||||
|
|
||||||
|
internal class ExtensionRegistryImpl<E : Extension> internal constructor(
|
||||||
|
/**
|
||||||
|
* 提供该 [ExtensionRegistry] 的插件. 若为 `null` 则表示由 Mirai Console 内置或者由前端实现.
|
||||||
|
*/
|
||||||
|
override val plugin: Plugin?,
|
||||||
|
/**
|
||||||
|
* [Extension] 实例.
|
||||||
|
*/
|
||||||
|
extensionInitializer: () -> E,
|
||||||
|
) : ExtensionRegistry<E> {
|
||||||
|
override val extension: E by lazy(extensionInitializer)
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
*
|
*
|
||||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
@ -13,19 +13,25 @@ import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
|
|||||||
import net.mamoe.mirai.console.command.resolve.CommandCallInterceptor
|
import net.mamoe.mirai.console.command.resolve.CommandCallInterceptor
|
||||||
import net.mamoe.mirai.console.extension.AbstractInstanceExtensionPoint
|
import net.mamoe.mirai.console.extension.AbstractInstanceExtensionPoint
|
||||||
import net.mamoe.mirai.console.extension.InstanceExtension
|
import net.mamoe.mirai.console.extension.InstanceExtension
|
||||||
|
import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||||
|
|
||||||
@ExperimentalCommandDescriptors
|
@ExperimentalCommandDescriptors
|
||||||
public interface CommandCallInterceptorProvider : InstanceExtension<CommandCallInterceptor> {
|
public interface CommandCallInterceptorProvider : InstanceExtension<CommandCallInterceptor> {
|
||||||
|
@ExperimentalCommandDescriptors
|
||||||
public companion object ExtensionPoint :
|
public companion object ExtensionPoint :
|
||||||
AbstractInstanceExtensionPoint<CommandCallInterceptorProvider, CommandCallInterceptor>(
|
AbstractInstanceExtensionPoint<CommandCallInterceptorProvider, CommandCallInterceptor>(
|
||||||
CommandCallInterceptorProvider::class
|
CommandCallInterceptorProvider::class
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Deprecated for removal. Please implement your own CommandCallInterceptorProvider.")
|
||||||
|
@DeprecatedSinceMirai(warningSince = "2.11") // for removal.
|
||||||
@ExperimentalCommandDescriptors
|
@ExperimentalCommandDescriptors
|
||||||
public class CommandCallInterceptorProviderImpl(override val instance: CommandCallInterceptor) :
|
public class CommandCallInterceptorProviderImpl(override val instance: CommandCallInterceptor) :
|
||||||
CommandCallInterceptorProvider
|
CommandCallInterceptorProvider
|
||||||
|
|
||||||
|
@Deprecated("Deprecated for removal. Please implement your own CommandCallInterceptorProvider.")
|
||||||
|
@DeprecatedSinceMirai(warningSince = "2.11") // for removal.
|
||||||
@ExperimentalCommandDescriptors
|
@ExperimentalCommandDescriptors
|
||||||
public class CommandCallInterceptorProviderImplLazy(initializer: () -> CommandCallInterceptor) :
|
public class CommandCallInterceptorProviderImplLazy(initializer: () -> CommandCallInterceptor) :
|
||||||
CommandCallInterceptorProvider {
|
CommandCallInterceptorProvider {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
*
|
*
|
||||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
@ -11,26 +11,27 @@ package net.mamoe.mirai.console.extensions
|
|||||||
|
|
||||||
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
|
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
|
||||||
import net.mamoe.mirai.console.command.parse.CommandCallParser
|
import net.mamoe.mirai.console.command.parse.CommandCallParser
|
||||||
import net.mamoe.mirai.console.command.parse.SpaceSeparatedCommandCallParser
|
|
||||||
import net.mamoe.mirai.console.extension.AbstractInstanceExtensionPoint
|
import net.mamoe.mirai.console.extension.AbstractInstanceExtensionPoint
|
||||||
import net.mamoe.mirai.console.extension.InstanceExtension
|
import net.mamoe.mirai.console.extension.InstanceExtension
|
||||||
|
import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The provider of [CommandCallParser]
|
* The provider of [CommandCallParser]
|
||||||
*/
|
*/
|
||||||
@ExperimentalCommandDescriptors
|
@ExperimentalCommandDescriptors
|
||||||
public interface CommandCallParserProvider : InstanceExtension<CommandCallParser> {
|
public interface CommandCallParserProvider : InstanceExtension<CommandCallParser> {
|
||||||
|
@ExperimentalCommandDescriptors
|
||||||
public companion object ExtensionPoint :
|
public companion object ExtensionPoint :
|
||||||
AbstractInstanceExtensionPoint<CommandCallParserProvider, CommandCallParser>(
|
AbstractInstanceExtensionPoint<CommandCallParserProvider, CommandCallParser>(CommandCallParserProvider::class)
|
||||||
CommandCallParserProvider::class,
|
|
||||||
SpaceSeparatedCommandCallParser.Provider
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Deprecated for removal. Please implement your own CommandCallParserProvider.")
|
||||||
|
@DeprecatedSinceMirai(warningSince = "2.11") // for removal.
|
||||||
@ExperimentalCommandDescriptors
|
@ExperimentalCommandDescriptors
|
||||||
public class CommandCallParserProviderImpl(override val instance: CommandCallParser) : CommandCallParserProvider
|
public class CommandCallParserProviderImpl(override val instance: CommandCallParser) : CommandCallParserProvider
|
||||||
|
|
||||||
|
@Deprecated("Deprecated for removal. Please implement your own CommandCallParserProvider.")
|
||||||
|
@DeprecatedSinceMirai(warningSince = "2.11") // for removal.
|
||||||
@ExperimentalCommandDescriptors
|
@ExperimentalCommandDescriptors
|
||||||
public class CommandCallParserProviderImplLazy(initializer: () -> CommandCallParser) : CommandCallParserProvider {
|
public class CommandCallParserProviderImplLazy(initializer: () -> CommandCallParser) : CommandCallParserProvider {
|
||||||
override val instance: CommandCallParser by lazy(initializer)
|
override val instance: CommandCallParser by lazy(initializer)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
*
|
*
|
||||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
@ -10,23 +10,26 @@
|
|||||||
package net.mamoe.mirai.console.extensions
|
package net.mamoe.mirai.console.extensions
|
||||||
|
|
||||||
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
|
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
|
||||||
import net.mamoe.mirai.console.command.resolve.BuiltInCommandCallResolver
|
|
||||||
import net.mamoe.mirai.console.command.resolve.CommandCallResolver
|
import net.mamoe.mirai.console.command.resolve.CommandCallResolver
|
||||||
import net.mamoe.mirai.console.extension.AbstractSingletonExtensionPoint
|
import net.mamoe.mirai.console.extension.AbstractInstanceExtensionPoint
|
||||||
import net.mamoe.mirai.console.extension.SingletonExtension
|
import net.mamoe.mirai.console.extension.InstanceExtension
|
||||||
|
import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||||
|
|
||||||
@ExperimentalCommandDescriptors
|
@ExperimentalCommandDescriptors
|
||||||
public interface CommandCallResolverProvider : SingletonExtension<CommandCallResolver> {
|
public interface CommandCallResolverProvider : InstanceExtension<CommandCallResolver> {
|
||||||
|
|
||||||
|
@ExperimentalCommandDescriptors
|
||||||
public companion object ExtensionPoint :
|
public companion object ExtensionPoint :
|
||||||
AbstractSingletonExtensionPoint<CommandCallResolverProvider, CommandCallResolver>(
|
AbstractInstanceExtensionPoint<CommandCallResolverProvider, CommandCallResolver>(CommandCallResolverProvider::class)
|
||||||
CommandCallResolverProvider::class,
|
|
||||||
{ BuiltInCommandCallResolver }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Deprecated for removal. Please implement your own CommandCallResolverProvider.")
|
||||||
|
@DeprecatedSinceMirai(warningSince = "2.11") // for removal.
|
||||||
@ExperimentalCommandDescriptors
|
@ExperimentalCommandDescriptors
|
||||||
public class CommandCallResolverProviderImpl(override val instance: CommandCallResolver) : CommandCallResolverProvider
|
public class CommandCallResolverProviderImpl(override val instance: CommandCallResolver) : CommandCallResolverProvider
|
||||||
|
|
||||||
|
@Deprecated("Deprecated for removal. Please implement your own CommandCallResolverProvider.")
|
||||||
|
@DeprecatedSinceMirai(warningSince = "2.11") // for removal.
|
||||||
@ExperimentalCommandDescriptors
|
@ExperimentalCommandDescriptors
|
||||||
public class CommandCallResolverProviderImplLazy(initializer: () -> CommandCallResolver) : CommandCallResolverProvider {
|
public class CommandCallResolverProviderImplLazy(initializer: () -> CommandCallResolver) : CommandCallResolverProvider {
|
||||||
override val instance: CommandCallResolver by lazy(initializer)
|
override val instance: CommandCallResolver by lazy(initializer)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
*
|
*
|
||||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
@ -9,55 +9,35 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.console.extensions
|
package net.mamoe.mirai.console.extensions
|
||||||
|
|
||||||
import net.mamoe.mirai.console.extension.AbstractSingletonExtensionPoint
|
import net.mamoe.mirai.console.extension.AbstractInstanceExtensionPoint
|
||||||
import net.mamoe.mirai.console.extension.SingletonExtension
|
import net.mamoe.mirai.console.extension.InstanceExtension
|
||||||
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
|
|
||||||
import net.mamoe.mirai.console.internal.permission.BuiltInPermissionService
|
|
||||||
import net.mamoe.mirai.console.permission.PermissionService
|
import net.mamoe.mirai.console.permission.PermissionService
|
||||||
import net.mamoe.mirai.console.plugin.Plugin
|
import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||||
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [权限服务][PermissionService] 提供器.
|
* [权限服务][PermissionService] 提供器.
|
||||||
*
|
*
|
||||||
* 当插件注册 [PermissionService] 后, 默认会使用插件的 [PermissionService].
|
* 当插件注册 [PermissionService] 后, 默认会使用插件的 [PermissionService].
|
||||||
*/
|
*/
|
||||||
public interface PermissionServiceProvider : SingletonExtension<PermissionService<*>> {
|
public interface PermissionServiceProvider : InstanceExtension<PermissionService<*>> {
|
||||||
|
|
||||||
public companion object ExtensionPoint :
|
public companion object ExtensionPoint :
|
||||||
AbstractSingletonExtensionPoint<PermissionServiceProvider, PermissionService<*>>(
|
AbstractInstanceExtensionPoint<PermissionServiceProvider, PermissionService<*>>(PermissionServiceProvider::class)
|
||||||
PermissionServiceProvider::class,
|
// ! BREAKING CHANGE MADE IN 2.11: supertype changed from AbstractSingletonExtensionPoint to AbstractInstanceExtensionPoint
|
||||||
{ BuiltInPermissionService() }
|
|
||||||
) {
|
|
||||||
internal var permissionServiceOk = false
|
|
||||||
|
|
||||||
@ConsoleExperimentalApi
|
|
||||||
public val providerPlugin: Plugin? by lazy {
|
|
||||||
GlobalComponentStorage.run {
|
|
||||||
val instance = PermissionService.INSTANCE
|
|
||||||
if (instance is BuiltInPermissionService) return@lazy null
|
|
||||||
PermissionServiceProvider.getExtensions().find { it.extension.instance === instance }?.plugin
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ConsoleExperimentalApi
|
|
||||||
override val selectedInstance: PermissionService<*>
|
|
||||||
get() {
|
|
||||||
if (!permissionServiceOk) {
|
|
||||||
error("PermissionService not yet loaded")
|
|
||||||
}
|
|
||||||
return super.selectedInstance
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see PermissionServiceProvider
|
* @see PermissionServiceProvider
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Please implement your own PermissionServiceProvider.")
|
||||||
|
@DeprecatedSinceMirai(warningSince = "2.11") // for hidden.
|
||||||
public class PermissionServiceProviderImpl(override val instance: PermissionService<*>) : PermissionServiceProvider
|
public class PermissionServiceProviderImpl(override val instance: PermissionService<*>) : PermissionServiceProvider
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see PermissionServiceProvider
|
* @see PermissionServiceProvider
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Please implement your own PermissionServiceProvider.")
|
||||||
|
@DeprecatedSinceMirai(warningSince = "2.11") // for hidden.
|
||||||
public class PermissionServiceProviderImplLazy(initializer: () -> PermissionService<*>) : PermissionServiceProvider {
|
public class PermissionServiceProviderImplLazy(initializer: () -> PermissionService<*>) : PermissionServiceProvider {
|
||||||
override val instance: PermissionService<*> by lazy(initializer)
|
override val instance: PermissionService<*> by lazy(initializer)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
*
|
*
|
||||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
@ -14,6 +14,7 @@ import net.mamoe.mirai.console.extension.Extension
|
|||||||
import net.mamoe.mirai.console.extension.InstanceExtension
|
import net.mamoe.mirai.console.extension.InstanceExtension
|
||||||
import net.mamoe.mirai.console.extension.PluginComponentStorage
|
import net.mamoe.mirai.console.extension.PluginComponentStorage
|
||||||
import net.mamoe.mirai.console.plugin.loader.PluginLoader
|
import net.mamoe.mirai.console.plugin.loader.PluginLoader
|
||||||
|
import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提供扩展 [PluginLoader]
|
* 提供扩展 [PluginLoader]
|
||||||
@ -30,8 +31,12 @@ public interface PluginLoaderProvider : InstanceExtension<PluginLoader<*, *>> {
|
|||||||
public companion object ExtensionPoint : AbstractExtensionPoint<PluginLoaderProvider>(PluginLoaderProvider::class)
|
public companion object ExtensionPoint : AbstractExtensionPoint<PluginLoaderProvider>(PluginLoaderProvider::class)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Please implement your own PluginLoaderProvider.")
|
||||||
|
@DeprecatedSinceMirai(warningSince = "2.11") // for hidden.
|
||||||
public class PluginLoaderProviderImpl(override val instance: PluginLoader<*, *>) : PluginLoaderProvider
|
public class PluginLoaderProviderImpl(override val instance: PluginLoader<*, *>) : PluginLoaderProvider
|
||||||
|
|
||||||
|
@Deprecated("Please implement your own PluginLoaderProvider.")
|
||||||
|
@DeprecatedSinceMirai(warningSince = "2.11") // for hidden.
|
||||||
public class PluginLoaderProviderImplLazy(initializer: () -> PluginLoader<*, *>) : PluginLoaderProvider {
|
public class PluginLoaderProviderImplLazy(initializer: () -> PluginLoader<*, *>) : PluginLoaderProvider {
|
||||||
override val instance: PluginLoader<*, *> by lazy(initializer)
|
override val instance: PluginLoader<*, *> by lazy(initializer)
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
*
|
*
|
||||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
@ -7,18 +7,17 @@
|
|||||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("DEPRECATION")
|
||||||
|
|
||||||
package net.mamoe.mirai.console.extensions
|
package net.mamoe.mirai.console.extensions
|
||||||
|
|
||||||
import net.mamoe.mirai.console.MiraiConsole
|
import net.mamoe.mirai.console.MiraiConsole
|
||||||
import net.mamoe.mirai.console.extension.AbstractExtensionPoint
|
import net.mamoe.mirai.console.extension.*
|
||||||
import net.mamoe.mirai.console.extension.Extension
|
|
||||||
import net.mamoe.mirai.console.extension.FunctionExtension
|
|
||||||
import net.mamoe.mirai.console.extension.SingletonExtension
|
|
||||||
import net.mamoe.mirai.console.internal.extension.SingletonExtensionSelectorImpl
|
|
||||||
import net.mamoe.mirai.console.internal.extension.ExtensionRegistry
|
|
||||||
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
|
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
|
||||||
|
import net.mamoe.mirai.console.internal.extension.SingletonExtensionSelectorImpl
|
||||||
import net.mamoe.mirai.console.plugin.Plugin
|
import net.mamoe.mirai.console.plugin.Plugin
|
||||||
import net.mamoe.mirai.console.plugin.name
|
import net.mamoe.mirai.console.plugin.name
|
||||||
|
import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||||
import net.mamoe.mirai.utils.info
|
import net.mamoe.mirai.utils.info
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
@ -27,10 +26,20 @@ import kotlin.reflect.KClass
|
|||||||
*
|
*
|
||||||
* 如有多个 [SingletonExtensionSelector] 注册, 将会停止服务器.
|
* 如有多个 [SingletonExtensionSelector] 注册, 将会停止服务器.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(
|
||||||
|
"Order of extensions is now determined by its priority property since 2.11. SingletonExtensionSelector is not needed anymore. ",
|
||||||
|
level = DeprecationLevel.WARNING
|
||||||
|
)
|
||||||
|
@DeprecatedSinceMirai(warningSince = "2.11")
|
||||||
public interface SingletonExtensionSelector : FunctionExtension {
|
public interface SingletonExtensionSelector : FunctionExtension {
|
||||||
/**
|
/**
|
||||||
* 表示一个插件注册的 [Extension]
|
* 表示一个插件注册的 [Extension]
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(
|
||||||
|
"Order of extensions is now determined by its priority property since 2.11. SingletonExtensionSelector is not needed anymore. ",
|
||||||
|
level = DeprecationLevel.WARNING
|
||||||
|
)
|
||||||
|
@DeprecatedSinceMirai(warningSince = "2.11")
|
||||||
public data class Registry<T : Extension>(
|
public data class Registry<T : Extension>(
|
||||||
val plugin: Plugin?,
|
val plugin: Plugin?,
|
||||||
val extension: T,
|
val extension: T,
|
||||||
@ -44,6 +53,11 @@ public interface SingletonExtensionSelector : FunctionExtension {
|
|||||||
candidates: Collection<Registry<T>>,
|
candidates: Collection<Registry<T>>,
|
||||||
): T?
|
): T?
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
"Order of extensions is now determined by its priority property since 2.11. SingletonExtensionSelector is not needed anymore. ",
|
||||||
|
level = DeprecationLevel.WARNING
|
||||||
|
)
|
||||||
|
@DeprecatedSinceMirai(warningSince = "2.11")
|
||||||
public companion object ExtensionPoint :
|
public companion object ExtensionPoint :
|
||||||
AbstractExtensionPoint<SingletonExtensionSelector>(SingletonExtensionSelector::class) {
|
AbstractExtensionPoint<SingletonExtensionSelector>(SingletonExtensionSelector::class) {
|
||||||
|
|
||||||
@ -53,16 +67,22 @@ public interface SingletonExtensionSelector : FunctionExtension {
|
|||||||
|
|
||||||
internal fun init() {
|
internal fun init() {
|
||||||
check(instanceField == null) { "Internal error: reinitialize SingletonExtensionSelector" }
|
check(instanceField == null) { "Internal error: reinitialize SingletonExtensionSelector" }
|
||||||
val instances = GlobalComponentStorage.run { SingletonExtensionSelector.getExtensions() }
|
val instances = GlobalComponentStorage.getExtensions(ExtensionPoint).toList()
|
||||||
instanceField = when {
|
instanceField = when {
|
||||||
instances.isEmpty() -> SingletonExtensionSelectorImpl
|
instances.isEmpty() -> SingletonExtensionSelectorImpl
|
||||||
instances.size == 1 -> {
|
instances.size == 1 -> {
|
||||||
instances.single().also { (plugin, ext) ->
|
instances.single().also { registry ->
|
||||||
MiraiConsole.mainLogger.info { "Loaded SingletonExtensionSelector: $ext from ${plugin?.name ?: "<builtin>"}" }
|
MiraiConsole.mainLogger.info { "Loaded SingletonExtensionSelector: ${registry.extension} from ${registry.plugin?.name ?: "<builtin>"}" }
|
||||||
}.extension
|
}.extension
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
error("Found too many SingletonExtensionSelectors: ${instances.joinToString { (p, i) -> "'$i' from '${p?.name ?: "<builtin>"}'" }}. Check your plugins and ensure there is only one external SingletonExtensionSelectors")
|
val hint = instances.joinToString { reg ->
|
||||||
|
"'${reg.extension}' from '${reg.plugin?.name ?: "<builtin>"}'"
|
||||||
|
}
|
||||||
|
error(
|
||||||
|
"Found too many SingletonExtensionSelectors: $hint. " +
|
||||||
|
"Check your plugins and ensure there is only one external SingletonExtensionSelectors"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,13 @@ import net.mamoe.mirai.console.MiraiConsoleImplementation
|
|||||||
import net.mamoe.mirai.console.command.BuiltInCommands
|
import net.mamoe.mirai.console.command.BuiltInCommands
|
||||||
import net.mamoe.mirai.console.command.CommandManager
|
import net.mamoe.mirai.console.command.CommandManager
|
||||||
import net.mamoe.mirai.console.command.ConsoleCommandSender
|
import net.mamoe.mirai.console.command.ConsoleCommandSender
|
||||||
|
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
|
||||||
|
import net.mamoe.mirai.console.command.parse.SpaceSeparatedCommandCallParser
|
||||||
|
import net.mamoe.mirai.console.command.resolve.BuiltInCommandCallResolver
|
||||||
|
import net.mamoe.mirai.console.extensions.CommandCallParserProvider
|
||||||
|
import net.mamoe.mirai.console.extensions.CommandCallResolverProvider
|
||||||
import net.mamoe.mirai.console.extensions.PermissionServiceProvider
|
import net.mamoe.mirai.console.extensions.PermissionServiceProvider
|
||||||
import net.mamoe.mirai.console.extensions.PostStartupExtension
|
import net.mamoe.mirai.console.extensions.PostStartupExtension
|
||||||
import net.mamoe.mirai.console.extensions.SingletonExtensionSelector
|
|
||||||
import net.mamoe.mirai.console.internal.command.CommandConfig
|
import net.mamoe.mirai.console.internal.command.CommandConfig
|
||||||
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig
|
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig
|
||||||
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.ConfigurationKey
|
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.ConfigurationKey
|
||||||
@ -32,7 +36,7 @@ import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.Pa
|
|||||||
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.PasswordKind.PLAIN
|
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.PasswordKind.PLAIN
|
||||||
import net.mamoe.mirai.console.internal.data.builtins.LoggerConfig
|
import net.mamoe.mirai.console.internal.data.builtins.LoggerConfig
|
||||||
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
|
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
|
||||||
import net.mamoe.mirai.console.internal.extension.SingletonExtensionSelectorImpl
|
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorageImpl
|
||||||
import net.mamoe.mirai.console.internal.logging.LoggerControllerImpl
|
import net.mamoe.mirai.console.internal.logging.LoggerControllerImpl
|
||||||
import net.mamoe.mirai.console.internal.logging.MiraiConsoleLogger
|
import net.mamoe.mirai.console.internal.logging.MiraiConsoleLogger
|
||||||
import net.mamoe.mirai.console.internal.permission.BuiltInPermissionService
|
import net.mamoe.mirai.console.internal.permission.BuiltInPermissionService
|
||||||
@ -77,6 +81,9 @@ internal class MiraiConsoleImplementationBridge(
|
|||||||
override val version: SemVersion by MiraiConsoleBuildConstants::version
|
override val version: SemVersion by MiraiConsoleBuildConstants::version
|
||||||
override val pluginManager: PluginManagerImpl by lazy { PluginManagerImpl(coroutineContext) }
|
override val pluginManager: PluginManagerImpl by lazy { PluginManagerImpl(coroutineContext) }
|
||||||
|
|
||||||
|
// used internally
|
||||||
|
val globalComponentStorage: GlobalComponentStorageImpl by lazy { GlobalComponentStorageImpl() }
|
||||||
|
|
||||||
override val mainLogger: MiraiLogger by lazy { createLogger("main") }
|
override val mainLogger: MiraiLogger by lazy { createLogger("main") }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -99,6 +106,15 @@ internal class MiraiConsoleImplementationBridge(
|
|||||||
internal fun doStart() {
|
internal fun doStart() {
|
||||||
externalImplementation.preStart()
|
externalImplementation.preStart()
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCommandDescriptors::class)
|
||||||
|
phase("register builtin componenets") {
|
||||||
|
GlobalComponentStorage.run {
|
||||||
|
contributeConsole(CommandCallParserProvider, SpaceSeparatedCommandCallParser.Provider)
|
||||||
|
contributeConsole(CommandCallResolverProvider, BuiltInCommandCallResolver.Provider)
|
||||||
|
contributeConsole(PermissionServiceProvider, BuiltInPermissionService.Provider())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
phase("setup logger controller") {
|
phase("setup logger controller") {
|
||||||
if (loggerController === LoggerControllerImpl) {
|
if (loggerController === LoggerControllerImpl) {
|
||||||
// Reload LoggerConfig.
|
// Reload LoggerConfig.
|
||||||
@ -159,25 +175,30 @@ internal class MiraiConsoleImplementationBridge(
|
|||||||
mainLogger.verbose { "${PluginManager.plugins.size} plugin(s) loaded." }
|
mainLogger.verbose { "${PluginManager.plugins.size} plugin(s) loaded." }
|
||||||
}
|
}
|
||||||
|
|
||||||
phase("load SingletonExtensionSelector") {
|
// phase("load SingletonExtensionSelector") {
|
||||||
SingletonExtensionSelector.init()
|
// SingletonExtensionSelector.init()
|
||||||
val instance = SingletonExtensionSelector.instance
|
// val instance = SingletonExtensionSelector.instance
|
||||||
if (instance is SingletonExtensionSelectorImpl) {
|
// if (instance is SingletonExtensionSelectorImpl) {
|
||||||
consoleDataScope.addAndReloadConfig(instance.config)
|
// consoleDataScope.addAndReloadConfig(instance.config)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
phase("load PermissionService") {
|
phase("load PermissionService") {
|
||||||
mainLogger.verbose { "Loading PermissionService..." }
|
mainLogger.verbose { "Loading PermissionService..." }
|
||||||
|
|
||||||
PermissionServiceProvider.permissionServiceOk = true
|
|
||||||
PermissionService.INSTANCE.let { ps ->
|
PermissionService.INSTANCE.let { ps ->
|
||||||
if (ps is BuiltInPermissionService) {
|
if (ps is BuiltInPermissionService) {
|
||||||
consoleDataScope.addAndReloadConfig(ps.config)
|
consoleDataScope.addAndReloadConfig(ps.config)
|
||||||
mainLogger.verbose { "Reloaded PermissionService settings." }
|
mainLogger.verbose { "Reloaded PermissionService settings." }
|
||||||
} else {
|
} else {
|
||||||
mainLogger.info { "Loaded PermissionService from plugin ${PermissionServiceProvider.providerPlugin?.name}" }
|
mainLogger.info {
|
||||||
|
"Loaded PermissionService from plugin ${
|
||||||
|
GlobalComponentStorage.getPreferredExtension(
|
||||||
|
PermissionServiceProvider
|
||||||
|
).plugin?.name
|
||||||
|
}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,9 +279,7 @@ internal class MiraiConsoleImplementationBridge(
|
|||||||
}
|
}
|
||||||
|
|
||||||
phase("finally post") {
|
phase("finally post") {
|
||||||
GlobalComponentStorage.run {
|
globalComponentStorage.useEachExtensions(PostStartupExtension) { it.invoke() }
|
||||||
PostStartupExtension.useExtensions { it() } // exceptions thrown will be caught by caller of `doStart`.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
externalImplementation.postStart()
|
externalImplementation.postStart()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
*
|
*
|
||||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
@ -10,140 +10,116 @@
|
|||||||
package net.mamoe.mirai.console.internal.extension
|
package net.mamoe.mirai.console.internal.extension
|
||||||
|
|
||||||
import net.mamoe.mirai.console.extension.*
|
import net.mamoe.mirai.console.extension.*
|
||||||
import net.mamoe.mirai.console.extensions.SingletonExtensionSelector
|
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
|
||||||
import net.mamoe.mirai.console.extensions.SingletonExtensionSelector.ExtensionPoint.selectSingleton
|
|
||||||
import net.mamoe.mirai.console.internal.data.kClassQualifiedNameOrTip
|
import net.mamoe.mirai.console.internal.data.kClassQualifiedNameOrTip
|
||||||
import net.mamoe.mirai.console.plugin.Plugin
|
import net.mamoe.mirai.console.plugin.Plugin
|
||||||
import net.mamoe.mirai.console.plugin.name
|
import net.mamoe.mirai.console.plugin.name
|
||||||
|
import java.util.*
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.util.concurrent.CopyOnWriteArraySet
|
import java.util.stream.Stream
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
internal class GlobalComponentStorageImpl : AbstractConcurrentComponentStorage()
|
||||||
|
|
||||||
|
// source compatibility for <2.11
|
||||||
|
internal val GlobalComponentStorage get() = MiraiConsoleImplementationBridge.globalComponentStorage
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The [ComponentStorage] containing all components provided by Mirai Console internals and installed plugins.
|
* thread-safe.
|
||||||
*/
|
*/
|
||||||
internal object GlobalComponentStorage : AbstractConcurrentComponentStorage()
|
internal abstract class AbstractConcurrentComponentStorage : ComponentStorage, ComponentStorageInternal {
|
||||||
internal interface ExtensionRegistry<out E : Extension> {
|
///////////////////////////////////////////////////////////////////////////
|
||||||
val plugin: Plugin?
|
// registry implementation
|
||||||
val extension: E
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
operator fun component1(): Plugin? {
|
/**
|
||||||
return this.plugin
|
* For each [ExtensionPoint]. thread-safe.
|
||||||
}
|
*/
|
||||||
|
internal class Registries<T : Extension> {
|
||||||
|
@Volatile
|
||||||
|
private var data: MutableCollection<ExtensionRegistry<T>> = ArrayList()
|
||||||
|
private val lock = Any()
|
||||||
|
|
||||||
operator fun component2(): E {
|
fun register(registry: ExtensionRegistry<T>) {
|
||||||
return this.extension
|
synchronized(lock) {
|
||||||
}
|
val list = PriorityQueue(
|
||||||
}
|
data.size + 1,
|
||||||
|
Comparator.comparing<ExtensionRegistry<T>, Int> { it.extension.priority }.reversed()
|
||||||
internal class LazyExtensionRegistry<out E : Extension>(
|
|
||||||
override val plugin: Plugin?,
|
|
||||||
initializer: () -> E,
|
|
||||||
) : ExtensionRegistry<E> {
|
|
||||||
override val extension: E by lazy { initializer() }
|
|
||||||
}
|
|
||||||
|
|
||||||
internal data class DataExtensionRegistry<out E : Extension>(
|
|
||||||
override val plugin: Plugin?,
|
|
||||||
override val extension: E,
|
|
||||||
) : ExtensionRegistry<E>
|
|
||||||
|
|
||||||
internal abstract class AbstractConcurrentComponentStorage : ComponentStorage {
|
|
||||||
private val instances: MutableMap<ExtensionPoint<*>, MutableSet<ExtensionRegistry<*>>> = ConcurrentHashMap()
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
internal fun <T : Extension> ExtensionPoint<out T>.getExtensions(): Set<ExtensionRegistry<T>> {
|
|
||||||
val userDefined = instances.getOrPut(this, ::CopyOnWriteArraySet) as Set<ExtensionRegistry<T>>
|
|
||||||
|
|
||||||
val builtins = if (this is AbstractInstanceExtensionPoint<*, *>) {
|
|
||||||
this.builtinImplementations.mapTo(HashSet()) { instance ->
|
|
||||||
DataExtensionRegistry(
|
|
||||||
null,
|
|
||||||
instance()
|
|
||||||
)
|
)
|
||||||
} as Set<ExtensionRegistry<T>>
|
list.addAll(data)
|
||||||
} else null
|
list.add(registry)
|
||||||
|
data = list
|
||||||
return builtins?.plus(userDefined) ?: userDefined
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// unused for now
|
|
||||||
internal fun removeExtensionsRegisteredByPlugin(plugin: Plugin) {
|
|
||||||
instances.forEach { (_, u) ->
|
|
||||||
u.removeAll { it.plugin == plugin }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return thread-safe Sequence
|
||||||
|
*/
|
||||||
|
fun asSequence(): Sequence<ExtensionRegistry<T>> = data.asSequence()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return thread-safe Sequence
|
||||||
|
*/
|
||||||
|
fun asStream(): Stream<ExtensionRegistry<T>> = data.stream()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val registries: MutableMap<ExtensionPoint<*>, Registries<*>> = ConcurrentHashMap()
|
||||||
|
|
||||||
|
private fun <T : Extension> getRegistries(ep: ExtensionPoint<T>): Registries<T> {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return registries.getOrPut(ep) { Registries<T>() } as Registries<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T : Extension> registerExtension(ep: ExtensionPoint<T>, registry: ExtensionRegistry<T>) {
|
||||||
|
getRegistries(ep).register(registry)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// public API implementation
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
internal fun mergeWith(another: AbstractConcurrentComponentStorage) {
|
internal fun mergeWith(another: AbstractConcurrentComponentStorage) {
|
||||||
for ((ep, list) in another.instances) {
|
another.registries.forEach { (ep, registries) ->
|
||||||
for (extensionRegistry in list) {
|
for (extensionRegistry in registries.asSequence()) {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
ep as ExtensionPoint<Extension>
|
ep as ExtensionPoint<Extension>
|
||||||
this.contribute(ep, extensionRegistry.plugin, lazyInstance = { extensionRegistry.extension })
|
registerExtension(ep, ExtensionRegistryImpl(extensionRegistry.plugin) { extensionRegistry.extension })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline fun <T : Extension> ExtensionPoint<out T>.withExtensions(block: T.() -> Unit) {
|
internal inline fun <T : Extension> useEachExtensions(
|
||||||
return withExtensions { _ -> block() }
|
extensionPoint: ExtensionPoint<T>,
|
||||||
}
|
block: ExtensionRegistry<T>.(instance: T) -> Unit
|
||||||
|
) {
|
||||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
contract { callsInPlace(block) }
|
||||||
@kotlin.internal.LowPriorityInOverloadResolution
|
getExtensions(extensionPoint).forEach { registry ->
|
||||||
internal inline fun <T : Extension> ExtensionPoint<out T>.withExtensions(block: T.(plugin: Plugin?) -> Unit) {
|
val plugin = registry.plugin
|
||||||
contract {
|
val extension = registry.extension
|
||||||
callsInPlace(block)
|
|
||||||
}
|
|
||||||
for ((plugin, extension) in this.getExtensions()) {
|
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
block.invoke(extension, plugin)
|
block.invoke(registry, registry.extension)
|
||||||
}.getOrElse { throwable ->
|
}.getOrElse { throwable ->
|
||||||
throwExtensionException(extension, plugin, throwable)
|
extensionPoint.throwExtensionException(extension, plugin, throwable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline fun <reified E : SingletonExtension<*>> ExtensionPoint<out E>.findSingleton(builtin: E): E =
|
internal inline fun <T : Extension, E> foldExtensions(
|
||||||
findSingleton(E::class, builtin)
|
extensionPoint: ExtensionPoint<T>,
|
||||||
|
|
||||||
internal fun <E : SingletonExtension<*>> ExtensionPoint<out E>.findSingleton(type: KClass<E>, builtin: E): E {
|
|
||||||
val candidates = this.getExtensions()
|
|
||||||
return when (candidates.size) {
|
|
||||||
0 -> builtin
|
|
||||||
1 -> candidates.single().extension
|
|
||||||
else -> SingletonExtensionSelector.instance.selectSingleton(type, candidates) ?: builtin
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal inline fun <reified E : SingletonExtension<T>, T> ExtensionPoint<out E>.findSingletonInstance(noinline default: () -> T): T =
|
|
||||||
findSingletonInstance(E::class, default)
|
|
||||||
|
|
||||||
internal fun <E : SingletonExtension<T>, T> ExtensionPoint<out E>.findSingletonInstance(
|
|
||||||
type: KClass<E>,
|
|
||||||
default: () -> T,
|
|
||||||
): T {
|
|
||||||
val candidates = this.getExtensions()
|
|
||||||
return when (candidates.size) {
|
|
||||||
0 -> default()
|
|
||||||
1 -> candidates.single().extension.instance
|
|
||||||
else -> SingletonExtensionSelector.instance.selectSingleton(type, candidates)?.instance ?: default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal inline fun <T : Extension, E> ExtensionPoint<out T>.foldExtensions(
|
|
||||||
initial: E,
|
initial: E,
|
||||||
block: (acc: E, extension: T) -> E,
|
block: (acc: E, extension: T) -> E,
|
||||||
): E {
|
): E {
|
||||||
contract {
|
contract { callsInPlace(block) }
|
||||||
callsInPlace(block)
|
|
||||||
}
|
|
||||||
var e: E = initial
|
var e: E = initial
|
||||||
for ((plugin, extension) in this.getExtensions()) {
|
getExtensions(extensionPoint).forEach { registry ->
|
||||||
|
val plugin = registry.plugin
|
||||||
|
val extension = registry.extension
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
e = block.invoke(e, extension)
|
e = block.invoke(e, extension)
|
||||||
}.getOrElse { throwable ->
|
}.getOrElse { throwable ->
|
||||||
throwExtensionException(extension, plugin, throwable)
|
extensionPoint.throwExtensionException(extension, plugin, throwable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return e
|
return e
|
||||||
@ -153,52 +129,38 @@ internal abstract class AbstractConcurrentComponentStorage : ComponentStorage {
|
|||||||
extension: T,
|
extension: T,
|
||||||
plugin: Plugin?,
|
plugin: Plugin?,
|
||||||
throwable: Throwable,
|
throwable: Throwable,
|
||||||
) {
|
): Nothing {
|
||||||
throw ExtensionException(
|
throw ExtensionException(
|
||||||
"Exception while executing extension '${extension.kClassQualifiedNameOrTip}' provided by plugin '${plugin?.name ?: "<builtin>"}', registered for '${this.extensionType.qualifiedName}'",
|
"Exception while executing extension '${extension.kClassQualifiedNameOrTip}' provided by plugin '${plugin?.name ?: "<builtin>"}', registered for '${this.extensionType.qualifiedName}'",
|
||||||
throwable
|
throwable
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline fun <T : Extension> ExtensionPoint<T>.useExtensions(block: (extension: T) -> Unit): Unit =
|
override fun <E : Extension> contribute(
|
||||||
withExtensions(block)
|
extensionPoint: ExtensionPoint<E>,
|
||||||
|
|
||||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
|
||||||
@kotlin.internal.LowPriorityInOverloadResolution
|
|
||||||
internal inline fun <T : Extension> ExtensionPoint<T>.useExtensions(block: (extension: T, plugin: Plugin?) -> Unit): Unit =
|
|
||||||
withExtensions(block)
|
|
||||||
|
|
||||||
override fun <T : Extension> contribute(
|
|
||||||
extensionPoint: ExtensionPoint<T>,
|
|
||||||
plugin: Plugin,
|
plugin: Plugin,
|
||||||
extensionInstance: T,
|
extensionInstance: E,
|
||||||
) {
|
) {
|
||||||
instances.getOrPut(extensionPoint, ::CopyOnWriteArraySet).add(DataExtensionRegistry(plugin, extensionInstance))
|
registerExtension(extensionPoint, ExtensionRegistryImpl(plugin) { extensionInstance })
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmName("contribute1")
|
override fun <E : Extension> contributeConsole(extensionPoint: ExtensionPoint<E>, lazyInstance: () -> E) {
|
||||||
fun <T : Extension> contribute(
|
registerExtension(extensionPoint, ExtensionRegistryImpl(null, lazyInstance))
|
||||||
extensionPoint: ExtensionPoint<T>,
|
|
||||||
plugin: Plugin?,
|
|
||||||
extensionInstance: T,
|
|
||||||
) {
|
|
||||||
instances.getOrPut(extensionPoint, ::CopyOnWriteArraySet).add(DataExtensionRegistry(plugin, extensionInstance))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <T : Extension> contribute(
|
override fun <E : Extension> contribute(
|
||||||
extensionPoint: ExtensionPoint<T>,
|
extensionPoint: ExtensionPoint<E>,
|
||||||
plugin: Plugin,
|
plugin: Plugin,
|
||||||
lazyInstance: () -> T,
|
lazyInstance: () -> E,
|
||||||
) {
|
) {
|
||||||
instances.getOrPut(extensionPoint, ::CopyOnWriteArraySet).add(LazyExtensionRegistry(plugin, lazyInstance))
|
registerExtension(extensionPoint, ExtensionRegistryImpl(plugin, lazyInstance))
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmName("contribute1")
|
override fun <E : Extension> getExtensions(extensionPoint: ExtensionPoint<E>): Sequence<ExtensionRegistry<E>> {
|
||||||
fun <T : Extension> contribute(
|
return getRegistries(extensionPoint).asSequence()
|
||||||
extensionPoint: ExtensionPoint<T>,
|
}
|
||||||
plugin: Plugin?,
|
|
||||||
lazyInstance: () -> T,
|
override fun <E : Extension> getExtensionsStream(extensionPoint: ExtensionPoint<E>): Stream<ExtensionRegistry<E>> {
|
||||||
) {
|
return getRegistries(extensionPoint).asStream()
|
||||||
instances.getOrPut(extensionPoint, ::CopyOnWriteArraySet).add(LazyExtensionRegistry(plugin, lazyInstance))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
*
|
*
|
||||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
@ -18,9 +18,16 @@ import net.mamoe.mirai.console.extensions.SingletonExtensionSelector
|
|||||||
import net.mamoe.mirai.console.internal.data.kClassQualifiedName
|
import net.mamoe.mirai.console.internal.data.kClassQualifiedName
|
||||||
import net.mamoe.mirai.console.plugin.name
|
import net.mamoe.mirai.console.plugin.name
|
||||||
import net.mamoe.mirai.console.util.ConsoleInput
|
import net.mamoe.mirai.console.util.ConsoleInput
|
||||||
|
import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||||
import net.mamoe.mirai.utils.info
|
import net.mamoe.mirai.utils.info
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
@Deprecated(
|
||||||
|
"Order of extensions is not determined by its priority property since 2.11. SingletonExtensionSelector is not needed anymore. ",
|
||||||
|
level = DeprecationLevel.WARNING
|
||||||
|
)
|
||||||
|
@DeprecatedSinceMirai(warningSince = "2.11")
|
||||||
internal object SingletonExtensionSelectorImpl : SingletonExtensionSelector {
|
internal object SingletonExtensionSelectorImpl : SingletonExtensionSelector {
|
||||||
|
|
||||||
internal val config: SaveData = SaveData()
|
internal val config: SaveData = SaveData()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
*
|
*
|
||||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
@ -14,6 +14,7 @@ import net.mamoe.mirai.console.data.AutoSavePluginConfig
|
|||||||
import net.mamoe.mirai.console.data.PluginDataExtensions
|
import net.mamoe.mirai.console.data.PluginDataExtensions
|
||||||
import net.mamoe.mirai.console.data.PluginDataExtensions.withDefault
|
import net.mamoe.mirai.console.data.PluginDataExtensions.withDefault
|
||||||
import net.mamoe.mirai.console.data.value
|
import net.mamoe.mirai.console.data.value
|
||||||
|
import net.mamoe.mirai.console.extensions.PermissionServiceProvider
|
||||||
import net.mamoe.mirai.console.permission.*
|
import net.mamoe.mirai.console.permission.*
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.util.concurrent.CopyOnWriteArraySet
|
import java.util.concurrent.CopyOnWriteArraySet
|
||||||
@ -100,6 +101,12 @@ internal class AllDenyPermissionService : PermissionService<PermissionImpl> {
|
|||||||
internal class BuiltInPermissionService : AbstractConcurrentPermissionService<PermissionImpl>(),
|
internal class BuiltInPermissionService : AbstractConcurrentPermissionService<PermissionImpl>(),
|
||||||
PermissionService<PermissionImpl> {
|
PermissionService<PermissionImpl> {
|
||||||
|
|
||||||
|
class Provider : PermissionServiceProvider {
|
||||||
|
override val instance: PermissionService<*> by lazy {
|
||||||
|
BuiltInPermissionService()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override val permissionType: KClass<PermissionImpl>
|
override val permissionType: KClass<PermissionImpl>
|
||||||
get() = PermissionImpl::class
|
get() = PermissionImpl::class
|
||||||
override val permissions: ConcurrentHashMap<PermissionId, PermissionImpl> = ConcurrentHashMap()
|
override val permissions: ConcurrentHashMap<PermissionId, PermissionImpl> = ConcurrentHashMap()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
*
|
*
|
||||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
@ -160,12 +160,10 @@ internal class PluginManagerImpl(
|
|||||||
|
|
||||||
internal fun initExternalPluginLoaders(): Int {
|
internal fun initExternalPluginLoaders(): Int {
|
||||||
var count = 0
|
var count = 0
|
||||||
GlobalComponentStorage.run {
|
GlobalComponentStorage.useEachExtensions(PluginLoaderProvider) {
|
||||||
PluginLoaderProvider.useExtensions { ext, plugin ->
|
logger.info { "Loaded PluginLoader ${extension.instance} from ${plugin?.name ?: "<builtin>"}" }
|
||||||
logger.info { "Loaded PluginLoader ${ext.instance} from ${plugin?.name ?: "<builtin>"}" }
|
_pluginLoaders.add(extension.instance)
|
||||||
_pluginLoaders.add(ext.instance)
|
count++
|
||||||
count++
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||||
*
|
*
|
||||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* 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/master/LICENSE
|
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:Suppress("NOTHING_TO_INLINE", "unused", "MemberVisibilityCanBePrivate")
|
@file:Suppress("NOTHING_TO_INLINE", "unused", "MemberVisibilityCanBePrivate")
|
||||||
@ -13,7 +13,9 @@ package net.mamoe.mirai.console.permission
|
|||||||
|
|
||||||
import net.mamoe.mirai.console.compiler.common.ResolveContext
|
import net.mamoe.mirai.console.compiler.common.ResolveContext
|
||||||
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.COMMAND_NAME
|
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.COMMAND_NAME
|
||||||
|
import net.mamoe.mirai.console.extension.instance
|
||||||
import net.mamoe.mirai.console.extensions.PermissionServiceProvider
|
import net.mamoe.mirai.console.extensions.PermissionServiceProvider
|
||||||
|
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
|
||||||
import net.mamoe.mirai.console.internal.permission.checkType
|
import net.mamoe.mirai.console.internal.permission.checkType
|
||||||
import net.mamoe.mirai.console.permission.Permission.Companion.parentsWithSelf
|
import net.mamoe.mirai.console.permission.Permission.Companion.parentsWithSelf
|
||||||
import net.mamoe.mirai.console.plugin.Plugin
|
import net.mamoe.mirai.console.plugin.Plugin
|
||||||
@ -140,14 +142,12 @@ public interface PermissionService<P : Permission> {
|
|||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
/**
|
/**
|
||||||
* [PermissionService] 实例
|
* 选用的 [PermissionService] 实例.
|
||||||
*
|
|
||||||
* @see PermissionServiceProvider.selectedInstance
|
|
||||||
*/
|
*/
|
||||||
@get:JvmName("getInstance")
|
@get:JvmName("getInstance")
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
public val INSTANCE: PermissionService<out Permission>
|
public val INSTANCE: PermissionService<out Permission>
|
||||||
get() = PermissionServiceProvider.selectedInstance
|
get() = GlobalComponentStorage.getPreferredExtension(PermissionServiceProvider).instance
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取一个权限, 失败时抛出 [NoSuchElementException]
|
* 获取一个权限, 失败时抛出 [NoSuchElementException]
|
||||||
|
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2022 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.extension
|
||||||
|
|
||||||
|
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
|
||||||
|
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorageImpl
|
||||||
|
import net.mamoe.mirai.console.testFramework.AbstractConsoleInstanceTest
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
internal class GlobalComponentStorageTest : AbstractConsoleInstanceTest() {
|
||||||
|
class MyInstance
|
||||||
|
|
||||||
|
class MyExtension(override val instance: MyInstance, override val priority: Int) : InstanceExtension<MyInstance> {
|
||||||
|
companion object EP : AbstractInstanceExtensionPoint<MyExtension, MyInstance>(MyExtension::class)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `can register`() {
|
||||||
|
GlobalComponentStorage.contributeConsole(MyExtension, MyExtension(MyInstance(), 1))
|
||||||
|
GlobalComponentStorage.contributeConsole(MyExtension, MyExtension(MyInstance(), 2))
|
||||||
|
GlobalComponentStorage.getExtensionsList(MyExtension).run {
|
||||||
|
assertEquals(2, size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `can contribute`() {
|
||||||
|
GlobalComponentStorage.contribute(MyExtension, mockPlugin, MyExtension(MyInstance(), 1))
|
||||||
|
GlobalComponentStorage.contribute(MyExtension, mockPlugin, MyExtension(MyInstance(), 2))
|
||||||
|
GlobalComponentStorage.getExtensionsList(MyExtension).run {
|
||||||
|
assertEquals(2, size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `can sort by priority`() {
|
||||||
|
GlobalComponentStorage.contributeConsole(MyExtension, MyExtension(MyInstance(), 1))
|
||||||
|
GlobalComponentStorage.contributeConsole(MyExtension, MyExtension(MyInstance(), 2))
|
||||||
|
GlobalComponentStorage.getExtensionsList(MyExtension).run {
|
||||||
|
assertEquals(2, size)
|
||||||
|
assertEquals(2, first().extension.priority)
|
||||||
|
assertEquals(1, get(1).extension.priority)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `can sort by priority 2`() {
|
||||||
|
GlobalComponentStorage.contributeConsole(MyExtension, MyExtension(MyInstance(), 2))
|
||||||
|
GlobalComponentStorage.contributeConsole(MyExtension, MyExtension(MyInstance(), 1))
|
||||||
|
GlobalComponentStorage.getExtensionsList(MyExtension).run {
|
||||||
|
assertEquals(2, size)
|
||||||
|
assertEquals(2, first().extension.priority)
|
||||||
|
assertEquals(1, get(1).extension.priority)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `can fold`() {
|
||||||
|
GlobalComponentStorage.contributeConsole(MyExtension, MyExtension(MyInstance(), 2))
|
||||||
|
GlobalComponentStorage.contributeConsole(MyExtension, MyExtension(MyInstance(), 1))
|
||||||
|
val list = GlobalComponentStorage.foldExtensions(MyExtension, listOf<MyExtension>()) { acc, extension ->
|
||||||
|
acc + extension
|
||||||
|
}
|
||||||
|
assertEquals(2, list.size)
|
||||||
|
assertEquals(2, list.first().priority)
|
||||||
|
assertEquals(1, list[1].priority)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T : Extension> GlobalComponentStorageImpl.getExtensionsList(ep: ExtensionPoint<T>): List<ExtensionRegistry<T>> {
|
||||||
|
return getExtensions(ep).toList()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user