From c76a6dacc9e43d31c4ad1f229b00ed625be2f417 Mon Sep 17 00:00:00 2001 From: Him188 Date: Thu, 10 Sep 2020 10:30:00 +0800 Subject: [PATCH] Introduce JvmPluginDescriptionBuilder, add checks --- .../MiraiConsoleImplementationBridge.kt | 3 - .../internal/data/builtins/BotManagerImpl.kt | 53 ----- .../data/builtins/ConsoleDataScope.kt | 2 +- .../internal/plugin/PluginManagerImpl.kt | 10 +- .../net/mamoe/mirai/console/plugin/Plugin.kt | 2 +- .../IllegalPluginDescriptionException.kt | 8 + .../plugin/description/PluginDependency.kt | 18 +- .../plugin/description/PluginDescription.kt | 124 ++++++++++- .../plugin/jvm/JvmPluginDescription.kt | 198 +++++++++++++++++- .../mamoe/mirai/console/util/BotManager.kt | 36 ---- .../mamoe/mirai/console/data/SettingTest.kt | 4 +- 11 files changed, 340 insertions(+), 118 deletions(-) delete mode 100644 backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/data/builtins/BotManagerImpl.kt create mode 100644 backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/IllegalPluginDescriptionException.kt delete mode 100644 backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/BotManager.kt 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 a604cc13d..c40a49b7e 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,7 +42,6 @@ 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.util.BotManager import net.mamoe.mirai.console.util.ConsoleExperimentalAPI import net.mamoe.mirai.console.util.ConsoleInput import net.mamoe.mirai.utils.* @@ -121,8 +120,6 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI phase `load configurations`@{ mainLogger.verbose { "Loading configurations..." } ConsoleDataScope.reloadAll() - - BotManager } val pluginLoadSession: PluginManagerImpl.PluginLoadSession diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/data/builtins/BotManagerImpl.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/data/builtins/BotManagerImpl.kt deleted file mode 100644 index 3abac0c9a..000000000 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/data/builtins/BotManagerImpl.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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("MemberVisibilityCanBePrivate") - -package net.mamoe.mirai.console.internal.data.builtins - -import net.mamoe.mirai.Bot -import net.mamoe.mirai.console.data.AutoSavePluginConfig -import net.mamoe.mirai.console.data.PluginDataExtensions.mapKeys -import net.mamoe.mirai.console.data.PluginDataExtensions.withEmptyDefault -import net.mamoe.mirai.console.data.ValueDescription -import net.mamoe.mirai.console.data.value -import net.mamoe.mirai.console.util.BotManager -import net.mamoe.mirai.contact.User - -internal object BotManagerImpl : BotManager { - override val User.isManager: Boolean get() = this.id in ManagersConfig[this.bot] - - override fun Bot.removeManager(id: Long): Boolean { - return ManagersConfig[this].remove(id) - } - - override val Bot.managers: List - get() = ManagersConfig[this].toList() - - override fun Bot.addManager(id: Long): Boolean { - return ManagersConfig[this].add(id) - } -} - -internal object ManagersConfig : AutoSavePluginConfig() { - override val saveName: String - get() = "Managers" - - @ValueDescription( - """ - 管理员列表 - """ - ) - private val managers - by value>>() - .withEmptyDefault() - .mapKeys(Bot::getInstance, Bot::id) - - internal operator fun get(bot: Bot): MutableSet = managers[bot] -} \ No newline at end of file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/data/builtins/ConsoleDataScope.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/data/builtins/ConsoleDataScope.kt index 61463c6c1..98b8077bd 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/data/builtins/ConsoleDataScope.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/data/builtins/ConsoleDataScope.kt @@ -22,7 +22,7 @@ import net.mamoe.mirai.utils.minutesToMillis internal object ConsoleDataScope : CoroutineScope by MiraiConsole.childScope("ConsoleDataScope") { private val data: List = mutableListOf() - private val configs: MutableList = mutableListOf(ManagersConfig, AutoLoginConfig) + private val configs: MutableList = mutableListOf(AutoLoginConfig) fun addAndReloadConfig(config: PluginConfig) { configs.add(config) 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 5805b3d01..bdef81153 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 @@ -171,8 +171,10 @@ internal object PluginManagerImpl : PluginManager, CoroutineScope by MiraiConsol @kotlin.jvm.Throws(PluginLoadException::class) internal fun checkPluginDescription(description: PluginDescription) { - when (description.name.toLowerCase()) { - "main", "console", "plugin", "config", "data" -> throw PluginLoadException("Plugin name '${description.name}' is forbidden.") + kotlin.runCatching { + PluginDescription.checkPluginDescription(description) + }.getOrElse { + throw PluginLoadException("PluginDescription check failed.", it) } } @@ -214,7 +216,7 @@ internal object PluginManagerImpl : PluginManager, CoroutineScope by MiraiConsol return cannotBeLoad } - fun List.filterIsMissing(): List = + fun Collection.filterIsMissing(): List = this.filterNot { it.isOptional || it in resolved } tailrec fun List.doSort() { @@ -257,4 +259,4 @@ internal fun PluginDescription.wrapWith(loader: PluginLoader<*, *>, plugin: Plug ) internal operator fun List.contains(dependency: PluginDependency): Boolean = - any { it.name == dependency.name } + any { it.id == dependency.id } 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 ec09365fa..a9248bb7d 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 @@ -82,4 +82,4 @@ public inline val Plugin.author: String get() = this.description.author /** * 获取 [PluginDescription.dependencies] */ -public inline val Plugin.dependencies: List get() = this.description.dependencies +public inline val Plugin.dependencies: Set get() = this.description.dependencies 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 new file mode 100644 index 000000000..1083259ce --- /dev/null +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/IllegalPluginDescriptionException.kt @@ -0,0 +1,8 @@ +package net.mamoe.mirai.console.plugin.description + +public class IllegalPluginDescriptionException : 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/description/PluginDependency.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/PluginDependency.kt index 0e4dc7802..957a14bf7 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/PluginDependency.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/PluginDependency.kt @@ -18,9 +18,11 @@ import com.vdurmont.semver4j.Semver * * @see PluginDescription.dependencies */ -public data class PluginDependency( - /** 依赖插件名 */ - public val name: String, +public data class PluginDependency @JvmOverloads constructor( + /** + * 依赖插件 ID, [PluginDescription.id] + */ + public val id: String, /** * 依赖版本号. 为 null 时则为不限制版本. * @@ -34,6 +36,16 @@ public data class PluginDependency( */ public val isOptional: Boolean = false ) { + /** + * @see PluginDependency + */ + public constructor(name: String, isOptional: Boolean = false) : this( + name, null, isOptional + ) + + /** + * @see PluginDependency + */ public constructor(name: String, version: String, isOptional: Boolean) : this( name, Semver(version, Semver.SemverType.IVY), 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 c9e40ad0d..6ef60f81a 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,6 +11,7 @@ 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 /** @@ -27,14 +28,44 @@ public interface PluginDescription { public val kind: PluginKind /** - * 插件名称. 不允许存在 ":", 推荐全英文. + * 插件 ID, 必须全英文, 仅允许英文字母, '-', '_', '.'. * - * 插件名称不能完全是以下其中一种. + * - 类似于 Java 包名, 插件 ID 需要 '域名.名称' 格式, 如 `net.mamoe.mirai.example-plugin` + * - 域名和名称都是必须的 + * - '.' 不允许位于首位或末尾 + * - '-' 和 '_' 仅允许存在于两个英文字母之间 + * + * ID 在插件发布后就应该保持不变, 以便其他插件添加依赖. + * + * 插件 ID 的域名和名称都不能完全是以下其中一个 ([FORBIDDEN_ID_WORDS]). + * - "console" + * - "main" + * - "plugin" + * - "config" + * - "data" + * + * + * ID 用于指令权限等一些内部处理 + * + * @see FORBIDDEN_ID_LETTERS + * @see FORBIDDEN_ID_WORDS + */ + public val id: String + + /** + * 插件名称. 允许中文, 允许各类符号. + * + * 插件名称不能完全是以下其中一种 ([FORBIDDEN_ID_WORDS]). * - console * - main * - plugin * - config * - data + * + * 插件名称用于显示给用户. + * + * @see FORBIDDEN_ID_LETTERS + * @see FORBIDDEN_ID_WORDS */ public val name: String @@ -46,7 +77,21 @@ public interface PluginDescription { /** * 插件版本. * - * 语法参考: ([语义化版本 2.0.0](https://semver.org/lang/zh-CN/)) + * 语法参考: ([语义化版本 2.0.0](https://semver.org/lang/zh-CN/)). + * + * 合法的版本号示例: + * - `1.0.0` + * - `1.0` + * - `1.0-M1` + * - `1.0.0-M1` + * - `1.0.0-M2-1` + * - `1` (尽管非常不建议这么做) + * + * 非法版本号实例: + * - `DEBUG-1` + * - `-1.0` + * - `v1.0` (不允许 "v") + * - `V1.0` (不允许 "V") * * @see Semver 语义化版本. 允许 [宽松][Semver.SemverType.LOOSE] 类型版本. */ @@ -62,6 +107,77 @@ public interface PluginDescription { * * @see PluginDependency */ - public val dependencies: List + 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] 的 [PluginDescription.id], [PluginDescription.name], [PluginDescription.dependencies] 的合法性 + * + * @throws IllegalPluginDescriptionException 当不合法时抛出. + */ + @Throws(IllegalPluginDescriptionException::class) + public fun checkPluginDescription(instance: PluginDescription) { + kotlin.runCatching { + checkPluginId(instance.id) + checkPluginName(instance.name) + checkDependencies(instance.id, instance.dependencies) + }.getOrElse { + throw IllegalPluginDescriptionException( + "Illegal description. Plugin ${instance.name} (${instance.id})", + it + ) + } + } + + /** + * 检查 [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. ") + + FORBIDDEN_ID_LETTERS.firstOrNull { it in id }?.let { illegal -> + throw IllegalPluginDescriptionException("Plugin id contains illegal char: $illegal.") + } + + val idSections = id.split('.') + FORBIDDEN_ID_WORDS.firstOrNull { it in idSections }?.let { illegal -> + throw IllegalPluginDescriptionException("Plugin id contains illegal word: '$illegal'.") + } + } + + /** + * 检查 [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 -> + throw IllegalPluginDescriptionException("Plugin name is illegal: '$illegal'.") + } + } + + /** + * 检查 [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") + + if (dependencies.any { it.id == pluginId }) + throw PluginLoadException("Recursive dependency detected: A plugin cannot depend on itself") + } + } } diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginDescription.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginDescription.kt index 6f9de4245..363f356df 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginDescription.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginDescription.kt @@ -7,7 +7,7 @@ * https://github.com/mamoe/mirai/blob/master/LICENSE */ -@file:Suppress("unused") +@file:Suppress("unused", "INVISIBLE_REFERENCE", "INVISIBLE_member") package net.mamoe.mirai.console.plugin.jvm @@ -15,35 +15,207 @@ import com.vdurmont.semver4j.Semver import net.mamoe.mirai.console.plugin.description.PluginDependency import net.mamoe.mirai.console.plugin.description.PluginDescription import net.mamoe.mirai.console.plugin.description.PluginKind +import kotlin.internal.LowPriorityInOverloadResolution /** * JVM 插件的描述. 通常作为 `plugin.yml` + * + * 请不要自行实现 [JvmPluginDescription] 接口. 它不具有继承稳定性. + * * @see SimpleJvmPluginDescription + * @see JvmPluginDescriptionBuilder */ -public interface JvmPluginDescription : PluginDescription +public interface JvmPluginDescription : PluginDescription { + public companion object { + /** + * 构建 [JvmPluginDescription] + * @see JvmPluginDescriptionBuilder + */ + @JvmSynthetic + public operator fun invoke( + name: String, + version: String, + block: JvmPluginDescriptionBuilder.() -> Unit = {} + ): JvmPluginDescription = JvmPluginDescriptionBuilder(name, version).apply(block).build() + + /** + * 构建 [JvmPluginDescription] + * @see JvmPluginDescriptionBuilder + */ + @JvmSynthetic + public operator fun invoke( + name: String, + version: Semver, + block: JvmPluginDescriptionBuilder.() -> Unit = {} + ): JvmPluginDescription = JvmPluginDescriptionBuilder(name, version).apply(block).build() + } +} /** + * [JvmPluginDescription] 构建器. + * + * #### Kotlin Example + * ``` + * val desc = JvmPluginDescription("org.example.example-plugin", "1.0.0") { + * info("This is an example plugin") + * dependsOn("org.example.another-plugin") + * } + * ``` + * + * #### Java Example + * ``` + * JvmPluginDescription desc = new JvmPluginDescriptionBuilder("org.example.example-plugin", "1.0.0") + * .info("This is an example plugin") + * .dependsOn("org.example.another-plugin") + * .build() + * ``` + * + * @see [JvmPluginDescription.invoke] + */ +public class JvmPluginDescriptionBuilder( + private var id: String, + private var version: Semver, +) { + public constructor(name: String, version: String) : this(name, Semver(version, Semver.SemverType.LOOSE)) + + private var name: String = id + private var author: String = "" + private var info: String = "" + private var dependencies: MutableSet = mutableSetOf() + private var kind: PluginKind = PluginKind.NORMAL + + @ILoveKuriyamaMiraiForever + public fun name(value: String): JvmPluginDescriptionBuilder = apply { this.name = value.trim() } + + @ILoveKuriyamaMiraiForever + public fun version(value: String): JvmPluginDescriptionBuilder = + apply { this.version = Semver(value, Semver.SemverType.LOOSE) } + + @ILoveKuriyamaMiraiForever + public fun version(value: Semver): JvmPluginDescriptionBuilder = apply { this.version = value } + + @ILoveKuriyamaMiraiForever + public fun id(value: String): JvmPluginDescriptionBuilder = apply { this.id = value.trim() } + + @ILoveKuriyamaMiraiForever + public fun author(value: String): JvmPluginDescriptionBuilder = apply { this.author = value.trim() } + + @ILoveKuriyamaMiraiForever + public fun info(value: String): JvmPluginDescriptionBuilder = apply { this.info = value.trimIndent() } + + @ILoveKuriyamaMiraiForever + public fun kind(value: PluginKind): JvmPluginDescriptionBuilder = apply { this.kind = value } + + @ILoveKuriyamaMiraiForever + public fun normalPlugin(): JvmPluginDescriptionBuilder = apply { this.kind = PluginKind.NORMAL } + + @ILoveKuriyamaMiraiForever + public fun loaderProviderPlugin(): JvmPluginDescriptionBuilder = apply { this.kind = PluginKind.LOADER } + + @ILoveKuriyamaMiraiForever + public fun highPriorityExtensionsPlugin(): JvmPluginDescriptionBuilder = + apply { this.kind = PluginKind.HIGH_PRIORITY_EXTENSIONS } + + @ILoveKuriyamaMiraiForever + public fun dependsOn( + pluginId: String, + version: String? = null, + isOptional: Boolean = false + ): JvmPluginDescriptionBuilder = apply { + if (version == null) this.dependencies.add(PluginDependency(pluginId, version, isOptional)) + else this.dependencies.add(PluginDependency(pluginId, version, isOptional)) + } + + @ILoveKuriyamaMiraiForever + public fun setDependencies( + value: Set + ): JvmPluginDescriptionBuilder = apply { + this.dependencies = value.toMutableSet() + } + + @ILoveKuriyamaMiraiForever + public fun dependsOn( + vararg dependencies: PluginDependency + ): JvmPluginDescriptionBuilder = apply { + for (dependency in dependencies) { + this.dependencies.add(dependency) + } + } + + @ILoveKuriyamaMiraiForever + public fun dependsOn( + pluginId: String, + version: Semver? = null, + isOptional: Boolean = false + ): JvmPluginDescriptionBuilder = apply { this.dependencies.add(PluginDependency(pluginId, version, isOptional)) } + + + @Suppress("DEPRECATION_ERROR") + public fun build(): JvmPluginDescription = + SimpleJvmPluginDescription(name, version, id, author, info, dependencies, kind) + + @Retention(AnnotationRetention.SOURCE) + @DslMarker + private annotation class ILoveKuriyamaMiraiForever // https://zh.moegirl.org.cn/zh-cn/%E6%A0%97%E5%B1%B1%E6%9C%AA%E6%9D%A5 +} + +/** + * @constructor 推荐使用带名称的参数, 而不要按位置摆放. + * * @see JvmPluginDescription */ +@Deprecated( + """ + 将在 1.0-RC 删除. 请使用 JvmPluginDescription. +""", + replaceWith = ReplaceWith( + "JvmPluginDescription", + "net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription" + ), + level = DeprecationLevel.ERROR +) public data class SimpleJvmPluginDescription +@Deprecated( + """ + 构造器不稳定, 将在 1.0-RC 删除. 请使用 JvmPluginDescriptionBuilder. +""", + replaceWith = ReplaceWith( + "JvmPluginDescription(name, version) {}", + "net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription.Companion.invoke" + ), + level = DeprecationLevel.ERROR +) @JvmOverloads public constructor( public override val name: String, public override val version: Semver, + public override val id: String = name, public override val author: String = "", public override val info: String = "", - public override val dependencies: List = listOf(), + public override val dependencies: Set = setOf(), public override val kind: PluginKind = PluginKind.NORMAL, ) : JvmPluginDescription { + @Deprecated( + """ + 构造器不稳定, 将在 1.0-RC 删除. 请使用 JvmPluginDescriptionBuilder. +""", + replaceWith = ReplaceWith( + "JvmPluginDescription.invoke(name, version) {}", + "net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription.Companion.invoke" + ), + level = DeprecationLevel.ERROR + ) + @Suppress("DEPRECATION_ERROR") @JvmOverloads public constructor( name: String, version: String, + id: String = name, author: String = "", info: String = "", - dependencies: List = listOf(), + dependencies: Set = setOf(), kind: PluginKind = PluginKind.NORMAL, - ) : this(name, Semver(version, Semver.SemverType.LOOSE), author, info, dependencies, kind) + ) : this(name, Semver(version, Semver.SemverType.LOOSE), id, author, info, dependencies, kind) init { require(!name.contains(':')) { "':' is forbidden in plugin name" } @@ -59,15 +231,17 @@ public data class SimpleJvmPluginDescription ), level = DeprecationLevel.WARNING ) -@Suppress("FunctionName") +@LowPriorityInOverloadResolution +@Suppress("DEPRECATION_ERROR", "FunctionName") public fun JvmPluginDescription( name: String, version: Semver, + id: String = name, author: String = "", info: String = "", - dependencies: List = listOf(), + dependencies: Set = setOf(), kind: PluginKind = PluginKind.NORMAL -): JvmPluginDescription = SimpleJvmPluginDescription(name, version, author, info, dependencies, kind) +): JvmPluginDescription = SimpleJvmPluginDescription(name, version, id, author, info, dependencies, kind) @Deprecated( "JvmPluginDescription 没有构造器. 请使用 SimpleJvmPluginDescription.", @@ -77,12 +251,14 @@ public fun JvmPluginDescription( ), level = DeprecationLevel.WARNING ) -@Suppress("FunctionName") +@LowPriorityInOverloadResolution +@Suppress("DEPRECATION_ERROR", "FunctionName") public fun JvmPluginDescription( name: String, version: String, + id: String = name, author: String = "", info: String = "", - dependencies: List = listOf(), + dependencies: Set = setOf(), kind: PluginKind = PluginKind.NORMAL -): JvmPluginDescription = SimpleJvmPluginDescription(name, version, author, info, dependencies, kind) +): JvmPluginDescription = SimpleJvmPluginDescription(name, version, id, author, info, dependencies, kind) diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/BotManager.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/BotManager.kt deleted file mode 100644 index 6007e47df..000000000 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/BotManager.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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("NOTHING_TO_INLINE") -@file:JvmMultifileClass -@file:JvmName("ConsoleUtils") - -package net.mamoe.mirai.console.util - -import net.mamoe.mirai.Bot -import net.mamoe.mirai.console.internal.data.builtins.BotManagerImpl -import net.mamoe.mirai.contact.User - -public interface BotManager { - /** - * 判断此用户是否为 console 管理员 - */ - public val User.isManager: Boolean - public val Bot.managers: List - - public fun Bot.removeManager(id: Long): Boolean - public fun Bot.addManager(id: Long): Boolean - - public companion object INSTANCE : BotManager { // kotlin import handler doesn't recognize delegation. - override fun Bot.addManager(id: Long): Boolean = BotManagerImpl.run { addManager(id) } - override fun Bot.removeManager(id: Long): Boolean = BotManagerImpl.run { removeManager(id) } - override val User.isManager: Boolean get() = BotManagerImpl.run { isManager } - override val Bot.managers: List get() = BotManagerImpl.run { managers } - } -} \ No newline at end of file diff --git a/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/data/SettingTest.kt b/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/data/SettingTest.kt index d5c01c6f9..861101fd1 100644 --- a/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/data/SettingTest.kt +++ b/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/data/SettingTest.kt @@ -10,8 +10,8 @@ package net.mamoe.mirai.console.data import kotlinx.serialization.json.Json +import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin -import net.mamoe.mirai.console.plugin.jvm.SimpleJvmPluginDescription import net.mamoe.mirai.console.util.ConsoleInternalAPI import org.junit.jupiter.api.Test import kotlin.test.assertEquals @@ -21,7 +21,7 @@ import kotlin.test.assertSame internal class PluginDataTest { object MyPlugin : KotlinPlugin( - SimpleJvmPluginDescription( + JvmPluginDescription( "1", "2" ) )