From 126a476c4e192141e65e8e8d1ea6ce203aa242c3 Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Fri, 13 Mar 2026 18:29:04 +0100 Subject: [PATCH 1/4] fix: update permissions for command menu classes --- .../fr/maxlego08/menu/common/enums/Permission.java | 14 ++++++++------ .../menu/command/commands/CommandMenuEditor.java | 4 +++- .../command/commands/CommandMenuGiveOpenItem.java | 2 +- .../menu/command/commands/CommandMenuVersion.java | 4 +++- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Common/src/main/java/fr/maxlego08/menu/common/enums/Permission.java b/Common/src/main/java/fr/maxlego08/menu/common/enums/Permission.java index 66b03e5c..4be55899 100644 --- a/Common/src/main/java/fr/maxlego08/menu/common/enums/Permission.java +++ b/Common/src/main/java/fr/maxlego08/menu/common/enums/Permission.java @@ -10,18 +10,20 @@ public enum Permission { ZMENU_CONVERT, ZMENU_LIST, ZMENU_TEST_DUPE, - ZMENU_OPEN_ITEM, ZMENU_CREATE, - ZMENU_DOWNLOAD, - ZMENU_LOGIN, - ZMENU_MARKETPLACE, - ZMENU_INVENTORIES, - ZMENU_DESCRIPTION, + ZMENU_DOWNLOAD, + ZMENU_LOGIN, + ZMENU_MARKETPLACE, + ZMENU_INVENTORIES, + ZMENU_DESCRIPTION, ZMENU_OPEN_DIALOG, ZMENU_RELOAD_DIALOG, ZMENU_DUMPLOG, ZMENU_CONTRIBUTORS, ZMENU_GIVE_ITEM, + ZMENU_GIVE_OPEN_ITEM, + ZMENU_EDITOR, + ZMENU_VERSION, ZMENU_ADDONS, ZMENU_DOCUMENTATION; diff --git a/src/main/java/fr/maxlego08/menu/command/commands/CommandMenuEditor.java b/src/main/java/fr/maxlego08/menu/command/commands/CommandMenuEditor.java index 48f15542..35557fe8 100644 --- a/src/main/java/fr/maxlego08/menu/command/commands/CommandMenuEditor.java +++ b/src/main/java/fr/maxlego08/menu/command/commands/CommandMenuEditor.java @@ -1,8 +1,9 @@ package fr.maxlego08.menu.command.commands; import fr.maxlego08.menu.ZMenuPlugin; -import fr.maxlego08.menu.command.VCommand; import fr.maxlego08.menu.api.utils.Message; +import fr.maxlego08.menu.command.VCommand; +import fr.maxlego08.menu.common.enums.Permission; import fr.maxlego08.menu.zcore.utils.commands.CommandType; public class CommandMenuEditor extends VCommand { @@ -11,6 +12,7 @@ public CommandMenuEditor(ZMenuPlugin plugin) { super(plugin); this.addSubCommand("editor"); this.setDescription(Message.DESCRIPTION_EDITOR); + this.setPermission(Permission.ZMENU_EDITOR); } @Override diff --git a/src/main/java/fr/maxlego08/menu/command/commands/CommandMenuGiveOpenItem.java b/src/main/java/fr/maxlego08/menu/command/commands/CommandMenuGiveOpenItem.java index 861a64dc..c3b7b3ea 100644 --- a/src/main/java/fr/maxlego08/menu/command/commands/CommandMenuGiveOpenItem.java +++ b/src/main/java/fr/maxlego08/menu/command/commands/CommandMenuGiveOpenItem.java @@ -19,7 +19,7 @@ public class CommandMenuGiveOpenItem extends VCommand { public CommandMenuGiveOpenItem(ZMenuPlugin plugin) { super(plugin); - this.setPermission(Permission.ZMENU_OPEN_ITEM); + this.setPermission(Permission.ZMENU_GIVE_OPEN_ITEM); this.setDescription(Message.DESCRIPTION_OPEN_ITEM); this.addSubCommand("giveopenitem"); this.addSubCommand("goi"); diff --git a/src/main/java/fr/maxlego08/menu/command/commands/CommandMenuVersion.java b/src/main/java/fr/maxlego08/menu/command/commands/CommandMenuVersion.java index a53f4026..789339ff 100644 --- a/src/main/java/fr/maxlego08/menu/command/commands/CommandMenuVersion.java +++ b/src/main/java/fr/maxlego08/menu/command/commands/CommandMenuVersion.java @@ -1,8 +1,9 @@ package fr.maxlego08.menu.command.commands; import fr.maxlego08.menu.ZMenuPlugin; -import fr.maxlego08.menu.command.VCommand; import fr.maxlego08.menu.api.utils.Message; +import fr.maxlego08.menu.command.VCommand; +import fr.maxlego08.menu.common.enums.Permission; import fr.maxlego08.menu.zcore.utils.commands.CommandType; public class CommandMenuVersion extends VCommand { @@ -10,6 +11,7 @@ public class CommandMenuVersion extends VCommand { public CommandMenuVersion(ZMenuPlugin plugin) { super(plugin); this.setDescription(Message.DESCRIPTION_VERSION); + this.setPermission(Permission.ZMENU_VERSION); this.addSubCommand("version", "v", "ver"); } From 331b0a5f7ef4cf998cb635db1bb59a5f545c7e6a Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Fri, 13 Mar 2026 20:27:43 +0100 Subject: [PATCH 2/4] fix: handle null flags in menu item stack --- Common/src/main/java/fr/maxlego08/menu/ZMenuItemStack.java | 4 +--- .../java/fr/maxlego08/menu/loader/MenuItemStackLoader.java | 4 +++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Common/src/main/java/fr/maxlego08/menu/ZMenuItemStack.java b/Common/src/main/java/fr/maxlego08/menu/ZMenuItemStack.java index dff3d6e6..180149b9 100644 --- a/Common/src/main/java/fr/maxlego08/menu/ZMenuItemStack.java +++ b/Common/src/main/java/fr/maxlego08/menu/ZMenuItemStack.java @@ -358,9 +358,7 @@ private void applyEnchantments(Material finalMaterial, ItemMeta itemMeta) { private void applyFlags(ItemMeta itemMeta) { for (ItemFlag flag : this.flags) { - if (flag != null) { - itemMeta.addItemFlags(flag); - } + itemMeta.addItemFlags(flag); } } diff --git a/src/main/java/fr/maxlego08/menu/loader/MenuItemStackLoader.java b/src/main/java/fr/maxlego08/menu/loader/MenuItemStackLoader.java index 5bdbccf0..355d06c9 100644 --- a/src/main/java/fr/maxlego08/menu/loader/MenuItemStackLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/MenuItemStackLoader.java @@ -96,7 +96,9 @@ public MenuItemStack load(@NonNull YamlConfiguration configuration, @NonNull Str List flagStrings = configuration.getStringList(path + "flags"); List flags = new ArrayList<>(flagStrings.size()); for (String flagName : flagStrings) { - flags.add(this.getFlag(flagName)); + ItemFlag flag = this.getFlag(flagName); + if (flag != null) + flags.add(flag); } menuItemStack.setFlags(flags); From 17571c50561b51022bb166afe3537ee8c5bb4078 Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Fri, 13 Mar 2026 20:59:52 +0100 Subject: [PATCH 3/4] fix: improve trim pattern and material validation in MenuItemStackLoader (use registry) --- .../menu/loader/MenuItemStackLoader.java | 47 +++++++++++++++---- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/src/main/java/fr/maxlego08/menu/loader/MenuItemStackLoader.java b/src/main/java/fr/maxlego08/menu/loader/MenuItemStackLoader.java index 355d06c9..f6f68d18 100644 --- a/src/main/java/fr/maxlego08/menu/loader/MenuItemStackLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/MenuItemStackLoader.java @@ -15,7 +15,6 @@ import fr.maxlego08.menu.api.loader.ItemComponentLoader; import fr.maxlego08.menu.api.utils.Loader; import fr.maxlego08.menu.api.utils.LoreType; -import fr.maxlego08.menu.api.utils.TrimHelper; import fr.maxlego08.menu.common.context.ZBuildContext; import fr.maxlego08.menu.common.utils.ZUtils; import fr.maxlego08.menu.common.utils.nms.NmsVersion; @@ -35,6 +34,7 @@ import java.io.File; import java.io.IOException; import java.util.*; +import java.util.stream.Collectors; @SuppressWarnings("deprecation") public class MenuItemStackLoader extends ZUtils implements Loader { @@ -519,18 +519,47 @@ private void loadNewItemStacks(ZMenuItemStack menuItemStack, YamlConfiguration c private void loadTrims(ZMenuItemStack menuItemStack, YamlConfiguration configuration, String path, File file) { boolean enableTrim = configuration.getBoolean(path + "trim.enable", false); if (enableTrim) { - TrimHelper trimHelper = new TrimHelper(); - TrimPattern trimPattern = trimHelper.getTrimPatterns().get(configuration.getString(path + "trim.pattern", "").toLowerCase()); - if (trimPattern == null) { + String patternKey = configuration.getString(path + "trim.pattern", "").toLowerCase(); + TrimPattern trimPattern = null; + try { + NamespacedKey patternNamespace = NamespacedKey.fromString(patternKey); + if (patternNamespace != null) { + trimPattern = Registry.TRIM_PATTERN.get(patternNamespace); + } + if (trimPattern == null) { + enableTrim = false; + String joinedNames = Registry.TRIM_PATTERN.stream() + .map(TrimPattern::getKey) + .map(NamespacedKey::toString) + .collect(Collectors.joining(", ")); + Logger.info("Trim pattern '" + patternKey + "' was not found for item '" + file.getAbsolutePath() + "'. Available patterns: " + joinedNames, Logger.LogType.ERROR); + } + } catch (Exception e) { enableTrim = false; - Bukkit.getLogger().severe("Trim pattern " + configuration.getString(path + "trim.pattern", "") + " was not found for item " + file.getAbsolutePath()); + Logger.info("Invalid namespace for trim pattern: '" + patternKey + "' in file '" + file.getAbsolutePath() + "'", Logger.LogType.ERROR); } - TrimMaterial trimMaterial = trimHelper.getTrimMaterials().get(configuration.getString(path + "trim.material", "").toLowerCase()); - if (trimMaterial == null) { + + String materialKey = configuration.getString(path + "trim.material", "").toLowerCase(); + TrimMaterial trimMaterial = null; + try { + NamespacedKey materialNamespace = NamespacedKey.fromString(materialKey); + if (materialNamespace != null) { + trimMaterial = Registry.TRIM_MATERIAL.get(materialNamespace); + } + if (trimMaterial == null) { + enableTrim = false; + String joinedNames = Registry.TRIM_MATERIAL.stream() + .map(TrimMaterial::getKey) + .map(NamespacedKey::toString) + .collect(Collectors.joining(", ")); + Logger.info("Trim material '" + materialKey + "' was not found for item '" + file.getAbsolutePath() + "'. Available materials: " + joinedNames, Logger.LogType.ERROR); + } + } catch (Exception e) { enableTrim = false; - Bukkit.getLogger().severe("Trim material " + configuration.getString(path + "trim.material", "") + " was not found for item " + file.getAbsolutePath()); + Logger.info("Invalid namespace for trim material: '" + materialKey + "' in file '" + file.getAbsolutePath() + "'", Logger.LogType.ERROR); } - menuItemStack.setTrimConfiguration(new TrimConfiguration(enableTrim, trimMaterial, trimPattern)); + if (trimMaterial != null && trimPattern != null) + menuItemStack.setTrimConfiguration(new TrimConfiguration(enableTrim, trimMaterial, trimPattern)); } } From 34129c05ddab476e922fd2854a7edd0da5664469 Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Sat, 14 Mar 2026 10:38:40 +0100 Subject: [PATCH 4/4] fix: enhance attribute wrapper and menu item stack loading logic --- .../menu/api/attribute/AttributeWrapper.java | 9 +++++++-- .../java/fr/maxlego08/menu/ZMenuItemStack.java | 15 --------------- .../java/fr/maxlego08/menu/ZInventoryManager.java | 5 +++-- .../menu/loader/MenuItemStackLoader.java | 3 +++ ...igotAttributeModifiersItemComponentLoader.java | 2 +- ...chantmentGlintOverrideItemComponentLoader.java | 5 +++-- 6 files changed, 17 insertions(+), 22 deletions(-) diff --git a/API/src/main/java/fr/maxlego08/menu/api/attribute/AttributeWrapper.java b/API/src/main/java/fr/maxlego08/menu/api/attribute/AttributeWrapper.java index dc7690f3..934b5291 100644 --- a/API/src/main/java/fr/maxlego08/menu/api/attribute/AttributeWrapper.java +++ b/API/src/main/java/fr/maxlego08/menu/api/attribute/AttributeWrapper.java @@ -7,6 +7,7 @@ import org.bukkit.attribute.AttributeModifier; import org.bukkit.inventory.EquipmentSlotGroup; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Locale; import java.util.Map; @@ -17,7 +18,11 @@ * Value object for encapsulating all data needed for an attribute modifier on an item: the attribute, operation, amount, and slot. * Provides deserialization and conversion to Bukkit AttributeModifier. */ -public record AttributeWrapper(Attribute attribute, AttributeModifier.Operation operation, double amount, EquipmentSlotGroup slot) { +public record AttributeWrapper(Attribute attribute, AttributeModifier.Operation operation, double amount, EquipmentSlotGroup slot, @Nullable NamespacedKey namespacedKey) { + + AttributeWrapper(Attribute attribute, AttributeModifier.Operation operation, double amount, EquipmentSlotGroup slot) { + this(attribute, operation, amount, slot, null); + } public static AttributeWrapper deserialize(@NotNull Map attributeMap) { var attribute = Registry.ATTRIBUTE.get(Objects.requireNonNull(NamespacedKey.fromString(((String) attributeMap.get("attribute")).toLowerCase(Locale.ROOT)))); @@ -30,6 +35,6 @@ public static AttributeWrapper deserialize(@NotNull Map attribut } public AttributeModifier toAttributeModifier(MenuPlugin plugin) { - return new AttributeModifier(new NamespacedKey(plugin, UUID.randomUUID().toString()), amount, operation, slot); + return new AttributeModifier(Objects.requireNonNullElseGet(this.namespacedKey, () -> new NamespacedKey(plugin, UUID.randomUUID().toString())), amount, operation, slot); } } diff --git a/Common/src/main/java/fr/maxlego08/menu/ZMenuItemStack.java b/Common/src/main/java/fr/maxlego08/menu/ZMenuItemStack.java index 180149b9..bfba0bd6 100644 --- a/Common/src/main/java/fr/maxlego08/menu/ZMenuItemStack.java +++ b/Common/src/main/java/fr/maxlego08/menu/ZMenuItemStack.java @@ -20,7 +20,6 @@ import fr.maxlego08.menu.api.utils.Placeholders; import fr.maxlego08.menu.common.context.ZBuildContext; import fr.maxlego08.menu.common.utils.ZUtils; -import fr.maxlego08.menu.common.utils.itemstack.MenuItemStackFormMap; import fr.maxlego08.menu.common.utils.itemstack.MenuItemStackFromItemStack; import fr.maxlego08.menu.common.utils.nms.NmsVersion; import fr.maxlego08.menu.zcore.logger.Logger; @@ -39,7 +38,6 @@ import org.jspecify.annotations.NonNull; import javax.annotation.Nullable; -import java.io.File; import java.util.*; public class ZMenuItemStack extends ZUtils implements MenuItemStack { @@ -102,19 +100,6 @@ public static ZMenuItemStack fromItemStack(InventoryManager manager, ItemStack i return MenuItemStackFromItemStack.fromItemStack(manager, itemStack); } - /** - * Build a MenuItemStack from a map. - * - * @param inventoryManager the inventoryManager of the item - * @param file the file where the item is saved - * @param path the path of the item in the file - * @param map the map which contains the item data - * @return the menuItemStack - */ - public static ZMenuItemStack fromMap(InventoryManager inventoryManager, File file, String path, Map map) { - return MenuItemStackFormMap.fromMap(inventoryManager, file, path, map); - } - /** * @return the inventoryManager */ diff --git a/src/main/java/fr/maxlego08/menu/ZInventoryManager.java b/src/main/java/fr/maxlego08/menu/ZInventoryManager.java index ba4c6dd3..1eecd1d8 100644 --- a/src/main/java/fr/maxlego08/menu/ZInventoryManager.java +++ b/src/main/java/fr/maxlego08/menu/ZInventoryManager.java @@ -27,7 +27,6 @@ import fr.maxlego08.menu.common.utils.ZUtils; import fr.maxlego08.menu.common.utils.cache.YamlFileCache; import fr.maxlego08.menu.common.utils.cache.YamlFileCacheEntry; -import fr.maxlego08.menu.common.utils.itemstack.MenuItemStackFormMap; import fr.maxlego08.menu.common.utils.nms.ItemStackUtils; import fr.maxlego08.menu.common.utils.yaml.YamlParser; import fr.maxlego08.menu.hooks.dialogs.loader.body.ItemBodyLoader; @@ -130,7 +129,9 @@ public MenuItemStack loadItemStack(YamlConfiguration configuration, String path, @Override public MenuItemStack loadItemStack(File file, String path, Map map) { - return MenuItemStackFormMap.fromMap(this, file, path, map); + YamlConfiguration configuration = new YamlConfiguration(); + configuration.set("item", map); + return new MenuItemStackLoader(this).load(configuration, "item", file); } @Override diff --git a/src/main/java/fr/maxlego08/menu/loader/MenuItemStackLoader.java b/src/main/java/fr/maxlego08/menu/loader/MenuItemStackLoader.java index 617515ae..3abc0ee5 100644 --- a/src/main/java/fr/maxlego08/menu/loader/MenuItemStackLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/MenuItemStackLoader.java @@ -53,6 +53,9 @@ public MenuItemStackLoader(InventoryManager manager) { * Load ItemStack */ public MenuItemStack load(@NonNull YamlConfiguration configuration, @NonNull String path, Object... objects) { + if (!path.isEmpty() && !path.endsWith(".")) + path = path + "."; + File file = (File) objects[0]; diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotAttributeModifiersItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotAttributeModifiersItemComponentLoader.java index a02d37e8..16a86353 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotAttributeModifiersItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotAttributeModifiersItemComponentLoader.java @@ -59,7 +59,7 @@ public SpigotAttributeModifiersItemComponentLoader(MenuPlugin plugin){ if (attribute == null) continue; try { AttributeModifier deserialize = AttributeModifier.deserialize(map); - modifiersWrapper.add(new AttributeWrapper(attribute, deserialize.getOperation(), deserialize.getAmount(), deserialize.getSlotGroup())); + modifiersWrapper.add(new AttributeWrapper(attribute, deserialize.getOperation(), deserialize.getAmount(), deserialize.getSlotGroup(), deserialize.getKey())); } catch (IllegalArgumentException e) { if (Configuration.enableDebug){ Logger.info("Error deserializing attribute modifier for attribute " + attribute.name() + ": " + e.getMessage()); diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEnchantmentGlintOverrideItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEnchantmentGlintOverrideItemComponentLoader.java index f34fa7e2..f60fea69 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEnchantmentGlintOverrideItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEnchantmentGlintOverrideItemComponentLoader.java @@ -20,7 +20,8 @@ public SpigotEnchantmentGlintOverrideItemComponentLoader(){ @Override public @Nullable ItemComponent load(@NotNull MenuItemStackContext context, @NotNull File file, @NotNull YamlConfiguration configuration, @NotNull String path, @Nullable ConfigurationSection componentSection) { path = normalizePath(path); - boolean hasGlint = configuration.getBoolean(path, false); - return hasGlint ? new EnchantmentGlintOverrideComponent(true) : null; + Object obj = configuration.get(path); + if (obj == null) return null; + return obj instanceof Boolean hasGlint ? new EnchantmentGlintOverrideComponent(hasGlint) : null; } }