Infinite Item - one that always stays at max stack size. | Action (Event Handler) | Blocks Protected? | Blocks Final? | Notes / Hand Nuance | |--------------------------------------------------------------|---------------------------------|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **onCraftItem**
(`CraftItemEvent`) | ✅ result | ✅ ingredients when modifying | Only cancels crafting **Protected** results. For **Final** ingredients it uses a heuristic (`isModifyingCraft`) to see if the recipe would alter the item. | | **onSmithingTableUse**
(`PrepareSmithingEvent`) | ✅ result | ✅ base or addition | Smithing always “modifies” the base; both base and addition are checked for **Final**. | | **onEnchantItem**
(`EnchantItemEvent`) | ❌ (Protected can be enchanted) | ✅ item | Only checks the single item in the enchanting slot (no off-hand concept). | | **onPrepareEnchant**
(`PrepareItemEnchantEvent`) | ❌ | ✅ item | Prevents placing a **Final** item into the table; no hand distinction. | | **onAnvilUse**
(`PrepareAnvilEvent`) | ✅ result | ✅ first/second if modifying | Heuristic same as crafting. Cancels creation of **Protected** results and any **Final** input being “modified.” | | **onBrew**
(`BrewEvent`) | ✅ ingredient & results | ✅ bottles | Checks the single “ingredient” slot for **Protected**, then all bottle slots for **Final**. | | **onBrewingStandFuel**
(`BrewingStandFuelEvent`) | ✅ fuel | ❌ | Only checks the one fuel slot. | | **onFurnaceBurn**
(`FurnaceBurnEvent`) | ❌ | ✅ fuel | Only the one fuel slot. | | **onFurnaceSmelt**
(`FurnaceSmeltEvent`) | ✅ result | ✅ source | Checks both source (no fuel here) for **Final** and result for **Protected**. | | **onSpecialCraft**
(`PrepareItemCraftEvent`) | ✅ result | ✅ various inputs | Covers Loom, Cartography, Grindstone, Stonecutter. Only the specific input slots per inventory type are checked for **Final**. | | **onCauldron**
(`CauldronLevelChangeEvent`) | ❌ | ✅ main & off | Explicitly checks both `getItemInMainHand()` **and** `getItemInOffHand()` for **Final**. | | **onCommand**
(`PlayerCommandPreprocessEvent`) | ❌ | ✅ main & off | Checks both hands’ items against configured command-regex; if the command could modify a **Final** item in either hand, it’s cancelled. | | **onPickUp**
(`EntityPickupItemEvent`) | ✅ non-player only | ❌ | Only blocks non-players from picking up **Protected** items. | | **onBlockPlace**
(`BlockPlaceEvent`) | ✅ in-hand item | ❌ | Uses `event.getItemInHand()` (the hand used) to prevent placing **Protected** items. | | **onPlayerInteract**
(`PlayerInteractEvent`) | ✅ item | ✅ only when filling bottles | Blocks any use of **Protected** items. For **Final**, only blocks filling a bottle/bucket (checks both material and water target), using `event.getItem()` (hand-sensitive). | | **onBucketEmpty**
(`PlayerBucketEmptyEvent`) | ✅ hand item | ✅ hand item | Uses `event.getHand()` to locate the bucket (main vs. off) and blocks emptying either **Protected** or **Final** buckets. | | **onBucketFill**
(`PlayerBucketFillEvent`) | ✅ hand item | ✅ hand item | Same as empty: checks bucket in the hand specified by `event.getHand()`. | | **onBucketFish**
(`PlayerBucketEntityEvent`) | ✅ original bucket | ✅ original bucket | Uses `event.getOriginalBucket()`, so it covers the bucket used to capture an entity (no main/off distinction here). | | **onPlayerInteractEntity**
(`PlayerInteractEntityEvent`) | ✅ hand item | ❌ | Uses `event.getHand()`, but only blocks **Protected** items. | | **onItemConsume**
(`PlayerItemConsumeEvent`) | ✅ item | ❌ | Single `event.getItem()`, blocks **Protected** consumables only. | | **onBowShoot**
(`EntityShootBowEvent`) | ✅ bow or ammo | ✅ bow | Checks both the bow (main hand item) and the ammo for **Protected**, and stops any **Final** bow use. | | **onProjectileLaunch**
(`ProjectileLaunchEvent`) | ✅ held item (incl. projectiles) | ❌ | Looks at `ItemStack` in hand or from the projectile’s `getItem()`. | | **onAttack**
(`EntityDamageByEntityEvent`) | ✅ main hand item | ❌ | Only checks `player.getInventory().getItemInMainHand()`. | | **onBreakBlock**
(`BlockBreakEvent`) | ✅ main hand item | ❌ | Same: only the main hand tool is checked. | | **onDispense**
(`BlockDispenseEvent`) | ✅ dispensed item | ❌ | Does not consider any player hand. | | **onItemDamage**
(`PlayerItemDamageEvent`) | ❌ | ✅ item | Prevents durability loss on **Final** items (single item context). | | **onItemMend**
(`PlayerItemMendEvent`) | ❌ | ✅ item | Prevents XP-mending of **Final** items. | | **onBlockDrop**
(`BlockDropItemEvent`) | ✅ world drops | ❌ | Filters out **Protected** item drops from any block. | | **onItemSpawn**
(`ItemSpawnEvent`) | ✅ world spawns | ❌ | Cancels spawning of **Protected** items from non-player sources. | | **onInventoryClick**
(`InventoryClickEvent`) | ✅ protected in trade result | ❌ | Only blocks taking **Protected** items from a villager “RESULT” slot (no check on **Final**). | | **onInventoryMove**
(`InventoryMoveItemEvent`) | ✅ item | ❌ | Prevents hoppers/droppers from moving **Protected** items only. |