Use Permission for Permission.parent

This commit is contained in:
Him188 2020-09-10 19:53:27 +08:00
parent dd9cc3c706
commit cea884c3d7
18 changed files with 151 additions and 113 deletions

View File

@ -16,17 +16,13 @@ import net.mamoe.mirai.Bot
import net.mamoe.mirai.alsoLogin
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.register
import net.mamoe.mirai.console.command.description.PermissibleIdentifierArgumentParser
import net.mamoe.mirai.console.command.description.PermissionIdArgumentParser
import net.mamoe.mirai.console.command.description.buildCommandArgumentContext
import net.mamoe.mirai.console.command.description.*
import net.mamoe.mirai.console.internal.command.CommandManagerImpl
import net.mamoe.mirai.console.internal.command.CommandManagerImpl.allRegisteredCommands
import net.mamoe.mirai.console.internal.command.qualifiedNameOrTip
import net.mamoe.mirai.console.permission.ExperimentalPermission
import net.mamoe.mirai.console.permission.PermissibleIdentifier
import net.mamoe.mirai.console.permission.PermissionId
import net.mamoe.mirai.console.permission.PermissionService
import net.mamoe.mirai.console.permission.*
import net.mamoe.mirai.console.permission.PermissionService.Companion.denyPermission
import net.mamoe.mirai.console.permission.PermissionService.Companion.findCorrespondingPermissionOrFail
import net.mamoe.mirai.console.permission.PermissionService.Companion.getGrantedPermissions
import net.mamoe.mirai.console.permission.PermissionService.Companion.grantPermission
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
@ -51,6 +47,7 @@ internal interface BuiltInCommandInternal : Command
*/
@ConsoleExperimentalAPI
@Suppress("unused")
@OptIn(ExperimentalPermission::class)
public object BuiltInCommands {
public val all: Array<out Command> by lazy {
@ -63,9 +60,10 @@ public object BuiltInCommands {
}
}
public object Help : SimpleCommand(
public object HelpCommand : SimpleCommand(
ConsoleCommandOwner, "help",
description = "Command list"
description = "Command list",
parentPermission = RootConsoleBuiltInPermission,
), BuiltInCommand {
@Handler
public suspend fun CommandSender.handle() {
@ -82,9 +80,10 @@ public object BuiltInCommands {
})
}
public object Stop : SimpleCommand(
public object StopCommand : SimpleCommand(
ConsoleCommandOwner, "stop", "shutdown", "exit",
description = "Stop the whole world."
description = "Stop the whole world.",
parentPermission = RootConsoleBuiltInPermission,
), BuiltInCommand {
private val closingLock = Mutex()
@ -117,9 +116,10 @@ public object BuiltInCommands {
}
}
public object Login : SimpleCommand(
public object LoginCommand : SimpleCommand(
ConsoleCommandOwner, "login", "登录",
description = "Log in a bot account."
description = "Log in a bot account.",
parentPermission = RootConsoleBuiltInPermission,
), BuiltInCommand {
@Handler
public suspend fun CommandSender.handle(id: Long, password: String) {
@ -145,23 +145,28 @@ public object BuiltInCommands {
}
@OptIn(ExperimentalPermission::class)
public object Permission : CompositeCommand(
ConsoleCommandOwner, "permission", "权限",
public object PermissionCommand : CompositeCommand(
ConsoleCommandOwner, "permission", "权限", "perm",
description = "Manage permissions",
overrideContext = buildCommandArgumentContext {
PermissibleIdentifier::class with PermissibleIdentifierArgumentParser
PermissionId::class with PermissionIdArgumentParser
}
Permission::class with PermissionIdArgumentParser.map { id ->
kotlin.runCatching {
id.findCorrespondingPermissionOrFail()
}.getOrElse { illegalArgument("指令不存在: $id", it) }
}
},
parentPermission = RootConsoleBuiltInPermission,
), BuiltInCommand {
// TODO: 2020/9/10 improve Permission command
@SubCommand
public suspend fun CommandSender.grant(target: PermissibleIdentifier, permission: PermissionId) {
public suspend fun CommandSender.grant(target: PermissibleIdentifier, permission: Permission) {
target.grantPermission(permission)
sendMessage("OK")
}
@SubCommand
public suspend fun CommandSender.deny(target: PermissibleIdentifier, permission: PermissionId) {
public suspend fun CommandSender.deny(target: PermissibleIdentifier, permission: Permission) {
target.denyPermission(permission)
sendMessage("OK")
}

View File

@ -19,7 +19,6 @@ import net.mamoe.mirai.console.internal.command.createOrFindCommandPermission
import net.mamoe.mirai.console.internal.command.isValidSubName
import net.mamoe.mirai.console.permission.ExperimentalPermission
import net.mamoe.mirai.console.permission.Permission
import net.mamoe.mirai.console.permission.PermissionId
import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.message.data.SingleMessage
@ -107,7 +106,7 @@ public abstract class AbstractCommand
public override val owner: CommandOwner,
vararg names: String,
description: String = "<no description available>",
parentPermission: PermissionId = owner.basePermission,
parentPermission: Permission = owner.parentPermission,
/** 为 `true` 时表示 [指令前缀][CommandManager.commandPrefix] 可选 */
public override val prefixOptional: Boolean = false
) : Command {

View File

@ -10,10 +10,7 @@
package net.mamoe.mirai.console.command
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.unregisterAllCommands
import net.mamoe.mirai.console.permission.ExperimentalPermission
import net.mamoe.mirai.console.permission.PermissionId
import net.mamoe.mirai.console.permission.PermissionIdNamespace
import net.mamoe.mirai.console.permission.RootPermission
import net.mamoe.mirai.console.permission.*
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
/**
@ -27,12 +24,12 @@ import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
@OptIn(ExperimentalPermission::class)
public interface CommandOwner : PermissionIdNamespace {
/**
* [PermissionIdNamespace] 拥有的指令都默认将 [basePermission] 作为父权限.
* [PermissionIdNamespace] 拥有的指令都默认将 [parentPermission] 作为父权限.
*
* TODO document
*/
@ExperimentalPermission
public val basePermission: PermissionId
public val parentPermission: Permission
}
/**
@ -40,8 +37,8 @@ public interface CommandOwner : PermissionIdNamespace {
*/
internal object ConsoleCommandOwner : CommandOwner {
@ExperimentalPermission
override val basePermission: PermissionId
get() = RootPermission.id
override val parentPermission: Permission
get() = RootPermission
@ExperimentalPermission
override fun permissionId(id: String): PermissionId = PermissionId("console", id)

View File

@ -21,7 +21,7 @@ import net.mamoe.mirai.console.command.description.*
import net.mamoe.mirai.console.internal.command.AbstractReflectionCommand
import net.mamoe.mirai.console.internal.command.CompositeCommandSubCommandAnnotationResolver
import net.mamoe.mirai.console.permission.ExperimentalPermission
import net.mamoe.mirai.console.permission.PermissionId
import net.mamoe.mirai.console.permission.Permission
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
import net.mamoe.mirai.message.data.MessageChain
import kotlin.annotation.AnnotationRetention.RUNTIME
@ -86,7 +86,7 @@ public abstract class CompositeCommand @OptIn(ExperimentalPermission::class) con
owner: CommandOwner,
vararg names: String,
description: String = "no description available",
parentPermission: PermissionId = owner.basePermission,
parentPermission: Permission = owner.parentPermission,
prefixOptional: Boolean = false,
overrideContext: CommandArgumentContext = EmptyCommandArgumentContext
) : Command, AbstractReflectionCommand(owner, names, description, parentPermission, prefixOptional),
@ -110,12 +110,6 @@ public abstract class CompositeCommand @OptIn(ExperimentalPermission::class) con
@Target(FUNCTION)
protected annotation class SubCommand(vararg val value: String)
/** 指定子指令要求的权限 */
@Retention(RUNTIME)
@Target(FUNCTION)
@ExperimentalPermission
protected annotation class Permission(val value: String)
/** 指令描述 */
@Retention(RUNTIME)
@Target(FUNCTION)

View File

@ -17,7 +17,6 @@ import net.mamoe.mirai.console.command.java.JRawCommand
import net.mamoe.mirai.console.internal.command.createOrFindCommandPermission
import net.mamoe.mirai.console.permission.ExperimentalPermission
import net.mamoe.mirai.console.permission.Permission
import net.mamoe.mirai.console.permission.PermissionId
import net.mamoe.mirai.message.data.MessageChain
/**
@ -44,7 +43,7 @@ public abstract class RawCommand @OptIn(ExperimentalPermission::class) construct
/** 指令描述, 用于显示在 [BuiltInCommands.Help] */
public override val description: String = "<no descriptions given>",
/** 指令父权限 */
parentPermission: PermissionId = owner.basePermission,
parentPermission: Permission = owner.parentPermission,
/** 为 `true` 时表示 [指令前缀][CommandManager.commandPrefix] 可选 */
public override val prefixOptional: Boolean = false
) : Command {

View File

@ -23,7 +23,7 @@ import net.mamoe.mirai.console.command.java.JSimpleCommand
import net.mamoe.mirai.console.internal.command.AbstractReflectionCommand
import net.mamoe.mirai.console.internal.command.SimpleCommandSubCommandAnnotationResolver
import net.mamoe.mirai.console.permission.ExperimentalPermission
import net.mamoe.mirai.console.permission.PermissionId
import net.mamoe.mirai.console.permission.Permission
import net.mamoe.mirai.message.data.MessageChain
/**
@ -53,10 +53,10 @@ public abstract class SimpleCommand @OptIn(ExperimentalPermission::class) constr
owner: CommandOwner,
vararg names: String,
description: String = "no description available",
basePermission: PermissionId = owner.basePermission,
parentPermission: Permission = owner.parentPermission,
prefixOptional: Boolean = false,
overrideContext: CommandArgumentContext = EmptyCommandArgumentContext
) : Command, AbstractReflectionCommand(owner, names, description, basePermission, prefixOptional),
) : Command, AbstractReflectionCommand(owner, names, description, parentPermission, prefixOptional),
CommandArgumentContextAware {
/**

View File

@ -81,6 +81,21 @@ public interface CommandArgumentParser<out T : Any> {
public fun parse(raw: MessageContent, sender: CommandSender): T = parse(raw.content, sender)
}
/**
* 使用原 [this] 解析, 成功后使用 [mapper] 映射为另一个类型.
*/
public fun <T : Any, R : Any> CommandArgumentParser<T>.map(
mapper: CommandArgumentParser<R>.(T) -> R
): CommandArgumentParser<R> = MappingCommandArgumentParser(this, mapper)
private class MappingCommandArgumentParser<T : Any, R : Any>(
private val original: CommandArgumentParser<T>,
private val mapper: CommandArgumentParser<R>.(T) -> R
) : CommandArgumentParser<R> {
override fun parse(raw: String, sender: CommandSender): R = mapper(original.parse(raw, sender))
override fun parse(raw: MessageContent, sender: CommandSender): R = mapper(original.parse(raw, sender))
}
/**
* 解析一个字符串或 [SingleMessage] [T] 类型参数
*

View File

@ -15,7 +15,7 @@ import net.mamoe.mirai.console.command.CommandOwner
import net.mamoe.mirai.console.command.CompositeCommand
import net.mamoe.mirai.console.command.description.buildCommandArgumentContext
import net.mamoe.mirai.console.permission.ExperimentalPermission
import net.mamoe.mirai.console.permission.PermissionId
import net.mamoe.mirai.console.permission.Permission
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
/**
@ -73,14 +73,14 @@ public abstract class JCompositeCommand @OptIn(ExperimentalPermission::class)
@JvmOverloads constructor(
owner: CommandOwner,
vararg names: String,
parentPermission: PermissionId = owner.basePermission,
parentPermission: Permission = owner.parentPermission,
) : CompositeCommand(owner, *names, parentPermission = parentPermission) {
/** 指令描述, 用于显示在 [BuiltInCommands.Help] */
public final override var description: String = "<no descriptions given>"
protected set
@OptIn(ExperimentalPermission::class)
public final override var permission: net.mamoe.mirai.console.permission.Permission = super.permission
public final override var permission: Permission = super.permission
protected set
/** 为 `true` 时表示 [指令前缀][CommandManager.commandPrefix] 可选 */

View File

@ -16,7 +16,6 @@ import net.mamoe.mirai.console.command.CommandManager.INSTANCE.execute
import net.mamoe.mirai.console.internal.command.createOrFindCommandPermission
import net.mamoe.mirai.console.permission.ExperimentalPermission
import net.mamoe.mirai.console.permission.Permission
import net.mamoe.mirai.console.permission.PermissionId
import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.message.data.SingleMessage
@ -55,7 +54,7 @@ public abstract class JRawCommand @OptIn(ExperimentalPermission::class)
public override val owner: CommandOwner,
/** 指令名. 需要至少有一个元素. 所有元素都不能带有空格 */
public override vararg val names: String,
parentPermission: PermissionId = owner.basePermission,
parentPermission: Permission = owner.parentPermission,
) : Command {
/** 用法说明, 用于发送给用户 */
public override var usage: String = "<no usages given>"

View File

@ -16,7 +16,6 @@ import net.mamoe.mirai.console.command.SimpleCommand
import net.mamoe.mirai.console.command.description.CommandArgumentContext
import net.mamoe.mirai.console.permission.ExperimentalPermission
import net.mamoe.mirai.console.permission.Permission
import net.mamoe.mirai.console.permission.PermissionId
/**
* Java 实现:
@ -44,8 +43,8 @@ import net.mamoe.mirai.console.permission.PermissionId
public abstract class JSimpleCommand @OptIn(ExperimentalPermission::class) constructor(
owner: CommandOwner,
vararg names: String,
basePermission: PermissionId,
) : SimpleCommand(owner, *names, basePermission = basePermission) {
basePermission: Permission,
) : SimpleCommand(owner, *names, parentPermission = basePermission) {
public override var description: String = super.description
protected set

View File

@ -18,8 +18,6 @@ import net.mamoe.mirai.console.command.description.CommandArgumentContextAware
import net.mamoe.mirai.console.internal.data.kClassQualifiedNameOrTip
import net.mamoe.mirai.console.permission.ExperimentalPermission
import net.mamoe.mirai.console.permission.Permission
import net.mamoe.mirai.console.permission.PermissionId
import net.mamoe.mirai.console.permission.PermissionService
import net.mamoe.mirai.console.permission.PermissionService.Companion.testPermission
import net.mamoe.mirai.message.data.*
import kotlin.reflect.KAnnotatedElement
@ -53,7 +51,7 @@ internal abstract class AbstractReflectionCommand @OptIn(ExperimentalPermission:
owner: CommandOwner,
names: Array<out String>,
description: String = "<no description available>",
parentPermission: PermissionId = owner.basePermission,
parentPermission: Permission = owner.parentPermission,
prefixOptional: Boolean = false
) : Command, AbstractCommand(
owner,
@ -144,7 +142,7 @@ internal abstract class AbstractReflectionCommand @OptIn(ExperimentalPermission:
argsWithSubCommandNameNotRemoved: MessageChain,
removeSubName: Boolean
) {
val args = parseArgs(sender, argsWithSubCommandNameNotRemoved, if (removeSubName) names.size else 0)
val args = parseArgs(sender, argsWithSubCommandNameNotRemoved, if (removeSubName) 1 else 0)
if (!this.permission.testPermission(sender)) {
sender.sendMessage(usage) // TODO: 2020/8/26 #127
return
@ -259,7 +257,7 @@ internal fun AbstractReflectionCommand.createSubCommand(
context: CommandArgumentContext
): AbstractReflectionCommand.SubCommandDescriptor {
val notStatic = !function.hasAnnotation<JvmStatic>()
val overridePermission = function.findAnnotation<CompositeCommand.Permission>()//optional
//val overridePermission = null//function.findAnnotation<CompositeCommand.PermissionId>()//optional
val subDescription =
function.findAnnotation<CompositeCommand.Description>()?.value ?: ""
@ -331,7 +329,7 @@ internal fun AbstractReflectionCommand.createSubCommand(
commandName,
params,
subDescription, // overridePermission?.value
overridePermission?.value?.let { PermissionService.INSTANCE[PermissionId.parseFromString(it)] } ?: permission,
permission,//overridePermission?.value?.let { PermissionService.INSTANCE[PermissionId.parseFromString(it)] } ?: permission,
onCommand = { sender: CommandSender, args: Array<out Any> ->
val result = if (notStatic) {
if (hasSenderParam) {

View File

@ -13,7 +13,6 @@ import net.mamoe.mirai.console.command.*
import net.mamoe.mirai.console.command.Command.Companion.primaryName
import net.mamoe.mirai.console.permission.ExperimentalPermission
import net.mamoe.mirai.console.permission.Permission
import net.mamoe.mirai.console.permission.PermissionId
import net.mamoe.mirai.console.permission.PermissionService
import net.mamoe.mirai.console.permission.PermissionService.Companion.testPermission
import net.mamoe.mirai.contact.Group
@ -143,7 +142,7 @@ internal fun Group.fuzzySearchMember(
}
@OptIn(ExperimentalPermission::class)
internal fun Command.createOrFindCommandPermission(parent: PermissionId): Permission {
internal fun Command.createOrFindCommandPermission(parent: Permission): Permission {
val id = owner.permissionId(primaryName)
return PermissionService.INSTANCE[id] ?: PermissionService.INSTANCE.register(id, description, parent)
}

View File

@ -16,6 +16,7 @@ import net.mamoe.mirai.console.MiraiConsole
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.Permission
import net.mamoe.mirai.console.permission.PermissionId
import net.mamoe.mirai.console.permission.PermissionService
import net.mamoe.mirai.console.permission.PermissionService.Companion.allocatePermissionIdForPlugin
@ -44,11 +45,11 @@ internal abstract class JvmPluginInternal(
) : JvmPlugin, CoroutineScope {
@OptIn(ExperimentalPermission::class)
final override val basePermission: PermissionId by lazy {
final override val parentPermission: Permission by lazy {
PermissionService.INSTANCE.register(
PermissionService.INSTANCE.allocatePermissionIdForPlugin(name, "*"),
"The base permission"
).id
)
}
final override var isEnabled: Boolean = false
@ -110,7 +111,7 @@ internal abstract class JvmPluginInternal(
}
internal fun internalOnEnable(): Boolean {
basePermission
parentPermission
if (!firstRun) refreshCoroutineContext()
kotlin.runCatching {
onEnable()

View File

@ -23,14 +23,14 @@ public abstract class AbstractConcurrentPermissionService<P : Permission> : Perm
protected abstract fun createPermission(
id: PermissionId,
description: String,
base: PermissionId = RootPermission.id
parent: Permission
): 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, parent: Permission): P {
grantedPermissionsMap[id] = CopyOnWriteArrayList() // mutations are not quite often performed
val instance = createPermission(id, description, base)
val instance = createPermission(id, description, parent)
val old = permissions.putIfAbsent(id, instance)
if (old != null) throw DuplicatedPermissionRegistrationException(instance, old)
return instance

View File

@ -9,28 +9,27 @@
package net.mamoe.mirai.console.permission
import kotlinx.serialization.Serializable
import net.mamoe.mirai.console.data.AutoSavePluginConfig
import net.mamoe.mirai.console.data.PluginDataExtensions.withDefault
import net.mamoe.mirai.console.data.value
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.CopyOnWriteArrayList
import kotlin.reflect.KClass
import kotlin.reflect.KType
import kotlin.reflect.full.createType
@ExperimentalPermission
public object AllGrantPermissionService : PermissionService<PermissionImpl> {
internal object AllGrantPermissionService : PermissionService<PermissionImpl> {
private val all = ConcurrentHashMap<PermissionId, PermissionImpl>()
override val permissionType: KClass<PermissionImpl>
get() = PermissionImpl::class
override val permissionType: KClass<PermissionImpl> get() = PermissionImpl::class
override val rootPermission: PermissionImpl get() = RootPermissionImpl
override fun register(
id: PermissionId,
description: String,
base: PermissionId
parent: Permission
): PermissionImpl {
val new = PermissionImpl(id, description, base)
val new = PermissionImpl(id, description, parent)
val old = all.putIfAbsent(id, new)
if (old != null) throw DuplicatedPermissionRegistrationException(new, old)
return new
@ -51,18 +50,23 @@ public object AllGrantPermissionService : PermissionService<PermissionImpl> {
}
}
@Suppress("DEPRECATION")
@OptIn(ExperimentalPermission::class)
private val RootPermissionImpl = PermissionImpl(PermissionId("*", "*"), "The root permission").also { it.parent = it }
@ExperimentalPermission
public object AllDenyPermissionService : PermissionService<PermissionImpl> {
internal object AllDenyPermissionService : PermissionService<PermissionImpl> {
private val all = ConcurrentHashMap<PermissionId, PermissionImpl>()
override val permissionType: KClass<PermissionImpl>
get() = PermissionImpl::class
override val rootPermission: PermissionImpl get() = RootPermissionImpl
override fun register(
id: PermissionId,
description: String,
base: PermissionId
parent: Permission
): PermissionImpl {
val new = PermissionImpl(id, description, base)
val new = PermissionImpl(id, description, parent)
val old = all.putIfAbsent(id, new)
if (old != null) throw DuplicatedPermissionRegistrationException(new, old)
return new
@ -91,27 +95,23 @@ internal object BuiltInPermissionService : AbstractConcurrentPermissionService<P
override val permissionType: KClass<PermissionImpl>
get() = PermissionImpl::class
override val permissions: MutableMap<PermissionId, PermissionImpl> = ConcurrentHashMap()
override val rootPermission: PermissionImpl
get() = RootPermissionImpl
@Suppress("UNCHECKED_CAST")
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 =
PermissionImpl(id, description, base)
override fun createPermission(id: PermissionId, description: String, parent: Permission): PermissionImpl =
PermissionImpl(id, description, parent)
internal val config: ConcurrentSaveData<PermissionImpl> =
ConcurrentSaveData(
PermissionImpl::class.createType(),
"PermissionService",
)
internal val config: ConcurrentSaveData =
ConcurrentSaveData("PermissionService")
@Suppress("RedundantVisibilityModifier")
@ExperimentalPermission
internal class ConcurrentSaveData<P : Permission> private constructor(
permissionType: KType,
internal class ConcurrentSaveData private constructor(
public override val saveName: String,
// delegate: PluginConfig,
@Suppress("UNUSED_PARAMETER") primaryConstructorMark: Any?
) : AutoSavePluginConfig() {
public val grantedPermissionMap: MutableMap<PermissionId, MutableList<AbstractPermissibleIdentifier>>
@ -120,11 +120,49 @@ internal object BuiltInPermissionService : AbstractConcurrentPermissionService<P
public companion object {
@JvmStatic
public operator fun <P : Permission> invoke(
permissionType: KType,
public operator fun invoke(
saveName: String,
// delegate: PluginConfig,
): ConcurrentSaveData<P> = ConcurrentSaveData(permissionType, saveName, null)
): ConcurrentSaveData = ConcurrentSaveData(saveName, null)
}
}
}
/**
* [Permission] 的简单实现
*/
@Serializable
@ExperimentalPermission
internal data class PermissionImpl @Deprecated("Only for Root") constructor(
override val id: PermissionId,
override val description: String,
) : Permission {
override lateinit var parent: Permission
@Suppress("DEPRECATION")
constructor(id: PermissionId, description: String, parent: Permission) : this(id, description) {
this.parent = parent
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as PermissionImpl
if (id != other.id) return false
if (description != other.description) return false
if (parent != other.parent) return false
return true
}
override fun hashCode(): Int {
var result = id.hashCode()
result = 31 * result + description.hashCode()
result = 31 * result + parent.hashCode()
return result
}
override fun toString(): String = "PermissionImpl(id=$id, description='$description', parentId=$parent)"
}

View File

@ -9,8 +9,6 @@
package net.mamoe.mirai.console.permission
import kotlinx.serialization.Serializable
import net.mamoe.mirai.console.permission.PermissionService.Companion.findCorrespondingPermission
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
@ -25,22 +23,29 @@ import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
public interface Permission {
public val id: PermissionId
public val description: String
public val parentId: PermissionId
}
@OptIn(ExperimentalPermission::class)
private val ROOT_PERMISSION_ID = PermissionId("*", "*")
/**
* [RootPermission] parent 为自身
*/
public val parent: Permission
}
/**
* 所有权限的父权限.
*/
@get:JvmName("getRootPermission")
@ExperimentalPermission
public val RootPermission: Permission by lazy {
public val RootPermission: Permission
get() = PermissionService.INSTANCE.rootPermission
/**
* 所有内建指令的权限
*/
@ExperimentalPermission
public val RootConsoleBuiltInPermission: Permission by lazy {
PermissionService.INSTANCE.register(
ROOT_PERMISSION_ID,
"The parent of any permission",
ROOT_PERMISSION_ID
PermissionId("console", "*"),
"The parent of any built-in commands"
)
}
@ -48,16 +53,5 @@ public val RootPermission: Permission by lazy {
@ExperimentalPermission
public fun Permission.parentsWithSelfSequence(): Sequence<Permission> =
generateSequence(this) { p ->
p.parentId.findCorrespondingPermission()?.takeIf { parent -> parent != p }
}
/**
* [Permission] 的简单实现
*/
@Serializable
@ExperimentalPermission
public data class PermissionImpl(
override val id: PermissionId,
override val description: String,
override val parentId: PermissionId = RootPermission.id
) : Permission
p.parent.takeIf { parent -> parent != p }
}

View File

@ -23,6 +23,7 @@ import kotlin.reflect.full.isSuperclassOf
public interface PermissionService<P : Permission> {
@ExperimentalPermission
public val permissionType: KClass<P>
public val rootPermission: P
///////////////////////////////////////////////////////////////////////////
@ -46,7 +47,7 @@ public interface PermissionService<P : Permission> {
public fun register(
id: PermissionId,
description: String,
base: PermissionId = RootPermission.id
parent: Permission = RootPermission
): P
///////////////////////////////////////////////////////////////////////////

View File

@ -35,7 +35,7 @@ internal fun startupConsoleThread() {
val next = MiraiConsole.requestInput("").let {
when {
it.startsWith(CommandManager.commandPrefix) -> it
it == "?" -> CommandManager.commandPrefix + BuiltInCommands.Help.primaryName
it == "?" -> CommandManager.commandPrefix + BuiltInCommands.HelpCommand.primaryName
else -> CommandManager.commandPrefix + it
}
}