# Moderation

Mutes, permanent/temporary bans, IP bans, warnings with automatic escalation actions, a jail system with movement and command locks, SocialSpy/CommandSpy and vanish. All active punishments persist across restarts; expired ones are dropped on startup.

## Commands

| Command | Syntax | Permission | Default | Description |
|---|---|---|---|---|
| `/mute` | `/mute <player> [duration] [reason]` | `mod.mute` | `false` | Mutes chat and private messages (permanent without duration) |
| `/unmute` | `/unmute <player>` | `mod.unmute` | `false` | Lifts a mute |
| `/checkmute` | `/checkmute <player>` | `mod.mute` | `false` | Mute status, remaining time, reason, issuer |
| `/cban` | `/cban <player> [reason]` (alias `/coreban`) | `mod.ban` | `false` | Permanent ban, kicks instantly |
| `/ctempban` | `/ctempban <player> <duration> [reason]` (alias `/coretempban`) | `mod.tempban` | `false` | Temporary ban, kicks instantly |
| `/cunban` | `/cunban <player>` (alias `/coreunban`) | `mod.unban` | `false` | Unbans (also never-joined players via name lookup) |
| `/checkban` | `/checkban <player>` | `mod.ban` | `false` | Ban type, remaining time, reason, issuer |
| `/cbanip` | `/cbanip <ip\|player> [reason]` (alias `/corebanip`) | `mod.banip` | `false` | Bans an IP (player must be online for lookup); kicks everyone on that IP |
| `/cunbanip` | `/cunbanip <ip>` (alias `/coreunbanip`) | `mod.unban` | `false` | Unbans an IP (deliberately no tab completion) |
| `/warn` | `/warn <player> [reason]` | `mod.warn` | `false` | Warning with a per-player sequential ID |
| `/warnings` | `/warnings <player>` (alias `/warns`) | `mod.warn` | `false` | Lists active warnings |
| `/clearwarnings` | `/clearwarnings <player>` (alias `/clearwarns`) | `mod.clearwarnings` | `false` | Deletes all warnings |
| `/setjail` | `/setjail <name>` | `mod.setjail` | `false` | Jail point at your position (max 32 characters) |
| `/deljail` | `/deljail <name>` | `mod.setjail` | `false` | Deletes the jail point and releases all inmates |
| `/jail` | `/jail <player> [jail] [duration] [reason]` | `mod.jail` | `false` | Jails (permanent without duration) |
| `/unjail` | `/unjail <player>` | `mod.unjail` | `false` | Releases and teleports to spawn |
| `/socialspy` | `/socialspy` | `mod.socialspy` | `false` | Read other players' private messages (toggle) |
| `/commandspy` | `/commandspy` | `mod.commandspy` | `false` | See other players' commands (toggle) |
| `/vanish` | `/vanish` (alias `/v`) | `mod.vanish` | `false` | Invisible: no mob aggro, no item pickup, no join/leave message |

## Additional permissions

| Permission | Default | Description |
|---|---|---|
| `mod.vanish.see` | `false` | Still sees vanished players (also in `/msg` tab completion) |
| `mod.bypass.mute` | `false` | Chats despite a mute (private messages additionally need `msg.bypass.mute`) |
| `mod.bypass.jail` | `false` | Moves and uses commands despite jail |

## Duration format

For `/mute`, `/ctempban`, `/jail` and warn actions: units `s`, `m`, `h`, `d`, `w`, freely combinable (`2h30m`, `1w2d`). A plain number counts as **minutes**. Maximum 10 years; invalid inputs like `5m abc` are rejected entirely.

> **Warning:** An active mute/ban must be removed before a new one with a different reason or duration can be set. IP bans are separate from account bans: `/cunban` does not lift an IP ban.

> **Note:** Warn actions fire exactly when the threshold is reached (not on every further warning) and run through the console. For `tempban` actions a valid `duration` is REQUIRED, otherwise the action is skipped silently.

> **Note:** Both spy modes do not survive relog/restart and exclude your own messages. Messages blocked by a mute do not appear in SocialSpy. A mute only affects chat and PM commands, not signs or books.

## Jail behavior

Movement is limited to `radius` blocks around the jail point (world changes and outbound teleports are teleported back, respawn lands in jail). Only commands from `allowed-commands` work; chat is blocked with `block-chat`. Online-only jails count only time spent online, otherwise the clock also runs offline; on login an active inmate is teleported back into jail (re-jail).

## Configuration (modules/moderation.yml)

```yaml
# Enables or disables the moderation module with all commands.
enabled: true

moderation:
  warnings:
    # Days until a warning expires automatically. 0 = never.
    expiry-days: 0
    # Automatic actions at exactly reached thresholds, any number of
    # entries, sorted by threshold.
    actions:
      action1:
        threshold: 3
        # mute, tempban or ban.
        action: mute
        # Duration format. Required for tempban, empty = permanent for mute/ban.
        duration: "1h"
        reason: "Too many warnings (auto-mute)"
      action2:
        threshold: 5
        action: tempban
        duration: "1d"
        reason: "Too many warnings (auto-tempban)"
      action3:
        threshold: 7
        action: ban
        duration: ""
        reason: "Too many warnings (auto-permban)"
  jail:
    # Movement radius in blocks around the jail point.
    radius: 5.0
    # true = new jails only count time spent online.
    online-only-default: false
    # Blocks chat for inmates.
    block-chat: true
    # Allowed commands in jail (compared on the first word).
    allowed-commands:
      - "/msg"
      - "/tell"
      - "/r"
      - "/reply"
  commandspy:
    # Commands never reported to CommandSpy (login/password).
    blacklist:
      - "/login"
      - "/register"
      - "/changepassword"
      - "/l"
      - "/reg"
  vanish:
    # true = vanish state survives restarts and relogs.
    persist: false
    # Permanent night vision (without particles) while vanished.
    night-vision: true
```

## Complete example config

```yaml
enabled: true

moderation:
  warnings:
    expiry-days: 30
    actions:
      action1:
        threshold: 3
        action: mute
        duration: "6h"
        reason: "Too many warnings"
      action2:
        threshold: 5
        action: tempban
        duration: "3d"
        reason: "Too many warnings"
      action3:
        threshold: 8
        action: ban
        duration: ""
        reason: "Permanently too many warnings"
  jail:
    radius: 10.0
    online-only-default: true
    block-chat: false
    allowed-commands:
      - "/msg"
      - "/r"
      - "/rules"
  commandspy:
    blacklist:
      - "/login"
      - "/register"
  vanish:
    persist: true
    night-vision: true
```
