mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-11 02:50:15 +08:00
Add builtin Permission command
This commit is contained in:
parent
c76a6dacc9
commit
8dd302073b
@ -16,17 +16,23 @@ import net.mamoe.mirai.Bot
|
|||||||
import net.mamoe.mirai.alsoLogin
|
import net.mamoe.mirai.alsoLogin
|
||||||
import net.mamoe.mirai.console.MiraiConsole
|
import net.mamoe.mirai.console.MiraiConsole
|
||||||
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.register
|
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.internal.command.CommandManagerImpl
|
import net.mamoe.mirai.console.internal.command.CommandManagerImpl
|
||||||
import net.mamoe.mirai.console.internal.command.CommandManagerImpl.allRegisteredCommands
|
import net.mamoe.mirai.console.internal.command.CommandManagerImpl.allRegisteredCommands
|
||||||
import net.mamoe.mirai.console.internal.command.qualifiedNameOrTip
|
import net.mamoe.mirai.console.internal.command.qualifiedNameOrTip
|
||||||
import net.mamoe.mirai.console.util.BotManager.INSTANCE.addManager
|
import net.mamoe.mirai.console.permission.ExperimentalPermission
|
||||||
import net.mamoe.mirai.console.util.BotManager.INSTANCE.managers
|
import net.mamoe.mirai.console.permission.PermissibleIdentifier
|
||||||
import net.mamoe.mirai.console.util.BotManager.INSTANCE.removeManager
|
import net.mamoe.mirai.console.permission.PermissionId
|
||||||
|
import net.mamoe.mirai.console.permission.PermissionService
|
||||||
|
import net.mamoe.mirai.console.permission.PermissionService.Companion.denyPermission
|
||||||
|
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
|
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
|
||||||
import net.mamoe.mirai.console.util.ConsoleInternalAPI
|
import net.mamoe.mirai.console.util.ConsoleInternalAPI
|
||||||
import net.mamoe.mirai.contact.*
|
import net.mamoe.mirai.contact.*
|
||||||
import net.mamoe.mirai.event.events.EventCancelledException
|
import net.mamoe.mirai.event.events.EventCancelledException
|
||||||
import net.mamoe.mirai.getFriendOrNull
|
|
||||||
import net.mamoe.mirai.message.nextMessageOrNull
|
import net.mamoe.mirai.message.nextMessageOrNull
|
||||||
import net.mamoe.mirai.utils.secondsToMillis
|
import net.mamoe.mirai.utils.secondsToMillis
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
@ -57,30 +63,6 @@ public object BuiltInCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public object Managers : CompositeCommand(
|
|
||||||
ConsoleCommandOwner, "managers",
|
|
||||||
description = "Manage the managers for each bot"
|
|
||||||
), BuiltInCommand {
|
|
||||||
@SubCommand
|
|
||||||
public suspend fun CommandSender.add(target: User) {
|
|
||||||
target.bot.addManager(target.id)
|
|
||||||
sendMessage("已成功添加 ${target.render()} 为 ${target.bot.render()} 的管理员")
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubCommand
|
|
||||||
public suspend fun CommandSender.remove(target: User) {
|
|
||||||
target.bot.removeManager(target.id)
|
|
||||||
sendMessage("已成功取消 ${target.render()} 对 ${target.bot.render()} 的管理员权限")
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubCommand
|
|
||||||
public suspend fun CommandSender.list(bot: Bot) {
|
|
||||||
sendMessage("$bot 的管理员列表:\n" + bot.managers.joinToString("\n") {
|
|
||||||
bot.getFriendOrNull(it)?.render() ?: it.toString()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public object Help : SimpleCommand(
|
public object Help : SimpleCommand(
|
||||||
ConsoleCommandOwner, "help",
|
ConsoleCommandOwner, "help",
|
||||||
description = "Command list"
|
description = "Command list"
|
||||||
@ -136,7 +118,7 @@ public object BuiltInCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public object Login : SimpleCommand(
|
public object Login : SimpleCommand(
|
||||||
ConsoleCommandOwner, "login",
|
ConsoleCommandOwner, "login", "登录",
|
||||||
description = "Log in a bot account."
|
description = "Log in a bot account."
|
||||||
), BuiltInCommand {
|
), BuiltInCommand {
|
||||||
@Handler
|
@Handler
|
||||||
@ -161,6 +143,40 @@ public object BuiltInCommands {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalPermission::class)
|
||||||
|
public object Permission : CompositeCommand(
|
||||||
|
ConsoleCommandOwner, "permission", "权限",
|
||||||
|
description = "Manage permissions",
|
||||||
|
overrideContext = buildCommandArgumentContext {
|
||||||
|
PermissibleIdentifier::class with PermissibleIdentifierArgumentParser
|
||||||
|
PermissionId::class with PermissionIdArgumentParser
|
||||||
|
}
|
||||||
|
), BuiltInCommand {
|
||||||
|
// TODO: 2020/9/10 improve Permission command
|
||||||
|
@SubCommand
|
||||||
|
public suspend fun CommandSender.grant(target: PermissibleIdentifier, permission: PermissionId) {
|
||||||
|
target.grantPermission(permission)
|
||||||
|
sendMessage("OK")
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubCommand
|
||||||
|
public suspend fun CommandSender.deny(target: PermissibleIdentifier, permission: PermissionId) {
|
||||||
|
target.denyPermission(permission)
|
||||||
|
sendMessage("OK")
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubCommand("grantedPermissions", "gp")
|
||||||
|
public suspend fun CommandSender.grantedPermissions(target: PermissibleIdentifier) {
|
||||||
|
val grantedPermissions = target.getGrantedPermissions()
|
||||||
|
sendMessage(grantedPermissions.joinToString("\n") { it.id.toString() })
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubCommand("listPermissions", "lp")
|
||||||
|
public suspend fun CommandSender.listPermissions() {
|
||||||
|
sendMessage(PermissionService.INSTANCE.getRegisteredPermissions().joinToString("\n") { it.id.toString() })
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline fun <reified E : Throwable, R> ignoreException(block: () -> R): R? {
|
internal inline fun <reified E : Throwable, R> ignoreException(block: () -> R): R? {
|
||||||
|
@ -11,7 +11,12 @@ package net.mamoe.mirai.console.command.description
|
|||||||
|
|
||||||
import net.mamoe.mirai.Bot
|
import net.mamoe.mirai.Bot
|
||||||
import net.mamoe.mirai.console.command.*
|
import net.mamoe.mirai.console.command.*
|
||||||
|
import net.mamoe.mirai.console.command.CommandSender.Companion.asCommandSender
|
||||||
import net.mamoe.mirai.console.internal.command.fuzzySearchMember
|
import net.mamoe.mirai.console.internal.command.fuzzySearchMember
|
||||||
|
import net.mamoe.mirai.console.permission.AbstractPermissibleIdentifier
|
||||||
|
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.contact.*
|
import net.mamoe.mirai.contact.*
|
||||||
import net.mamoe.mirai.getFriendOrNull
|
import net.mamoe.mirai.getFriendOrNull
|
||||||
import net.mamoe.mirai.getGroupOrNull
|
import net.mamoe.mirai.getGroupOrNull
|
||||||
@ -303,6 +308,31 @@ public object ExistingMemberArgumentParser : InternalCommandArgumentParserExtens
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExperimentalPermission
|
||||||
|
public object PermissionIdArgumentParser : CommandArgumentParser<PermissionId> {
|
||||||
|
override fun parse(raw: String, sender: CommandSender): PermissionId {
|
||||||
|
return kotlin.runCatching { PermissionId.parseFromString(raw) }.getOrElse {
|
||||||
|
illegalArgument("无法解析 $raw 为 PermissionId")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalPermission
|
||||||
|
public object PermissibleIdentifierArgumentParser : CommandArgumentParser<PermissibleIdentifier> {
|
||||||
|
override fun parse(raw: String, sender: CommandSender): PermissibleIdentifier {
|
||||||
|
return kotlin.runCatching { AbstractPermissibleIdentifier.parseFromString(raw) }.getOrElse {
|
||||||
|
illegalArgument("无法解析 $raw 为 PermissionId")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun parse(raw: MessageContent, sender: CommandSender): PermissibleIdentifier {
|
||||||
|
if (raw is At) {
|
||||||
|
return ExistingUserArgumentParser.parse(raw, sender).asCommandSender(false).identifier
|
||||||
|
}
|
||||||
|
return super.parse(raw, sender)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal interface InternalCommandArgumentParserExtensions<T : Any> : CommandArgumentParser<T> {
|
internal interface InternalCommandArgumentParserExtensions<T : Any> : CommandArgumentParser<T> {
|
||||||
fun String.parseToLongOrFail(): Long = toLongOrNull() ?: illegalArgument("无法解析 $this 为整数")
|
fun String.parseToLongOrFail(): Long = toLongOrNull() ?: illegalArgument("无法解析 $this 为整数")
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ public abstract class AbstractConcurrentPermissionService<P : Permission> : Perm
|
|||||||
grantedPermissionsMap[permission.id]?.remove(permissibleIdentifier)
|
grantedPermissionsMap[permission.id]?.remove(permissibleIdentifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getRegisteredPermissions(): Sequence<P> = permissions.values.asSequence()
|
||||||
public override fun getGrantedPermissions(permissibleIdentifier: PermissibleIdentifier): Sequence<P> = sequence<P> {
|
public override fun getGrantedPermissions(permissibleIdentifier: PermissibleIdentifier): Sequence<P> = sequence<P> {
|
||||||
for ((permissionIdentifier, permissibleIdentifiers) in grantedPermissionsMap) {
|
for ((permissionIdentifier, permissibleIdentifiers) in grantedPermissionsMap) {
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ public object AllGrantPermissionService : PermissionService<PermissionImpl> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun get(id: PermissionId): PermissionImpl? = all[id]
|
override fun get(id: PermissionId): PermissionImpl? = all[id]
|
||||||
|
override fun getRegisteredPermissions(): Sequence<PermissionImpl> = all.values.asSequence()
|
||||||
override fun getGrantedPermissions(permissibleIdentifier: PermissibleIdentifier): Sequence<PermissionImpl> =
|
override fun getGrantedPermissions(permissibleIdentifier: PermissibleIdentifier): Sequence<PermissionImpl> =
|
||||||
all.values.asSequence()
|
all.values.asSequence()
|
||||||
|
|
||||||
@ -68,6 +69,7 @@ public object AllDenyPermissionService : PermissionService<PermissionImpl> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun get(id: PermissionId): PermissionImpl? = all[id]
|
override fun get(id: PermissionId): PermissionImpl? = all[id]
|
||||||
|
override fun getRegisteredPermissions(): Sequence<PermissionImpl> = all.values.asSequence()
|
||||||
override fun getGrantedPermissions(permissibleIdentifier: PermissibleIdentifier): Sequence<PermissionImpl> =
|
override fun getGrantedPermissions(permissibleIdentifier: PermissibleIdentifier): Sequence<PermissionImpl> =
|
||||||
emptySequence()
|
emptySequence()
|
||||||
|
|
||||||
|
@ -43,13 +43,26 @@ public interface PermissibleIdentifier {
|
|||||||
public sealed class AbstractPermissibleIdentifier(
|
public sealed class AbstractPermissibleIdentifier(
|
||||||
public final override vararg val parents: PermissibleIdentifier
|
public final override vararg val parents: PermissibleIdentifier
|
||||||
) : PermissibleIdentifier {
|
) : PermissibleIdentifier {
|
||||||
internal companion object {
|
public companion object {
|
||||||
val objects by lazy {
|
@JvmStatic
|
||||||
|
public fun parseFromString(string: String): AbstractPermissibleIdentifier {
|
||||||
|
val str = string.trim()
|
||||||
|
objects.find { it.toString() == str }?.let { return it as AbstractPermissibleIdentifier }
|
||||||
|
for ((regex, block) in regexes) {
|
||||||
|
val result = regex.find(str) ?: continue
|
||||||
|
if (result.range.last != str.lastIndex) continue
|
||||||
|
if (result.range.first != 0) continue
|
||||||
|
return result.destructured.run(block)
|
||||||
|
}
|
||||||
|
error("Cannot deserialize '$str' as AbstractPermissibleIdentifier")
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val objects by lazy {
|
||||||
// https://youtrack.jetbrains.com/issue/KT-41782
|
// https://youtrack.jetbrains.com/issue/KT-41782
|
||||||
AbstractPermissibleIdentifier::class.nestedClasses.mapNotNull { it.objectInstance }
|
AbstractPermissibleIdentifier::class.nestedClasses.mapNotNull { it.objectInstance }
|
||||||
}
|
}
|
||||||
|
|
||||||
val regexes: List<Pair<Regex, (matchGroup: MatchResult.Destructured) -> AbstractPermissibleIdentifier>> =
|
internal val regexes: List<Pair<Regex, (matchGroup: MatchResult.Destructured) -> AbstractPermissibleIdentifier>> =
|
||||||
listOf(
|
listOf(
|
||||||
Regex("""ExactGroup\(\s*([0-9]+)\s*\)""") to { (id) -> ExactGroup(id.toLong()) },
|
Regex("""ExactGroup\(\s*([0-9]+)\s*\)""") to { (id) -> ExactGroup(id.toLong()) },
|
||||||
Regex("""ExactFriend\(\s*([0-9]+)\s*\)""") to { (id) -> ExactFriend(id.toLong()) },
|
Regex("""ExactFriend\(\s*([0-9]+)\s*\)""") to { (id) -> ExactFriend(id.toLong()) },
|
||||||
@ -69,17 +82,7 @@ public sealed class AbstractPermissibleIdentifier(
|
|||||||
public object AsStringSerializer : KSerializer<AbstractPermissibleIdentifier> by String.serializer().map(
|
public object AsStringSerializer : KSerializer<AbstractPermissibleIdentifier> by String.serializer().map(
|
||||||
serializer = { it.toString() },
|
serializer = { it.toString() },
|
||||||
|
|
||||||
deserializer = d@{ str ->
|
deserializer = d@{ str -> parseFromString(str) }
|
||||||
@Suppress("NAME_SHADOWING") val str = str.trim()
|
|
||||||
objects.find { it.toString() == str }?.let { return@d it as AbstractPermissibleIdentifier }
|
|
||||||
for ((regex, block) in regexes) {
|
|
||||||
val result = regex.find(str) ?: continue
|
|
||||||
if (result.range.last != str.lastIndex) continue
|
|
||||||
if (result.range.first != 0) continue
|
|
||||||
return@d result.destructured.run(block)
|
|
||||||
}
|
|
||||||
error("Cannot deserialize '$str' as AbstractPermissibleIdentifier")
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
public object AnyGroup : AbstractPermissibleIdentifier(AnyContact) {
|
public object AnyGroup : AbstractPermissibleIdentifier(AnyContact) {
|
||||||
|
@ -28,6 +28,7 @@ public interface PermissionService<P : Permission> {
|
|||||||
|
|
||||||
public operator fun get(id: PermissionId): P?
|
public operator fun get(id: PermissionId): P?
|
||||||
|
|
||||||
|
public fun getRegisteredPermissions(): Sequence<P>
|
||||||
public fun getGrantedPermissions(permissibleIdentifier: PermissibleIdentifier): Sequence<P>
|
public fun getGrantedPermissions(permissibleIdentifier: PermissibleIdentifier): Sequence<P>
|
||||||
|
|
||||||
public fun testPermission(permissibleIdentifier: PermissibleIdentifier, permission: P): Boolean {
|
public fun testPermission(permissibleIdentifier: PermissibleIdentifier, permission: P): Boolean {
|
||||||
@ -74,6 +75,18 @@ public interface PermissionService<P : Permission> {
|
|||||||
INSTANCE.checkType(permission::class).grant(this, permission)
|
INSTANCE.checkType(permission::class).grant(this, permission)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun PermissibleIdentifier.grantPermission(permissionId: PermissionId) {
|
||||||
|
grantPermission(permissionId.findCorrespondingPermissionOrFail())
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun PermissibleIdentifier.denyPermission(permission: Permission) {
|
||||||
|
INSTANCE.checkType(permission::class).deny(this, permission)
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun PermissibleIdentifier.denyPermission(permissionId: PermissionId) {
|
||||||
|
denyPermission(permissionId.findCorrespondingPermissionOrFail())
|
||||||
|
}
|
||||||
|
|
||||||
public fun Permissible.hasPermission(permission: Permission): Boolean =
|
public fun Permissible.hasPermission(permission: Permission): Boolean =
|
||||||
permission.testPermission(this@hasPermission)
|
permission.testPermission(this@hasPermission)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user