
Список изменений
New Features
- Added live sync with the website (Minecraft Inventory Builder): link your server with
/zmenu login(no argument starts a secure device-authorization flow - approve the shown code on the website), open the live link with/zmenu connect, and close it with/zmenu disconnect. Once connected, clicking "Sync to Server" on the web builder reloads the inventory on your server live, with no restart. - Added permissions
zmenu.connectandzmenu.disconnect. - Custom item
on-clickmechanic: custom items (defined initems/*.yml) can now run zMenu actions when their holder left/right-clicks. Configure it undermechanics.on-clickwithcooldown(seconds),cancel-event,click-target(air/block/both),click-types(LEFT,RIGHT,SHIFT_LEFT,SHIFT_RIGHT),click-requirementsandactions. - Dynamic dialog buttons: two new dialog button types repeat a body or input element over a numeric range —
dialog-dynamic-body-button(insidebody:) anddialog-dynamic-input-button(insideinputs:), each with placeholder-awarestart/endbounds. The%index%placeholder resolves to the current iteration, and each generated input value is available as%<button-name>_<index>%(e.g.%my_input_1%). Seedialogs/dynamic-dialog-example.yml. - Dynamic Bedrock buttons:
bedrock-dynamic-input-button(CUSTOM forms) andbedrock-dynamic-button(SIMPLE forms) repeat an input/button overstart/end, exposing%index%and per-index response placeholders (e.g.%dynamic_input_1%,%dynamic_toggle_1%). Seebedrock/dynamic-bedrock-example.ymlandbedrock/dynamic-simple-bedrock-example.yml. - Pluggable dialog action types: dialog action buttons (yes/no, notice, multi-action, server-links) now accept a
type:field —custom-click(default, runs zMenuactions:) orstaticfor native client actions viastatic-type:(OPEN_URL,OPEN_FILE,RUN_COMMAND,SUGGEST_COMMAND,COPY_TO_CLIPBOARD). - Dialog action limits: dialog action buttons support
usage-limit(maximum activations) andduration-limit— either plain seconds or a{ value, type }section with aTimeUnit(SECONDS,MINUTES, ...) — plusenable-placeholders. - Placeholders inside item components: item component fields now accept
%placeholder%values, resolved per viewer at build time (local placeholders + PlaceholderAPI) through a newResolvableframework.dyed-colorand other color / enum / number / string fields can now be dynamic. - New item components:
tropical-fish/pattern,wolf/sound-variant,can-break,can-place-on, and a now-functionaldyecomponent (Paper 1.26.1+).
Improvements
-
Unique permissions for every command: refactored all commands to use distinct permission nodes — no two commands share the same permission anymore.
- Added
zmenu.open.main.menufor/zmenu openMainMenu(was sharingzmenu.open). - Added
zmenu.dialogfor/zmenu dialogs, andzmenu.open.dialog.configfor/zmenu dialogs config. - Split
zmenu.playersinto 9 granular permissions:zmenu.players.add,zmenu.players.clear.all,zmenu.players.clear.player,zmenu.players.convert,zmenu.players.get,zmenu.players.keys,zmenu.players.remove,zmenu.players.remove.all,zmenu.players.subtract.
- Added
-
/zmenu login <token>still works as before (legacy token paste); running/zmenu loginwith no argument now links the server for live sync. -
Live sync now sends a stable, persistent
server_id(stored inlive-sync.json, kept across re-links) at pairing time, so the website recognises the same server across re-pairings and never creates duplicate linked-server entries. -
Synced inventories are now written into a subfolder of
inventories/mirroring the inventory's folder on the website (e.g.inventories/Shop/Weapons/menu.yml). The subfolder path is taken from the sync notification and sanitised (segments only, no../absolute/backslash) before any file is written. -
New command
/zmenu unlink(permzmenu.unlink): force-detach this server from the website - it revokes the link on the site, and clears the locallive-sync.jsoncredential even if the site call fails (so a down/unreachable website never leaves a stuck link). -
/zmenu connectnow first verifies the link is still valid with the website and refreshes the stored relay url / connection id (so a changedZMENU_WS_URLis picked up automatically); a revoked link is detected and cleared up front. -
All integrations are now optional: every integration plugin (Oraxen, ItemsAdder, PlaceholderAPI, LuckPerms, Geyser/Floodgate, MythicMobs, MMOItems, ...) is declared as a soft dependency in
paper-plugin.yml— none are required for zMenu to start. -
Expanded color parsing: color fields (
dyed-color,map-color, fireworkcolors/fade_colors,custom-model-datacolors,potion-contentscustom color, collar colors, ...) now also accept"r,g,b"and"r,g,b,a"strings (with or without spaces, values clamped 0–255) in addition to hex strings and RGB(A) lists. -
Backward-compatible dialog action buttons: the new nested form (
<key>.label,<key>.tooltip,<key>.width,<key>.actions,<key>.type) falls back to the old flat keys (yes-text,notice.text,multi-actions.<key>.text, ...), so existing dialog files keep working. -
Bedrock text input now accepts both
bedrock_textandbedrock_text_input. -
Page placeholders (
%page%,%maxPage%,%max-page%) now resolve everywhere inside an inventory (buttons, names, lore), not only in the title. -
DeluxeMenu import (
zmenuconvert) now honours DeluxeMenu'sinventory_type(CHEST, HOPPER, DISPENSER, ...), rejects unsupported types with a clear message, and only enforces the multiple-of-9 size rule on CHEST inventories. -
Maven Central mirror fallback: zMenu downloads its runtime libraries via Paper's library loader on startup; a mirror fallback (
PAPER_DEFAULT_CENTRAL_REPOSITORYenv var →org.bukkit.plugin.java.LibraryLoader.centralURLsystem property → Google mirror) keeps this working on older Paper builds and restricted networks. -
Players can now safely type
%inside dialog/chat answers (it is no longer misinterpreted as a placeholder).
Changes
- zMenu is now Paper-only. The Spigot
plugin.ymlhas been removed in favour ofpaper-plugin.yml(Paperbootstrapper+loader); zMenu no longer runs on Spigot — Paper, a Paper fork (Purpur/Pufferfish) or Folia is required. Work has also started on Paper 26+ support. - Item component keys normalized to kebab-case (no alias kept — existing configs must be updated):
custom_name→custom-name,death_protection→death-protection,intangible_projectile→intangible-projectile,map_decorations→map-decorations,note_block_sound→note-block-sound,pot_decorations→pot-decorations,provides_banner_patterns→provides-banner-patterns,provides_trim_material→provides-trim-material,tropical_fish/base_color→tropical-fish/base-color,tropical_fish/pattern_color→tropical-fish/pattern-color. - API:
InventoryManagermethods now return/acceptContainerInventoryinstead of BukkitInventory; plugins compiling againstzmenu-apimust update.
Security
- The live link is end-to-end safe: the WebSocket carries only
{inventory_id, file_name, hash}- the YAML is pulled over the authenticated HTTPS API and its SHA-256 hash is verified before being applied. The file is written atomically with a.bakbackup and rolled back on a parse/reload failure; all network I/O runs off the main thread and the reload happens on the main thread. The scoped server token is stored inlive-sync.jsonand never printed.
Fixes
- Fixed
/zmenu disconnectusing the wrong permission node (zmenu.description→zmenu.disconnect). - Live sync now stays connected after
/zmenu connect: it auto-reconnects (with backoff) after a relay idle-eviction, relay restart or network blip, until you run/zmenu disconnector the token is revoked. Previously the link could drop silently and "Sync to Server" on the website would report "server not connected" even though the operator believed the server was still connected. - Fixed synced inventories failing to write on Windows (
the file is used by another process): the downloaded temp file's stream was still open when the atomic move ran. The stream is now closed before the file is applied. - Fixed a same-named inventory in two different folders reloading the wrong file (zMenu indexes inventories by bare name): the synced inventory is now resolved by its actual file path. Concurrent syncs of same-named inventories also no longer share a temp file.
- Fixed dialog config permission : https://github.com/Maxlego08/zMenu/issues/252
- Fixed
widthbeing ignored insidedialog_plain_message. - Fixed translated inventory/item names (
translatedName/translated-name) never being applied. - Fixed player-selector arguments (
@p,@a, ...) in/zmenu open,giveitem,giveopenitem,openmainmenuand the Bedrock/dialog open commands. - Fixed commands sometimes not registering, and allowed
:inside inventory names/arguments. - Fixed a
ConcurrentModificationExceptionwhile flushing player data (#246). - Fixed the anvil inventory registration to only load on Minecraft 1.21+.
- Fixed placeholder-driven commands being split in the wrong order in player-command actions.
- Fixed button post-processing only applying to the last button of an
elsechain instead of every button. - Fixed the legacy (pre-1.13) material-by-ID mapping never being built.
- Fixed the MythicMobs hook activating even when MythicMobs was installed but disabled.
- Fixed font image handling for optional plugins (#250).
- Fixed a crash on older Paper builds where JDK 25 bytecode could not be read (ASM), and a build
StackOverflowErrorduring POM resolution. - Fixed version parsing for Paper 26+ build strings (e.g.
26.2.build.12-alpha).
Internal Changes:
- Reworked the Dialog and Bedrock systems to support custom, editable and dynamic buttons; dialog and Bedrock button/input loaders are now discovered by reflection.
- New reflection-based auto-loading annotations:
@AutoButtonLoader,@AutoCommandArgumentValidator,@AutoFontImage,@AutoItemStackSimilar, and@RequireSupport(gates loading onDIALOG/BEDROCK_INVENTORYsupport being active). - Dialog API split into specialized interfaces (
ConfirmationDialogInventory,NoticeDialogInventory,MultiActionDialogInventory,ServerLinksDialogInventory); ~40 type-specific methods onDialogInventorywere deprecated. A newConfigFieldProcessorextension point lets integrators customize the/zmenu dialogs configeditor. - Bedrock inputs now build Geyser Cumulus components directly; new
bedrock/inputsandbedrock/componentsAPI packages; dialog body/input types moved intobody/andinputs/subpackages (import paths changed for API consumers). - New
Resolvableframework backing placeholder-aware component fields;PotionContentsComponentrewritten on PaperDataComponentTypes;ResolvableRegistrynow uses BukkitRegistryKey; entity variant loaders reorganized into per-entity packages; the Spigot/Papercustom-model-dataloaders were merged into a single dynamic loader. - New
ResolvablePersistentDataEntry/ResolvableContainerSlotAPI building blocks (typed, placeholder-resolvable persistent-data entries using avalue@typesyntax). - Commands migrated to the
paper-dispatchlibrary. openInventorynow runs on the entity scheduler (Folia-safe); hardened packet-handler injection.- Migrated compile/test to Paper 26 with a MockBukkit-based mock-server test harness; Gradle wrapper updated to 9.6.1.
