VonixGuardian Vonix Mods v2.3.2 Search GitHub
VonixGuardian/Reference/Permissions

Permissions#

Every /vg subcommand is gated by a permission node. Nodes are checked in a fixed order: LuckPerms first if available, then a vanilla op-level fallback.

Resolution order#

For a player source, PermissionResolver checks in this order and stops at the first definitive answer:

  1. LuckPerms, when permissions.useLuckPerms is true and the bridge is available. A true grants, a false denies.
  2. Op level, when LP is absent, disabled, or returns UNDEFINED. Grant iff opLevel >= requiredLevel, where requiredLevel is the per-node default or a permissions.perNodeOpLevels override.

The console is always authorised — a non-player source never fails a command gate.

LuckPerms is a soft dependency#

The bridge is pure reflection; VonixGuardian never imports net.luckperms.*. It compiles, ships, and runs with no LuckPerms present. Detection happens once per JVM and is cached:

State Behaviour
Absent from classpath Cached as unavailable; op-level fallback for the rest of the JVM's life.
Present but not yet registered Not cached — the next call re-probes. This is why LP works even though it loads after some mods.
Present and registered Used for every check.

Nothing needs configuring to switch between modes. Install LuckPerms and the next check uses it; remove it and the fallback resumes.

Node reference#

Canonical nodes live under vonixguardian.<action>. The default op level applies only when the fallback path is in use — with LuckPerms, the node's value decides.

Node Gates Default op
vonixguardian.base The /vg root literal itself. 2
vonixguardian.inspect /vg inspect, i, inspector 2
vonixguardian.lookup /vg lookup, l, page 2
vonixguardian.near /vg near 2
vonixguardian.rollback /vg rollback, rb, ro, /vg apply, /vg cancel (rollback preview) 3
vonixguardian.restore /vg restore, rs, re, /vg apply, /vg cancel (restore preview) 3
vonixguardian.undo /vg undo 3
vonixguardian.purge /vg purge 4
vonixguardian.status /vg status, stats, version 3
vonixguardian.consumer /vg consumer 4
vonixguardian.reload /vg reload 4
vonixguardian.migrate_db /vg migrate-db 4
vonixguardian.command.config /vg config, /vg entitylog 4
vonixguardian.command.teleport /vg teleport, tp 3
vonixguardian.command.give /vg give 4
vonixguardian.help /vg help 0

Two naming shapes, both real

Most nodes are vonixguardian.<verb>, but config, teleport, and give are vonixguardian.command.<verb>. That is the shipped registry, not a typo — grant exactly the strings in this table. Legacy vonixguardian.command.<verb> aliases are also accepted for the other verbs, so an older permission set keeps working, but the canonical form above is what /vg status and the override map expect.

Per-category child nodes#

For lookup, rollback, and restore, category-scoped child nodes allow a narrower grant than the whole family. They are checked per row when results are filtered.

Lookup child Default op Rollback child Restore child
vonixguardian.lookup.block 2 vonixguardian.rollback.block vonixguardian.restore.block
vonixguardian.lookup.container 2 vonixguardian.rollback.container vonixguardian.restore.container
vonixguardian.lookup.inventory 2 vonixguardian.rollback.inventory vonixguardian.restore.inventory
vonixguardian.lookup.item 2 vonixguardian.rollback.item vonixguardian.restore.item
vonixguardian.lookup.kill 2 — —
vonixguardian.lookup.click 2 — —
vonixguardian.lookup.session 2 — —
vonixguardian.lookup.sign 2 — —
vonixguardian.lookup.username 2 — —
vonixguardian.lookup.chat 3 — —
vonixguardian.lookup.command 3 — —

Fall-open by design. If a family has no child node for a category, the family node is used. There is no way to be scoped out of a family that has no subdivision — holding vonixguardian.rollback grants rollback for messages and sessions too, where those types are reversible at all.

A player with vonixguardian.lookup but not vonixguardian.lookup.chat sees block and container rows in a /vg lookup and has chat rows silently filtered out of the result. #count respects the same filter, so counts match what is visible.

