Improve /permissions listPermissions

This commit is contained in:
Karlatemp 2022-03-08 13:37:05 +08:00 committed by Him188
parent 30f1f98a83
commit ffcc489455

View File

@ -39,6 +39,7 @@ import net.mamoe.mirai.console.internal.pluginManagerImpl
import net.mamoe.mirai.console.internal.util.runIgnoreException
import net.mamoe.mirai.console.permission.Permission
import net.mamoe.mirai.console.permission.Permission.Companion.parentsWithSelf
import net.mamoe.mirai.console.permission.PermissionId
import net.mamoe.mirai.console.permission.PermissionService
import net.mamoe.mirai.console.permission.PermissionService.Companion.cancel
import net.mamoe.mirai.console.permission.PermissionService.Companion.findCorrespondingPermissionOrFail
@ -273,9 +274,94 @@ public object BuiltInCommands {
@Description("查看所有权限列表")
@SubCommand("listPermissions", "lp")
public suspend fun CommandSender.listPermissions() {
sendMessage(
PermissionService.INSTANCE.getRegisteredPermissions()
.joinToString("\n") { it.id.toString() + " " + it.description })
class PermTree(
val perm: Permission,
val sub: MutableList<PermissionId> = mutableListOf(),
)
val rootView = PermTree(PermissionService.INSTANCE.rootPermission)
val mappings = mutableMapOf<PermissionId, PermTree>()
val permListSnapshot = PermissionService.INSTANCE.getRegisteredPermissions().toList()
permListSnapshot.forEach { perm ->
mappings[perm.id] = PermTree(perm)
}
mappings[rootView.perm.id] = rootView
permListSnapshot.forEach { perm ->
if (perm.id == rootView.perm.id) return@forEach
val parentView = mappings[perm.parent.id] ?: error("Can't find parent of ${perm.id}: ${perm.parent.id}")
parentView.sub.add(perm.id)
}
mappings.values.forEach { view ->
view.sub.sortWith { p1, p2 ->
val namespaceCompare = p1.namespace compareTo p2.namespace
if (namespaceCompare != 0) return@sortWith namespaceCompare
if (p1.name == p2.name) return@sortWith 0 // ?
if (p1.name == "*") return@sortWith -1
if (p2.name == "*") return@sortWith 1
return@sortWith p1.name compareTo p2.name
}
}
//*:*
// | `-
// |- .....
// | | `-
// | |- ......
// | | | `-
// | | |-
val prefixed = 50
fun renderDepth(depth: Int, sb: AnsiMessageBuilder) {
repeat(depth) { sb.append(" | ") }
}
fun render(depth: Int, view: PermTree, sb: AnsiMessageBuilder) {
kotlin.run { // render perm id
var doReset = false
val permId = view.perm.id
if (permId == rootView.perm.id || permId.name.endsWith("*")) {
doReset = true
sb.red()
}
sb.append(permId)
if (doReset) {
sb.reset()
}
}
val linePrefixLen =
(depth * 3) + 1 + view.perm.id.let { it.name.length + it.namespace.length } + (if (depth == 0) 0 else 1)
val descFlatten = view.perm.description.replace("\r\n", "\n").replace("\r", "\n")
if (!descFlatten.contains('\n') && linePrefixLen < prefixed) {
if (descFlatten.isNotBlank()) {
repeat(prefixed - linePrefixLen) { sb.append(' ') }
sb.append(" ").append(descFlatten)
}
} else {
descFlatten.splitToSequence('\n').forEach { line ->
sb.append('\n')
renderDepth(depth, sb)
sb.append(" | `- ").append(line)
}
}
sb.append('\n')
view.sub.forEach { sub ->
val subView = mappings[sub] ?: return@forEach
renderDepth(depth, sb)
sb.append(" |- ")
render(depth + 1, subView, sb)
}
}
sendAnsiMessage {
render(0, rootView, this)
}
}
}