Bug Fixes
Vanish packet crash — ProtocolLib 5.4.0 on Paper 26.1.2 cannot rewrite the immutable ClientboundPlayerInfoUpdatePacket (final actions field), which crashed every player join. Packet-level tab-list hiding removed for this version; entity-level vanish still fully hides players.
Recipe craft crash — runtime recipe reload was rebuilding per-recipe caches, leaking a stonecutter SingleItemRecipe into crafting-grid matches and throwing ClassCastException on every grid change. All recipe registration now batches and resyncs once.
EditBox invisible — screens that override extractRenderState must render child widgets manually (framework skips them when super is omitted). All screens now render EditBox/MultiLineEditBox widgets.
CustomPacketPayload.createType("esmpmod:…") crash — createType applies the minecraft: namespace automatically, producing illegal double-colon paths. Replaced with new Type<>(Identifier.fromNamespaceAndPath(…)).
Config Changes
All new options live in config.yml:
# config.yml
sync-enabled: true # removed — service layer is always-on
anti-health-indicator:
enabled: true
health-index: 9
warnings:
mute-at: 3
mute-duration-minutes: 60
tempban-at: 5
tempban-duration-hours: 24
permban-at: 7
discord:
enabled: false
webhook-url: ""
chat-messages: true
deaths: true
join-quit: true
punishments: true
death-messages:
enabled: false
default: "&7{victim} died."
by-player: "&c{victim} &7was slain by &c{killer}&7."
by-player-with-weapon: "&c{victim} &7was slain by &c{killer} &7using &c{weapon}&7."
New Features
Warning System (/warn, /warns, /clearwarns, /delwarn) — staff issue warnings against any player (online or offline). Config-driven escalation automatically mutes at 3, tempbans at 5, and permbans at 7 active warnings. All thresholds and durations live in config.yml.
Player Reports (/report, /reports, /closereport) — any player can file a report via /report <player> <reason>. Online staff with esmp.reports permission are notified immediately. Staff can list open reports and close them by id.
Player Notes (/note, /notes, /delnote) — every player can leave and read notes about any player (online or offline). Notes are stored per-subject in notes/<uuid>.yml. Staff can delete notes by index.
Playtime Tracking — session-based playtime counters with 5-minute periodic flush. Exposed as %esmp_playtime% (formatted: Xd Yh Zm) and %esmp_playtime_seconds% (raw). Leaderboard supports playtime as a sort option.
Discord Webhook Bridge — posts chat, death, join/quit, and punishment events to a Discord channel via webhook. All toggles gated in discord.* config. Fully async (JDK HttpClient, no external libraries). Punishment notifications fire from ban/mute/kick/warn commands automatically.
Custom Death Messages — replace vanilla death text with configurable templates. Supports {victim}, {killer}, and {weapon} placeholders with & color codes. Off by default; toggle death-messages.enabled.
Web Stats Export (/esmp export) — generates a self-contained HTML page and JSON file with top-10 leaderboards (kills, deaths, playtime) in plugins/ESMP/export/. Styled with inline CSS; "Powered by ESMP" footer.
Anti Health-Indicator — native, clean-room implementation using ProtocolLib entity-metadata rewriting. Hides other players' real health from non-op clients (everyone appears at full hearts). No third-party code; fully guarded — disables itself if ProtocolLib cannot write metadata on the running version.
Bug Fixes
- /ezrecipes previous button — was silently broken.
- Mojibake ( prefix) — all chat messages had corrupt § prefixes.
- Empty GUI slots — clickable air slots in inventories.
Config Changes
All new options live in config.yml or limits.yml:
# config.yml
mace-user-prefix: ""
hide-stealth-kill-messages: true
block-netherite-crafting: true
block-spear-crafting: true
happy-ghast:
speed-multiplier: 1.5
# limits.yml
global-item-limits:
mace: 1
New Features
Happy Ghast speed buff Mounting a happy_ghast applies a configurable MOVEMENT_SPEED attribute modifier. Multiplier set in config.yml under happy-ghast.speed-multiplier.
Offline Inventory Viewer (/oinvsee, /oesee) Staff can view the last-saved inventory or ender chest of offline players. Read-only GUI with a Switch button to toggle between inventory and EC views. Data is snapshotted to the player's YAML file on quit.
Mace Server-Wide Limit Configured via global-item-limits.mace in limits.yml.
Stealth Kill Message Truncation When a killer is invisible (potion effect) or vanished, the death message is trimmed at " by " — weapon and attacker name are hidden. Toggle: hide-stealth-kill-messages in config.yml.
- Count persists across sessions in mace-data.yml — offline holders still count toward the total.
- Acquisition blocked on: ground pickup, container click, creative menu grab, anvil/enchanting result.
- A 1-second repeating task sweeps all online inventories (storage + offhand) and removes excess.
- Ender chest storage of a mace is blocked.
- Mace holders get the configured prefix + gold name in the tab list.
- Count reconciled on drop, death, and logout.
Netherite Restrictions block-netherite-crafting: true in config.yml prevents producing netherite sword, axe, helmet, chestplate, leggings, and boots via smithing table or crafting table. Pickaxe, hoe, and shovel remain available.
