Skip to content

Rules

Protect matches illegal items using rules — simple operators that catch unusual items or abnormal quantities.

Creating Custom Rule Files

By default, we ship rules/main.rs with examples and some preconfigured filters. You can remove it and create as many .rs files as you wish in the rules/ folder. We will automatically load all of them.

Do not remove the groups.rs file — it's used for Groups.

Groups

You can bulk the operators above together in the groups.rs file. Instead of "match", use group <name> to create a rule. Then reference this group in your rules files using group <name>.

That way, you can manage 100s of rules easily without having to copy-paste operators under every rule.

Creating A New Rule

We match against material names using our cross-version compatible name table.

Open rules/main.rs or create a new .rs file. Each line after the match starts with an operator.

Below, <> = required, [] = optional.

Must-Have Operators

match <materialName>

Each rule starts with "match". Five matching modes:

  1. *_AXE — ends with: matches all axes (DIAMOND_AXE, IRON_AXE, etc.)
  2. DIAMOND_* — starts with: matches all diamond items (DIAMOND_SWORD, DIAMOND_BLOCK, etc.)
  3. *KEY* — contains: matches anything containing KEY (DUNGEON_KEY, KEY_STONE, MASTERKEY)
  4. "DIAMOND" — exact: matches only DIAMOND
  5. GRASS — contains (unquoted, no asterisks): matches GRASS, TALL_GRASS, GRASS_BLOCK

Use | to combine: DIAMOND_*|"GOLDEN_HOE"

Protect does not support regular expressions in match by default. See "Using Regex" below.

Example:

match DIAMOND
match "DIAMOND"
match "DIAMOND_*"
match "*_AXE"
match GRASS|"STONE"
match "DIAMOND"|"STONE"

You can use | to separate multiple matches i.e. DIAMOND_*|"GOLDEN_HOE" etc.

# Limit diamond and emerald blocks for beginner players to max 1 in their inventory.
match "DIAMOND_BLOCK"|"EMERALD_BLOCK"
name valuable-block-beginner
ignore inventory amount 1
group beginner

Use '*' to match everything, example: "match *".

Minecraft Tag Matching

Use #tagName to match items belonging to a vanilla Minecraft tag. Tags are resolved at plugin load into material sets, so runtime matching is O(1).

Examples:

match #swords
match #enchantable/durability
match #anvil
match #swords|TRIDENT

Tags are looked up from the items registry first, then blocks. See the Minecraft Wiki for all available tags. Requires MC 1.13+.

# Block too long nbt item tags (use /protect iteminfo to inspect) that
# crash the client and the server.
match *
name nbt-too-long
require tag length 256
then confiscate

Using Regex

Prefix your match with * to use regex: * ^DIAMOND_(SWORD|HOE). Note: regex is slower since each inventory slot (41 slots) is checked per rule.

name <rule name>

Give a rule a name that is unique to this rule. You can use it later with the {rule_name} variable.

Example:

name too-much-beacon

Item-Related Operators

require/ignore cause <cause1>|<cause2>

Only proceed with the rule if the cause of the scan is included (or excluded) in the given list separated by |.

Available: manual (from /protect scan), period, player_join, player_death, world_change, command (any command configured in setting.yml), inventory_open, item_click and item_spawn

See settings.yml scan section to configure the above in detail.

Example:

ignore cause inventory_open|player_join
require cause item_spawn

require amount <number>

Only match if the item stack at the scanned slot exceeds the given amount. For total inventory count, use require inventory amount instead.

require name length <number>

Only match this rule if the item has a custom name and the custom name (without colors) exceeds the given size.

require name <name>

Only match this rule if the item has a custom name and the custom name (without colors) matches the given title.

We use the same 5 matching modes as the "match" operator so you can use * and "" here too. See the main match operator for documentation.

require lore length <number>

Only match this rule if the item has a custom lore and it (without colors) exceeds the given size.

require lore <line1|line2||line3>

Only match this rule if the item has a custom lore and it (without colors) matches the given lore.

We join the item's lore with "|".

Example: The item has lore

"A mythical Boss Egg lore"

To match this, use "require lore A mythical Boss|Egg lore"

We use the same 5 matching modes as the "match" operator so you can use * and "" here too. See the main match operator for documentation.

require durability <number with operand>

Only match this rule if the item's durability matches the given value. See examples below for syntax.

Example:

