> For the complete documentation index, see [llms.txt](https://spiter.gitbook.io/spiter/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://spiter.gitbook.io/spiter/spiter-8.0/punishment.yml.md).

# punishment.yml

## 中文说明

`punishment.yml` 是 Spiter 反作弊系统中用于定义如何处理违规玩家的核心配置文件。本章节将指导您如何配置惩罚规则、动作指令、衰减机制，以及如何基于玩家权限分配不同的惩罚组。

***

### 1. 基础结构与权限分组 <a href="#id-1-ji-chu-jie-gou-yu-quan-xian-fen-zu-permissiongroups" id="id-1-ji-chu-jie-gou-yu-quan-xian-fen-zu-permissiongroups"></a>

`punishment.yml` 采用按组 (Group) 分类的结构。系统默认使用 `default` 组。

**基于权限的惩罚绕过/调整：**\
Spiter 支持为不同权限的玩家分配不同的惩罚组。当玩家登录时，系统会检查玩家是否拥有

`spiter.punishment.组名` 的权限。

如果有，该玩家将应用该组的惩罚配置，而不再使用 `default`。这非常适合用于配置**给不同玩家不同的判定**，或者**特定模式下的严格判定，例如特殊模式可以让玩家使用一些不公平的手段**。

```yaml
# 默认配置（普通玩家）
default:
  combat_reach:
    # 正常惩罚逻辑

# 当玩家拥有 `spiter.punishment.vip` 权限时，将使用这个配置块（例如不执行踢出，只发警告）
vip:
  combat_reach:
    # 针对VIP的宽松逻辑
```

***

### 2. 配置项 <a href="#id-2-he-xin-pei-zhi-xiang-jie-xi" id="id-2-he-xin-pei-zhi-xiang-jie-xi"></a>

每个检测代码块都由以下四个核心属性组成：

#### 2.1 `check`  <a href="#id-21codecheckcode-chu-fa-qi" id="id-21codecheckcode-chu-fa-qi"></a>

用于绑定触发此惩罚规则的检测项名称。

* **精确匹配:** 直接填写检测名称（如 `combat.reach`）。
* **通配符匹配:** 使用 `*` 匹配某一大类的所有检测（如 `combat.clk.*`）。
* **排除匹配:** 使用 `!` 排除特定检测（如 `!combat.clk.b`）。
* **权重调整:** 使用 `检测名:增加的VL数` 来调整该检测产生的 VL（违规值）权重。

```yaml
check:
  - "combat.reach"       # 精确匹配单项检测
  - "combat.hitbox:2.0"  # 触发 hitbox 时，增加 2 VL
  - "combat.clk.*"       # 匹配所有自动点击检测
  - "!combat.clk.b"      # 排除 combat.clk.b 检测
```

#### 2.2 `decay`  <a href="#id-22codedecaycode-wei-gui-zhi-shuai-jian-ji-zhi" id="id-22codedecaycode-wei-gui-zhi-shuai-jian-ji-zhi"></a>

控制玩家在停止作弊后，违规值 (VL) 的下降速度。合理的衰减配置可以有效防止因长时间游戏积累导致的误判。

```yaml
decay:
  interval: 20   # 衰减判定间隔，单位为秒（每 20 秒执行一次衰减判定）
  amount: 5      # 每次衰减的 VL 数量（一次扣除 5 点 VL）
```

#### 2.3 `intervals`  <a href="#id-23codeintervalscode-yi-ci-xing-cheng-fa-yu-zhi" id="id-23codeintervalscode-yi-ci-xing-cheng-fa-yu-zhi"></a>

当玩家的 VL **首次**达到指定的数值时，系统将执行对应的动作。一旦执行完毕，且没有更高的阈值，VL 将会被重置。

> 💡 **提示:** 动作内容推荐加上对应的前缀。如果需要同时执行多条指令，请使用 YAML 的列表格式。

```yaml
intervals:
  5: "[notify] spiter internals notify %prefix%%trscolor%%player%&r maybe using reach hack"
  15: 
    - "[notify] spiter internals notify %prefix%%trscolor%%player%&r is using reach hack (#2)"
    - "[command] kick %player% You have been kicked for cheating." # 达到 15 VL 时执行踢出
```

#### 2.4 `loop`  <a href="#id-24codeloopcode-zhou-qi-xing-cheng-fa" id="id-24codeloopcode-zhou-qi-xing-cheng-fa"></a>

不同于 `intervals` 的一次性执行，`loop` 用于配置需要重复执行的动作。当 VL 达到该阈值时会执行对应的动作，随后 VL 将扣除该阈值并继续累加，从而实现周期性惩罚。

```yaml
loop:
  5: "[mitigation] attack_damage" # 每累积 5 点 VL，执行一次攻击减免
  8: 
    - "[notify] spiter internals notify %prefix%%trscolor%%player%&r is using reach hack (#2)"
    - "[command] kick %player% You have been kicked for cheating." # 达到 15 VL 时执行踢出
```

***

### 3. 可用的动作前缀与变量 <a href="#id-3-ke-yong-de-dong-zuo-qian-zhui-yu-bian-liang" id="id-3-ke-yong-de-dong-zuo-qian-zhui-yu-bian-liang"></a>

#### 3.1 动作前缀 (Action Types) <a href="#id-31-dong-zuo-qian-zhui-actiontypes" id="id-31-dong-zuo-qian-zhui-actiontypes"></a>

Spiter 支持以下三种执行方式，在配置动作时，请使用对应的前缀声明：

| 前缀                 | 说明                           |
| ------------------ | ---------------------------- |
| **`[command]`**    | (默认) 以控制台身份执行指令。             |
| **`[notify]`**     | 发送内部警告消息给拥有 `spiter` 权限的管理员。 |
| **`[mitigation]`** | 触发底层缓解措施，强制阻止玩家作弊行为，无需外部插件。  |

**可用的 `[mitigation]` 类型：**

* `damage_tick`: 重置攻击伤害计时
* `attack_damage`: 取消下次攻击伤害
* `movement`: 强制拉回玩家位置 (Setback)
* `food_level`: 重置食物消耗
* `extra_velocity`: 清除额外速度
* `block_place`: 取消方块放置
* `block_break`: 取消方块破坏

例如：\[mitigation] block\_break

#### 3.2 可用变量 (Variables) <a href="#id-32-ke-yong-bian-liang-variables" id="id-32-ke-yong-bian-liang-variables"></a>

在 `[command]` 和 `[notify]` 中，您可以使用以下占位符，系统会自动替换为实际数据：

* `%player%`: 玩家名称
* `%check%`: 具体触发的检测节点 (如 combat.reach)
* `%alertsName%` / `%checkName%`: 检测项显示的名称
* `%vl%` / `%maxvl%`: 当前违规值 / 触发阈值
* `%ping%`: 玩家延迟
* `%version%`: 玩家客户端版本
* `%brand%`: 玩家客户端品牌 (如 forge, vanilla)
* `%id%`: 生成的封禁ID
* `%anticheat%`: 从配置中获取的反作弊名称

***

### 附录：检测名大全 <a href="#fu-lu-jian-ce-ming-da-quan" id="fu-lu-jian-ce-ming-da-quan"></a>

#### 检测名分类概览 <a href="#jian-ce-ming-fen-lei-gai-lan" id="jian-ce-ming-fen-lei-gai-lan"></a>

* **combat (战斗):** `combat.hitbox`, `combat.block`, `combat.entity`, `combat.reach`, `combat.backtrack.*`, `combat.autototem.*`, `combat.clk.*` ,`ka.ab.*`, `ka.flag.*`, `abt.analysis.*`, `move.ack`
* **sfd (脚手架):** `sfd.place.*`, `sfd.ray.*`, `sfd.rotation.*`, `sfd.bp.*`, `sfd.clk.a`, `sfd.twr.*`
* **vel (击退):** `vel.intave`, `vel.aug`, `vel.motion`, `vel.d`, `vel.e`, `vel.f`, `vel.g`, `vel.ground`, `vel.hor`, `vel.tick`, `vel.gf`
* **bp (异常包):** `bp.rec.*`, `bp.timer.low`, `bp.net.*` `bp.noslow.*`, `bp.dupe.*`, `bp.entity.*`, `bp.post.a`
* **move (移动/NoFall):** `move.gf.*` , `move.elytra.*` , `move.noslow.*`
* **survive (生存):** `survive.mining.*` , `survive.autofish.*`&#x20;
* **block (破坏):** `block.break.*`&#x20;
* **interact (交互):** `interact.air`, `interact.place`, `interact.break.*`
* **inv (物品栏):** `inv.csl.*`&#x20;
* **heur (启发式):** `heur.*`
* **invalid (非法):** `invalid.move.*`
* **phase (穿墙):** `phase.main`

完整列表：

* `abt.analysis.b`, `abt.analysis.c`, `abt.analysis.d`, `abt.analysis.e`, `abt.analysis.f`, `abt.analysis.g`, `abt.analysis.h`, `abt.analysis.i`, `abt.analysis.j`, `abt.analysis.k`, `abt.analysis.n`, `abt.analysis.o`, `abt.analysis.p`, `abt.analysis.q`, `abt.analysis.r`, `abt.analysis.s`, `abt.analysis.t`, `abt.analysis.u`, `abt.analysis.v`, `abt.analysis.w`, `abt.analysis.x`, `abt.analysis.y`, `abt.analysis.z`, `abt.analysis.z2`, `abt.analysis.a1`, `abt.analysis.3`, `abt.analysis.4`, `abt.analysis.5`, `abt.analysis.8`, `abt.analysis.8b`, `abt.analysis.9`, `abt.analysis.10`, `abt.analysis.11`, `abt.analysis.12`, `abt.analysis.13`, `abt.analysis.14`, `abt.analysis.15`, `abt.analysis.16`, `abt.analysis.17`, `abt.analysis.b2`, `abt.analysis.c2`
* `block.break.stm`, `block.break.ftm`, `block.break.invalidA`, `block.break.invalidB`, `block.break.invalidC`, `block.break.invalidD`, `block.break.invalidE`, `block.break.invalidF`, `block.break.invalidG`
* `bp.dupe.a`, `bp.dupe.b`
* `bp.entity.i`, `bp.entity.c`, `bp.entity.d`, `bp.entity.e`
* `bp.net.b`, `bp.net.c`, `bp.net.d`, `bp.net.e`, `bp.net.f`, `bp.net.g`
* `bp.noslow.a`, `bp.noslow.b`, `bp.noslow.c`, `bp.noslow.d`, `bp.noslow.e`, `bp.noslow.f`, `bp.noslow.g`, `bp.noslow.h`, `bp.noslow.i`, `bp.noslow.j`, `bp.noslow.n`, `bp.noslow.sneak`
* `bp.post.a`
* `bp.rec.1`, `bp.rec.3`, `bp.rec.4`, `bp.rec.5`, `bp.rec.b`, `bp.rec.c`, `bp.rec.d`, `bp.rec.e`, `bp.rec.f`, `bp.rec.g`, `bp.rec.gamemode`, `bp.rec.h`, `bp.rec.i`, `bp.rec.j`, `bp.rec.k`, `bp.rec.l`, `bp.rec.m`, `bp.rec.n`, `bp.rec.o`, `bp.rec.p`, `bp.rec.payload`, `bp.rec.q`, `bp.rec.r`, `bp.rec.s`, `bp.rec.t`, `bp.rec.tick`, `bp.rec.u`, `bp.rec.v`, `bp.rec.w`, `bp.rec.x`, `bp.rec.y`, `bp.rec.z`
* `bp.timer.low`
* `combat.autototem.a`, `combat.autototem.b`
* `combat.backtrack.a`, `combat.backtrack.b`, `combat.backtrack.c`, `combat.backtrack.d`, `combat.backtrack.e`, `combat.backtrack.f`, `combat.backtrack.g`, `combat.backtrack.h`, `combat.backtrack.i`, `combat.backtrack.j`
* `combat.block`, `combat.clk.left`, `combat.clk.right`, `combat.clk.b`, `combat.clk.c`, `combat.clk.d`, `combat.clk.e`, `combat.clk.f`, `combat.clk.g`, `combat.clk.h`, `combat.clk.i`, `combat.clk.j`, `combat.clk.k`, `combat.clk.l`, `combat.clk.m`, `combat.clk.n`, `combat.clk.o`, `combat.clk.p`, `combat.clk.q`, `combat.clk.r`, `combat.clk.s`, `combat.clk.t`, `combat.clk.u`, `combat.clk.v`, `combat.clk.w`, `combat.clk.x`, `combat.clk.y`, `combat.clk.z`, `combat.clk.1`, `combat.clk.2`, `combat.clk.3`, `combat.clk.4`, `combat.clk.5`, `combat.clk.6`, `combat.clk.7`, `combat.clk.8`, `combat.clk.9`, `combat.clk.10`, `combat.clk.11`
* `combat.entity`, `combat.hitbox`, `combat.reach`
* `heur.b`, `heur.c`, `heur.d`, `heur.e`, `heur.f`
* `interact.air`, `interact.break.b`, `interact.break.c`, `interact.break.d`, `interact.break.e`, `interact.place`
* `invalid.move.a`, `invalid.move.d`
* `inv.csl.a`, `inv.csl.b`, `inv.csl.c`, `inv.csl.d`, `inv.csl.f`, `inv.csl.g`
* `ka.ab.a`, `ka.ab.b`, `ka.ab.c`, `ka.ab.d`, `ka.ab.d2`, `ka.ab.e`, `ka.ab.f`, `ka.ab.g`, `ka.ab.h`, `ka.ab.i`, `ka.ab.j`, `ka.ab.k`, `ka.ab.l`, `ka.ab.m`, `ka.ab.n`, `ka.ab.o`, `ka.ab.p`, `ka.ab.q`, `ka.ab.r`, `ka.ab.s`, `ka.ab.t`, `ka.ab.u`, `ka.ab.v`, `ka.ab.w`, `ka.ab.x`, `ka.ab.y`, `ka.ab.z`, `ka.ab.1`, `ka.ab.3`, `ka.ab.4`
* `ka.flag.a`, `ka.flag.b`, `ka.flag.c`, `ka.flag.d`, `ka.flag.e`, `ka.flag.g`, `ka.flag.i`, `ka.flag.j`, `ka.flag.k`, `ka.flag.l`, `ka.flag.m`, `ka.flag.n`, `ka.flag.o`, `ka.flag.p`, `ka.flag.q`, `ka.flag.r`, `ka.flag.r2`, `ka.flag.s`, `ka.flag.t`, `ka.flag.u`
* `move.ack`
* `move.elytra.synca`, `move.elytra.syncb`, `move.elytra.syncc`, `move.elytra.action`, `move.elytra.tick`, `move.elytra.glide`, `move.elytra.fly`, `move.elytra.ground`, `move.elytra.potion`, `move.elytra.car`, `move.elytra.water`
* `move.gf.fly`, `move.gf.fakeliquid`, `move.gf.plc`, `move.gf.vt`, `move.gf.block`
* `move.noslow.potion`, `move.noslow.food`, `move.noslow.bow`, `move.noslow.item`
* `phase.main`
* `sfd.bp.a`, `sfd.bp.b`, `sfd.bp.c2`, `sfd.bp.d`, `sfd.bp.e`, `sfd.bp.f`, `sfd.bp.g`, `sfd.bp.h`, `sfd.bp.i`, `sfd.bp.j`
* `sfd.clk.a`
* `sfd.place.a`, `sfd.place.b`, `sfd.place.c`, `sfd.place.d`, `sfd.place.e`, `sfd.place.f`, `sfd.place.g`, `sfd.place.h`, `sfd.place.i`, `sfd.place.j`, `sfd.place.k`, `sfd.place.l`, `sfd.place.m`, `sfd.place.n`, `sfd.place.o`, `sfd.place.p`, `sfd.place.q`, `sfd.place.r`, `sfd.place.s`, `sfd.place.t`
* `sfd.ray.a`, `sfd.ray.b`, `sfd.ray.c`, `sfd.ray.d`, `sfd.ray.e`, `sfd.ray.f`, `sfd.ray.g`, `sfd.ray.h`, `sfd.ray.i`, `sfd.ray.j`, `sfd.ray.l`, `sfd.ray.m`, `sfd.ray.n`
* `sfd.rotation.a`, `sfd.rotation.b`, `sfd.rotation.c`, `sfd.rotation.d`, `sfd.rotation.e`, `sfd.rotation.f`, `sfd.rotation.g`, `sfd.rotation.h`, `sfd.rotation.i`, `sfd.rotation.j`, `sfd.rotation.k`, `sfd.rotation.l`, `sfd.rotation.m`, `sfd.rotation.o`
* `sfd.twr.a`, `sfd.twr.b`, `sfd.twr.c`
* `survive.autofish.a`, `survive.autofish.b`
* `survive.mining.a`, `survive.mining.b`, `survive.mining.c`, `survive.mining.e`, `survive.mining.f` ,`survive.mining.d`
* `vel.intave`, `vel.aug`, `vel.motion`, `vel.d`, `vel.e`, `vel.f`, `vel.g`, `vel.ground`, `vel.hor`, `vel.tick`, `vel.gf`

简单完整配置：

```
default:
  combat_reach:
    check:
      - "combat.reach"
      - "combat.hitbox"
      - "combat.block"
      - "combat.entity"
      - "combat.backtrack.*"
    decay:
      interval: 20
      amount: 5
    loop:
      5: "[mitigation] attack_damage"
    intervals:
      10: "[notify] spiter internals notify %prefix%%trscolor%%player%&r is flagged for Combat/Reach (VL: %vl%)"
      20: 
        - "[notify] spiter internals notify %prefix%%trscolor%%player%&r is flagged for Combat/Reach (VL: %vl%)"
        - "[command] kick %player% %anticheat%: Unfair Advantage (ID: %id%)"

  combat_autoclicker:
    check:
      - "combat.clk.*"
      - "heur.*"
    decay:
      interval: 30
      amount: 10
    loop:
      10: "[mitigation] damage_tick"
    intervals:
      20: "[notify] spiter internals notify %prefix%%trscolor%%player%&r is flagged for AutoClicker (VL: %vl%)"
      40: 
        - "[notify] spiter internals notify %prefix%%trscolor%%player%&r is flagged for AutoClicker (VL: %vl%)"
        - "[command] kick %player% %anticheat%: Unfair Advantage (ID: %id%)"

  killaura_autoblock:
    check:
      - "ka.ab.*"
      - "ka.flag.*"
      - "abt.analysis.*"
      - "move.ack"
    decay:
      interval: 25
      amount: 5
    loop:
      8: "[mitigation] attack_damage"
    intervals:
      15: "[notify] spiter internals notify %prefix%%trscolor%%player%&r is flagged for KillAura (VL: %vl%)"
      30: 
        - "[notify] spiter internals notify %prefix%%trscolor%%player%&r is flagged for KillAura (VL: %vl%)"
        - "[command] kick %player% %anticheat%: Unfair Advantage (ID: %id%)"

  scaffold_tower:
    check:
      - "sfd.*"
    decay:
      interval: 15
      amount: 5
    loop:
      5: "[mitigation] block_place"
    intervals:
      15: "[notify] spiter internals notify %prefix%%trscolor%%player%&r is flagged for Scaffold (VL: %vl%)"
      25: 
        - "[notify] spiter internals notify %prefix%%trscolor%%player%&r is flagged for Scaffold (VL: %vl%)"
        - "[command] kick %player% %anticheat%: Unfair Advantage (ID: %id%)"

  movement_velocity:
    check:
      - "vel.*"
    decay:
      interval: 20
      amount: 5
    loop:
      5: "[mitigation] extra_velocity"
    intervals:
      15: "[notify] spiter internals notify %prefix%%trscolor%%player%&r is flagged for Velocity (VL: %vl%)"
      25: 
        - "[notify] spiter internals notify %prefix%%trscolor%%player%&r is flagged for Velocity (VL: %vl%)"
        - "[command] kick %player% %anticheat%: Unfair Advantage (ID: %id%)"

  movement_flight_speed:
    check:
      - "move.gf.*"
      - "move.elytra.*"
      - "move.*"
      - "move.noslow.*"
      - "invalid.move.*"
      - "phase.main"
    decay:
      interval: 20
      amount: 5
    loop:
      5: "[mitigation] movement"
    intervals:
      15: "[notify] spiter internals notify %prefix%%trscolor%%player%&r is flagged for Movement (VL: %vl%)"
      50: 
        - "[notify] spiter internals notify %prefix%%trscolor%%player%&r is flagged for Movement (VL: %vl%)"
        - "[command] kick %player% %anticheat%: Unfair Advantage (ID: %id%)"

  badpackets_network:
    check:
      - "bp.*"
    decay:
      interval: 40
      amount: 5
    intervals:
      20: "[notify] spiter internals notify %prefix%%trscolor%%player%&r is flagged for BadPackets (VL: %vl%)"
      40: 
        - "[notify] spiter internals notify %prefix%%trscolor%%player%&r is flagged for BadPackets (VL: %vl%)"
        - "[command] kick %player% %anticheat%: Unfair Advantage (ID: %id%)"

  interaction_block:
    check:
      - "block.break.*"
      - "interact.*"
      - "inv.csl.*"
    decay:
      interval: 20
      amount: 5
    loop:
      5: "[mitigation] block_break"
    intervals:
      15: "[notify] spiter internals notify %prefix%%trscolor%%player%&r is flagged for Interaction (VL: %vl%)"
      30: 
        - "[notify] spiter internals notify %prefix%%trscolor%%player%&r is flagged for Interaction (VL: %vl%)"
        - "[command] kick %player% %anticheat%: Unfair Advantage (ID: %id%)"

  survive_baritone:
    check:
      - "survive.*"
      - "baritone.gcd"
    decay:
      interval: 60
      amount: 2
    intervals:
      10: "[notify] spiter internals notify %prefix%%trscolor%%player%&r is flagged for AutoBot (VL: %vl%)"
      20: 
        - "[notify] spiter internals notify %prefix%%trscolor%%player%&r is flagged for AutoBot (VL: %vl%)"
        - "[command] kick %player% %anticheat%: Unfair Advantage (ID: %id%)"

vip:
  combat_reach:
    check:
      - "combat.reach"
      - "combat.hitbox"
      - "combat.backtrack.*"
    decay:
      interval: 10
      amount: 10
    loop:
      10: "[mitigation] attack_damage"
    intervals:
      20: "[notify] spiter internals notify %prefix%%trscolor%%player%&r (VIP) is flagged for Combat/Reach (VL: %vl%)"
```

## <sup>English：</sup>

`punishment.yml` is the core configuration file in the Spiter Anti-Cheat system used to define how violations are handled. This section will guide you through configuring punishment rules, action commands, decay mechanisms, and assigning different groups based on player permissions.

***

### 1. Basic Structure & Permission Groups <a href="#id-1-basic-structure-amp-permission-groups" id="id-1-basic-structure-amp-permission-groups"></a>

The `punishment.yml` utilizes a Group-based structure. The system uses the `default` group natively.

**Permission-Based Punishment Adjustments:**\
Spiter supports assigning different punishment groups to players with specific permissions. Upon login, the system checks if the player holds the `spiter.&lt;group_name&gt;` permission. If they do, that group's configuration is applied instead of the `default`. This is highly useful for **lenient checks for VIP players** or **strict checks in specific game modes**.

```yaml
# Default configuration (normal players)
default:
  combat_reach:
    # Standard punishment logic

# When a player has the `spiter.vip` permission, this block is used (e.g., warn only, no kicks)
vip:
  combat_reach:
    # Lenient logic for VIPs复制
```

***

### 2. Core Configuration Keys <a href="#id-2-core-configuration-keys" id="id-2-core-configuration-keys"></a>

Each detection block is composed of the following four core attributes:

#### 2.1 `check` (Triggers) <a href="#id-21-codecheckcode-triggers" id="id-21-codecheckcode-triggers"></a>

Used to bind the detection names that trigger this punishment rule.

* **Exact Match:** Enter the exact detection name (e.g., `combat.reach`).
* **Wildcard Match:** Use `*` to match all detections in a category (e.g., `combat.clk.*`).
* **Exclude Match:** Use `!` to exclude specific detections (e.g., `!combat.clk.b`).
* **Weight Adjustment:** Use `:&lt;multiplier&gt;` to adjust the VL (Violation Level) weight generated by that detection.

```yaml
check:
  - "combat.reach"       # Exact match for a single detection
  - "combat.hitbox:2.0"  # Generate 2x VL when hitbox is triggered
  - "combat.clk.*"       # Match all auto-clicker detections
  - "!combat.clk.b"      # Exclude combat.clk.b from being processed here复制
```

#### 2.2 `decay` (VL Decay Mechanism) <a href="#id-22-codedecaycode-vl-decay-mechanism" id="id-22-codedecaycode-vl-decay-mechanism"></a>

Controls how quickly a player's Violation Level (VL) decreases after they stop cheating. A reasonable decay configuration effectively prevents false positives caused by long-term accumulation.

```yaml
decay:
  interval: 20   # Decay check interval in seconds (runs every 20s)
  amount: 5      # Amount of VL to deduct per interval (-5 VL)复制
```

#### 2.3 `intervals` (One-time Punishment Thresholds) <a href="#id-23-codeintervalscode-one-time-punishment-thresholds" id="id-23-codeintervalscode-one-time-punishment-thresholds"></a>

When a player's VL reaches a specified threshold for the **first time**, the system executes the corresponding actions. Once completed, if there are no higher thresholds, the VL will be reset.

> 💡 **Tip:** It is highly recommended to add prefixes to your actions. If you need to execute multiple commands simultaneously, use the YAML list format.

```yaml
intervals:
  5: "[notify] spiter internals notify %prefix%%trscolor%%player%&r maybe using reach hack"
  15: 
    - "[notify] spiter internals notify %prefix%%trscolor%%player%&r is using reach hack (#2)"
    - "[command] kick %player% You have been kicked for cheating." # Kick triggered at 15 VL复制
```

#### 2.4 `loop` (Cyclic Punishments) <a href="#id-24-codeloopcode-cyclic-punishments" id="id-24-codeloopcode-cyclic-punishments"></a>

Unlike the one-time execution of `intervals`, `loop` is used to configure actions that trigger repeatedly. When the VL reaches the threshold, the action is executed, the threshold value is subtracted from the VL, and it continues to accumulate, thereby achieving periodic punishments.

```yaml
loop:
  5: "[mitigation] attack_damage" # Trigger damage reduction for every 5 VL accumulated复制
```

***

### 3. Available Action Prefixes & Variables <a href="#id-3-available-action-prefixes-amp-variables" id="id-3-available-action-prefixes-amp-variables"></a>

#### 3.1 Action Prefixes <a href="#id-31-action-prefixes" id="id-31-action-prefixes"></a>

Spiter supports the following three execution methods. Please use the corresponding prefix when configuring actions:

| Prefix             | Description                                                                                              |
| ------------------ | -------------------------------------------------------------------------------------------------------- |
| **`[command]`**    | (Default) Executes the command from the console.                                                         |
| **`[notify]`**     | Sends an internal alert message to administrators with the `spiter.internals.notify` permission.         |
| **`[mitigation]`** | Triggers low-level mitigations to forcibly prevent cheating behaviors, without needing external plugins. |

**Available `[mitigation]` types:**

* `damage_tick`: Reset attack damage timer
* `attack_damage`: Cancel next attack damage
* `movement`: Force setback player location
* `food_level`: Reset food consumption
* `extra_velocity`: Clear extra velocity
* `block_place`: Cancel block placement
* `block_break`: Cancel block breaking

#### 3.2 Variables (Placeholders) <a href="#id-32-variables-placeholders" id="id-32-variables-placeholders"></a>

In `[command]` and `[notify]` actions, you can use the following placeholders, which the system will replace with live data:

* `%player%`: Player's name
* `%check%`: The specific detection node triggered (e.g., combat.reach)
* `%alertsName%` / `%checkName%`: Display name of the detection
* `%vl%` / `%maxvl%`: Current VL / Threshold VL
* `%ping%`: Player's latency
* `%version%`: Client version
* `%brand%`: Client brand (e.g., forge, vanilla)
* `%id%`: A randomly generated ban/kick ID for tracking
* `%anticheat%`: A random anti-cheat name fetched from config

***

### List <a href="#fu-lu-jian-ce-ming-da-quan" id="fu-lu-jian-ce-ming-da-quan"></a>

* **combat :** `combat.hitbox`, `combat.block`, `combat.entity`, `combat.reach`, `combat.backtrack.*`, `combat.autototem.*`, `combat.clk.*` ,`ka.ab.*`, `ka.flag.*`, `abt.analysis.*`, `move.ack`
* **sfd :** `sfd.place.*`, `sfd.ray.*`, `sfd.rotation.*`, `sfd.bp.*`, `sfd.clk.a`, `sfd.twr.*`
* **vel :** `vel.intave`, `vel.aug`, `vel.motion`, `vel.d`, `vel.e`, `vel.f`, `vel.g`, `vel.ground`, `vel.hor`, `vel.tick`, `vel.gf`
* **bp :** `bp.rec.*`, `bp.timer.low`, `bp.net.*` `bp.noslow.*`, `bp.dupe.*`, `bp.entity.*`, `bp.post.a`
* **move :** `move.gf.*` , `move.elytra.*` , `move.noslow.*`
* **survive :** `survive.mining.*` , `survive.autofish.*`&#x20;
* **block :** `block.break.*`&#x20;
* **interact :** `interact.air`, `interact.place`, `interact.break.*`
* **inv:** `inv.csl.*`&#x20;
* **heur :** `heur.*`
* **invalid :** `invalid.move.*`
* **phase :** `phase.main`

List：

* `abt.analysis.b`, `abt.analysis.c`, `abt.analysis.d`, `abt.analysis.e`, `abt.analysis.f`, `abt.analysis.g`, `abt.analysis.h`, `abt.analysis.i`, `abt.analysis.j`, `abt.analysis.k`, `abt.analysis.n`, `abt.analysis.o`, `abt.analysis.p`, `abt.analysis.q`, `abt.analysis.r`, `abt.analysis.s`, `abt.analysis.t`, `abt.analysis.u`, `abt.analysis.v`, `abt.analysis.w`, `abt.analysis.x`, `abt.analysis.y`, `abt.analysis.z`, `abt.analysis.z2`, `abt.analysis.a1`, `abt.analysis.3`, `abt.analysis.4`, `abt.analysis.5`, `abt.analysis.8`, `abt.analysis.8b`, `abt.analysis.9`, `abt.analysis.10`, `abt.analysis.11`, `abt.analysis.12`, `abt.analysis.13`, `abt.analysis.14`, `abt.analysis.15`, `abt.analysis.16`, `abt.analysis.17`, `abt.analysis.b2`, `abt.analysis.c2`
* `block.break.stm`, `block.break.ftm`, `block.break.invalidA`, `block.break.invalidB`, `block.break.invalidC`, `block.break.invalidD`, `block.break.invalidE`, `block.break.invalidF`, `block.break.invalidG`
* `bp.dupe.a`, `bp.dupe.b`
* `bp.entity.i`, `bp.entity.c`, `bp.entity.d`, `bp.entity.e`
* `bp.net.b`, `bp.net.c`, `bp.net.d`, `bp.net.e`, `bp.net.f`, `bp.net.g`
* `bp.noslow.a`, `bp.noslow.b`, `bp.noslow.c`, `bp.noslow.d`, `bp.noslow.e`, `bp.noslow.f`, `bp.noslow.g`, `bp.noslow.h`, `bp.noslow.i`, `bp.noslow.j`, `bp.noslow.n`, `bp.noslow.sneak`
* `bp.post.a`
* `bp.rec.1`, `bp.rec.3`, `bp.rec.4`, `bp.rec.5`, `bp.rec.b`, `bp.rec.c`, `bp.rec.d`, `bp.rec.e`, `bp.rec.f`, `bp.rec.g`, `bp.rec.gamemode`, `bp.rec.h`, `bp.rec.i`, `bp.rec.j`, `bp.rec.k`, `bp.rec.l`, `bp.rec.m`, `bp.rec.n`, `bp.rec.o`, `bp.rec.p`, `bp.rec.payload`, `bp.rec.q`, `bp.rec.r`, `bp.rec.s`, `bp.rec.t`, `bp.rec.tick`, `bp.rec.u`, `bp.rec.v`, `bp.rec.w`, `bp.rec.x`, `bp.rec.y`, `bp.rec.z`
* `bp.timer.low`
* `combat.autototem.a`, `combat.autototem.b`
* `combat.backtrack.a`, `combat.backtrack.b`, `combat.backtrack.c`, `combat.backtrack.d`, `combat.backtrack.e`, `combat.backtrack.f`, `combat.backtrack.g`, `combat.backtrack.h`, `combat.backtrack.i`, `combat.backtrack.j`
* `combat.block`, `combat.clk.left`, `combat.clk.right`, `combat.clk.b`, `combat.clk.c`, `combat.clk.d`, `combat.clk.e`, `combat.clk.f`, `combat.clk.g`, `combat.clk.h`, `combat.clk.i`, `combat.clk.j`, `combat.clk.k`, `combat.clk.l`, `combat.clk.m`, `combat.clk.n`, `combat.clk.o`, `combat.clk.p`, `combat.clk.q`, `combat.clk.r`, `combat.clk.s`, `combat.clk.t`, `combat.clk.u`, `combat.clk.v`, `combat.clk.w`, `combat.clk.x`, `combat.clk.y`, `combat.clk.z`, `combat.clk.1`, `combat.clk.2`, `combat.clk.3`, `combat.clk.4`, `combat.clk.5`, `combat.clk.6`, `combat.clk.7`, `combat.clk.8`, `combat.clk.9`, `combat.clk.10`, `combat.clk.11`
* `combat.entity`, `combat.hitbox`, `combat.reach`
* `heur.b`, `heur.c`, `heur.d`, `heur.e`, `heur.f`
* `interact.air`, `interact.break.b`, `interact.break.c`, `interact.break.d`, `interact.break.e`, `interact.place`
* `invalid.move.a`, `invalid.move.d`
* `inv.csl.a`, `inv.csl.b`, `inv.csl.c`, `inv.csl.d`, `inv.csl.f`, `inv.csl.g`
* `ka.ab.a`, `ka.ab.b`, `ka.ab.c`, `ka.ab.d`, `ka.ab.d2`, `ka.ab.e`, `ka.ab.f`, `ka.ab.g`, `ka.ab.h`, `ka.ab.i`, `ka.ab.j`, `ka.ab.k`, `ka.ab.l`, `ka.ab.m`, `ka.ab.n`, `ka.ab.o`, `ka.ab.p`, `ka.ab.q`, `ka.ab.r`, `ka.ab.s`, `ka.ab.t`, `ka.ab.u`, `ka.ab.v`, `ka.ab.w`, `ka.ab.x`, `ka.ab.y`, `ka.ab.z`, `ka.ab.1`, `ka.ab.3`, `ka.ab.4`
* `ka.flag.a`, `ka.flag.b`, `ka.flag.c`, `ka.flag.d`, `ka.flag.e`, `ka.flag.g`, `ka.flag.i`, `ka.flag.j`, `ka.flag.k`, `ka.flag.l`, `ka.flag.m`, `ka.flag.n`, `ka.flag.o`, `ka.flag.p`, `ka.flag.q`, `ka.flag.r`, `ka.flag.r2`, `ka.flag.s`, `ka.flag.t`, `ka.flag.u`
* `move.ack`
* `move.elytra.synca`, `move.elytra.syncb`, `move.elytra.syncc`, `move.elytra.action`, `move.elytra.tick`, `move.elytra.glide`, `move.elytra.fly`, `move.elytra.ground`, `move.elytra.potion`, `move.elytra.car`, `move.elytra.water`
* `move.gf.fly`, `move.gf.fakeliquid`, `move.gf.plc`, `move.gf.vt`, `move.gf.block`
* `move.noslow.potion`, `move.noslow.food`, `move.noslow.bow`, `move.noslow.item`
* `phase.main`
* `sfd.bp.a`, `sfd.bp.b`, `sfd.bp.c2`, `sfd.bp.d`, `sfd.bp.e`, `sfd.bp.f`, `sfd.bp.g`, `sfd.bp.h`, `sfd.bp.i`, `sfd.bp.j`
* `sfd.clk.a`
* `sfd.place.a`, `sfd.place.b`, `sfd.place.c`, `sfd.place.d`, `sfd.place.e`, `sfd.place.f`, `sfd.place.g`, `sfd.place.h`, `sfd.place.i`, `sfd.place.j`, `sfd.place.k`, `sfd.place.l`, `sfd.place.m`, `sfd.place.n`, `sfd.place.o`, `sfd.place.p`, `sfd.place.q`, `sfd.place.r`, `sfd.place.s`, `sfd.place.t`
* `sfd.ray.a`, `sfd.ray.b`, `sfd.ray.c`, `sfd.ray.d`, `sfd.ray.e`, `sfd.ray.f`, `sfd.ray.g`, `sfd.ray.h`, `sfd.ray.i`, `sfd.ray.j`, `sfd.ray.l`, `sfd.ray.m`, `sfd.ray.n`
* `sfd.rotation.a`, `sfd.rotation.b`, `sfd.rotation.c`, `sfd.rotation.d`, `sfd.rotation.e`, `sfd.rotation.f`, `sfd.rotation.g`, `sfd.rotation.h`, `sfd.rotation.i`, `sfd.rotation.j`, `sfd.rotation.k`, `sfd.rotation.l`, `sfd.rotation.m`, `sfd.rotation.o`
* `sfd.twr.a`, `sfd.twr.b`, `sfd.twr.c`
* `survive.autofish.a`, `survive.autofish.b`
* `survive.mining.a`, `survive.mining.b`, `survive.mining.c`, `survive.mining.e`, `survive.mining.f` ,`survive.mining.d`
* `vel.intave`, `vel.aug`, `vel.motion`, `vel.d`, `vel.e`, `vel.f`, `vel.g`, `vel.ground`, `vel.hor`, `vel.tick`, `vel.gf`
