Configuration
ShadowPermissions
Ranks, permissions and prefixes, driven from a window instead of a file.
Where the files are
plugins/ShadowPermissions/ The plugin creates them on first start and updates them by itself on new versions, keeping your changes.
Applying changes
/perm reload Reloads the files without restarting the server.
No setting found
Try another word, or search every plugin.
Settings
The files that decide how the plugin behaves. Start here.
config.yml
General settings 177 settings
config.ymlplugins/ShadowPermissions/config.yml File notes
Every key has a sensible default: a fresh install needs no editing at all. The local database creates itself on the first start.
This file is in English on purpose: keys, sections and comments. What your players read is in lang/, and that is where translation belongs.
Full documentation: docs/12-CONFIGURAZIONE.md
config-version1Do not edit. On update, this file and the language files are moved to the new version automatically: everything you changed is carried over, the old files are kept in backup/<date>/, and if something needs your attention you will find PORTING-<version>.txt in this folder. starter.yml is never touched.
server-id"global"The name of this server. It becomes the "server=<id>" context on its own and identifies this server in multi-server synchronisation.
Language
language3 keysdefault"en_US"The server language. Matches a file in lang/ (without .yml). Ships with en_US and it_IT. Set "it_IT" here for an Italian server.
per-playertruetrue = each player sees the language of their own client, when available.
fallback"en_US"Used only for keys missing from the chosen language.
Storage
storage10 keysBy default the plugin creates and uses a local database in plugins/ShadowPermissions/data/shadowpermissions.mv.db Nothing to install: tables and indexes are created automatically.
To use YOUR OWN MySQL/MariaDB set enabled: true and fill in the fields. The same tables are created there, with nothing else to change.
storage.mysql7 keysenabledfalsehost"localhost"port3306database"shadowpermissions"username"root"password""storage.mysql.properties2 keysuseSSL"false"characterEncoding"utf8"storage.h21 keyauto-serverfalsetrue = lets you open the file with DBeaver while the server is running.
storagetable-prefix"sp_"Table prefix. Useful when the database is shared with other plugins.
pool-size8connection-timeout5000fail-safetruetrue = if the database stops answering the plugin enters safe mode instead of shutting down: permissions keep working read-only from the snapshot.
fallback-to-localtruetrue = if the configured MySQL does not answer, use the local database.
snapshot-interval300Seconds between local snapshots (0 = off).
backup-before-migratetruemojang-lookupfalsetrue = resolves the UUID of a never-seen name by asking Mojang. Off by default: no data leaves the server.
Engine
engine4 keysmodeINJECTINJECT replaces the player's Permissible: complete wildcards, even over
nodes no plugin ever declared. Recommended.ATTACHMENT uses the Bukkit API only: more conservative, wildcards limited to
declared permissions. If INJECT fails this is used on its own.
default-group"member"The group a new arrival lands in. Out of the box it is "member", the first rung of the ladder the plugin builds by itself on the first start (see starter.yml). Change it if your ladder starts somewhere else.
auto-assign-defaulttruetrue = every new player joins the default group automatically.
inherit-default-on-createtruetrue = a group you create inherits the default group straight away.
Keep reading
Nearly every group is "everything a player can do, plus these". Without this you write the player commands into the new group by hand, and then again into the next one, and the day you add one to the default group you have to remember all nine places - which is how a VIP ends up unable to use /home.
It applies only to groups a person creates, with /perm creategroup or the interface. An import, a clone and starter.yml write their own inheritance and are left exactly as they are.
Resolution
resolution4 keysprimary-groupSTOREDHow the main group is chosen: STORED | HIGHEST_WEIGHT | FIRST
wildcard-modeFULLFULL essentials.* also covers essentials.fly.others
SHALLOW essentials.* covers only the next level down
OFF wildcards are ordinary nodes
max-inheritance-depth32context-specificitytruetrue = a node with a context beats a global node of the same holder.
Operators
opping2 keysmodeRESPECTRESPECT an operator gets every OP-default permission, as on a plain server
IGNORE being an operator grants nothing: only groups count (recommended)
MANAGED like IGNORE, but /op and /deop add and remove managed-group
managed-group"operator"Contexts
contexts5 keysEvery context you switch on multiplies the cache entries per player: turn on only the ones you actually use.
servertrueworldtruedimensionfalsegamemodefalsestatic{ }Contexts that always apply, decided by you.
Prefixes, suffixes, meta
meta6 keysprefix-formatHIGHESTA player is usually in more than one group. Which one shows in front of their name?
Keep reading
HIGHEST only one: the most important.
CONCAT all of them, most important first.
A Founder who is also a VIP becomes [FOUNDER][VIP] NameWho wins, both for HIGHEST and for the order of CONCAT:
1. the prefix set on the person, if there is one; 2. among groups, the highest priority; 3. on equal priority, the group with the greater weight.
That is why the nine shipped ranks all sit at priority 100: weight already orders them, which leaves priority free for the exceptions ("this one prefix jumps the queue").
suffix-formatHIGHESTdefault-prefix-priority100concat-separator""What to put between one prefix and the next with CONCAT.
concat-limit2How many prefixes at most with CONCAT (0 = all of them). Somebody in six groups would carry six tags in front of their name: that is not a rank any more, it is a wall.
auto-spacingtruetrue = the plugin puts the space between a prefix and the name, and between the name and a suffix, when whoever wrote them did not. Nobody should have to remember a trailing space, and forgetting it glues [VIP] to the name in chat, in the tab list and above the head all at once. Set it to false if you want a prefix deliberately touching the name.
Cache
cache2 keysuser-ttl300Seconds an offline player stays in memory (0 = for ever).
max-contexts-per-user16Scheduled work
tasks2 keysexpiry-interval30How often temporary permissions are checked for expiry, in seconds.
autosave-interval300Multi-server
sync3 keysTurn on only when several servers share the SAME MySQL database. No Redis needed, no plugin on the proxy.
enabledfalsepoll-interval3message-ttl60Interface
gui7 keysenabledtrueinput-timeout60When text is needed (a group name, a search, a prefix) the plugin asks for it in chat, with the [✔] and [✘] buttons underneath. Seconds to wait before giving up on its own:
input-spacingtrueA blank line above and below the request, to set it apart from the chat.
fill-emptytruefiller-material"GRAY_STAINED_GLASS_PANE"Shortcut for gui.icons.common.filler.
gui.group-colors12 keysA per-group icon in the lists. Optional: without it, gui.icons.groups.entry is used (or groups.entry-default for the default group).
default"LIGHT_GRAY_WOOL"member"BLUE_WOOL"The eleven ranks of starter.yml, each one recognisable at a glance.
basic"IRON_INGOT"Iron, amethyst and a nether star: the icons ShadowEssentials gives the same three tiers in vips/, so a rank looks the same wherever you meet it.
magic"AMETHYST_SHARD"epic"NETHER_STAR"twitch"MAGENTA_WOOL"youtube"REDSTONE_BLOCK"builder"LIME_WOOL"trial"PINK_WOOL"staff"RED_WOOL"admin"YELLOW_WOOL"founder"PURPLE_WOOL"The look of the interface
gui.icons92 keysEvery icon of every menu is here: there is not one material written by hand anywhere in the code. Change one and it changes everywhere it appears. A wrong material name does not break the menu: it falls back to the default and a console line says which key and which value.
common.back"ARROW"Shared by every menu
common.close"BARRIER"common.page-previous"SPECTRAL_ARROW"common.page-next"SPECTRAL_ARROW"common.search"OAK_SIGN"common.filler"GRAY_STAINED_GLASS_PANE"common.loading"CLOCK"common.empty"BARRIER"common.locked"IRON_BARS"common.manual-input"WRITABLE_BOOK"common.apply"EMERALD"common.create"NETHER_STAR"common.delete"BARRIER"common.question"PAPER"common.confirm-yes"LIME_CONCRETE"common.confirm-no"RED_CONCRETE"common.reset"BARRIER"common.sort"COMPARATOR"common.filter"HOPPER"main.groups"ENCHANTED_BOOK"Main menu
main.users"PLAYER_HEAD"main.tracks"RAIL"main.catalog"COMPASS"main.operators"NETHERITE_HELMET"main.status"BEACON"main.audit"CLOCK"groups.entry"WHITE_WOOL"Group list
groups.entry-owned"LIME_DYE"groups.entry-default"LIGHT_GRAY_WOOL"holder.displayname"NAME_TAG"The screen of one group or one user
holder.weight"COMPARATOR"holder.primary-group"GOLDEN_HELMET"holder.prefix"WHITE_BANNER"holder.suffix"YELLOW_BANNER"holder.permissions"CHEST"holder.parents"IRON_CHAIN"holder.meta"BOOK"holder.members"PLAYER_HEAD"holder.duplicate"BARREL"holder.delete"BARRIER"holder.tracks"RAIL"holder.resolved"WRITABLE_BOOK"holder.clone-from"ENDER_PEARL"holder.clear"TNT"nodes.granted"LIME_STAINED_GLASS_PANE"Node list and node editor
nodes.denied"RED_STAINED_GLASS_PANE"nodes.inherited"YELLOW_STAINED_GLASS_PANE"Yellow means "not this group's": it arrives from a group above and is shown read-only, because the place to change it is the group that owns it.
nodes.inherited-denied"ORANGE_STAINED_GLASS_PANE"nodes.temporary"CLOCK"nodes.add-catalog"COMPASS"nodes.add-parent"IRON_CHAIN"node-editor.node"PAPER"node-editor.value-allow"LIME_DYE"node-editor.value-deny"RED_DYE"node-editor.context"FILLED_MAP"node-editor.expiry"CLOCK"node-editor.save"EMERALD"context.current"FILLED_MAP"Context picker
context.world-on"LIME_WOOL"context.world-off"GRAY_WOOL"context.gamemode-on"LIME_DYE"context.gamemode-off"LIGHT_GRAY_DYE"context.custom-on"LIME_CANDLE"context.custom-off"CANDLE"context.here"ENDER_PEARL"context.global"BEACON"duration.current"CLOCK"Duration picker
duration.preset"SUNFLOWER"duration.permanent"BEDROCK"catalog.owner"BOOKSHELF"Permission catalogue
catalog.node-declared"PAPER"catalog.node-observed"MAP"catalog.node-granted"LIME_STAINED_GLASS_PANE"The four states of a permission in the catalogue: the one the group has, the one it is denied, the one it inherits, the one it inherits denied.
catalog.node-denied"RED_STAINED_GLASS_PANE"catalog.node-inherited"LIME_DYE"catalog.node-inherited-denied"RED_DYE"tracks.entry"RAIL"Tracks
track-editor.entry"LADDER"status.storage-ok"LIME_CONCRETE"Status screen
status.storage-down"RED_CONCRETE"status.data"CHEST"status.engine"REDSTONE_TORCH"status.catalog"COMPASS"status.hooks"LEVER"status.suite"ENDER_CHEST"status.languages"BOOK"audit.undoable"PAPER"Change log
audit.final"MAP"ops.tab-operators"NETHERITE_HELMET"Operators
ops.tab-players"LEATHER_HELMET"ops.mode-safe"LIME_DYE"ops.mode-risky"REDSTONE_TORCH"Security
security6 keysweight-protectiontruetrue = you cannot edit a group whose weight is equal to or above your own.
protect-own-grouptruetrue = you cannot take your own main group away from yourself.
confirm-destructivetrueprotect-own-nodestruetrue = handing out a "shadowperms.*" node requires already holding it. Without this, anybody who can edit permissions can grant "shadowperms.bypass.weight" to a second account and then log into it: two legal moves, one administrator more. Outside our own namespace nothing changes, and taking a permission away is always allowed.
audittrueaudit-retention-days300 = keep for ever.
Compatibility
compatibility3 keysluckperms-aliasestrueAlso registers /lp with the same syntax. Ignored when LuckPerms is present.
vaulttrueplaceholderapitrueShadow suite
integrations1 keyintegrations.shadow-suite3 keysenabledtrueannouncetrueprovide-group-servicetruePermission catalogue
catalog3 keysenabledtruescan-on-plugin-enabletrueinclude-undeclaredtruetrue = also includes nodes never declared but actually checked.
bStats
metrics1 keyAnonymous usage statistics, published on https://bstats.org
enabledtrueWhat is sent, every 30 minutes: that this server runs ShadowPermissions, the plugin, Minecraft/Paper and Java versions, the operating system, the number of CPU cores, how many players are online (a number, nothing else), a random serverUuid that identifies nothing, and whether the storage is the local database or MySQL. No player data leaves the server: no names, no UUIDs, no addresses, no groups or permissions.
Keep reading
false switches it off for this plugin only. enabled: false in plugins/bStats/config.yml switches it off for every plugin on this server at once.
Diagnostics
verbose1 keymax-lines-per-second20debugfalse starter.yml
Starter groups and permissions 53 settings
starter.ymlplugins/ShadowPermissions/starter.yml File notes
The ladder a new server starts with: ranks already coloured, already ordered, already carrying the right permissions. Not a demo to throw away - a rank structure that holds up on a real server from the first minute, and that you then change rather than having to invent.
WHEN IT IS APPLIED
Once, on the first start, while the database is still empty. If you already have groups, nothing here is touched. To apply it by hand later: /perm setup (creates only what is missing, never overwrites what you have)
DO NOT WANT IT?
Set apply: false below and start from the usual single empty group.
Or edit this file before the first start: what you read here is exactly what will be created.
NAMES AND LABELS
The group id - the key below, the word you type in commands - is in English, like everything else that is configuration. What players see is "display" and "prefix", and those are yours to write in any language: they ship in Italian to match the default language.
COLOURS
Written in MiniMessage. <gold>, <dark_purple>, <#FF8A8A> for an exact colour, <gradient:#A:#B>text</gradient> for a fade. A prefix ends with the colour of its rank, so in chat the player name inherits it - which is why ranks are recognisable at a glance. No bold anywhere: a chat line where every tag shouts is a chat line nobody reads. The colour is the rank; the weight is not needed.
IT MATCHES SHADOWESSENTIALS
The three supporter ranks are the three VIP tiers ShadowEssentials already ships in vips/: same ids, same weights, same colours, and each one carries the tier node that switches its perks on. Install the two plugins together and they agree without a single edit.
applytrueThe ranks, from the bottom up
weight how much it counts: on equal permissions the higher wins,
and the tab list sorts on it.
parents who it inherits from, so each rank writes only what it adds
instead of repeating everything below it.groups11 keysThe rank everybody starts in
groups.member4 keysweight0display"<blue>Utente"prefix"<dark_gray>[<blue>Utente<dark_gray>] <blue>"permissions[shadowperms.command.help, shadowessentials.command.spawn, shadowessentials.command.home, shadowessentials.command.homes, shadowessentials.command.sethome, shadowessentials.command.delhome, shadowessentials.command.warp …+29
The basics anybody expects the moment they join.
One home: more of them is what you earn by moving up.
The three supporter ranks
They are the VIP tiers of ShadowEssentials: vips/basic.yml, magic.yml and epic.yml. Each group carries its "shadowessentials.vip.<tier>" node, and that node alone is what switches the tier on - flight, home limit, reduced cooldowns, the lot. So selling the rank is one command:
/perm user Someone parent add magic
Keep reading
Each tier adds something the one below has not got, on purpose: the reason to move up has to be visible on the page that sells it.
basic flight, workbench, ender chest, colours, 5 homes magic nickname, flight in every world, speed, 10 homes epic instant teleport, gradient nicknames, 20 homes
Tier 1
groups.basic5 keysweight100display"<gradient:#7FD8FF:#3BA7E0>Basic"prefix"<dark_gray>[<gradient:#7FD8FF:#3BA7E0>BASIC<dark_gray>] <aqua>"parents[member]permissions[shadowessentials.vip.basic, shadowessentials.command.fly, shadowessentials.command.workbench, shadowessentials.command.enderchest, shadowessentials.kit.daily-basic, shadowessentials.limit.homes.5, shadowessentials.chat …+10
The tier itself: ShadowEssentials reads this and applies vips/basic.yml.
The three everybody asks for first.
Its daily kit. What unlocks it is the tier above; the node is here so it keeps working the day you set public: false on the kit file.
Note there is no tp-cooldown bypass here: basic gets the waits cut by a quarter through the tier perks, not removed. Removing them is what epic is for.
Tier 2
groups.magic5 keysweight200display"<gradient:#C77DFF:#7B2CBF>Magic"prefix"<dark_gray>[<gradient:#C77DFF:#7B2CBF>MAGIC<dark_gray>] <light_purple>"parents[basic]permissions[shadowessentials.vip.magic, shadowessentials.kit.daily-magic, shadowessentials.limit.homes.10, shadowessentials.command.nick, shadowessentials.nick.color, shadowessentials.world.fly.bypass, shadowessentials.command.spe …+9
A name of your own, in one colour.
Flight that the per-world rules do not switch off.
Tier 3
groups.epic5 keysweight300display"<gradient:#FFD166:#FF6B35>Epic"prefix"<dark_gray>[<gradient:#FFD166:#FF6B35>EPIC<dark_gray>] <gold>"parents[magic]permissions[shadowessentials.vip.epic, shadowessentials.kit.daily-epic, shadowessentials.limit.homes.20, shadowessentials.bypass.tp-cooldown, shadowessentials.bypass.tp-warmup, shadowessentials.nick.gradient, shadowessentials.nick …+11
Teleport with no wait and no cooldown: the headline perk.
A name in a gradient, or in an exact colour.
Creators
groups.twitch5 keysPartnered rather than paying: they sit above the tiers whose perks they are given, and carry their own kit.
weight450display"<light_purple>Twitch"prefix"<dark_gray>[<light_purple>TWITCH<dark_gray>] <light_purple>"parents[magic]permissions[shadowessentials.kit.twitch, shadowessentials.limit.homes.15, shadowessentials.command.hologram]+2
groups.youtube5 keysweight500display"<red>You<white>Tube"prefix"<dark_gray>[<red>You<white>Tube<dark_gray>] <white>"Half red and half white, like the mark itself.
parents[magic]permissions[shadowessentials.kit.youtuber, shadowessentials.kit.youtuber-daily, shadowessentials.limit.homes.15, shadowessentials.nick.gradient, shadowessentials.command.hologram]+4
member:
builderStaff
Split in two on purpose. "trial" can look, warn and quieten - every action it can take is reversible. "staff" adds the ones that are not: bans, jail, wiping an inventory. Somebody on their first week holds the first; you move them to the second when you trust them.
/perm user Someone promote staff
Staff on trial
groups.trial5 keysweight700display"<#FF8A8A>Prova Staff"prefix"<dark_gray>[<#FF8A8A>PROVA<dark_gray>] <#FF8A8A>"parents[member]permissions[shadowessentials.command.kick, shadowessentials.command.mute, shadowessentials.command.tempmute, shadowessentials.command.warn, shadowessentials.command.freeze, shadowessentials.command.invsee, shadowessentials.command …+22
Punishments that undo themselves or can be lifted.
Looking: the half of moderating that comes before acting.
The staff channel, and being told what the others are doing.
Nobody can silence a moderator by ignoring them.
Of ShadowPermissions, reading only: enough to answer "why can I not do this?" without being able to change anything.
Staff proper
groups.staff5 keysEverything it takes to moderate ShadowEssentials, with nothing missing: punish, inspect, hide, protect, and reach whoever needs reaching.
weight800display"<red>Staff"prefix"<dark_gray>[<red>STAFF<dark_gray>] <red>"parents[trial]permissions[shadowessentials.command.ban, shadowessentials.command.tempban, shadowessentials.command.jail, shadowessentials.command.jails, shadowessentials.command.jailtp, shadowessentials.command.clearinventory, shadowessentials. …+45
Punishments that last
A mute the muted player is not told about.
Inspecting, all the way
Opens an inventory another moderator marked protected, and marks their own so nobody below can rummage through it.
Being invisible
Reaching people
Chat
Reads what the filter caught, without being caught by it.
A moderator answers under their own name, always.
Not being moderated yourself
Working comfortably
Of ShadowPermissions: can promote and demote. Cannot touch permissions - that is what admin is for.
Administration
groups.admin5 keysweight900display"<yellow>Admin"prefix"<dark_gray>[<yellow>ADMIN<dark_gray>] <yellow>"parents[staff]permissions[shadowessentials.admin.reload, shadowessentials.admin.kits, shadowessentials.admin.profile, shadowessentials.admin.storage, shadowessentials.admin.voucher, shadowessentials.command.vip.give, shadowessentials.command.vi …+32
Selling and taking back the three supporter ranks.
Building the places everybody else uses.
Punishing somebody the rules said could not be punished.
Every permission command, except the guardrails.
Whoever owns the server
groups.founder5 keys"*" grants everything, including plugins you install tomorrow. The group starts empty: nobody holds it until you put yourself in.
/perm user YourName parent add founder
weight1000display"<dark_purple>Founder"prefix"<dark_gray>[<dark_purple>FOUNDER<dark_gray>] <dark_purple>"parents[admin]permissions["*"]Tracks: the ladders you move people up and down
/perm user Someone promote staff
/perm user Someone demote staff
"vip" is the one you will use most: it is the same order ShadowEssentials walks with its own "next" field, so a player who buys the upgrade moves the same way in both plugins.
tracks3 keysvip[basic, magic, epic]staff[trial, staff, admin, founder]ranks[member, basic, magic, epic]Languages
The texts the plugin shows to players, one file per language.
lang/
Texts and messages 2 files
lang/plugins/ShadowPermissions/lang/ File notes
ShadowPermissions — English (reference language) Translate the VALUES, never the keys. <placeholders> stay as they are. Tags such as <red> or <bold> are MiniMessage formatting, not text. An empty value ("") means "do not send this message".
Check coverage with: /perm lang check en_US
Every message the plugin shows to players, one file per language. The keys are not listed one by one: here are the files, how many texts they hold and the placeholders they use.
| File | Language | Texts |
|---|---|---|
lang/en_US.yml reference | — | 590 |
lang/it_IT.yml | — | 590 |
Most used placeholders
The plugin replaces them with the right value: leave them written as they are.
<node><group><value><user><count><holder><track><name><page><groups><to><context><weight><nodes>
Message groups
language-info3prefix1common8duration24general6error11prompt15confirm12usage34help3info10suite12sync2lang8check9verbose4tree6search3catalog4audit12user11group20track20node8parent6setup4transfer8migrate13expiry1bulk2ops3gui307