Skip to content
ShadowMC

Configuration

ShadowPermissions

Ranks, permissions and prefixes, driven from a window instead of a file.

Free v1.0.4

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.

What’s inside

4 files · 230 settings

Start with: config.yml

Settings

The files that decide how the plugin behaves. Start here.

config.yml

General settings
177 settings
plugins/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-version1

Do 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 keys
default"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-playertrue

true = 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 keys

By 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 keys
enabledfalse
host"localhost"
port3306
database"shadowpermissions"
username"root"
password""
storage.mysql.properties2 keys
useSSL"false"
characterEncoding"utf8"
storage.h21 key
auto-serverfalse

true = lets you open the file with DBeaver while the server is running.

storage
table-prefix"sp_"

Table prefix. Useful when the database is shared with other plugins.

pool-size8
connection-timeout5000
fail-safetrue

true = if the database stops answering the plugin enters safe mode instead of shutting down: permissions keep working read-only from the snapshot.

fallback-to-localtrue

true = if the configured MySQL does not answer, use the local database.

snapshot-interval300

Seconds between local snapshots (0 = off).

backup-before-migratetrue
mojang-lookupfalse

true = resolves the UUID of a never-seen name by asking Mojang. Off by default: no data leaves the server.

Engine

engine4 keys
modeINJECT
INJECT     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-defaulttrue

true = every new player joins the default group automatically.

inherit-default-on-createtrue

true = 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 keys
primary-groupSTORED

How the main group is chosen: STORED | HIGHEST_WEIGHT | FIRST

wildcard-modeFULL
FULL    essentials.* also covers essentials.fly.others

SHALLOW essentials.* covers only the next level down

OFF     wildcards are ordinary nodes
max-inheritance-depth32
context-specificitytrue

true = a node with a context beats a global node of the same holder.

Operators

opping2 keys
modeRESPECT

RESPECT 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 keys

Every context you switch on multiplies the cache entries per player: turn on only the ones you actually use.

servertrue
worldtrue
dimensionfalse
gamemodefalse
static{ }

Contexts that always apply, decided by you.

Prefixes, suffixes, meta

meta6 keys
prefix-formatHIGHEST

A 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] Name

Who 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-formatHIGHEST
default-prefix-priority100
concat-separator""

What to put between one prefix and the next with CONCAT.

concat-limit2

How 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-spacingtrue

true = 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 keys
user-ttl300

Seconds an offline player stays in memory (0 = for ever).

max-contexts-per-user16

Scheduled work

tasks2 keys
expiry-interval30

How often temporary permissions are checked for expiry, in seconds.

autosave-interval300

Multi-server

sync3 keys

Turn on only when several servers share the SAME MySQL database. No Redis needed, no plugin on the proxy.

enabledfalse
poll-interval3
message-ttl60

Interface

gui7 keys
enabledtrue
input-timeout60

When 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-spacingtrue

A blank line above and below the request, to set it apart from the chat.

fill-emptytrue
filler-material"GRAY_STAINED_GLASS_PANE"

Shortcut for gui.icons.common.filler.

gui.group-colors12 keys

A 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 keys

Every 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.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 keys
weight-protectiontrue

true = you cannot edit a group whose weight is equal to or above your own.

protect-own-grouptrue

true = you cannot take your own main group away from yourself.

confirm-destructivetrue
protect-own-nodestrue

true = 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.

audittrue
audit-retention-days30

0 = keep for ever.

Compatibility

compatibility3 keys
luckperms-aliasestrue

Also registers /lp with the same syntax. Ignored when LuckPerms is present.

vaulttrue
placeholderapitrue

Shadow suite

integrations1 key
integrations.shadow-suite3 keys
enabledtrue
announcetrue
provide-group-servicetrue

Permission catalogue

catalog3 keys
enabledtrue
scan-on-plugin-enabletrue
include-undeclaredtrue

true = also includes nodes never declared but actually checked.

bStats

metrics1 key

Anonymous usage statistics, published on https://bstats.org

enabledtrue

What 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 key
max-lines-per-second20
debugfalse

starter.yml

Starter groups and permissions
53 settings
plugins/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.

applytrue

The 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 keys

The rank everybody starts in

groups.member4 keys
weight0
display"<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 keys
weight100
display"<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 keys
weight200
display"<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 keys
weight300
display"<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 keys

Partnered rather than paying: they sit above the tiers whose perks they are given, and carry their own kit.

weight450
display"<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 keys
weight500
display"<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
1 more entry shaped like member: builder

Staff

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 keys
weight700
display"<#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 keys

Everything it takes to moderate ShadowEssentials, with nothing missing: punish, inspect, hide, protect, and reach whoever needs reaching.

weight800
display"<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 keys
weight900
display"<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
weight1000
display"<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 keys
vip[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
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.

FileLanguageTexts
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-info 3
  • prefix 1
  • common 8
  • duration 24
  • general 6
  • error 11
  • prompt 15
  • confirm 12
  • usage 34
  • help 3
  • info 10
  • suite 12
  • sync 2
  • lang 8
  • check 9
  • verbose 4
  • tree 6
  • search 3
  • catalog 4
  • audit 12
  • user 11
  • group 20
  • track 20
  • node 8
  • parent 6
  • setup 4
  • transfer 8
  • migrate 13
  • expiry 1
  • bulk 2
  • ops 3
  • gui 307

All the documentation