Introduce parentPermission for commands

This commit is contained in:
Him188 2020-09-09 10:02:56 +08:00
parent 44ef4e7c56
commit 2926e55590
16 changed files with 60 additions and 33 deletions

View File

@ -105,7 +105,7 @@ public abstract class AbstractCommand
public override val owner: CommandOwner,
vararg names: String,
description: String = "<no description available>",
basePermission: PermissionId? = null,
parentPermission: PermissionId = owner.basePermission,
/** 为 `true` 时表示 [指令前缀][CommandManager.commandPrefix] 可选 */
public override val prefixOptional: Boolean = false
) : Command {
@ -116,5 +116,5 @@ public abstract class AbstractCommand
}.toTypedArray()
@OptIn(ExperimentalPermission::class)
public override val permission: Permission by lazy { createCommandPermission(basePermission) }
public override val permission: Permission by lazy { createCommandPermission(parentPermission) }
}

View File

@ -10,6 +10,7 @@
package net.mamoe.mirai.console.command
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.unregisterAllCommands
import net.mamoe.mirai.console.permission.BasePermission
import net.mamoe.mirai.console.permission.ExperimentalPermission
import net.mamoe.mirai.console.permission.PermissionId
import net.mamoe.mirai.console.permission.PermissionIdNamespace
@ -23,12 +24,21 @@ import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
*
* @see JvmPlugin 是一个 [CommandOwner]
*/
public interface CommandOwner : PermissionIdNamespace
public interface CommandOwner : PermissionIdNamespace {
/**
* [PermissionIdNamespace] 拥有的指令都默认将 [basePermission] 作为父权限.
*
* TODO document
*/
public val basePermission: PermissionId
}
/**
* 代表控制台所有者. 所有的 mirai-console 内建的指令都属于 [ConsoleCommandOwner].
*/
internal object ConsoleCommandOwner : CommandOwner {
override val basePermission: PermissionId get() = BasePermission.id
@ExperimentalPermission
override fun permissionId(id: String): PermissionId = PermissionId("console", id)
}

View File

