Permissions System and Zones - ForgeEssentials/ForgeEssentials GitHub Wiki

Last updated for forgeessentials-1.7.10-1.4.4.1195

Forge Essentials Permission System

The permission system uses a zone based allocation of rights. Zones can be of one of the following three types:

  1. Server - There exists exactly one zone of this type. Every player belongs to that zone at all times. This zone is identified by passing a * as zone name, or omitting the zone specification altogether.

  2. World - This kind of zone, or "dimension" in Minecraft terms, has no other parameters than the world it belongs to. Every player who is in that world belongs to that zone.

  3. Area - World specific zone that covers a defined area (XYZ/WHL). Only players currently inside the specified area belong to that zone.

Zones have priorities which are managed automatically.

Whenever zones are changed, the system will determine the order of priority for all zones with a little algorithm and cache these values for quick access (in other words, it just store zones in an ordered list).

The order of zones is determined in the following way (from lowest to highest priority):

  1. Server (global zone)
  2. World (dimension)
  3. Manually defined Areas, in the following order for overlapping zones:
    1. Highest priority first - lowest priority last (for zones with explicit priority set)
    2. Smallest area first - biggest area last

You can see the list of defined zones, sorted by their priority (highest to lowest), ingame at your location using /feperm list zones.

How are permissions checked?

When permissions are checked, the result is evaluated by the following pseudo-code:

for (zones as zone)
    for (splitNodes(permission) as node)
        if (zone.hasUserPermission(user, node))
            return zone.getUserPermission(user, node)

for (groups as group)
    for (zones as zone)
        for (splitNodes(permission) as node)
            if (zone.hasGroupPermission(group, node))
                return zone.getGroupPermission(group, node)

return true

The function splitNodes(permission) converts a single permission into a hierarchical list of nodes that cover the permission. For example the permission a.b.c would result in the following list of permissions:

a.b.c
a.b.c.*
a.b.*
a.*
*

So if the permission a.b is checked in a world for the group members, the following permissions would be checked until the first defined value is found:

USER     WORLD   a.b
USER     WORLD   a.b.*
USER     WORLD   a.*
USER     WORLD   *
USER     SERVER  a.b
USER     SERVER  a.b.*
USER     SERVER  a.*
USER     SERVER  *
members  WORLD   a.b
members  WORLD   a.b.*
members  WORLD   a.*
members  WORLD   *
members  SERVER  a.b
members  SERVER  a.b.*
members  SERVER  a.*
members  SERVER  *
_ALL_    WORLD   a.b
_ALL_    WORLD   a.b.*
_ALL_    WORLD   a.*
_ALL_    WORLD   *
_ALL_    SERVER  a.b
_ALL_    SERVER  a.b.*
_ALL_    SERVER  a.*
_ALL_    SERVER  *

Permissions storage

Permissions are stored in ~/<world-dir>/FEData/permissions directory
(indicated below as ./).

Full flatfile format (default permission storage)

./server.xml							server data
./groups/<group>.txt					global group-permissions
./players/<player>.txt					global player-permissions

./<world>/world.xml						world data
./<world>/groups/<group>.txt			world specific group-permissions
./<world>/players/<player>.txt			world specific player-permissions

./<world>/<area>/area.xml				area data
./<world>/<area>/groups/<group>.txt		area specific group-permissions
./<world>/<area>/players/<player>.txt	area specific player-permissions

Group permission files are identified by their filename e.g. "OWNERS.txt" represents the group “OWNERS". A group-permission file would look like the following example:

#Permissions for group OWNERS
#Mon Sep 29 02:27:03 CEST 2014
*=true
fe.internal.group=true
fe.internal.group.priority=10
fe.internal.prefix=[OWNER]
fe.internal.suffix=

Player permission files are stored by playername only for convenience. The actual player identifications are stored as pseudo-permissions inside the file:

#Permissions for user ForgeDevName with UUID 040a63f0-e153-3f49-84a8-b60ca564e69f
#Mon Sep 29 02:27:03 CEST 2014
fe.commands.time=true
fe.commands.heal=true
fe.internal.player.groups=OWNERS,_OPS_
fe.internal.player.name=ForgeDevName
fe.internal.player.uuid=040a63f0-e153-3f49-84a8-b60ca564e69f
fe.internal.prefix=[MASTER]
fe.perm=true

Combined flatfile format

This format is still in development and cannot be used yet!

permissions/global.json
permissions/<world>/world.json
permissions/<world>/<zone>.json
permissions/<world>/zones.json		zone definitions

It is important, that the name "zones" is not allowed for zone-names.

⚠️ **GitHub.com Fallback** ⚠️