# Staff++

## Introduction

This plugin was originally developed By ShortNinja. After ShortNinja's passing Qball took over the support and further development.

I created this version as an attempt to add new features to StaffPlus and revitalize it. The first difference from StaffPlus is that I dropped support for all MC versions before **1.12**, this will hopefully allow me to add new features to the newer version easily and help in bug fixing more targeted. If you are using older version of Minecraft please refer to QBall's [repository](https://github.com/Qballl/StaffPlus)

I changed some of the core features:

* Support for MySQL/SQLITE Database integration
* BungeeCord integration for Staff Chat
* New and improved reporting system
* New and improved warning and punishment system
* Discord integration for reports/warnings/mutes/kicks...
* Investigation functionality
* Muting/kicking/banning
* Added a [Web platform](/web-platform/setup)

Overall I am trying to fix a lot of the existing bugs and am cleaning up the code. Hopefully this plugin can be a good successor to ShortNinja's original plugin.


# Quick start

## Installation

Download the latest version from the Spigot page. <https://www.spigotmc.org/resources/staff.83562/history> You should download the version corresponding to your MC version.

Place the jar file inside the plugins folder of your server and start your server. This will create the necessary files in the `plugins/StaffPlusPlus` folder.

## Basic configuration

Open the `config.yml` file located in the `plugins/StaffPlusPlus` folder. If you mess up the config file you can always take a look at the [default file](https://github.com/garagepoort/StaffPlusPlus/blob/master/StaffPlusCore/src/main/resources/config.yml).

#### main-world

Search for the property: `main-world` inside the configuration file. This should be the name of the main world. Meaning the world folder name which contains the player data files. By default in Minecraft this is just the "world" folder. So if you have a regular setup just leave the default setting. If for some reason your world location folder has a different name, you can change it here.&#x20;

#### server-name

Search for the property: `server-name` inside the configuration file.\
The server name should be unique for this server. If you have a multi-server setup every server running Staff++ must configure this with a different name. **If you are running a minecraft server network make sure to give this property the same name as the server name used by the network.**

{% hint style="warning" %}
I recommend keeping the server-name property alphanumeric. Underscore, dashes and spaces can be used.
{% endhint %}

#### modules

The config file contains the command and permission configuration. It also contains the different modules configuration. Different functionalities of Staff++ are configured as separate modules which can be enabled or disabled.

## Database configuration

We support 2 types of database `sqlite` and `mysql`. By default `sqlite` is configured. If you want to use a mysql database, change this part of the configuration file:

```yaml
storage:
  type: 'mysql'
  migrations-table-name: 'migrations'
  mysql:
    host: 'localhost'
    user: 'root'
    database: 'root'
    password: 'mypass'
    port: 3306
```

## Adding players as Staff Members

There is not one command to add players as Staff members. Everything in Staff++ is permission based, if you have the correct permissions you can access the Staff++ commands. If you are OP you can access all commands by default.

All permissions are listed [here](https://github.com/garagepoort/StaffPlusPlus/wiki/Permissions). This means you need some permission plugin to enable staff mode for your staff members. A commonly used permissions plugins is [Luckperms](https://www.spigotmc.org/resources/luckperms.28140/).

Once you have installed the permission plugin you can assign your player the correct permissions. All permissions in Staff++ start with a `staff.` prefix. Luckperms supports wildcards so you could give your player the permission `staff.*` and it will enable all Staff++ permissions for that player.


# Reload Configuration

Staff++ re-enabled to "reload" command. The reload command allows reloading the configuration file. However the reload command is still in an experimental phase. So keep below warnings in mind when executing it.

## Warnings

When executing the reload, player sessions won't be reverted. This means that for example if we disable the freeze command and reload the configuration the freeze command will no longer work. **But players that were frozen before reloading, will remain frozen.**

When we are changing configuration impacting "Staff Mode", it's preferable that staff members exit staff mode before reloading. Staff members that are in staff mode won't see all the config changes made until they exit and re-enter.

Changing the database connection parameters and reloading does not reset the database connection. To do so a restart is still required.

## Known issues

* Autocompletion of the commands does not change when reloading. The commands do no longer work but it's possible players will still see the commands being autocompleted.


# Multi Server Setup

{% hint style="warning" %}
You need a shared **MySQL** database to use this feature.
{% endhint %}

Staff++ added the ability to synchronize multiple features over a multiple servers.\
This guide will explain you how to easily set this up.

### Step 1: installation

Install Staff++ on every server that you want to be synced. **No** plugin is needed for the bungee server.

### Step 2: Database

Configure the database connection inside the configuration file.

```yaml
storage:
  type: 'mysql'
  migrations-table-name: 'migrations'
  mysql:
    host: 'localhost'
    user: 'root'
    database: 'root'
    password: 'mypass'
    port: 3306
```

You **must** configure **mysql** to synchronize the servers.\
Every Staff++ instance must be configured to use the same database

### Step 3: Server name

#### server-name

Search for the property: `server-name` inside the configuration file.\
The server name should be unique for every server. Every server running Staff++ must configure this with a different name. **If you are running a minecraft server network make sure to give this property the same name as the server name used by the network.**

{% hint style="info" %}
I recommend keeping the server-name property alphanumeric. Underscore, dashes and spaces can be used.
{% endhint %}

### Step 4: Server synchronization config

#### server-sync-module

Look for the following section in the configuration file.

```yaml
server-sync-module:
    vanish-sync: false
    staffmode-sync: false
    ban-sync: ''
    report-sync: ''
    warning-sync: ''
    mute-sync: ''
    kick-sync: ''
    notes-sync: ''
```

#### All these properties can be disabled and enabled at any time without impacting previous data.

#### vanish-sync

Allows a player to remain vanished when switching between servers. No join and leave message will be displayed.

#### staffmode-sync

Allows a staff member to keep his staff mode when switching between servers.&#x20;

{% hint style="warning" %}
To use this you must set the properties `enable-on-login` and `disable-on-logout` underneath the **staff-mode** section, to **false**
{% endhint %}

### Data sync

Below properties are all configured in the same way.&#x20;

Inside this property we can configure all other servers we want to be able to read data from. Let's say we have 4 servers all linked to the same Staff++ mysql db. The servers are named `MC1` `MC2` `MC3` and `MC4` . MC1, MC2 and MC4 should share reports, while MC3 has it's own reports. Bans should be shared across all servers. MC2 and MC4 share the same mutes. MC1 and MC3 also share the same mutes.&#x20;

You can leave the property empty if you only want to read data from your own server.

The `[ALL]` value can be used to tell staff++ to read data from all servers.&#x20;

#### MC1 config:

```yaml
server-sync-module:
    ban-sync: '[ALL]'
    report-sync: 'MC1;MC2;MC4'
    mute-sync: 'MC1;MC3'
```

#### MC2 config

```yaml
server-sync-module:
    ban-sync: '[ALL]'
    report-sync: 'MC1;MC2;MC4'
    mute-sync: 'MC2;MC4'
```

#### MC3 config

```yaml
server-sync-module:
    ban-sync: '[ALL]'
    report-sync: ''
    mute-sync: 'MC1;MC3'
```

#### MC4 config

```yaml
server-sync-module:
    ban-sync: '[ALL]'
    report-sync: 'MC1;MC2;MC4'
    mute-sync: 'MC2;MC4'
```

#### ban-sync

When configured players will get banned on every server listed. If nothing filled in, the player is only banned on the server where the ban was initiated.\
This also impacts the Staff GUI. When enabled the staff GUI shows all banned players from all configured servers. If disabled you only see the banned players on the current server.&#x20;

#### report-sync

When enabled, the GUI reports shows all reports a player has made on whatever server the report was created. The infractions GUI will also include players who got reported on other servers

#### warning-sync

When enabled warning thresholds will be calculated based on player warnings from across all configured servers.\
If disabled only warnings from the current server are taken into account.\
\
The list of warnings retrieved shows either all warnings from a player or only the warnings issued from the current server.

#### mute-sync

When enabled players will get muted on every configured server having staff++ installed. If disabled the player is only muted on the server where the mute was initiated.\
This also impacts the Staff GUI. When enabled the staff GUI shows all muted players from all configured servers. If disabled you only see the muted players on the current server.&#x20;

#### kick-sync

This impacts the infractions Staff GUI. When enabled the staff GUI shows all kicks a player has received from all configured servers. If disabled you only see the kicks the player has received from the current server.&#x20;

#### notes-sync

When enabled, the notes displayed linked to a player are shared across all configured servers. If disabled you will only see notes that were created on the current server.


# General Configuration

```yaml

# The name of the server. This can be anything you want but it must be unique and once chosen it shouldn't change anymore.
server-name: "MyUniqueServerName"
# The name of the main world. Meaning the world folder name which contains the player data files.
main-world: "world"
# The format in which all dates will be displayed inside the GUIs.
# All Java date time formats can be used
timestamp-format: 'dd/MM/yyyy-HH:mm:ss'

# The language file that will be referred to for messages.
# Current available languages are: lang_en, lang_sv, lang_de, lang_nl, lang_es, lang_hr, lang_no, and lang_fr.
# If you would like to translate Staff++, please message me on Spigot!
lang: "lang_en"

# Chooses the authentication provider. Default "noop", no authentication will be done.
# AuthMe is supported. When the provider is authMe, Staff++ will enforce that the user is authenticated through AuthMe before being able to execute the commands.
authentication:
    provider: noop

# Commands that staff will not be allowed to use at all.
# Must have "permissions.block" permission to take effect.
# Leave blank to disable.
blocked-commands: "/example1, /example2, /example3"

# Commands that staff will not be allowed to use while in staff mode.
# Must have "permissions.block" permission to take effect.
# Leave blank to disable.
blocked-mode-commands: "/example1, /example2, /example3"

# The default color of glass for the side of GUIs. Just a cosmetic thing that staff members can change.
glass-color: 0

# The title of the glass color chooser GUI.
glass-title: "&bChoose GUI glass color"

# Enable offline player mode
# report-bypass & warn-bypass does not work for offline players
offline-players-mode: true
```

#### server-name

Search for the property: `server-name` inside the configuration file.\
The server name should be unique for this server. If you have a multi-server setup every server running Staff++ must configure this with a different name.

{% hint style="warning" %}
I recommend keeping the server-name property alphanumeric. Underscore, dashes and spaces can be used.
{% endhint %}

#### main-world

Search for the property: `main-world` inside the configuration file. This should be the name of the main world. Meaning the world folder name which contains the player data files. By default in Minecraft this is just the "world" folder. So if you have a regular setup just leave the default setting. If for some reason your world location folder has a different name, you can change it here.&#x20;

#### timestamp-format

Configure the way you want dates and times to be displayed inside the in-game GUI screen.\
You can use the java datetime format options.\
Examples:

| **format**            | Example                |
| --------------------- | ---------------------- |
| dd/MM/yyyy HH:mm:ss   | 31/12/2020 15:23:10    |
| dd/MM/yyyy hh:mm:ss a | 31/12/2020 03:23:10 PM |
| MM-dd-yyyy hh:mm a    | 12-31-2020 03:23 PM    |

### Another plugin is overriding a staff++ command

It is possible that another plugin like 'essentialsx' might get priority over certain commands like the `ban`, `tempban` and `unban` command. To prevent this we suggest the same solution as is proposed by [EssentialsX](https://github.com/EssentialsX/Essentials/wiki/Common-Issues#essentialsx-overrides-a-command-from-spigot-or-another-plugin).

Configure your server aliases in such a way that the commands from Staff++ will always be used. This can be done by editing the `commands.yml` file and specifying your aliases there.

To enable Staff++ commands this would be done, for example, in this way:

```yaml
aliases:
    ban:
    - "staffplusplus:ban $1-"
    tempban:
    - "staffplusplus:tempban $1-"
    unban:
    - "staffplusplus:unban $1-"
```

More info on the [bukkit wiki](https://bukkit.gamepedia.com/Commands.yml#aliases)


# Other


# Text parsing

### Introduction

In staff++ there are messages file which contain most of the text used within staff++.

### New lines

New lines can be achieved using 2 ways

#### \n notation

```
ban-permabanned-kick: "[Banned] You have been permanently banned\nfrom this server"
```

#### YAML multiline notation

```
ban-permabanned-kick: |
    [Banned] You have been permanently banned 
    from this server
```

### Tooltips

Tooltips are supported in the newest version of staff++.\
These can be configured by using the notation:

#### \[tooltip|\<hoverable text>|\<tooltip text>]

#### Example

\[tooltip|&6%player%''s|&6%player%\n&7This guy] armor has been removed!

![](/files/5xe8Va14ZMXmTutz6fOj)

### Basic colors

Basic colors are supported using **"&"**

![](/files/RBh7Ka9wrrxZAsV7eRLK)

### Hex Colors

In versions >= 1.16 hex colors are supported using hex notation

```markup
#FF0044This is in some color. #EE8833This is another color.
```

### Gradients

In versions >= 1.16 gradient colors are supported using:

```markup
<#00d8e6>This is gradient</#8ae0e6>
```


# Styling the GUIs

In Staff++ it's possible to add configuration files to change the look of the in-game GUIs.

{% hint style="info" %}
Styling can only be used to change the appearance of the GUI. Color, Material, location of items, ...&#x20;

It cannot change the content of the GUI. It cannot change the title of the inventory to something else. It cannot change the action that is taking when clicking on an item. It cannot add random items to the GUI.
{% endhint %}

### Getting started

To begin styling in Staff++, follow these steps:

1. Grant yourself the `staff.show-style-info` permission. This permission enables you to use the `/show-style-info` command.
2. In your game, execute `/show-style-info`. In this example, we'll work with the report details screen.
3. You'll notice that the reports GUI now displays additional information in the inventory title and items.
4. To ensure that all lore (text descriptions) is displayed correctly, adjust the GUI scale in your video settings.
5. Keep in mind that some classes may not appear in the GUI, but you can find them in the important classes section of the Staff++ wiki.

![](/files/ch2PpLKfOidieoneboz6)

Id's are shown in RED and classes are shown in GREEN. Note that all labels and values in this item lore have all the same classes. While the ids are always different.

### Styles folder

Create a `styles` folder inside the Staff++ plugin folder. This folder will contain all style configuration files for Staff++. You can create as many files as needed and name them as you prefer. A good practice is to create at least one style config file for each GUI you want to modify.

For our example, we'll use two style files. Create a `report-detail.yml` file for styling rules specific to the report details GUI.

![](/files/z0ND0gKaU9iyhBL4EACl)

## Example

In the example below, we'll customize the view of the report details. Each part of the styling is explained separately, and the complete `report-details.yml` is provided at the end with all styling rules.

### Changing the title color

To change the title color, reference the class associated with all titles in the `report-detail.yml` and reload the plugin using `/staffplus reload`:

```yaml
# Id of the GUI
report-detail:
    # This is a class that is always placed on the title of GUIs 
    $gui-title:
        # Change the color of title component
        color: "&1"
```

![](/files/hxRYt2vQuFMAUbGDJ08k)

### Changing an item.

If you have enabled show-style-info you'll see that the item's id is `report-info`. But the item also has a **class report-info**. In our case we are going to use the class. We can use this class in our **report-detail.yml** to change the item.&#x20;

In this example I will change the material to be a book. I'll change the color of the item name to `&f`. I'll change the color of all labels to `&7` and change the colors of all values to `&6.` I'll remove the ID and location lines and I'll remove the status label but not the actual status.

Reload the plugin using `/staffplus reload`

```yaml
report-detail: 
    # Class of the info item
    $report-info:
        material: BOOK
        # All item names in the GUIs have a class called item-name
        # We can use this to change the color of the item.
        $item-name:
            color: "&f"

        # Change all text part color inside the lore of this item
        # We use the class name so that we can match all text parts with one rule.
        $detail-label:
            color: "&7"
        $detail-value:
            color: "&6"

        # Hide the entire id line
        id-label:
            hidden: true
        id-value:
            hidden: true

        # Hide the entire culprit line
        culprit-label:
            hidden: true
        culprit-value:
            hidden: true


        # Hide the entire location line
        location-label:
            hidden: true
        location-world-value:
            hidden: true
        location-separator:
            hidden: true
        location-block-value:
            hidden: true

        # Hide only the status label
        status-label:
            hidden: true
```

#### BEFORE

![before](/files/HQvKxijt7W2PTG98r1xx)

#### AFTER

![](/files/fKsP8Md6QVdH1ba8pG2X)

### Hiding Items

We can also hide items from the GUI.

{% hint style="warning" %}
Just because an item is hidden doesn't mean the player can't access the functionality in some other way. If you want to disallow the player from using a functionality you need to setup the correct permissions.
{% endhint %}

Let's remove some of those large unassign/reject and resolve action items. Add the following to your **report-detail.yml** and reload the plugin using `/staffplus reload`

```yaml
# Class of the GUI
$report-detail:
    # Id of the item   
    unassign-1:
        hidden: true
    unassign-2:
        hidden: true
    unassign-3:
        hidden: true

    reject-1:
        hidden: true
    reject-2:
        hidden: true
    reject-3:
        hidden: true
    reject-4:
        hidden: true
    reject-5:
        hidden: true

    resolve-1:
        hidden: true
    resolve-2:
        hidden: true
    resolve-3:
        hidden: true
```

![](/files/hGLkrLYglGtbpKWgH05N)

### Moving items

The above seems a bit weird. But we can move the items to make the GUI more compact. Also let's move the back button to another location. Add the following to your **report-detail.yml** and reload the plugin using `/staffplus reload`

```yaml
report-detail:
    back-button:
        slot: 17
    unassign-0:
        slot: 1
    reject-0:
        slot: 2
    resolve-0:
        slot: 3
```

![](/files/bYDcR45vbQqYWOjtk35l)

### Changing the size

Now that everything is more compact we can change the actual size of the inventory

{% hint style="warning" %}
Careful when changing the size. If you change the size but some items are located in slote that are not valid for the inventory's size that GUI will break. So make sure to first locate all items in the correct position before resizing.
{% endhint %}

Add the following to your **report-detail.yml** and reload the plugin using `/staffplus reload`

```yaml
report-detail:
    size: 18
```

![](/files/HNWn2LgQo4UzWoI9LBnu)

### Generalizing style rules

{% hint style="warning" %}
It's important to note that because all the styling rules are defined underneath the report-detail section, the rules are only applied to that specific GUI. If you would open the reports overview for example the report info item would have none of the below changes
{% endhint %}

If you would like that your report info item has the above rules applied to every GUI in which it is used we need to move the rules to be less specific to this gui. We can simply do this by creating another file called **reports-styling.yml (**&#x74;his file will serve as common style rules for report&#x73;**)** and place that file inside the styles folder.

Remove the entire **report-info** section from the report-details.yml file and add to the **reports-styling.yml**

Conveniently in staff++ all report information items in the GUI all have the **report-info** class. So this rule will match all those components regardless of which GUI they are in.

```yaml
# All rules for any component with the class report-info
$report-info:
    material: BOOK
    # All item names in the GUIs have a class called item-name
    # We can use this to change the color of the item.
    $item-name:
        color: "&f"

    # Change all text part color inside the lore of this item
    # We use the class name so that we can match all lorelines with one rule.
    $detail-label:
        color: "&7"
    $detail-value:
        color: "&6"

    # Hide the entire id line
    id-label:
        hidden: true
    id-value:
        hidden: true

    # Hide the entire culprit line
    culprit-label:
        hidden: true
    culprit-value:
        hidden: true


    # Hide the entire location line
    location-label:
        hidden: true
    location-world-value:
        hidden: true
    location-separator:
        hidden: true
    location-block-value:
        hidden: true

    # Hide only the status label
    status-label:
        hidden: true
```

&#x20; So now we can see our changes as well in all other GUIs containing report info items

![](/files/O3mHb7SSJCC9cZnMWZ38)

### Full example

{% tabs %}
{% tab title="styles/report-details.yml" %}

```yaml
# The id of the GUI
report-detail:
    # Change the size of the GUI
    size: 18
    # Change the gui title color
    # All gui titles in staff++ have the $gui-title class
    $gui-title:
        color: "&1"

    # Move the back button to the correct location
    back-button:
        slot: 17

    # Move the action buttons to the correct location    
    unassign-0:
        slot: 1
    reject-0:
        slot: 2
    resolve-0:
        slot: 3


    # Hide all action items we do not want
    # ====================================
    unassign-1:
        hidden: true
    unassign-2:
        hidden: true
    unassign-3:
        hidden: true


    reject-1:
        hidden: true
    reject-2:
        hidden: true
    reject-3:
        hidden: true
    reject-4:
        hidden: true
    reject-5:
        hidden: true

    resolve-1:
        hidden: true
    resolve-2:
        hidden: true
    resolve-3:
        hidden: true
```

{% endtab %}

{% tab title="styles/reports-styling.yml" %}

```yaml
# All rules for any component with the class "report-info"
$report-info:
    material: BOOK
    # All item names in the GUIs have a class called item-name
    # We can use this to change the color of the item.
    $item-name:
        color: "&f"

    # Change all text part color inside the lore of this item
    # We use the class name so that we can match all lorelines with one rule.
    $detail-label:
        color: "&7"
    $detail-value:
        color: "&6"

    # Hide the entire id line
    id-label:
        hidden: true
    id-value:
        hidden: true

    # Hide the entire culprit line
    culprit-label:
        hidden: true
    culprit-value:
        hidden: true


    # Hide the entire location line
    location-label:
        hidden: true
    location-world-value:
        hidden: true
    location-separator:
        hidden: true
    location-block-value:
        hidden: true

    # Hide only the status label
    status-label:
        hidden: true
```

{% endtab %}
{% endtabs %}


# Gui structure

### GUIs structure

GUIs in staff++ have these main components:

* Container -> The inventory as we see it.&#x20;
* Item -> One item in the container represented by an itemstack.&#x20;
* Text -> Text consists of one or more TextParts.
* TextPart -> A TextPart holds certain written context.

Using the configuration files we can [select components ](/general-information/other/styling-the-guis/selectors)and change their styling.

#### Container

The container is the inventory we are showing.  Using styling we can change:

* The color of the title
* The size of the GUI

#### Item

An Item is a wrapper around an itemstack. Using styling we can change.

* The location of the item
* The color of the name

#### Text & TextParts

The Text component is used whenever we want to display some sort of text inside the component. The component contains one or more TextParts. Text is used for the title of the GUI and the name or Lore of an ItemStack. Every TextPart can be changed using styling:

* TextPart can be hidden/shown
* Color of TextPart can be changed.

### IDs and Classes

The above components can all be assigned 1 id and multiple classes.

#### ID

An id is given to a component to identify it, we can use this id to reference the component inside our style configuration.

**Class**

A class, just like an id, is used to reference a component. The main difference is that a class can reference multiple components. While an id must only reference one.&#x20;

A class is also more lenient in how it can reference components.


# Selectors

Inside the style configuration files we need to use what we call "selectors" to try and select the correct [component](/general-information/other/styling-the-guis/gui-structure) for which we want to change the styling.

We basically have 2 ways of selecting a component.

* By ID
* By Class

Make sure to enable style information by executing `/show-style-info`

![](/files/ch2PpLKfOidieoneboz6)

Ids are shown in <mark style="color:red;">red</mark> and classes are shown in <mark style="color:green;">green</mark>.

### Gui

The ID of the GUI is shown before the title of the GUI

![](/files/xpqkqe8TlTC52LthW597)

### Items

Item id and classes are shown before the name of the item

![](/files/x81DiCGAxBTIyjCQU5xG)

### Lore line

Ids and classes of the lore lines are shown below the line. Do note that one line inside the lore can consist of multiple parts. Each part is a component and thus can have its own ID and classes. If you see multiple ids next to each other it means there are multiple text parts.

![](/files/LIfL3eiYdIivwpsdkkbg)

In this example there are 2 text parts for this one loreline. One is the label "Reporter: " and the other one is the value "garagepoort".&#x20;

## Selecting and applying styling

We use the YAML file format for styling. Inside the `styles` directory we can create whatever yml config file we want and the rules configured in it will be picked up.

#### ID selection

```yaml
report-detail:
    report-info:
        reporter-label:
            color: "&C"
```

The selector in the above case is: **report-detail -> report-info -> report-label**

Basically this means we are selecting a component with the id "report-label" which is part of another component with the id "report-info" which then again is part of a GUI with the ID "report-detail". We can see in the screenshot this will select part of the lore of the report information item.

Then we set the styling rules for this component by, in this example, setting the color of that specific part of the lore.

#### Class selection

```yaml
report-detail:
    report-info:
        $detail-label:
            color: "&C"
```

The selector in the above case is: **report-detail -> report-info -> $detail-label**

Basically this means we are selecting any component that has the class "detail-label" which is part of another component with the id "report-info" which then again is part of a GUI with the ID "report-detail". We can see in the screenshot this will select multiple parts of the lore of the report information item.

The dollar prefix in `$detail-label` means we are selecting a class and not an ID.

Then we set the styling rules for this component by, in this example, setting the color of that those specific parts of the lore.&#x20;


# Configuring command hooks

You can configure commands to execute for different parts of the staff++ configuration.\
For example when entering/exiting staff mode or on report lifecycle change

This part of the documentation explains how to configure commands.

An example of the report commands configuration.

```yaml
accept-commands:
    - command: "tell %culprit% You have been reported. %assigned% will handle the case."
      target: "culprit"
      target-run-strategy: ONLINE
      filters: "hasculprit=true"
```

A command consists of :

| property              | description                                                                                                                                                                                                    | required                       | default value |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | ------------- |
| command               | The command to be executed                                                                                                                                                                                     | true                           |               |
| executor              | Determines by who the command will be executed. If not filled in this will default to "console". Which values you can use for executor is determined by the context in which the command is used.              | false                          | console       |
| executor-run-strategy | If the executor is not online when the command should be invoked, you can delay the execution by specifying DELAY as run strategy                                                                              | false                          | ONLINE        |
| target                | If this command is targeting a specific player you can define the player to be targeted here. If not filled on no target is defined. This should only be used in combination with the **target-run-strategy.** | false                          |               |
| target-run-strategy   | If target is filled in you also need to provide a run strategy                                                                                                                                                 | Required if target is provided |               |
| filters               | Depending on the context in which the command is executed one or more filters may be configured. If all filters are valid the command will be executed.                                                        | false                          | empty         |

### Basics

The most basic command configuration is as such:

```yaml
- command: "mycommand here"
```

The command will be executed by console.

### Custom executor

If you want the command to be executed by someone else other than the console you can specify the executor here. Valid values depend on the context of the command. \
\
For example for report commands you can use the "**reporter**" as executor. To know which executor can be used in which context check the documentation page of the corresponding functionality

```yaml
- command: "mycommand here"
  executor: reporter
```

#### executor-run-strategy

This property defaults to ONLINE, which means the executor must be online for the command to be run. If he is not online the command will be skipped.\
\
If you would like to wait for the executor to come online, it's possible to define DELAY as run strategy. If the executor is offline, the command will run the next time the executor comes online. If the executor is online the command will run immediately.

```yaml
- command: "mycommand here"
  executor: reporter
  executor-run-strategy: DELAY
```

### Target

It's possible to define a **target** and **target-run-strategy**. These 2 properties must always be used together.

Using these properties we can choose the either not run a command if the target player is offline or to delay the command until the target comes online. Valid values depend on the context of the command. \
\
For example for report commands you can use the "**culprit**" as target. To know which targets can be used in which context check the documentation page of the corresponding functionality

If you would like to wait for the target to come online, it's possible to define DELAY as run strategy. If the target is offline, the command will run the next time the target comes online. If the target is online the command will run immediately.

```yaml
- command: "freeze %culprit%"
  target: culprit
  target-run-strategy: DELAY
```

### Filters

You can specify filters to determine if a command must be executed.\
Valid filters depend on the context of the command. To know which filters can be used in which context check the documentation page of the corresponding functionality

For example for commands executed by **warnings** you can use the **severity** filter.

```yaml
- command: "freeze %culprit%"
  filters: 'severity=CRITICAL'
```

#### Permission filter

However one filter is always available:

| filter     | possible values | Description                                                   |
| ---------- | --------------- | ------------------------------------------------------------- |
| permission | Any permission  | Only run the command if the executor has the given permission |

### placeholders

Different placeholders can be used inside the commands. The placeholders that you can use is depended in the context of the command. To know which placeholders can be used in which context check the documentation page of the corresponding functionality


# Commands

{% hint style="info" %}
All commands can be custom configured inside the `configuration/commands.yml` file
{% endhint %}

{% hint style="info" %}
To disable a command completely edit the commands.yml and provide an empty `''` value for that command.
{% endhint %}

## Over**vi**ew

```yaml
############################################################
# +------------------------------------------------------+ #
# |                      Commands                        | #
# +------------------------------------------------------+ #
############################################################

# All commands and their according names.
# Leave a command blank to disable it.

staffplus: ["staffplusplus"]
# The command for toggling staff mode.
staff-mode: ["staff"]
# The command for toggling fly while in staff mode.
staff-mode-fly: ["sfly"]
# The command opening the StaffHub GUI
staff-hub: ["staffhub"]

# The command for toggling freeze on players.
freeze: ["freeze"]
# The command sending messages on a freeze channel.
freezechannel.chat: ["fc"]

# The command for teleporting a player to predefined locations
teleport-to-location: ["teleportToLocation"]

# The command for teleporting a player back to a previous location
teleport-back: ["teleportBack"]

# The command for teleporting yourself to another player
teleport-to-player: ["teleportToPlayer"]

# The command for teleporting a player to your location
teleport-here: ["teleportHere"]

# The command for examining players' inventory
examine: ["examine"]

# The command for reading notes.
notes: ["notes"]
# The command for creating player notes
note: ["note"]
private-note: ["pnote"]

# The command for running a clicks per second test on a player
cps: ["cps"]

# The command for opening the my reports gui
my-reports: ["my-reports"]

# The command for reporting and managing reports.
report: ["report"]

players: ["players"]

# The command for reporting and managing reports specifically targeting a player.
reportPlayer: ["reportPlayer"]

reports:
    chat: ["rc"]
    manage:
        #Command to open the manage reports gui
        gui: ["manage-reports"]
        gui-find-reports: ["find-reports"]
        # The command for managing reports specifically targeting a player.
        cli: ["reports"]
        teleport-to-report: ["teleport-to-report"]

investigations.manage:
    start: ["investigate"]
    pause: ["pause-investigation"]
    conclude: ["conclude-investigation"]
    gui: ["manage-investigations"]
    add-note: ["inote"]
# The command for warning players
warn: ["warn"]

# The command for warning and managing warnings.
warns: ["warns"]

warnings.manage:
    #Command to open the manage warnings gui
    gui: ["manage-warnings"]
    #Command to open the manage warnings gui
    appealed-gui: ["manage-appealed-warnings"]

# The command for opening the my warnings gui
my-warnings: ["my-warnings"]

# The command for toggling vanish modes.
vanish: ["vanish"]

# The command for chat management.
chat: ["chat"]

# The command for creating and managing tickets.
ticket: ["ticket"]

# The command for alerts management.
alerts: ["alerts"]

# The command for toggling player following.
follow: ["follow"]

# The command for reviving players.
revive: ["revive"]

# The command for listing staff members.
staff-list: ["personnel"]

# The command for logging in.
login: ["login"]

# The command for registering a password.
register: ["register"]

# The command for stripping a player's armor.
strip: ["strip"]

# The command for clearing a players inventory
clearInv: ["clear"]

# The command to start/stop tracing a player
trace: ["trace"]

# The command to view a players ender chest
echest_view: ["eview"]

# The command to broadcast a message over all servers
broadcast: ["broadcast"]

# The command to toggle protection of a player
protect-player: ["protectPlayer"]

# The command to create/delete a protected area
protect-area: ["protectArea"]

bans.manage:
    gui: ["manage-bans"]
    appealed-gui: ["manage-appealed-bans"]

# The command to permanently ban a player
ban: ["ban"]
bans-migrate: ["bans-migrate"]

# The command to temporarily ban a player
tempban: ["tempban"]

extendban: ["ban-extend"]
reduceban: ["ban-reduce"]

# The command to unban a player
unban: ["unban"]

# The command to kick a player
kick: ["kick"]

# The command to permanently mute a player
mute: ["mute"]
mutes.manage:
    gui: ["manage-mutes"]
    appealed-gui: ["manage-appealed-mutes"]
# The command for opening the my mutes gui
my-mutes: ["my-mutes"]

# The command to temporarily mute a player
tempmute: ["tempmute"]
extendmute: ["mute-extend"]
reducemute: ["mute-reduce"]

# The command to unmute a player
unmute: ["unmute"]

# The command to unban a player
alt-detect-whitelist: ["altWhitelist"]
# The command to unban a player
alt-detect-check: ["altCheck"]

# The command to view the infractions of a player
infractions-view: ["infractions"]

# The command to view the players with the most infractions
infractions-top-view: ["infractions-top"]

webui:
    register: ["register"]

ipban:
    ban: ["ipban"]
    tempban: ["iptempban"]
    unban: ["ipunban"]
    bancheck: ["ipban-check"]
    ipbans: ["ipbans"]
    migrate: ["ipbans-migrate"]

ips:
    clear-ips: ["clear-ips"]
choice-action: ["choice-action"]

show-style-info: ["show-style-info"]

chatchannels:
    join: ["join-channel"]
    leave: ["leave-channel"]
    close: ["close-channel"]

staff-locations:
    create: ["create-stafflocation"]
    view: ["stafflocations"]
    teleport-to-stafflocation: [ "teleport-to-stafflocation" ]
```

### Cooldowns

Every command in staff++ can have a cooldown. This is purely permission based.\
If you want to enforce a cooldown, the player needs the cooldown permission.\
\
The permissions is the following:\
`staff.<command>.cooldown.<time>`\
\
So for example if I want to enforce a cooldown on the `report` command I assign the following permission to the players: `staff.report.cooldown.30s` \
This enforces a 30 second cooldown.

{% hint style="warning" %}
Cooldowns are not enforced across servers in a multi server setup. Restarting the server resets all cooldowns.
{% endhint %}

## Arguments

Staff++ supports an argument system which can be used to enhance the default commands. We list below the arguments we currently support. In the commands table you can see which commands can use which arguments

### -T Teleport

Teleport let's us enhance a command by teleporting the target to a predefined location. You can setup locations in the configuration file. See **Locations**

Example: `/freeze player1 -Tspawn`

Description: Teleports player1 to the predefined location "spawn" and immediately freezes him.

### -S Strip

-S does the same as the strip command: Takes off the player's armor and places it in his inventory. If there are no free spaces left in the player's inventory the armor is not taken off.

Example: `/freeze player1 -S`

Description: Freezes the player and strips his armor.

### -H Health

Sets the player's health to the given percentage.

Example: `/freeze player1 -H100`

Description: Freezes the player and gives the player full health.

### -D Delay a command

When provided with a base command. The command will be delayed until the player joins the server. This is useful when we want to for example clear the inventory of a player, but he's offline. With the -D argument we can still run the 'clear' command. It will not be executed immediately, but it will be executed the next time the player joins the server.

Example: `/clear player1 -D`

Description: Clear the players inventory the next time he joins the server

## Another plugin is overriding the a staff++ command

It is possible that another plugin like 'essentialsx' might get priority over the `staff++` command. To prevent this we suggest the same solution as is proposed by [EssentialsX](https://github.com/EssentialsX/Essentials/wiki/Common-Issues#essentialsx-overrides-a-command-from-spigot-or-another-plugin).

Configure your server aliases in such a way that the commands from Staff++ will always be used. This can be done by editing the `commands.yml` file and specifying your aliases there.

To enable Staff++ commands this would be done in this way. The below example is for the staff++ ban commands

```yaml
aliases:
    ban:
    - "staffplus:ban $1-"
    tempban:
    - "staffplus:tempban $1-"
    unban:
    - "staffplus:unban $1-"
```

More info on the [bukkit wiki](https://bukkit.gamepedia.com/Commands.yml#aliases)


# Permissions

{% hint style="info" %}
All permission nodes can be custom configured inside the `configuration/permissions.yml` file
{% endhint %}

{% hint style="danger" %}
Below is the configuration for the latest staff++ version.\
It's best to check your own configuration file to see the correct permissions
{% endhint %}

```yaml
############################################################
# +------------------------------------------------------+ #
# |                     Permissions                      | #
# +------------------------------------------------------+ #
############################################################

# Use this to give a player all Staff+ permissions.
# Take note that this will NOT give the player the "block" permission.
# This also gives the player permission to toggle other player's vanish, staff mode, and etc.
wild-card: "staff.*"
# Permission for using /staffplus
staffplus: "staff"
# Use this for players who's ip should not be shown in examine mode
ipPerm: "staff.hideip"
# Permission for blocking listed commands at "blocked-commands" and "blocked-mode-commands".
block: "staff.block"
# Permission for bypassing the word blacklist.
blacklist: "staff.blacklist.bypass"

# Permission for giving a player's previous inventory back.
revive: "staff.revive"
# Permission for being noted as a staff member in the staff list command and for login.
member: "staff.member"
# Permission for using "/strip".
strip: "staff.strip"
# Permission for managing the alerts you will get
broadcast: "staff.broadcast"
# Permission for initializing clicks per second tests
cps: "staff.cps"
# Permission for using examine
examine: "staff.examine"
# Permission to open the infractions gui
infractions:
    view: "staff.infractions.view"

staff-list.view: "staff.personnel.view"
staff-hub.view: "staff.hub.view"

########################
# REPORTS
# GROUP: staff.chatchannels
# permissions should be suffixed with the chatchannel type
# Example: staff.chatchannels.leave.report
########################

chatchannels:
    join: "staff.chatchannels.join"
    leave: "staff.chatchannels.leave"
    open: "staff.chatchannels.open"
    close: "staff.chatchannels.close"
########################
# REPORTS
# GROUP: staff.reports
########################
# Permission for reporting players.
report: "staff.reports.report"
reports:
    chat: "staff.reports.chat"
    # All permission for managing reports
    manage:
        view: "staff.reports.manage.view"
        delete: "staff.reports.manage.delete"
        accept: "staff.reports.manage.accept"
        resolve: "staff.reports.manage.resolve"
        reject: "staff.reports.manage.reject"
        teleport: "staff.reports.manage.teleport"
        reopen-other: "staff.reports.manage.reopen-other"
# Permission for bypassing reports.
report-bypass: "staff.reports.report-bypass"
# Permission for receiving notifications when a report is accepted/deleted/closed
report-update-notifications: "staff.reports.update.notifications"
# Permission to open to my reports gui
view-my-reports: "staff.reports.view-my-reports"

########################
# WARNINGS
# GROUP: staff.warnings
########################

# Permission to open to my warnings gui
view-my-warnings: "staff.warnings.view-my-warnings"
# Permission for using "/warn" and clearing/getting player warnings.
warn: "staff.warnings.warn"
# Permission for bypassing warnings.
warn-bypass: "staff.warnings.warn-bypass"
warnings:
    notifications: "staff.warnings.notifications"
    # All permission for managing warnings
    manage:
        view: "staff.warnings.manage.view"
        delete: "staff.warnings.manage.delete"
        expire: "staff.warnings.manage.expire"
    appeals:
        create: "staff.warnings.appeals.create"
        create-others: "staff.warnings.appeals.create.others"
        approve: "staff.warnings.appeals.approve"
        reject: "staff.warnings.appeals.reject"
        notifications: "staff.warnings.appeals.notifications"

########################
# INVESTIGATION
# GROUP: staff.investigation
########################
investigations:
    # All permission for managing investigations
    manage:
        investigate: "staff.investigation.manage.investigate"
        notifications: "staff.investigation.manage.notifications"
        view: "staff.investigation.manage.view"
        link-evidence: "staff.investigation.manage.link-evidence"
        add-note: "staff.investigation.manage.add-note"
        delete-note: "staff.investigation.manage.delete-note"
        delete-note-others: "staff.investigation.manage.delete-note-others"

########################
# VANISH
# GROUP: staff.vanish
########################
# Permission for using the vanish command
vanish: "staff.vanish.vanish"
# Permission for using the vanish command
vanish-others:
    total: "staff.vanish.others.total"
    list: "staff.vanish.others.list"
    player: "staff.vanish.others.player"
see-vanished: "staff.vanish.see-vanished"
# Permission for using "/v total".
vanish-total: "staff.vanish.total"
# Permission for using "/v list".
vanish-list: "staff.vanish.list"
# Permission for using "/v player".
vanish-player: "staff.vanish.player"

########################
# CHAT
# GROUP: staff.chat
########################
# Permission for using "/chat clear".
chat-clear: "staff.chat.clear"
# Permission for using "/chat toggle".
chat-toggle: "staff.chat.toggle"
# Permission for using "/chat slow".
chat-slow: "staff.chat.slow"

########################
# ALERTS
# GROUP: staff.alerts
########################
alerts:
    # Permission for managing the alerts you will get
    manage-alerts: "staff.alerts.alerts"
    notifications:
        # Permission for receiving mention alerts.
        mention: "staff.alerts.mention"
        # Permission for receiving name change alerts.
        name-change: "staff.alerts.namechange"
        # Permission for receiving xray alerts.
        xray: "staff.alerts.xray"
        # Permission for receiving alt detect alerts.
        alt-detect: "staff.alerts.alt-detects"
        # Permission for receiving chat word mentions alerts.
        chat-phrase-detection: "staff.alerts.chat-phrase-detection"
        # Permission for receiving chat word mentions alerts.
        command-detection: "staff.alerts.command-detection"
        # Permission for bypassing chat word mentions alerts.
        # Permission for receiving chat blacklist alerts.
        blacklist-detection: "staff.alerts.blacklist-detection"

name-change-bypass: "staff.namechange-bypass"
mention-bypass: "staff.mention-bypass"
xray-bypass: "staff.xray-bypass"
command-detection-bypass: "staff.command-detection.bypass"
# Permission for bypassing chat phrase detection.
chat-phrase-detection-bypass: "staff.chat-phrase-detection.bypass"

########################
# MODE
# GROUP: staff.mode
########################
# Permission for toggling staff mode.
mode: "staff.mode.mode"
# Permission for turning on a specific staff mode
mode-specific: "staff.mode.specific-mode"
# permission to interact with chests/hoppers/dispensers.
mode-silent-chest-interaction: "staff.mode.silent-chest-interaction"
# Permission for using the staff mode compass
compass: "staff.mode.compass"
# Permission for using the staff mode random teleport
random-teleport: "staff.mode.random-teleport"
# This excludes the player from being randomly teleported to!
random-teleport-bypass: "staff.mode.random-teleport.bypass"
# Permission for the staff mode GUI hub
gui: "staff.mode.gui"
# Permission for the staff mode counter GUI
counter: "staff.mode.counter"
# Permission to show if staff members are vanished in the counter GUI
counter-show-vanished: "staff.mode.counter-show-vanished"
# Permission for using staff mode follow
follow: "staff.mode.follow"

########################
# FREEZE
# GROUP: staff.freeze
########################
# Permission for using freeze.
freeze: "staff.freeze.freeze"
# Permission for bypassing freeze.
freeze-bypass: "staff.freeze.freeze-bypass"
freeze-chat: "staff.freeze.chat"

########################
# TELEPORT
# GROUP: staff.teleport
########################
# Permission for using teleport.
teleport-to-location: "staff.teleport.teleport-to-location"
# Permission for using teleportToPlayer.
teleport-to-player: "staff.teleport.teleport-to-player"
# Permission for using teleportHere.
teleport-here: "staff.teleport.teleport-here"
# Permission for bypassing teleport.
teleport-bypass: "staff.teleport.teleport.bypass"

########################
# TRACE
# GROUP: staff.trace
########################
# Permission for using trace.
trace: "staff.trace.trace"
# Permission for bypassing being traced.
trace-bypass: "staff.trace.bypass"

########################
# PROTECT
# GROUP: staff.protect
########################
# Permission to toggle protection of a player
protect-player: "staff.protect.protect-player"
# Permission to toggle protection of an area
protect-area: "staff.protect.protect-area"

########################
# BANS
# GROUP: staff.bans
########################
# ban permissions
ban: "staff.bans.ban"
tempban: "staff.bans.tempban"
extendban: "staff.bans.extendban"
reduceban: "staff.bans.reduceban"
ban-silent: "staff.bans.ban-silent"
ban-view: "staff.bans.ban-view"
ban-template-overwrite: "staff.bans.ban-template-overwrite"
unban: "staff.bans.unban"
ban-bypass: "staff.bans.ban-bypass"
ban-notifications: "staff.bans.ban-notifications"
bans:
    migrate: "staff.bans.migrate"
    appeals:
        view: "staff.bans.appeals.view"
        create: "staff.bans.appeals.create"
        create-others: "staff.bans.appeals.create.others"
        approve: "staff.bans.appeals.approve"
        reject: "staff.bans.appeals.reject"
        notifications: "staff.bans.appeals.notifications"

########################
# IP BANS
# GROUP: staff.ipban
########################
ipban:
    ban: "staff.ipban.ban"
    tempban: "staff.ipban.tempban"
    unban: "staff.ipban.unban"
    ban-check: "staff.ipban.ban-check"
    ban-view: "staff.ipban.ban-view"
    ban-silent: "staff.ipban.ban-silent"
    ban-template-overwrite: "staff.ipban.ban-template-overwrite"
    ban-notifications: "staff.ipban.ban-notifications"
    migrate: "staff.ipban.migrate"

########################
# IP
# GROUP: staff.ips
########################
ips:
    clear-ips: "staff.ips.clear-ips"
    notifications: "staff.ips.notifications"

########################
# KICKS
# GROUP: staff.kicks
########################
# Permission to kick players
kick: "staff.kicks.kick"
kick-notifications: "staff.kicks.kick-notifications"
# Permission to bypass being kicked
kick-bypass: "staff.kicks.kick-bypass"

########################
# MUTES
# GROUP: staff.mutes
########################
# Permission to mute players
mute: "staff.mutes.mute"
mute-view: "staff.mutes.mute-view"
tempmute: "staff.mutes.tempmute"
unmute: "staff.mutes.unmute"
extendmute: "staff.mutes.extendmute"
reducemute: "staff.mutes.reducemute"
mute-bypass: "staff.mutes.mute-bypass"
mute-override-softhard: "staff.mutes.mute-override-softhard"
mute-notifications: "staff.mutes.mute-notifications"
view-my-mutes: "staff.mutes.view-my-mutes"
mutes:
    appeals:
        view: "staff.mutes.appeals.view"
        create: "staff.mutes.appeals.create"
        create-others: "staff.mutes.appeals.create.others"
        approve: "staff.mutes.appeals.approve"
        reject: "staff.mutes.appeals.reject"
        notifications: "staff.mutes.appeals.notifications"
########################
# ALT DETECT
# GROUP: staff.altdetects
########################
# Permission to add/remove players from the alt detection whitelist
alt-detect-whitelist: "staff.altdetects.whitelist"
# Permission to run an alt detection check
alt-detect-check: "staff.altdetects.check"
# Permission to bypass the alt detection
alt-detect-bypass: "staff.altdetects.bypass"

########################
# INVENTORY INTERACTION
# GROUP: staff.inventory
########################
# Permission for using the clear inventory config
invClear: "staff.inventory.clearinv"
# Permission for bypassing clear inventory
invClear-bypass: "staff.inventory.clearinv-bypass"
# Permission to have inventory interaction while in examine mode
examine-inventory-interaction.online: "staff.inventory.inventory-interaction"
# Permission to have inventory interaction while in examine mode for offline players
examine-inventory-interaction.offline: "staff.inventory.inventory-interaction-offline"
# Permission to view player's inventory while in examine mode
examine-view-inventory.online: "staff.inventory.view-inventory"
# Permission to view player's inventory while in examine mode for offline player
examine-view-inventory.offline: "staff.inventory.view-inventory-offline"
# Permission to view player's ip in the examine view
examine-view-ip: "staff.examine.view-ip"

########################
# ENDERCHEST
# GROUP: staff.enderchests
########################
# Permissions to view/interact with players enderchests
enderchests:
    view:
        online: "staff.enderchests.view.online"
        offline: "staff.enderchests.view.offline"
    interact: "staff.enderchests.interact"

# Permission to open the players GUI.
players: "staff.players"
########################
# PLAYER GUI VIEW
# GROUP: staff.player-view.detail
# GROUP: staff.player-view.overview
# Below permissions determine what GUI items are shown in the player detail view
########################
playerView:
    detail:
        food: "staff.player-view.detail.food"
        ip: "staff.player-view.detail.ip"
        uuid: "staff.player-view.detail.uuid"
        gamemode: "staff.player-view.detail.gamemode"
        location: "staff.player-view.detail.location"
        timeplayed: "staff.player-view.detail.timeplayed"
        frozen: "staff.player-view.detail.frozen"
        protected: "staff.player-view.detail.protected"
        investigation: "staff.player-view.detail.investigation"
        muted: "staff.player-view.detail.muted"
        vanished: "staff.player-view.detail.vanished"
    overview:
        online-players: "staff.player-view.overview.onlineplayers"
        offline-players: "staff.player-view.overview.offlineplayers"
        staff-members: "staff.player-view.overview.staff"
        miners: "staff.player-view.overview.miners"
        protected: "staff.player-view.overview.protected"

########################
# PLAYER NOTES
# GROUP: staff.player-notes
########################
player-notes:
    view: "staff.player-notes.view"
    create: "staff.player-notes.create"
    create-private: "staff.player-notes.create-private"
    delete: "staff.player-notes.delete"
    delete-other: "staff.player-notes.delete-other"
    notifications: "staff.player-notes.notifications"

########################
# STAFF LOCATIONS
# GROUP: staff.staff-locations
########################
staff-locations:
    view: "staff.staff-locations.view"
    create: "staff.staff-locations.create"
    delete: "staff.staff-locations.delete"
    teleport: "staff.staff-locations.teleport"
    edit: "staff.staff-locations.edit"
    view-notes: "staff.staff-locations.notes.view"
    delete-note: "staff.staff-locations.notes.delete"
    create-note: "staff.staff-locations.notes.create"

webui:
    register: "staff.webui.register"

show-style-info: "staff.show-style-info"
```


# Legacy permissions

{% hint style="info" %}
Below are the permissions that were used in older versions of Staff++. If you have been using Staff++ for a while you will probably have this permissions.yml file. These will keep working. This permission set is also backwards compatible with the old Staff+
{% endhint %}

```yaml
############################################################
# +------------------------------------------------------+ #
# |                     Permissions                      | #
# +------------------------------------------------------+ #
############################################################

# Use this to give a player all Staff+ permissions.
# Take note that this will NOT give the player the "block" permission.
# This also gives the player permission to toggle other player's vanish, staff mode, and etc.
wild-card: "staff.*"

# Permission for blocking listed commands at "blocked-commands" and "blocked-mode-commands".
block: "staff.block"

# Permission for reporting players.
report: "staff.report"
reports:
    # All permission for managing reports
    manage:
        view: "staff.reports.manage.view"
        delete: "staff.reports.manage.delete"
        accept: "staff.reports.manage.accept"
        resolve: "staff.reports.manage.resolve"
        reject: "staff.reports.manage.reject"
        teleport: "staff.reports.manage.teleport"
        reopen-other: "staff.reports.manage.reopen-other"

# Permission for bypassing reports.
report-bypass: "staff.report.bypass"

# Permission for receiving notifications when a report is accepted/deleted/closed
report-update-notifications: "staff.report.update.notifications"

# Permission to open to my reports gui
view-my-reports: "staff.report.view-my-reports"

# Permission to open to my warnings gui
view-my-warnings: "staff.warn.view-my-warnings"

# Permission for using "/warn" and clearing/getting player warnings.
warn: "staff.warn"

# Permission for bypassing warnings.
warn-bypass: "staff.warn.bypass"
warnings:
    notifications: "staff.warnings.notifications"
    # All permission for managing warnings
    manage:
        view: "staff.warnings.manage.view"
        delete: "staff.warnings.manage.delete"
        expire: "staff.warnings.manage.expire"
    appeals:
        create: "staff.warnings.appeals.create"
        create-others: "staff.warnings.appeals.create.others"
        approve: "staff.warnings.appeals.approve"
        reject: "staff.warnings.appeals.reject"
        notifications: "staff.warnings.appeals.notifications"
investigations:
    # All permission for managing investigations
    manage:
        investigate: "staff.investigation.manage.investigate"
        notifications: "staff.investigation.manage.notifications"
        view: "staff.investigation.manage.view"
        link-evidence: "staff.investigation.manage.link-evidence"
        add-note: "staff.investigation.manage.add-note"
        delete-note: "staff.investigation.manage.delete-note"
        delete-note-others: "staff.investigation.manage.delete-note-others"

# Permission for using the vanish command
vanish: "staff.vanish"
see-vanished: "staff.vanish.see-vanished"

# Permission for using "/v total".
vanish-total: "staff.vanish.total"

# Permission for using "/v list".
vanish-list: "staff.vanish.list"
# Permission for using "/v player".
vanish-player: "staff.vanish.player"

# Permission for using "/chat clear".
chat-clear: "staff.chat.clear"

# Permission for using "/chat toggle".
chat-toggle: "staff.chat.toggle"

# Permission for using "/chat slow".
chat-slow: "staff.chat.slow"

# Permission for bypassing the word blacklist.
blacklist: "staff.blacklist"

# Permission for managing tickets.
tickets: "staff.tickets"

# Permission for receiving mention alerts.
mention: "staff.alerts.mention"
# Permission for receiving mention alerts.
mention-bypass: "staff.alerts.mention.bypass"

# Permission for receiving name change alerts.
name-change: "staff.alerts.namechange"
# Permission for bypassing being alerting for name change alerts.
name-change-bypass: "staff.alerts.namechange.bypass"

# Permission for receiving xray alerts.
xray: "staff.alerts.xray"
xray-bypass: "staff.alerts.xray.bypass"

# Permission for toggling staff mode.
mode: "staff.mode"

# Permission for turning on a specific staff mode
mode-specific: "staff.mode.specific"

# permission to interact with chests/hoppers/dispensers.
mode-silent-chest-interaction: "staff.mode.silent-chest-interaction"

# Permission for using the staff mode compass
compass: "staff.compass"

# Permission for using the staff mode random teleport
random-teleport: "staff.random-teleport"

# Permission for the staff mode GUI hub
gui: "staff.gui"

# Permission for the staff mode counter GUI
counter: "staff.counter"

# Permission to show if staff members are vanished in the counter GUI
counter-show-vanished: "staff.counter-show-vanished"

# Permission for using freeze.
freeze: "staff.freeze"

# Permission for bypassing freeze.
freeze-bypass: "staff.freeze.bypass"

# Permission for using teleport.
teleport-to-location: "staff.teleport-to-location"

# Permission for using teleportToPlayer.
teleport-to-player: "staff.teleport-to-player"

# Permission for using teleportHere.
teleport-here: "staff.teleport-here"

# Permission for bypassing teleport.
teleport-bypass: "staff.teleport.bypass"

# Permission for using trace.
trace: "staff.trace"

# Permission for bypassing teleport.
trace-bypass: "staff.trace.bypass"

# Permission for initializing clicks per second tests
cps: "staff.cps"

# Permission for using examine
examine: "staff.examine"

# Permission for using staff mode follow
follow: "staff.follow"

# Permission for locking/unlocking the server.
lockdown: "staff.lockdown"

# Permission for giving a player's previous inventory back.
revive: "staff.revive"

# Permission for being noted as a staff member in the staff list command and for login.
# This also excludes the player from being randomly teleported to!
member: "staff.member"

# Permission for using "/strip".
strip: "staff.strip"

# Permission for use /tp
tp: "staff.tp"

# Permission for using /staffplus
staffplus: "staff.staffplus"

# Use this for players who's ip should not be shown in examine mode
ipPerm: "staff.staffplus.hideip"
ipView: "staff.staffplus.viewip"



# Permission for using the clear inventory config
invClear: "staff.staffplus.clearinv"

# Permission for bypassing clear inventory
invClear-bypass: "staff.staffplus.clearinv-bypass"

# Permission for using the /resetPassword command
resetPass: "staff.staffplus.resetpassword"

# Permission for managing the alerts you will get
alerts: "staff.staffplus.alerts"

# Permission for managing the alerts you will get
broadcast: "staff.staffplus.broadcast"

# Permission to toggle protection of a player
protect-player: "staff.staffplus.protect-player"

# Permission to toggle protection of an area
protect-area: "staff.staffplus.protect-area"

# ban permissions
ban: "staff.staffplus.ban"
tempban: "staff.staffplus.tempban"
extendban: "staff.staffplus.extendban"
reduceban: "staff.staffplus.reduceban"
ban-silent: "staff.staffplus.ban-silent"
ban-view: "staff.staffplus.ban-view"
ban-template-overwrite: "staff.staffplus.ban-template-overwrite"
unban: "staff.staffplus.unban"
ban-bypass: "staff.staffplus.ban-bypass"
ban-notifications: "staff.staffplus.ban-notifications"

ips:
    clear-ips: "staff.ips.clear-ips"
    notifications: "staff.ips.notifications"

ipban:
    ban: "staff.staffplus.ipban.ban"
    tempban: "staff.staffplus.ipban.tempban"
    unban: "staff.staffplus.ipban.unban"
    ban-check: "staff.staffplus.ipban.ban-check"
    ban-view: "staff.staffplus.ipban.ban-view"
    ban-silent: "staff.staffplus.ipban.ban-silent"
    ban-template-overwrite: "staff.staffplus.ipban.ban-template-overwrite"
    ban-notifications: "staff.staffplus.ipban.ban-notifications"

# Permission to kick players
kick: "staff.staffplus.kick"
kick-notifications: "staff.staffplus.kick-notifications"

# Permission to bypass being kicked
kick-bypass: "staff.staffplus.kick-bypass"

# Permission to mute players
mute: "staff.staffplus.mute"
mute-view: "staff.staffplus.mute-view"
tempmute: "staff.staffplus.tempmute"
unmute: "staff.staffplus.unmute"
extendmute: "staff.staffplus.extendmute"
reducemute: "staff.staffplus.reducemute"
mute-bypass: "staff.staffplus.mute-bypass"
mute-override-softhard: "staff.staffplus.mute-override-softhard"
mute-notifications: "staff.staffplus.mute-notifications"

# Permission to add/remove players from the alt detection whitelist
alt-detect-whitelist: "staff.staffplus.alt-detect-whitelist"
# Permission to run an alt detection check
alt-detect-check: "staff.staffplus.alt-detect-check"

# Permission to bypass the alt detection
alt-detect-bypass: "staff.staffplus.alt-detect-bypass"
# Permission for receiving alt detect alerts.
alerts-alt-detect: "staff.alerts.alt-detects"

# Permission for receiving chat word mentions alerts.
alerts-chat-phrase-detection: "staff.alerts.chat-phrase-detection"
# Permission for bypassing chat word mentions alerts.
alerts-chat-phrase-detection-bypass: "staff.alerts.chat-phrase-detection.bypass"

# Permission to have inventory interaction while in examine mode
examine-inventory-interaction.online: "staff.examine.inventory-interaction"
# Permission to have inventory interaction while in examine mode for offline players
examine-inventory-interaction.offline: "staff.examine.inventory-interaction-offline"

# Permission to view player's inventory while in examine mode
examine-view-inventory.online: "staff.examine.view-inventory"
# Permission to view player's inventory while in examine mode for offline player
examine-view-inventory.offline: "staff.examine.view-inventory-offline"

# Permission to open the infractions gui
infractions:
    view: "staff.infractions.view"

# Permissions to view/interact with players enderchests
enderchests:
    view:
        online: "staff.enderchests.view.online"
        offline: "staff.enderchests.view.offline"
    interact: "staff.enderchests.interact"

webui:
    register: "staff.webui.register"


players: "staff.players"
playerView:
    detail:
        food: "staff.player-view.detail.food"
        ip: "staff.player-view.detail.ip"
        uuid: "staff.player-view.detail.uuid"
        gamemode: "staff.player-view.detail.gamemode"
        location: "staff.player-view.detail.location"
        timeplayed: "staff.player-view.detail.timeplayed"
        frozen: "staff.player-view.detail.frozen"
        protected: "staff.player-view.detail.protected"
        investigation: "staff.player-view.detail.investigation"
        muted: "staff.player-view.detail.muted"
        vanished: "staff.player-view.detail.vanished"
    overview:
        online-players: "staff.player-view.overview.onlineplayers"
        offline-players: "staff.player-view.overview.offlineplayers"
        staff-members: "staff.player-view.overview.staff"
        miners: "staff.player-view.overview.miners"
        protected: "staff.player-view.overview.protected"

player-notes:
    view: "staff.player-notes.view"
    create: "staff.player-notes.create"
    create-private: "staff.player-notes.create-private"
    delete: "staff.player-notes.delete"
    delete-other: "staff.player-notes.delete-other"
    notifications: "staff.player-notes.notifications"


show-style-info: "staff.show-style-info"
```


# Alerts

Staff++ kept the same alerting system that was already present in the old Staff+ plugin. Using this system staff members can subscribe to be notified when certain events happen. The notification is done through a message send in-game. If the staff member is not online he will miss the notification.

## Configuration

```yaml
############################################################
# +------------------------------------------------------+ #
# |                        Alerts                        | #
# +------------------------------------------------------+ #
############################################################

# Requires "permissions.notify" permission.
alerts-module:
  # Whether or not staff will be notified when a user changes their name.
  name-notify: true
  name-notify-console: false
  name-notify-bungee: ''

  # Whether or not staff will be notified when they are mentioned.
  mention-notify: true
  mention-notify-console: false
  mention-notify-bungee: ''

  # Whether or not staff will be notified when the chat module detect phrases.
  chat-phrase-detection: true
  chat-phrase-detection-console: false

  # Whether or not staff will be notified when the command-detection gets triggered.
  command-detection: true
  command-detection-console: false

  # Whether or not staff will be notified when the command-detection gets triggered.
  blacklist-detection: true
  blacklist-detection-console: false
  blacklist-notify-bungee: ''

  # The sound that is played to staff when notified.
  sound: ORB_PICKUP

  # Notifies staff when a player mines blocks listed in "blocks".
  xray-alerts:
    # Whether or not this module is enabled.
    enabled: true
    console: false
    notify-bungee: ''
    # Block type that, when mined, will invoke an alert.
    blocks: SPAWNER, EMERALD_ORE, DIAMOND_ORE, GOLD_ORE, IRON_ORE, COAL_ORE, LAPIS_ORE, REDSTONE_ORE

  alt-detect-notify:
      enabled: true
      console: false
      # Trust levels for which an alert should be triggered
      # POSITIVE;FAIRLY_POSITIVE;POSSIBLE;NOT_LIKELY
      trust-levels: FAIRLY_POSITIVE;POSITIVE
```

Enable all the alerts you want to be able to have your staff members receive.

## Subscribing to alerts

A staff member can subscribe to or unsubscribe from these events manually using the `/alerts [type]` command.

Keep in mind a staff member can only receive an alert if he has the correct permission.

```yaml
  # Permission for managing the alerts you will get
  alerts: "staff.staffplus.alerts"
  # Permission for receiving mention alerts.
  mention: "staff.alerts.mention"
  # Permission for receiving name change alerts.
  name-change: "staff.alerts.namechange"
  # Permission for receiving xray alerts.
  xray: "staff.alerts.xray"
  # Permission for receiving alt detect alerts.
  alerts-alt-detect: "staff.alerts.alt-detects"
```

### Bypassing triggering alerts

View the bypass permissions on the [permissions](/permissions-and-commands/permissions) page

### Sending over bungee.

Some alerts can be send over the bungee network. For example:

```
blacklist-notify-bungee: '[ALL]'
```

You either provided a `;` separate list of server names. Or `[ALL]` if you want to send the alerts to all server in the network.

### Example

(Un)Subscribe yourself to alt account detection alerts

```
/alerts ALT_DETECT
```


# X-Ray

The x-ray is used to notify staff members when players mine a certain block. The alerts can be configured to run after a specific threshold has been reached.

```yaml
xray-alerts:
    # Whether or not this module is enabled.
    enabled: true

    # Block type that, when mined, will invoke an alert.
    blocks: SPAWNER, EMERALD_ORE:10, DIAMOND_ORE:10:1m, GOLD_ORE, IRON_ORE, COAL_ORE, LAPIS_ORE, REDSTONE_ORE
```

Blocks can be configured in three different ways.

#### Trigger every time \[blocktype]

Example: `SPAWNER` \
The above configuration will trigger an alert every time a player mines a spawner.

#### Trigger after amount \[blocktype:amount]

Example: `EMERALD_ORE:10` \
The above configuration will trigger an alert every time a player mines a total of 10 emeralds.

#### Trigger after amount/time \[blocktype:amount:time]

Example: `DIAMOND_ORE:10:1m` \
The above configuration will trigger an alert whenever a player mines 10 diamond block within the time span of 1 minute.

**Possible time values:**

* s = second
* m = minute
* h = hour
* d = day
* w = week
* M = month
* y = year

*Time values cannot be combined. For example this is invalid: "1m30s" instead type "90s"*


# Alt account detection

Staff++ provides a way to be notified when it thinks a user is using alternative accounts. The detection is really simple so don't expect miracles. It will detect the most basic and obvious alt accounts. Alt detection is disabled by default

## Configuration

```yaml
alt-detect-module:
  enabled: true
  # will not send out any notification unless at least the IPs are matching
  same-ip-required: false
```

## How it works

### Ip similarity

When enabled the system will start recording players IP addresses. Every address a player ever connects with gets stored. If a player connects with the same address as another player his detection score is upped by 1.

### Username similarity

When a player connects we check his username against all other users known to the server. Similarity is calculated using the Levenshtein Distance Algorithm. Based on this a score is returned:

* 70% similarity --> score 3
* 50% similarity --> score 2
* 30% similarity --> score 1

### Detection trust levels (score)

The trust level is the result of the above mentioned checks. We have four levels of trust:

| Trust Level      | score | Description                                                                                                                                                                                               |
| ---------------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| POSITIVE         | 5     | Only one case can trigger the POSITIVE level. When a username has an IP match and a username match of at least 70%. We can be fairly certain something is going on with these accounts                    |
| FAIRLY\_POSITIVE | 4     | Triggered when username match is between 50% and 70% and IP is matching. Or when username match is at least 70% and IP is not matching.                                                                   |
| POSSIBLE         | 3     | Triggered when username match is between 30% and 50% and IP is matching. Or when username match is between 50% and 70%, and IP is not matching.                                                           |
| NOT\_LIKELY      | 2     | Triggered when username match is between 30% and 50% and IP is not matching. In general I would not recommend listening to alerts with this trust level as most likely this will not be a reliable result |
| SAME\_IP         | 1     | Triggered when IP is matching but there is no username similarity.                                                                                                                                        |

{% hint style="warning" %}
If the option `same-ip-required` is set, no level is triggered unless the ip is matching as well
{% endhint %}

## Listening to events

Currently Staff++ supports 2 ways of being notified when an alt account is detected.

* The [alerting system](/features/alerts) (in-game)
* Through Discord ([Integration plugin](https://github.com/garagepoort/StaffPlusPlus/wiki/Discord-Integration))

## Whitelisting Accounts

Since some accounts might actually not be real alt accounts but still trigger the system, a whitelist is added to ensure that staff members can ignore these false positives.

The ignore a match you can use the `/altwhitelist` command.

* `/altwhitelist add playerName1 playerName2`
* `/altwhitelist remove playerName1 playerName2`
* `/altwhitelist list pagenumber` PageNumber is optional.

This will add or remove certain user combinations from the whitelist. When added to the whitelist this users combination will never trigger a detection event. Adding a combination to the whitelist tells the system that these 2 accounts are not alts.


# Authentication

Staff++ does not have an internal authentication system.

The main reason for this decision is that there are other better plugins out there to support authentication. We do however cover the following scenarios:

### Online server mode + permissions.

In this case the official Minecraft authentication system is used. This system in combination with the correct permission setup allows for a secure authentication mechanism.

### Offline server mode + AuthMe Authentication. Everyone needs to login.

When we use AuthMe we can enforce all players to login. Using this system every player has to login before being able to execute commands. Using this + permissions is enough to block other users from using the commands.

### Offline server mode + AuthMe Authentication. Only Staff needs to log in.

AuthMe can be configured to have optional registration. Players can choose if they want to register or not. However this allows any player who joins with the same name as a staff member to have the staff member's permissions. To prevent any player to execute the Staff++ commands we have integrated the AuthMe plugin. Configure the authentication provider inside the Staff++ config to "authme". This will make sure any player who tries to execute a Staff++ command must be logged in and have the correct permissions. In other words we enforce authentication before you can use Staff++ commands even if AuthMe registration is optional.

## Configuration

Inside the configuration file make sure the following section is present:

```yaml
# Chooses the authentication provider. Default "noop", no authentication will be done.
# AuthMe is supported. When the provider is authMe, Staff++ will enforce that the user is authenticated through AuthMe before being able to execute the commands.
authentication:
    provider: authme
```

The provider must be configured to `authme`. If `noop` is configured no authentication check will be done by StaffPlusPlus. Permissions are off-course still validated

#### Authme Plugin <https://github.com/AuthMe/AuthMeReloaded>


# Banning

Staff++ overrides the default ban command with its own `ban` command. Next to the permanent ban command it also adds the `tempban` command. With every ban a reason must be given why this player is getting banned.

## Configuration

```yaml
ban-module:
    # Whether or not the plugin will use "/ban-player" features.
    enabled: true
    permban-template: ''
    tempban-template: ''
    # List of staff ranks. Ordered from low to highest rank.
    # when configured, staff members can only ban player with a lower rank.
    ranks: []
    appeals:
        enabled: true
        unban-on-approve: true
        resolve-reason-enabled: false
        fixed-reason: false
        reasons:
            - ''
```

### Commands

| Command                                        | Description                                            |
| ---------------------------------------------- | ------------------------------------------------------ |
| /ban \[player] \[reason]                       | Permanently ban a player                               |
| /tempban \[player] \[amount] \[unit] \[reason] | Temporary ban a player the given duration              |
| /ban-extend \[player] \[amount] \[unit]        | Extend the ban duration of a temporarily banned player |
| /ban-reduce \[player] \[amount] \[unit]        | Reduce the ban duration of a temporarily banned player |
| /unban \[player] \[reason]                     | Unban a player from the server                         |
| /manage-bans                                   | Opens the bans overview GUI                            |

### Permanent banning

`/ban [player] [reason]`

```
/ban playername He was bothering me
```

### Temporary banning

`/tempban [player] [amount] [unit] [reason]`

```
/tempban playername 15 MINUTE He was bothering me
```

The duration of the tempban is specified by \[amount] \[unit]

Amount must be a positive number > 0 and unit must be one of the following:

* SECOND
* MINUTE
* HOUR
* DAY
* WEEK
* MONTH
* YEAR

#### Restricting tempban duration

The tempban command can also be configured to restrict the duration a staff member can use for a ban.\
Give the staff member and extra permission with a duration limit as suffix. Example: `staff.bans.tempban.limit.2w` , with this permission a staff member can only issue a ban for a maximum duration of 2 weeks.

{% hint style="warning" %}
A staff member must have both permissions to use the command. So for a 2 week duration limit the permissions needed are:

* `staff.bans.tempban`
* `staff.bans.tempban.limit.2w`
  {% endhint %}

**Possible time values:**

* s = second
* m = minute
* h = hour
* d = day
* w = week
* M = month
* y = year

*Time values cannot be combined. For example this is invalid: ".1m30s" instead type ".90s"*

### Extending/reducing ban duration

A ban duration can be extended or reduced by the following commands:&#x20;

`/ban-reduce [player] [amount] [unit]`\
`/ban-extend [player] [amount] [unit]`\
\
This command can also be limited in duration the same way a tempban is limited.\
Giving the player the following 2 permissions will limit the extension duration for example:

* staff.`bans`.extendban
* staff.`bans`.extendban.limit.2w

{% hint style="warning" %}
When extending a ban, the staff member cannot extend the ban further than his tempban limit will allow. This is to prevent a staff member spamming an extend command.\
This means that if a player is banned for 2 months. His ban cannot be extended by a staff member whose tempban limit is 3 weeks for example.
{% endhint %}

### Unbanning

`/unban [player] [reason]`

```
/unban playername We are friends now
```

### Silent banning

The `-silent` can be used to ban/tempban/unban players without sending out a notification to anyone.

```
/ban playername -silent He was bothering me
```

## Showing ban reason on ban/rejoin

If you want banned players can see the reason why they are banned you can edit the kick message in the lang files:

```yaml
ban-tempbanned-kick: "[Banned] You have been temporarily banned from this server. Ban ends in: %duration%"
ban-permabanned-kick: "[Banned] You have been permanently banned from this server"
```

#### placeholders

Inside the message the following placeholders can be used

| placeholder | description                                           |
| ----------- | ----------------------------------------------------- |
| %target%    | The banned player's username                          |
| %issuer%    | The staff members username                            |
| %reason%    | The ban reason                                        |
| %duration%  | Human readable duration. Only available with tempbans |


# IP Banning

Staff++ added a simple ip banning system to ensure players with certain ip addresses cannot join the server.

{% hint style="warning" %}
NOTE: An IP ban is not player based! Banning an IP will most probably impact more than one player. If you want to block a specific player by username use the normal banning of staff++.\
\
If you still want to proceed with banning a player based on his IP, realize you might impact other players as well.

Luckily staff++ will always warn you what players will be impacted when banning unbanning an IP.
{% endhint %}

### Configuration

```yaml
ban-module:
  # Whether or not the plugin will use "/ban-player" features.
  enabled: true
  permban-template: ''
  tempban-template: ''
  ipban:
      enabled: true
      # Type of confirmation when banning an IP
      # Possible values: CHAT | GUI | DISABLED
      confirmation: CHAT
      permban-template: ''
      tempban-template: ''
```

### Permissions

View [permissions](/permissions-and-commands/permissions) page

### Commands

| Command                                                    | Description                                             |
| ---------------------------------------------------------- | ------------------------------------------------------- |
| /ipban \[player/ip-address/cidr]                           | Add an ip ban based on a player, ip or cidr             |
| /iptempban \[player/ip-address/cidr] \[amount] \[timeunit] | Temporarily add an ip ban based on a player, ip or cidr |
| /ipunban \[player/ip-address/cidr]                         | Remove a ban based on a player, ip or cidr              |
| /ipban-check \[playername]                                 | Check if the given player's ip is banned                |
| /ipbans \[-players]                                        | List all active IP-bans or list all banned players      |

## Examples

### Permanent banning

`/ipban [player/ip-address/cidr]`

```
# By playername 
/ipban player1

# By specific IP
/ipban 20.15.62.15

# By CIDR
/ipban 20.15.62.0/24
```

Ip banning will always ask for a confirmation when executed from in game. An ip ban can impact multiple players. Staff++ will check the last known IP of on- and offline players and list players the will be impacted. Of course there is no 100% certainty other players might not be impacted. But at least this gives an indication.

![](/files/-MdxzgGXTvW_k-ZNFS4B)

### Temporary banning

`/tempban [player/ip-address/cidr] [amount] [unit]`

```
# By playername 
/iptempban player1 15 MINUTE

# By specific IP
/iptempban 20.15.62.15 15 MINUTE

# By CIDR
/iptempban 20.15.62.0/24 15 MINUTE
```

The duration of the tempban is specified by \[amount] \[unit]

Amount must be a positive number > 0 and unit must be one of the following:

* SECOND
* MINUTE
* HOUR
* DAY
* WEEK
* MONTH
* YEAR

### Unbanning

`/ipunban [player]`

```
# By playername 
/ipunban player1

# By specific IP
/ipunban 20.15.62.15

# By CIDR
/ipunban 20.15.62.0/24
```

### Silent banning

The `-silent` can be used to ban/tempban/unban ips without sending out a notification to anyone.

```
/ipban playername -silent
```


# Messages

Following messages are available for the ip banning system in the lang files:

| message            | Description                                                                                                 | placeholders                           |
| ------------------ | ----------------------------------------------------------------------------------------------------------- | -------------------------------------- |
| ipbans.prefix      | Prefix for every ip ban message in chat                                                                     |                                        |
| ipbans.permabanned | The message send to all players that can receive ipban notifications when a permanent ip ban has been added | %issuer%, %ip%                         |
| ipbans.tempbanned  | The message send to all players that can receive ipban notifications when a temporary ip ban has been added | <p>%issuer%, %ip%</p><p>%duration%</p> |
| ipbans.unbanned    | The message send to all players that can receive ipban notifications when an ip ban has been removed        | %issuer%, %ip%                         |
| permabanned-kick   | The message a player sees when he gets kicked from the server as a result from a permanent ip ban           | %issuer%, %ip%                         |
| tempbanned-kick    | The message a player sees when he gets kicked from the server as a result from a temporary ip ban           | <p>%issuer%, %ip%</p><p>%duration%</p> |


# Fixed Ban Reason

You can configure custom ban reasons. This will enforce the staff members to use your reasons.

{% hint style="info" %}
The entire **reasons** section is optional and **not** present in the default config
{% endhint %}

### Configuration

```yaml
ban-module:
  enabled: true
  permban-template: default
  tempban-template: default
  reasons: 
    - name: GRIEFING
      reason: No griefing allowed on this server
    - name: BULLYING
      reason: bullying will not be tolerated
      template: bullying
    - name: CURSING
      reason: Consistent cursing. Temporarily banned.
      template: cursing
      ban-type: TEMP_BAN
```

In the above config we have defined 3 ban reasons. GRIEFING, BULLYING and CURSING.\
\
Every reason configuration must have at least a `name` and a `reason` . Optionally you can also define a `template` . When you define a template you overwrite any other configured template. However staff members can still [provide a template in their command](/features/banning/templates#overwriting-the-default-template).&#x20;

By default ban reasons are applicable to both permanent and temporary ban. You can however define another optional configuration option`ban-type` . The ban type can be configured with **TEMP\_BAN** or  **PERM\_BAN.** When the type is configured, this ban reason will only apply for these types of bans. \
\
If no ban reasons are configured, the staff members can provide a custom reason. As soon as at least one ban reason is configured they are obligated to use ban reasons and can no longer fill in a custom message


# Templates

You can use txt files to describe the logout message a player will see when he gets banned.\
By default this entire functionality is disabled. To enable templates do the following.

### Setup

Inside the Staff++ plugin directory create a **bans** directory if it does not already exists.\
\
Inside this bans directory you can create the template files. A template file is a simple text file containing the message that will displayed to the user on ban. Example file:

{% file src="/files/-MW6p7-bk759j2hyKOEZ" %}
bans/default.txt
{% endfile %}

I named the above file **default.txt.** The file name without extension will be used as **template name**.<br>

This will result in the following:

![](/files/-MW6q6iGCsvw71M8Nu1u)

My example is not that pretty but it illustrates the usage.<br>

#### placeholders

Inside the template the following placeholders can be used

| placeholder | description                                           |
| ----------- | ----------------------------------------------------- |
| %target%    | The banned player's username                          |
| %issuer%    | The staff members username                            |
| %reason%    | The ban reason                                        |
| %duration%  | Human readable duration. Only available with tempbans |

### Configuration

```yaml
ban-module:
  enabled: true
  permban-template: default
  tempban-template: default
```

Inside the **config.yml** file you can fill in a default template for permanent and temporary ban. Or leave it empty to fall back on the message defined in the lang file.

### Overwriting the default template

If staff members have the permission: `staff.bans.ban-template-overwrite` they can use an extra parameter **"-template="** when banning a player.\
Example:\
`/ban thisplayer -template=other I ban you!`

This will overwrite the default configured template and try to find and use a template with the given name. If the template does not exist an error will be shown.


# Blacklist

The blacklist module allows you to censor certain words/phrases in chat/books/item/signs names

### Config.yml

```yaml
############################################################
# +------------------------------------------------------+ #
# |                    Blacklist                         | #
# +------------------------------------------------------+ #
############################################################
# All word blacklist options.
# Leave any of the lists below blank to disable them!
blacklist-module:
    # Whether or not the blacklist will be enabled.
    enabled: false

    censor-chat: true
    censor-signs: true
    censor-anvil: true
    censor-book: true
    # Whether or not messages that have censored words in them will be hoverable.
    # This means you will be able to hover over a chat message to see an uncensored message if you have the "permissions.blacklist" permission.
    # This may not work well with other chat plugins!
    hoverable: false

    # The character that will replace blocked word characters.
    character: "*"

    # Whether or not messages that have merged blocked words will be detected.
    # So if you block the word "ass", it will also block "asshole" or "dickass".
    # May cause issues with legal words like "bypass"! Fix is below.
    merging: true

    # All words that will be censored.
    # Separate words with commas.
    words: fuck, shit, ass, bitch, dick, cock, piss, cunt, fag, faggot, slut, nigger, nigga

    # All characters that will be censored.
    # These are merely characters that will be detected anywhere in messages.
    characters: 卐, 卍

    # All domain levels that will be censored.
    # This can prevent users from sending links in chat.
    # This will only check the end of words which have detected periods!
    domains: com, net, org

    # All strings that will be detected as periods in messages. Of course characters like "." and "," are detected by default.
    # This will work in coordination with "domains".
    # For example, it can detect "mineplex()com" as "mineplex.com".
    periods: (), (dot),

    # All words that will be allowed to be typed no matter what.
    # This helps quite a bit if you have "merging" enabled.
    # I recommend using http://www.morewords.com/contains/[word]/!
    allowed: bypass, assembly, assassin, compass, assume, assault, asset, assort

```


# Broadcasting

Staff++ added a "broadcast" command. This allows a staff member to send a message across the server. If you are in a bungee network the message will be send to all servers or only to the ones specified in the config.

## Configuration

Make sure the following section is present in your config file:

```yaml
############################################################
# +------------------------------------------------------+ #
# |                      Broadcast                       | #
# +------------------------------------------------------+ #
############################################################

# Requires "permissions.broadcast" permission.
broadcast-module:
  # Whether or not the plugin will use "/broadcast" features.
  enabled: true
  # The servers to which the broadcasting is applied "CURRENT" is the default value and broadcasts only on the current server.
  # This also prevents staff members from broadcasting to other servers
  # "ALL" broadcasts to all known servers on the network.
  # Alternatively you can provide a list of semicolon separated server names to which the broadcasting should be applied.
  # Example: lobby;survival;skyblock
  enabled-servers: CURRENT
```

The enabled-servers option allows us to restrict the receiving servers.

* CURRENT: only the current server is allowed to receive message. Use this when you are not on a bungee network
* ALL: The message will be send to all servers on the network.
* LIST: The message will only be send to the servers in the list


# Chat module

### Introduction

The chat module allows you to manage certain chat functionalities. Most of these are still the old Staff+ ones.&#x20;

### Configuration

```yaml
############################################################
# +------------------------------------------------------+ #
# |                    Staff Chat                        | #
# +------------------------------------------------------+ #
############################################################

# Requires "permissions.staff-chat" permission.
staff-chat-module:
    # Whether or not the plugin will use "/sc" features.
    enabled: true
    # Whether or not the plugin synchronises staff chat across the bungee network
    bungee: true

    # The string that can be used at the beginning of a message to make it appear in staff chat.
    # If you have "@" as your string, typing "@hey guys" would send "hey guys" to staff chat.
    # Leave blank to disable.

    channels:
        -   command: sc
            handle: "@"
            name: staffchat
            prefix: '&dStaffChat &8»'
            message-format: '&b%player% &8» &7%message%'
            permission: staff.staffchat
            sound: "NONE"
```

### Phrase detection actions

You can execute actions whenever certain phrases are detected

```yaml
  detection:
    phrase-groups:
      - phrases:
            - admin
            - mod
        actions: []
```

Commands listed here should be in the [Staff ++ command format](/general-information/other/configuring-commands)

#### Placeholders

<table><thead><tr><th width="265.0007983677815">placeholder</th><th>description</th></tr></thead><tbody><tr><td>%player%</td><td>The name of the player that triggered the phrase detection</td></tr><tr><td>%phrases%</td><td>The configured phrases that were detected</td></tr></tbody></table>

#### Targets

<table><thead><tr><th width="353">target value</th><th>description</th></tr></thead><tbody><tr><td>player</td><td>The player that triggered the phrase detection</td></tr></tbody></table>

#### Executors <a href="#undefined" id="undefined"></a>

<table><thead><tr><th width="351.47558770343585">executor value</th><th>description</th></tr></thead><tbody><tr><td>player</td><td>The player that triggered the phrase detection</td></tr></tbody></table>


# Chest/Inventory Interaction

In Staff++ a staff member can interact with other player's EnderChest or inventory.\
On this page we explain the different types of interaction and how to enable them.

## Silent Chest Interaction

When in Staff mode, the player can open chest/dispenser/hoppers,.... by right clicking on them.\
This is called "silent chest opening". When a player opens this he may or may not be able to interact with the item in the container depending on his permissions.

If you want to enable interacting with chests when opening them in "silent" mode enable the following property in the config. If this is disabled no staff members can interact in silent mode.&#x20;

```yaml
staff-mode:
    silent-chest-interaction: true
```

### Permission

Only staff members with the permission `staff.mode.silent-chest-interaction` can interact with containers in silent mode.

## Enderchest Interaction

Staff++ has a command called `/eview <playername>` . This command has been there since the old Staff+. However it was never able to interact with another player's enderchest. In Staff++ we added the ability to open and interact with enderchests of online and offline players.

### Configuration

Make sure to enable the module.

```yaml
enderchest-module:
    enabled: true
```

### Permissions

| Permission                      | Description                                              |
| ------------------------------- | -------------------------------------------------------- |
| staff.enderchests.view\.online  | Permission to view the enderchest of online players      |
| staff.enderchests.view\.offline | Permission to view the enderchest of offline player      |
| staff.enderchests.interact      | Permission to interact with enderchests of other players |

## Inventory Interaction

Staff members can access another player's inventory using the `/examine` command.\
You can view and interact with the inventory of online and offline players.

When opening the examine GUI you will see a chest is available:

![](/files/-MRbSF7TwTqTjD7kRAHW)

Clicking on this chest opens the interaction screen

![Inventory Interaction](/files/-MRbVzO5rOnhRIFNEzv0)

The **blue** outlined items are the hotbar items of the player's inventory.\
The **red** outlined items are the armor contents of the player.\
\
The examined player's inventory looks like this:

![](/files/-MRbWJ7VPvqfelLMSAGv)

### Permissions

View the [permissions](/permissions-and-commands/permissions) page<br>


# Command detection

A small module that can detect players executing certain commands.

### Configuration

```yaml
command-detection:
    enabled: true
    command-groups:
        - commands:
            - op
            - deop
            - lp
          actions: []
```

We can group certain commands and link actions to them.

### Actions

You can link actions whenever a player tries to execute a command inside the configured command-group.

Actions listed here should be in the [Staff ++ command format](/general-information/other/configuring-commands)

#### Placeholders:

| Placeholder value | Description                                            |
| ----------------- | ------------------------------------------------------ |
| %player%          | The playername of the player that executed the command |
| %command%         | The exact command the player tried to execute          |

#### Targets/Executors

|        |                                              |
| ------ | -------------------------------------------- |
| player | The player that tried to execute the command |

### Alerts

In addition players can also be notified about the commands being executing through the [alerts module](/features/alerts).

```yaml
alerts-module:

  # Whether or not staff will be notified when the command-detection gets triggered.
  command-detection: true
  command-detection-console: false
```


# Examine players

The examine command allows Staff members to open a GUI containing the specified player's information.<br>

## Configuration

The current configuration section is part of the `staff-mode` section. This will probably change in the future as the examine mode can also be accessed through commands and thus is not mode specific.\
\
Now the configuration of the examine mode and staff-mode GUI kind of overlap

```yaml
 staff-mode:
  # When clicked, this will open the inventory of the player that the staff is looking at.
  examine-module:
    enabled: true
    slot: 8
    item: CHEST

    # The name of the compass item.
    name: "&bExamine"

    # The lore of the compass item.
    # Lines are separated by commas.
    lore: "&7Inspects the inventory of the player that was clicked."

    # The title of the examine GUI.
    title: "&bExamine inventory"

    # The configuration of the final line of the examine GUI.
    # Set the slot of a node to zero to disable it.
    # Remember that the maximum amount of allowed items within this line is nine!
    info-line:
      # Food and hunger information.
      food: 1

      # IP address information.
      ip-address: 2

      # Ping information.
      # Currently not working
      ping: 3

      # Gamemode and flight information.
      gamemode: 4

      # Infractions information.
      infractions: 5

      # Location information and teleport button.
      location: 6

      # Player "notes" button.
      notes: 7

      # Freeze button
      freeze: 8

      # Warn button.
      warn: 9
```

## Permissions

View [permissions](/permissions-and-commands/permissions) page


# Freezing

### commands

| Command           | Description              |
| ----------------- | ------------------------ |
| /freeze \<player> | Toggle freezing a player |

### Permissions

View [permissions](/permissions-and-commands/permissions) page

### Config

```yaml
freeze-module:
    # Enable this module
    enabled: true
    chatchannels:
      enabled: false
    # Whether or not a player can chat while frozen.
    chat: true
  
    # Whether or not a player is able to damage or be damaged while frozen.
    damage: false
  
    # The interval, in seconds, at which a frozen player will be reminded that they are frozen.
    # Disable by setting to zero.
    timer: 5
  
    # The sound that is played to the player when warned.
    # Set to "NONE" to disable.
    sound: ORB_PICKUP
  
    # Whether or not a GUI prompt will open up with a paper containing the freeze message.
    prompt: false
  
    # The title of the frozen prompt GUI.
    prompt-title: "&bFrozen"
    
    # A comma separated list of commands that should be 
    # executed when a players disconnected while he is frozen
    logout-commands: "ban %player%"
    
    # Determines if a player will see a title on his screen when frozen
    # The title message can be changed through the lang files (freeze-title, freeze-subtitle properties)
    title-message-enabled: true
    
    # Commands that are allowed when a player is frozen
    # By default a player can not execute any command while frozen
    allowed-commands: 
      - login
      - tpa
      
    # command hooks for freeze/unfreeze
    freeze-commands: []
    unfreeze-commands: []
```


# Command hooks

You can execute commands upon certain lifecycle changes of an investigation:

```yaml
freeze-module:
    # command hooks for freeze/unfreeze
    freeze-commands: []
    unfreeze-commands: []
```

Commands listed here should be in the [Staff ++ command format](/general-information/other/configuring-commands)

### Placeholders:

<table data-header-hidden><thead><tr><th width="265.0007983677815">placeholder</th><th>description</th></tr></thead><tbody><tr><td>placeholder</td><td>description</td></tr><tr><td>%issuer%</td><td>The name of the player executing the freeze</td></tr><tr><td>%target%</td><td>The name of the player that is getting frozen</td></tr></tbody></table>


# Luckperms integration

When a player gets frozen and you have the LuckPerms plugin installed. A frozen context will be added to that player. This allows you to configure LuckPerms permissions that will only be applied when a player is frozen.

The exact context is: &#x20;

* **key**: `staff++:frozen`&#x20;
* **value**: `true`


# Chat channels

Staff++ has the possibility to open chat channels when a player gets frozen

### Configuration

```yaml
freeze-module:
  chatchannels:
      enabled: true
```

With the above configured, when a player gets frozen a channel will be automatically opened.\
If the player gets unfrozen, the channel is closed. When the channel is opened, the player frozen and the staff member who has frozen automatically are added to the channel.

### Permissions

```yaml
chatchannels:
    join: "staff.chatchannels.join.freeze"
    leave: "staff.chatchannels.leave.freeze"
    open: "staff.chatchannels.open.freeze"
    close: "staff.chatchannels.close.freeze"
```

### Commands

| description                 | Description                                                                                                            |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| /fc \<channelid> \<message> | Send a message to a freeze channel                                                                                     |
| /fc \<message>              | If you are frozen you can use the /fc command without the freezechannel id                                             |
| /join-channel \<channelId>  | Join this chatchannel. You will see the messages send on this channel and will be able to send message to this channel |
| /leave-channel \<channelId> | Leave the chat channel                                                                                                 |
| /close-channel \<channelId> | The chat channel will be closed. This forces all players to leave the channel and the channel gets deleted             |


# Infractions

Staff++ provides a command to show all infractions a player has. This gives you a nice history off the player actions and punishments in time. The infractions are ordered by date. Latest infractions are shown first.\
Currently infractions include: bans, mutes, warnings, kicks and it also shows an infraction when a player is reported by another player.

## Configuration

```yaml
infractions-module:
  # Whether or not the plugin will enable the infractions gui.
  enabled: true
  show-bans: true
  show-mutes: true
  show-warnings: true
  show-reported: true
  show-kicks: true
  # Configure the material which is shown inside the GUI 
  # for every type of infraction
  bans-gui-item: PAPER
  mutes-gui-item: PAPER
  warnings-gui-item: PAPER
  reported-gui-item: PAPER
  kicks-gui-item: PAPER
```

You can choose which infractions will be shown in the overview.

### Permissions

| Permission             | Description                            |
| ---------------------- | -------------------------------------- |
| staff.infractions.view | Permission to open the infraction guis |

### Commands

| Command                     | Description                                                                                                                                                                                                    |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/infractions <playername>` | Opens the infractions gui displaying all infractions of the given player                                                                                                                                       |
| `/infractions-top <type?>`  | Open the overview of players and their amount of infractions. Ordered by most to least infractions. The type parameter is optional. When given only the top of that specific type of infraction will be shown. |

### <br>

#### Player Infraction GUI

![](/files/-MSL12GzqebmtQ4K9U1h)

#### Top infraction GUI

![](/files/-MSL0q16y2pElley0tJX)


# Investigate

Staff++ added an investigation module. You can start investigating players, takes notes and link evidence to the investigation. Once finished the investigation must be concluded.

## Configuration

```yaml
investigations-module:
    enabled: true
    allow-offline-investigation: false
    # How many investigations can be conducted on one player at a time.
    # By default only one investigation can be ongoing for one player
    max-concurrent-investigations: 1
    # When enabled investigations will automatically be paused 
    # when the player under investigation leaves the server.
    automatic-pause: true
    notifications:
        investigated:
            # Player under investigation has a constant message in his action bar. 
            title-message-enabled: true
            # Player under investigation has a constant message in his action bar.
            chat-message-enabled: true
    # Run commands whenever an investigation open/pauses/isConcluded        
    start-investigation-commands: []
    conclude-investigation-commands: []
    pause-investigation-commands: []
    # When set to true, staff mode will be enabled when starting an investigation.
    # When disabling staff mode during an investigation, your investigation will be paused.
    enforce-staff-mode: true
    # Optional property, if set, enforce a specific staff mode during investigations.
    staff-mode: Investigator
```

## Commands

| command                               | description                                                                                                       |
| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| /investigate \<player?>               | Open/resume an investigation. If no player name is given you will start an investigation with an "Unknown" player |
| /pause-investigation                  | Pause your currently ongoing investigation                                                                        |
| /conclude-investigation               | Conclude your investigation. This closes the investigation                                                        |
| /manage-investigations \<playername?> | Opens up the overview of all investigations or all investigation for a player if the playername is provided       |
| /inote \<notemessage>                 | Add a note to your current investigation                                                                          |

## Permissions

| permission                                    | Description                                       |
| --------------------------------------------- | ------------------------------------------------- |
| staff.investigation.manage.investigate        | allows the use of /investigate                    |
| staff.investigation.manage.notifications      | Get all staff notifications for investigations    |
| staff.investigation.manage.view               | Allow viewing all investigations                  |
| staff.investigation.manage.link-evidence      | Allow linking evidence to investigations          |
| staff.investigation.manage.add-note           | Allow adding notes to investigations              |
| staff.investigation.manage.delete-note        | Allow deleting your own notes from investigations |
| staff.investigation.manage.delete-note-others | Allow deleting any note from investigations       |

## Manage investigation

Staff members can view an overview of all investigations.

![Investigations](/files/-MXZeVSqhu-RLiTnKp02)

![Player under investigation](/files/-MXZldJTZWAEbulipIuk)

## Linking evidence

Staff++ allows you to link certain infractions to an investigation.

Currently following infractions can be linked to investigations:

* Reports
* Mutes
* Bans
* Warnings

Developers can also link any other kind of evidence using the [Developer API](/developers/api-guide)

![Link report as evidence](/files/-MXZc6hyBOZQx41Xnidf)

![Confirmation evidence linked](/files/-MXZcNaJWCC-u5KqlsbM)

![Investigation manage screen](/files/-MXZcdAmDtm94AdSu3P3)

![Evidence overview](/files/-MXZcn77BaDDjSZDbOJW)

## Taking notes

Players can add notes to an investigation.

![Go to notes](/files/-MXZe1wvEqhA98QfF9pO)

![Notes overview](/files/-MXZe6XYpjxw9K8Z0Hrc)


# Command hooks


# Join messages

Staff++ provides the ability to configure join messages. A join message replace the regular vanilla join message that is broadcasted

### Configuration

```yaml
joinmessages-module:
  enabled: true
  messages:
      - permission: 'staff.joinmessages.staff'
        message: '&6[Staff] &4%player% &7joined the server'
        weight: 1
```

You can configure different messages based on the permission a player has.\
The weight determines which message get's priority should a player have multiple join messages permissions. A higher weight will get priority.


# Player IPs

Staff++ tracks player ips for ip banning and alt detection.\
If at any point you want to delete the ip history for a player you can use below command.

### Command

| Command              | Description                                  |
| -------------------- | -------------------------------------------- |
| /clear-ips \[player] | Clears all tracked ips for the given player. |

### Permissions

| Permission              | Description                                                                                |
| ----------------------- | ------------------------------------------------------------------------------------------ |
| staff.ips.clear-ips     | Permission to use the /clear-ips command                                                   |
| staff.ips.notifications | Permission to receive staff notification when a staff member clears a player's ip history. |


# Kicking

Staff++ adds its own kick command. When used, a history of the kicks will be preserved. Kicks also will be shown in the [infractions](/features/infractions) menu.

### Permissions

View [permissions](/permissions-and-commands/permissions) page

### Commands

| Command                    | Description                                            |
| -------------------------- | ------------------------------------------------------ |
| /kick \[player] \[reason?] | Kicks a player from the server. With specified reason. |

### Config

```yaml
kick-module:
  # Whether or not the plugin will use "/kick" features.
  enabled: false
  # If set to true, staff members will no longer have the ability 
  # to specify a custom reason
  fixed-reason: false
  # Possible kick reasons, when defined the staff member will see
  # a reason selection GUI
  reasons: []
```

### Examples

#### Kick with custom reason&#x20;

```yaml
/kick myplayer He was spamming
```

#### Kick with reason select:

```
/kick myplayer
```

```yaml
kick-module:
  enabled: true
  fixed-reason: false
  reasons:
  - reason: ANNOYING
    material: PAPER
    info: he is ANNOYING
  - reason: SPAM
    material: PAPER
    info: Use when a player is spamming
```

![](/files/-MchnHIwpyrDNv8VG1Lm)

#### Kick with default reason

```
/kick myplayer
```

```yaml
kick-module:
  enabled: true
  fixed-reason: false
  reasons:
  - reason: SPAM
    material: PAPER
    info: Use when a player is spamming
```

{% hint style="info" %}
No reason selection is shown because only one reason is available.
{% endhint %}


# Muting

Staff++ adds the ability to mute players. Next to the permanent mute command it also adds the `tempmute` command. With every mute a reason must be given why this player is getting muted.

## Configuration

```yaml
mute-module:
  # Whether or not the plugin will use "/mute player" features.
  enabled: true
  # Will the player know he is muted.
  default-soft-mutes: false
  # Commands that get blocked when a player is muted
  blocked-commands:
      - msg
      - whisper
      - tell
```

## Permissions

| Permission                             | Description                                                                                                           |
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| staff.staffplus.mute                   | Permission for muting a player                                                                                        |
| staff.staffplus.tempmute               | Permission for temporarily muting a player                                                                            |
| staff.staffplus.unmute                 | Permission for unmuting a player                                                                                      |
| staff.staffplus.mute-bypass            | Permission for bypassing being muted                                                                                  |
| staff.staffplus.mute-notifications     | Permission to receive notifications when someone is muted/unmuted                                                     |
| staff.staffplus.mute-override-softhard | Permission to use the -soft/-hard option when muting players. See [soft/hard mutes](/features/muting#soft-hard-mutes) |

## Commands

| Command                                                             | Description               |
| ------------------------------------------------------------------- | ------------------------- |
| /mute \[player] \[reason] \[-soft?] \[-hard?]                       | Permanently mute a player |
| /tempmute \[player] \[amount] \[unit] \[reason] \[-soft?] \[-hard?] | Temporarily mute a player |
| /unmute \[player] \[reason]                                         | Unmute a player           |

## Soft/Hard Mutes

Staff++ provides two ways of muting. Mutes where the player will be notified he is muted, we call this **hard** mutes. And mutes where the player has no idea he has been muted, we call this **soft** mutes.

By default all mutes are hard mutes but this can be changed with the `default-soft-mutes` configuration property.

```yaml
mute-module:
  # Will the player know he is muted.
  default-soft-mutes: false
```

You can override the default mute type by specifying a `-soft` or `-hard` option when muting players.

```yaml
/mute playername To much spamming -soft
```

{% hint style="info" %}
Even though a soft mute will not notify the player that he has been muted. There is no easy way to fake the blocked-commands of the mute configuration. If a player executes one of the blocked commands nothing will happen so he might figure out something is going on.
{% endhint %}

## **Restricting tempmute duration**

The tempmute command can also be configured to restrict the duration a staff member can use for a mute.\
Give the staff member and extra permission with a duration limit as suffix. Example: `staff.staffplus.tempmute.limit.2w` , with this permission a staff member can only issue a mute for a maximum duration of 2 weeks.

{% hint style="warning" %}
A staff member must have both permissions to use the command. So for a 2 week duration limit the permissions needed are:

* `staff.staffplus.tempmute`
* `staff.staffplus.tempmute.limit.2w`
  {% endhint %}

**Possible time values:**

* s = second
* m = minute
* h = hour
* d = day
* w = week
* M = month
* y = year

*Time values cannot be combined. For example this is invalid: ".1m30s" instead type ".90s"*

## Extending/reducing mute duration

A mute duration can be extended or reduced by the following commands:&#x20;

`/mute-reduce [player] [amount] [unit]`\
`/mute-extend [player] [amount] [unit]`\
\
This command can also be limited in duration the same way a tempmute is limited.\
Giving the player the following 2 permissions will limit the extension duration for example:

* staff.staffplus.extendmute
* staff.staffplus.extendmute.limit.2w

{% hint style="warning" %}
When extending a mute, the staff member cannot extend the mute further than his tempmute limit will allow. This is to prevent a staff member spamming an extend command.\
This means that if a player is muted for 2 months. His mute cannot be extended by a staff member whose tempmute limit is 3 weeks for example.
{% endhint %}

## Examples

### Permanent muting

`/mute [player] [reason]`

```
/mute playername He was bothering me
```

### Temporary muting

`/tempmute [player] [amount] [unit] [reason]`

```
/tempmute playername 15 MINUTE He was bothering me
```

The duration of the tempmute is specified by \[amount] \[unit]

Amount must be a positive number > 0 and unit must be one of the following:

* SECOND
* MINUTE
* HOUR
* DAY
* WEEK
* MONTH
* YEAR

{% hint style="info" %}
The tempmute command can be delayed by adding a `-D` option to it. This will delay the command until the player muted will come online
{% endhint %}

### Unmuting

`/unmute [player] [reason]`

```
/unmute playername We are friends now
```

## Another plugin is overriding the `/mute`, `/tempmute`, `/unmute`

It is possible that another plugin like 'essentialsx' might get priority over the `mute`, `tempmute` and `unmute` command. To prevent this we suggest the same solution as is proposed by [EssentialsX](https://github.com/EssentialsX/Essentials/wiki/Common-Issues#essentialsx-overrides-a-command-from-spigot-or-another-plugin).

Configure your server aliases in such a way that the mute commands from Staff++ will always be used. This can be done by editing the `commands.yml` file and specifying your aliases there.

To enable Staff++ mute commands this would be done in this way:

```yaml
aliases:
    mute:
    - "staffplus:mute $1-"
    tempmute:
    - "staffplus:tempmute $1-"
    unmute:
    - "staffplus:unmute $1-"
```

More info on the [bukkit wiki](https://bukkit.gamepedia.com/Commands.yml#aliases)

## Integration

The [discord integration](/integrations/discord-integration) plugin supports notifying to a discord channel whenever a player gets mute/unmuted.


# Appealing

This page explains how you can setup the mute appealing system. The system allows players to appeal when a mute has been issued towards them.\
Should they find the mute unjustified they can appeal and a staff member can approve or reject the appeal. If the appeal is approved the mute is undone[.](/features/warnings/actions-punishments)&#x20;

## Setup

### configuration

Underneath the `mute-module` make sure to configure the `appeals` section.

```yaml
mute-module:
   appeals:
      enabled: true
      unmute-on-approve: true
      resolve-reason-enabled: false
      fixed-reason: true
      reasons:
          - 'SPAMMING'
          - 'PROFANITY'
      on-approved-commands: []
      on-rejected-commands: []
```

### Permissions&#x20;

Following permission **must** be set or the appeals functionality can not be used:

| Permission                | Description                                                                                                                                                                   |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| staff.mutes.view-my-mutes | Permission to open a GUI showing all your mutes. All players should get this permission. This is needed because it's the only entrypoint to the GUI where players can appeal. |
| staff.mutes.mute-view     | Allows the usage of the `manage-mutes` command. This is the entrypoint to the GUI that shows player mutes.                                                                    |

#### Appeal specific permissions

| Actor  | Permission                        | Description                                                                                                                                             |
| ------ | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| player | staff.mutes.appeals.create        | Permission to create an appeal. Players will need this permission to appeal a mute                                                                      |
| staff  | staff.mutes.appeals.create.other  | Permission to appeal a mute that is not yours. You should only give this permission to staff members.                                                   |
| staff  | staff.mutes.appeals.approve       | Permission to approve an appeal                                                                                                                         |
| staff  | staff.mutes.appeals.reject        | Permission to reject an appeal                                                                                                                          |
| staff  | staff.mutes.appeals.notifications | Permission to get appeal notifications. When you have this permission you will get notified about open appeals and whenever a player creates an appeal. |


# Protection

The protection system allows a Staff Member to protect a player or protect an entire area.

## Configuration

Inside the config file make sure this section is added:

```yaml
############################################################
# +------------------------------------------------------+ #
# |                      Protection                      | #
# +------------------------------------------------------+ #
############################################################

protect-module:
  # Whether or not the plugin will use "/protectplayer" features.
  player-enabled: true
  # Whether or not the plugin will use "/protectarea" features.
  area-enabled: true
  # The max area size that can be protected.
  area-max-size: 40
```

## Protecting a player

This is pretty simple. `/protectplayer playername` toggles protection for a player, when protected the player takes no damage at all. Protection wears off after the players logs out or if a staff member turns it off.

## Protecting an area

A Staff member can decide to quickly protect an area from non Staff Members. This can be useful when something needs to be investigated. Once protection for an area is turned on, players cannot open chests, break blocks, place blocks, press buttons, switch levers, place water/lava. In general we try to protect everything inside the area from other players. If the feature is useful we can see if other protection measures must be taken.

To protect an area type `/protectarea create 40 My new area`.

* action: create
* size: a square of 40x40
* name: My new area
* The center point of the area is where you are standing.

To delete a protected `/protectarea delete My new area`.

* action: delete
* name: My new area

### Staff Mode

In addition to the command line tool. There is also an overview of protected areas when in staff mode.

#### This can be accessed through the GUI HUB:

![](/files/-MPQwvzAhirN3LSL2BA5)

#### All areas are displayed here:

![](/files/-MPQwzdXQNmBLs6AyEsy)

#### When clicking on an item we can delete(red) the protected area or teleport(orange) to it.

![](/files/-MPQx221RlTYHUDUvFUf)


# Player information

Staff++ added a new GUI to show all player information.

### Commands

| command                | description                             |
| ---------------------- | --------------------------------------- |
| /players               | Show the players overview selection GUI |
| /players \<playername> | Show the details of the given player    |

### Permissions

| Permission    | Description                            |
| ------------- | -------------------------------------- |
| staff.players | Permission to use the /players command |

### GUIs

#### Select overview

When executing the players command without parameters the following GUI will be shown:

![](/files/-MiEH0G8oCbLlc0Ccnzj)

From left to right we have:

| Description              | Permission needed                           |
| ------------------------ | ------------------------------------------- |
| Online players overview  | staff.player-view\.overview\.onlineplayers  |
| Offline players overview | staff.player-view\.overview\.offlineplayers |
| Staff members            | staff.player-view\.overview\.staff          |
| Miners GUI               | staff.player-view\.overview\.miners         |
| Protected players GUI    | staff.player-view\.overview\.protected      |

Each one of those will take you to a different overview:

#### player overview

![](/files/-MiEHnDHhNB422Vtzzge)

Hovering over the player head will show you some information of the player. What you get to see or not is based upon permissions explained in the [player information popup](/features/players-information#player-information-popup) section.

Clicking on a player takes you to his details screen

#### player details

The details screen contains an overview of a player's infraction, state and a set of actions the staff member can perform on the player

![](/files/lIXcW4KUqP188djEUk7g)

On to top row we have

* The player head with detailed info
* The reports overview
* the warnings overview
* The Kicks overview
* Mute indicator
* Ban indicator
* Ip ban indicator

On the bottom row we have:

| action                    | Permission needed                                                                      |
| ------------------------- | -------------------------------------------------------------------------------------- |
| Follow                    | staff.mode.follow                                                                      |
| Freeze                    | staff.freeze.freeze                                                                    |
| Cps                       | No permission                                                                          |
| Teleport to player        | staff.teleport.teleport-to-player                                                      |
| Teleport the player to me | staff.teleport.teleport-here                                                           |
| Check Inventory           | staff.inventory.inventory-interaction OR staff.inventory.inventory-interaction-offline |
| Check Enderchest          | No permission                                                                          |
| Back button               | No permission                                                                          |

What you get to see here is determined by the permissions you have and what modules are enabled or not.

### Player information popup

Whenever hovering over a player's head in the GUIs you will get to see detailed player information.

![](/files/-MiG_ddZK-OfpPGKGiBy)

The first section shows IP, game mode, food level and location of the player.\
The second section shows the state a player is in. Showing if the players is frozen, protected, under investigation, muted or vanished. So in the above case the player is all of these things.

#### permissions

| Description | Permission Needed |
| ----------- | ----------------- |
| IP address  | <p>               |

</p><p>staff.player-view.detail.ip</p> |
| UUID                   | staff.player-view.detail.uuid               |
| Game Mode              | staff.player-view.detail.gamemode           |
| Food level             | staff.player-view.detail.food               |
| Location               | staff.player-view.detail.location           |
| Time played            | staff.player-view.detail.timeplayed         |
| Is frozen              | staff.player-view.detail.frozen             |
| Is protected           | staff.player-view.detail.protected          |
| Is under investigation | staff.player-view.detail.investigated       |
| Is muted               | staff.player-view.detail.muted              |
| Is vanished            | staff.player-view.detail.vanished           |

{% hint style="warning" %}
The above information is only available if the player is online. This is due to performance issues. Online players information is already retrieved and readily available. For offline players you want to check the "player details" GUI.
{% endhint %}


# Player notes

Staff++ reworked how the player notes work to be more consistent with the staff++ other features.\
Notes are now stored in the database and can be synced across multiple servers.\
\
Staff++ also added the ability to create private notes.

### Commands

| Command                                  | Description                                                                                                                                              |
| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| /notes \[playername?] \[filters?] \[-l?] | <p>Retrieve all notes of a player, either in a GUI or in chat.</p><p>More info <a href="/pages/-Min2uD2FYaP2F5W4VrI#searching-player-notes">here</a></p> |
| /note \[playername] \[note] \[-private?] | Create a note for a player                                                                                                                               |
| /pnote \[playername] \[note]             | Create a private not for a player (this can also be conceived with the /note command using the -private option). This command is just for convenience.   |

### Permissions

View [permissions](/permissions-and-commands/permissions) page

### Searching player notes

You can use the /notes command to search for notes. Staff++ provides you several filters which you can use with the notes command:

| Filter                 | Description                                                                                                                             |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| -id=\[noteId]          | search by a note's ID                                                                                                                   |
| -private=\[true/false] | Search only private or only public notes                                                                                                |
| -target=\[playername]  | Search notes specifically linked to a player (you can also just provide the playername as first parameter instead of using this option) |
| -notedBy=\[playername] | Search all notes created by the given player                                                                                            |
| -note=\[note text]     | Search all notes that contain the given text. If you want to use spaces in you need to surround it with double quotes                   |

#### Example

Find all private notes for player "garagepoort" containing the words "is hacking"

```
/notes garagepoort -private=true -note="is hacking"
```

![](/files/-MinKus3HhP7YZXnQO--)

Or in chat with the list "-l" option

```
/notes garagepoort -private=true -note="is hacking" -l
```

![](/files/-MinL77DMH_VSVjH9Ao-)

{% hint style="info" %}
Note that private notes are marked with \[P] in chat.
{% endhint %}

### Private notes

Staff members can create private notes if they have the correct [permission](/features/player-notes#permissions). A private note can only be seen by the player who has created it. \
\
A private note can be create with the `/note` command using the `-private` option. Or by using the `/pnote` command.&#x20;


# Reporting

Staff++ implemented a new reporting system. The new system is a bit different from the old Staff+ reporting system. We now support reporting online and offline players. Reporting events can be send to discord using the Staff++ Discord Integration plugin. Below I will explain how to set up and use the reporting system.

## Configuration

The configuration is pretty self-explanatory. Make sure you have this section inside your configuration file and enable the reporting module by setting `enabled` to `true`

```yaml
reports-module:
  chatchannels:
      enabled: false
      open-on: IN_PROGRESS
      close-on: REJECTED;RESOLVED

  # Whether or not the plugin will use "/report" features.
  enabled: true

  # The sound that is played to staff when someone is reported.
  # Set to "NONE" to disable.
  sound: ORB_PICKUP

  # The cooldown, in seconds, for using "/report".
  # This is disabled for players with the "permissions.report" permission.
  cooldown: 10

  # Whether or not the player that reported another player will be visible in GUIs.
  show-reporter: true

  # Whether or not a staff member must provide a reason when resolving/rejecting a report
  closing-reason-enabled: true

  # Types of reports. When configured the reporter will see a UI where he must choose the type
  report-types: []
  fixed-reason: false
  fixed-reason-culprit: false
  reasons: []

  reporter-notifications:
      # The reporter will be notified the moment he comes online that he has reports OPEN or IN_PROGRESS
      notify-on-join: true
      # Enable status change notifications. Whenever a staff member changes the status to one of the specified statuses, the reporter will be notified (if he is online).
      # Statuses must be semi-colon separated
      status-change-notifications: IN_PROGRESS;RESOLVED;REJECTED
  # command hooks
  accept-commands: []
  reject-commands: []
  reopen-commands: []
  resolve-commands: []
```

## Report commands

#### players

* `/reportplayer [playerName] [message]` Report a specific player.
* `/report [message]` Report something but don't link a specific player to it.
* `/my-reports` Open the GUI to show the reports you created.

#### staff members

* `/reports` Used to manage reports. You can list or clear all the reports of a player
* `/manage-reports` Open the manage reports GUI.
* `/find-reports` [Search reports](/features/reporting/finding-reports) by different criteria

## Report permissions

#### Player permissions

Following permissions are used to allow players creating reports

* `staff.reports.report` Permission to create a report
* `staff.reports.view-my-reports` Permission to open the my-reports GUI
* `staff.reports.bypass` Permission to bypass getting reported

#### Staff permissions

* `staff.reports.manage.view` Permission to view all reports. If a staff member does not have this perm, he won't be able to manage reports
* `staff.reports.manage.delete` Permission to permanently delete reports
* `staff.reports.manage.accept` Permission to accept reports
* `staff.reports.manage.resolve` Permission to resolve reports
* `staff.reports.manage.close` Permission to close reports
* `staff.reports.manage.reject` Permission to reject reports
* `staff.reports.manage.teleport` Permission to teleport to a report creation location
* `staff.reports.manage.reopen-other` Permission to un-assign other staff members from their reports
* `staff.report.update.notifications` Permission for receiving notifications when a report is accepted/deleted/closed

## Report lifecycle

### OPEN

When a report first gets created it get the status `OPEN`, open reports can be picked up by any staff member with the correct permission.

### IN\_PROGRESS

After a staff member picks up a report it gets placed into the status `IN_PROGRESS`. When one member of staff picks up a report no other member can handle this report. The staff member who picks up the report gets assigned to the report. He can un-assign himself from the report through the GUI. If he un-assigns himself someone else can pick up the report again. \
Staff members with the `staff.reports.manage.reopen-other` can also un-assign other staff members from their reports.

### RESOLVED

A staff member can manage reports assigned to him. If he deems the report to be completely handled he can resolve the report. When a report is resolved, other staff members can view it in the closed reports GUI.

### REJECTED

A staff member can manage reports assigned to him. If he deems the report to be incorrect, or spam, or just not enough information he can reject the report. When a report is rejected, other staff members can view it in the closed reports GUI.

## Screenshots

![manage reports](/files/-MU5QM2xdQq4HSfBHu4A)

![Unresolved reports GUI](/files/-MU5QQXlCPUqZq8PjqMp)

![Manage a report](/files/-MU5QV6NpTs5UwXwuvOH)


# Command hooks

You can execute commands upon certain lifecycle changes of a report:

```yaml
 investigations-module: 
   accept-commands: []
   reject-commands: []
   reopen-commands: []
   resolve-commands: []
```

Commands listed here should be in the [Staff ++ command format](/general-information/other/configuring-commands)

### Placeholders:

| placeholder | description                                                     |
| ----------- | --------------------------------------------------------------- |
| %reporter%  | The name of the player that created the report                  |
| %assigned%  | The name of the staff member assigned to the report, if present |
| %culprit%   | The name of the player that has been reported, if present       |

### Executors:

| executor value | description                         |
| -------------- | ----------------------------------- |
| reporter       | The player that created the report  |
| assigned       | The staff member currently assigned |
| culprit        | The player that has been reported   |

### Targets:

| target value | description                         |
| ------------ | ----------------------------------- |
| reporter     | The player that created the report  |
| assigned     | The staff member currently assigned |
| culprit      | The player that has been reported   |

### Filters

| filter     | possible values                      | description                                                                                                                      |
| ---------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| type       | comma separated list of the any type | Can specify if a command should be executed only when the report is of a certain [type](/features/reporting/custom-report-types) |
| hasculprit | \[true/false]                        | Can specify if a command should be executed only when it's a report that is targeting a player                                   |

### Example:

```yaml
 reports-module: 
    accept-commands: []
   reject-commands: []
   reopen-commands: []
   resolve-commands:
       - command: "tell %assigned% Good job?"
         target: "assigned"
         target-run-strategy: ONLINE
       - command: "tell %culprit% A staff member has resolved a report in which you were the culprit"
         target: culprit
         target-run-strategy: DELAY
         filters: "hasculprit=true;type=HACKING,GRIEFING" 
```


# Messages

Following messages are available for the reporting system in the lang files:

```yaml
reports:
    # The prefix for all messages related to reports.
    prefix: "&dReports &8»"
    reporter.report-created: "&bReported &7%culprit% &bfor &7%reason%&b."
    reporter.report-player-created: "&bReported &7%culprit% &bfor &7%reason%&b."
    reporter.report-rejected: "&7Your report has been rejected by &6%staff%&7."
    reporter.report-resolved: "&7Your report has been resolved by &6%staff%&7."
    reporter.report-accepted: "&7Your report has been accepted by &6%staff%&7."
    reporter.view-reports-button: "&9View your reports!"
    reporter.view-reports-button-tooltip: "Click to view your reports"

    report-created-notification: "&7%reporter% &bhas created a report with reason &7%reason%&b."
    report-player-created-notification: "&7%reporter% &bhas reported %culprit% for &7%reason%&b."
    report-reopened-notification: "&b%staff% &7reopened report from &6%reporter%"
    report-deleted-notification: "&b%staff% &7deleted report from &6%reporter%"
    report-accepted-notification: "&b%staff% &7has accepted report from &6%reporter%"
    report-closed-notification: "&6%staff% &fchanged report status to &6%status% &fReporter: &6%reporter%"
    reports-cleared: "&bReports cleared for &7%culprit%&b!"

    # Lines are separated by commas.
    reports-list-start: "&7%longline%, &7%target% &bhas &7%reports% &breports."
    reports-list-entry: "&b%count%: &7%reason% (%reporter%)"
    # Lines are separated by commas.
    reports-list-end: "&7%longline%"
```

### Placeholders:

| placeholder     | description                                                                    |
| --------------- | ------------------------------------------------------------------------------ |
| %staff%         | Staff currently assigned to the report (only if the report has staff assigned) |
| %reporter%      | Name of the player who created the report                                      |
| %culprit%       | Name of the player that got reported, or "Unknown" if no culprit               |
| %reason%        | Reason for the report                                                          |
| %status%        | The current status of the report                                               |
| %close\_reason% | The reason for closing the report (only on report close messages)              |


# Finding reports

Staff++ has a command to search reports by specific criteria. For example:

`/find-reports assignee=garagepoort status=IN_PROGRESS type=GRIEFED`&#x20;

The above command will find all reports handled by garagepoort and with status IN\_PROGRESS and report type GRIEFED.

| criteria | description                                                           |
| -------- | --------------------------------------------------------------------- |
| id       | Id of the report. Will always return one report                       |
| reporter | Player who created the report                                         |
| assignee | Currently assigned staff member                                       |
| status   | Status of the report                                                  |
| culprit  | Reported player.                                                      |
| type     | Type of the report. Will only work if custom report types are enabled |


# Report types & Reasons

You can configure the reports section to act in different ways. Below I will explain the different ways of setting up the report configuration.

### 1. No predefined reasons, No Types

This is the default configuration for reports.

```yaml
reports-module:
  enabled: true
  ...
  fixed-reason: false
  fixed-reason-culprit: false
  report-types: []
  reasons: []
  ...
```

When configured like this, a player can create a report in the following ways:

* /report \<reason>
* /reportplayer \<playername> \<reason>&#x20;

### 2. No predefined reasons, predefined Types

You can configure report-types underneath the reports-module. This is completely optional.\
If you do configure them the player creating the report will get a selection screen where he must select his report type.

When configured like this, a player can create a report in the following ways:

* /report \<reason>
* /reportplayer \<playername> \<reason>&#x20;

After executing the command the select type GUI will be shown.

Every report type must define a **name.** \
Optionally you can also define **info** which will be displayed as lore of the item and a **material.**

```yaml
reports-module:
  enabled: true
  ...
  fixed-reason: false
  fixed-reason-culprit: false
  report-types:
    - name: GRIEFED
      info: Select when you want to report someone destroying your property.
      material: MUSIC_DISC_11
    - name: BULLIED
      info: Something about bullying
      material: MUSIC_DISC_13
    - name: BUG
      info: Select this report type if you found a bug somewhere on the server
      material: MUSIC_DISC_BLOCKS
  reasons: []
  ...
```

![](/files/-MVJXAJGEx2Kq7nPu72s)

### Predefined Reasons, No types

You can define predefined reasons for reports. When reasons are defined a player can create a report in the following ways:

* /report \<reason?>
* /reportplayer \<player> \<reason?>

Notice that the reason becomes optional in this scenario. If the player does not provide a reason, the reason select GUI will be shown. You can make it so that the GUI always shows up by setting the `fixed-reason` to true.

Every report reason must define a **reason.** \
Optionally you can also define **info** which will be displayed as lore of the item and a **material.**\
you can also define a **type,** this is also optional. If you define a type, this type will be stored inside the database if the user selects this reason through the GUI.

```yaml
reports-module:
  enabled: true
  ...
  fixed-reason: false 
  fixed-reason-culprit: false
  report-types: []
  reasons:
    - reason: Kill Aura
      info: Report for kill aura
      material: MUSIC_DISC_11
      type: HACKING
    - reason: Speed hacks
      info: Select for reporting speed hacks
      material: MUSIC_DISC_13
      type: HACKING
    - reason: god mode
      info: Select when suspecting a player from using god mode
      type: HACKING
    - reason: Something sab1
      info: Select when sabtao
      type: SABOTAGE
    - reason: something sab2
      info: Select when sabot
      type: SABOTAGE
  ...
```

![](/files/-MaGHjX0ffjTvR7NyC2o)

### 4. Predefined reasons, Predefined types

When configuring the reports in this way a player can create a report in the following ways:

* /report \<reason?>
* /reportplayer \<player> \<reason?>

Reason is optional in this scenario. If reason is provided only the select type GUI is shown.\
If the player does not provide a reason then first the select Type GUI is shown, and based on the Type select the Select Reason GUI is shown.

**In this setup \`type\` for report reasons is mandatory! The type must be the same as the one defined in the report types.**

```yaml
reports-module:
  enabled: true
  ...
  fixed-reason: false
  fixed-reason-culprit: false
  report-types:
    - name: HACKS
      info: 'Select iof you want to report someone for hacking'
      material: MUSIC_DISC_11
      filters: culprit=true
    - name: BUG
      info: 'Report a bug'
      material: MUSIC_DISC_13
      filters: culprit=false
  reasons:
    - reason: Kill Aura
      info: Report for kill aura
      material: MUSIC_DISC_11
      type: HACKS
    - reason: Fly hacks
      info: Select for reporting fly hacks
      material: ELYTRA
      type: HACKS
    - reason: X ray
      info: Select when suspecting a player from using an xray
      material: MUSIC_DISC_13
      type: HACKS
    - reason: Network
      info: Something went wrong connecting to a server
      type: BUG
    - reason: Plugin 
      info: A plugin is not working as expected
      type: BUG
  ...
```

### Filters

Both reasons as report types can define a filter **"culprit".** You can use this filter to decide if reasons or types should be visible depending the fact if a player got reported or not. When the filter is not defined they will be shown with both.

```yaml
reports-module:
  enabled: true
  ...
  fixed-reason: false
  fixed-reason-culprit: false
  report-types:
    - name: HACKS
      info: 'Select iof you want to report someone for hacking'
      material: MUSIC_DISC_11
      filters: culprit=true
  reasons: []
  ...
```


# Chat channels

Staff++ has the possibility to open chat channels linked to reports.

### Configuration

```yaml
reports-module:
  chatchannels:
      enabled: false
      open-on: IN_PROGRESS
      close-on: REJECTED;RESOLVED;DELETED
```

With the above configure when a report channel should be automatically opened and closed.\
In the default configuration the channel gets opened as soon as the report is picked up by a staff member. And the chat channel is closed automatically when the report gets resolved, rejected or deleted.

### Permissions

```yaml
chatchannels:
    join: "staff.chatchannels.join.report"
    leave: "staff.chatchannels.leave.report"
    open: "staff.chatchannels.open.report"
    close: "staff.chatchannels.close.report"
```

### Commands

| description                | Description                                                                                                            |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| /rc \<reportId> \<message> | Send a message to a report channel                                                                                     |
| /join-channel \<channelId> | Join this chatchannel. You will see the messages send on this channel and will be able to send message to this channel |
| /leave-channel \<reportId> | Leave the chat channel                                                                                                 |
| /close-channel \<reportId> | The chat channel will be closed. This forces all players to leave the channel and the channel gets deleted             |

### GUI

There are 2 buttons on the report GUI that allow staff members to open/close/join/leave the chatchannel manually.

![](/files/JK8V4IqHtLhzCf701xD0)


# Staff Chat

### Configuration

```yaml
# Requires "permissions.staff-chat" permission.
staff-chat-module:
  # Whether or not the plugin will use "/sc" features.
  enabled: true
  # Whether or not the plugin synchronises staff chat across the bungee network
  bungee: true

  channels:
    - name: staffchat
      # What command will be used to send message to this channel
      command: sc
      permission: staff.staffchat
      prefix: '&dStaffChat &8»'
      message-format: '&b%player% &8» &7%message%'
      # The string that can be used at the beginning of a message to make it appear in staff chat.
      # If you have "@" as your string, typing "@hey guys" would send "hey guys" to staff chat.
      # Leave blank to disable.
      handle: '@'
      sound: ENTITY_EXPERIENCE_ORB_PICKUP
    - name: adminchat
      command: ac
      permission: staff.staffchat
      prefix: '&dAdminChat &8»'
      message-format: '&b%player% &8» &7%message%'
      handle: $
```

### Channels

You now have the flexibility to define multiple staff chat channels, with each channel having its own configurable command. Furthermore, you can specify the required permissions for accessing each channel.

#### Mute **Functionality**

When setting up a staff channel, an additional command for muting that channel is automatically created. For instance, if you configure a command `sc` for a channel, a corresponding `sc-mute` command is also generated. To gain access to the mute command, users must possess the necessary permissions for the channel, denoted by `.mute` appended to the configured permission. In the example mentioned, this permission would be `staff.staffchat.mute`.

#### Sound control

While configuring a staff channel, another command is introduced to manage notification sounds, allowing users to enable or disable them for the specific channel. Just like the mute command, to access the sound command, users must have the appropriate permissions for the channel, marked by `.sound` added to the configured permission. In the example given, this permission would be `staff.staffchat.sound`.

### Discord Integration

For seamless communication, staff chat can be seamlessly integrated with a Discord channel through the use of the [discord integration plugin](/integrations/discord-integration/staff-chat). This integration enables bidirectional communication between your staff chat and a preconfigured Discord channel.


# Staff Mode

Staff mode is one of the biggest features in Staff+ & Staff++. It allows a staff member to enter a mode in which he gets extra privileges so that he/she can go patrolling around. Staff++ introduced the option of multiple staff modes.&#x20;

### Permissions

View [permissions](/permissions-and-commands/permissions) page

## Commands

| Command | Description                                                                                                                                     | Example                        |
| ------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ |
| `staff` | <p>Turns on/off Staff mode for the current user. <br>If the user has the specific permission, the parameter <code>-mode=</code> can be used</p> | `/staff` `/staff -mode=Helper` |
| `sfly`  | Turn on/off flight. Only available if the current mode has set flight to true.                                                                  | `/sfly`                        |

All staff modes are configured inside the`configuration/staffmode/modes.yml` config file.&#x20;

#### Basic configuration

The part below contains the basic settings for the staff mode. Be default there is only one staff mode called "default". You're allowed to change this mode but you can **not delete it.**\
\
All other staff modes that you might configure extend from the default mode.

```yaml
modes:
    default:
        block-manipulation: false
        inventory-interaction: true
        silent-chest-interaction: false
        item-drop: false
        item-pickup: false
        vanish-type: TOTAL
        vanish-on-enter: true
        invincible: true
        damage: false
        hunger-loss: false
        flight: true
        creative: false
        night-vision: false
        original-location: false
        disable-on-logout: false
        enable-on-login: false
        disable-on-world-change: false
        enable-commands: []
        disable-commands: []
        initial-item-states: []
        gui:
            - compass-module:1
            - random-teleport-module:2
            - vanish-module:3
            - gui-module:4
            - counter-module:5
            - freeze-module:6
            - cps-module:7
            - examine-module:8
            - follow-module:9
            - player-details-module:10
```

### Enable/Disable commands

Moved to [Command hooks](/features/staff-mode/command-hooks)

### Mode Options

| option                   | type              | description                                                                                                                                                                                                                                                                |
| ------------------------ | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| permission               | String            | <p>Which permission is needed to enable the staff mode.</p><p>This is mandatory except for the <code>default</code> mode.</p>                                                                                                                                              |
| weight                   | int               | <p>Determines which priority a staff mode gets during mode calculation. The higher the weight the higher the priority. This is mandatory except for the <code>default</code> mode.</p><p>Configure this to <code>-1</code> to exclude this mode from mode calculation.</p> |
| damage                   | boolean           | Can the player damage other entities while in staff mode                                                                                                                                                                                                                   |
| invincible               | boolean           | Can the player take damage while in staff mode                                                                                                                                                                                                                             |
| block-manipulation       | boolean           | Can the player place/break blocks while in staff mode                                                                                                                                                                                                                      |
| item-drop                | boolean           | Allow dropping items                                                                                                                                                                                                                                                       |
| item-pickup              | boolean           | Allow picking up items                                                                                                                                                                                                                                                     |
| hunger-loss              | boolean           | Will hunger be enabled while in staff mode                                                                                                                                                                                                                                 |
| vanish-type              | TOTAL\|LIST\|NONE | The vanish type to enable when entering staff mode                                                                                                                                                                                                                         |
| staff-see-staff-in-mode  | boolean           | Can staff members see other staff members while in vanish                                                                                                                                                                                                                  |
| enable-commands          | List              | A list of commands that will be executed when the player enters staff mode                                                                                                                                                                                                 |
| disable-commands         | List              | A list of commands that will be executed when the player exits staff mode                                                                                                                                                                                                  |
| enable-on-login          | boolean           | Enable this staff mode automatically when the player logs in                                                                                                                                                                                                               |
| disable-on-logout        | boolean           | Disable this staff mode automatically when the player logs out                                                                                                                                                                                                             |
| disable-on-world-change  | boolean           | Should staff mode disable automatically when the staff members switches worlds. Keep in mind that if a staff members switches to a world in which his staff mode is not allowed, it will also be disabled automatically.                                                   |
| creative                 | boolean           | Give the player creative mode while in staff mode                                                                                                                                                                                                                          |
| night-vision             | boolean           | Gives the player night vision while in staff mode                                                                                                                                                                                                                          |
| flight                   | boolean           | Give the player flight while in staff mode.                                                                                                                                                                                                                                |
| inventory-interaction    | boolean           | Whether or not a player is allowed to interact with their inventory while in staff mode.                                                                                                                                                                                   |
| silent-chest-interaction | boolean           | Is the player allowed to open ches                                                                                                                                                                                                                                         |
| original-location        | boolean           | When enabled the staff members will be teleported to his original location where he entered staff mode, when exiting staff mode.                                                                                                                                           |
| GUI                      | List              | All staff-modules which should be included in the staff mode gui.                                                                                                                                                                                                          |
| allowed-worlds           | List              | This is optional. If you don't define it inside the default config and don't overwrite it in any of the underlying modes, all worlds will be enabled. If defined this staff mode can only be used in the defined worlds                                                    |


# Multiple modes

You can configure multiple staff modes inside the `modes.yml` file.\
All modes extend, by default, the `default` mode. You cannot remove the default mode from the configuration but you can alter it.

{% hint style="warning" %}

* If a staff-mode module is disabled it won't show up in the GUI&#x20;
* Custom modules can also be used inside the GUI config. Make sure the key name matches.
  {% endhint %}

## Example configuration

We'll go over the following example configuration.

```yaml
modes:
  default:
    damage: false
    enable-commands: []
    disable-commands: []
    initial-item-states: []
    disable-on-world-change: false
    creative: false
    night-vision: false
    flight: false
    inventory-interaction: false
    invincible: false
    item-drop: false
    item-pickup: false
    vanish-type: NONE
    enable-on-login: false
    disable-on-logout: true
    original-location: true
    block-manipulation: false
    silent-chest-interaction: false
    hunger-loss: true
    allowed-worlds:
    - world
    gui:
    - counter-module:1
  Helper:
    permission: rank.helper
    weight: 1
    flight: true
    hunger-loss: false
    gui:
    - compass-module:1
    - vanish-module:2
    - counter-module:3
    - follow-module:4
  Mod:
    permission: rank.moderator
    weight: 2
    extends: Helper
    invincible: true
    allowed-worlds:
    - world
    - world_nether
    gui:
    - compass-module:1
    - random-teleport-module:2
    - vanish-module:3
    - counter-module:4
    - freeze-module:5
    - follow-module:6
    - Whip:7
  Admin:
    permission: rank.admin
    weight: 3
    extends: Mod
    creative: true
    allowed-worlds:
    - world
    - world_nether
    - world_the_end
    gui:
    - compass-module:1
    - random-teleport-module:2
    - vanish-module:3
    - gui-module:4
    - counter-module:5
    - freeze-module:6
    - cps-module:7
    - examine-module:8
    - follow-module:9
    - player-details-module:10
    
  # --------------------  
  Investigator:
    permission: rank.investigator
    weight: -1
    gui:
    - compass-module:1
```

### Default mode

The default mode is a mandatory mode which needs to be present. It contains all possible configuration options. To access this mode you need at least the `staff.mode` permission. In this setup I configured the default mode to be as basic as possible. In reality no one will ever enter just "default" mode in this setup. They will always use one of the other configured modes. To see all configuration options explained see the [staff mode section](/features/staff-mode#mode-options).

```yaml
default:
    damage: false
    enable-commands: []
    disable-on-world-change: false
    creative: false
    night-vision: false
    flight: false
    inventory-interaction: false
    invincible: false
    staff-see-staff-in-mode: false
    disable-commands: []
    item-drop: false
    item-pickup: false
    vanish-type: NONE
    enable-on-login: false
    disable-on-logout: true
    original-location: true
    block-manipulation: false
    silent-chest-interaction: false
    hunger-loss: true
    allowed-worlds:
    - world
    gui:
    - counter-module:1
```

###

### Helper

Every custom mode must provide a **permission** and **weight** property. These properties are used during mode calculation.\
The helper mode has no `extends` property so it extends from the `default` mode.\
When you create a new mode it inherits all properties from the default mode. You can overwrite every property by defining it inside your mode config. In this example I give Helpers `flight` and no `hunger loss`. I also provide them with different [Staff items](/features/staff-mode/staff-modules).&#x20;

```yaml
Helper:
    permission: rank.helper
    weight: 1
    flight: true
    hunger-loss: false
    gui:
    - compass-module:1
    - vanish-module:2
    - counter-module:3
    - follow-module:4
```

![](/files/-MQj76Rl4lTShqY6h-dl)

###

### Mod

The **Mod** mode extends from the **Helper** mode. So it automatically gets `flight` and disables `hunger loss`. In addition to that I configure `invincibility`. \
I also add the nether to allowed worlds. And Mods get a different GUI with some more staff items.\
Notice it also has a higher **weight.** So if a staff member has both the helper and mod permission, the mod staff mode has priority.

```yaml
Mod:
    permission: rank.moderator
    weight: 2
    extends: Helper
    invincible: true
    allowed-worlds:
    - world
    - world_nether
    gui:
    - compass-module:1
    - random-teleport-module:2
    - vanish-module:3
    - counter-module:4
    - freeze-module:5
    - follow-module:6
    - Whip:7
```

![](/files/-MQj7BEaWwpTsZkAp3IZ)

###

### Admin

Admin is the highest staff mode that is available. This is indicated by the weight. It extends the **Mod** mode and thus inherits everything from **Mod** mode. In addition to this Admin mode can be enabled in more worlds and his GUI has been extended.  Admins also get creative mode.

```yaml
Admin:
  permission: rank.admin
  weight: 3
  extends: Mod
  creative: true
  allowed-worlds:
  - world
  - world_nether
  - world_the_end
  gui:
  - compass-module:1
  - random-teleport-module:2
  - vanish-module:3
  - gui-module:4
  - counter-module:5
  - freeze-module:6
  - cps-module:7
  - examine-module:8
  - follow-module:9
```

![](/files/-MQj7EWfhIy3TO1Iy9k3)

###

### Investigator

The last mode in my configuration file is the Investigator mode. This mode is special because it won't be considered during mode calculation. In other words, you can only access the mode if you have the permission to switch to a specific staff mode `staff.mode.specific` or if it gets enabled programmatically. This is indicated by the **weight.** It is set to `-1` , which means don't use it for staff mode calculation. Notice it does not define an `extends` property, thus it gets all properties defined in the `default` mode.

When enabled the player gets vanished automatically and gains the compass module.

```yaml
Investigator:
  permission: rank.investigator
  weight: -1
  vanish-type: TOTAL
  gui:
  - compass-module:1
```


# Staff Modules

When entering staff mode the player's hot bar gets replaced with "Staff Items" these are special items which execute actions when used. Every item is listed as a staff mode module inside the `configuration/staffmode/modules.yml`file. You can disable them there and they will never be included inside the staff mode GUI.

### Compass module

The name of this module is a bit strange as it is named after the item rather then the action it performs.\
When this module item is clicked, it launches the staff towards the direction they are facing. It's an easy way to move very fast across the world.

#### configuration

```yaml
compass-module:
  enabled: true
  item: COMPASS
  name: "&4Launcher"
  lore: "&7Launches you towards the, &7location you are facing."
  
  # The velocity at which a player will be launched.
  velocity: 5
```

### Random Teleport module

This module teleports you to a player on the server. Either randomly or round robin. Could be used for when staff are patrolling.

```yaml
random-teleport-module:
  enabled: true
  item: ENDEREYE
  name: "&cRandom Teleport"
  lore: "&7Teleports you to a random player."
  
  # Whether or not actual pseudo-randomness will be used.
  # If set to false, "random" teleport will just cycle through players in order.
  random: false
```

### Vanish module

Allows players to turn vanish mode on/off using the item. Underneath this does exactly the same as the vanish command.

```yaml
vanish-module:
    enabled: true
    item: INK:10
    name: "&6Vanish"
    lore: "&7Toggles your total vanish."
    
    # The type of item for when vanish is disabled.
    item-off: INK:8
```

### GUI module

The GUI item opens the Staff++ GUI. It contains a GUI which allows you to manage reports, view bans mutes. Mostly you won't want to touch this unless if you want to change some of the translations or want to remove items from the GUI

```yaml
gui-module:
  enabled: true
  item: PAPER
  name: "&eGUI Hub"
  lore: "&7Opens the GUI hub."

  # Reports GUI
  reports-gui: true
  reports-title: "&bUnresolved reports"
  my-reports-title: "&bReports assigned to you"
  closed-reports-title: "&bClosed reports"
  
  reports-name: "&bUnresolved reports GUI"
  reports-lore: "&7Shows all open reports."
  my-reports-lore: "&7Shows reports currently assigned to you."
  closed-reports-lore: "&7History of all closed reports."

  # Miner GUI. Show players below a certain y level
  miner-gui: true
  miner-title: "&bUnderground users"
  miner-name: "&bMiner GUI"
  miner-lore: "&7Shows all players under the set Y value."
  # The y-level at which a player will be marked as a miner.
  xray-level: 16

  # Protected Areas GUI
  protected-areas-gui: true
  protected-areas-title: "&bOverview protected areas"
  protected-areas-name: "&bProtected Areas GUI"
  protected-areas-lore: "&7Shows all currently set protected areas."

  # Banned players GUI
  ban-gui: true
  ban-title: "&bOverview banned players"
  ban-name: "&bBanned players GUI"
  ban-lore: "&7Shows all currently banned players."

  # Muted players GUI
  mute-gui: true
  mute-title: "&bOverview muted players"
  mute-name: "&bMuted players GUI"
  mute-lore: "&7Shows all currently muted players."

```

### Counter module

The name of this module is again a bit strange as it does not represent the action it holds. When clicking on the item it opens a GUI showing all Staff members currently online.&#x20;

```yaml
counter-module:
  enabled: true
  item: HEAD
  name: "&aStaff List"
  lore: "&7Shows all staff online and in staff mode"
  title: "&bCurrent staff online"

  # Whether or not the head item count will represent online staff or staff in staff mode.
  show-staff-mode: false
```

### Freeze module

When clicking on a player with this item he will get frozen, clicking him again will unfreeze him.

```yaml
freeze-module:
  enabled: true
  item: BLAZE_ROD
  name: "&2Freeze"
  lore: "&7Toggles freeze for the clicked player."
```

### CPS module

When clicking a player with this item, Staff++ will start recording how many clicks per second that player is executing. Useful for finding players who are using an autoclicker.

```yaml
cps-module:
  enabled: true
  item: CLOCK
  name: "&3CPS"
  lore: "&7Runs a click per second test on, &7the player that was clicked."

  # Amount of time, in seconds, that the test will run for.
  time: 10

  # The maximum allowed amount of CPS. If a result contains this amount or more, it will be significantly marked.
  max: 16.0
```

### Examine module

When clicked on a player with this item, the examine GUI will open. This GUI contains the player's info like IP, game mode, notes and so on.

You can configure what exactly is displayed inside the GUI. \
**To disable a certain info-line, give it the value 0**

> NOTE: ping is not working

```yaml
examine-module:
  enabled: true
  item: CHEST
  name: "&bExamine"
  lore: "&7Inspects the inventory of the player that was clicked."

  # The title of the examine GUI.
  title: "&bExamine inventory"

  # The configuration of the final line of the examine GUI.
  # Set the slot of a node to zero to disable it.
  # Remember that the maximum amount of allowed items within this line is nine!
  info-line:
    # Food and hunger information.
    food: 1

    # IP address information.
    ip-address: 2

    # Ping information.
    ping: 3

    # Gamemode and flight information.
    gamemode: 4

    # Infractions information.
    infractions: 5

    # Location information and teleport button.
    location: 6

    # Player "notes" button.
    notes: 7

    # Freeze button
    freeze: 8

    # Warn button.
    warn: 9
```

### Follow module

When clicking on a player you will mount the player. Effectively being tied to him.

```yaml
follow-module:
  enabled: true
  item: LEAD
  name: "&9Follow"
  lore: "&7Mounts the player that was clicked."
```

### Player details module

When clicking on a player this will open the [player details GUI](/features/players-information#player-details)

```yaml
player-details-module:
    enabled: true
    item: STICK
    name: "&9Details stick"
    lore: "&7Show all player details."
```


# Custom Staff Modules

To make staff mode more configurable Staff++ has the option to add custom staff modules.\
These staff modules can be used when a player enters `staff mode`. \
Custom modules can be configured inside the `configuration/staffmode/custom-modules.yml`

{% hint style="info" %}
To use your custom module, you need to configure it as a **gui item** inside the staff mode configuration file (**modes.yml**).&#x20;
{% endhint %}

There are 2 types of custom modules: **Command modules** & **Plain Modules.**

#### **Command module**

```yaml
custom-modules:            
    # Name of the module, can be anything you want as long as it's a valid yaml key
    - name: ExampleCommandModule
      # Indicates if this module should be enabled
      enabled: true
      # Type of command module: COMMAND_STATIC;COMMAND_DYNAMIC;COMMAND_CONSOLE
      type: COMMAND_STATIC
      # The material of the item
      item: 
        type: DIAMOND
        name: "&4Ban all god kids"
        lore: "&4line1, &6line2, &3line3"
      # The commands to execute when this item is used
      commands: 
        - "ban Shortninja &4For coding 2hard!!11!1!one!"
```

| Type             | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| COMMAND\_STATIC  | <p>Execute the configured commands as the player who clicked the item.</p><p>This command takes only <strong>%clicker%</strong> as placeholder. No target must be provided.</p>                                                                                                                                                                                                                                                                                                                            |
| COMMAND\_DYNAMIC | <p>Execute the configured commands as the staff member who clicked the item.</p><p>Use this if you are writing a command module that targets a player.<br>The commands will target the player the staff member is pointing at.</p><p>You can use the following placeholders: "<strong>%clicker%"</strong> & <strong>"%clicked%".</strong></p><p>Clicker is the name of the staff member, clicked is the name of the target player. If the staff member is not targeting a player, nothing will happen.</p> |
| COMMAND\_CONSOLE | <p>Execute the configured commands as the console. This can either target a player or not. The commands will target the player the staff member is pointing at. You can use the following placeholders: "<strong>%clicker%"</strong> & <strong>"%clicked%".</strong></p><p>"Clicker" is the name of the staff member, "clicked" is the name of the target player</p>                                                                                                                                       |

#### Plain Module

Plain modules just add a regular item inside the staff's inventory.

> Make sure to define "TYPE: ITEM"

```yaml
custom-modules:
    # Name of the module, can be anything you want as long as it's a valid yaml key
  - name: ExamplePlainModule
    # Indicates if this module should be enabled
    enabled: true
    # Type always ITEM for plain modules.
    type: ITEM
    # The material of the item
    item:
      lore: '&8Knock em out!!'
      name: '&7Knock out stick'
      type: STICK
    
    # Optional enchantment 
    # The enchantment for the item format is name:level 
    # for names of enchantments reference https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/enchantments/Enchantment.html
    enchantment: "knockback:2"
```

### Input

Modules can have an input prompt popup before they get executed. The input can then be used as a placeholder in the command.

```yaml
custom-modules:
- enabled: true
  type: COMMAND_DYNAMIC
  item:
    lore: '&4Ban a player after providing reason'
    name: '&4Ban target player, provide reason in chat'
    type: DIAMOND
  name: '&4Ban target player, provide reason in chat'
  commands:
    - ban %clicked% %input%
  require-input: true
  input-prompt: Please provide a reason for banning %clicked%.
```

<div align="center"><img src="/files/-MVxfnuA-re8COva-7j-" alt=""></div>

### Confirmation

Modules can have a confirmation GUI or Chat pop up before the action is executed.\
This is useful to prevent accidents from happening, especially for modules that execute severe actions.\
You can combine confirmation with input as shown in the example below. Confirmation can of course also be used standalone without the input option.

```yaml
custom-modules:
  CustomBanModule:
    enabled: true
    type: COMMAND_DYNAMIC
    item: DIAMOND
    name: '&4Ban target player, provide reason in chat'
    lore: '&4Ban a player after providing reason'
    commands: 
      - ban %clicked% %input%
    require-input: true
    input-prompt: Please provide a reason for banning %clicked%.
    confirmation: CHAT
    confirmation-message: Are you sure you want to ban %clicked% for reason "%input%".
```

![input + chat confirm](/files/-MVxi8jrAK4FIiCZHBnW)

![input + GUI confirm](/files/-MVxiom8zjKodXxDlfcX)

#### Example configuration

```yaml
custom-modules:
  - enabled: true
    name: ExampleStaticCommand
    type: COMMAND_STATIC
    commands:
      - ban Shortninja &4For coding 2hard!!11!1!one!
    item:
      lore: '&4line1, &6line2, &3line3'
      name: '&4Ban all god kids'
      type: DIAMOND
      
  - enabled: true
    name: ExampleDynamicCommand
    type: COMMAND_DYNAMIC
    commands:
      - ban %clicked% &6for shitposting too much with %clicker%
    item:
      lore: '&cyou damn lazy staff'
      name: '&4Ban this kid'
      type: QUARTZ
      
  - enabled: true
    name: ExampleConsoleCommand
    type: COMMAND_CONSOLE
    commands:
      - staff %clicker% disable
    item:
      lore: '&7you''re so lazy'
      name: '&bDisable staff mode'
      type: OBSIDIAN
      
  - enabled: true
    name: ExamplePlainItem
    type: ITEM
    item:
      lore: '&8don''t grief shitlord!!'
      name: '&7WorldEdit Wand'
      type: WOOD_AXE
      
  - enabled: true
    name: ExampleEchantment
    type: ITEM
    item:
      lore: '&8Knock em out!!'
      name: '&7Knock out stick'
      type: STICK
    enchantment: knockback:2
```


# State dependent modules

This page describes the setup to create state dependent modules. These modules can be used to dynamically show/hide staff items by activating other staff items. Example and use cases below.

### custom module config

Each custom module can configure these 3 optional configuration parameters:

| option           | description                                                                                          |
| ---------------- | ---------------------------------------------------------------------------------------------------- |
| enabled-on-state | A string value which defines that this module should only get enabled when the given state is active |
| enable-state     | Tell staff++ to enable this state when the module is executed.                                       |
| disable-state    | Tell staff++ to disable this state when the module is executed.                                      |

### Modes config

In the modes config we can specify which states should be active when entering the mode:

```yaml
modes:
  default:
    ...
    initial-item-states:
    - nightvision-off
```

Using this system we can create modules which are enabled only on certain states.\
Because state changes can be done by staff modules themselves we can create some flexible configurations.

## Examples

### Nightvision modules

We defined 2 modules. 1 for toggling night mode on. And one for turning it off.\
The first module switches the state to `nightvision-on` This state change makes it so that the second module will be enabled and shown inside the player's inventory.\
Vice versa the second module triggers the state to `nightvision-off`

{% code title="custom-modules.yml" %}

```yaml
custom-modules:
  - name: TurnOnNightVisionModule
    enabled: true
    enabled-on-state: nightvision-off
    enable-state: nightvision-on
    disable-state: nightvision-off
    type: COMMAND_STATIC
    item: 
      type: OBSIDIAN
      name: '&bEnables night vision'
      lore: '&7Click to enable night vision'
    commands: 
       - "nightvision on"
  - name: TurnOffNightVisionModule
    enabled: true
    enabled-on-state: nightvision-on
    enable-state: nightvision-off
    disable-state: nightvision-on
    type: COMMAND_STATIC
    item: 
      type: DIAMOND
      name: '&bDisables night vision'
      lore: '&7Click to disable night vision'
    commands: 
       - "nightvision off"
```

{% endcode %}

### Modes config

To configure the mode I did the following:

* disable the default night vision of staff mode
* Disable night vision when exiting staff mode
* Set initial state to night vision off. So when you enter staff mode the obsidian block will be in your inventory
* We defined the module on the same inventory location. Due to the state only one will be shown at a time.

```yaml
modes:
  default:
    # other config here
    ...
    night-vision: false
    disable-commands:
    - command: nightvision off %staff%
    initial-item-states:
    - nightvision-off
    gui:
    - TurnOnNightVisionModule:1
    - TurnOffNightVisionModule:1
```

<figure><img src="/files/WvlP3nUIlssPy16Qb1cG" alt=""><figcaption></figcaption></figure>


# Command hooks

You can execute commands whenever a staff member exits or enters a mode

```yaml
modes:
    default:
        enable-commands: []
        disable-commands: []
```

Commands listed here should be in the [Staff ++ command format](/general-information/other/configuring-commands)

### Placeholders:

| placeholder | description                                            |
| ----------- | ------------------------------------------------------ |
| %staff%     | The name of the staff member entering/exiting the mode |

### Executors:

| executor value | description                                |
| -------------- | ------------------------------------------ |
| staff          | The staff member entering/exiting the mode |

### Targets:

| target value | description                                |
| ------------ | ------------------------------------------ |
| staff        | The staff member entering/exiting the mode |

### Filters

Currently no filters are available except the [permission filter](/general-information/other/configuring-commands#permission-filter)

### Example:

```yaml
 modes:
    default:
        enable-commands: []
        disable-commands:
          - command: "tell %staff% Taking a break uh?"
            target: "staff"
            target-run-strategy: ONLINE
```


# Luckperms integration

When a staff member goes into staff mode and you have the LuckPerms plugin installed. A staff-mode context will be added to that player. This allows you to configure LuckPerms permissions that will only be applied when a player is in staff-mode.

The exact context is: &#x20;

* **key**: `staff++:staffmode`&#x20;
* **value**: `true`


# Staff Locations

Staff locations are stored locations by staff members. These locations are shared among staff members and players with access can teleport to them.

### Configuration

```yaml
staff-locations-module:
    enabled: true
    # if configured, players can choose a location from the predefined icons.
    # If left empty they will have the choice of any icon.
    icons: []
```

#### Icon configuration

Example:

```yaml
staff-locations-module:
  enabled: true
  icons:
    - text: Unclaimed base (Requesting admin claim)
      icon: GOLDEN_SHOVEL
    - text: AFK evader
      icon: WATER_BUCKET
    - text: Autofishing farm
      icon: FISHING_ROD
    - text: Inappropriate build
      icon: BARRIER
    - text: Flymachine
      icon: SLIME_BLOCK
    - text: Lagmachine
      icon: REPEATER
    - text: Traps
      icon: IRON_TRAPDOOR
    - text: Griefed area
      icon: TNT
    - text: Griefed animals or other mobs
      icon: LEAD
    - text: Disturbingly named animals or other mobs
      icon: NAME_TAG
    - text: Disturbing signs
      icon: OAK_SIGN
    - text: Suspicious location (like storage of players suspected of raiding)
      icon: SPYGLASS
    - text: Trouble area, players often getting at eachother
      icon: DIAMOND_SWORD
```

### Commands

<table><thead><tr><th width="199.80319148936172">Command</th><th width="151.33333333333331">description</th><th>Example</th></tr></thead><tbody><tr><td>/stafflocations</td><td>Open locations GUI</td><td><code>/stafflocations</code><br><code>/stafflocations -id=2</code><br><code>/stafflocations -name="My name here"</code><br><code>/stafflocations -creator=garagepoort</code></td></tr><tr><td>/create-stafflocation</td><td>Create a new staff location</td><td><code>/create-stafflocation new location name</code></td></tr></tbody></table>

### GUIs

#### Staff locations

![](/files/sufjopsH0TIwQJiZlGal)

#### Manage location

![](/files/EoIyZLFn22F0AJYi9M27)

#### Edit location

![](/files/r1C5kzjAkbsEv9kzPMoR)

#### Location Notes

![](/files/kTqJqS3M3LIUmlPRHzyb)


# Teleporting

Staff++ introduces new teleport commands. These very basic commands can be used to teleport yourself or other players.

## Locations

You can specify predefined locations inside the configuration file. This allows you to teleport yourself or other players to this location.\
Make sure the following section is present in your configuration file:

```yaml
############################################################
# +------------------------------------------------------+ #
# |                       Locations                        | #
# +------------------------------------------------------+ #
############################################################
# Used to predefine certain locations in the world which can be used in other commands
# Type in the location identifier and location using format: x;y;z
# ex. config
# locations:
#     spawn: 14;45;62;world
# ex. /freeze myplayer -Tspawn
# This will freeze the player and teleport him to spawn location.
locations:
```

You can define multiple locations underneath the `locations` section. Example:

```yaml
locations:
     spawn: 14;45;62;world
     jail: 58;789;70;world_nether
```

## Commands:

### Teleport a player to a location:

The `teleportToLocation` command can also be used as an argument `-T` to enhance other commands.

```
/teleportToLocation thatplayer spawn
```

### Teleport yourself to a player:

```
/teleportToPlayer thatplayer
```

### Teleport a player to your location:

```
/teleportHere thatplayer
```

### Teleport a player back to his original location:

This only works if the player has been teleported at least ones before. Previous locations are lost when the server restarts.

```
/teleportBack thatplayer
```


# Vanish

Allows players to vanish.

### Permissions

View [permissions](/permissions-and-commands/permissions) page

### Configuration

```yaml
vanish-module:
    # Whether or not the plugin will use "/v" features.
    enabled: true

    # Whether or not list vanish will hide the vanished users from tab list.
    # Does not completely hide players in tab for 1.7 versions.
    tab-list: true

    # Whether or not list vanish users will be shown as "away" or "offline" in the staff list.
    show-away: false

    # Whether or not user should be shown in command tab-complete suggestions.
    suggestions: false

    # Whether or not chat can be used when vanished.
    chat: false

    # Whether or not to show a message on screen telling the staff member his vanish is enabled
    vanish-message-enabled: true

    # Whether or not to show a bossbar on screen telling the staff member his vanish is enabled
    vanish-bossbar-enabled: false

    # Default vanish mode. Gets used when using the vanish the command without arguments
    default-mode: TOTAL
    # Allow item drop while vanished
    item-drop: true
    # Allow item pickup while vanished
    item-pickup: true
    # When true, you can't take damage while vanished
    invincible: false
    # Allow giving damage while vanished
    damage: true
    # Allow placing blocks while vanished
    block-place: true
    # Allow breaking blocks while vanished
    block-break: true
    # Allow opening a chest normally
    normal-chest-opening: true
    # Allow interacting with a chest that has been normally opened
    normal-chest-interaction: true
    # Allow opening a chest silently
    silent-chest-opening: false
    # Allow interacting with a chest that has been silently opened
    silent-chest-interaction: false
    # Will give players night vision while vanished in TOTAL or PLAYER mode.
    night-vision: false
    # Enable to add join leave message in chat when a player gets vanished.
    join-leave-message-enabled: true
    # List all the items which the player should not be able to interact with
    cancelled-interaction-types:
        - '*PRESSURE_PLATE'
        - '*TRIP*'
```

### Command

| Command                                      | Examples                                                                                                 |
| -------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| /vanish \<type> \<player> \<enable\|disable> | <p><code>/vanish</code><br><code>/vanish LIST</code><br><code>/vanish LIST garagepoort enable</code></p> |

### Vanish types

| Type   | Description                                                    |
| ------ | -------------------------------------------------------------- |
| LIST   | Vanished the player only in the tab list                       |
| PLAYER | Vanished the player in-game but keeps his name in the tab list |
| TOTAL  | Vanished the player in-game and in the tab list                |

### Join/leave message

The join and leave message can be configured inside the `lang_*.yml` file

```yaml
vanish-join-message: "&e%player% joined the game"
vanish-leave-message: "&e%player% left the game"
```


# Luckperms integration

When a staff member goes into vanish and you have the LuckPerms plugin installed. A staff-vanished context will be added to that player. This allows you to configure LuckPerms permissions that will only be applied when a player is in vanished or not vanished.

The exact context is: &#x20;

* **key**: `staff++:vanished`&#x20;
* **value**: `true`


# Warnings

Staff++ created a new way of warning players.

{% hint style="info" %}
To setup the warning configuration checkout the [quick start](/features/warnings/quick-start)
{% endhint %}

## Configuration

```yaml
# Requires "permissions.warn" permission.
warnings-module:
  # Whether or not the plugin will use "/warn" features.
  enabled: true

  # The sound that is played to the player when warned.
  # Set to "NONE" to disable.
  sound: ORB_PICKUP


  # Whether or not the player issued the warning will be visible in GUIs.
  show-issuer: true

  # Enables the ability to notify a user when he has warnings
  # User will be notified the moment he comes online.
  user-notifications:
      enabled: false
      # Enable this to show the message every time the user comes online.
      # If Disabled the warnings will be marked as "read" when the player views his warnings 
      # and he will only be notified of new warnings
      always-notify: false
  
  actions: []

  severity-levels:
    - name: MINOR
      score: 1
      # After how much time warnings with this severity should expire.
      # Expired warnings are not counted when doing threshold calculations.
      expiresAfter: 1 WEEK
    - name: MAJOR
      score: 3
      expiresAfter: 1 MONTH
    - name: CRITICAL
      score: 5
  # Define thresholds for the warning system. Whenever the player reaches a threshold the actions are triggered
  thresholds:
    - score: 6
      actions:
        - command: "ban %target% &4Met three warnings. Appeal @ &7www.shithcf.net&4."
          target: target
          target-run-strategy: DELAY
```

### Permissions

View [permissions](/permissions-and-commands/permissions) page

### Commands

| Command                              | Description                                                                                                                                                                              | Example                               |
| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- |
| `/warn [severity] [player] [reason]` | Command to give a player a warning. [Severity ](/features/warnings/severity-levels)should be configured inside the configuration file and provided as first argument to the warn command | `/warn MAJOR player1 For some reason` |
| `/warns [get] [player]`              | Command to manage warnings. You can list current warnings                                                                                                                                | `/warns get player1`                  |
| `/my-warnings`                       | The command for opening the my warnings GUI                                                                                                                                              | `/my-warnings`                        |
| `/manage-warnings [player]`          | Command for opening a GUI showing all the warnings of the give player                                                                                                                    | `/manage-warnings player1`            |

## Enable user notifications

You can enable user notifications. This will notify the player that he has warnings. To do so change this part of the warnings-module inside the config file:

```yaml
  # Enables the ability to notify a user when he has warnings
  # User will be notified the moment he comes online.
  user-notifications:
      enabled: true
      # Enable this to show the message every time the user comes online.
      # If Disabled the warnings will be marked as "read" and he will only be notified of new warnings
      always-notify: false
```

Whenever a user opens his warning GUI all his warnings are marked as 'read'. If `always-notify` is disabled, a user will only be notified if he has unread warnings. Keep in mind that to open the warnings GUI the player has to have the following permission: `staff.warn.view-my-warnings`


# Quick start

A small guide to help you configure the warnings system

{% hint style="info" %}
On this page I guide you through an example configuration.\
The example used here is purely fictional, so don't go and copy paste the configuration.\
It is just to help you understand how you can set up the warnings system
{% endhint %}

## Default configuration

When you clean install Staff++ the below configuration is installed>

```yaml
# Requires "permissions.warn" permission.
warnings-module:
  # Whether or not the plugin will use "/warn" features.
  enabled: true
  # The sound that is played to the player when warned.
  # Set to "NONE" to disable.
  sound: ORB_PICKUP
  # Whether or not the player issued the warning will be visible in GUIs.
  show-issuer: true

  # Enables the ability to notify a user when he has warnings
  # User will be notified the moment he comes online.
  user-notifications:
      enabled: true
      # Enable this to show the message every time the user comes online.
      # If Disabled the warnings will be marked as "read" and he will only be notified of new warnings
      always-notify: false

  actions: []
  severity-levels:
    - name: MINOR
      score: 1
      expiresAfter: 1 WEEK
    - name: MAJOR
      score: 3
      expiresAfter: 1 MONTH
    - name: CRITICAL
      score: 5
  # Define thresholds for the warning system. Whenever the player reaches a threshold the actions are triggered
  thresholds:
    - score: 6
      actions:
        - command: "ban %player% &4Warning threshold has been met"
        
  appeals:
      enabled: true
      resolve-reason-enabled: false
      fixed-reason: false
      reasons:
          - ''
```

However this configuration is only an example and you most probably want to change this to fit your needs.

### [Severity levels](/features/warnings/severity-levels)

Start by changing the [severity levels](/features/warnings/severity-levels) inside the configuration file. You want to choose levels that you find logical for your server. They describe the different types of warnings you might have.\
For example I will change mine to something like this:

```yaml
severity-levels:
  - name: CUSSING
    score: 1
    expiresAfter: 1 WEEK
    reason: Player us ed curse words 
  - name: ADVERTISEMENT
    score: 2
    expiresAfter: 4 DAY
  - name: STEALING
    expiresAfter: 1 MONTH
    score: 4
  - name: GRIEFING
    expiresAfter: 1 MONTH
    score: 5
  - name: MURDER
    expiresAfter: 1 MONTH
    score: 6
  - name: EXTREME GRIEFING
    expiresAfter: 3 MONTH
    score: 7
  - name: HACKING
    score: 7
  - name: BULLYING
    score: 9
```

The above is an example of how you could configure severity levels. The **score** is used for [threshold](/features/warnings/thresholds) calculations and indicates how severe the warning is. **expiresAfter** defines when a warning should be expired, meaning no longer used for [threshold ](/features/warnings/thresholds)calculations, leave this out to never expire this type of warning. We can specify a default **reason** which will be linked to the warning when issued.\
Every warning needs a severity level. When you issue a warning you have to choose one of the above levels.

### [Actions](/features/warnings/actions-punishments)

You will notice the **actions** array is empty by default. Actions aka "punishments" define what commands should be executed when a player receives a warning. Actions can be triggered for every warning or for a specific severity level by using the filter. \
To illustrate I will add following punishments: (This configuration uses fictive commands)

```yaml
actions:
  # For every warning a player receives, deduct $200 from his balance 
  - command: eco take %target% 200
    rollback-command:
      command: eco give %target% 200
  # Jail a player for 30 minutes for stealing, griefing or murder
  - command: jail %target% 30
    filters: severity=STEALING,GRIEFING,MURDER
    rollback-command: 
      command: unjail %target%
  # Ban player for hacking  
  - command: ban %target% Hacking
    filters: severity=HACKING
    rollback-command: 
      command: unban %target% Warning rolled back
  # Ban player for bullying
  - command: ban %player% Bullying
    filters: severity=BULLYING
    rollback-command: 
      command: unban %player% Warning rolled back
```

Notice I always define a [rollback command](/features/warnings/actions-punishments). This command gets executed should the warning get appealed or deleted. This is a way to automatically reverse punishments.

### [Thresholds](/features/warnings/thresholds)

The last thing you can configure are [thresholds](/features/warnings/thresholds). Thresholds are punishments that are given when a players gets too many warnings. Warnings score will be counted unless the warning is expired or the warning has been successfully appealed

```yaml
thresholds:
  - score: 16
    actions:
      - command: "ban %player% &4Too many warnings received"
```

In the above configuration I define that if a player received a total warning score of 16 he will get automatically banned. You can define multiple thresholds and punishments.&#x20;

This is the basic setup of the warning configuration. You can find more information on every topic discussed here on the other documentation pages.&#x20;


# Severity levels

In the configuration file we defined severity levels. These can be as many as you want but you must have at least one. We define a `name`,`score` Optionally we can define `expiresAfter` , `reason` and `reasonOverwriteEnabled` property. The score determines how serious an offence the player has committed. Every warning must have a severity level. An example configuration could be:

```yaml
severity-levels:
  - name: STEALING
    score: 1
    expiresAfter: 1 WEEK
    reason: No you don't do that
    reasonOverwriteEnabled: true
  - name: GRIEFING
    score: 3
  - name: BULLYING
    score: 6
```

As you can see in the above config, griefing is a more serious offence than stealing. And bullying is the most serious offence.&#x20;

{% hint style="warning" %}
Severity levels cannot contain **spaces.** I suggest using simple alphanumeric names.
{% endhint %}

#### reason & reasonOverwriteEnabled

We can define a default reason for severity levels. This means that whenever a staff members issues a warning with this severity level he does not need or cannot specify a reason. \
This means that when a default reason is set the following is a valid command:\
\
&#x20;    `/warn STEALING aPlayerName`

Another configuration option, `reasonOverwriteEnabled` , can be set to enable a staff member to specify a custom reason if he wants to. If both `reason` and `reasonOverwriteEnabled: true` are set a staff member can either issue a warning this way:\
\
&#x20;    `/warn STEALING aPlayerName`

Or this way:

&#x20;    `/warn STEALING aPlayerName My custom reason`

#### Expiration

The **expiresAfter** property is optional and defines when a warning gets expired. Expired warnings still show up in the infractions GUI but are not taken into account when doing threshold calculations. \
Specified by \[amount] \[unit].

Amount must be a positive number > 0 and unit must be one of the following:

* SECOND
* MINUTE
* HOUR
* DAY
* WEEK
* MONTH
* YEAR


# Thresholds

Thresholds can be reached by players if they receive too many warnings. An example configuration:

```yaml
severity-levels:
  - name: STEALING
    score: 1
    expiresAfter: 1 WEEK
  - name: GRIEFING
    score: 3
  - name: BULLYING
    score: 6
thresholds:
  - score: 3
    actions:
      - command: "tempban %target% 4 days"
  - score: 6
    actions:
      - command: "ban %target%"
        rollback-command: 
          command: "unban %target%" 
```

We defined two thresholds. When the player reaches the first threshold of a total warning score of 3 he will be temporarily banned. Keep in mind that his total score wont be reset. Which means that if he gets another warning for stealing for example, his total score will be 4 and he will immediately get temporarily [banned](/features/banning) again. So once you reach a threshold you will be punished more severely on subsequent warnings.

However warnings can be **expired**. This mean they will no longer be counted during threshold calculations.

You will notice you can also define [rollback-commands](/features/warnings#actions-and-rollback) here. These will get executed if the warning that originally caused a threshold breach gets deleted or [appealed](/features/warnings/appealing).

The second threshold bans a player when he reaches a total score of 6. This also means that a warning for bullying in this example will immediately ban the player.

### **Score Calculation Example**

Consider player "myman" has following warning history:

| Type     | score | appeal approved | expired |
| -------- | ----- | --------------- | ------- |
| STEALING | 1     | true            | false   |
| GRIEFING | 3     | false           | false   |
| GRIEFING | 3     | false           | true    |
| STEALING | 1     | true            | true    |
| BULLYING | 6     | false           | false   |

In this example the player his total score will be: **9**

* The first warning does **not** count because it was **successfully appealed**
* The second warning **counts**
* The third warning does **not count** because it is expired
* The fourth warning does **not count** because it was **successfully appealed AND expired**
* The fifth warning **counts**

&#x20;&#x20;


# Actions (punishments)

We can define actions inside the warnings-module. Actions will be executed whenever a warning is issued. Every action must follow the [Staff++ command format](/general-information/other/configuring-commands)

Besides the general command, a **rollback-command** can be specified. A rollback command follows the [Staff++ command format](/general-information/other/configuring-commands). The rollback command gets executed whenever a warning is deleted or has been successfully [appealed](/features/warnings/appealing).

### Placeholders:

| placeholder | description                                           |
| ----------- | ----------------------------------------------------- |
| %target%    | The name of the player that was warned                |
| %issuer%    | The name of the staff member that created the warning |
| %severity%  | The severity of the warning                           |
| %score%     | The score of the warning                              |
| %reason%    | The reason of the warning                             |

### Executors:

| executor value | description                              |
| -------------- | ---------------------------------------- |
| target         | The player that has been warned          |
| issuer         | The staff member that issued the warning |

### Targets:

| target value | description                              |
| ------------ | ---------------------------------------- |
| target       | The player that has been warned          |
| issuer       | The staff member that issued the warning |

### Filters

| filter     | possible values                      | description                                                                                                                      |
| ---------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| type       | comma separated list of the any type | Can specify if a command should be executed only when the report is of a certain [type](/features/reporting/custom-report-types) |
| hasculprit | \[true/false]                        | Can specify if a command should be executed only when it's a report that is targeting a player                                   |

**Example configuration:**

```yaml
warnings-module:
  actions:
    - command: 'eco take %target% 2000'
      filters: 'severity=MINOR,MAJOR'
      rollback-command: 
        command: 'eco give %target% 2000'
    - command: 'eco take %target% 5000'
      filters: 'severity=CRITICAL'
      rollback-command: 
        command: 'eco give %target% 5000'
    - command: 'freeze enabled %target%'
      filters: 'severity=CRITICAL'
      rollback-command: 
        command: 'freeze disabled %target%'
```

In the above example configuration the following will happen:

If a MINOR or MAJOR warning is issued. \
&#x20;        \- The target will be deducted $2000 from his balance.\
If a CRITICAL warning is issued. \
&#x20;        \- The target will be deducted $5000 from his balance.\
&#x20;        \- The target will get frozen if he is online, or the next time he comes online.\
\
If the warning gets rollbacked the target will get automatically reimbursed.&#x20;

{% hint style="warning" %}
It's important to not that actions get linked to the warning the moment the warning is created.\
Changing the action configuration will not impact existing warnings.
{% endhint %}


# Appealing

This page explains how you can setup the warnings appealing system. The system allows players to appeal when a warning has been issued towards them.\
Should they find the warning unjustified they can appeal and a staff member can approve or reject the appeal. If the appeal is approved the warning is [rolled back.](/features/warnings/actions-punishments)&#x20;

## Setup

### configuration

Underneath the `warnings-module` make sure to configure the `appeals` section.

```yaml
warnings-module:
  appeals:
      #enable the ability to appeal a warning
      enabled: true
      # When enabled staff members must enter a reason of approval/rejection
      # of the appeal
      resolve-reason-enabled: false
      # When enabled the player will have to choose an appeal reason from the 
      # list defined in the reasons property
      # When disabled the player will get to fill in a reason himself.
      fixed-reason: true
      reasons:
          - 'MOD abuse'
          - 'I did not do it'
```

### Permissions&#x20;

Following permission **must** be set or the appeals functionality can not be used:

| Permission                  | Description                                                                                                                                                                      |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| staff.warn.view-my-warnings | Permission to open a GUI showing all your warnings. All players should get this permission. This is needed because it's the only entrypoint to the GUI where players can appeal. |
| staff.warnings.manage.view  | Allows the usage of the `manage-warnings` command. This is the entrypoint to the GUI that shows player warnings.                                                                 |

#### Appeal specific permissions

| Actor  | Permission                           | Description                                                                                                                                                                                                                 |
| ------ | ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| player | staff.warnings.appeals.create        | Permission to create an appeal. Players will need this permission to appeal a warning                                                                                                                                       |
| staff  | staff.warnings.appeals.create.other  | Permission to appeal a warning that is not your. You should only give this permission to staff members. This could be useful if for some reason the player can't appeal his warning himself. For example when he is banned. |
| staff  | staff.warnings.appeals.approve       | Permission to approve an appeal                                                                                                                                                                                             |
| staff  | staff.warnings.appeals.reject        | Permission to reject an appeal                                                                                                                                                                                              |
| staff  | staff.warnings.appeals.notifications | Permission to get appeal notifications. When you have this permission you will get notified about open appeals and whenever a player creates an appeal.                                                                     |

### Add an appeal

![](/files/-MTSNzGm0h-LyyiN8_Kx)

### Select Appeal reason

![](/files/-MTSO4wImFYDcsCsjHdK)

### Appeal opened

![](/files/-MTSOCNoa2OkhTQ-eox1)

### Staff: Manage appeal

![](/files/-MTSOnTqeXiHPbyT6exd)


# Warning workflow

## Warning statuses

### Warning created

When a warning gets created punishment actions of the warning get executed.\
At this point the warning is in a state where it is counted during [threshold calculation](/features/warnings/thresholds#score-calculation-example).\
A player can [appeal](/features/warnings/appealing) the warning, a staff member can manually expire the warning or even delete the warning

### Warning [appealed](/features/warnings/appealing)

When a warning gets appealed a staff member has the ability to approve or reject the appeal.\
Once an [appeal is rejected](/features/warnings/appealing#staff-manage-appeal) the player can no longer appeal it. When an appeal is approved, [rollback actions](/features/warnings/actions-punishments) are triggered and the warning is marked appeal approved. Once an [appeal is approved](/features/warnings/appealing#staff-manage-appeal) it is like the warning never existed. It does not get counted when doing [threshold calculations](/features/warnings/thresholds#score-calculation-example) and won't show up in the [infractions GUI](/features/infractions). However the warning does not get deleted, this makes sure we can keep a history of the warning and appeal reasons.

### Warning expired

Warnings can expire after a configured amount of time. Or manually by a staff member. When a warning is expired the punishments do **not** get [rollbacked](/features/warnings/actions-punishments). The only real reason for warning expiration is to make sure this warning no longer gets counted when doing [threshold calculations](/features/warnings/thresholds#score-calculation-example). It's a way to ensure warnings won't be held against the player forever.

Notice that a player can still appeal this warning. The reason a player might want to do this is if feels the warning was incorrectly given and although it's expired he still received the [punishment](/features/warnings/actions-punishments). So by appealing he asks to rollback his punishment.

### Warning deleted

A staff member can choose to delete a warning completely. This action can always be taken no matter what status the warning is in. When a warning gets deleted, [rollback actions](/features/warnings/actions-punishments) are triggered and the warning is removed from the database. All history of the warning is gone.\
In general you should only delete a warning if there was actually a mistake made. In most cases you can use the appeal system to [rollback warnings](/features/warnings/actions-punishments) in a clean way.

![Warnings workflow](/files/-MUGZrqJx43Ml5id4iGe)


# Register Players

You can let players link their Staff++ web platform account with your server group.\
To do so you need to setup "**webui"** module of the plugin.

### Configuration

Inside the config.yml

```yaml
webui-module:
    enabled: true
    # Don't change this
    host: https://web.staffplusplus.org
    # The role the member will get when registering
    role: MEMBER
    # Application key, can be found on your admin panel 
    application-key: 
```

Set enabled to **true** and fill in your application-key. The application key can be found on the "general settings" page of your application

![](/files/-M_bPHjBXbSJEXngpHIr)

### Commands

| Command   | Description                                                                             |
| --------- | --------------------------------------------------------------------------------------- |
| /register | Generate a registration url which can be used to register your user to the server group |

### Permissions

| Permission           | Description                      |
| -------------------- | -------------------------------- |
| staff.webui.register | Allow using the register command |


# Setup Web Platform

### Register organisation

Start by going to <https://web.staffplusplus.org/> and clicking on "I want to register my organisation". This will take you to the page where you can create an account.

![](/files/-M_S9HKFN56OfHv7ipCg)

Fill in your credentials an choose an application name which fits your organisation best.\
Once you register you will need to **verify your email**. After verification you will be taken to your application's admin panel.

![](/files/-M_SEDSKlMkOmzYPjF3D)

### General settings

Once you are able to access your dashboard go to the General Settings

![](/files/-M_SEQ8MM_CfsnzUMm3X)

This takes you to the configuration page where you can edit your organisation details like name, logo and connection url.

![](/files/-M_SEzHeFwZvhR5MVDEa)

* Fill in the connection url to your server. Or something else. It doesn't have to be a real url.
* Upload your logo. Preferably an image of at least 80x80 px
* Set your organisation's visibility. By default your organisation can't be found by other users of the platform.
* Save your settings

Once that is done, your organisation dashboard should already be visible. To verify this. Click on "**Exit Admin interface**" in the menu on the left. This takes you to the dashboard of your application.

![](/files/-M_STq86YOf1CovDaS18)

You can't really do anything yet, but you should be able to see it.&#x20;

**Head back over to the admin interface**.

### Server groups

Your organisation needs at least one server group. A server group is a collection of servers linked by the same Staff++ database. You set it up and configure every or some servers that are in your network. If you only have 1 server you only need to configure one.

On the server groups overview click "**create**".

![](/files/-M_SbFz4JNNmMPMkv8Lm)

Fill in your **Name.** Just choose something that describes these servers best. Like mini-games.

Check `public access` if you want to make this server group visible to everyone". When public access is checked you will notice a "Public permissions" section is added, here you can finetune what information should actually be accessible for none registered users.

Check all features you want to have enabled. `warnings` `bans` `mutes`

{% hint style="danger" %}
`At least one feature must be enabled!`
{% endhint %}

#### Database Connection

{% hint style="warning" %}
You need a Mysql Database.\
Make sure your Mysql database is [accessible from the Staff++ web platform](https://www.digitalocean.com/community/tutorials/how-to-allow-remote-access-to-mysql).
{% endhint %}

All servers using Staff++ that you want to include in one server group need to be connected to the same Mysql database. That Mysql database connection must also be configured on the web platform, inside the server group configuration.

![](/files/-M_VYukt7RoGxW-_DivJ)

Save the server group. You should now see the server group on your overview.

![](/files/-M_Y8iHttyzBcdki-Rxe)

Click on edit and make sure the database connection is not giving you any errors.\
If the connection does **fail**, an error message will be shown like this:

![](/files/-M_Y96hzznZ7JiLs9ToP)

This can only happen if either the credentials are incorrect or the database can't be accessed. If you don't have any error, continue with the following section.

### Linking Servers

When editing your server group you will now see there is a new section called "**Linked Servers**". Here we will configure every server for which we want data to be available on the platform. In my example I only have one server.

![](/files/-M_bBVjnbgJ1MQZoXF8L)

Click on the "ADD SERVER" button. This will open up a dialog.

![](/files/-M_bBe224v0XTFuVxrz9)

The first part is the most important one.&#x20;

{% hint style="warning" %}
The Server Name should be exactly the same as the property [server-name](/general-information/quick-start#server-name) configured inside your config.yml file.
{% endhint %}

Click on OK and your server should now be visible in the list of linked servers.

![](/files/-M_bJJeL0CDngzCanPVS)

Add all servers you want to see on the dashboard. After the servers are setup exit the admin interface. If you configured your server group to be fully publicly available, you are done here. You should be able to see the dashboard and all information.

### User registration

&#x20;Players on your server can register to your server group by accessing your server and executing the `register` command. More information can be found on [this page](/web-platform/register-players).

When executing that command, a registration url is returned. This url can be used to link your staff++ account to the server group of the server from which you executed the command.

You can finetune permission and roles for user through the "**roles & permission**" section of the admin panel. Choosing what information is available to which users on the platform.<br>

## Video Tutorial

I only had time to make the 2 following videos and it's unedited.

#### Basic setup

{% embed url="<https://www.youtube.com/watch?v=b1lNdc7riao>" %}

### User Registration

{% embed url="<https://www.youtube.com/watch?v=iBDiLLiL8s4>" %}


# Architecture

The web platform is a front-end on top of the Staff++ database.

In the first version of the web platform it was only a view. Meaning we could read data but no changes could be made through the web platform. In the latest version the ability was added to also execute actions such as accepting/rejecting reports.

{% hint style="warning" %}
Actions can only be executed by users that have an account on the web platform and that are registered to your server group. For more information check [register players](/web-platform/register-players)
{% endhint %}

The web platform is not changing the data directly in the database. Instead it sends a request for changes to the Staff++ core Minecraft plugin. This architecture has the advantage that all logic is contained within the core plugin and not duplicated inside the web platform. This also means that changes done through the web platform are seen in game same as if the change was done through the MC guis/commands. Meaning report notifications are broadcast in game was well.

The disadvantage of this approach is that on the web platform your changes are not directly visible. It can take up to 10 seconds before changes done through the web platform become visible and if your MC server is down the changes will not come through until your server starts back up again.

![](/files/XlhlTmIcEgpj0Vdkt3bl)

Reading the change request is done periodically by the core plugin every 10 seconds. In a multi server setup the first server that picks up the request will execute it. Because it is only done every 10 seconds the front-end needs to wait for the changes to be processed.

Whenever the changes are processed a message will pop-up on the front-end.

![](/files/jHYuXttO6WFvfbOxTpX9)

This indicates that your changes have been processed and you can refresh the page to view them.

### Permissions

Make sure to give your staff members the correct permission through the web platform

![](/files/9uiUy5qYKxoCJ3J9sz3F)

### Example manage report view

![](/files/36gYiXTFFtUhrYG73Tt6)


# Discord Integration

## Introduction

Discord integration lets Staff++ notify certain events to your discord server using discord webhooks.

To Enable integration you need to install a separate **plugin:** <https://www.spigotmc.org/resources/staff-discord-integration.83871/>

## Configuration

The configuration of the discord integration plugin is fairly simple.

```yaml
StaffPlusPlusDiscord:
    templatePack: "default" # Choose from template packs "default" or "videndum"
    # The time format which will be used in the discord messages. 
    # This needs to be a valid datetime pattern according to: https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
    timestamp-format: "yyyy-MM-dd'T'HH:mm:ss"
    # REPORTS

    reports:
        # The discord webhook url. This can be found in you discord server settings
        webhookUrl: ""
        # Optional webhook url. When provided, reports linked to a player will be send on this url.
        playerReportsWebhookUrl: ""
        # Trigger a discord message when some player opens a new report
        notifyOpen: false
        # Trigger a discord message when a staff member for some reason decides to not handle a report and he unassigns himself
        notifyReopen: false
        # Trigger a discord message when a staff member assigns himself to an open report
        notifyAccept: false
        # Trigger a discord message when a staff member rejects a report
        notifyReject: false
        # Trigger a discord message when a staff member resolves a report
        notifyResolve: false

    warnings:
        webhookUrl: ""
        notifyCleared: false
        notifyCreate: false
        notifyThresholdReached: false
        appeals:
            webhookUrl: ""
            notifyCreate: false
            notifyApproved: false
            notifyRejected: false
    bans:
        webhookUrl: ""
        ban: false
        unban: false
        extension: false
        reduction: false
        appeals:
            webhookUrl: ""
            notifyCreate: false
            notifyApproved: false
            notifyRejected: false
    ipbans:
        webhookUrl: ""
        ban: false
        unban: false
    kicks:
        webhookUrl: ""
        kick: false
    mutes:
        webhookUrl: ""
        mute: false
        unmute: false
        appeals:
            webhookUrl: ""
            notifyCreate: false
            notifyApproved: false
            notifyRejected: false
    altDetect:
        webhookUrl: ""
        # Levels that should be notified to discord, leave empty to disable all notifications. Should be semi-colon separated
        # possible values: POSITIVE, FAIRLY_POSITIVE, POSSIBLE, NOT_LIKELY
        # example value: POSITIVE;FAIRLY_POSITIVE
        enabledTrustLevels: ""
    xray:
        webhookUrl: ""
        # Ores that should be notified to discord, leave empty to disable all notifications. Should be semi-colon separated
        # possible values: any bukkit material
        # example value: DIAMOND;REDSTONE
        enabledOres: ""
    staffmode:
        webhookUrl: ""
        # Trigger a discord message whenever a staffmember enters staffmode
        notify-enter: false
        # Trigger a discord message whenever a staffmember enters staffmode
        notify-exit: false
    chat:
        webhookUrl: ""
        # Trigger a discord message whenever a a player sends a chat message containing predefined words/phrases
        phrase-detection: false
    commanddetection:
        enabled: false
        webhookUrl: ""
    staffchat:
        sync: false

```

Make sure you create a webhook on your discord server. This can be done by following this guide: <https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks> Once you created the webhook paste it inside the configuration file.

#### commands

| Command\`                    | Description                                                                            |
| ---------------------------- | -------------------------------------------------------------------------------------- |
| /staffplusplusdiscord reload | Reload the entire configuration, this includes the discord templates and webhook urls. |

#### permissions

| Permission                  | Description                     |
| --------------------------- | ------------------------------- |
| staffplusplusdiscord.reload | Allows using the reload command |

### Examples:

{% hint style="info" %}
All discord templates can be [customized](/integrations/discord-integration/customize-discord-templates).&#x20;
{% endhint %}

#### Report

![](/files/-MPQwUu2TYTKNSyORCoy)

#### Warning

![](/files/-MPQwYWcT4Kopb3YXN7D)


# Staff Chat

{% hint style="info" %}
This functionality requires the DiscordSRV plugin
{% endhint %}

You can use the discord integration plugin to setup a staff-chat channel and synchronize messages between in-game and discord chat.\
\
To do so you must have the DiscordSRV bot configured as described here: <https://docs.dedicatedmc.io/plugins-mods/how-to-install-discordsrv/>\
\
Once this is setup you can start setting up Staff++ Discord.

### **Discord setup**

Go into Discord and create a new channel. The channel name can be whatever you want.

![](/files/-MVWbrULqKVH6iu6Nect)

![](/files/-MVWc3U8hOoJTOEFUvea)

Go ahead an grab the **channel id** by right clicking on the channel name and selecting **copy id:**

![](/files/-MVWfmTDwt3xcStw5S3q)

### DiscordSRV Configuration

Open the **config.yml** file of the DiscordSRV plugin. Add your channel id to the channels array.\
The identifier inside the array must be **"staffplusplus-\<channelname>" .** By default staff++ only has one staffchat channel, name "staffchat". So in this case I will configure "**staffplusplus-staffchat**".\
\
If you have for example another channel configured in staff++ called **"adminchat",** you can add another channel in the discordsrv config called "**staffplusplus-adminchat**".<br>

```yaml
Channels: { "global": "000000000000000000", "staffplusplus-staffchat": "xxxxxxxxxxxxxxxxxxxxx"}
```

#### Channel custom formatting

In DiscordSRV you can have custom formatting for every channel differently. To have custom formatting inside DiscordSRV open up the language file inside the `messages` folder of DiscordSRV

```yaml
MinecraftChatToDiscordMessageFormat: "**%primarygroup%** %displayname% » %message%"
MinecraftChatToDiscordMessageFormatNoPrimaryGroup: "%displayname% » %message%"

MinecraftChatToDiscordMessageFormat_staffplusplus-staffchat: "**(STAFFCHAT)** %displayname% » %message%"
MinecraftChatToDiscordMessageFormatNoPrimaryGroup_staffplusplus-staffchat: "**(STAFFCHAT)** %displayname% » %message%"
```

You can set a format for your specific channel by adding `MinecraftChatToDiscordMessageFormat_staffplusplus-staffchat`

### Staff++ Discord Configuration

Open the config.yml of the Staff++ plugin. And enable staffchat sync.

```yaml
StaffPlusPlusDiscord:
  staffchat:
    sync: true
```

That's it! Restart your server and you will be see that message in game get displayed inside your discord channel and vice versa. &#x20;

### Example messages

![](/files/-MVWjhM7I0S3lYZsPKeS)

![](/files/-MVWjwIRiPvluRGgz4qQ)


# Template Packs

The integration plugins offers a template system. Inside the plugin directory there is a **discordtemplates** folder. This folder contains all installed templates.

Currently there are 2 template packs. **default** and **videndum.**\
To switch template packs change the following property in the **config.yml**

```yaml
StaffPlusPlusDiscord:
  templatePack: default
```

### Showcase

#### default:

![](/files/-MVR_4eeJ5L1CkHgoyR3)

![](/files/-MVR_7L0_JYWgTCiO7oA)

![](/files/-MVR_A1UwzB40EaEE30H)

#### videndum:

![](/files/-MVRdatplslr94m_2SlL)

![](/files/-MVRe2pvoWivxZyhp08u)

![](/files/-MVRdi0t3vNhQVi3eXry)


# Customize Discord Templates

{% hint style="warning" %}
This functionality is only available from version 1.16.48 of the discord plugin
{% endhint %}

{% hint style="danger" %}
This is an advanced configuration section. A certain level of technical knowledge is required depending on how much you want to change.
{% endhint %}

## Introduction

To create your own custom discord messages you will need some knowledge of \
[The discord API](https://discord.com/developers/docs/resources/webhook#execute-webhook) and the [JEXL](https://commons.apache.org/proper/commons-jexl/) (Java Expression Language) [syntax](https://commons.apache.org/proper/commons-jexl/reference/syntax.html)\
\
Basically we are doing a REST call to the webhook URL and sending a JSON body with it.\
The JSON bodies are build from template files which can be found inside your **plugin directory** underneath a folder "**discordtemplates**". There are different template packs. **"default"** is enabled by default. Every [template pack](/integrations/discord-integration/template-packs) contains all the template files needed.

These files are a combination of JSON and JEXL.&#x20;

## Configuring a template

{% hint style="info" %}
To easily change and test templates, edit the template and execute the `/staffplusplusdiscord reload` command
{% endhint %}

Start by setting the "**updateTemplates**" property inside the **config.yml** file to **false**. This will prevent Staff++ Discord from overwriting the template files at startup.

Copy paste the **default** templates directory into a new directory with your template name:

![](/files/-MVRTaxDHyVAqWF1XZk9)

Change the **template** configuration property inside the **config.yml**

```yaml
StaffPlusPlusDiscord:
  templatePack: mycustomtemplates
```

S++ Discord will now start using the templates defined in the "**mycustomtemplates"** directory. Change these templates how you like. You can always switch back to another template pack by change the configuration property.

#### Example: discordtemplates/mycustomtemplates/reports/report-rejected.json

````javascript
// Context:
// report: IReport => https://github.com/garagepoort/StaffPlusPlus/blob/master/StaffPlusAPI/src/main/java/net/shortninja/staffplus/unordered/IReport.java
// timestamp: String
{
    "content": "Report update from Staff++",
    "embeds": [
        {
            "title": "Report rejected by ${report.staffName}",
            "url": "https://www.spigotmc.org/resources/staff.83562/",
            "color": "16601379",
            "timestamp": "${timestamp}",
            "footer": {
                "text": "Provided by Staff++",
                "icon_url": "https://cdn.discordapp.com/embed/avatars/0.png"
            },
            "fields": [
                {
                    "name": "Reporter",
                    "value": "${report.reporterName}\n[${report.reporterUuid}]",
                    "inline": true
                },
                {
                    "name": "Culprit",
                    "value": "${report.culpritUuid != null ? report.culpritName + '\\\\n[' + report.culpritUuid + ']' : '[Unknown]'}",
                    "inline": true
                },
                {
                    "name": "Staff",
                    "value": "${report.staffName}\n[${report.staffUuid}]",
                    "inline": false
                },
                {
                    "name": "Reason",
                    "value": "```${report.reason}```",
                    "inline": false
                },
                #IF report.closeReason != null
                {
                    "name": "Reason for closing",
                    "value": "```${report.closeReason}```",
                    "inline": false
                },
                #ENDIF
                {
                    "name": "Status",
                    "value": "**${report.reportStatus}**",
                    "inline": true
                },
                {
                    "name": "Location",
                    "value": "${report.location.isPresent() ? utils:parseLocation(report.serverName, report.location.get()) : 'Unknown'}",
                    "inline": true
                }
            ]
        }
    ]
}
````

The above shows the default template for a rejection of a report. This is a fairly good example because it contains most of what you might need. In theory you can completely overwrite the contents of this file as long as it will result in a valid JSON request body for the Discord Webhook API.

### JSON

Notice how most of the template is just a JSON body. The entirety of the body is constructed so it will be parsed into a valid request body that can be send to the discord webhook.\
I won't go into detail on the JSON structure because this is defined by the [Discord webhook API](https://discord.com/developers/docs/resources/webhook#execute-webhook).\
In the default templates I always use [Discord Embeds](https://discord.com/developers/docs/resources/channel#embed-object)

### JEXL

Before the above gets send to discord it gets parsed by the S++ Discord plugin.  It allows you to use JEXL expressions within the template.\
Everything inside the template between **"${}"** signs gets parsed as a JEXL expression.

**Context**

```javascript
// Context:
// report: IReport => https://github.com/garagepoort/StaffPlusPlus/blob/master/StaffPlusAPI/src/main/java/net/shortninja/staffplus/unordered/IReport.java
// timestamp: String
```

At the top of every template you will notice the context definition. This describes what properties are placed on the JEXL context for this template. A timestamp will always be provided.\
Besides, the timestamp you also get an object of type IReport. The type definition can be viewed on [Github](https://github.com/garagepoort/staffplusplus-discord). Now that we know what properties we can access, we can write a JEXL expressions like this:

```javascript
"value": "${report.reporterName}\n[${report.reporterUuid}]"
```

In the above string literal we have 2 jexl expressions:

* ${report.reporterName}
* ${report.reporterUuid}

After the template is parsed and the Discord API is called your channel will receive a message looking like this:

![](/files/-MTuHkrBz7eX2GKPPqwK)

## Conditional JSON

In the example template you will notice there is a section surrounded by an if statement.

````javascript
#IF report.closeReason != null
{
    "name": "Reason for closing",
    "value": "```${report.closeReason}```",
    "inline": false
},
#ENDIF
````

You can use the **#IF \<jexl expression> #ENDIF** syntax to allow certain parts of the JSON body to be in- or excluded. In this case only a closing reason section will be send to discord if there is actually a closing reason inside the IReport object.


# Trello Integration

Staff++supports Trello integration. Whenever reports are created, or they change status it can by synchronized with Trello. However this a one way synchronization, if you change the cards created by Staff++ in Trello it will not be updated in game.

Install the Staff++ Trello Integration plugin: <https://www.spigotmc.org/resources/staff-trello-integration.84552/>

## Configuration

```yaml
StaffPlusPlusTrello:
    reports:
        # Your api key
        apiKey: ""
        # Your user token
        userToken: ""
        # The id of your board, can be found in the url
        boardId: ""

        # The list names in which the cards should be placed when moved to this status
        openListName: "open"
        rejectedListName: "rejected"
        acceptedListName: "accepted"
        resolvedListName: "resolved"
```

### Obtaining the API key

I recommend creating a new Trello user purely for the purpose of the Staff++ integration, but you can also use your existing user.

Log in into Trello with the user you want to use for the integration. The user needs access to the board where the reports should be added on.

Go to: <https://trello.com/app-key> \
&#x20;Your api Key is displayed here.

Add your API key to the config file.

### Obtaining the User Token

Make sure you first obtain the API key as explained in the previous section\
&#x20;Visit the following url: (Change {your-api-key} with the API key)

<https://trello.com/1/authorize?expiration=never&name=StaffPlusPlusToken&scope=read,write&response_type=token&key={your-api-key}>

This page gives you the user token. ***Keep this token a secret as anyone with this token can access your board.***

Add your User Token to the config file.

### Obtaining the board ID

The board ID can be found inside the URL when navigating to your board\
&#x20;For example: <https://trello.com/b/WkCJeuKv/staffplusplus>\
&#x20;The board ID in this case is `WkCJeuKv`

Add your Board ID to the config file.

### The lists

Lastly map the Staff++ statuses to the correct Lists on your Trello board. The match is done based on the List name and it must be an exact match. If the plugin can't find any of the configured lists on the board, an error message will be thrown at startup of the plugin

## Example:

![](/files/-MPQyxDKOg-Ui3PAD1fs)


# PAPI expansion

Staff++ integrates with the Placeholder API plugin.\
\
You need to install the papi expansion by downloading it from the papi ecloud:\
[https://api.extendedclip.com/expansions/staffplusplus/versions/staffplusplus-130/](https://api.extendedclip.com/expansions/staffplusplus/)

{% hint style="info" %}
For placeholders with filters: filters are always prefixed with **\_@** and should be placed at the **end** of the placeholder definition
{% endhint %}

{% hint style="info" %}
You can nest other placeholders be wrapping them in `${` and `}$` characters.\
Example: `warnings_score_${player_name}$`
{% endhint %}

## Configuration

All placeholders are cached to make sure we don't query the database too much. This depends on how the placeholders is used. The default cache is 30 seconds but can be configured through the config.yml of the PlaceholderAPI plugin.

**config.yml**

```yaml
expansions:
  staffplusplus:
    # How often the placeholder cache should be cleared in milliseconds
    cache-clear-interval: 30000
    # exclude certain placeholders for the caching mechanism.
    cache-disabled-placeholders:
      - session
      - player_count
```

#### excluding from caching

Some placeholders are actually safe to use without hitting the database too much. All session variables can be safely excluded from caching. You can exclude other placeholders as well.

## Players

| Placeholder                  | Description                                          |
| ---------------------------- | ---------------------------------------------------- |
| staffplusplus\_player\_count | Count of all players that are not currently vanished |

## Staff

| Placeholder                             | Description                                           |
| --------------------------------------- | ----------------------------------------------------- |
| staffplusplus\_staff\_members\_online   | amount of staff members online on this server.        |
| staffplusplus\_staff\_members\_in\_mode | amount of staff members in staff mode on this server. |
| staffplusplus\_staff\_members\_vanished | amount of staff members currently vanished            |

### Session

| Placeholder                                                                                     | Description                                                                                                |
| ----------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| staffplusplus\_session\_muted\_@player=\<playername>                                            | Returns true/false indicating of the player is muted or not                                                |
| staffplusplus\_session\_vanished\_@player=\<playername>                                         | Returns true/false indicating of the player is vanished or not                                             |
| staffplusplus\_session\_frozen\_@player=\<playername>                                           | Returns true/false indicating of the player is frozen or not                                               |
| staffplusplus\_session\_inStaffMode\_@player=\<playername>                                      | Returns true/false indicating of the player is in staff mode or not                                        |
| staffplusplus\_session\_activestaffchatchannel\_@player=\<playername>\_@default=\<defaultValue> | Return the active staff chat channel of the given player. Or if no active channel return the default value |

## Bans

| Placeholder                                                             | description                                                     | Parameters                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| ----------------------------------------------------------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| staffplusplus\_bans\_all\_count                                         | Returns total amount of bans in the system                      |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| staffplusplus\_bans\_active\_count                                      | <p></p><p>Returns total amount of active bans in the system</p> |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| staffplusplus\_bans\_newest\_*<*&#x69;nde&#x78;*>\_<*&#x66;iel&#x64;*>* | returns active bans from newest to oldest at the given index    | <p><strong>index</strong>: which ban do you want to retrieve. For example 1 will return the newest ban. 2 will return the one issued before that. And so on.</p><p></p><p><strong>field:</strong> Which field you want to retrieve from the issued ban. (Casing is important here)</p><p></p><p>Possible values:</p><ul><li>id</li><li>reason</li><li>targetName</li><li>targetUuid</li><li>issuerName</li><li>issuerUuid</li><li>unbannedByName</li><li>unbannedByUuid</li><li>unbanReason</li><li>humanReadableDuration</li><li>serverName</li></ul> |

## Mutes

| Placeholder                                                              | description                                                      | Parameters                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| ------------------------------------------------------------------------ | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| staffplusplus\_mutes\_all\_count                                         | Returns total amount of mutes in the system                      |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| staffplusplus\_mutes\_active\_count                                      | <p></p><p>Returns total amount of active mutes in the system</p> |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| staffplusplus\_mutes\_newest\_*<*&#x69;nde&#x78;*>\_<*&#x66;iel&#x64;*>* | returns active mutes from newest to oldest at the given index    | <p><strong>index</strong>: which mute do you want to retrieve. For example 1 will return the newest mute. 2 will return the one issued before that. And so on.</p><p></p><p><strong>field:</strong> Which field you want to retrieve from the issued mute. (Casing is important here)</p><p></p><p>Possible values:</p><ul><li>id</li><li>reason</li><li>targetName</li><li>targetUuid</li><li>issuerName</li><li>issuerUuid</li><li>unmutedByName</li><li>unmutedByUuid</li><li>unmuteReason</li><li>humanReadableDuration</li><li>serverName</li></ul> |

## Warnings

| Placeholder                                                                             | Description                                                                                                            | parameters                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| --------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| staffplusplus\_warnings\_score\_\<playername>                                           | Get the total warning score of a player                                                                                | **playername:** The name of the player for which we want to get the score                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| staffplusplus\_warnings\_count\_\<filters>                                              | Retrieve the count of all warnings                                                                                     | <p><strong>Filter:</strong> </p><p>Multiple filters can be applied to narrow down the retrieved warnings count</p><p></p><p><a href="/pages/-MbL0pyBvfFDTUtjbBsx#possible-filter-values">Possible filters values</a></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| staffplusplus\_warnings\_newest\_*<*&#x69;nde&#x78;*>\_<*&#x66;iel&#x64;*>\_*\<filters> | returns warnings newest to oldest at the given index. Using filters you can further narrow down the warnings retrieved | <p></p><p><strong>index</strong>: which mute do you want to retrieve. For example 1 will return the newest mute. 2 will return the one issued before that. And so on.</p><p></p><p><strong>field:</strong> Which field you want to retrieve from the issued mute. (Casing is important here)</p><p></p><p>Possible values:</p><ul><li>id</li><li>reason</li><li>targetName</li><li>targetUuid</li><li>issuerName</li><li>issuerUuid</li><li>score</li><li>severity</li><li>serverName</li></ul><p><strong>Filter:</strong> </p><p>Multiple filters can be applied to narrow down the retrieved warnings count</p><p></p><p><a href="/pages/-MbL0pyBvfFDTUtjbBsx#possible-filter-values">Possible filters values</a></p> |

#### **Possible filter values:**

| Filter     | Description                                                                                     | Example                                                  |
| ---------- | ----------------------------------------------------------------------------------------------- | -------------------------------------------------------- |
| severity   | A comma separated list of all included severities as defined in the staff++ config              | staffplusplus\_warnings\_count\_@severity=MAJOR,CRITICAL |
| period     | How far back should we go looking for warnings. Possible values. day, week, month, year         | staffplusplus\_warnings\_count\_@period=week             |
| reason     | Only shows warnings given for a specific reason                                                 | staffplusplus\_warnings\_count\_@reason=HACKING          |
| expired    | Boolean indicating if we should include [expired warnings](/features/warnings/warning-workflow) | staffplusplus\_warnings\_count\_@expired=false           |
| issuerName | Filter warnings based on the name of the staff member that issued the warnings                  | staffplusplus\_warnings\_count\_@issuerName=myman        |
| targetName | Filter warnings based on the name of the player that got warned                                 | staffplusplus\_warnings\_count\_@targetName=myman        |
| server     | Filter warnings based on the server they were issued on.                                        | staffplusplus\_warnings\_count\_@server=MyUniqueServer   |

## Reports

| Placeholder                                                                            | Description                                                                                                            | parameters                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| staffplusplus\_reports\_count\_\<filters>                                              | Retrieve the count of all reports                                                                                      | <p><strong>Filter:</strong> </p><p>Multiple filters can be applied to narrow down the retrieved warnings count</p><p></p><p><a href="/pages/-MbL0pyBvfFDTUtjbBsx#possible-filter-values">Possible filters values</a></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| staffplusplus\_reports\_newest\_*<*&#x69;nde&#x78;*>\_<*&#x66;iel&#x64;*>\_*\<filters> | returns warnings newest to oldest at the given index. Using filters you can further narrow down the warnings retrieved | <p></p><p><strong>index</strong>: which mute do you want to retrieve. For example 1 will return the newest mute. 2 will return the one issued before that. And so on.</p><p></p><p><strong>field:</strong> Which field you want to retrieve from the issued mute. (Casing is important here)</p><p></p><p>Possible values:</p><ul><li>id</li><li>reason</li><li>targetName</li><li>targetUuid</li><li>issuerName</li><li>issuerUuid</li><li>score</li><li>severity</li><li>serverName</li></ul><p><strong>Filter:</strong> </p><p>Multiple filters can be applied to narrow down the retrieved warnings count</p><p></p><p><a href="/pages/-MbL0pyBvfFDTUtjbBsx#possible-filter-values">Possible filters values</a></p> |

#### **Possible filter values:**

| Filter   | Description                                                                            | Example                                                              |
| -------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| status   | A comma separated list of all statuses on which we should search                       | staffplusplus\_reports\_count\_@statu&#x73;*=*&#x49;N\_PROGRESS,OPEN |
| period   | How far back should we go looking for reports. Possible values. day, week, month, year | staffplusplus\_reports\_count\_@period=week                          |
| type     | Report type as defined in the config                                                   | staffplusplus\_reports\_count\_@type=HACKING                         |
| reporter | Find all reports create by the given reportName                                        | staffplusplus\_reports\_count\_@reporter=myman                       |
| assignee | Filter all reports assigned to staff member                                            | staffplusplus\_reports\_count\_@assignee=myman                       |
| culprit  | Filter reports for which the given is reported                                         | staffplusplus\_reports\_count\_@culprit=myman                        |
| server   | Filter warnings based on the server they were issued on.                               | staffplusplus\_reports\_count\_@server=MyUniqueServer                |


# PAPI Examples

## Scoreboard

Using a scoreboard plugin you could create something like this:

![](/files/-MbhWQduKt2me89U9yow)

A scoreboard showing the reports currently assigned to you.\
Using following configuration:

```
'1: %staffplusplus_reports_newest_1_reporterName_@assignee=${player_name}$_@status=IN_PROGRESS% | %staffplusplus_reports_newest_1_reason_@assignee=${player_name}$_@status=IN_PROGRESS%'
'2: %staffplusplus_reports_newest_2_reporterName_@assignee=${player_name}$_@status=IN_PROGRESS% | %staffplusplus_reports_newest_2_reason_@assignee=${player_name}$_@status=IN_PROGRESS%'
'3: %staffplusplus_reports_newest_3_reporterName_@assignee=${player_name}$_@status=IN_PROGRESS% | %staffplusplus_reports_newest_3_reason_@assignee=${player_name}$_@status=IN_PROGRESS%'
'4: %staffplusplus_reports_newest_4_reporterName_@assignee=${player_name}$_@status=IN_PROGRESS% | %staffplusplus_reports_newest_4_reason_@assignee=${player_name}$_@status=IN_PROGRESS%'
'5: %staffplusplus_reports_newest_5_reporterName_@assignee=${player_name}$_@status=IN_PROGRESS% | %staffplusplus_reports_newest_5_reason_@assignee=${player_name}$_@status=IN_PROGRESS%'
```

## Animated Scoreboard

Using the animated scoreboard. Example by **Hunter\_**

![](/files/-MkgNfGeS-Q17vSWFkh4)


# Staff+ migration guide

## Steps:

* Download your staffplusplus version from Spigot: <https://www.spigotmc.org/resources/staff.83562/history>
* Replace the Old Staff+.jar with the new Staff++ jar.
* A new directory StaffPlusPlus will be created.
* In the config file change storage type from `flatfile` to `sqlite` or `mysql`:

```yaml
storage:
  #Type is how it will store either a sqlite or mysql
  type: 'sqlite'
```

Staff++ dropped support for flatfile storage. We now support MySql or Sqlite. We do not yet support a migration from flatfile to the SQL database. **This means you will lose your previous reports/warning should you have them.** This is a one time loss and everything from this point out will always be gracefully migrated.

* All other properties should be migrated automatically if you are using the latest version of Staff++.
* Start up the server and see if everything runs.

Should you still encounter errors, compare your config with the [default configuration file](https://github.com/garagepoort/StaffPlusPlus/blob/master/StaffPlusCore/src/main/resources/config.yml).

Head over to the [Quick Start guide](/general-information/quick-start) to setup Staff++


# Migrating to >=V1.16.43

This is also the migration guide for 1.12.23, 1.13.38, 1.14.36, 1.15.37

This release focuses on adding full support for a multi server setup.\
Typically this includes having a bungee network setup and a hub server redirecting players to the different MC servers.

This was already possible by connecting every server instance running Staff++ to the same MySQL database. But this was never really supported and having this setup might have caused some bugs with certain features.

### Step 1: shutdown

Make sure every staff member has **exited staff mode.** Shut down the server!\
Replace the old Staff++ jar with the new one. Start the server up so that the configuration file can be generated. After successful start up shut the server down again so we can start configuration.

### Step 2: Server name

#### server-name

Search for the property: `server-name` inside the configuration file.\
The server name should be unique for this server. If you have a multi-server setup every server running Staff++ must configure this with a different name. **If you are running a minecraft server network make sure to give this property the same name as the server name used by the network.**

{% hint style="info" %}
I recommend keeping the server-name property alphanumeric. Underscore, dashes and spaces can be used.
{% endhint %}

### Step 3: Staff mode

This release has recoded part of the staff mode system. This has little to no impact on the functionality.\
However we now do support persisting staff-mode when exiting and reentering the server.

```yaml
staff-mode:
  # Whether or not staff mode will be enabled for staff when they login.
  enable-on-login: false

  # Whether or not staff mode will be disabled for staff when they logout. If false the staff mode will be reenabled on login.
  disable-on-logout: false
```

If you want to keep the previous behavior where Staff++ would automatically exit staff mode when you exit the server, change the property `disable-on-logout` to **true**.

{% hint style="info" %}
If you want to enable the below mentioned server synchronization for staff-mode. Both these properties must be **false.**
{% endhint %}

## Multi server setup

{% hint style="info" %}
If you are only using SQLITE database setup you are done here.\
You won't be able to use any of the below features. Should you have a multi-server setup and want to use any of the synchronization features, you will need to use an MySQL database.
{% endhint %}

### Step 4: Server synchronization

#### server-sync-module

Look for the following section in the configuration file.

```yaml
server-sync-module:
    vanish-sync: false
    staffmode-sync: false
    ban-sync: false
    report-sync: false
    warning-sync: false
    mute-sync: false
    kick-sync: false
```

For more information on these properties check the [server-synchronization documentation](/general-information/multi-server-setup) page.\
However if you were already using a multi-server setup with a shared MySQL database, you will probably want to set all these properties to **true.** This will give you the same behavior as before.

{% hint style="danger" %}
All warnings/bans/kicks/mutes/reports created before migrating to this version will always be visible on all servers, disregarding of the above properties. This is due to the fact there is no way the system can know on what server they got generated. Everything generated after switching to this release will work as intended.
{% endhint %}


# Upgrading Discord Integration to 1.16.51

{% hint style="info" %}
If you are not using customized templates, just remove the **discordtemplates** folder and start up the server
{% endhint %}

### If you are using Customized templates:

Backup your **discordtemplates** folder. Delete the **discordtemplates** folder and restart the server.\
The discordtemplates folder will get generated with a folder **default** inside of it.\
From here read the [customized templates guide](/integrations/discord-integration/customize-discord-templates) again. \
\
It is best to start over again from the newly generated templates. Check your backed up templates and compare them with your new template pack. Unfortunately there is no easy way to migrate them other than to compare and adjust. Sorry about the inconvenience caused.\
\
But this will be the only and last time we will break the S++ API. A clean up was desperately needed. And from this point forward your customized templates will always keep working!


# API guide

{% hint style="warning" %}
This API is only available from Staff++ versions:\
1.16.51, 1.15.44, 1.14.43, 1.13.45, 1.12.30
{% endhint %}

### Introduction

Staff++ provides an API to listen to different types of events that Staff++ generates.\
This API is in its very early stages and will be expanded upon request.

### Maven repository

```markup
<repository>
    <id>staffplusplus</id>
    <url>https://repo.repsy.io/mvn/garagepoort/staffplusplus</url>
</repository>

<dependencies>
    <dependency>
        <groupId>net.shortninja.staffplus</groupId>
        <artifactId>staffplusplus-api</artifactId>
        <version>1.1.2</version>
    </dependency>
</dependencies>
```

```markup
RegisteredServiceProvider<IStaffPlus> provider = Bukkit.getServicesManager().getRegistration(IStaffPlus.class);
if (provider != null) {
    IStaffPlus staffPlusApi = provider.getProvider();
}
```

The full API can be found here: <https://github.com/garagepoort/staffplusplus-api>


# Staff++

## Introduction

This plugin was originally developed By ShortNinja. After ShortNinja's passing Qball took over the support and further development.

I created this repository as an attempt to add new features to StaffPlus and revitalize it. The first difference from StaffPlus is that I dropped support for the older versions, this will hopefully allow me to add new features to the newer version easily and help in bug fixing more targeted. If you are using older version of Minecraft please refer to QBall's [repository](https://github.com/Qballl/StaffPlus)

I changed some of the core features:

* Support for MySQL/SQLITE Database integration
* BungeeCord integration for Staff Chat
* New and improved reporting system
* New and improved warning and punishment system
* Discord integration for reports & warning.

Overall I am trying to fix a lot of the existing bugs and am cleaning up the code. Hopefully this plugin can be a good successor to ShortNinja's original plugin.


# Quick start

## Installation

Download the latest version from the Spigot page. <https://www.spigotmc.org/resources/staff.83562/history> You should download the version corresponding to your MC version.

Place the jar file inside the plugins folder of your server and start your server. This will create the necessary files in the `plugins/StaffPlus` folder.

## Basic configuration

Open the `config.yml` file located in the `plugins/StaffPlus` folder. If you mess up the config file you can always take a look at the [default file](https://github.com/garagepoort/StaffPlusPlus/blob/master/StaffPlusCore/src/main/resources/config.yml).

#### main-world

Search for the property: `main-world` inside the configuration file. This should be the name of the main world. Meaning the world folder name which contains the player data files. By default in Minecraft this is just the "world" folder. So if you have a regular setup just leave the default setting. If for some reason your world location folder has a different name, you can change it here.&#x20;

#### server-name

Search for the property: `server-name` inside the configuration file.\
The server name should be unique for this server. If you have a multi-server setup every server running Staff++ must configure this with a different name. **If you are running a minecraft server network make sure to give this property the same name as the server name used by the network.**

{% hint style="warning" %}
I recommend keeping the server-name property alphanumeric. Underscore, dashes and spaces can be used.
{% endhint %}

#### modules

The config file contains the command and permission configuration. It also contains the different modules configuration. Different functionalities of Staff++ are configured as separate modules which can be enabled or disabled.

These are the modules:

| module             | Description                                                                                               | Enabled by default |
| ------------------ | --------------------------------------------------------------------------------------------------------- | ------------------ |
| alerts-module      | Enable an alerting system. This can notify staff members in-game when certain events transpire.           | true               |
| alt-detect-module  | Enable an alt account detection system.                                                                   | false              |
| ban-module         | Enable StaffMembers to /ban or /tempban players.                                                          | true               |
| broadcast-module   | Enable StaffMembers broadcast messages.                                                                   | true               |
| chat-module        | Enable StaffMembers to slow or clear chat. Allow blacklisting certain words                               | true               |
| protect-module     | Enable StaffMembers to protect players or areas from damage.                                              | true               |
| reports-module     | Allow players to create reports. Staff members can pickup and resolve the reports.                        | true               |
| staff-chat-module  | Enable staffchat                                                                                          | true               |
| trace-module       | Enable Staff members to start a trace on a player. This records actions the specified player is executing | true               |
| vanish-module      | Allow staffmembers to vanish                                                                              | true               |
| warns-module       | Allow Staff members to warn players.                                                                      | true               |
| infractions-module | Allows to open an overview menu showing all infractions a player has                                      | true               |

## Database configuration

We support 2 types of database `sqlite` and `mysql`. By default `sqlite` is configured. If you want to use a mysql database, change this part of the configuration file:

```yaml
storage:
  type: 'mysql'
  mysql:
    host: 'localhost'
    user: 'root'
    database: 'root'
    password: 'mypass'
    port: 3306
```

## Adding players as Staff Members

There is not one command to add players as Staff members. Everything in Staff++ is permission based, if you have the correct permissions you can access the Staff++ commands. If you are OP you can access all commands by default.

All permissions are listed [here](https://github.com/garagepoort/StaffPlusPlus/wiki/Permissions). This means you need some permission plugin to enable staff mode for your staff members. A commonly used permissions plugins is [Luckperms](https://www.spigotmc.org/resources/luckperms.28140/).

Once you have installed the permission plugin you can assign your player the correct permissions. All permissions in Staff++ start with a `staff.` prefix. Luckperms supports wildcards so you could give your player the permission `staff.*` and it will enable all Staff++ permissions for that player.


# Reload Configuration

Staff++ re-enabled to "reload" command. The reload command allows reloading the configuration file. However the reload command is still in an experimental phase. So keep below warnings in mind when executing it.

## Warnings

When executing the reload, player sessions won't be reverted. This means that for example if we disable the freeze command and reload the configuration the freeze command will no longer work. **But players that were frozen before reloading, will remain frozen.**

When we are changing configuration impacting "Staff Mode", it's preferable that staff members exit staff mode before reloading. Staff members that are in staff mode won't see all the config changes made until they exit and re-enter.

Changing the database connection parameters and reloading does not reset the database connection. To do so a restart is still required.

## Known issues

* Autocompletion of the commands does not change when reloading. The commands do no longer work but it's possible players will still see the commands being autocompleted.


# Multi Server Setup

{% hint style="warning" %}
You need a shared **MySQL** database to use this feature.
{% endhint %}

Staff++ added the ability to synchronize multiple features over a multiple servers.\
This guide will explain you how to easily set this up.

### Step 1: installation

Install Staff++ on every server that you want to be synced. **No** plugin is needed for the bungee server.

### Step 2: Database

Configure the database connection inside the configuration file.

```yaml
storage:
  type: 'mysql'
  mysql:
    host: 'localhost'
    user: 'root'
    database: 'root'
    password: 'mypass'
    port: 3306
```

You **must** configure **mysql** to synchronize the servers.\
Every Staff++ instance must be configured to use the same database

### Step 3: Server name

#### server-name

Search for the property: `server-name` inside the configuration file.\
The server name should be unique for every server. Every server running Staff++ must configure this with a different name. **If you are running a minecraft server network make sure to give this property the same name as the server name used by the network.**

{% hint style="info" %}
I recommend keeping the server-name property alphanumeric. Underscore, dashes and spaces can be used.
{% endhint %}

### Step 4: Server synchronization config

#### server-sync-module

Look for the following section in the configuration file.

```yaml
server-sync-module:
    vanish-sync: false
    staffmode-sync: false
    ban-sync: false
    report-sync: false
    warning-sync: false
    mute-sync: false
    kick-sync: false
```

#### All these properties can be disabled and enabled at any time without impacting previous data. However a restart of the server is required after changing these.

#### vanish-sync

Allows a player to remain vanished when switching between servers. No join and leave message will be displayed.

#### staffmode-sync

Allows a staff member to keep his staff mode when switching between servers.&#x20;

{% hint style="warning" %}
To use this you must set the properties `enable-on-login` and `disable-on-logout` underneath the **staff-mode** section, to **false**
{% endhint %}

#### ban-sync

When enabled players will get banned on every server having staff++ installed. If disabled the player is only banned on the server where the ban was initiated.\
This also impacts the Staff GUI. When enabled the staff GUI shows all banned players from all servers. If disabled you only see the banned players on the current server.&#x20;

#### report-sync

When enabled, the GUI reports shows all reports a player has made on whatever server the report was created. The infractions GUI will also include players who got reported on other servers

#### warning-sync

When enabled warning thresholds will be calculated based on player warnings from across all servers.\
If disabled only warnings from the current server are taken into account.\
\
The list of warnings retrieved shows either all warnings from a player or only the warnings issued from the current server.

#### mute-sync

When enabled players will get muted on every server having staff++ installed. If disabled the player is only muted on the server where the mute was initiated.\
This also impacts the Staff GUI. When enabled the staff GUI shows all muted players from all servers. If disabled you only see the muted players on the current server.&#x20;

#### kick-sync

This impacts the infractions Staff GUI. When enabled the staff GUI shows all kicks a player has received from all servers. If disabled you only see the kicks the player has received from the current server.&#x20;


# General Configuration

```yaml

# The name of the server. This can be anything you want but it must be unique and once chosen it shouldn't change anymore.
server-name: "MyUniqueServerName"
# The name of the main world. Meaning the world folder name which contains the player data files.
main-world: "world"
# The format in which all dates will be displayed inside the GUIs.
# All Java date time formats can be used
timestamp-format: 'dd/MM/yyyy-HH:mm:ss'

# The language file that will be referred to for messages.
# Current available languages are: lang_en, lang_sv, lang_de, lang_nl, lang_es, lang_hr, lang_no, and lang_fr.
# If you would like to translate Staff++, please message me on Spigot!
lang: "lang_en"

# Chooses the authentication provider. Default "noop", no authentication will be done.
# AuthMe is supported. When the provider is authMe, Staff++ will enforce that the user is authenticated through AuthMe before being able to execute the commands.
authentication:
    provider: noop

# Commands that staff will not be allowed to use at all.
# Must have "permissions.block" permission to take effect.
# Leave blank to disable.
blocked-commands: "/example1, /example2, /example3"

# Commands that staff will not be allowed to use while in staff mode.
# Must have "permissions.block" permission to take effect.
# Leave blank to disable.
blocked-mode-commands: "/example1, /example2, /example3"

# The default color of glass for the side of GUIs. Just a cosmetic thing that staff members can change.
glass-color: 0

# The title of the glass color chooser GUI.
glass-title: "&bChoose GUI glass color"

# Enable offline player mode
# report-bypass & warn-bypass does not work for offline players
offline-players-mode: true
```

#### server-name

Search for the property: `server-name` inside the configuration file.\
The server name should be unique for this server. If you have a multi-server setup every server running Staff++ must configure this with a different name.

{% hint style="warning" %}
I recommend keeping the server-name property alphanumeric. Underscore, dashes and spaces can be used.
{% endhint %}

#### main-world

Search for the property: `main-world` inside the configuration file. This should be the name of the main world. Meaning the world folder name which contains the player data files. By default in Minecraft this is just the "world" folder. So if you have a regular setup just leave the default setting. If for some reason your world location folder has a different name, you can change it here.&#x20;

#### timestamp-format

Configure the way you want dates and times to be displayed inside the in-game GUI screen.\
You can use the java datetime format options.\
Examples:

| **format**            | Example                |
| --------------------- | ---------------------- |
| dd/MM/yyyy HH:mm:ss   | 31/12/2020 15:23:10    |
| dd/MM/yyyy hh:mm:ss a | 31/12/2020 03:23:10 PM |
| MM-dd-yyyy hh:mm a    | 12-31-2020 03:23 PM    |


# Commands

## Overview

| Command                                          | Description                                                                                                                                                | Available Arguments                                                                | Example usages                                                              |                                                                                            |
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `/alerts`                                        | Subscribe/Unsubscribe yourself to be notified when certain events happen in Staff++. Currently following events are supported: XRAY, MENTION, NAME\_CHANGE |                                                                                    | `/alerts player1 NAME_CHANGE`                                               |                                                                                            |
| \`/altwhitelist \[add\\                          | remove] \[playername1] \[playername2]\`                                                                                                                    | Add remove players from the alt account detection whitelist                        |                                                                             | `/altwhitelist add player1 player2` `/altwhitelist remove player1 player2`                 |
| `/altwhitelist [list] [page?]`                   | List all whitelisted items from alt account detection whitelist.                                                                                           |                                                                                    | `/altwhitelist list` `/altwhitelist list 3`                                 |                                                                                            |
| `/ban [playername] [reason]`                     | Permanently ban a player                                                                                                                                   |                                                                                    | `/ban player1 I don't like him`                                             |                                                                                            |
| `/tempban [playername] [amount] [unit] [reason]` | Temporary ban a player the given duration. See [banning](/master/features/banning) for more info                                                           |                                                                                    | `/tempban player1 1 WEEK I don't like him`                                  |                                                                                            |
| `/unban [playername] [reason]`                   | Unban a player from the server                                                                                                                             |                                                                                    | `/unban player1 I like him again`                                           |                                                                                            |
| `/broadcast [server] [message]`                  | Send a message to all players on all servers. Display's the message using a "broadcast" prefix.                                                            |                                                                                    | `/broadcast ALL This is my message`                                         |                                                                                            |
| `/chat`                                          | Manage in game chat. Disable/Enable chat completely. Clear the chat history. Enable slow chat                                                              |                                                                                    | `/chat clear` `/chat toggle` `/chat slow`                                   |                                                                                            |
| `/clear [player]`                                | Clear the given player's inventory                                                                                                                         | `-T` `-H` `-D`                                                                     | `/clear player1`                                                            |                                                                                            |
| `/cps`                                           | Run a clicks per second test on a player                                                                                                                   |                                                                                    | `/cps player1`                                                              |                                                                                            |
| `/examine`                                       | Opens the examine GUI. The GUI can be used to check a players IP address, check his game mode, etc.                                                        |                                                                                    | `/examine player1`                                                          |                                                                                            |
| `/follow [player]`                               | Start following a player. This will attach you to the player and follow him where he goes                                                                  |                                                                                    | `/follow player1`                                                           |                                                                                            |
| `/freeze [player]`                               | Freezes/unfreezes a player. Either you specify enabled/disabled or you just freeze and freeze mode will be toggled                                         | `-T` `-S` `-H` `-D`                                                                | `/freeze player1` `/freeze enabled player1` `/freeze player1 -Tspawn -S`    |                                                                                            |
| `/infractions [player]`                          | Show the history of all the infractions a players has                                                                                                      |                                                                                    | `/infractions player1`                                                      |                                                                                            |
| `/notes`                                         | Add/clear/list notes on different players.                                                                                                                 |                                                                                    | `/notes get player1` `/notes clear player1` `/notes player1 This is a note` |                                                                                            |
| `/personnel`                                     | Lists online staff members                                                                                                                                 |                                                                                    | `/personnel`                                                                |                                                                                            |
| \`/protectarea \[create\\                        | delete] \[size?] \[name]\`                                                                                                                                 | Create or deletes a protected area. More info on the protection documentation page |                                                                             | `/protectarea create 30 My new protected area` `/protectarea delete My new protected area` |
| `/protectplayer [playername]`                    | Toggles damage protection on/off for the player                                                                                                            |                                                                                    | `/protectplayer player1`                                                    |                                                                                            |
| `/report [message]`                              | Command to report something. Used when the player wants to report something but doesn't know who was the culprit or there was no culprit                   |                                                                                    | `/report Some reason`                                                       |                                                                                            |
| `/reportPlayer [player] [message]`               | Command for players to report another player                                                                                                               |                                                                                    | `/reportPlayer player1 For some reason`                                     |                                                                                            |
| `/kick [player] [reason]`                        | Kick a player and provide a reason for kicking                                                                                                             |                                                                                    | `/kick player1 Annoying`                                                    |                                                                                            |
| `/my-reports`                                    | The command for opening the my reports GUI                                                                                                                 |                                                                                    | `/my-reports`                                                               |                                                                                            |
| `/reports`                                       | Command used by staff to manage reports: list current reports or remove all player reports                                                                 |                                                                                    | `/reports get player1`                                                      |                                                                                            |
| `/manage-reports`                                | Command used by staff to open the manage reports GUI                                                                                                       |                                                                                    | `/manage-reports`                                                           |                                                                                            |
| `/mute [player] [reason]`                        | Mute a player permanently                                                                                                                                  |                                                                                    | `/mute player1 My reason for muting here`                                   |                                                                                            |
| `/tempmute [player] [amount] [unit] [reason]`    | Temporarily mute a player.                                                                                                                                 |                                                                                    | `/tempmute player1 1 HOUR No spamming`                                      |                                                                                            |
| `/unmute [player] [reason]`                      | Unmute a player                                                                                                                                            |                                                                                    | `/unmute player1 Reason for unmuting here`                                  |                                                                                            |
| `/revive [player]`                               | Revive let's you restore a player's inventory after a players has died.                                                                                    | `-T` `-S` `-H`                                                                     | `/revive player1`                                                           |                                                                                            |
| `/sc [message?]`                                 | Enables/disables staffchat. All messages send in staff chat mode will only be readable by other staff members                                              |                                                                                    | `/sc`                                                                       |                                                                                            |
| `sc-mute`                                        | Mutes/unmutes staffchat                                                                                                                                    |                                                                                    | `/sc-mute`                                                                  |                                                                                            |
| `/staff`                                         | Turns on/off Staff mode for the current user. Only available if the user has the correct permissions.                                                      |                                                                                    | `/staff`                                                                    |                                                                                            |
| `/sfly`                                          | Toggles on/off fly when in staff mode                                                                                                                      |                                                                                    | `/sfly`                                                                     |                                                                                            |
| `/strip [player]`                                | Takes off the player's armor and places it in his inventory. If there are no free spaces left in the player's inventory the armor is not taken off.        |                                                                                    | `/strip player1`                                                            |                                                                                            |
| `/teleportHere [player]`                         | Teleports a player to your location                                                                                                                        | `-S` `-H`                                                                          | `/teleportHere player1`                                                     |                                                                                            |
| `/teleportToLocation [player] [location]`        | Teleports a player to a given location. Location should be configured inside the configuration file                                                        | `-D` `-S` `-H`                                                                     | `/teleport player1 spawn`                                                   |                                                                                            |
| `/teleportToPlayer [player]`                     | Teleport yourself to the given player's location                                                                                                           |                                                                                    | `/teleportToPlayer player1`                                                 |                                                                                            |
| `/teleportBack [player]`                         | Teleport the given player back to his original location. This only works if that players has been teleported before.                                       | `-S` `-H`                                                                          | `/teleportBack player1`                                                     |                                                                                            |
| `/vanish`                                        | Toggle vanish on/off                                                                                                                                       |                                                                                    | `/vanish`                                                                   |                                                                                            |
| `Warnings`                                       |                                                                                                                                                            |                                                                                    | All warning commands listed [here](/master/features/warnings#commands)      |                                                                                            |

## Arguments

Staff++ supports an argument system which can be used to enhance the default commands. We list below the arguments we currently support. In the commands table you can see which commands can use which arguments

### -T Teleport

Teleport let's us enhance a command by teleporting the target to a predefined location. You can setup locations in the configuration file. See **Locations**

Example: `/freeze player1 -Tspawn`

Description: Teleports player1 to the predefined location "spawn" and immediately freezes him.

### -S Strip

-S does the same as the strip command: Takes off the player's armor and places it in his inventory. If there are no free spaces left in the player's inventory the armor is not taken off.

Example: `/freeze player1 -S`

Description: Freezes the player and strips his armor.

### -H Health

Sets the player's health to the given percentage.

Example: `/freeze player1 -H100`

Description: Freezes the player and gives the player full health.

### -D Delay a command

When provided with a base command. The command will be delayed until the player joins the server. This is useful when we want to for example clear the inventory of a player, but he's offline. With the -D argument we can still run the 'clear' command. It will not be executed immediately, but it will be executed the next time the player joins the server.

Example: `/clear player1 -D`

Description: Clear the players inventory the next time he joins the server


# Permissions

{% hint style="info" %}
All permission nodes can be custom configured inside the config.yml file
{% endhint %}

| name                       | default permission node              | Description                                                                                                                                                                                                         |
| -------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| alerts-alt-detect          | staff.alerts.alt-detects             | Permission for receiving alt detect alerts.                                                                                                                                                                         |
| alt-detect-bypass          | staff.staffplus.alt-detect-bypass    | Permission for allowing players to bypass being detect by alt account detection                                                                                                                                     |
| alt-detect-whitelist       | staff.staffplus.alt-detect-whitelist | Permission to add/remove players from the alt detection whitelist                                                                                                                                                   |
| banning/tempbanning        | staff.staffplus.ban                  | Permission for banning or temporarily banning a player                                                                                                                                                              |
| unban                      | staff.staffplus.unban                | Permission for unbanning a player                                                                                                                                                                                   |
| ban-bypass                 | staff.staffplus.ban-bypass           | Permission for bypassing being banned                                                                                                                                                                               |
| blacklist                  | staff.blacklist                      | Permission for bypassing the word blacklist.                                                                                                                                                                        |
| block                      | staff.block                          | Permission for blocking listed commands at "blocked-commands" and "blocked-mode-commands".                                                                                                                          |
| broadcast                  | staff.staffplus.broadcast            | Permission for sending broadcast messages                                                                                                                                                                           |
| chat-clear                 | staff.chat.clear                     | Permission for using  / chat clear .                                                                                                                                                                                |
| chat-slow                  | staff.chat.slow                      | Permission for using  / chat slow .                                                                                                                                                                                 |
| chat-toggle                | staff.chat.toggle                    | Permission for using  / chat toggle .                                                                                                                                                                               |
| compass                    | staff.compass                        | Permission for using the staff mode compass                                                                                                                                                                         |
| counter                    | staff.counter                        | Permission for the staff mode counter GUI                                                                                                                                                                           |
| counter-show-vanished      | staff.counter-show-vanished          | Permission to show if staff members are vanished in the counter GUI                                                                                                                                                 |
| cps                        | staff.cps                            | Permission for initializing clicks per second tests                                                                                                                                                                 |
| examine                    | staff.examine                        | Permission for using examine                                                                                                                                                                                        |
| examine-modify             | staff.examine.modify                 | Permission for editing inventories with examine.                                                                                                                                                                    |
| follow                     | staff.follow                         | Permission for using staff mode follow                                                                                                                                                                              |
| freeze                     | staff.freeze                         | Permission for using freeze.                                                                                                                                                                                        |
| freeze-bypass              | staff.freeze.bypass                  | Permission for bypassing freeze.                                                                                                                                                                                    |
| gui                        | staff.gui                            | Permission for the staff mode GUI hub                                                                                                                                                                               |
| infractions.view           | staff.infractions.view               | Permission to open the infractions GUI                                                                                                                                                                              |
| invClear                   | staff.staffplus.clearinv             | Permission for using the clear inventory config                                                                                                                                                                     |
| ipPerm                     | staff.staffplus.hideip               | Use this for players who's ip should not be shown in examine mode                                                                                                                                                   |
| lockdown                   | staff.lockdown                       | Permission for locking/unlocking the server.                                                                                                                                                                        |
| member                     | staff.member                         | Permission for being noted as a staff member in the staff list command and for login. This also excludes the player from being randomly teleported to!                                                              |
| mention                    | staff.alerts.mention                 | Permission for receiving mention alerts.                                                                                                                                                                            |
| mode                       | staff.mode                           | Permission for toggling staff mode.                                                                                                                                                                                 |
| muting/tempmuting a player | staff.staffplus.mute                 | Permission to mute/tempmute a player                                                                                                                                                                                |
| unmute                     | staff.staffplus.unmute               | Permission to unmute a player                                                                                                                                                                                       |
| mute-bypass                | staff.staffplus.mute-bypass          | Permission for bypassing being muted                                                                                                                                                                                |
| name-change                | staff.alerts.namechange              | Permission for receiving name change alerts.                                                                                                                                                                        |
| protect-area               | staff.staffplus.protect-area         | Permission for toggling protection over a certain area                                                                                                                                                              |
| protect-player             | staff.staffplus.protect-player       | Permission for toggling damage protection over a player                                                                                                                                                             |
| random-teleport            | staff.random-teleport                | Permission for using the staff mode random teleport                                                                                                                                                                 |
| report                     |                                      | Permissions listed [here](/master/features/reporting#report-permission)                                                                                                                                             |
| resetPass                  | staff.staffplus.resetpassword        | Permission for using the /resetPassword command                                                                                                                                                                     |
| revive                     | staff.revive                         | Permission for giving a player's previous inventory back.                                                                                                                                                           |
| staff-chat                 | staff.staffchat                      | Permission for using staff chat.                                                                                                                                                                                    |
| staffplus                  | staff.staffplus                      | Permission for using `/staffplus`                                                                                                                                                                                   |
| strip                      | staff.strip                          | Permission for using  `/strip` .                                                                                                                                                                                    |
| teleport-to-location       | staff.teleport-to-location           | Permission for teleporting a player to predefined locations.                                                                                                                                                        |
| teleport-to-player         | staff.teleport-to-player             | Permission for teleporting to a specific player.                                                                                                                                                                    |
| teleport-bypass            | staff.teleport-bypass                | Permission for bypassing teleport.                                                                                                                                                                                  |
| teleport-here              | staff.teleport-here                  | Permission for teleporting players to your location.                                                                                                                                                                |
| tickets                    | staff.tickets                        | Permission for managing tickets.                                                                                                                                                                                    |
| vanish-list                | staff.vanish.list                    | Permission for using  / v list .                                                                                                                                                                                    |
| vanish-total               | staff.vanish.total                   | Permission for using  / v total .                                                                                                                                                                                   |
| Warnings                   |                                      | Permissions listed [here](/master/features/warnings#permissions).                                                                                                                                                   |
| wild-card                  | staff.\*                             | Use this to give a player all Staff+ permissions.  Take note that this will NOT give the player the "block" permission. This also gives the player permission to toggle other player's vanish, staff mode, and etc. |
| xray                       | staff.alerts.xray                    | Permission for receiving xray alerts.                                                                                                                                                                               |


# Alerts

Staff++ kept the same alerting system that was already present in the old Staff+ plugin. Using this system staff members can subscribe to be notified when certain events happen. The notification is done through a message send in-game. If the staff member is not online he will miss the notification.

## Configuration

```yaml
# Requires "permissions.notify" permission.
alerts-module:
  # Whether or not staff will be notified when a user changes their name.
  name-notify: true

  # Whether or not staff will be notified when they are mentioned.
  mention-notify: true

  # Whether or not staff will be notified when the chat module detect phrases.
  chat-phrase-detection: true

  # The sound that is played to staff when notified.
  sound: ORB_PICKUP

  # Notifies staff when a player mines blocks listed in "blocks".
  xray-alerts:
    # Whether or not this module is enabled.
    enabled: true

    # Block type that, when mined, will invoke an alert.
    blocks: SPAWNER, EMERALD_ORE, DIAMOND_ORE, GOLD_ORE, IRON_ORE, COAL_ORE, LAPIS_ORE, REDSTONE_ORE

  alt-detect-notify:
      enabled: true
      # Trust levels for which an alert should be triggered
      # POSITIVE;FAIRLY_POSITIVE;POSSIBLE;NOT_LIKELY
      trust-levels: FAIRLY_POSITIVE;POSITIVE
```

Enable all the alerts you want to be able to have your staff members receive.

## Subscribing to alerts

A staff member can subscribe to or unsubscribe from these events manually using the `/alerts [type]` command.

Keep in mind a staff member can only receive an alert if he has the correct permission.

```yaml
  # Permission for managing the alerts you will get
  alerts: "staff.staffplus.alerts"
  # Permission for receiving mention alerts.
  mention: "staff.alerts.mention"
  # Permission for receiving name change alerts.
  name-change: "staff.alerts.namechange"
  # Permission for receiving xray alerts.
  xray: "staff.alerts.xray"
  # Permission for receiving alt detect alerts.
  alerts-alt-detect: "staff.alerts.alt-detects"
```

### Example

(Un)Subscribe yourself to alt account detection alerts

```
/alerts ALT_DETECT
```


# X-Ray

The x-ray is used to notify staff members when players mine a certain block. The alerts can be configured to run after a specific threshold has been reached.

```yaml
xray-alerts:
    # Whether or not this module is enabled.
    enabled: true

    # Block type that, when mined, will invoke an alert.
    blocks: SPAWNER, EMERALD_ORE:10, DIAMOND_ORE:10:1m, GOLD_ORE, IRON_ORE, COAL_ORE, LAPIS_ORE, REDSTONE_ORE
```

Blocks can be configured in three different ways.

#### Trigger every time \[blocktype]

Example: `SPAWNER` \
The above configuration will trigger an alert every time a player mines a spawner.

#### Trigger after amount \[blocktype:amount]

Example: `EMERALD_ORE:10` \
The above configuration will trigger an alert every time a player mines a total of 10 emeralds.

#### Trigger after amount/time \[blocktype:amount:time]

Example: `DIAMOND_ORE:10:1m` \
The above configuration will trigger an alert whenever a player mines 10 diamond block within the time span of 1 minute.

**Possible time values:**

* s = second
* m = minute
* h = hour
* d = day
* w = week
* M = month
* y = year

*Time values cannot be combined. For example this is invalid: "1m30s" instead type "90s"*


# Alt account detection

Staff++ provides a way to be notified when it thinks a user is using alternative accounts. The detection is really simple so don't expect miracles. It will detect the most basic and obvious alt accounts. Alt detection is disabled by default

## Configuration

```yaml
alt-detect-module:
  enabled: true
```

## How it works

### Ip similarity

When enabled the system will start recording players IP addresses. Every address a player ever connects with gets stored. If a player connects with the same address as another player his detection score is upped by 1.

### Username similarity

When a player connects we check his username against all other users known to the server. Similarity is calculated using the Levenshtein Distance Algorithm. Based on this a score is returned:

* 70% similarity --> score 3
* 50% similarity --> score 2
* 30% similarity --> score 1

### Detection trust levels (score)

The trust level is the result of the above mentioned checks. We have four levels of trust:

| Trust Level      | score | Description                                                                                                                                                                                                                                                           |
| ---------------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| POSITIVE         | 4     | Only one case can trigger the POSITIVE level. When a username has an IP match and a username match of at least 70%. We can be fairly certain something is going on with these accounts                                                                                |
| FAIRLY\_POSITIVE | 3     | Triggered when username match is between 50% and 70% and IP is matching. Or when username match is at least 70% and IP is not matching.                                                                                                                               |
| POSSIBLE         | 2     | Triggered when username match is between 30% and 50% and IP is matching. Or when username match is between 50% and 70%, and IP is not matching.                                                                                                                       |
| NOT\_LIKELY      | 1     | Triggered when username match is between 30% and 50% and IP is not matching. Or when IP is matching but there is no username similarity. In general I would not recommend listening to alerts with this trust level as most likely this will not be a reliable result |

## Listening to events

Currently Staff++ supports 2 ways of being notified when an alt account is detected.

* The [alerting system](/master/features/alerts) (in-game)
* Through Discord ([Integration plugin](https://github.com/garagepoort/StaffPlusPlus/wiki/Discord-Integration))

## Whitelisting Accounts

Since some accounts might actually not be real alt accounts but still trigger the system, a whitelist is added to ensure that staff members can ignore these false positives.

The ignore a match you can use the `/altwhitelist` command.

* `/altwhitelist add playerName1 playerName2`
* `/altwhitelist remove playerName1 playerName2`
* `/altwhitelist list pagenumber` PageNumber is optional.

This will add or remove certain user combinations from the whitelist. When added to the whitelist this users combination will never trigger a detection event. Adding a combination to the whitelist tells the system that these 2 accounts are not alts.


# Authentication

Staff++ does not have an internal authentication system.

The main reason for this decision is that there are other better plugins out there to support authentication. We do however cover the following scenarios:

### Online server mode + permissions.

In this case the official Minecraft authentication system is used. This system in combination with the correct permission setup allows for a secure authentication mechanism.

### Offline server mode + AuthMe Authentication. Everyone needs to login.

When we use AuthMe we can enforce all players to login. Using this system every player has to login before being able to execute commands. Using this + permissions is enough to block other users from using the commands.

### Offline server mode + AuthMe Authentication. Only Staff needs to log in.

AuthMe can be configured to have optional registration. Players can choose if they want to register or not. However this allows any player who joins with the same name as a staff member to have the staff member's permissions. To prevent any player to execute the Staff++ commands we have integrated the AuthMe plugin. Configure the authentication provider inside the Staff++ config to "authme". This will make sure any player who tries to execute a Staff++ command must be logged in and have the correct permissions. In other words we enforce authentication before you can use Staff++ commands even if AuthMe registration is optional.

## Configuration

Inside the configuration file make sure the following section is present:

```yaml
# Chooses the authentication provider. Default "noop", no authentication will be done.
# AuthMe is supported. When the provider is authMe, Staff++ will enforce that the user is authenticated through AuthMe before being able to execute the commands.
authentication:
    provider: authme
```

The provider must be configured to `authme`. If `noop` is configured no authentication check will be done by StaffPlusPlus. Permissions are off-course still validated

#### Authme Plugin <https://github.com/AuthMe/AuthMeReloaded>


# Banning

Staff++ overrides the default ban command with its own `ban` command. Next to the permanent ban command it also adds the `tempban` command. With every ban a reason must be given why this player is getting banned.

## Configuration

```yaml
ban-module:
  # Whether or not the plugin will use Staff++ "/ban" features.
  enabled: true
```

## Integration

The [discord integration](/master/integrations/discord-integration) plugin supports notifying to a discord channel whenever a player gets banned/unbanned.

## Examples

### Permanent banning

`/ban [player] [reason]`

```
/ban playername He was bothering me
```

### Temporary banning

`/tempban [player] [amount] [unit] [reason]`

```
/tempban playername 15 MINUTE He was bothering me
```

The duration of the tempban is specified by \[amount] \[unit]

Amount must be a positive number > 0 and unit must be one of the following:

* SECOND
* MINUTE
* HOUR
* DAY
* WEEK
* MONTH
* YEAR

### Unbanning

`/unban [player] [reason]`

```
/unban playername We are friends now
```

## Showing ban reason on ban/rejoin

If you want banned players can see the reason why they are banned you can edit the kick message in the lang files:

```yaml
ban-tempbanned-kick: "[Banned] You have been temporarily banned from this server. Ban ends in: %duration%"
ban-permabanned-kick: "[Banned] You have been permanently banned from this server"
```

You can use the placeholder `%reason%` to add a reason to the kick message.

## Another plugin is overriding the `/ban`, `/tempban`, `/unban`

It is possible that another plugin like 'essentialsx' might get priority over the `ban`, `tempban` and `unban` command. To prevent this we suggest the same solution as is proposed by [EssentialsX](https://github.com/EssentialsX/Essentials/wiki/Common-Issues#essentialsx-overrides-a-command-from-spigot-or-another-plugin).

Configure your server aliases in such a way that the ban commands from Staff++ will always be used. This can be done by editing the `commands.yml` file and specifying your aliases there.

To enable Staff++ ban commands this would be done in this way:

```yaml
aliases:
    ban:
    - "staffplus:ban $1-"
    tempban:
    - "staffplus:tempban $1-"
    unban:
    - "staffplus:unban $1-"
```

More info on the [bukkit wiki](https://bukkit.gamepedia.com/Commands.yml#aliases)

## GUI

Banned players can be listed and unbanned through the gui hub.

// TODO add screenshots


# Fixed Ban Reason

You can configure custom ban reasons. This will enforce the staff members to use your reasons.

{% hint style="info" %}
The entire **reasons** section is optional and **not** present in the default config
{% endhint %}

### Configuration

```yaml
ban-module:
  enabled: true
  permban-template: default
  tempban-template: default
  reasons: 
    - name: GRIEFING
      reason: No griefing allowed on this server
    - name: BULLYING
      reason: bullying will not be tolerated
      template: bullying
    - name: CURSING
      reason: Consistent cursing. Temporarily banned.
      template: cursing
      ban-type: TEMP_BAN
```

In the above config we have defined 3 ban reasons. GRIEFING, BULLYING and CURSING.\
\
Every reason configuration must have at least a `name` and a `reason` . Optionally you can also define a `template` . When you define a template you overwrite any other configured template. However staff members can still [provide a template in their command](/master/features/banning/templates#overwriting-the-default-template).&#x20;

By default ban reasons are applicable to both permanent and temporary ban. You can however define another optional configuration option`ban-type` . The ban type can be configured with **TEMP\_BAN** or  **PERM\_BAN.** When the type is configured, this ban reason will only apply for these types of bans. \
\
If no ban reasons are configured, the staff members can provide a custom reason. As soon as at least one ban reason is configured they are obligated to use ban reasons and can no longer fill in a custom message


# Templates

You can use txt files to describe the logout message a player will see when he gets banned.\
By default this entire functionality is disabled. To enable templates do the following.

### Setup

Inside the data directory of the Staff++ plugin create a **bans** directory if it does not already exists.\
\
Inside this bans directory you can create the template files. A template file is a simple text file containing the message that will displayed to the user on ban. Example file:

{% file src="/files/-MW6p7-bk759j2hyKOEZ" %}
bans/default.txt
{% endfile %}

I named the above file **default.txt.** The file name without extension will be used as **template name**.<br>

This will result in the following:

![](/files/-MW6q6iGCsvw71M8Nu1u)

My example is not that pretty but it illustrates the usage.<br>

#### placeholders

Inside the template the following placeholders can be used

| placeholder | description                                           |
| ----------- | ----------------------------------------------------- |
| %target%    | The banned player's username                          |
| %issuer%    | The staff members username                            |
| %reason%    | The ban reason                                        |
| %duration%  | Human readable duration. Only available with tempbans |

### Configuration

```yaml
ban-module:
  enabled: true
  permban-template: default
  tempban-template: default
```

Inside the **config.yml** file you can fill in a default template for permanent and temporary ban. Or leave it empty to fall back on the message defined in the lang file.

### Overwriting the default template

If staff members have the permission: `staff.staffplus.ban-template-overwrite` they can use an extra parameter **"-template="** when banning a player.\
Example:\
`/ban thisplayer -template=other I ban you!`

This will overwrite the default configured template and try to find and use a template with the given name. If the template does not exist an error will be shown.


# Broadcasting

Staff++ added a "broadcast" command. This allows a staff member to send a message across the server. If you are in a bungee network the message will be send to all servers or only to the ones specified in the config.

## Configuration

Make sure the following section is present in your config file:

```yaml
############################################################
# +------------------------------------------------------+ #
# |                      Broadcast                       | #
# +------------------------------------------------------+ #
############################################################

# Requires "permissions.broadcast" permission.
broadcast-module:
  # Whether or not the plugin will use "/broadcast" features.
  enabled: true
  # The servers to which the broadcasting is applied "CURRENT" is the default value and broadcasts only on the current server.
  # This also prevents staff members from broadcasting to other servers
  # "ALL" broadcasts to all known servers on the network.
  # Alternatively you can provide a list of semicolon separated server names to which the broadcasting should be applied.
  # Example: lobby;survival;skyblock
  enabled-servers: CURRENT
```

The enabled-servers option allows us to restrict the receiving servers.

* CURRENT: only the current server is allowed to receive message. Use this when you are not on a bungee network
* ALL: The message will be send to all servers on the network.
* LIST: The message will only be send to the servers in the list


# Chat module

### Introduction

The chat module allows you to manage certain chat functionalities. Most of these are still the old Staff+ ones.&#x20;

### Configuration

```yaml
# Requires "permissions.chat" permission.
chat-module:
  # Whether or not the plugin will use "/chat" features.
  enabled: true

  # The amount of lines that will be sent when "/chat clear" is executed.
  lines: 100

  # The cooldown, in seconds, for chatting when the chat is slowed.
  # Bypass permission is "chat-slow".
  slow: 5

  # Whenever one of these words/phrases is detected in a chat message, 
  # an alert will be triggered. These can either notify the staff members 
  # through the alerts-system of discord.
  detection:
    phrases:
      - admin
      - mod

  # All word blacklist options.
  # Leave any of the lists below blank to disable them!
  blacklist-module:
    # Whether or not the blacklist will be enabled.
    enabled: false

    # Whether or not messages that have censored words in them will be hoverable.
    # This means you will be able to hover over a chat message to see an uncensored message if you have the "permissions.blacklist" permission.
    # This may not work well with other chat plugins!
    hoverable: false

    # The character that will replace blocked word characters.
    character: "*"

    # Whether or not messages that have merged blocked words will be detected.
    # So if you block the word "ass", it will also block "asshole" or "dickass".
    # May cause issues with legal words like "bypass"! Fix is below.
    merging: true

    # All words that will be censored.
    # Separate words with commas.
    words: bad, words, here

    # All characters that will be censored.
    # These are merely characters that will be detected anywhere in messages.
    characters: b, a, d

    # All domain levels that will be censored.
    # This can prevent users from sending links in chat.
    # This will only check the end of words which have detected periods!
    domains: com, net, org

    # All strings that will be detected as periods in messages. Of course characters like "." and "," are detected by default.
    # This will work in coordination with "domains".
    # For example, it can detect "mineplex()com" as "mineplex.com".
    periods: (), (dot),

    # All words that will be allowed to be typed no matter what.
    # This helps quite a bit if you have "merging" enabled.
    # I recommend using http://www.morewords.com/contains/[word]/!
    allowed: bypass, assembly, assassin, compass, assume, assault, asset, assort
```


# Chest/Inventory Interaction

In Staff++ a staff member can interact with other player's EnderChest or inventory.\
On this page we explain the different types of interaction and how to enable them.

## Silent Chest Interaction

When in Staff mode, the player can open chest/dispenser/hoppers,.... by right clicking on them.\
This is called "silent chest opening". When a player opens this he may or may not be able to interact with the item in the container depending on his permissions.

If you want to enable interacting with chests when opening them in "silent" mode enable the following property in the config. If this is disabled no staff members can interact in silent mode.&#x20;

```yaml
staff-mode:
    silent-chest-interaction: true
```

### Permission

Only staff members with the permission `staff.mode.silent-chest-interaction` can interact with containers in silent mode.

## Enderchest Interaction

Staff++ has a command called `/eview <playername>` . This command has been there since the old Staff+. However it was never able to interact with another player's enderchest. In Staff++ we added the ability to open and interact with enderchests of online and offline players.

### Configuration

Make sure to enable the module.

```yaml
enderchest-module:
    enabled: true
```

### Permissions

| Permission                      | Description                                              |
| ------------------------------- | -------------------------------------------------------- |
| staff.enderchests.view\.online  | Permission to view the enderchest of online players      |
| staff.enderchests.view\.offline | Permission to view the enderchest of offline player      |
| staff.enderchests.interact      | Permission to interact with enderchests of other players |

## Inventory Interaction

Staff members can access another player's inventory using the `/examine` command.\
You can view and interact with the inventory of online and offline players.

When opening the examine GUI you will see a chest is available:

![](/files/-MRbSF7TwTqTjD7kRAHW)

Clicking on this chest opens the interaction screen

![Inventory Interaction](/files/-MRbVzO5rOnhRIFNEzv0)

The **blue** outlined items are the hotbar items of the player's inventory.\
The **red** outlined items are the armor contents of the player.\
\
The examined player's inventory looks like this:

![](/files/-MRbWJ7VPvqfelLMSAGv)

### Permissions

| Permission                                  | Description                                                        |
| ------------------------------------------- | ------------------------------------------------------------------ |
| staff.examine                               | Permission to use the examine command                              |
| staff.examine.view-inventory                | Allow a staff member to view online player's inventories           |
| staff.examine.view-inventory-offline        | Allow a staff member to view offline player's inventories          |
| staff.examine.inventory-interaction         | Allow a staff member to interact with online player's inventories  |
| staff.examine.inventory-interaction-offline | Allow a staff member to interact with offline player's inventories |

### <br>




---

[Next Page](/llms-full.txt/1)

