Content generated with AI — it may contain mistakes.

Reference

Permissions

Every node, the two kinds they come in, and why the ownership nodes are deliberately left undeclared.

The design in one paragraph

There are two kinds of node here, and the difference is not their name — it is whether plugin.yml declares them.

The nodes a player needs to use the plugin at all are declared, each with a default, so a fresh install works before you have configured a permission plugin: everybody can open the menu, whisper and show what they hold, and only operators can run the admin command. Every node that says a player owns a cosmetic is deliberately not declared. An undeclared node in Bukkit defaults to operators only, so nothing in the catalogue is anybody's until you say so — which is exactly what makes a cosmetic something you grant rather than something everyone already has.

Do not add ownership nodes to a wildcard group

exyliachatcosmetics.* is a real node and it owns everything. A permission plugin that hands a default group * or exyliachatcosmetics.* gives every player the whole catalogue, and no grant, expiry or purchase will ever matter again.

Using the plugin

NodeGrantsDefault
exyliachatcosmetics.command.cosmetics/chatcosmetics, every player subcommand, the four shortcuts and the menustrue
exyliachatcosmetics.admin/chatcosmeticsadmin and every one of its subcommandsop
exyliachatcosmetics.customtag.createmay write custom tags; a create token pays for eachtrue
exyliachatcosmetics.customcolor.createmay mix custom chat colourstrue
exyliachatcosmetics.customnick.createmay mix custom nick colourstrue
exyliachatcosmetics.customrank.createmay mix custom rank colourstrue

The four .create nodes are permission to make one at all. How many a player may then make is a token balance, not a node — see Tokens.

Owning a cosmetic

Four shapes, checked in this order. Any one of them owns it.

NodeOwns
exyliachatcosmetics.<type>.<id>one cosmetic — exyliachatcosmetics.tag.mvp, exyliachatcosmetics.font.fraktur
exyliachatcosmetics.<type>.category.<category>every cosmetic in that tab — exyliachatcosmetics.chat_color.category.premium
exyliachatcosmetics.<type>.*every cosmetic of that type
exyliachatcosmetics.*everything

The types are tag, nick_color, rank_color, chat_color, shadow_color, font and modifier — the seven that come from files. The four a player writes for themselves — customtag, customcolor, customnick, customrank — have no ownership nodes at all: whoever made one owns it, permanently, the way a node would.

The permission is asked live, every time, and never stored. That is why revoking a node takes effect the moment it is revoked, even for a player who is offline while you do it.

The two exceptions

An entry may write permission: false, and then the ownership nodes above are not consulted for it at all. It is held only through a grant — /cca give, a purchase, an API call. Use it for anything that must be bought or won rather than assigned to a group.

Rank colours start from the opposite default. Everywhere else an entry that says nothing about permission is read as permission: true. In rank-colors.yml an entry that does not mention permission is read as false instead, and ownership falls to the entry's groups list:

The entry saysWho owns it
neither groups nor permissionevery rank — the palette the whole server shares
groups: [admin, mod]anybody the permission plugin puts in one of those groups
permission: truethe ordinary rules again: exyliachatcosmetics.rank_color.<id>, its category, its wildcards, or a grant

That is the mechanism, not a description of the type: all three cases are in the shipped file. Of its 77 entries the 15 in SOLID name neither, so every rank may wear them; the 12 in METAL, 15 in GEMS, 15 in GRADIENT and 12 in ANIMATED each write permission: true, so they need a node or a grant like anything else; and only the 8 in STAFF are owned by groups. A player in admin wears the admin colour because they are in admin, and stops wearing it the day they are not — which is why that tab needs no node at all, and why the group names in it are guesses at yours and want editing. Group membership comes from LuckPerms, so rank colours need it.

The chat module

Every node below applies only while the module is running. Nothing here is checked with it off.

Commands

