diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt index f2e43d769..317efebcd 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt @@ -21,10 +21,10 @@ import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start import net.mamoe.mirai.console.extension.GlobalComponentStorage import net.mamoe.mirai.console.extensions.BotConfigurationAlterer import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge -import net.mamoe.mirai.console.plugin.PluginLoader import net.mamoe.mirai.console.plugin.PluginManager import net.mamoe.mirai.console.plugin.center.PluginCenter import net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader +import net.mamoe.mirai.console.plugin.loader.PluginLoader import net.mamoe.mirai.console.util.ConsoleExperimentalApi import net.mamoe.mirai.console.util.ConsoleInternalApi import net.mamoe.mirai.console.util.CoroutineScopeUtils.childScopeContext @@ -68,7 +68,7 @@ public interface MiraiConsole : CoroutineScope { * * @return 不可变 [List] ([java.util.Collections.unmodifiableList]) */ - public val builtInPluginLoaders: List> + public val builtInPluginLoaders: List>> /** * 此 Console 后端构建时间 @@ -80,6 +80,7 @@ public interface MiraiConsole : CoroutineScope { */ public val version: Semver + @ConsoleExperimentalApi public val pluginCenter: PluginCenter diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleImplementation.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleImplementation.kt index eb4488e80..0090bcc7a 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleImplementation.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleImplementation.kt @@ -18,8 +18,8 @@ import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start import net.mamoe.mirai.console.command.ConsoleCommandSender import net.mamoe.mirai.console.data.PluginDataStorage import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge -import net.mamoe.mirai.console.plugin.PluginLoader import net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader +import net.mamoe.mirai.console.plugin.loader.PluginLoader import net.mamoe.mirai.console.util.ConsoleInput import net.mamoe.mirai.message.data.Message import net.mamoe.mirai.utils.BotConfiguration @@ -76,7 +76,7 @@ public interface MiraiConsoleImplementation : CoroutineScope { * * @return 不可变的 [List], [Collections.unmodifiableList] */ - public val builtInPluginLoaders: List> + public val builtInPluginLoaders: List>> /** * 由 Kotlin 用户实现 @@ -120,8 +120,8 @@ public interface MiraiConsoleImplementation : CoroutineScope { public val consoleCommandSender: ConsoleCommandSenderImpl - public val dataStorageForJarPluginLoader: PluginDataStorage - public val configStorageForJarPluginLoader: PluginDataStorage + public val dataStorageForJvmPluginLoader: PluginDataStorage + public val configStorageForJvmPluginLoader: PluginDataStorage public val dataStorageForBuiltIns: PluginDataStorage public val configStorageForBuiltIns: PluginDataStorage diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extension/ExtensionPoint.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extension/ExtensionPoint.kt index 6fda56d81..efe62a988 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extension/ExtensionPoint.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extension/ExtensionPoint.kt @@ -11,7 +11,7 @@ package net.mamoe.mirai.console.extension -import net.mamoe.mirai.console.plugin.PluginLoader +import net.mamoe.mirai.console.plugin.loader.PluginLoader import net.mamoe.mirai.console.util.ConsoleExperimentalApi import kotlin.reflect.KClass import kotlin.reflect.full.isSubclassOf 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 cf2271981..4e6d9c41d 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 @@ -2,7 +2,7 @@ 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.loader.PluginLoader /** * 提供扩展 [PluginLoader] 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 1170d35cc..d063c1059 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 @@ -42,10 +42,10 @@ import net.mamoe.mirai.console.internal.util.autoHexToBytes import net.mamoe.mirai.console.permission.PermissionService import net.mamoe.mirai.console.permission.PermissionService.Companion.grantPermission import net.mamoe.mirai.console.permission.RootPermission -import net.mamoe.mirai.console.plugin.PluginLoader import net.mamoe.mirai.console.plugin.PluginManager import net.mamoe.mirai.console.plugin.center.PluginCenter import net.mamoe.mirai.console.plugin.jvm.AbstractJvmPlugin +import net.mamoe.mirai.console.plugin.loader.PluginLoader import net.mamoe.mirai.console.util.ConsoleExperimentalApi import net.mamoe.mirai.console.util.ConsoleInput import net.mamoe.mirai.utils.* @@ -74,11 +74,11 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI createLogger("main") } override val coroutineContext: CoroutineContext by instance::coroutineContext - override val builtInPluginLoaders: List> by instance::builtInPluginLoaders + override val builtInPluginLoaders: List>> by instance::builtInPluginLoaders override val consoleCommandSender: MiraiConsoleImplementation.ConsoleCommandSenderImpl by instance::consoleCommandSender - override val dataStorageForJarPluginLoader: PluginDataStorage by instance::dataStorageForJarPluginLoader - override val configStorageForJarPluginLoader: PluginDataStorage by instance::configStorageForJarPluginLoader + override val dataStorageForJvmPluginLoader: PluginDataStorage by instance::dataStorageForJvmPluginLoader + override val configStorageForJvmPluginLoader: PluginDataStorage by instance::configStorageForJvmPluginLoader override val dataStorageForBuiltIns: PluginDataStorage by instance::dataStorageForBuiltIns override val configStorageForBuiltIns: PluginDataStorage by instance::configStorageForBuiltIns override val consoleInput: ConsoleInput by instance::consoleInput diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/plugin/BuiltInJvmPluginLoaderImpl.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/plugin/BuiltInJvmPluginLoaderImpl.kt index 947d3a846..63397ed3e 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/plugin/BuiltInJvmPluginLoaderImpl.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/plugin/BuiltInJvmPluginLoaderImpl.kt @@ -17,9 +17,9 @@ import net.mamoe.mirai.console.data.PluginDataStorage import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge import net.mamoe.mirai.console.internal.util.PluginServiceHelper.findServices import net.mamoe.mirai.console.internal.util.PluginServiceHelper.loadAllServices -import net.mamoe.mirai.console.plugin.AbstractFilePluginLoader -import net.mamoe.mirai.console.plugin.PluginLoadException import net.mamoe.mirai.console.plugin.jvm.* +import net.mamoe.mirai.console.plugin.loader.AbstractFilePluginLoader +import net.mamoe.mirai.console.plugin.loader.PluginLoadException import net.mamoe.mirai.console.util.CoroutineScopeUtils.childScope import net.mamoe.mirai.utils.MiraiLogger import java.io.File @@ -28,25 +28,24 @@ import java.util.concurrent.ConcurrentHashMap internal object BuiltInJvmPluginLoaderImpl : AbstractFilePluginLoader(".jar"), - CoroutineScope by MiraiConsole.childScope("JarPluginLoader", CoroutineExceptionHandler { _, throwable -> + CoroutineScope by MiraiConsole.childScope("JvmPluginLoader", CoroutineExceptionHandler { _, throwable -> BuiltInJvmPluginLoaderImpl.logger.error("Unhandled Jar plugin exception: ${throwable.message}", throwable) }), JvmPluginLoader { override val configStorage: PluginDataStorage - get() = MiraiConsoleImplementationBridge.configStorageForJarPluginLoader + get() = MiraiConsoleImplementationBridge.configStorageForJvmPluginLoader @JvmStatic internal val logger: MiraiLogger = MiraiConsole.createLogger(JvmPluginLoader::class.simpleName!!) override val dataStorage: PluginDataStorage - get() = MiraiConsoleImplementationBridge.dataStorageForJarPluginLoader + get() = MiraiConsoleImplementationBridge.dataStorageForJvmPluginLoader internal val classLoaders: MutableList = mutableListOf() @Suppress("EXTENSION_SHADOWED_BY_MEMBER") // doesn't matter - override val JvmPlugin.description: JvmPluginDescription - get() = this.description + override fun getPluginDescription(plugin: JvmPlugin): JvmPluginDescription = plugin.description private val pluginFileToInstanceMap: MutableMap = ConcurrentHashMap() 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 fef019555..f6776bd8f 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 @@ -18,10 +18,14 @@ import net.mamoe.mirai.console.extension.GlobalComponentStorage import net.mamoe.mirai.console.extensions.PluginLoaderProvider import net.mamoe.mirai.console.internal.data.cast import net.mamoe.mirai.console.internal.data.mkdir -import net.mamoe.mirai.console.plugin.* +import net.mamoe.mirai.console.plugin.Plugin +import net.mamoe.mirai.console.plugin.PluginManager import net.mamoe.mirai.console.plugin.description.PluginDependency import net.mamoe.mirai.console.plugin.description.PluginDescription import net.mamoe.mirai.console.plugin.jvm.JvmPlugin +import net.mamoe.mirai.console.plugin.loader.PluginLoadException +import net.mamoe.mirai.console.plugin.loader.PluginLoader +import net.mamoe.mirai.console.plugin.name import net.mamoe.mirai.console.util.CoroutineScopeUtils.childScope import net.mamoe.mirai.utils.info import java.io.File @@ -39,8 +43,9 @@ internal object PluginManagerImpl : PluginManager, CoroutineScope by MiraiConsol @Suppress("ObjectPropertyName") private val _pluginLoaders: MutableList> by lazy { - MiraiConsole.builtInPluginLoaders.toMutableList() + builtInLoaders.toMutableList() } + private val logger = MiraiConsole.createLogger("plugin") @JvmField @@ -48,17 +53,18 @@ internal object PluginManagerImpl : PluginManager, CoroutineScope by MiraiConsol CopyOnWriteArrayList() // write operations are mostly performed on init override val plugins: List get() = resolvedPlugins.toList() - override val builtInLoaders: List> - get() = MiraiConsole.builtInPluginLoaders + override val builtInLoaders: List> by lazy { + MiraiConsole.builtInPluginLoaders.map { it.value } + } override val pluginLoaders: List> get() = _pluginLoaders.toList() override val Plugin.description: PluginDescription get() = if (this is JvmPlugin) { - this.safeLoader.getDescription(this) + this.safeLoader.getPluginDescription(this) } else resolvedPlugins.firstOrNull { it == this } ?.loader?.cast>() - ?.getDescription(this) + ?.getPluginDescription(this) ?: error("Plugin is unloaded") @@ -76,10 +82,10 @@ internal object PluginManagerImpl : PluginManager, CoroutineScope by MiraiConsol resolvedPlugins.add(plugin) }.fold( onSuccess = { - logger.info { "Successfully loaded plugin ${plugin.description.name}" } + logger.info { "Successfully loaded plugin ${getPluginDescription(plugin).name}" } }, onFailure = { - logger.info { "Cannot load plugin ${plugin.description.name}" } + logger.info { "Cannot load plugin ${getPluginDescription(plugin).name}" } throw it } ) 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 d0f95888c..55a00f667 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 @@ -19,6 +19,7 @@ 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.jvm.JvmPlugin +import net.mamoe.mirai.console.plugin.loader.PluginLoader /** * 表示一个 mirai-console 插件. @@ -51,7 +52,7 @@ public interface Plugin : CommandOwner { /** * 获取 [PluginDescription] */ -public inline val Plugin.description: PluginDescription get() = this.safeLoader.getDescription(this) +public inline val Plugin.description: PluginDescription get() = this.safeLoader.getPluginDescription(this) /** * 获取 [PluginDescription.name`] diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginManager.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginManager.kt index 6b8970099..309f5acc1 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginManager.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginManager.kt @@ -14,6 +14,7 @@ package net.mamoe.mirai.console.plugin import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.internal.plugin.PluginManagerImpl import net.mamoe.mirai.console.plugin.description.PluginDescription +import net.mamoe.mirai.console.plugin.loader.PluginLoader import java.io.File import java.nio.file.Path @@ -102,7 +103,7 @@ public interface PluginManager { public val pluginLoaders: List> /** - * 获取插件的 [描述][PluginDescription], 通过 [PluginLoader.getDescription] + * 获取插件的 [描述][PluginDescription], 通过 [PluginLoader.getPluginDescription] */ public val Plugin.description: PluginDescription diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/center/PluginCenter.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/center/PluginCenter.kt index 0f1791400..9e5979319 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/center/PluginCenter.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/center/PluginCenter.kt @@ -14,6 +14,9 @@ import kotlinx.serialization.Serializable import net.mamoe.mirai.console.util.ConsoleExperimentalApi import java.io.File +/** + * 插件中心, 计划实现中 + */ @ConsoleExperimentalApi public interface PluginCenter { @@ -29,7 +32,7 @@ public interface PluginCenter { val author: String, val description: String, val tags: List, - val commands: List + val commands: List, ) @ConsoleExperimentalApi @@ -48,7 +51,7 @@ public interface PluginCenter { val usage: String, val vcs: String, val commands: List, - val changeLog: List + val changeLog: List, ) /** diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/IllegalPluginDescriptionException.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/IllegalPluginDescriptionException.kt index 1083259ce..d2a05199e 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/IllegalPluginDescriptionException.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/IllegalPluginDescriptionException.kt @@ -1,5 +1,21 @@ +/* + * Copyright 2019-2020 Mamoe Technologies and contributors. + * + * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. + * Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +@file:Suppress("unused") + package net.mamoe.mirai.console.plugin.description +/** + * 在检查到非法 [PluginDescription] 时抛出. + * + * @see PluginDescription.checkPluginDescription + */ public class IllegalPluginDescriptionException : RuntimeException { public constructor() : super() public constructor(message: String?) : super(message) 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 301c04b97..7e90ebe72 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 @@ -11,7 +11,6 @@ package net.mamoe.mirai.console.plugin.description import com.vdurmont.semver4j.Semver import net.mamoe.mirai.console.plugin.Plugin -import net.mamoe.mirai.console.plugin.PluginLoadException /** @@ -21,34 +20,40 @@ import net.mamoe.mirai.console.plugin.PluginLoadException */ public interface PluginDescription { /** - * 插件 ID, 必须全英文, 仅允许英文字母, '-', '_', '.'. + * 插件 ID. * + * - 仅允许英文字母, '-', '_', '.'. 在内部操作处理时不区分大小写. * - 类似于 Java 包名, 插件 ID 需要 '域名.名称' 格式, 如 `net.mamoe.mirai.example-plugin` * - 域名和名称都是必须的 - * - '.' 不允许位于首位或末尾 - * - '-' 和 '_' 仅允许存在于两个英文字母之间 + * - 数字和符号都不允许位于首位 + * - '-' 和 '_' 仅允许存在于两个英文字母之间. 不推荐使用 '_'. 请参照 `org.example.mirai.plugin.my-example-plugin` 格式. + * + * 可使用 [ID_REGEX] 检验格式合法性. * * ID 在插件发布后就应该保持不变, 以便其他插件添加依赖. * - * 插件 ID 的域名和名称都不能完全是以下其中一个 ([FORBIDDEN_ID_WORDS]). + * 插件 ID 的域名和名称都不能完全是以下其中一个 ([FORBIDDEN_ID_NAMES]). * - "console" * - "main" * - "plugin" * - "config" * - "data" * + * ### 示例 + * - 合法 `net.mamoe.mirai.example-plugin` + * - 非法 `.example-plugin` * * ID 用于指令权限等一些内部处理 * - * @see FORBIDDEN_ID_LETTERS - * @see FORBIDDEN_ID_WORDS + * @see ID_REGEX + * @see FORBIDDEN_ID_NAMES */ public val id: String /** * 插件名称. 允许中文, 允许各类符号. * - * 插件名称不能完全是以下其中一种 ([FORBIDDEN_ID_WORDS]). + * 插件名称不能完全是以下其中一种 ([FORBIDDEN_ID_NAMES]). * - console * - main * - plugin @@ -57,8 +62,7 @@ public interface PluginDescription { * * 插件名称用于显示给用户. * - * @see FORBIDDEN_ID_LETTERS - * @see FORBIDDEN_ID_WORDS + * @see FORBIDDEN_ID_NAMES */ public val name: String @@ -103,8 +107,22 @@ public interface PluginDescription { public val dependencies: Set public companion object { - public val FORBIDDEN_ID_LETTERS: Array = "~!@#$%^&*()+/*<>{}|[]\\?".map(Char::toString).toTypedArray() - public val FORBIDDEN_ID_WORDS: Array = arrayOf("main", "console", "plugin", "config", "data") + /** + * [PluginDescription.id] 的合法 [Regex]. + * + * - Group 1: 域名 + * - Group 2: 名称 + * + * @see PluginDescription.id + */ + public val ID_REGEX: Regex = Regex("""([a-zA-Z]+[a-zA-Z0-9]*)\.([a-zA-Z]+[a-zA-Z0-9]*)""") + + /** + * 在 [PluginDescription.id] 和 [PluginDescription.name] 中禁止用的完全匹配名称列表. + * + * @see PluginDescription.id + */ + public val FORBIDDEN_ID_NAMES: Array = arrayOf("main", "console", "plugin", "config", "data") /** * 依次检查 [PluginDescription] 的 [PluginDescription.id], [PluginDescription.name], [PluginDescription.dependencies] 的合法性 @@ -126,50 +144,55 @@ public interface PluginDescription { } /** - * 检查 [PluginDescription.id] 的合法性. + * 检查 [PluginDescription.id] 的合法性. 忽略大小写. * * @throws IllegalPluginDescriptionException 当不合法时抛出. */ @Throws(IllegalPluginDescriptionException::class) public fun checkPluginId(id: String) { if (id.isBlank()) throw IllegalPluginDescriptionException("Plugin id cannot be blank") - if (id.count { it == '.' } < 2) throw IllegalPluginDescriptionException("'$id' is illegal. Plugin id must consist of both domain and name. ") + if (id.none { it == '.' }) throw IllegalPluginDescriptionException("'$id' is illegal. Plugin id must consist of both domain and name. ") - FORBIDDEN_ID_LETTERS.firstOrNull { it in id }?.let { illegal -> - throw IllegalPluginDescriptionException("Plugin id contains illegal char: $illegal.") + val lowercaseId = id.toLowerCase() + + if (ID_REGEX.matchEntire(id) == null) { + throw IllegalPluginDescriptionException("Plugin does not match regex '${ID_REGEX.pattern}'.") } - val idSections = id.split('.') - FORBIDDEN_ID_WORDS.firstOrNull { it in idSections }?.let { illegal -> + FORBIDDEN_ID_NAMES.firstOrNull { it == lowercaseId }?.let { illegal -> throw IllegalPluginDescriptionException("Plugin id contains illegal word: '$illegal'.") } } /** - * 检查 [PluginDescription.name] 的合法性. + * 检查 [PluginDescription.name] 的合法性. 忽略大小写. * * @throws IllegalPluginDescriptionException 当不合法时抛出. */ @Throws(IllegalPluginDescriptionException::class) public fun checkPluginName(name: String) { if (name.isBlank()) throw IllegalPluginDescriptionException("Plugin name cannot be blank") - FORBIDDEN_ID_WORDS.firstOrNull { it in name }?.let { illegal -> + val lowercaseName = name.toLowerCase() + FORBIDDEN_ID_NAMES.firstOrNull { it in lowercaseName }?.let { illegal -> throw IllegalPluginDescriptionException("Plugin name is illegal: '$illegal'.") } } /** - * 检查 [PluginDescription.dependencies] 的合法性. + * 检查 [PluginDescription.dependencies] 的合法性. 忽略大小写. * * @throws IllegalPluginDescriptionException 当不合法时抛出. */ @Throws(IllegalPluginDescriptionException::class) public fun checkDependencies(pluginId: String, dependencies: Set) { - if (dependencies.distinctBy { it.id }.size != dependencies.size) - throw PluginLoadException("Duplicated dependency detected: A plugin cannot depend on different versions of dependencies of the same id") + val lowercaseId = pluginId.toLowerCase() + val lowercaseDependencies = dependencies.mapTo(LinkedHashSet(dependencies.size)) { it.id.toLowerCase() } - if (dependencies.any { it.id == pluginId }) - throw PluginLoadException("Recursive dependency detected: A plugin cannot depend on itself") + if (lowercaseDependencies.size != dependencies.size) + throw IllegalPluginDescriptionException("Duplicated dependency detected: A plugin cannot depend on different versions of dependencies of the same id") + + if (lowercaseDependencies.any { it == lowercaseId }) + throw IllegalPluginDescriptionException("Recursive dependency detected: A plugin cannot depend on itself") } } } diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginLoader.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginLoader.kt index 1f4b90e33..66986ee9e 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginLoader.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginLoader.kt @@ -12,13 +12,16 @@ package net.mamoe.mirai.console.plugin.jvm import kotlinx.coroutines.CoroutineScope import net.mamoe.mirai.console.data.PluginDataStorage import net.mamoe.mirai.console.internal.plugin.BuiltInJvmPluginLoaderImpl -import net.mamoe.mirai.console.plugin.FilePluginLoader +import net.mamoe.mirai.console.plugin.loader.FilePluginLoader /** * 内建的 Jar (JVM) 插件加载器 */ public interface JvmPluginLoader : CoroutineScope, FilePluginLoader { - public override val fileSuffix: String get() = ".jar" + /** + * ".jar" + */ + public override val fileSuffix: String /** * [AbstractJvmPlugin.reloadPluginData] 默认使用的实例 @@ -32,7 +35,7 @@ public interface JvmPluginLoader : CoroutineScope, FilePluginLoader : PluginLoader { + /** + * 所支持的插件文件后缀, 含 '.', 不区分大小写. 如 [JvmPluginLoader] 为 ".jar" + */ + public val fileSuffix: String +} + +/** + * [FilePluginLoader] 的默认基础实现. + * + * @see FilePluginLoader + */ +public abstract class AbstractFilePluginLoader

( + /** + * 所支持的插件文件后缀, 含 '.', 不区分大小写. 如 [JvmPluginLoader] 为 ".jar" + */ + public override val fileSuffix: String, +) : FilePluginLoader { + private fun pluginsFilesSequence(): Sequence = + PluginManager.pluginsFolder.listFiles().orEmpty().asSequence() + .filter { it.isFile && it.name.endsWith(fileSuffix, ignoreCase = true) } + + /** + * 读取扫描到的后缀与 [fileSuffix] 相同的文件中的插件实例, 但不 [加载][PluginLoader.load] + */ + protected abstract fun Sequence.extractPlugins(): List

+ + public final override fun listPlugins(): List

= pluginsFilesSequence().extractPlugins() +} \ No newline at end of file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/loader/PluginLoadException.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/loader/PluginLoadException.kt new file mode 100644 index 000000000..ac6e6621b --- /dev/null +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/loader/PluginLoadException.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2019-2020 Mamoe Technologies and contributors. + * + * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. + * Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +@file:Suppress("unused") + +package net.mamoe.mirai.console.plugin.loader + +/** + * 在加载插件过程中遇到的意料之中的问题. + * + * @see PluginLoader.load + * @see PluginLoader.enable + * @see PluginLoader.disable + * @see PluginLoader.getPluginDescription + */ +public open class PluginLoadException : RuntimeException { + public constructor() : super() + public constructor(message: String?) : super(message) + public constructor(message: String?, cause: Throwable?) : super(message, cause) + public constructor(cause: Throwable?) : super(cause) +} \ No newline at end of file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginLoader.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/loader/PluginLoader.kt similarity index 54% rename from backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginLoader.kt rename to backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/loader/PluginLoader.kt index 5acc7ee43..9d7307c53 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginLoader.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/loader/PluginLoader.kt @@ -9,13 +9,14 @@ @file:Suppress("unused", "INAPPLICABLE_JVM_NAME", "NOTHING_TO_INLINE") -package net.mamoe.mirai.console.plugin +package net.mamoe.mirai.console.plugin.loader +import net.mamoe.mirai.console.plugin.Plugin +import net.mamoe.mirai.console.plugin.PluginManager import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.disable import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.enable import net.mamoe.mirai.console.plugin.description.PluginDescription import net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader -import java.io.File import java.util.* /** @@ -58,11 +59,10 @@ public interface PluginLoader

{ * @throws PluginLoadException 在加载插件遇到意料之中的错误时抛出 (如无法读取插件信息等). * * @see PluginDescription 插件描述 - * @see getDescription 无 receiver, 接受参数的版本. + * @see getPluginDescription 无 receiver, 接受参数的版本. */ - @get:JvmName("getPluginDescription") - @get:Throws(PluginLoadException::class) - public val P.description: D // Java signature: `public D getDescription(P)` + @Throws(PluginLoadException::class) + public fun getPluginDescription(plugin: P): D // Java signature: `public D getDescription(P)` /** * 主动加载一个插件 (实例), 但不 [启用][enable] 它. 返回加载成功的主类实例 @@ -100,86 +100,4 @@ public interface PluginLoader

{ */ @Throws(IllegalStateException::class, PluginLoadException::class) public fun disable(plugin: P) -} - -/** - * 获取此插件的描述. - * - * **实现细节**: 此函数只允许抛出 [PluginLoadException] 作为正常失败原因, 其他任意异常都属于意外错误. - * - * 若在 console 启动并加载所有插件的过程中, 本函数抛出异常, 则会放弃此插件的加载, 并影响依赖它的其他插件. - * - * @throws PluginLoadException 在加载插件遇到意料之中的错误时抛出 (如无法读取插件信息等). - * - * @see PluginDescription 插件描述 - * @see PluginLoader.description - */ -@Suppress("UNCHECKED_CAST") -@JvmSynthetic -public inline fun PluginLoader.getDescription(plugin: P): D = - plugin.description - -/** - * 在加载插件过程中遇到的意料之中的问题. - * - * @see PluginLoader.load - * @see PluginLoader.enable - * @see PluginLoader.disable - * @see PluginLoader.description - */ -public open class PluginLoadException : RuntimeException { - public constructor() : super() - public constructor(message: String?) : super(message) - public constructor(message: String?, cause: Throwable?) : super(message, cause) - public constructor(cause: Throwable?) : super(cause) -} - -/** - * ['/plugins'][PluginManager.pluginsPath] 目录中的插件的加载器. 每个加载器需绑定一个后缀. - * - * @see AbstractFilePluginLoader 默认基础实现 - * @see JvmPluginLoader 内建的 Jar (JVM) 插件加载器. - */ -public interface FilePluginLoader

: PluginLoader { - /** - * 所支持的插件文件后缀, 含 '.', 不区分大小写. 如 [JvmPluginLoader] 为 ".jar" - */ - public val fileSuffix: String -} - -/** - * [FilePluginLoader] 的默认基础实现. - * - * @see FilePluginLoader - */ -public abstract class AbstractFilePluginLoader

( - /** - * 所支持的插件文件后缀, 含 '.', 不区分大小写. 如 [JvmPluginLoader] 为 ".jar" - */ - public override val fileSuffix: String, -) : FilePluginLoader { - private fun pluginsFilesSequence(): Sequence = - PluginManager.pluginsFolder.listFiles().orEmpty().asSequence() - .filter { it.isFile && it.name.endsWith(fileSuffix, ignoreCase = true) } - - /** - * 读取扫描到的后缀与 [fileSuffix] 相同的文件中的插件实例, 但不 [加载][PluginLoader.load] - */ - protected abstract fun Sequence.extractPlugins(): List

- - public final override fun listPlugins(): List

= pluginsFilesSequence().extractPlugins() -} - - -// Not yet decided to make public API -internal class DeferredPluginLoader

( - initializer: () -> PluginLoader, -) : PluginLoader { - private val instance by lazy(initializer) - - override fun listPlugins(): List

= instance.run { listPlugins() } - override val P.description: D get() = instance.run { description } - override fun load(plugin: P) = instance.load(plugin) - override fun enable(plugin: P) = instance.enable(plugin) - override fun disable(plugin: P) = instance.disable(plugin) -} +} \ No newline at end of file diff --git a/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/TestMiraiConosle.kt b/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/TestMiraiConosle.kt index 0ab21192b..8afa90d9a 100644 --- a/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/TestMiraiConosle.kt +++ b/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/TestMiraiConosle.kt @@ -15,9 +15,8 @@ import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start import net.mamoe.mirai.console.command.CommandManager import net.mamoe.mirai.console.data.MemoryPluginDataStorage import net.mamoe.mirai.console.data.PluginDataStorage -import net.mamoe.mirai.console.plugin.DeferredPluginLoader -import net.mamoe.mirai.console.plugin.PluginLoader import net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader +import net.mamoe.mirai.console.plugin.loader.PluginLoader import net.mamoe.mirai.console.util.ConsoleExperimentalApi import net.mamoe.mirai.console.util.ConsoleInput import net.mamoe.mirai.console.util.ConsoleInternalApi @@ -48,7 +47,7 @@ fun initTestEnvironment() { get() = Semver("1.0.0") } - override val builtInPluginLoaders: List> = listOf(DeferredPluginLoader { JvmPluginLoader }) + override val builtInPluginLoaders: List>> = listOf(lazy { JvmPluginLoader }) override val consoleCommandSender: MiraiConsoleImplementation.ConsoleCommandSenderImpl = object : MiraiConsoleImplementation.ConsoleCommandSenderImpl { override suspend fun sendMessage(message: Message) { @@ -59,8 +58,8 @@ fun initTestEnvironment() { println(message) } } - override val dataStorageForJarPluginLoader: PluginDataStorage = MemoryPluginDataStorage() - override val configStorageForJarPluginLoader: PluginDataStorage = MemoryPluginDataStorage() + override val dataStorageForJvmPluginLoader: PluginDataStorage = MemoryPluginDataStorage() + override val configStorageForJvmPluginLoader: PluginDataStorage = MemoryPluginDataStorage() override val dataStorageForBuiltIns: PluginDataStorage = MemoryPluginDataStorage() override val configStorageForBuiltIns: PluginDataStorage = MemoryPluginDataStorage() diff --git a/docs/Commands.md b/docs/Commands.md index bde5b82d2..a1a9ce551 100644 --- a/docs/Commands.md +++ b/docs/Commands.md @@ -3,9 +3,9 @@ [`Plugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/Plugin.kt [`PluginDescription`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/PluginDescription.kt -[`PluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginLoader.kt +[`PluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/loader/PluginLoader.kt [`PluginManager`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginManager.kt -[`JarPluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JarPluginLoader.kt +[`JvmPluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginLoader.kt [`JvmPlugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPlugin.kt [`JvmPluginDescription`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginDescription.kt [`AbstractJvmPlugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/AbstractJvmPlugin.kt diff --git a/docs/PluginData.md b/docs/PluginData.md index 986421fe0..bde09d2c1 100644 --- a/docs/PluginData.md +++ b/docs/PluginData.md @@ -2,9 +2,9 @@ [`Plugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/Plugin.kt [`PluginDescription`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/PluginDescription.kt -[`PluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginLoader.kt +[`PluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/loader/PluginLoader.kt [`PluginManager`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginManager.kt -[`JarPluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JarPluginLoader.kt +[`JvmPluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginLoader.kt [`JvmPlugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPlugin.kt [`JvmPluginDescription`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginDescription.kt [`AbstractJvmPlugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/AbstractJvmPlugin.kt @@ -35,7 +35,6 @@ [`RawCommand`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/RawCommand.kt [`CommandManager`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt -[`BotManager`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/BotManager.kt [`Annotations`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/Annotations.kt [`ConsoleInput`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/ConsoleInput.kt [`JavaPluginScheduler`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JavaPluginScheduler.kt diff --git a/docs/Plugins.md b/docs/Plugins.md index 9e7a7a467..b89b4b0c9 100644 --- a/docs/Plugins.md +++ b/docs/Plugins.md @@ -2,9 +2,9 @@ [`Plugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/Plugin.kt [`PluginDescription`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/PluginDescription.kt -[`PluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginLoader.kt +[`PluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/loader/PluginLoader.kt [`PluginManager`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginManager.kt -[`JarPluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JarPluginLoader.kt +[`JvmPluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginLoader.kt [`JvmPlugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPlugin.kt [`JvmPluginDescription`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginDescription.kt [`AbstractJvmPlugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/AbstractJvmPlugin.kt @@ -63,7 +63,7 @@ interface Plugin : CommandOwner { // CommandOwner 是空的 interface ## JVM 平台插件接口 - [`JvmPlugin`] -所有的 JVM 插件都必须实现 [`JvmPlugin`](否则不会被 [`JarPluginLoader`] 加载)。 +所有的 JVM 插件都必须实现 [`JvmPlugin`](否则不会被 [`JvmPluginLoader`] 加载)。 Mirai Console 提供一些基础的实现,即 [`AbstractJvmPlugin`],并将 [`JvmPlugin`] 分为 [`KotlinPlugin`] 和 [`JavaPlugin`]。 ### 主类和描述 @@ -174,7 +174,7 @@ Mirai Console 不提供热加载和热卸载功能,所有插件只能在服务 #### 加载 -[`JarPluginLoader`] 调用插件的 `onLoad()`,在 `onLoad()` 正常返回后插件被认为成功加载。 +[`JvmPluginLoader`] 调用插件的 `onLoad()`,在 `onLoad()` 正常返回后插件被认为成功加载。 由于 `onLoad()` 只会被初始化一次,插件可以在该方法内进行一些*一次性*的*初始化*任务。 @@ -184,13 +184,13 @@ Mirai Console 不提供热加载和热卸载功能,所有插件只能在服务 #### 启用 -[`JarPluginLoader`] 调用插件的 `onEnable()`,意为启用一个插件。 +[`JvmPluginLoader`] 调用插件的 `onEnable()`,意为启用一个插件。 此时插件可以启动所有协程,事件监听,和其他任务。**但这些任务都应该拥有生命周期管理,详见 [任务生命周期管理](#任务生命周期管理)。** #### 禁用 -[`JarPluginLoader`] 调用插件的 `onDisable()`,意为禁用一个插件。 +[`JvmPluginLoader`] 调用插件的 `onDisable()`,意为禁用一个插件。 插件的任何类和对象都不会被卸载。「禁用」仅表示停止关闭所有正在进行的任务,保存所有数据,停止处理将来的数据。 diff --git a/docs/README.md b/docs/README.md index a46c1b636..99ad44576 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,7 +5,7 @@ ## 目录 - **[准备工作](#准备工作)** -- **[启动 Console](#Run.md)** +- **[启动 Console](Run.md)** ### 后端插件开发基础 @@ -29,10 +29,9 @@ [`JavaPluginScheduler`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JavaPluginScheduler.kt [`JvmPlugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPlugin.kt [`PluginConfig`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginConfig.kt -[`PluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginLoader.kt +[`PluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/loader/PluginLoader.kt [`ConsoleInput`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/ConsoleInput.kt [`PluginDataStorage`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginDataStorage.kt -[`BotManager`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/BotManager.kt [`Command`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt ## 准备工作 diff --git a/frontend/mirai-console-pure/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsoleImplementationPure.kt b/frontend/mirai-console-pure/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsoleImplementationPure.kt index ebe903c6f..14ec86af7 100644 --- a/frontend/mirai-console-pure/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsoleImplementationPure.kt +++ b/frontend/mirai-console-pure/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsoleImplementationPure.kt @@ -30,9 +30,8 @@ import net.mamoe.mirai.console.MiraiConsoleFrontEndDescription import net.mamoe.mirai.console.MiraiConsoleImplementation import net.mamoe.mirai.console.data.MultiFilePluginDataStorage import net.mamoe.mirai.console.data.PluginDataStorage -import net.mamoe.mirai.console.plugin.DeferredPluginLoader -import net.mamoe.mirai.console.plugin.PluginLoader import net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader +import net.mamoe.mirai.console.plugin.loader.PluginLoader import net.mamoe.mirai.console.pure.ConsoleInputImpl.requestInput import net.mamoe.mirai.console.util.ConsoleExperimentalApi import net.mamoe.mirai.console.util.ConsoleInput @@ -51,7 +50,6 @@ import java.time.Instant import java.time.LocalDateTime import java.time.ZoneId import java.time.format.DateTimeFormatter -import java.util.* /** * mirai-console-pure 后端实现 @@ -61,15 +59,13 @@ import java.util.* @ConsoleExperimentalApi class MiraiConsoleImplementationPure @JvmOverloads constructor( - override val rootPath: Path = Paths.get("."), - override val builtInPluginLoaders: List> = Collections.unmodifiableList( - listOf(DeferredPluginLoader { JvmPluginLoader }) - ), + override val rootPath: Path = Paths.get(".").toAbsolutePath(), + override val builtInPluginLoaders: List>> = listOf(lazy { JvmPluginLoader }), override val frontEndDescription: MiraiConsoleFrontEndDescription = ConsoleFrontEndDescImpl, override val consoleCommandSender: MiraiConsoleImplementation.ConsoleCommandSenderImpl = ConsoleCommandSenderImplPure, - override val dataStorageForJarPluginLoader: PluginDataStorage = MultiFilePluginDataStorage(rootPath.resolve("data")), + override val dataStorageForJvmPluginLoader: PluginDataStorage = MultiFilePluginDataStorage(rootPath.resolve("data")), override val dataStorageForBuiltIns: PluginDataStorage = MultiFilePluginDataStorage(rootPath.resolve("data")), - override val configStorageForJarPluginLoader: PluginDataStorage = MultiFilePluginDataStorage(rootPath.resolve("config")), + override val configStorageForJvmPluginLoader: PluginDataStorage = MultiFilePluginDataStorage(rootPath.resolve("config")), override val configStorageForBuiltIns: PluginDataStorage = MultiFilePluginDataStorage(rootPath.resolve("config")), ) : MiraiConsoleImplementation, CoroutineScope by CoroutineScope( NamedSupervisorJob("MiraiConsoleImplementationPure") +