Repository navigation
feat(command): gates answer refused players with the plugin's line - #87
Merged
Merged
Conversation
…n's line, not Brigadier's
… suggestions, trim hidden words from completions, and check the class node in the executor
siracozmen01
added a commit
that referenced
this pull request
Nov 4, 2026
🤖 I have created a release *beep* *boop* --- ## [0.8.0](uxm-lib-v0.7.0...uxm-lib-v0.8.0) (2026-11-04) ### Features * **command:** gates answer refused players with the plugin's line ([#87](#87)) ([0e726da](0e726da)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Sirac Ozmen <siracozmen@protonmail.com>
siracozmen01
added a commit
to UXPLIMA/uxm-essentials
that referenced
this pull request
Nov 4, 2026
) The customer report behind UXPLIMA/uxm-lib#87: `/kits editor` answered `Incorrect argument for command` when the player lacked `uxmessentials.kit.edit`. - Every `requires(src -> src.getSender().hasPermission(X))` (356) and the helpers built on it (`/worlds` `p()`, the NPC and hologram capabilities, the either-node roots of `/skin`, `/invrestore`, `/ranks`, `/poses`) are now `Gate`s. The `/pwarp sponsor` word is `Gate.when(sponsor on)` joined with its node. - `GateBinding` seals each published command right before the `LocaleBinding`, so a refusal is the catalog line in the player's language: `command.no-permission`, or the new `command.unavailable` (12 languages) for a feature that is off. - One `GateVisibility` listener trims each player's command list and completions; a command reload clears and refills it. Checked on ess-folia (Folia) against a local uxmLib snapshot: a player typing `/kits editor`, `/worlds create foo`, `/guard define test` or `/npc create bob` read "you don't have permission."; the command tree sent to that player lacked every staff word and `/npc`, an operator's held all of them. `./gradlew build` green against the snapshot. Builds against uxm-gradle 0.7.0, which pins uxmLib 0.8.0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A customer read
Incorrect argument for command kits editor<--[HERE]and nothing in the console (2026-11-04). Brigadier'srequireshides a word from the client's command list and from the parser at once, and the parser tries only the literal a typed word matches, so a sender without the node reads Brigadier's own text: not the plugin's line, not which node. The same happens to every@Permissionbranch the annotation layer renders, throughCmd.visibility.This separates the two jobs.
Gate: who sees a node (shows) and who may use it (allows). As a requirement it always passes, so the parser accepts every word.Gate.permission,Gate.visibility(keeps thedefault: truemeaning),Gate.shownTo(a word for some readers, usable by everyone),Gate.when(a feature that is off),Gate.open, joined withand/or; a plain predicate cannot be joined in, since it would always pass.CommandGates.seal: rebuilds a tree so every executor and every suggestion below a gate asks the gates on its path first and answers a refusal with the plugin'sRefusal. The gates are read at seal time, so a Paper alias that redirects to the root still passes the root's gate. A tree with a gate may not redirect anywhere.GateVisibility: one listener per plugin; trims each player's command list and the completions the server sends of what a gate hides from them. Geyser translates the same list.CommandRegistrarseals and listens; a new overload takes aRefusal, the old one answers with the server's permission message.AnnotatedCommandsrefuses withCommandMessages.noPermission. The executor of an annotated branch now checks the class node as well as its own.Cmd.permissionandCmd.visibilitykeep their native meaning and are deprecated.17 tests run the trees in a real
CommandDispatcher: refusals, suggestions (custom and the argument type's own), pruning, words for some readers, redirects, joined gates, the class node. Checked on a Folia server through uxmEssentials built on this snapshot: a player typing/kits editor,/worlds create,/guard defineor/npc createreads the catalog's no-permission line; the tree each player was sent, captured after the listener, lacked every staff word for the player and held all of them for an operator.Goes with UXPLIMA/uxm-essentials feat/command-gates and UXPLIMA/.github#39.