Permissions System and Zones - ForgeEssentials/ForgeEssentials GitHub Wiki
Last updated for forgeessentials-1.7.10-1.4.4.1195
The permission system uses a zone based allocation of rights. Zones can be of one of the following three types:
-
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.
-
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.
-
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):
- Server (global zone)
- World (dimension)
- Manually defined Areas, in the following order for overlapping zones:
- Highest priority first - lowest priority last (for zones with explicit priority set)
- 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
.
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 are stored in ~/<world-dir>/FEData/permissions
directory
(indicated below as ./
).
./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
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.