-
Notifications
You must be signed in to change notification settings - Fork 14
Events
Codex fires several custom events that plugins can listen to like any Bukkit event.
Fires when a player equips or unequips armor. Bukkit has no built-in event for this, and the ways armor can change are surprisingly varied — this event covers most of them.
ArmorType.matchTypereturnsMAIN_HANDfor any non-air, non-armor item, which is why the event also fires for ordinary items on held-slot changes and item consumption. It also mapsELYTRA→CHESTPLATE,SHIELD→OFFHAND, and any*_SKULL/*_HEAD→HELMET.Codex only fires the event when the piece actually changed (compared with
isSimilar), so no-op swaps are silent.
Fired by ArmorListener in codex-plugin — not by the NMS ArmorUtil, which handles armor trims
and is unrelated. See Compat and NMS.
@EventHandler
public void onArmorEquip(ArmorEquipEvent event) {
Player player = event.getPlayer();
ArmorType type = event.getType();
ItemStack oldPiece = event.getOldArmorPiece();
ItemStack newPiece = event.getNewArmorPiece();
if (type == ArmorType.HELMET && newPiece != null) {
player.sendMessage("Nice hat.");
}
}Cancellable — with one exception. Cancelling a BROKE event throws
UnsupportedOperationException; you cannot veto a durability break.
| Value | Slot |
|---|---|
HELMET |
39 |
CHESTPLATE |
38 |
LEGGINGS |
37 |
BOOTS |
36 |
OFFHAND |
40 |
MAIN_HAND |
-1 |
event.getMethod() tells you how the change happened:
| Method | Meaning |
|---|---|
SHIFT_CLICK |
Shift-clicking an armor piece |
DRAG |
Dragging the item into the slot |
PICK_DROP |
Manually placing or removing the item |
HOTBAR |
Right-clicking armor in the hotbar with the inventory closed |
HOTBAR_SWAP |
Pressing a hotbar number while hovering an armor slot |
DISPENSER |
A dispenser equipped the armor |
BROKE |
The piece lost all durability |
HELD_SLOT_CHANGE |
Changing held slot, altering the main-hand item |
DROP |
Using the drop key (Q by default) |
CONSUME |
Consuming a held item |
DEATH |
Declared but never fired — no death handler exists |
Filtering on the method matters for stat plugins: BROKE needs handling if your bonuses are tied to
the item, and DROP/CONSUME/HELD_SLOT_CHANGE fire for ordinary items, not just armor.
DISPENSERrequires the server version to implementBlockDispenseArmorEvent.Do not write logic against
DEATH— the constant exists but nothing emits it.
event.setNewArmorPiece(modifiedItem);
event.setOldArmorPiece(otherItem);Codex's packet layer fires events for intercepted traffic.
| Event | Fired for |
|---|---|
EnginePacketEvent |
Abstract base type — never fired directly |
EnginePlayerPacketEvent |
Outbound packets to a player — the only one actually fired |
EngineServerPacketEvent |
Declared but never constructed anywhere |
Only server → client packets are intercepted. The injected handler overrides
write()and notchannelRead(), so inbound client packets produce no event at all.
@EventHandler
public void onPacket(EnginePlayerPacketEvent event) {
Object packet = event.getPacket(); // opaque NMS object
Player p = event.getReciever(); // note the spelling in the API
// event.setPacket(...) to replace, or cancel to drop the packet entirely
}PacketManager.registerHandler(IPacketHandler) is the alternative extension point if you would
rather not use @EventHandler.
These are asynchronous Bukkit events, fired from the netty pipeline thread. Do not touch the Bukkit API directly from a packet handler — schedule work back onto the main thread:
Bukkit.getScheduler().runTask(plugin, () -> player.sendMessage("..."));Keep handlers short; they run for every matching packet.
IEvent and ICancellableEvent are abstract classes, not interfaces — events extend them.
| Class | Purpose |
|---|---|
IEvent |
Extends Bukkit's Event; supplies a shared HandlerList, a final getHandlers(), and an (boolean async) constructor |
ICancellableEvent |
Adds cancellation on top of IEvent
|
Only the packet events use this hierarchy. ArmorEquipEvent does not — it extends PlayerEvent
and implements Cancellable with its own HandlerList.
Every
IEventdescendant shares a single staticHandlerList, so a listener registered for any one of them is walked for all of them. Given these fire per outbound packet, keep such handlers cheap.
Standard Bukkit registration:
Bukkit.getPluginManager().registerEvents(new MyListener(), plugin);If your listener belongs to a menu, register it through the menu instead so it is cleaned up automatically — see Menus and GUIs:
registerListener(myListener);Codex also provides two base types for lifecycle handling tied to a manager. Note the naming is the
reverse of what you would expect: AbstractListener is the interface (extending Listener, with
registerListeners() and a default unregisterListeners()), and IListener<P> is the abstract
class implementing it.
Source · Issues · Discord · Maven repo
Server Owners
- Installation
- Configuration
- Commands
- Permissions
- Join and Interact Commands
- Localization
- Version Support
Deprecated
-
Chat Module
⚠️ -
Scoreboard Module
⚠️
Developers