NodeGrantsDefault
exyliachatcosmetics.chat.command.msg/msg /tell /w /whispertrue
exyliachatcosmetics.chat.command.reply/reply /rtrue
exyliachatcosmetics.chat.command.ignore/ignoretrue
exyliachatcosmetics.chat.command.ignoreall/ignorealltrue
exyliachatcosmetics.chat.command.channel/channel /chtrue
exyliachatcosmetics.chat.command.spymsg/spymsg /socialspyop
exyliachatcosmetics.chat.command.mutechat/mutechatop
exyliachatcosmetics.chat.command.clearchat/clearchatop
exyliachatcosmetics.chat.command.broadcast/broadcast /bcop

A command whose switch in chat/config.yml → commands is off is not registered at all, and its node then grants nothing.

What a player may write

NodeGrantsDefault
exyliachatcosmetics.chat.mentionsnaming a player highlights and nudges them, @ or nottrue
exyliachatcosmetics.chat.render.item[item] shows what they holdtrue
exyliachatcosmetics.chat.render.inv[inv] shows their inventorytrue
exyliachatcosmetics.chat.render.ec[ec] shows their ender chesttrue
exyliachatcosmetics.chat.linkstheir URLs are drawn clickableop
exyliachatcosmetics.chat.formattheir own & codes, MiniMessage tags and palette tokens survive the sanitiserop
chat.format is not a cosmetic

exyliachatcosmetics.chat.format bypasses chat.sanitize, which means a player who holds it can write any colour, any hover and any click into the chat. It is op by default for that reason. Give it to staff, not to a donor rank that only wants a colour — a chat colour cosmetic is what that rank should get.

Staff

NodeGrantsDefault
exyliachatcosmetics.chat.staffcounts as staff: their private messages cannot be ignoredop
exyliachatcosmetics.chat.staff.alertsreads every filter tripop
exyliachatcosmetics.chat.staff.filteredreads a blocked message anyway, marked as filteredop

Bypasses

Undeclared, so operators only until you say otherwise. Each one skips exactly one check.

NodeSkips
exyliachatcosmetics.chat.bypass.mutethe chat mute
exyliachatcosmetics.chat.bypass.cooldownthe per-message cooldown
exyliachatcosmetics.chat.bypass.similaritythe too-alike check
exyliachatcosmetics.chat.bypass.floodlength and repeated characters
exyliachatcosmetics.chat.bypass.capsthe capitals check
exyliachatcosmetics.chat.bypass.filterthe rules and the pattern filters
exyliachatcosmetics.chat.bypass.ignoreclosed inboxes and ignores
exyliachatcosmetics.chat.bypass.clearchata /clearchat

Content

Three more nodes exist, and their names are yours rather than the plugin's, because each comes from a file:

NodeWhere it is set
exyliachatcosmetics.chat.emoji.<name>the default for a gated.<name> emoji in chat/text/emojis.yml; the entry's own permission key overrides it
a channel's permissionchat/channels.yml. Any node you like; the convention this documentation follows is exyliachatcosmetics.chat.channel.<id>
a format's permissionchat/formats/<name>.yml. Same, conventionally exyliachatcosmetics.chat.format.<name>

Note that exyliachatcosmetics.chat.format and a format node like exyliachatcosmetics.chat.format.vip are unrelated nodes — Bukkit gives no node authority over the ones below it. Granting the second does not grant the first.

The declared defaults, in full

Everything below is what plugin.yml writes. Everything not on these two lists is undeclared, and therefore operators only.

default: true — everybody, including a server with no permission plugin: command.cosmetics, customtag.create, customcolor.create, customnick.create, customrank.create, chat.command.msg, chat.command.reply, chat.command.ignore, chat.command.ignoreall, chat.command.channel, chat.mentions, chat.render.item, chat.render.inv, chat.render.ec.

default: op — operators until you grant them: admin, chat.command.spymsg, chat.command.mutechat, chat.command.clearchat, chat.command.broadcast, chat.links, chat.format, chat.staff, chat.staff.alerts, chat.staff.filtered.

Something missing on this page? Tell us on Discord