From 74925ff6e8c883604270849745e32e8b3f0408b4 Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 31 Jul 2020 16:35:41 +0800 Subject: [PATCH] Public api stabilization: Separate PluginManager and its implementations; Add Setting extensions; Documentation updates --- backend/mirai-console/build.gradle.kts | 3 +- .../net/mamoe/mirai/console/MiraiConsole.kt | 6 +- .../console/MiraiConsoleImplementation.kt | 4 +- .../mirai/console/plugin/PluginLoader.kt | 3 +- .../mirai/console/plugin/PluginManager.kt | 216 ++---------------- .../mamoe/mirai/console/plugin/description.kt | 30 +-- .../console/plugin/jvm/PluginManagerImpl.kt | 193 ++++++++++++++++ .../mamoe/mirai/console/setting/Setting.kt | 17 +- .../mamoe/mirai/console/utils/BotManagers.kt | 10 +- .../mirai/console/utils/ResourceContainer.kt | 6 +- .../pure/MiraiConsoleImplementationPure.kt | 6 +- 11 files changed, 274 insertions(+), 220 deletions(-) create mode 100644 backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/PluginManagerImpl.kt diff --git a/backend/mirai-console/build.gradle.kts b/backend/mirai-console/build.gradle.kts index d76f2360b..6bc228587 100644 --- a/backend/mirai-console/build.gradle.kts +++ b/backend/mirai-console/build.gradle.kts @@ -1,6 +1,5 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import java.text.SimpleDateFormat -import java.util.* plugins { kotlin("jvm") version Versions.kotlinCompiler @@ -75,6 +74,8 @@ dependencies { api("com.vdurmont:semver4j:3.1.0") + //api(kotlinx("collections-immutable", Versions.collectionsImmutable)) + testApi("net.mamoe:mirai-core-qqandroid:${Versions.core}") testApi(kotlin("stdlib-jdk8")) testApi(kotlin("test")) 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 337799227..ae4d730b6 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 @@ -23,10 +23,10 @@ import net.mamoe.mirai.console.command.internal.InternalCommandManager import net.mamoe.mirai.console.command.primaryName import net.mamoe.mirai.console.plugin.PluginLoader import net.mamoe.mirai.console.plugin.PluginManager -import net.mamoe.mirai.console.plugin.PluginManagerImpl import net.mamoe.mirai.console.plugin.center.CuiPluginCenter import net.mamoe.mirai.console.plugin.center.PluginCenter import net.mamoe.mirai.console.plugin.jvm.JarPluginLoader +import net.mamoe.mirai.console.plugin.jvm.PluginManagerImpl import net.mamoe.mirai.console.setting.SettingStorage import net.mamoe.mirai.console.utils.ConsoleBuiltInSettingStorage import net.mamoe.mirai.console.utils.ConsoleExperimentalAPI @@ -64,7 +64,9 @@ public interface MiraiConsole : CoroutineScope { public val mainLogger: MiraiLogger /** - * 内建加载器列表, 一般需要包含 [JarPluginLoader] + * 内建加载器列表, 一般需要包含 [JarPluginLoader]. + * + * @return 不可变 [List] ([java.util.Collections.unmodifiableList]) */ public val builtInPluginLoaders: List> 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 2ff1c6277..961774f1a 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 @@ -55,7 +55,9 @@ public interface MiraiConsoleImplementation : CoroutineScope { public val mainLogger: MiraiLogger /** - * 内建加载器列表, 一般需要包含 [JarPluginLoader] + * 内建加载器列表, 一般需要包含 [JarPluginLoader]. + * + * @return 不可变的 [List] */ public val builtInPluginLoaders: List> 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/PluginLoader.kt index 1ec910364..1d78f04f6 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/PluginLoader.kt @@ -36,7 +36,7 @@ public interface PluginLoader

{ */ @get:JvmName("getPluginDescription") @get:Throws(PluginLoadException::class) - public val P.description: D // Java signature: `public P getDescription(P)` + public val P.description: D // Java signature: `public D getDescription(P)` /** * 加载一个插件 (实例), 但不 [启用][enable] 它. 返回加载成功的主类实例 @@ -50,6 +50,7 @@ public interface PluginLoader

{ public fun disable(plugin: P) } +@JvmSynthetic public inline fun PluginLoader.getDescription(plugin: P): D = plugin.description 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 674f33149..d519a3d52 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 @@ -11,30 +11,22 @@ package net.mamoe.mirai.console.plugin -import kotlinx.atomicfu.locks.withLock import net.mamoe.mirai.console.MiraiConsole -import net.mamoe.mirai.console.setting.internal.cast -import net.mamoe.mirai.utils.info +import net.mamoe.mirai.console.plugin.jvm.PluginManagerImpl import java.io.File -import java.util.concurrent.locks.ReentrantLock -// TODO: 2020/7/11 top-level or in PluginManager.companion? -public val Plugin.description: PluginDescription - get() = PluginManagerImpl.resolvedPlugins.firstOrNull { it == this } - ?.loader?.cast>() - ?.getDescription(this) - ?: error("Plugin is unloaded") - -@JvmSynthetic -public inline fun PluginLoader<*, *>.register(): Boolean = PluginManager.registerPluginLoader(this) - -@JvmSynthetic -public inline fun PluginLoader<*, *>.unregister(): Boolean = PluginManager.unregisterPluginLoader(this) - -// TODO: 2020/7/11 document +/** + * 插件管理器. + */ public interface PluginManager { + /** + * `$rootDir/plugins` + */ public val pluginsDir: File + /** + * `$rootDir/data` + */ public val pluginsDataFolder: File /** @@ -43,7 +35,9 @@ public interface PluginManager { public val plugins: List /** - * 内建的插件加载器列表. 由 [MiraiConsole] 初始化 + * 内建的插件加载器列表. 由 [MiraiConsole] 初始化. + * + * @return 不可变的 list. */ public val builtInLoaders: List> @@ -56,9 +50,20 @@ public interface PluginManager { public fun unregisterPluginLoader(loader: PluginLoader<*, *>): Boolean + /** + * 获取插件的 [描述][PluginDescription], 通过 [PluginLoader.getDescription] + */ + public val Plugin.description: PluginDescription + public companion object INSTANCE : PluginManager by PluginManagerImpl } +@JvmSynthetic +public inline fun PluginLoader<*, *>.register(): Boolean = PluginManager.registerPluginLoader(this) + +@JvmSynthetic +public inline fun PluginLoader<*, *>.unregister(): Boolean = PluginManager.unregisterPluginLoader(this) + public class PluginMissingDependencyException : PluginResolutionException { public constructor() : super() public constructor(message: String?) : super(message) @@ -71,175 +76,4 @@ public open class PluginResolutionException : Exception { public constructor(message: String?) : super(message) public constructor(message: String?, cause: Throwable?) : super(message, cause) public constructor(cause: Throwable?) : super(cause) -} - - -// internal - - -internal object PluginManagerImpl : PluginManager { - override val pluginsDir = File(MiraiConsole.rootDir, "plugins").apply { mkdir() } - override val pluginsDataFolder = File(MiraiConsole.rootDir, "data").apply { mkdir() } - - @Suppress("ObjectPropertyName") - private val _pluginLoaders: MutableList> = mutableListOf() - private val loadersLock: ReentrantLock = ReentrantLock() - private val logger = MiraiConsole.newLogger("PluginManager") - - @JvmField - internal val resolvedPlugins: MutableList = mutableListOf() - override val plugins: List - get() = resolvedPlugins.toList() - override val builtInLoaders: List> - get() = MiraiConsole.builtInPluginLoaders - override val pluginLoaders: List> - get() = _pluginLoaders.toList() - - override fun registerPluginLoader(loader: PluginLoader<*, *>): Boolean = loadersLock.withLock { - if (_pluginLoaders.any { it::class == loader }) { - return false - } - _pluginLoaders.add(loader) - } - - override fun unregisterPluginLoader(loader: PluginLoader<*, *>) = loadersLock.withLock { - _pluginLoaders.remove(loader) - } - - - // region LOADING - - private fun

PluginLoader.loadPluginNoEnable(description: D): P { - return kotlin.runCatching { - this.load(description).also { resolvedPlugins.add(it) } - }.fold( - onSuccess = { - logger.info { "Successfully loaded plugin ${description.name}" } - it - }, - onFailure = { - logger.info { "Cannot load plugin ${description.name}" } - throw it - } - ) - } - - private fun

PluginLoader.enablePlugin(plugin: Plugin) { - kotlin.runCatching { - @Suppress("UNCHECKED_CAST") - this.enable(plugin as P) - }.fold( - onSuccess = { - logger.info { "Successfully enabled plugin ${plugin.description.name}" } - }, - onFailure = { - logger.info { "Cannot enable plugin ${plugin.description.name}" } - throw it - } - ) - } - - /** - * STEPS: - * 1. 遍历插件列表, 使用 [builtInLoaders] 加载 [PluginKind.LOADER] 类型的插件 - * 2. [启动][PluginLoader.enable] 所有 [PluginKind.LOADER] 的插件 - * 3. 使用内建和所有插件提供的 [PluginLoader] 加载全部除 [PluginKind.LOADER] 外的插件列表. - * 4. 解决依赖并排序 - * 5. 依次 [PluginLoader.load] - * 但不 [PluginLoader.enable] - * - * @return [builtInLoaders] 可以加载的插件. 已经完成了 [PluginLoader.load], 但没有 [PluginLoader.enable] - */ - @Suppress("UNCHECKED_CAST") - @Throws(PluginMissingDependencyException::class) - internal fun loadEnablePlugins() { - (loadAndEnableLoaderProviders() + _pluginLoaders.listAllPlugins().flatMap { it.second }) - .sortByDependencies().loadAndEnableAllInOrder() - } - - private fun List.loadAndEnableAllInOrder() { - return this.map { (loader, desc) -> - loader to loader.loadPluginNoEnable(desc) - }.forEach { (loader, plugin) -> - loader.enablePlugin(plugin) - } - } - - /** - * @return [builtInLoaders] 可以加载的插件. 已经完成了 [PluginLoader.load], 但没有 [PluginLoader.enable] - */ - @Suppress("UNCHECKED_CAST") - @Throws(PluginMissingDependencyException::class) - private fun loadAndEnableLoaderProviders(): List { - val allDescriptions = - this.builtInLoaders.listAllPlugins() - .asSequence() - .onEach { (loader, descriptions) -> - loader as PluginLoader - - descriptions.filter { it.kind == PluginKind.LOADER }.sortByDependencies().loadAndEnableAllInOrder() - } - .flatMap { it.second.asSequence() } - - return allDescriptions.toList() - } - - private fun List>.listAllPlugins(): List, List>> { - return associateWith { loader -> loader.listPlugins().map { desc -> desc.wrapWith(loader) } }.toList() - } - - @Throws(PluginMissingDependencyException::class) - private fun List.sortByDependencies(): List { - val resolved = ArrayList(this.size) - - fun D.canBeLoad(): Boolean = this.dependencies.all { it.isOptional || it in resolved } - - fun List.consumeLoadable(): List { - val (canBeLoad, cannotBeLoad) = this.partition { it.canBeLoad() } - resolved.addAll(canBeLoad) - return cannotBeLoad - } - - fun List.filterIsMissing(): List = - this.filterNot { it.isOptional || it in resolved } - - tailrec fun List.doSort() { - if (this.isEmpty()) return - - val beforeSize = this.size - this.consumeLoadable().also { resultPlugins -> - check(resultPlugins.size < beforeSize) { - throw PluginMissingDependencyException(resultPlugins.joinToString("\n") { badPlugin -> - "Cannot load plugin ${badPlugin.name}, missing dependencies: ${ - badPlugin.dependencies.filterIsMissing() - .joinToString() - }" - }) - } - }.doSort() - } - - this.doSort() - return resolved - } - - // endregion -} - -internal data class PluginDescriptionWithLoader( - @JvmField val loader: PluginLoader<*, PluginDescription>, // easier type - @JvmField val delegate: PluginDescription -) : PluginDescription by delegate - -@Suppress("UNCHECKED_CAST") -internal fun PluginDescription.unwrap(): D = - if (this is PluginDescriptionWithLoader) this.delegate as D else this as D - -@Suppress("UNCHECKED_CAST") -internal fun PluginDescription.wrapWith(loader: PluginLoader<*, *>): PluginDescriptionWithLoader = - PluginDescriptionWithLoader( - loader as PluginLoader<*, PluginDescription>, this - ) - -internal operator fun List.contains(dependency: PluginDependency): Boolean = - any { it.name == dependency.name } +} \ No newline at end of file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description.kt index 76775f09c..1469b446e 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description.kt @@ -20,6 +20,21 @@ import net.mamoe.yamlkt.YamlDynamicSerializer import java.io.File +/** + * 插件描述 + */ +public interface PluginDescription { + public val kind: PluginKind + + public val name: String + public val author: String + public val version: Semver + public val info: String + + /** 此插件依赖的其他插件, 将会在这些插件加载之后加载此插件 */ + public val dependencies: List<@Serializable(with = PluginDependency.SmartSerializer::class) PluginDependency> +} + /** 插件类型 */ @Serializable(with = PluginKind.AsStringSerializer::class) public enum class PluginKind { @@ -39,21 +54,6 @@ public enum class PluginKind { ) } -/** - * 插件描述 - */ -public interface PluginDescription { - public val kind: PluginKind - - public val name: String - public val author: String - public val version: Semver - public val info: String - - /** 此插件依赖的其他插件, 将会在这些插件加载之后加载此插件 */ - public val dependencies: List<@Serializable(with = PluginDependency.SmartSerializer::class) PluginDependency> -} - /** 插件的一个依赖的信息 */ @Serializable public data class PluginDependency( diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/PluginManagerImpl.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/PluginManagerImpl.kt new file mode 100644 index 000000000..937868985 --- /dev/null +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/PluginManagerImpl.kt @@ -0,0 +1,193 @@ +/* + * Copyright 2020 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/master/LICENSE + */ + +@file:Suppress("NOTHING_TO_INLINE", "unused") + +package net.mamoe.mirai.console.plugin.jvm + +import kotlinx.atomicfu.locks.withLock +import net.mamoe.mirai.console.MiraiConsole +import net.mamoe.mirai.console.plugin.* +import net.mamoe.mirai.console.setting.internal.cast +import net.mamoe.mirai.utils.info +import java.io.File +import java.util.concurrent.locks.ReentrantLock + +internal object PluginManagerImpl : PluginManager { + override val pluginsDir = File(MiraiConsole.rootDir, "plugins").apply { mkdir() } + override val pluginsDataFolder = File(MiraiConsole.rootDir, "data").apply { mkdir() } + + @Suppress("ObjectPropertyName") + private val _pluginLoaders: MutableList> = mutableListOf() + private val loadersLock: ReentrantLock = ReentrantLock() + private val logger = MiraiConsole.newLogger("PluginManager") + + @JvmField + internal val resolvedPlugins: MutableList = mutableListOf() + override val plugins: List + get() = resolvedPlugins.toList() + override val builtInLoaders: List> + get() = MiraiConsole.builtInPluginLoaders + override val pluginLoaders: List> + get() = _pluginLoaders.toList() + + override val Plugin.description: PluginDescription + get() = resolvedPlugins.firstOrNull { it == this } + ?.loader?.cast>() + ?.getDescription(this) + ?: error("Plugin is unloaded") + + override fun registerPluginLoader(loader: PluginLoader<*, *>): Boolean = loadersLock.withLock { + if (_pluginLoaders.any { it::class == loader }) { + return false + } + _pluginLoaders.add(loader) + } + + override fun unregisterPluginLoader(loader: PluginLoader<*, *>) = loadersLock.withLock { + _pluginLoaders.remove(loader) + } + + + // region LOADING + + private fun

PluginLoader.loadPluginNoEnable(description: D): P { + return kotlin.runCatching { + this.load(description).also { resolvedPlugins.add(it) } + }.fold( + onSuccess = { + logger.info { "Successfully loaded plugin ${description.name}" } + it + }, + onFailure = { + logger.info { "Cannot load plugin ${description.name}" } + throw it + } + ) + } + + private fun

PluginLoader.enablePlugin(plugin: Plugin) { + kotlin.runCatching { + @Suppress("UNCHECKED_CAST") + this.enable(plugin as P) + }.fold( + onSuccess = { + logger.info { "Successfully enabled plugin ${plugin.description.name}" } + }, + onFailure = { + logger.info { "Cannot enable plugin ${plugin.description.name}" } + throw it + } + ) + } + + /** + * STEPS: + * 1. 遍历插件列表, 使用 [builtInLoaders] 加载 [PluginKind.LOADER] 类型的插件 + * 2. [启动][PluginLoader.enable] 所有 [PluginKind.LOADER] 的插件 + * 3. 使用内建和所有插件提供的 [PluginLoader] 加载全部除 [PluginKind.LOADER] 外的插件列表. + * 4. 解决依赖并排序 + * 5. 依次 [PluginLoader.load] + * 但不 [PluginLoader.enable] + * + * @return [builtInLoaders] 可以加载的插件. 已经完成了 [PluginLoader.load], 但没有 [PluginLoader.enable] + */ + @Suppress("UNCHECKED_CAST") + @Throws(PluginMissingDependencyException::class) + internal fun loadEnablePlugins() { + (loadAndEnableLoaderProviders() + _pluginLoaders.listAllPlugins().flatMap { it.second }) + .sortByDependencies().loadAndEnableAllInOrder() + } + + private fun List.loadAndEnableAllInOrder() { + return this.map { (loader, desc) -> + loader to loader.loadPluginNoEnable(desc) + }.forEach { (loader, plugin) -> + loader.enablePlugin(plugin) + } + } + + /** + * @return [builtInLoaders] 可以加载的插件. 已经完成了 [PluginLoader.load], 但没有 [PluginLoader.enable] + */ + @Suppress("UNCHECKED_CAST") + @Throws(PluginMissingDependencyException::class) + private fun loadAndEnableLoaderProviders(): List { + val allDescriptions = + this.builtInLoaders.listAllPlugins() + .asSequence() + .onEach { (loader, descriptions) -> + loader as PluginLoader + + descriptions.filter { it.kind == PluginKind.LOADER }.sortByDependencies().loadAndEnableAllInOrder() + } + .flatMap { it.second.asSequence() } + + return allDescriptions.toList() + } + + private fun List>.listAllPlugins(): List, List>> { + return associateWith { loader -> loader.listPlugins().map { desc -> desc.wrapWith(loader) } }.toList() + } + + @Throws(PluginMissingDependencyException::class) + private fun List.sortByDependencies(): List { + val resolved = ArrayList(this.size) + + fun D.canBeLoad(): Boolean = this.dependencies.all { it.isOptional || it in resolved } + + fun List.consumeLoadable(): List { + val (canBeLoad, cannotBeLoad) = this.partition { it.canBeLoad() } + resolved.addAll(canBeLoad) + return cannotBeLoad + } + + fun List.filterIsMissing(): List = + this.filterNot { it.isOptional || it in resolved } + + tailrec fun List.doSort() { + if (this.isEmpty()) return + + val beforeSize = this.size + this.consumeLoadable().also { resultPlugins -> + check(resultPlugins.size < beforeSize) { + throw PluginMissingDependencyException(resultPlugins.joinToString("\n") { badPlugin -> + "Cannot load plugin ${badPlugin.name}, missing dependencies: ${ + badPlugin.dependencies.filterIsMissing() + .joinToString() + }" + }) + } + }.doSort() + } + + this.doSort() + return resolved + } + + // endregion +} + +internal data class PluginDescriptionWithLoader( + @JvmField val loader: PluginLoader<*, PluginDescription>, // easier type + @JvmField val delegate: PluginDescription +) : PluginDescription by delegate + +@Suppress("UNCHECKED_CAST") +internal fun PluginDescription.unwrap(): D = + if (this is PluginDescriptionWithLoader) this.delegate as D else this as D + +@Suppress("UNCHECKED_CAST") +internal fun PluginDescription.wrapWith(loader: PluginLoader<*, *>): PluginDescriptionWithLoader = + PluginDescriptionWithLoader( + loader as PluginLoader<*, PluginDescription>, this + ) + +internal operator fun List.contains(dependency: PluginDependency): Boolean = + any { it.name == dependency.name } diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/Setting.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/Setting.kt index 0bb578b57..a48f5225d 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/Setting.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/Setting.kt @@ -88,7 +88,7 @@ public abstract class AbstractSetting : Setting, SettingImpl() { * * @see JvmPlugin.loadSetting 通过 [JvmPlugin] 获取指定 [Setting] 实例. */ -public interface Setting { +public interface Setting : ExperimentalSettingExtensions { /** * 使用 `by` 时自动调用此方法, 添加对 [Value] 的值修改的跟踪. */ @@ -113,6 +113,21 @@ public interface Setting { public fun setStorage(storage: SettingStorage) } +@ConsoleExperimentalAPI("") +public interface ExperimentalSettingExtensions { + public fun MutableMap.shadowMap( + eToK: (E) -> K, + kToE: (K) -> E + ): MutableMap { + return this.shadowMap( + kTransform = eToK, + kTransformBack = kToE, + vTransform = { it }, + vTransformBack = { it } + ) + } +} + //// region Setting_value_primitives CODEGEN //// public fun Setting.value(default: Byte): SerializerAwareValue = valueImpl(default) diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/BotManagers.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/BotManagers.kt index 4e071e9a9..f30e8f3b3 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/BotManagers.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/BotManagers.kt @@ -41,7 +41,7 @@ internal fun Bot.addManager(id: Long): Boolean { } -internal object ManagersConfig : Setting by (ConsoleBuiltInSettingStorage.load(ConsoleBuiltInSettingHolder)) { +internal object ManagersConfig : Setting by ConsoleBuiltInSettingStorage.load() { private val managers: MutableMap> by value() internal operator fun get(bot: Bot): MutableSet = managers.getOrPut(bot.id, ::mutableSetOf) @@ -54,10 +54,12 @@ internal fun CoroutineScope.childScope(context: CoroutineContext = EmptyCoroutin internal object ConsoleBuiltInSettingHolder : AutoSaveSettingHolder, CoroutineScope by MiraiConsole.childScope() { - override val autoSaveIntervalMillis: LongRange - get() = 30.minutesToMillis..60.minutesToMillis + override val autoSaveIntervalMillis: LongRange = 30.minutesToMillis..60.minutesToMillis override val name: String get() = "ConsoleBuiltIns" } internal object ConsoleBuiltInSettingStorage : - SettingStorage by MiraiConsoleImplementationBridge.settingStorageForJarPluginLoader \ No newline at end of file + SettingStorage by MiraiConsoleImplementationBridge.settingStorageForJarPluginLoader { + + inline fun load(): T = load(ConsoleBuiltInSettingHolder) +} \ No newline at end of file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/ResourceContainer.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/ResourceContainer.kt index 2ae5fe526..66144d8a9 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/ResourceContainer.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/ResourceContainer.kt @@ -42,21 +42,21 @@ public interface ResourceContainer { */ @JvmDefault public fun getResource(name: String, charset: Charset): String = - this.getResourceAsStream(name).use { it.readBytes() }.encodeToString() + this.getResourceAsStream(name).use { it.readBytes() }.encodeToString(charset) public companion object { /** * 使用 [Class.getResourceAsStream] 读取资源文件 */ @JvmStatic - @JvmName("byClass") + @JvmName("create") public fun KClass<*>.asResourceContainer(): ResourceContainer = this.java.asResourceContainer() /** * 使用 [Class.getResourceAsStream] 读取资源文件 */ @JvmStatic - @JvmName("byClass") + @JvmName("create") public fun Class<*>.asResourceContainer(): ResourceContainer = ClassAsResourceContainer(this) } } 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 39894ac08..75c8b4f3f 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 @@ -37,6 +37,7 @@ import net.mamoe.mirai.console.setting.SettingStorage import net.mamoe.mirai.console.utils.ConsoleInternalAPI import net.mamoe.mirai.utils.MiraiLogger import java.io.File +import java.util.* /** * mirai-console-pure 后端实现 @@ -47,7 +48,10 @@ import java.io.File class MiraiConsoleImplementationPure @JvmOverloads constructor( override val rootDir: File = File("."), - override val builtInPluginLoaders: List> = listOf(DeferredPluginLoader { JarPluginLoader }), + override val builtInPluginLoaders: List> = Collections.unmodifiableList( + listOf( + DeferredPluginLoader { JarPluginLoader }) + ), override val frontEnd: MiraiConsoleFrontEnd = MiraiConsoleFrontEndPure, override val mainLogger: MiraiLogger = frontEnd.loggerFor("main"), override val consoleCommandSender: ConsoleCommandSender = ConsoleCommandSenderImpl,