zMenu - Ultra complete menu plugin 1.1.1.6
Our goal: Dethrone DeluxeMenu
Hold
Shift
and click to select a range
1.1.1.6
Compatible with Minecraft 1.20 - 26.2
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.connect and zmenu.disconnect.
- Custom item on-click mechanic: custom items (defined in items/*.yml) can now run zMenu actions when their holder left/right-clicks. Configure it under mechanics.on-click with cooldown (seconds), cancel-event, click-target (air / block / both), click-types (LEFT, RIGHT, SHIFT_LEFT, SHIFT_RIGHT), click-requirements and actions.
- Dynamic dialog buttons: two new dialog button types repeat a body or input element over a numeric range — dialog-dynamic-body-button (inside body) and dialog-dynamic-input-button (inside inputs), each with placeholder-aware start / end bounds. The %index% placeholder resolves to the current iteration, and each generated input value is available as %_% (e.g. %my_input_1%). See dialogs/dynamic-dialog-example.yml.
- Dynamic Bedrock buttons: bedrock-dynamic-input-button (CUSTOM forms) and bedrock-dynamic-button (SIMPLE forms) repeat an input/button over start / end, exposing %index% and per-index response placeholders (e.g. %dynamic_input_1%, %dynamic_toggle_1%). See bedrock/dynamic-bedrock-example.yml and bedrock/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 zMenu actions) or static for native client actions via static-type: (OPEN_URL, OPEN_FILE, RUN_COMMAND, SUGGEST_COMMAND, COPY_TO_CLIPBOARD).
- Dialog action limits: dialog action buttons support usage-limit (maximum activations) and duration-limit — either plain seconds or a { value, type } section with a TimeUnit (SECONDS, MINUTES, ...) — plus enable-placeholders.
- Placeholders inside item components: item component fields now accept %placeholder% values, resolved per viewer at build time (local placeholders + PlaceholderAPI) through a new Resolvable framework. dyed-color and 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-functional dye component (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.menu for /zmenu openMainMenu (was sharing zmenu.open).
- Added zmenu.dialog for /zmenu dialogs, and zmenu.open.dialog.config for /zmenu dialogs config.
- Split zmenu.players into 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.
- /zmenu login still works as before (legacy token paste); running /zmenu login with no argument now links the server for live sync.
- Live sync now sends a stable, persistent server_id (stored in live-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 (perm zmenu.unlink): force-detach this server from the website - it revokes the link on the site, and clears the local live-sync.json credential even if the site call fails (so a down/unreachable website never leaves a stuck link).
- /zmenu connect now first verifies the link is still valid with the website and refreshes the stored relay url / connection id (so a changed ZMENU_WS_URL is 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, firework colors/fade_colors, custom-model-data colors, potion-contents custom 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 (.label, .tooltip, .width, .actions, .type) falls back to the old flat keys (yes-text, notice.text, multi-actions..text, ...), so existing dialog files keep working.
- Bedrock text input now accepts both bedrock_text and bedrock_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's inventory_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_REPOSITORY env var → org.bukkit.plugin.java.LibraryLoader.centralURL system 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.yml has been removed in favour of paper-plugin.yml (Paper bootstrapper + 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: InventoryManager methods now return/accept ContainerInventory instead of Bukkit Inventory; plugins compiling against zmenu-api must 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 .bak backup 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 in live-sync.json and never printed.
Fixes
- Fixed /zmenu disconnect using 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 disconnect or 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 width being ignored inside dialog_plain_message.
- Fixed translated inventory/item names (translatedName / translated-name) never being applied.
- Fixed player-selector arguments (@p, @a, ...) in /zmenu open, giveitem, giveopenitem, openmainmenu and the Bedrock/dialog open commands.
- Fixed commands sometimes not registering, and allowed : inside inventory names/arguments.
- Fixed a ConcurrentModificationException while 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 else chain 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 StackOverflowError during 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 on DIALOG / BEDROCK_INVENTORY support being active).
- Dialog API split into specialized interfaces (ConfirmationDialogInventory, NoticeDialogInventory, MultiActionDialogInventory, ServerLinksDialogInventory); ~40 type-specific methods on DialogInventory were deprecated. A new ConfigFieldProcessor extension point lets integrators customize the /zmenu dialogs config editor.
- Bedrock inputs now build Geyser Cumulus components directly; new bedrock/inputs and bedrock/components API packages; dialog body/input types moved into body/ and inputs/ subpackages (import paths changed for API consumers).
- New Resolvable framework backing placeholder-aware component fields; PotionContentsComponent rewritten on Paper DataComponentTypes; ResolvableRegistry now uses Bukkit RegistryKey; entity variant loaders reorganized into per-entity packages; the Spigot/Paper custom-model-data loaders were merged into a single dynamic loader.
- New ResolvablePersistentDataEntry / ResolvableContainerSlot API building blocks (typed, placeholder-resolvable persistent-data entries using a value@type syntax).
- Commands migrated to the paper-dispatch library.
- openInventory now 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.
No ratings yet
1.1.1.5
Compatible with Minecraft 1.20 - 26.2
New Features
- Player Inventory Placeholders: Added %zmenu_player_empty_slots% to get the number of free slots in the player's inventory, and %zmenu_player_item_count_% to count the total amount of a specific item. These placeholders work even when the bottom inventory is hidden with clear-inventory: true, allowing shop menus to check if the player has enough space before purchasing.
- Custom Commands: Add a new field actions-requirements for custom commands, allowing you to specify requirements that must be met for the command's actions to execute. This provides more control over argument conditions and enhances command functionality.
- Anvil Inventory Support: Added a new ANVIL inventory type, with rename-requirements to validate the text entered by the player before running the rename actions. Inventory types are now resolved through a dedicated InventoryType registry (currently ANVIL and CHEST), making it easier to add new container types in the future.
- Item Rules System: Added a flexible item-matching system configurable through a rule section. Built-in rule types: material, material-contains, material-prefix, material-suffix, name, lore, tag, custom-model-data, and the and / or composites to combine several rules. Plugin-specific item rules (match by item id, supporting wildcards and ignore-case) are available for CraftEngine, Denizen, Eco, ExecutableBlocks, ExecutableItems, HeadDatabase, ItemsAdder, MMOItems, Nexo, NextGens, Nova, Oraxen and SlimeFun. The item_drag button now accepts a rule section to validate which items a player is allowed to drop.
- New Action set_item (set_item / set-item): place an item in one or several inventory slots (menu or player inventory via in-player-inventory: true), with dupe-protection enabled by default.
- New Action take_item (take_item / take-item): remove a configurable amount of matching items from the player's inventory, with verification: SIMILAR (default) or MODELID to control how items are matched.
- New Action refresh_slot (refresh_slot / refresh-slot): refresh only the given slots (menu or player inventory) without rebuilding the whole inventory.
- Check Inventory Requirement (check-inventory permissible): verify that a given slot contains a specific item (or that the player owns it), with success and deny actions and a configurable comparison type.
- Denizen Support: Added a new hook for Denizen, allowing Denizen items to be matched through the item rules system (denizen rule type).
Bug Fixes
- Clear Inventory Session Items: Fixed a bug where items given to the player during a menu session (e.g., via shop purchase actions) were lost when closing a menu with clear-inventory: true. Session items are now collected before restoring the original inventory and properly restored afterward.
- ItemGiveAction Inventory Update: Added player.updateInventory() after giving items via the give_item action, ensuring the client inventory display updates immediately.
- Inventory Desync on Item Give: Fixed ItemGiveAction not calling player.updateInventory() after adding items, causing a visual desynchronization where the player's hotbar/inventory wouldn't visually update until the next interaction.
- Multi Dialogs number-of-columns: Fixed multi-action dialogs not supporting the number-of-columns option.
- Nexo Glyphs in Items: Fixed Nexo glyphs not working inside items. Add skip-first-cache: true to the item configuration to use them.
- Animation Listener: Fixed an issue with PacketAnimationListener (#245).
Internal Changes
- New Minecraft version detection system MinecraftVersion over old NMSVersion enum, allowing more flexible version checks and better support for future Minecraft versions without needing to update the plugin.
- New utils annotations
- @SinceVersion | These annotations can be used to mark classes that should only be loaded for specific Minecraft versions, check in the VersionFilter class for more details.
- @UntilVersion | These annotations can be used to mark classes that should only be loaded for specific Minecraft versions, check in the VersionFilter class for more details.
- @PaperOnly | These annotations can be used to mark classes that should only be loaded if the server is a Paper version, check in the VersionFilter class for more details.
- @SpigotOnly | These annotations can be used to mark classes that should only be loaded if the server is a spigot version, check in the VersionFilter class for more details.
- @AutoComponentLoader (renamed from @ComponentLoader) | Allow to load dynamically all items component loader without having to register them one by one in the ZComponentManager class for "fr.maxlego08.zmenu" package, filtering by version and server type with the new annotations by the helper of VersionFilter class.
- @AutoListener | Allow to load dynamically all listeners who take a MenuPlugin in their constructor or no-arg constructor without having to register them one by one in the ZListenerManager class for "fr.maxlego08.zmenu" package, filtering by version and server type with the new annotations by the helper of VersionFilter class.
- @AutoActionLoader | Allow to load dynamically all action loaders without having to register them one by one, filtering by version and server type via the VersionFilter class.
- @AutoMaterialLoader | Allow to load dynamically all material loaders without having to register them one by one, filtering by version and server type via the VersionFilter class.
- @AutoPermissibleLoader | Allow to load dynamically all permissible (requirement) loaders without having to register them one by one, filtering by version and server type via the VersionFilter class.
- @AutoRuleLoader | Allow to load dynamically all item rule loaders without having to register them one by one in the ZRuleLoaderRegistry, filtering by version and server type via the VersionFilter class.
- @RequiresPlugin | Mark a class so it is only loaded when a given plugin is present. Now supports a version and a type (Comparison) to only load the class when the plugin version comparison is true, plus a checkMode (EXISTS / EXISTS_AND_ENABLED) to choose between "plugin installed" and "plugin installed and enabled".
- All action, component, listener, material, permissible and rule loaders are now discovered and registered automatically at startup through ClassRegistry and the annotations above, instead of being registered one by one.
- ClassRegistry now logs constructor instantiation failures, making it easier to diagnose why a loader did not register.
- New dedicated NMS modules (NMS/Base, NMS/v1_20_R3, NMS/v1_20_R4, NMS/v1_21_R1) with a versioned NMSHandler abstraction.
- New item packet management classes: NMSMenuPacketListener, PacketQueue and ForceChannelPromise.
- New item components: AttackRange and MaxStackSize (with Spigot and Paper implementations); entity variant loaders refactored onto shared base classes (CollarColor, DyeColor, Enum, Registry variant loaders).
- Standardized string casing using Locale.ROOT across all classes for consistent, locale-independent behavior.
- Migrated the build to a Gradle version catalog (gradle/libs.versions.toml).
No ratings yet
Product Info
Statistics
5
Views
0
Downloads
2.69 MB
File size
14.07.2026
Published
15.07.2026
Updated
Info
Server type
Supported Versions
1.20 - 26.2