@ -86,10 +86,10 @@ public abstract class CompositeCommand(
owner: CommandOwner,
vararg names: String,
description: String = "no description available",
basePermission: PermissionId? = null,
parentPermission: PermissionId = owner.basePermission,
prefixOptional: Boolean = false,
overrideContext: CommandArgumentContext = EmptyCommandArgumentContext
) : Command, AbstractReflectionCommand(owner, names, description, basePermission, prefixOptional),
) : Command, AbstractReflectionCommand(owner, names, description, parentPermission, prefixOptional),
CommandArgumentContextAware {
/**

View File

@ -43,13 +43,13 @@ public abstract class RawCommand(
public override val usage: String = "<no usages given>",
/** 指令描述, 用于显示在 [BuiltInCommands.Help] */
public override val description: String = "<no descriptions given>",
/** 指令权限 */
basePermission: PermissionId? = null,
/** 指令权限 */
parentPermission: PermissionId = owner.basePermission,
/** 为 `true` 时表示 [指令前缀][CommandManager.commandPrefix] 可选 */
public override val prefixOptional: Boolean = false
) : Command {
@OptIn(ExperimentalPermission::class)
public override val permission: Permission by lazy { createCommandPermission(basePermission) }
public override val permission: Permission by lazy { createCommandPermission(parentPermission) }
/**
* 在指令被执行时调用.

View File

@ -52,7 +52,7 @@ public abstract class SimpleCommand(
owner: CommandOwner,
vararg names: String,
description: String = "no description available",
basePermission: PermissionId? = null,
basePermission: PermissionId = owner.basePermission,
prefixOptional: Boolean = false,
overrideContext: CommandArgumentContext = EmptyCommandArgumentContext
) : Command, AbstractReflectionCommand(owner, names, description, basePermission, prefixOptional),

View File

@ -72,8 +72,8 @@ import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
public abstract class JCompositeCommand @JvmOverloads constructor(
owner: CommandOwner,
vararg names: String,
basePermission: PermissionId? = null,
) : CompositeCommand(owner, *names, basePermission = basePermission) {
parentPermission: PermissionId = owner.basePermission,
) : CompositeCommand(owner, *names, parentPermission = parentPermission) {
/** 指令描述, 用于显示在 [BuiltInCommands.Help] */
public final override var description: String = "<no descriptions given>"
protected set

View File

@ -53,7 +53,7 @@ public abstract class JRawCommand @JvmOverloads constructor(
public override val owner: CommandOwner,
/** 指令名. 需要至少有一个元素. 所有元素都不能带有空格 */
public override vararg val names: String,
basePermission: PermissionId? = null,
parentPermission: PermissionId = owner.basePermission,
) : Command {
/** 用法说明, 用于发送给用户 */
public override var usage: String = "<no usages given>"
@ -64,7 +64,7 @@ public abstract class JRawCommand @JvmOverloads constructor(
protected set
/** 指令权限 */
public final override var permission: Permission = createCommandPermission(basePermission)
public final override var permission: Permission = createCommandPermission(parentPermission)
protected set
/** 为 `true` 时表示 [指令前缀][CommandManager.commandPrefix] 可选 */

View File

@ -48,13 +48,13 @@ internal abstract class AbstractReflectionCommand @JvmOverloads constructor(
owner: CommandOwner,
names: Array<out String>,
description: String = "<no description available>",
basePermission: PermissionId? = null,
parentPermission: PermissionId = owner.basePermission,
prefixOptional: Boolean = false
) : Command, AbstractCommand(
owner,
names = names,
description = description,
basePermission = basePermission,
parentPermission = parentPermission,
prefixOptional = prefixOptional
), CommandArgumentContextAware {
internal abstract val subCommandAnnotationResolver: SubCommandAnnotationResolver
@ -74,7 +74,7 @@ internal abstract class AbstractReflectionCommand @JvmOverloads constructor(
internal val defaultSubCommand: DefaultSubCommandDescriptor by lazy {
DefaultSubCommandDescriptor(
"",
createCommandPermission(basePermission),
createCommandPermission(parentPermission),
onCommand = { sender: CommandSender, args: MessageChain ->
sender.onDefault(args)
}

View File

@ -139,15 +139,12 @@ internal fun Group.fuzzySearchMember(
}
@OptIn(ExperimentalPermission::class)
internal fun Command.createCommandPermission(basePermission: PermissionId?): Permission {
return PermissionService.INSTANCE.register(owner.permissionId(primaryName), description, basePermission)
internal fun Command.createCommandPermission(parent: PermissionId): Permission {
return PermissionService.INSTANCE.register(owner.permissionId(primaryName), description, parent)
}
//// internal
@JvmSynthetic
internal inline fun <reified T> List<T>.dropToTypedArray(n: Int): Array<T> = Array(size - n) { this[n + it] }
@OptIn(ExperimentalPermission::class)
@JvmSynthetic
@Throws(CommandExecutionException::class)

View File

@ -17,11 +17,14 @@ import net.mamoe.mirai.console.data.runCatchingLog
import net.mamoe.mirai.console.internal.data.mkdir
import net.mamoe.mirai.console.permission.ExperimentalPermission
import net.mamoe.mirai.console.permission.PermissionId
import net.mamoe.mirai.console.permission.PermissionService
import net.mamoe.mirai.console.permission.allocatePermissionIdForPlugin
import net.mamoe.mirai.console.plugin.Plugin
import net.mamoe.mirai.console.plugin.PluginManager
import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.safeLoader
import net.mamoe.mirai.console.plugin.ResourceContainer.Companion.asResourceContainer
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
import net.mamoe.mirai.console.plugin.name
import net.mamoe.mirai.console.util.NamedSupervisorJob
import net.mamoe.mirai.utils.MiraiLogger
import java.io.File
@ -40,6 +43,14 @@ internal abstract class JvmPluginInternal(
parentCoroutineContext: CoroutineContext
) : JvmPlugin, CoroutineScope {
@OptIn(ExperimentalPermission::class)
final override val basePermission: PermissionId by lazy {
PermissionService.INSTANCE.register(
PermissionService.INSTANCE.allocatePermissionIdForPlugin(name, "*"),
"The base permission"
).id
}
final override var isEnabled: Boolean = false
private val resourceContainerDelegate by lazy { this::class.java.classLoader.asResourceContainer() }
@ -99,6 +110,7 @@ internal abstract class JvmPluginInternal(
}
internal fun internalOnEnable(): Boolean {
basePermission
if (!firstRun) refreshCoroutineContext()
kotlin.runCatching {
onEnable()
@ -124,6 +136,7 @@ internal abstract class JvmPluginInternal(
internal val _intrinsicCoroutineContext: CoroutineContext by lazy {
CoroutineName("Plugin $dataHolderName")
}
@JvmField
internal val coroutineContextInitializer = {
CoroutineExceptionHandler { context, throwable ->

View File

@ -20,12 +20,12 @@ public abstract class AbstractConcurrentPermissionService<P : Permission> : Perm
protected abstract fun createPermission(
id: PermissionId,
description: String,
base: PermissionId?
base: PermissionId = BasePermission.id
): P
override fun get(id: PermissionId): P? = permissions[id]
override fun register(id: PermissionId, description: String, base: PermissionId?): P {
override fun register(id: PermissionId, description: String, base: PermissionId): P {
grantedPermissionsMap[id] = CopyOnWriteArrayList() // mutations are not quite often performed
val instance = createPermission(id, description, base)
if (permissions.putIfAbsent(id, instance) != null) {

View File

@ -32,7 +32,7 @@ public object AllGrantPermissionService : PermissionService<PermissionImpl> {
override fun register(
id: PermissionId,
description: String,
base: PermissionId?
base: PermissionId
): PermissionImpl {
val new = PermissionImpl(id, description, base)
if (all.putIfAbsent(id, new) != null) {
@ -48,7 +48,7 @@ public object AllGrantPermissionService : PermissionService<PermissionImpl> {
override fun grant(permissibleIdentifier: PermissibleIdentifier, permission: PermissionImpl) {
}
override fun testPermission(permissibleIdentifier: PermissibleIdentifier, permission: PermissionImpl): Boolean =
override fun testPermission(permissibleIdentifier: PermissibleIdentifier, permissionId: PermissionId): Boolean =
true
override fun deny(permissibleIdentifier: PermissibleIdentifier, permission: PermissionImpl) {
@ -64,7 +64,7 @@ public object AllDenyPermissionService : PermissionService<PermissionImpl> {
override fun register(
id: PermissionId,
description: String,
base: PermissionId?
base: PermissionId
): PermissionImpl {
val new = PermissionImpl(id, description, base)
if (all.putIfAbsent(id, new) != null) {
@ -80,7 +80,7 @@ public object AllDenyPermissionService : PermissionService<PermissionImpl> {
override fun grant(permissibleIdentifier: PermissibleIdentifier, permission: PermissionImpl) {
}
override fun testPermission(permissibleIdentifier: PermissibleIdentifier, permission: PermissionImpl): Boolean =
override fun testPermission(permissibleIdentifier: PermissibleIdentifier, permissionId: PermissionId): Boolean =
false
override fun deny(permissibleIdentifier: PermissibleIdentifier, permission: PermissionImpl) {
@ -100,7 +100,7 @@ internal object BuiltInPermissionService : AbstractConcurrentPermissionService<P
override val grantedPermissionsMap: MutableMap<PermissionId, MutableCollection<PermissibleIdentifier>>
get() = config.grantedPermissionMap as MutableMap<PermissionId, MutableCollection<PermissibleIdentifier>>
override fun createPermission(id: PermissionId, description: String, base: PermissionId?): PermissionImpl =
override fun createPermission(id: PermissionId, description: String, base: PermissionId): PermissionImpl =
PermissionImpl(id, description, base)
internal val config: ConcurrentSaveData<PermissionImpl> =

View File

@ -14,7 +14,9 @@ import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
/**
* 一个权限节点
* 一个权限节点.
*
* [PermissionService] 实现不同, [Permission] 可能会有多种实例. 但一个权限总是拥有确定的 [id]
*/
@ExperimentalPermission
public interface Permission {
@ -29,10 +31,9 @@ public interface Permission {
@ExperimentalPermission
public object BasePermission :
Permission {
override val id: PermissionId = PermissionId("console", "base")
override val id: PermissionId = PermissionId("*", "*")
override val description: String get() = "The parent of any permission"
override val parent: PermissionId get() = id
}
@ConsoleExperimentalAPI

View File

@ -16,6 +16,9 @@ import kotlinx.serialization.builtins.serializer
import net.mamoe.mirai.console.internal.data.map
/**
* [PermissionId] [Permission] 唯一对应.
*/
@Serializable
@ExperimentalPermission
public data class PermissionId(

View File

@ -43,7 +43,7 @@ public interface PermissionService<P : Permission> {
public fun register(
id: PermissionId,
description: String,
base: PermissionId? = null
base: PermissionId = BasePermission.id
): P
///////////////////////////////////////////////////////////////////////////
@ -60,6 +60,9 @@ public interface PermissionService<P : Permission> {
}
}
internal fun PermissionService<*>.allocatePermissionIdForPlugin(name: String, id: String) =
PermissionId("plugin.${name.toLowerCase()}", id.toLowerCase())
@ExperimentalPermission
public fun PermissionId.findCorrespondingPermission(): Permission? = PermissionService.INSTANCE[this]

View File

@ -27,7 +27,7 @@ public interface PluginDescription {
public val kind: PluginKind
/**
* 插件名称. 不允许存在 ":".
* 插件名称. 不允许存在 ":", 推荐全英文.
*
* 插件名称不能完全是以下其中一种.
* - console