require durability 20 # match if durability is equal to 20
require durability > 5 # match if durability is 6 or greater
require durability >= 5 # match if durability is 5 or greater
require durability < 25 # match if durability is 24 or less
require durability <= 25 # match if durability is 25 or less

require potion amount <number>

Only match this rule if the item is a potion with at least the given amount of custom effects (potions can hold multiple custom effects and this is abused by hack clients, i.e. Wurst's Troll Potion).

Example:

require potion amount 2

require potion duration <durationTicks>

Only match this rule if the item is a potion and its effect lasts at least the given amount of ticks. Can be used to prevent infinite hacked potions.

Example:

require potion duration 20 # match effects lasting over 1 second

require potion amplifier <number>

Only match this rule if the item is a potion and its amplifier is at least the given number. Note that amplifier 0 means level 1, amplifier 1 means level 2 etc., because the base is 1 already.

Example:

require potion amplifier 1 # match potions level 2 or greater

require enchant level <number>

Only match this rule if the item has any enchant at least of the given level. See "ignore enchant" to ignore certain enchants.

require tag length <size>

Only match this rule if the item's NBT tag is equals or exceeds the given number. Used to match i.e. Crash Chest from Wurst. You can use "/protect iteminfo nbt" to view what NBT tag of a held item is.

Example:

require tag length 512

require persistent tag <key> <value>

Only match if the item's persistent metadata tag has the given key-value pair.

The value uses NBT prefix notation (e.g., 20b for byte tag 20). See Data types.

This only matches custom plugin-coded data tags. For vanilla NBT, use require script with the nbt instance.

Example:

require persistent tag CoreArena_Item true
require persistent tag Stamina 1b

require attribute value <amount>

Only match if the item has an attribute modifier whose absolute value equals or exceeds the given amount. Must be combined with check attribute modified.

Example:

check attribute modified
require attribute value 100

ignore inventory title <title>

Ignore items in containers with the given title (colors stripped).

Protect ignores custom-sized and custom-named inventory titles by default.

Example:

ignore inventory title Spartan AntiCheat

ignore tag <key>

Ignore the item has the given NBT tag. We use NBT-API library and check NBTItem#hasTag(key) so it will work if the tag is set at the root level.

For example, our Boss plugin puts a tag with key Boss_V4 and value of the Boss name to each mob spawning egg before it's given to the player. To prevent its confiscation, you can use the following example:

Example:

ignore tag Boss_V4

ignore material <material1>|<material2>

Ignore the item if its material is one of https://mineacademy.org/materials. Use | to separate multiple materials. We evaluate each as equals.

Supports *, see the main "match" at the top.

Example:

ignore material STONE
ignore material PLAYER_HEAD|PLAYER_WALL_HEAD

ignore inventory amount <totalAmount>

Ignore the scan if the container with player inventory combined contains less than the given amount of matching items.

When the rule has require name or require lore, only items matching those conditions are counted — not all items of the same material type.

Example: If I hold 5x diamonds and I open a chest with 10x diamonds, together the container + my inventory hold 15x diamonds. If you want the scan to match when there is a total of 50x diamonds, you set the totalAmount to 50.

Example:

ignore inventory amount 50

ignore displayname <pattern>

Ignore items whose display name (colors stripped) matches the pattern. Supports wildcard matching.

Example:

ignore displayname *Custom Weapon*

ignore lore <pattern>

Ignore items whose lore (lines joined with |, colors stripped) matches the pattern. Supports wildcard matching.

Example:

ignore lore *Quest Item*

ignore modeldata <number>

Ignore items with the given custom model data value.

Example:

ignore modeldata 12345

ignore enchant <enchantName>

Ignore the scan if the item contains the given enchant. See this link for valid enchant types.

Example:

ignore enchant PROTECTION_EXPLOSIONS

ignore enchantlevel <level>

Ignore the scan if the item has only enchants less or equal the given level. Useful if your custom plugin gives enchants higher than vanilla.

Example:

ignore enchantlevel 12

check stack size

Fire this rule if the item at the scanned slot is unnaturally stacked. I.e. 64x diamond swords when there can only be 1 per slot.

Example:

check stack size

check enchant not-applicable

Fire this rule if the item at the scanned slot has an enchant that is not possible to add on this item type with vanilla rules.

Example:

check enchant not-applicable

check enchant too-high

Fire this rule if the item at the scanned slot has an enchant with a level that is higher than vanilla rules permit.

See "ignore enchantlevel" to tweak this setting.

Example:

check enchant too-high

check enchant conflicting

Fire this rule if the item has two or more enchantments that conflict with each other (e.g. Sharpness + Smite, Protection + Blast Protection). Vanilla Minecraft prevents this combination, so it indicates a hacked item.

Example:

check enchant conflicting

check unbreakable

Fire this rule if the item has the unbreakable flag set. This flag cannot be obtained in survival without commands or hacks.

Example:

check unbreakable

check attribute modified

Fire this rule if the item has custom attribute modifiers (e.g. custom damage, speed, armor values). Combine with require attribute value to only match modifiers above a threshold.

Example:

check attribute modified
require attribute value 100

then disenchant

Remove all enchantments from the item.

Example:

then disenchant

then nerf

Reduce the enchant level to the maximum allowed by vanilla.

Example:

then nerf

then strip-attributes

Remove all custom attribute modifiers from the item, keeping the item itself intact. Useful with check attribute modified.

Example:

then strip-attributes

then strip-nbt

Strip all NBT data from the item, keeping only the material type and stack amount. This is the nuclear option — the item loses its name, lore, enchantments, and all other data.

Example:

then strip-nbt

Component Operators (1.21+)

These operators detect and strip hacked item components added via NBT editors or hacked clients. They require Minecraft 1.21+ and are silently skipped on older versions.

check hide-tooltip

Fire this rule if the item has a hidden tooltip (the entire tooltip is suppressed so players can't see what the item really is).

Example:

check hide-tooltip

check illegal food

Fire this rule if the item has a food component that doesn't belong on this item type in vanilla. E.g. a sword made edible.

check illegal food

check illegal consumable

Fire this rule if the item has a consumable component that doesn't belong on this item type in vanilla. Catches items with custom on-consume effects (potion effects, teleport, etc.).

check illegal consumable

check illegal equippable

Fire this rule if the item has an equippable component that doesn't belong on this item type in vanilla. E.g. a pickaxe wearable as a helmet.

check illegal equippable

check illegal rarity

Fire this rule if the item has a rarity component that doesn't belong on this item type in vanilla.

check illegal rarity

check illegal death-protection

Fire this rule if the item has a death protection component that doesn't belong on this item type in vanilla. E.g. an enchanted golden apple that grants custom effects on death.

check illegal death-protection

check illegal damage-resistant

Fire this rule if the item has a damage resistance component that doesn't belong on this item type in vanilla.

check illegal damage-resistant

check illegal tool

Fire this rule if the item has a tool component that doesn't belong on this item type in vanilla.

check illegal tool

check enchantment-glint-override

Fire this rule if the item has a forced enchantment glint override (making it glow or suppressing the glow).

check enchantment-glint-override

check illegal components

Catch-all: fire this rule if the item has ANY component that doesn't exist on the vanilla version of that item type. This is the broadest check and catches all of the above in one rule.

check illegal components

check illegal <name>

Check any component by name. You can use any Minecraft data component name with dashes instead of underscores. The 8 built-in names above are shortcuts for this syntax.

check illegal attack-range

ignore component

Whitelist specific components so check illegal components and then strip-components skip them. Use pipe | to list multiple. This is essential when using the catch-all to avoid stripping legitimate components like enchantments or custom names.

ignore component enchantments|repair_cost|custom_name|lore|custom_data|custom_model_data

See the Minecraft Wiki for all available component names.

then strip-hide-tooltip

Remove the hidden tooltip from the item.

then strip-food

Remove the food component from the item.

then strip-consumable

Remove the consumable component from the item.

then strip-equippable

Remove the equippable component from the item.

then strip-rarity

Remove the rarity component from the item.

then strip-death-protection

Remove the death protection component from the item.

then strip-damage-resistant

Remove the damage resistance component from the item.

then strip-tool

Remove the tool component from the item.

then strip-enchantment-glint

Remove the enchantment glint override from the item.

then strip-components

Remove ALL non-vanilla components from the item at once. Respects ignore component whitelist. Pair with check illegal components for a catch-all rule:

match *
name illegal-components
check illegal components
ignore component enchantments|repair_cost|custom_name|lore|custom_data|custom_model_data
then strip-components

then strip-<name>

Strip any component by name. You can use any Minecraft data component name with dashes instead of underscores. The 8 built-in names above are shortcuts for this syntax.

then strip-attack-range

then clone

Silently clone the item into the logs table. View with /protect logs.

To prevent duplicate clones, we add an invisible NBT tag (makes the item unstackable).

Example:

then clone

then confiscate excess

Attempts to remove the excessive amount of matching items from the inventory and logs to the database. Use "/protect logs" to view.

When the rule has require name or require lore, only items matching those conditions are removed — other items of the same material type are left untouched.

Requires "require inventory amount" to be set. Example: I hold 64x beacons. The "require inventory amount" is set to 10. After "then confiscate excess" is fired, Protect will take 54x beacons so I am left with 10x in my inventory.

Example:

then confiscate excess

then confiscate

Remove the item at the scanned slot from the inventory and logs to the database. Use "/protect logs" to view.

Requires "require inventory amount" to be set. Example: I hold 64x beacons. The "require inventory amount" is set to 10. After "then confiscate excess" is fired, Protect will take 54x beacons so I am left with 10x in my inventory.

Example:

then confiscate

Standard Operators

group <group name>

Assign a group to the rule. Multiple rules can have the same group to share operators into. See Groups for more info.

Example:

group advertisement

begins and expires

Begins means the date on which we start executing this rule. Expires means the date after which we stop executing this rule. This is a great addition to pre-create rules for the holiday or special events!

Examples:

begins 24 Dec 2023, 00:00
expires 31 Dec 2023, 23:59

Or you can even use variables to replace with the current timestamp:

# This will broadcast from 24 Dec to 31 Dec each year.
begins 24 Dec {year}, 00:00
expires 31 Dec {year}, 23:56

# This will broadcast between 0 and 30th minute of each hour
begins {day} {month} {year}, {hour}:00
expires {day} {month} {year}, {hour}:30

delay <time> [message]

How much time to wait before running this rule again? This is reset upon /reload or server restart.

This delay is applied globally to all users.

delay 6 seconds
delay 6 seconds You must wait {delay} seconds before triggering this rule again!

player delay <time> [message]

How much time to wait before running this rule again for this player? This is reset upon /reload or server restart.

Works similar to the above operator, however, the "player delay" operator only affects a single user.

player delay 6 seconds
player delay 6 seconds You must wait {player_delay} seconds before triggering this rule again!

require perm <permission> [message]

An optional permission that, if set, will make the rule only execute if the sender has it. You can also specify what message will be sent to the player if he lacks the permission.

Example:

require perm protect.rule.special
require perm protect.rule.special {error_prefix} You lack the ‘{permission}’ for this action.

require script <javascript returning a boolean>

JavaScript that must return true for the rule to execute. Use player for the Bukkit Player instance (nullable) and nbt for the NBT-API NBTItem instance.

Warning

JavaScript knowledge required. We don't offer help with creating custom scripts.

Example:

require script player.getHandle().ping > 10
require script nbt.hasCompount("CustomItem")

require gamemode <survival/creative/adventure/spectate>

Only apply rule if sender has the given gamemode. You can use | to specify multiple gamemodes to require.

Example:

require gamemode creative
require gamemode adventure|spectate

require world <world name>

If sender is not within any of the given world(s), ignore the rule. Use | to separate multiple worlds to ignore.

Example:

require world flat
require world flat|flat_nether

require region <region name>

If sender is not within any of the given region(s), ignore the rule. Use | to separate multiple regions to ignore.

Example:

require region warzone
require region warzone|peacezone

require key <key name>

Require the custom data key to be set using the "save key" operator elsewhere to execute this rule.

Example:

require key player-name

ignore key <key name>

Ignore the custom data key if set using the "save key" operator elsewhere from executing this rule.

Example:

ignore key player-name

save key <key> <value>

Save a custom key to player's data (permanent, survives reload).

The value is evaluated as JavaScript. To save a plain string like "tree", wrap it in quotes: save key 'tree'. Use player variable for the Bukkit Player class.

Example:

save key player-name <key>

require playtime <human readable format>

Only execute this rule if the player has spent at least the given amount of time on the server. Use /protect playtime to view playtime of players. Please note that this is per-server and not sync over bungee/velocity. This data is stored in your world/playerdata dat file.

Example:

require playtime 1 hour

ignore perm <permission>

A permission the sender will have to bypass the rule.

ignore script <javascript returning a boolean>

See "require script", except that, if this script here returns true, the rule will not be applied.

ignore gamemode <survival/creative/adventure/spectate>

If sender has the given gamemode, the rule will not apply for him. You can use | to specify multiple gamemodes to ignore.

Example:

ignore gamemode creative
ignore gamemode adventure|spectate

ignore world <world name>

If sender is in the given world, bypass the rule. Use | to separate multiple worlds to ignore.

Example:

ignore world anarchy
ignore world anarchy|anarchy _nether|anarchy _the_end

ignore region <region name>

If sender is the given region(s), bypass the rule. Use | to separate multiple regions to ignore.

Example:

ignore region warzone
ignore region warzone|peacezone

ignore playtime <human readable format>

Do not execute this rule if the player has spent the given amount of time or more on the server. Use /protect playtime to view playtime of players. Please note that this is per-server and not sync over bungee/velocity. This data is stored in your world/playerdata dat file.

Example:

ignore playtime 12 hours
ignore playtime 1 day
ignore playtime 60 minutes

then command <command1|command2>

Commands that will be executed in the given order as the sender, with his permissions. Use | to define multiple commands, and use the {player} variable to get the player.

then console <command1|command2>

Commands that will be executed in the given order from the console, with server privileges. Use | to define multiple commands, and use the {player} variable to get the player.

then bungeeconsole <server> <command1|command2>

Temporarily Disabled

This operator is currently disabled in the latest version of Protect.

then log

Log a message to the console.

Example:

then log {player} at {world} {x} {y} {z} has triggered this rule!

then kick <reason>

If specified, player will be kicked with the given message. Use the {player} variable to get the player and other variables normally.

then toast [material] [style] <message>

Sends a toast notification to the player. Styles available are CHALLENGE, GOAL and TASK

then toast Hello world!
then toast WITCH_SPAWN_EGG Hello world!
then toast WITCH_SPAWN_EGG CHALLENGE Hello world!

then notify <permission> <message>

Send the given message to every other player on your network/server that has the given permission. Used for staff notifications. You need ChatControl Red and VelocityControl or BungeeControl Red if you want cross-server sync.

Example:

then notify protect.alert.admins &8[&4{rule_name} violation&8] &c{player} got his {item_type} confiscated

then discord <channel> <message>

Requires DiscordSRV. Send a message to the given Discord channel. Use the {player} variable to get the player and other variables normally.

then write

Write a message to the file.

Example:

then write logs/swear.log {player} at {world} {x} {y} {z} has triggered this rule with: {original_message}

then fine <amount>

If specified, and you have Vault plugin installed, we will take the given amount of your currency from the player's bank account. Do not specify the currency symbol.

Example:

then fine 100

then sound <name> <volume> <pitch>

Plays a sound to the player.

Select the sound names from the following link:

https://github.com/kangarko/Foundation/blob/master/src/main/java/org/mineacademy/fo/remain/CompSound.java

Example:

then sound ENTITY_ARROW_HIT_PLAYER 1.0 0.1

then title <title|subtitle|fadeIn|stay|fadeOut>

Send a title with subtitle to the player, if possible. Use the {player} variable to get the player and other variables normally. Split the message with | to send the other part as subtitle. The fadein, stay and fadeout values are in ticks (20 = 1s), and they are not necessary.

Example:

then title &6Hi {player}|&cThis is a subtitle
then title &6Hi {player}|&cThis is a subtitle|10|60|10

then actionbar <message>

Send action bar message to the player, if possible. Use the {player} variable to get the player and other variables normally.

then bossbar <color> <style> <seconds to show> <message>

Send boss bar to the player, if possible. For message, use the {player} variable to get the player and other variables normally.

Use this link to select a color:

https://github.com/kangarko/Foundation/blob/master/src/main/java/org/mineacademy/fo/remain/CompBarColor.java

Use this link to select a style:

https://github.com/kangarko/Foundation/blob/master/src/main/java/org/mineacademy/fo/remain/CompBarStyle.java

then warn <message>

Optional message to send to the player. Use | to define multiple messages, one of which will be selected randomly. Use the {player} variable to get the player and other variables normally.

To send multiline warn messages, you can use multiple "then warn" operators multiple times on new lines.

then abort

Stop processing rules that follow after this one. We process rules from top to bottom of your files.

Example:

then abort

dont log

Prevent the rule from being logged into "/protect logs".

Example:

dont log

dont verbose

Prevent the rule from printing "MATCHED **" and similar messages to console.

Example:

dont verbose

disabled

Makes this rule load to memory but be disabled.

Example:

disabled