Skip to content
This repository has been archived by the owner on Feb 3, 2024. It is now read-only.

Advanced permissions setup

Stormbow edited this page Apr 6, 2015 · 38 revisions

In this section, we will cover the more advanced features of PEX, such as inheritance, regular expression (regex) support and multi-world permissions.

Contents

Permissions Inheritance (top)

Many servers are configured to have multiple groups, with each group in the ranking adding new permissions as a player advances. Permissions inheritance allows the admin to configure this while minimizing the amount of duplicated nodes for each group.

This section assumes that you have successfully completed the Basic Permissions Setup tutorial. If you haven't done this yet and you want to start directly with this tutorial, it is not guaranteed that you will understand each step here as this tutorial builds upon the earlier sections.

Using the example from the Basic Permissions Setup, you may have noticed that the Member, VIP and Moderator groups all share a permissions node, the modifyworld.* node. This is unnecessary with inheritance.

Permissions Inheritance Rules (top)

When dealing with inheritance, PEX follows a few rules:

  • Player specific settings (prefix, suffix, permission nodes, etc) are evaluated before group level settings
  • Settings that are part of the group the player is a member of are evaluated before inherited settings
  • Permission nodes are evaluated in order of the inheritance tree (see The Inheritance Tree for details)
  • A group set to inherit from another group will inherit everything (this includes other inheritance directives!) from the source group, not just permissions. For example, if you have group B inheriting from group A, and group A is set to inherit from group B, PEX will follow the inheritance chain on group A, which is set to inherit from B, which inherits from A, and so on. Watch for this, it will cause a loop that will crash PEX.

Converting Existing Groups To Use Inheritance (top)

Converting an existing group to use inheritance is easy with the pex group parents set command.

Convert the VIP and Moderator groups
  • pex group VIP parents set Member
  • pex group Moderator parents set VIP
Remove the redundant nodes
  • pex group VIP remove modifyworld.*
  • pex group Moderator remove modifyworld.*

At this point, the VIP and Moderator groups still have the same access as before as the VIP group inherits the modifyworld.* node from the Member group while adding the -modifyworld.mobtarget.monster.creeper node, and the Moderator group inherits it's nodes from the VIP group (including the nodes it inherited from the Member group) while adding the -modifyworld.mobtarget.* node.

The relevant portion of the permissions file now looks like this:

  Member:
    permissions:
    - modifyworld.*
    options:
      rank: '900'
      prefix: '&0(&8M&7ember&0)&7 '
  VIP:
    inheritance:
    - Member
    permissions:
    - -modifyworld.mobtarget.monster.creeper
    options:
      rank: '800'
      prefix: '&0(&eVIP&0)&7 '
  Moderator:
    inheritance:
    - VIP
    permissions:
    - -modifyworld.mobtarget.*
    options:
      rank: '100'
      prefix: '&0(&1Moderator&0)&7 '

It's not a large reduction with this example, but if a server has multiple groups with a dozen or more nodes in common with the groups, the file size savings can be considerable.

This inheritance can also be applied at a world level for servers with multiple worlds. See the Multiworld inheritance section page for more.

The Inheritance Tree (top)

(Thanks goes to aviator14 for use of these nodes)

Due to the way PEX deals with file backends, it may help to view inheritance as a tree. For example, we have the following permission nodes:

  Guest:
    prefix: '&7'
    default: true
    permissions: []
  Player:
    prefix: '&f'
    default: false
    permissions:
    - generic.user.permissions
    - -multiverse.access.world_creative
    - -multiverse.portal.access.end
    - multiverse.access.*
    - multiverse.core.coord
    - multiverse.core.info
    - multiverse.core.list.who
    - multiverse.portal.access.*
    inheritance:
    - Guest
  Donator:
    prefix: '&5'
    permissions:
    - generic.donor.permissions
    - multiverse.access.world_creative
    inheritance:
    - Player
  Supporter:
    prefix: '&6'
    permissions:
    - more.generic.donor.permissons
    - multiverse.portal.access.end
    inheritance:
    - Donator
  Moderator:
    prefix: '&d'
    permissions:
    - generic.moderator.permissions
    inheritance:
    - Player
  ModD:
    prefix: '&d'
    permissions: []
    inheritance:
    - Moderator
    - Donator
  ModS:
    prefix: '&d'
    permissions: []
    inheritance:
    - Moderator
    - Supporter

The original forum post these nodes came from was asking why the ModD group was not getting the multiverse.portal.access.end node it was inheriting from the Donator group. Well, the reason for this is because of the way PEX evaluates nodes in a file backend and the inheritance tree.

An abbreviated version of the tree for the ModD group is this:

  • ModD permissions (none)
    • Moderator (generic.moderator.permissions) which inherits from Player
      • Player (which has -multiverse.access.world_creative among others) and inherits from Guest
        • Guest (no permissions)
    • Donator (generic.donor.permissions, multiverse portal access node) which inherits from Player
      • Player (which has -multiverse.access.world_creative among others) and inherits from Guest
        • Guest (no permissions)

In this case, the issue was due to the Moderator tree being evaluated first, which finds the negation node for multiverse and stops looking. If the Donator tree was listed first (which was the suggested fix), PEX would follow that inheritance tree first, which has the multiverse permissions, and allow access to that node.

Regular Expressions (regex) (top)

Regular Expressions, also known as regex or regexp, is a way to 'match' strings of text, such as particular characters, words, or patterns of characters. PEX supports a subset of regex in it's permission node checks.

PEX supports open and closed parentheses ( ) for grouping, curly braces { } for pattern matching, a pipe | for "or", and a dash - for through (as in numbers 1 through 5).

