diff --git a/README.md b/README.md index f2286a8..870cc69 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,9 @@ commands = kommand(this) { ``` - `permissions { ... }` で名前空間やルートセグメント (`rootSegment = "command"`) を定義すると、`hareworks.command.eco`, `hareworks.command.eco.give` のような ID が自動生成され、`permits-lib` の `MutationSession` を使って Bukkit に適用されます。 -- 各 `command`/`literal`/`argument` ブロック内で `permission { ... }` を宣言すると、説明文・デフォルト値・タグ・パスの上書きを細かく制御できます。`skipPermission()` を呼び出せば、そのノードだけ自動生成から除外されます。 +- `literal` や `command` ノードはデフォルトで Bukkit パーミッションとして登録されます。`string` や `integer` などの引数ノードは、`requires("permission.id")` もしくは `permission { id = ... }` を記述した場合のみ登録され、それ以外は構造上のノードに留まります。これにより `/money give ` では `...money.give` だけ付与すれば実行できます。 +- 各ブロック内の `permission { ... }` で説明文・デフォルト値 (`PermissionDefault.TRUE/FALSE/OP/NOT_OP`)・タグ・パスを細かく制御できます。`requires(...)` を使うと DSL での検証と permits 側の登録が同じ ID になります。 +- 引数ノードを明示的に登録したい場合は `permission { id = "example.money.give.amount" }` や `requires("example.money.give.amount")` を設定してください。逆にリテラルでも不要なら `skipPermission()` で除外できます。 - `requires("custom.id")` を指定した場合も、同じ ID が DSL の実行と `permits-lib` への登録の両方で利用されます (名前空間外の ID は登録対象外になります)。 - `KommandLib` のライフサイクルに合わせて `MutationSession` が適用/解除されるため、プラグインの有効化・無効化に伴い Bukkit のパーミッションリストも最新状態に保たれます。 diff --git a/permits-lib b/permits-lib index 29dc1f1..58ad0e6 160000 --- a/permits-lib +++ b/permits-lib @@ -1 +1 @@ -Subproject commit 29dc1f10dda3c24992796788f126fb457c8f6261 +Subproject commit 58ad0e67c9b4c46a74019d4de11c0b72a37e3db7 diff --git a/src/main/kotlin/net/hareworks/kommand-lib/dsl/RegistryBuilders.kt b/src/main/kotlin/net/hareworks/kommand-lib/dsl/RegistryBuilders.kt index 733e47f..a373b43 100644 --- a/src/main/kotlin/net/hareworks/kommand-lib/dsl/RegistryBuilders.kt +++ b/src/main/kotlin/net/hareworks/kommand-lib/dsl/RegistryBuilders.kt @@ -126,6 +126,7 @@ abstract class BranchScope internal constructor( val node = ValueNode(name, type) node.permission = inheritedPermission node.condition = inheritedCondition + node.permissionOptions.preferSkipByDefault = true children += node ValueBuilder(node).apply(block) } diff --git a/src/main/kotlin/net/hareworks/kommand-lib/permissions/PermissionOptions.kt b/src/main/kotlin/net/hareworks/kommand-lib/permissions/PermissionOptions.kt index 1b9c5b4..c3271ea 100644 --- a/src/main/kotlin/net/hareworks/kommand-lib/permissions/PermissionOptions.kt +++ b/src/main/kotlin/net/hareworks/kommand-lib/permissions/PermissionOptions.kt @@ -10,6 +10,7 @@ class PermissionOptions { val tags: MutableSet = linkedSetOf() var skip: Boolean = false private var customPath: MutableList? = null + internal var preferSkipByDefault: Boolean = false internal var resolvedId: String? = null private set diff --git a/src/main/kotlin/net/hareworks/kommand-lib/permissions/PermissionPlan.kt b/src/main/kotlin/net/hareworks/kommand-lib/permissions/PermissionPlan.kt index f28d115..c69c709 100644 --- a/src/main/kotlin/net/hareworks/kommand-lib/permissions/PermissionPlan.kt +++ b/src/main/kotlin/net/hareworks/kommand-lib/permissions/PermissionPlan.kt @@ -1,5 +1,6 @@ package net.hareworks.kommand_lib.permissions +import net.hareworks.permits_lib.domain.NodeRegistration import org.bukkit.permissions.PermissionDefault data class PermissionPlan( @@ -17,5 +18,6 @@ data class PlannedPermission( val description: String?, val defaultValue: PermissionDefault, val wildcard: Boolean, - val tags: Set + val tags: Set, + val registration: NodeRegistration ) diff --git a/src/main/kotlin/net/hareworks/kommand-lib/permissions/PermissionPlanner.kt b/src/main/kotlin/net/hareworks/kommand-lib/permissions/PermissionPlanner.kt index e70fce7..43c1c3f 100644 --- a/src/main/kotlin/net/hareworks/kommand-lib/permissions/PermissionPlanner.kt +++ b/src/main/kotlin/net/hareworks/kommand-lib/permissions/PermissionPlanner.kt @@ -4,6 +4,7 @@ import net.hareworks.kommand_lib.CommandDefinition import net.hareworks.kommand_lib.nodes.KommandNode import net.hareworks.kommand_lib.nodes.LiteralNode import net.hareworks.kommand_lib.nodes.ValueNode +import net.hareworks.permits_lib.domain.NodeRegistration import org.bukkit.plugin.java.JavaPlugin internal class PermissionPlanner( @@ -18,7 +19,8 @@ internal class PermissionPlanner( val entry = createEntry( options = PermissionOptions().apply { id = buildId(path) }, pathSegments = path, - context = PermissionContext(commandName = "", path = path, kind = PermissionNodeKind.LITERAL) + context = PermissionContext(commandName = "", path = path, kind = PermissionNodeKind.LITERAL), + registration = NodeRegistration.STRUCTURAL ) if (entry != null) entries[entry.id] = entry path @@ -59,14 +61,20 @@ internal class PermissionPlanner( entries: MutableMap, commandName: String ) { - if (node.permissionOptions.skip) { - node.children.forEach { child -> - planNode(child, basePath, entries, commandName) - } + val rawOverride = node.permissionOptions.pathOverride() + val shouldSkip = + node.permissionOptions.skip || + (node.permissionOptions.preferSkipByDefault && + node.permissionOptions.id.isNullOrBlank() && + rawOverride == null) + if (shouldSkip) { + node.children.forEach { child -> + planNode(child, basePath, entries, commandName) + } return } val segment = node.segment()?.let { sanitize(it) } - val pathAddition = node.permissionOptions.pathOverride()?.let { normalizeSegments(it) } + val pathAddition = rawOverride?.let { normalizeSegments(it) } val path = when { pathAddition != null -> basePath + pathAddition segment != null -> basePath + segment @@ -100,7 +108,8 @@ internal class PermissionPlanner( private fun createEntry( options: PermissionOptions, pathSegments: List, - context: PermissionContext + context: PermissionContext, + registration: NodeRegistration = NodeRegistration.PERMISSION ): PlannedPermission? { val finalId = (options.id?.takeIf { it.isNotBlank() } ?: buildId(pathSegments)).trim() if (finalId.isEmpty()) return null @@ -124,7 +133,8 @@ internal class PermissionPlanner( description = description, defaultValue = defaultValue, wildcard = wildcard, - tags = tags + tags = tags, + registration = registration ) } diff --git a/src/main/kotlin/net/hareworks/kommand-lib/permissions/PermissionRuntime.kt b/src/main/kotlin/net/hareworks/kommand-lib/permissions/PermissionRuntime.kt index a641040..35b9a00 100644 --- a/src/main/kotlin/net/hareworks/kommand-lib/permissions/PermissionRuntime.kt +++ b/src/main/kotlin/net/hareworks/kommand-lib/permissions/PermissionRuntime.kt @@ -2,6 +2,7 @@ package net.hareworks.kommand_lib.permissions import net.hareworks.permits_lib.bukkit.MutationSession import net.hareworks.permits_lib.domain.MutablePermissionTree +import net.hareworks.permits_lib.domain.NodeRegistration import org.bukkit.plugin.java.JavaPlugin internal class PermissionRuntime( @@ -15,8 +16,18 @@ internal class PermissionRuntime( if (plan.isEmpty()) return val mutable = MutablePermissionTree.create(plan.config.namespace) val sorted = plan.entries.sortedBy { it.relativePath.size } + val registrations = sorted + .mapNotNull { entry -> + entry.relativePath.takeIf { it.isNotEmpty() }?.joinToString(".")?.let { it to entry.registration } + } + .toMap() sorted.forEach { entry -> - mutable.node(entry.relativePath.joinToString(".")) { + if (entry.relativePath.isEmpty()) { + plugin.logger.warning("Skipping permission '${entry.id}' because it resolved to the namespace root.") + return@forEach + } + val nodeId = entry.relativePath.joinToString(".") + mutable.node(nodeId, entry.registration) { entry.description?.let { description = it } defaultValue = entry.defaultValue wildcard = entry.wildcard @@ -24,7 +35,9 @@ internal class PermissionRuntime( } val parent = entry.parentPath if (parent != null && parent.isNotEmpty()) { - mutable.node(parent.joinToString(".")) { + val parentId = parent.joinToString(".") + val parentRegistration = registrations[parentId] ?: NodeRegistration.STRUCTURAL + mutable.node(parentId, parentRegistration) { child(entry.relativePath.last()) } }