Reserved nodes#

These exist in the registry but do not gate a subcommand:

Node Default op Purpose
vonixguardian.lookup.ip 4 Reserved for IP-visibility scoping.
vonixguardian.bypass.inspector 0 Reserved for inspector bypass.

Do not build a permission scheme around them; they are declared for forward compatibility and are not enforced on a command path.

Setting up LuckPerms#

Two roles cover most servers: moderator investigates, admin mutates.

# Moderator — read-only investigation
/lp group moderator permission set vonixguardian.base true
/lp group moderator permission set vonixguardian.inspect true
/lp group moderator permission set vonixguardian.lookup true
/lp group moderator permission set vonixguardian.near true
/lp group moderator permission set vonixguardian.status true
/lp group moderator permission set vonixguardian.command.teleport true

# Admin — inherits moderator, gains mutation and maintenance
/lp group admin parent add moderator
/lp group admin permission set vonixguardian.rollback true
/lp group admin permission set vonixguardian.restore true
/lp group admin permission set vonixguardian.undo true
/lp group admin permission set vonixguardian.purge true
/lp group admin permission set vonixguardian.reload true
/lp group admin permission set vonixguardian.consumer true
/lp group admin permission set vonixguardian.command.give true

Notes that save support tickets:

  • Grant vonixguardian.base to anyone who holds another node. It gates the root literal; without it some clients hide /vg from tab-completion entirely.
  • Three nodes carry the .command. infix — command.config, command.teleport, command.give. Copy them exactly from the table; a plausible-looking vonixguardian.teleport grants nothing.
  • purge at op 4 is deliberate. It is destructive and irreversible.
  • consumer and reload are operational, not investigative. Pausing the writer during an investigation silently loses events; keep them with admins.
  • Wildcards work: vonixguardian.* grants every node in the table.

Op-level fallback#

Without LuckPerms there is no per-command granularity by default — any player at permissions.defaultOpLevel or above passes every node check, including purge.

"permissions": {
  "useLuckPerms": true,
  "defaultOpLevel": 3,
  "perNodeOpLevels": {}
}

defaultOpLevel must be 0–4. 3 matches the vanilla /op tier, so a normally opped administrator can use everything.

Per-node overrides#

perNodeOpLevels restores per-command control without LuckPerms. This is the supported way to let a builder inspect without letting them purge:

"permissions": {
  "useLuckPerms": true,
  "defaultOpLevel": 4,
  "perNodeOpLevels": {
    "vonixguardian.base": 0,
    "vonixguardian.inspect": 0,
    "vonixguardian.lookup": 0,
    "vonixguardian.near": 0,
    "vonixguardian.status": 2,
    "vonixguardian.rollback": 3,
    "vonixguardian.restore": 3,
    "vonixguardian.purge": 4
  }
}

With that map, a level-0 player can inspect and look up, a level-3 admin can roll back, and purge stays at 4.

Rules:

  • Keys are canonical node strings from the table. An unknown key logs a WARN and is ignored at runtime.
  • Values must be 0–4. Anything else is a hard config validation error.
  • The map only affects the fallback path. When LuckPerms answers, the map is not consulted.
  • permissions is restart-only — /vg reload detects the change and reports Requires restart.

If a node is absent from the map, its own default op level applies. A malformed override does not silently degrade to the coarse default; it is rejected at load.

Choosing a scheme#

Situation Recommended
Small server, one admin LuckPerms absent, defaultOpLevel: 3. Nothing to configure.
Staff team on a modded pack LuckPerms with moderator and admin groups above.
No LuckPerms but you want tiers perNodeOpLevels map with defaultOpLevel: 4.
Letting players audit their own builds Grant lookup broadly; keep rollback and purge with staff.

Verify a grant before handing out roles

Run /vg status and read the Permissions section — it reports the default op level and how many per-node overrides are active. If the override count is 0 when you expected a map, the config did not load it, and every node is using its default.