WARNING: If you have any nodes that use these characters then you MUST either put the line in quotes or escape with a backslash the character. If you do not, PEX may mistake the character as an attempt to use a regex, causing a Java error and rendering your permissions useless!

To use it, place the conditions/keywords and/or id numbers in a group, separated by a pipe or a dash if wanting to cover multiple numbers in a sequence.

If this is confusing, worry not. There is a reason why several technical book publishers sell books dedicated to regular expressions. Fortunately, for the purposes of PEX and permission nodes, it's much simpler to deal with, especially with examples of it in action.

Assume that you have a group that you don't want opening the following:

  • Dispensers ('dispenser', or 23)
  • Chests ('chest', or 54)
  • Furnaces ('furnace', or 61 unlit and 'burning_furnance', or 62 lit)
  • Jukeboxes ('jukebox', or 84)

Remember to check your use-material-names node setting.

You could have a set of nodes like this:

- -modifyworld.blocks.interact.dispenser

- -modifyworld.blocks.interact.chest

- -modifyworld.blocks.interact.furnace

- -modifyworld.blocks.interact.burning_furnace

- -modifyworld.blocks.interact.jukebox

However, this is unnecessary. Using the regex support in PEX, you can combine the nodes into a single line: (if use-material-names: false, use 2nd line)

- -modifyworld.blocks.interact.(dispenser|chest|burning_furnace|furnace|jukebox)

- -modifyworld.blocks.interact.(23|54|61|62|84)

If you wanted to keep a group from destroying stone (1), grass (2), dirt (3), and cobblestone (4), you can use modifyworld.blocks.destroy.(1-4)

You can also use 'or' on other parts of the node.

Keeping with the previous example, adding the ability to place the blocks looks like modifyworld.blocks.(destroy|place).(1-4) Adding sand (12) to this example, you could use modifyworld.blocks.(destroy|place).(1-4|12)

Adding this to a group, such as the default group, is as simple as using the pex group <group> add <node> command.

  • pex group default add modifyworld.blocks.(destroy|place).(1-4|12)

Any extra nodes can be removed with the pex group <group> remove <node> command. See Commands for more on the add/remove commands.

For advanced users, users can place a $ character directly in front of the node (after any other flag characters) to prevent PEX from performing regex escaping of . and *, so that they behave as normal regex characters rather than their function as delimiters in permissions nodes (escaped by default for backwards compatibility and user sanity)

As you can see, the ability to use regex in permissions can save a lot of typing.

File Back-end Example

In the interest of completeness, this is the full permissions file after the inheritance and regex commands listed above. This example assume use-material-names: false in your plugins/Modifyworld/config.yml file.

groups:
  default:
    options:
      default: true
      rank: '1000'
    permissions:
    - modifyworld.chat
    - modifyworld.blocks.(destroy|place).(1-4|12)
  Member:
    permissions:
    - modifyworld.*
    options:
      rank: '900'
      prefix: '&0(&8M&7ember&0)&7 '
  VIP:
    inheritance:
    - Member
    permissions:
    - -modifyworld.mobtarget.monster.creeper
    options:
      rank: '800'
      prefix: '&0(&eVIP&0)&7 '
  Moderator:
    inheritance:
    - VIP
    permissions:
    - -modifyworld.mobtarget.*
    options:
      rank: '100'
      prefix: '&0(&1Moderator&0)&7 '
  Admins:
    permissions:
    - -modifyworld.mobtarget.*
    - modifyworld.*
    - permissions.*
    options:
      rank: '1'
      prefix: '&0(&4Admins&0)&7 '
schema-version: 1
users:
  AnotherPlayer:
    group:
    - default
  YourPlayerName:
    group:
    - Admins

Multiworld (top)

Having several maps (or worlds) on a server is a common way to offer more than one game play experience. However, not all commands are suitable for all worlds. You wouldn't want a hardcore survival world to have access to the give command, but it may be perfectly fine, if not required, in a world intended for free building. Fortunately, limiting a permission node to a specific world is easy with PEX by specifying the world when adding the permission node.

Assume the following server setup:

  • A survival world with Nether and End worlds (named survival, survival_nether, and survival_the_end respectively)
  • A free build world (named freebuild)
  • A group (pvp) that has the ability to build in the survival world only (modifyworld.*)
  • A group (build) that has the ability to build in the survival and free build world (modifyworld.*)

See Modifyworld page for details on block placement permission nodes.

The commands to set this up are:

  • /pex group pvp add modifyworld.* survival (add build permissions to the survival world for the pvp group)
  • /pex group build add modifyworld.* freebuild (add build permissions to the freebuild world for the build group)
  • /pex group build parents set pvp (Set the build group to inherit the permission to build in the survival world)

Keep in mind that if you edit/add the multiworld lines into the permissions file by hand, make sure the name you use matches the one used in the bukkit configs and what is on the server, capitalization matters here!

The resulting permissions will look like this in the file back-end:

groups:
  pvp:
    permissions:
    worlds:
      survival:
        permissions:
        - modifyworld.*
  build:
    inheritance:
    - pvp
    permissions:
    worlds:
      freebuild:
        permissions:
        - modifyworld.*

Multiworld inheritance (top)

You may have noticed the flaw in this setup, which is neither group had permission to build in the Nether and End worlds. This can be corrected in two ways:

  • Add the modifyworld.* node to each world individually
  • Set up world-level inheritance using /pex world <world> inherit <parentWorlds> /pex world pvp_nether inherit pvp /pex world pvp_the_end inherit pvp

These commands look like the following in the file back-end:

worlds:
  pvp_nether:
    inheritance:
    - pvp
  pvp_the_end:
     inheritance:
     - pvp
Previous: Basic Permissions Setup, Next: Ranks (Promotion and Demotion)