From dc1e29201165aed895e4693452851608b44e5dbd Mon Sep 17 00:00:00 2001 From: BlitzOffline <52609756+BlitzOffline@users.noreply.github.com> Date: Fri, 2 May 2025 19:53:18 +0300 Subject: [PATCH 1/5] Added support for the new CustomModelDataComponent that was added in 1.21.4 --- gradle/libs.versions.toml | 2 +- .../deluxemenus/config/DeluxeMenusConfig.java | 14 ++ .../deluxemenus/menu/MenuItem.java | 122 +++++++++++++----- .../options/CustomModelDataComponent.java | 65 ++++++++++ .../menu/options/MenuItemOptions.java | 13 ++ .../deluxemenus/utils/VersionHelper.java | 4 + 6 files changed, 188 insertions(+), 32 deletions(-) create mode 100644 src/main/java/com/extendedclip/deluxemenus/menu/options/CustomModelDataComponent.java diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 31515423..4f867b25 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] # Compile only -spigot = "1.21.4-R0.1-SNAPSHOT" +spigot = "1.21.5-R0.1-SNAPSHOT" vault = "1.7.1" authlib = "1.5.25" headdb = "1.3.2" diff --git a/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java b/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java index e2bdfa6c..fb830157 100644 --- a/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java +++ b/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java @@ -12,6 +12,7 @@ import com.extendedclip.deluxemenus.menu.MenuItem; import com.extendedclip.deluxemenus.menu.options.MenuItemOptions; import com.extendedclip.deluxemenus.menu.options.MenuOptions; +import com.extendedclip.deluxemenus.menu.options.CustomModelDataComponent; import com.extendedclip.deluxemenus.requirement.HasExpRequirement; import com.extendedclip.deluxemenus.requirement.HasItemRequirement; import com.extendedclip.deluxemenus.requirement.HasMetaRequirement; @@ -632,6 +633,19 @@ private Map> loadMenuItems(FileConfiguration .tooltipStyle(c.getString(currentPath + "tooltip_style", null)) .itemModel(c.getString(currentPath + "item_model", null)); + if (c.contains(currentPath + "model_data_component") && c.isConfigurationSection(currentPath + "model_data_component")) { + final ConfigurationSection modelDataComponent = c.getConfigurationSection(currentPath + "model_data_component"); + if (modelDataComponent != null) { + builder.customModelDataComponent( + CustomModelDataComponent.builder() + .colors(modelDataComponent.getStringList("colors")) + .flags(modelDataComponent.getStringList("flags")) + .floats(modelDataComponent.getStringList("floats")) + .strings(modelDataComponent.getStringList("strings")) + ); + } + } + // Lore Append Mode if (c.contains(currentPath + "lore_append_mode")) { String loreAppendMode = c.getString(currentPath + "lore_append_mode", "OVERRIDE").toUpperCase(); diff --git a/src/main/java/com/extendedclip/deluxemenus/menu/MenuItem.java b/src/main/java/com/extendedclip/deluxemenus/menu/MenuItem.java index ca6eb178..56028261 100644 --- a/src/main/java/com/extendedclip/deluxemenus/menu/MenuItem.java +++ b/src/main/java/com/extendedclip/deluxemenus/menu/MenuItem.java @@ -5,6 +5,7 @@ import com.extendedclip.deluxemenus.menu.options.HeadType; import com.extendedclip.deluxemenus.menu.options.LoreAppendMode; import com.extendedclip.deluxemenus.menu.options.MenuItemOptions; +import com.extendedclip.deluxemenus.menu.options.CustomModelDataComponent; import com.extendedclip.deluxemenus.nbt.NbtProvider; import com.extendedclip.deluxemenus.utils.DebugLevel; import com.extendedclip.deluxemenus.utils.ItemUtils; @@ -39,6 +40,7 @@ import org.bukkit.inventory.meta.trim.TrimPattern; import org.bukkit.potion.PotionEffect; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.ArrayList; @@ -158,13 +160,9 @@ public ItemStack getItemStack(@NotNull final MenuHolder holder) { if (meta != null) { if (this.options.rgb().isPresent()) { - final String rgbString = holder.setPlaceholdersAndArguments(this.options.rgb().get()); - final String[] parts = rgbString.split(","); - - try { - meta.setColor(Color.fromRGB(Integer.parseInt(parts[0].trim()), Integer.parseInt(parts[1].trim()), - Integer.parseInt(parts[2].trim()))); - } catch (Exception ignored) { + final Color color = parseRGBColor(holder.setPlaceholdersAndArguments(this.options.rgb().get())); + if (color != null) { + meta.setColor(color); } } @@ -224,7 +222,7 @@ public ItemStack getItemStack(@NotNull final MenuHolder holder) { return itemStack; } - if (this.options.customModelData().isPresent() && VersionHelper.IS_CUSTOM_MODEL_DATA) { + if (VersionHelper.IS_CUSTOM_MODEL_DATA && this.options.customModelData().isPresent()) { try { final int modelData = Integer.parseInt(holder.setPlaceholdersAndArguments(this.options.customModelData().get())); itemMeta.setCustomModelData(modelData); @@ -232,6 +230,10 @@ public ItemStack getItemStack(@NotNull final MenuHolder holder) { } } + if (VersionHelper.IS_CUSTOM_MODEL_DATA_COMPONENT && this.options.customModelDataComponent().isPresent()) { + itemMeta.setCustomModelDataComponent(parseCustomModelDataComponent(this.options.customModelDataComponent().get(), itemMeta.getCustomModelDataComponent(), holder)); + } + if (this.options.displayName().isPresent()) { final String displayName = holder.setPlaceholdersAndArguments(this.options.displayName().get()); itemMeta.setDisplayName(StringUtils.color(displayName)); @@ -346,37 +348,33 @@ public ItemStack getItemStack(@NotNull final MenuHolder holder) { } if (itemMeta instanceof LeatherArmorMeta && this.options.rgb().isPresent()) { - final String rgbString = holder.setPlaceholdersAndArguments(this.options.rgb().get()); - final String[] parts = rgbString.split(","); final LeatherArmorMeta leatherArmorMeta = (LeatherArmorMeta) itemMeta; - try { - leatherArmorMeta.setColor(Color.fromRGB(Integer.parseInt(parts[0].trim()), Integer.parseInt(parts[1].trim()), - Integer.parseInt(parts[2].trim()))); - itemStack.setItemMeta(leatherArmorMeta); - } catch (final Exception exception) { - plugin.printStacktrace( - "Invalid rgb colors found for leather armor: " + parts[0].trim() + ", " + parts[1].trim() + ", " + - parts[2].trim(), - exception + final Color color = parseRGBColor(holder.setPlaceholdersAndArguments(this.options.rgb().get())); + if (color != null) { + leatherArmorMeta.setColor(color); + } else { + plugin.debug( + DebugLevel.HIGHEST, + Level.WARNING, + "Invalid rgb colors found for leather armor: " + this.options.rgb().get() ); } + + itemStack.setItemMeta(leatherArmorMeta); } else if (itemMeta instanceof FireworkEffectMeta && this.options.rgb().isPresent()) { - final String rgbString = holder.setPlaceholdersAndArguments(this.options.rgb().get()); - final String[] parts = rgbString.split(","); final FireworkEffectMeta fireworkEffectMeta = (FireworkEffectMeta) itemMeta; - - try { - fireworkEffectMeta.setEffect(FireworkEffect.builder().withColor(Color.fromRGB(Integer.parseInt(parts[0].trim()), - Integer.parseInt(parts[1].trim()), Integer.parseInt(parts[2].trim()))).build()); - itemStack.setItemMeta(fireworkEffectMeta); - } catch (final Exception exception) { - plugin.printStacktrace( - "Invalid rgb colors found for firework or firework star: " + parts[0].trim() + ", " - + parts[1].trim() + ", " + parts[2].trim(), - exception + final Color color = parseRGBColor(holder.setPlaceholdersAndArguments(this.options.rgb().get())); + if (color != null) { + fireworkEffectMeta.setEffect(FireworkEffect.builder().withColor(color).build()); + } else { + plugin.debug( + DebugLevel.HIGHEST, + Level.WARNING, + "Invalid RGB color found for firework or firework star: " + this.options.rgb().get() ); } + itemStack.setItemMeta(fireworkEffectMeta); } else if (itemMeta instanceof EnchantmentStorageMeta && !this.options.enchantments().isEmpty()) { final EnchantmentStorageMeta enchantmentStorageMeta = (EnchantmentStorageMeta) itemMeta; for (final Map.Entry entry : this.options.enchantments().entrySet()) { @@ -548,6 +546,68 @@ private List getMenuItemLore(@NotNull final MenuHolder holder, @NotNull .collect(Collectors.toList()); } + private @NotNull org.bukkit.inventory.meta.components.CustomModelDataComponent parseCustomModelDataComponent( + @NotNull final CustomModelDataComponent unparsedComponent, + @NotNull final org.bukkit.inventory.meta.components.CustomModelDataComponent component, + @NotNull final MenuHolder holder + ) { + if (!unparsedComponent.colors().isEmpty()) { + final List colors = unparsedComponent.colors() + .stream() + .map(holder::setPlaceholdersAndArguments) + .map(this::parseRGBColor) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + component.setColors(colors); + } + + if (!unparsedComponent.flags().isEmpty()) { + final List flags = unparsedComponent.flags() + .stream() + .map(holder::setPlaceholdersAndArguments) + .map(Boolean::parseBoolean) + .collect(Collectors.toList()); + component.setFlags(flags); + } + + if (!unparsedComponent.floats().isEmpty()) { + final List floats = unparsedComponent.floats() + .stream() + .map(holder::setPlaceholdersAndArguments) + .map(Float::parseFloat) + .collect(Collectors.toList()); + component.setFloats(floats); + } + + if (!unparsedComponent.strings().isEmpty()) { + final List strings = unparsedComponent.strings() + .stream() + .map(holder::setPlaceholdersAndArguments) + .collect(Collectors.toList()); + component.setStrings(strings); + } + + return component; + } + + private @Nullable Color parseRGBColor(@NotNull final String input) { + final String[] parts = input.split(","); + try { + return Color.fromRGB( + Integer.parseInt(parts[0].trim()), + Integer.parseInt(parts[1].trim()), + Integer.parseInt(parts[2].trim()) + ); + } catch (final Exception exception) { + plugin.printStacktrace( + "Invalid RGB color found: " + parts[0].trim() + ", " + parts[1].trim() + ", " + + parts[2].trim(), + exception + ); + return null; + } + } + public @NotNull MenuItemOptions options() { return options; } diff --git a/src/main/java/com/extendedclip/deluxemenus/menu/options/CustomModelDataComponent.java b/src/main/java/com/extendedclip/deluxemenus/menu/options/CustomModelDataComponent.java new file mode 100644 index 00000000..c4bbdbbf --- /dev/null +++ b/src/main/java/com/extendedclip/deluxemenus/menu/options/CustomModelDataComponent.java @@ -0,0 +1,65 @@ +package com.extendedclip.deluxemenus.menu.options; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +public class CustomModelDataComponent { + private List colors = new ArrayList<>(); + private List flags = new ArrayList<>(); + private List floats = new ArrayList<>(); + private List strings = new ArrayList<>(); + + private CustomModelDataComponent() { + // Private constructor to force builder usage + } + + @NotNull + public CustomModelDataComponent colors(@NotNull final List<@NotNull String> colors) { + this.colors = colors; + return this; + } + + @NotNull + public List<@NotNull String> colors() { + return colors; + } + + @NotNull + public CustomModelDataComponent flags(@NotNull final List<@NotNull String> flags) { + this.flags = flags; + return this; + } + + @NotNull + public List<@NotNull String> flags() { + return flags; + } + + @NotNull + public CustomModelDataComponent floats(@NotNull final List<@NotNull String> floats) { + this.floats = floats; + return this; + } + + @NotNull + public List<@NotNull String> floats() { + return floats; + } + + @NotNull + public CustomModelDataComponent strings(@NotNull final List<@NotNull String> strings) { + this.strings = strings; + return this; + } + + @NotNull + public List<@NotNull String> strings() { + return strings; + } + + public static @NotNull CustomModelDataComponent builder() { + return new CustomModelDataComponent(); + } +} diff --git a/src/main/java/com/extendedclip/deluxemenus/menu/options/MenuItemOptions.java b/src/main/java/com/extendedclip/deluxemenus/menu/options/MenuItemOptions.java index 3377bec1..f0b4bbd8 100644 --- a/src/main/java/com/extendedclip/deluxemenus/menu/options/MenuItemOptions.java +++ b/src/main/java/com/extendedclip/deluxemenus/menu/options/MenuItemOptions.java @@ -25,6 +25,7 @@ public class MenuItemOptions { private final String damage; private final int amount; private final String customModelData; + private final CustomModelDataComponent customModelDataComponent; private final String dynamicAmount; private final String lightLevel; private final String displayName; @@ -87,6 +88,7 @@ private MenuItemOptions(final @NotNull MenuItemOptionsBuilder builder) { this.damage = builder.damage; this.amount = builder.amount; this.customModelData = builder.customModelData; + this.customModelDataComponent = builder.customModelDataComponent; this.dynamicAmount = builder.dynamicAmount; this.lightLevel = builder.lightLevel; this.displayName = builder.displayName; @@ -156,6 +158,10 @@ public int amount() { return Optional.ofNullable(customModelData); } + public @NotNull Optional customModelDataComponent() { + return Optional.ofNullable(customModelDataComponent); + } + public @NotNull Optional dynamicAmount() { return Optional.ofNullable(dynamicAmount); } @@ -354,6 +360,7 @@ public boolean updatePlaceholders() { .damage(this.damage) .amount(this.amount) .customModelData(this.customModelData) + .customModelDataComponent(this.customModelDataComponent) .dynamicAmount(this.dynamicAmount) .lightLevel(this.lightLevel) .displayName(this.displayName) @@ -407,6 +414,7 @@ public static class MenuItemOptionsBuilder { private String damage; private int amount; private String customModelData; + private CustomModelDataComponent customModelDataComponent; private String dynamicAmount; private String lightLevel; private String displayName; @@ -487,6 +495,11 @@ public MenuItemOptionsBuilder customModelData(final @Nullable String customModel return this; } + public MenuItemOptionsBuilder customModelDataComponent(final @Nullable CustomModelDataComponent customModelDataComponent) { + this.customModelDataComponent = customModelDataComponent; + return this; + } + public MenuItemOptionsBuilder dynamicAmount(final @Nullable String configDynamicAmount) { this.dynamicAmount = configDynamicAmount; return this; diff --git a/src/main/java/com/extendedclip/deluxemenus/utils/VersionHelper.java b/src/main/java/com/extendedclip/deluxemenus/utils/VersionHelper.java index 08e0d68f..87e9a943 100644 --- a/src/main/java/com/extendedclip/deluxemenus/utils/VersionHelper.java +++ b/src/main/java/com/extendedclip/deluxemenus/utils/VersionHelper.java @@ -21,6 +21,8 @@ public final class VersionHelper { private static final String PACKAGE_NAME = Bukkit.getServer().getClass().getPackage().getName(); public static final String NMS_VERSION = PACKAGE_NAME.substring(PACKAGE_NAME.lastIndexOf('.') + 1); + // Custom Model Data Component + private static final int V1_21_4 = 1_21_4; // Tooltip Style & Item Model private static final int V1_21_2 = 1_21_2; // Data components @@ -98,6 +100,8 @@ public final class VersionHelper { */ public static final boolean IS_CUSTOM_MODEL_DATA = CURRENT_VERSION >= V1_14; + public static final boolean IS_CUSTOM_MODEL_DATA_COMPONENT = CURRENT_VERSION >= V1_21_4; + public static final boolean IS_HEX_VERSION = CURRENT_VERSION >= V1_16; private static List CHEST_INVENTORY_TYPES = null; From 605eedf1697ed1d935e9e6a172dda35fba1b3b3b Mon Sep 17 00:00:00 2001 From: BlitzOffline <52609756+BlitzOffline@users.noreply.github.com> Date: Sat, 17 May 2025 01:31:16 +0300 Subject: [PATCH 2/5] Added support for the new CustomModelDataComponent that was added in 1.21.4 for has item requirement --- .../deluxemenus/config/DeluxeMenusConfig.java | 13 +++ .../deluxemenus/menu/MenuItem.java | 20 ++-- .../requirement/HasItemRequirement.java | 101 +++++++++++++++++- .../requirement/wrappers/ItemWrapper.java | 11 ++ .../deluxemenus/utils/StringUtils.java | 15 +++ 5 files changed, 144 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java b/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java index fb830157..5ca3201b 100644 --- a/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java +++ b/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java @@ -921,6 +921,19 @@ private RequirementList getRequirements(FileConfiguration c, String path) { wrapper.setCustomData(c.getInt(rPath + ".modeldata", 0)); } + if (c.contains(rPath + "model_data_component") && c.isConfigurationSection(rPath + "model_data_component")) { + final ConfigurationSection modelDataComponent = c.getConfigurationSection(rPath + "model_data_component"); + if (modelDataComponent != null) { + wrapper.setCustomModelDataComponent( + CustomModelDataComponent.builder() + .colors(modelDataComponent.getStringList("colors")) + .flags(modelDataComponent.getStringList("flags")) + .floats(modelDataComponent.getStringList("floats")) + .strings(modelDataComponent.getStringList("strings")) + ); + } + } + if (c.contains(rPath + ".name_contains")) { wrapper.setNameContains(c.getBoolean(rPath + ".name_contains")); } else { diff --git a/src/main/java/com/extendedclip/deluxemenus/menu/MenuItem.java b/src/main/java/com/extendedclip/deluxemenus/menu/MenuItem.java index 573b605e..13f70198 100644 --- a/src/main/java/com/extendedclip/deluxemenus/menu/MenuItem.java +++ b/src/main/java/com/extendedclip/deluxemenus/menu/MenuItem.java @@ -591,21 +591,15 @@ protected List getMenuItemLore(@NotNull final MenuHolder holder, @NotNul } private @Nullable Color parseRGBColor(@NotNull final String input) { - final String[] parts = input.split(","); - try { - return Color.fromRGB( - Integer.parseInt(parts[0].trim()), - Integer.parseInt(parts[1].trim()), - Integer.parseInt(parts[2].trim()) + final Color color = StringUtils.parseRGBColor(input); + if (color == null) { + plugin.debug( + DebugLevel.HIGHEST, + Level.WARNING, + "Invalid RGB color found: " + input ); - } catch (final Exception exception) { - plugin.printStacktrace( - "Invalid RGB color found: " + parts[0].trim() + ", " + parts[1].trim() + ", " + - parts[2].trim(), - exception - ); - return null; } + return color; } public @NotNull MenuItemOptions options() { diff --git a/src/main/java/com/extendedclip/deluxemenus/requirement/HasItemRequirement.java b/src/main/java/com/extendedclip/deluxemenus/requirement/HasItemRequirement.java index 97b3d965..6cefa4c0 100644 --- a/src/main/java/com/extendedclip/deluxemenus/requirement/HasItemRequirement.java +++ b/src/main/java/com/extendedclip/deluxemenus/requirement/HasItemRequirement.java @@ -7,11 +7,17 @@ import com.extendedclip.deluxemenus.utils.StringUtils; import com.extendedclip.deluxemenus.utils.VersionHelper; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; + +import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.components.CustomModelDataComponent; +import org.jetbrains.annotations.NotNull; +@SuppressWarnings("UnstableApiUsage") public class HasItemRequirement extends Requirement { private final DeluxeMenus plugin; @@ -80,15 +86,33 @@ private boolean isRequiredItem(ItemStack itemToCheck, MenuHolder holder, Materia if (wrapper.isStrict()) { if (metaToCheck != null) { if (VersionHelper.IS_CUSTOM_MODEL_DATA) { - if (metaToCheck.hasCustomModelData()) return false; + if (metaToCheck.hasCustomModelData()) { + return false; + } + } + if (VersionHelper.IS_CUSTOM_MODEL_DATA_COMPONENT) { + if (metaToCheck.hasCustomModelDataComponent()) { + if (!isEmptyModelData(metaToCheck.getCustomModelDataComponent())) { + return false; + } + } } if (metaToCheck.hasLore()) return false; return !metaToCheck.hasDisplayName(); } } else { - if ((wrapper.getCustomData() != 0 || wrapper.getName() != null || wrapper.getLore() != null) && metaToCheck == null) - return false; + if (metaToCheck == null) { + if (wrapper.getCustomData() != 0 || wrapper.getName() != null || wrapper.getLore() != null) { + return false; + } + + if (VersionHelper.IS_CUSTOM_MODEL_DATA_COMPONENT) { + if (isEmptyModelData(wrapper.getCustomModelDataComponent())) { + return false; + } + } + } if (wrapper.getCustomData() != 0) { if (VersionHelper.IS_CUSTOM_MODEL_DATA) { @@ -97,6 +121,17 @@ private boolean isRequiredItem(ItemStack itemToCheck, MenuHolder holder, Materia } } + if (VersionHelper.IS_CUSTOM_MODEL_DATA_COMPONENT) { + if (!isEmptyModelData(wrapper.getCustomModelDataComponent())) { + if (!metaToCheck.hasCustomModelDataComponent()) { + return false; + } + if (!itemModelComponentContains(holder, metaToCheck.getCustomModelDataComponent(), wrapper.getCustomModelDataComponent())) { + return false; + } + } + } + if (wrapper.getName() != null) { if (!metaToCheck.hasDisplayName()) return false; @@ -159,4 +194,64 @@ else if (wrapper.checkLoreIgnoreCase()) { } return true; } + + private boolean isEmptyModelData(@NotNull final CustomModelDataComponent modelData) { + return modelData.getColors().isEmpty() && modelData.getFlags().isEmpty() && modelData.getFloats().isEmpty() && modelData.getStrings().isEmpty(); + } + + private boolean isEmptyModelData(@NotNull final com.extendedclip.deluxemenus.menu.options.CustomModelDataComponent modelData) { + return modelData.colors().isEmpty() && modelData.flags().isEmpty() && modelData.floats().isEmpty() && modelData.strings().isEmpty(); + } + + private boolean itemModelComponentContains(MenuHolder holder, @NotNull final CustomModelDataComponent modelData, @NotNull final com.extendedclip.deluxemenus.menu.options.CustomModelDataComponent wrapper) { + if (!wrapper.colors().isEmpty()) { + final List colors = wrapper.colors() + .stream() + .map(holder::setPlaceholdersAndArguments) + .map(StringUtils::parseRGBColor) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + for (Color color : colors) { + if (!modelData.getColors().contains(color)) return false; + } + } + + if (!wrapper.flags().isEmpty()) { + final List flags = wrapper.flags() + .stream() + .map(holder::setPlaceholdersAndArguments) + .map(Boolean::parseBoolean) + .collect(Collectors.toList()); + + for (Boolean flag : flags) { + if (!modelData.getFlags().contains(flag)) return false; + } + } + + if (!wrapper.floats().isEmpty()) { + final List floats = wrapper.floats() + .stream() + .map(holder::setPlaceholdersAndArguments) + .map(Float::parseFloat) + .collect(Collectors.toList()); + + for (Float floatValue : floats) { + if (!modelData.getFloats().contains(floatValue)) return false; + } + } + + if (!wrapper.strings().isEmpty()) { + final List strings = wrapper.strings() + .stream() + .map(holder::setPlaceholdersAndArguments) + .collect(Collectors.toList()); + + for (String string : strings) { + if (!modelData.getStrings().contains(string)) return false; + } + } + + return true; + } } diff --git a/src/main/java/com/extendedclip/deluxemenus/requirement/wrappers/ItemWrapper.java b/src/main/java/com/extendedclip/deluxemenus/requirement/wrappers/ItemWrapper.java index f3bf7a8f..32dd5ff5 100644 --- a/src/main/java/com/extendedclip/deluxemenus/requirement/wrappers/ItemWrapper.java +++ b/src/main/java/com/extendedclip/deluxemenus/requirement/wrappers/ItemWrapper.java @@ -1,5 +1,7 @@ package com.extendedclip.deluxemenus.requirement.wrappers; +import com.extendedclip.deluxemenus.menu.options.CustomModelDataComponent; + import java.util.List; public class ItemWrapper { @@ -11,6 +13,7 @@ public class ItemWrapper { private short data = 0; private boolean hasData = false; + private CustomModelDataComponent customDataComponent = null; private int customData = 0; private int amount = 1; @@ -80,6 +83,14 @@ public void setCustomData(int customData) { this.customData = customData; } + public CustomModelDataComponent getCustomModelDataComponent() { + return this.customDataComponent; + } + + public void setCustomModelDataComponent(CustomModelDataComponent customDataComponent) { + this.customDataComponent = customDataComponent; + } + public int getAmount() { return amount; } diff --git a/src/main/java/com/extendedclip/deluxemenus/utils/StringUtils.java b/src/main/java/com/extendedclip/deluxemenus/utils/StringUtils.java index 0304c7eb..6ae95804 100644 --- a/src/main/java/com/extendedclip/deluxemenus/utils/StringUtils.java +++ b/src/main/java/com/extendedclip/deluxemenus/utils/StringUtils.java @@ -6,6 +6,7 @@ import me.clip.placeholderapi.PlaceholderAPI; import net.md_5.bungee.api.ChatColor; +import org.bukkit.Color; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -73,4 +74,18 @@ public static String replaceArguments(@NotNull String input, final @Nullable Map return input; } + + @Nullable + public static Color parseRGBColor(@NotNull final String input) { + final String[] parts = input.split(","); + try { + return Color.fromRGB( + Integer.parseInt(parts[0].trim()), + Integer.parseInt(parts[1].trim()), + Integer.parseInt(parts[2].trim()) + ); + } catch (final Exception exception) { + return null; + } + } } From 559b2a784441ce10351f23da66e4d8e54c08abf8 Mon Sep 17 00:00:00 2001 From: BlitzOffline <52609756+BlitzOffline@users.noreply.github.com> Date: Wed, 28 May 2025 02:24:47 +0300 Subject: [PATCH 3/5] fix has item with custom model data component --- .../deluxemenus/config/DeluxeMenusConfig.java | 130 +----- .../requirement/HasItemRequirement.java | 401 +++++++++--------- .../requirement/wrappers/ItemWrapper.java | 7 +- 3 files changed, 217 insertions(+), 321 deletions(-) diff --git a/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java b/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java index 5ca3201b..e935baaa 100644 --- a/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java +++ b/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java @@ -6,13 +6,13 @@ import com.extendedclip.deluxemenus.action.ClickActionTask; import com.extendedclip.deluxemenus.action.ClickHandler; import com.extendedclip.deluxemenus.hooks.ItemHook; -import com.extendedclip.deluxemenus.menu.options.LoreAppendMode; import com.extendedclip.deluxemenus.menu.Menu; import com.extendedclip.deluxemenus.menu.MenuHolder; import com.extendedclip.deluxemenus.menu.MenuItem; +import com.extendedclip.deluxemenus.menu.options.CustomModelDataComponent; +import com.extendedclip.deluxemenus.menu.options.LoreAppendMode; import com.extendedclip.deluxemenus.menu.options.MenuItemOptions; import com.extendedclip.deluxemenus.menu.options.MenuOptions; -import com.extendedclip.deluxemenus.menu.options.CustomModelDataComponent; import com.extendedclip.deluxemenus.requirement.HasExpRequirement; import com.extendedclip.deluxemenus.requirement.HasItemRequirement; import com.extendedclip.deluxemenus.requirement.HasMetaRequirement; @@ -156,13 +156,7 @@ public boolean loadDefConfig() { FileConfiguration c = plugin.getConfig(); - c.options().header( - "DeluxeMenus " + plugin.getDescription().getVersion() + " main configuration file" + - "\n" + - "\nA full wiki on how to use this plugin can be found at:" + - "\nhttps://wiki.helpch.at/helpchat-plugins/deluxemenus" + - "\n" - ); + c.options().header("DeluxeMenus " + plugin.getDescription().getVersion() + " main configuration file" + "\n" + "\nA full wiki on how to use this plugin can be found at:" + "\nhttps://wiki.helpch.at/helpchat-plugins/deluxemenus" + "\n"); c.addDefault("debug", "LOW"); c.addDefault("check_updates", true); c.addDefault("use_admin_commands_in_menus_list", false); @@ -598,51 +592,12 @@ private Map> loadMenuItems(FileConfiguration checkForDeprecatedItemOptions(c.getConfigurationSection(currentPath), name); - MenuItemOptions.MenuItemOptionsBuilder builder = MenuItemOptions.builder() - .material(material) - .baseColor(Optional.ofNullable(c.getString(currentPath + "base_color")) - .map(String::toUpperCase) - .map(DyeColor::valueOf) - .orElse(null)) - .slot(c.getInt(currentPath + "slot", 0)) - .amount(c.getInt(currentPath + "amount", -1)) - .dynamicAmount(c.getString(currentPath + "dynamic_amount", null)) - .customModelData(c.getString(currentPath + "model_data", null)) - .lightLevel(c.getString(currentPath + "light_level", null)) - .displayName(c.getString(currentPath + "display_name")) - .lore(c.getStringList(currentPath + "lore")) - .hasLore(c.contains(currentPath + "lore")) - .rgb(c.getString(currentPath + "rgb", null)) - .unbreakable(c.getBoolean(currentPath + "unbreakable", false)) - .updatePlaceholders(c.getBoolean(currentPath + "update", false)) - .hideAttributes(c.getBoolean(currentPath + "hide_attributes", false)) - .hideUnbreakable(c.getBoolean(currentPath + "hide_unbreakable", false)) - .hideEnchants(c.getBoolean(currentPath + "hide_enchantments", false)) - .nbtString(c.getString(currentPath + "nbt_string", null)) - .nbtByte(c.getString(currentPath + "nbt_byte", null)) - .nbtShort(c.getString(currentPath + "nbt_short", null)) - .nbtInt(c.getString(currentPath + "nbt_int", null)) - .nbtStrings(c.getStringList(currentPath + "nbt_strings")) - .nbtBytes(c.getStringList(currentPath + "nbt_bytes")) - .nbtShorts(c.getStringList(currentPath + "nbt_shorts")) - .nbtInts(c.getStringList(currentPath + "nbt_ints")) - .priority(c.getInt(currentPath + "priority", 1)) - .hideTooltip(c.getString(currentPath + "hide_tooltip", null)) - .enchantmentGlintOverride(c.getString(currentPath + "enchantment_glint_override", null)) - .rarity(c.getString(currentPath + "rarity", null)) - .tooltipStyle(c.getString(currentPath + "tooltip_style", null)) - .itemModel(c.getString(currentPath + "item_model", null)); + MenuItemOptions.MenuItemOptionsBuilder builder = MenuItemOptions.builder().material(material).baseColor(Optional.ofNullable(c.getString(currentPath + "base_color")).map(String::toUpperCase).map(DyeColor::valueOf).orElse(null)).slot(c.getInt(currentPath + "slot", 0)).amount(c.getInt(currentPath + "amount", -1)).dynamicAmount(c.getString(currentPath + "dynamic_amount", null)).customModelData(c.getString(currentPath + "model_data", null)).lightLevel(c.getString(currentPath + "light_level", null)).displayName(c.getString(currentPath + "display_name")).lore(c.getStringList(currentPath + "lore")).hasLore(c.contains(currentPath + "lore")).rgb(c.getString(currentPath + "rgb", null)).unbreakable(c.getBoolean(currentPath + "unbreakable", false)).updatePlaceholders(c.getBoolean(currentPath + "update", false)).hideAttributes(c.getBoolean(currentPath + "hide_attributes", false)).hideUnbreakable(c.getBoolean(currentPath + "hide_unbreakable", false)).hideEnchants(c.getBoolean(currentPath + "hide_enchantments", false)).nbtString(c.getString(currentPath + "nbt_string", null)).nbtByte(c.getString(currentPath + "nbt_byte", null)).nbtShort(c.getString(currentPath + "nbt_short", null)).nbtInt(c.getString(currentPath + "nbt_int", null)).nbtStrings(c.getStringList(currentPath + "nbt_strings")).nbtBytes(c.getStringList(currentPath + "nbt_bytes")).nbtShorts(c.getStringList(currentPath + "nbt_shorts")).nbtInts(c.getStringList(currentPath + "nbt_ints")).priority(c.getInt(currentPath + "priority", 1)).hideTooltip(c.getString(currentPath + "hide_tooltip", null)).enchantmentGlintOverride(c.getString(currentPath + "enchantment_glint_override", null)).rarity(c.getString(currentPath + "rarity", null)).tooltipStyle(c.getString(currentPath + "tooltip_style", null)).itemModel(c.getString(currentPath + "item_model", null)); if (c.contains(currentPath + "model_data_component") && c.isConfigurationSection(currentPath + "model_data_component")) { final ConfigurationSection modelDataComponent = c.getConfigurationSection(currentPath + "model_data_component"); if (modelDataComponent != null) { - builder.customModelDataComponent( - CustomModelDataComponent.builder() - .colors(modelDataComponent.getStringList("colors")) - .flags(modelDataComponent.getStringList("flags")) - .floats(modelDataComponent.getStringList("floats")) - .strings(modelDataComponent.getStringList("strings")) - ); + builder.customModelDataComponent(CustomModelDataComponent.builder().colors(modelDataComponent.getStringList("colors")).flags(modelDataComponent.getStringList("flags")).floats(modelDataComponent.getStringList("floats")).strings(modelDataComponent.getStringList("strings"))); } } @@ -880,11 +835,7 @@ private RequirementList getRequirements(FileConfiguration c, String path) { if (c.contains(rPath + ".material")) { String materialName = c.getString(rPath + ".material"); try { - if (!containsPlaceholders(materialName) && plugin.getItemHooks().values() - .stream() - .filter(x -> materialName.toLowerCase().startsWith(x.getPrefix())) - .findFirst() - .orElse(null) == null) + if (!containsPlaceholders(materialName) && plugin.getItemHooks().values().stream().filter(x -> materialName.toLowerCase().startsWith(x.getPrefix())).findFirst().orElse(null) == null) Material.valueOf(materialName.toUpperCase()); } catch (Exception ex) { plugin.debug(DebugLevel.HIGHEST, Level.WARNING, "has item requirement at path: " + rPath + " does not specify a valid Material name!"); @@ -921,16 +872,15 @@ private RequirementList getRequirements(FileConfiguration c, String path) { wrapper.setCustomData(c.getInt(rPath + ".modeldata", 0)); } - if (c.contains(rPath + "model_data_component") && c.isConfigurationSection(rPath + "model_data_component")) { - final ConfigurationSection modelDataComponent = c.getConfigurationSection(rPath + "model_data_component"); + if (c.contains(rPath + ".model_data_component") && c.isConfigurationSection(rPath + ".model_data_component")) { + final ConfigurationSection modelDataComponent = c.getConfigurationSection(rPath + ".model_data_component"); if (modelDataComponent != null) { wrapper.setCustomModelDataComponent( CustomModelDataComponent.builder() .colors(modelDataComponent.getStringList("colors")) .flags(modelDataComponent.getStringList("flags")) .floats(modelDataComponent.getStringList("floats")) - .strings(modelDataComponent.getStringList("strings")) - ); + .strings(modelDataComponent.getStringList("strings"))); } } @@ -976,36 +926,20 @@ private RequirementList getRequirements(FileConfiguration c, String path) { invert = type == RequirementType.DOES_NOT_HAVE_PERMISSIONS; int minimum = -1; if (c.contains(rPath + ".minimum") && (minimum = c.getInt(rPath + ".minimum")) < 1) { - plugin.debug( - DebugLevel.HIGHEST, - Level.WARNING, - "Has Permissions requirement at path: " + rPath + " has a minimum lower than 1. All permissions will be checked" - ); + plugin.debug(DebugLevel.HIGHEST, Level.WARNING, "Has Permissions requirement at path: " + rPath + " has a minimum lower than 1. All permissions will be checked"); minimum = -1; } List permissions = c.getStringList(rPath + ".permissions"); if (permissions.isEmpty()) { - plugin.debug( - DebugLevel.HIGHEST, - Level.WARNING, - "Has Permissions requirement at path: " + rPath + " has no permissions to check. Ignoring..." - ); + plugin.debug(DebugLevel.HIGHEST, Level.WARNING, "Has Permissions requirement at path: " + rPath + " has no permissions to check. Ignoring..."); break; } else if (minimum > permissions.size()) { - plugin.debug( - DebugLevel.HIGHEST, - Level.WARNING, - "Has Permissions requirement at path: " + rPath + " has a minimum higher than the amount of permissions. Using "+permissions.size()+" instead" - ); + plugin.debug(DebugLevel.HIGHEST, Level.WARNING, "Has Permissions requirement at path: " + rPath + " has a minimum higher than the amount of permissions. Using " + permissions.size() + " instead"); minimum = permissions.size(); } req = new HasPermissionsRequirement(permissions, minimum, invert); } else { - plugin.debug( - DebugLevel.HIGHEST, - Level.WARNING, - "Has Permissions requirement at path: " + rPath + " does not contain permissions: entry" - ); + plugin.debug(DebugLevel.HIGHEST, Level.WARNING, "Has Permissions requirement at path: " + rPath + " does not contain permissions: entry"); } break; case JAVASCRIPT: @@ -1279,9 +1213,8 @@ public void debug(String... messages) { public File getMenuDirector() { return menuDirectory; } - public void addEnchantmentsOptionToBuilder(final FileConfiguration c, final String currentPath, - final String itemKey, final String menuName, - final MenuItemOptions.MenuItemOptionsBuilder builder) { + + public void addEnchantmentsOptionToBuilder(final FileConfiguration c, final String currentPath, final String itemKey, final String menuName, final MenuItemOptions.MenuItemOptionsBuilder builder) { if (!c.contains(currentPath + "enchantments")) { return; } @@ -1291,55 +1224,32 @@ public void addEnchantmentsOptionToBuilder(final FileConfiguration c, final Stri for (final String configEnchantment : configEnchantments) { if (configEnchantment == null || !configEnchantment.contains(";")) { - plugin.debug( - DebugLevel.HIGHEST, - Level.WARNING, - "Enchantment format '" + configEnchantment + "' is incorrect for item " + itemKey + - " in GUI " + menuName + "!", - "Correct format: - ';" - ); + plugin.debug(DebugLevel.HIGHEST, Level.WARNING, "Enchantment format '" + configEnchantment + "' is incorrect for item " + itemKey + " in GUI " + menuName + "!", "Correct format: - ';"); continue; } String[] parts = configEnchantment.split(";", 2); if (parts.length != 2 || parts[0] == null || parts[1] == null) { - plugin.debug( - DebugLevel.HIGHEST, - Level.WARNING, - "Enchantment format '" + configEnchantment + "' is incorrect for item " + itemKey + - " in GUI " + menuName + "!", - "Correct format: - ';" - ); + plugin.debug(DebugLevel.HIGHEST, Level.WARNING, "Enchantment format '" + configEnchantment + "' is incorrect for item " + itemKey + " in GUI " + menuName + "!", "Correct format: - ';"); continue; } final Enchantment enchantment = Enchantment.getByName(parts[0].strip().toUpperCase()); if (enchantment == null) { - plugin.debug( - DebugLevel.HIGHEST, - Level.WARNING, - "Enchantment '" + parts[0].strip() + "' for item " + itemKey + - " in menu " + menuName + " is not a valid enchantment name!" - ); + plugin.debug(DebugLevel.HIGHEST, Level.WARNING, "Enchantment '" + parts[0].strip() + "' for item " + itemKey + " in menu " + menuName + " is not a valid enchantment name!"); } Integer level = Ints.tryParse(parts[1].strip()); if (level == null) { level = 1; - plugin.debug( - DebugLevel.HIGHEST, - Level.WARNING, - "Enchantment level '" + parts[1].strip() + "' is incorrect for item " + itemKey + - " in menu " + menuName + "!" - ); + plugin.debug(DebugLevel.HIGHEST, Level.WARNING, "Enchantment level '" + parts[1].strip() + "' is incorrect for item " + itemKey + " in menu " + menuName + "!"); } parsedEnchantments.put(enchantment, level); } builder.enchantments(parsedEnchantments); } - public void addDamageOptionToBuilder(final FileConfiguration c, final String currentPath, final String itemKey, - final String menuName, final MenuItemOptions.MenuItemOptionsBuilder builder) { + public void addDamageOptionToBuilder(final FileConfiguration c, final String currentPath, final String itemKey, final String menuName, final MenuItemOptions.MenuItemOptionsBuilder builder) { boolean damageOptionIsPresent = false; String damageValue = null; diff --git a/src/main/java/com/extendedclip/deluxemenus/requirement/HasItemRequirement.java b/src/main/java/com/extendedclip/deluxemenus/requirement/HasItemRequirement.java index 6cefa4c0..9c1a1442 100644 --- a/src/main/java/com/extendedclip/deluxemenus/requirement/HasItemRequirement.java +++ b/src/main/java/com/extendedclip/deluxemenus/requirement/HasItemRequirement.java @@ -6,10 +6,6 @@ import com.extendedclip.deluxemenus.requirement.wrappers.ItemWrapper; import com.extendedclip.deluxemenus.utils.StringUtils; import com.extendedclip.deluxemenus.utils.VersionHelper; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; @@ -17,241 +13,230 @@ import org.bukkit.inventory.meta.components.CustomModelDataComponent; import org.jetbrains.annotations.NotNull; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + @SuppressWarnings("UnstableApiUsage") public class HasItemRequirement extends Requirement { - private final DeluxeMenus plugin; - private final ItemWrapper wrapper; - private final boolean invert; - - public HasItemRequirement(final DeluxeMenus plugin, final ItemWrapper wrapper, final boolean invert) { - this.plugin = plugin; - this.wrapper = wrapper; - this.invert = invert; - } - - @Override - public boolean evaluate(MenuHolder holder) { - String materialName = holder.setPlaceholdersAndArguments(wrapper.getMaterial()); - Material material = DeluxeMenus.MATERIALS.get(materialName.toUpperCase()); - ItemHook pluginHook = null; - if (material == null) { - pluginHook = plugin.getItemHooks().values() - .stream() - .filter(x -> materialName.toLowerCase().startsWith(x.getPrefix())) - .findFirst() - .orElse(null); - if (pluginHook == null) return invert; - } - - if (material == Material.AIR) return invert == (holder.getViewer().getInventory().firstEmpty() == -1); - - ItemStack[] armor = wrapper.checkArmor() ? holder.getViewer().getInventory().getArmorContents() : null; - ItemStack[] offHand = wrapper.checkOffhand() ? holder.getViewer().getInventory().getExtraContents() : null; - ItemStack[] inventory = holder.getViewer().getInventory().getStorageContents(); + private final DeluxeMenus plugin; + private final ItemWrapper wrapper; + private final boolean invert; - int total = 0; - for (ItemStack itemToCheck: inventory) { - if (!isRequiredItem(itemToCheck, holder, material, pluginHook)) continue; - total += itemToCheck.getAmount(); + public HasItemRequirement(final DeluxeMenus plugin, final ItemWrapper wrapper, final boolean invert) { + this.plugin = plugin; + this.wrapper = wrapper; + this.invert = invert; } - if (offHand != null) { - for (ItemStack itemToCheck: offHand) { - if (!isRequiredItem(itemToCheck, holder, material, pluginHook)) continue; - total += itemToCheck.getAmount(); - } - } - - if (armor != null) { - for (ItemStack itemToCheck: armor) { - if (!isRequiredItem(itemToCheck, holder, material, pluginHook)) continue; - total += itemToCheck.getAmount(); - } - } + @Override + public boolean evaluate(MenuHolder holder) { + String materialName = holder.setPlaceholdersAndArguments(wrapper.getMaterial()); + Material material = DeluxeMenus.MATERIALS.get(materialName.toUpperCase()); + ItemHook pluginHook = null; + if (material == null) { + pluginHook = plugin.getItemHooks().values() + .stream() + .filter(x -> materialName.toLowerCase().startsWith(x.getPrefix())) + .findFirst() + .orElse(null); + if (pluginHook == null) return invert; + } - return invert == (total < wrapper.getAmount()); - } + if (material == Material.AIR) return invert == (holder.getViewer().getInventory().firstEmpty() == -1); - private boolean isRequiredItem(ItemStack itemToCheck, MenuHolder holder, Material material, ItemHook pluginHook) { - if (itemToCheck == null || itemToCheck.getType() == Material.AIR) return false; + ItemStack[] armor = wrapper.checkArmor() ? holder.getViewer().getInventory().getArmorContents() : null; + ItemStack[] offHand = wrapper.checkOffhand() ? holder.getViewer().getInventory().getExtraContents() : null; + ItemStack[] inventory = holder.getViewer().getInventory().getStorageContents(); - if (pluginHook != null) { - if (!pluginHook.itemMatchesIdentifiers(itemToCheck, holder.setPlaceholdersAndArguments(wrapper.getMaterial().substring(pluginHook.getPrefix().length())))) return false; - } - else if (wrapper.getMaterial() != null && itemToCheck.getType() != material) return false; - if (wrapper.hasData() && itemToCheck.getDurability() != wrapper.getData()) return false; - - ItemMeta metaToCheck = itemToCheck.getItemMeta(); - if (wrapper.isStrict()) { - if (metaToCheck != null) { - if (VersionHelper.IS_CUSTOM_MODEL_DATA) { - if (metaToCheck.hasCustomModelData()) { - return false; - } - } - if (VersionHelper.IS_CUSTOM_MODEL_DATA_COMPONENT) { - if (metaToCheck.hasCustomModelDataComponent()) { - if (!isEmptyModelData(metaToCheck.getCustomModelDataComponent())) { - return false; - } - } - } - if (metaToCheck.hasLore()) return false; - return !metaToCheck.hasDisplayName(); - } - - } else { - if (metaToCheck == null) { - if (wrapper.getCustomData() != 0 || wrapper.getName() != null || wrapper.getLore() != null) { - return false; + int total = 0; + for (ItemStack itemToCheck : inventory) { + if (!isRequiredItem(itemToCheck, holder, material, pluginHook)) continue; + total += itemToCheck.getAmount(); } - if (VersionHelper.IS_CUSTOM_MODEL_DATA_COMPONENT) { - if (isEmptyModelData(wrapper.getCustomModelDataComponent())) { - return false; - } + if (offHand != null) { + for (ItemStack itemToCheck : offHand) { + if (!isRequiredItem(itemToCheck, holder, material, pluginHook)) continue; + total += itemToCheck.getAmount(); + } } - } - if (wrapper.getCustomData() != 0) { - if (VersionHelper.IS_CUSTOM_MODEL_DATA) { - if (!metaToCheck.hasCustomModelData()) return false; - if (metaToCheck.getCustomModelData() != wrapper.getCustomData()) return false; - } - } - - if (VersionHelper.IS_CUSTOM_MODEL_DATA_COMPONENT) { - if (!isEmptyModelData(wrapper.getCustomModelDataComponent())) { - if (!metaToCheck.hasCustomModelDataComponent()) { - return false; - } - if (!itemModelComponentContains(holder, metaToCheck.getCustomModelDataComponent(), wrapper.getCustomModelDataComponent())) { - return false; - } + if (armor != null) { + for (ItemStack itemToCheck : armor) { + if (!isRequiredItem(itemToCheck, holder, material, pluginHook)) continue; + total += itemToCheck.getAmount(); + } } - } - if (wrapper.getName() != null) { - if (!metaToCheck.hasDisplayName()) return false; + return invert == (total < wrapper.getAmount()); + } - String name = StringUtils.color(holder.setPlaceholdersAndArguments(wrapper.getName())); - String nameToCheck = StringUtils.color(holder.setPlaceholdersAndArguments(metaToCheck.getDisplayName())); + private boolean isRequiredItem(ItemStack itemToCheck, MenuHolder holder, Material material, ItemHook pluginHook) { + if (itemToCheck == null || itemToCheck.getType() == Material.AIR) return false; + + if (pluginHook != null) { + if (!pluginHook.itemMatchesIdentifiers(itemToCheck, holder.setPlaceholdersAndArguments(wrapper.getMaterial().substring(pluginHook.getPrefix().length())))) + return false; + } else if (wrapper.getMaterial() != null && itemToCheck.getType() != material) return false; + if (wrapper.hasData() && itemToCheck.getDurability() != wrapper.getData()) return false; + + ItemMeta metaToCheck = itemToCheck.getItemMeta(); + if (wrapper.isStrict()) { + if (metaToCheck != null) { + if (VersionHelper.IS_CUSTOM_MODEL_DATA && metaToCheck.hasCustomModelData()) { + return false; + } + if (VersionHelper.IS_CUSTOM_MODEL_DATA_COMPONENT && !isEmptyModelData(metaToCheck.getCustomModelDataComponent())) { + return false; + } + if (metaToCheck.hasLore()) return false; + return !metaToCheck.hasDisplayName(); + } + } else { + if (metaToCheck == null) { + if (wrapper.getCustomData() != 0 || wrapper.getName() != null || wrapper.getLore() != null || wrapper.getLoreList() != null) { + return false; + } + + if (VersionHelper.IS_CUSTOM_MODEL_DATA_COMPONENT) { + if (!isEmptyModelData(wrapper.getCustomModelDataComponent())) { + return false; + } + } + } - if (wrapper.checkNameContains() && wrapper.checkNameIgnoreCase()) { - if (!org.apache.commons.lang3.StringUtils.containsIgnoreCase(nameToCheck, name)) return false; - } - else if (wrapper.checkNameContains()) { - if (!nameToCheck.contains(name)) return false; - } - else if (wrapper.checkNameIgnoreCase()) { - if (!nameToCheck.equalsIgnoreCase(name)) return false; - } - else if (!nameToCheck.equals(name)) { - return false; - } - } + if (wrapper.getCustomData() != 0) { + if (VersionHelper.IS_CUSTOM_MODEL_DATA) { + if (!metaToCheck.hasCustomModelData()) return false; + if (metaToCheck.getCustomModelData() != wrapper.getCustomData()) return false; + } + } - if (wrapper.getLoreList() != null) { - List loreX = metaToCheck.getLore(); - if (loreX == null) return false; + if (VersionHelper.IS_CUSTOM_MODEL_DATA_COMPONENT && !isEmptyModelData(wrapper.getCustomModelDataComponent()) && !itemModelComponentContains(holder, metaToCheck.getCustomModelDataComponent(), wrapper.getCustomModelDataComponent())) { + return false; + } - String lore = wrapper.getLoreList().stream().map(holder::setPlaceholdersAndArguments).map(StringUtils::color).collect(Collectors.joining("&&")); - String loreToCheck = loreX.stream().map(holder::setPlaceholdersAndArguments).map(StringUtils::color).collect(Collectors.joining("&&")); + if (wrapper.getName() != null) { + if (!metaToCheck.hasDisplayName()) return false; + + String name = StringUtils.color(holder.setPlaceholdersAndArguments(wrapper.getName())); + String nameToCheck = StringUtils.color(holder.setPlaceholdersAndArguments(metaToCheck.getDisplayName())); + + if (wrapper.checkNameContains() && wrapper.checkNameIgnoreCase()) { + if (!org.apache.commons.lang3.StringUtils.containsIgnoreCase(nameToCheck, name)) return false; + } else if (wrapper.checkNameContains()) { + if (!nameToCheck.contains(name)) return false; + } else if (wrapper.checkNameIgnoreCase()) { + if (!nameToCheck.equalsIgnoreCase(name)) return false; + } else if (!nameToCheck.equals(name)) { + return false; + } + } - if (wrapper.checkLoreContains() && wrapper.checkLoreIgnoreCase()) { - if (!org.apache.commons.lang3.StringUtils.containsIgnoreCase(loreToCheck, lore)) return false; - } - else if (wrapper.checkLoreContains()) { - if (!loreToCheck.contains(lore)) return false; - } - else if (wrapper.checkLoreIgnoreCase()) { - if (!loreToCheck.equalsIgnoreCase(lore)) return false; - } - else if (!loreToCheck.equals(lore)) { - return false; - } - } + if (wrapper.getLoreList() != null) { + List loreX = metaToCheck.getLore(); + if (loreX == null) return false; + + String lore = wrapper.getLoreList().stream().map(holder::setPlaceholdersAndArguments).map(StringUtils::color).collect(Collectors.joining("&&")); + String loreToCheck = loreX.stream().map(holder::setPlaceholdersAndArguments).map(StringUtils::color).collect(Collectors.joining("&&")); + + if (wrapper.checkLoreContains() && wrapper.checkLoreIgnoreCase()) { + if (!org.apache.commons.lang3.StringUtils.containsIgnoreCase(loreToCheck, lore)) return false; + } else if (wrapper.checkLoreContains()) { + if (!loreToCheck.contains(lore)) return false; + } else if (wrapper.checkLoreIgnoreCase()) { + if (!loreToCheck.equalsIgnoreCase(lore)) return false; + } else if (!loreToCheck.equals(lore)) { + return false; + } + } - if (wrapper.getLore() != null) { - List loreX = metaToCheck.getLore(); - if (loreX == null) return false; + if (wrapper.getLore() != null) { + List loreX = metaToCheck.getLore(); + if (loreX == null) return false; - String lore = StringUtils.color(holder.setPlaceholdersAndArguments(wrapper.getLore())); - String loreToCheck = loreX.stream().map(holder::setPlaceholdersAndArguments).map(StringUtils::color).collect(Collectors.joining("&&")); + String lore = StringUtils.color(holder.setPlaceholdersAndArguments(wrapper.getLore())); + String loreToCheck = loreX.stream().map(holder::setPlaceholdersAndArguments).map(StringUtils::color).collect(Collectors.joining("&&")); - if (wrapper.checkLoreContains() && wrapper.checkLoreIgnoreCase()) { - return org.apache.commons.lang3.StringUtils.containsIgnoreCase(loreToCheck, lore); - } - else if (wrapper.checkLoreContains()) { - return loreToCheck.contains(lore); - } - else if (wrapper.checkLoreIgnoreCase()) { - return loreToCheck.equalsIgnoreCase(lore); + if (wrapper.checkLoreContains() && wrapper.checkLoreIgnoreCase()) { + return org.apache.commons.lang3.StringUtils.containsIgnoreCase(loreToCheck, lore); + } else if (wrapper.checkLoreContains()) { + return loreToCheck.contains(lore); + } else if (wrapper.checkLoreIgnoreCase()) { + return loreToCheck.equalsIgnoreCase(lore); + } else return loreToCheck.equals(lore); + } } - else return loreToCheck.equals(lore); - } - } - return true; - } - - private boolean isEmptyModelData(@NotNull final CustomModelDataComponent modelData) { - return modelData.getColors().isEmpty() && modelData.getFlags().isEmpty() && modelData.getFloats().isEmpty() && modelData.getStrings().isEmpty(); - } - - private boolean isEmptyModelData(@NotNull final com.extendedclip.deluxemenus.menu.options.CustomModelDataComponent modelData) { - return modelData.colors().isEmpty() && modelData.flags().isEmpty() && modelData.floats().isEmpty() && modelData.strings().isEmpty(); - } - - private boolean itemModelComponentContains(MenuHolder holder, @NotNull final CustomModelDataComponent modelData, @NotNull final com.extendedclip.deluxemenus.menu.options.CustomModelDataComponent wrapper) { - if (!wrapper.colors().isEmpty()) { - final List colors = wrapper.colors() - .stream() - .map(holder::setPlaceholdersAndArguments) - .map(StringUtils::parseRGBColor) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - - for (Color color : colors) { - if (!modelData.getColors().contains(color)) return false; - } + return true; } - if (!wrapper.flags().isEmpty()) { - final List flags = wrapper.flags() - .stream() - .map(holder::setPlaceholdersAndArguments) - .map(Boolean::parseBoolean) - .collect(Collectors.toList()); + private boolean isEmptyModelData(@NotNull final CustomModelDataComponent modelData) { + return modelData.getColors().isEmpty() && modelData.getFlags().isEmpty() && modelData.getFloats().isEmpty() && modelData.getStrings().isEmpty(); + } - for (Boolean flag : flags) { - if (!modelData.getFlags().contains(flag)) return false; - } + private boolean isEmptyModelData(@NotNull final com.extendedclip.deluxemenus.menu.options.CustomModelDataComponent modelData) { + return modelData.colors().isEmpty() && modelData.flags().isEmpty() && modelData.floats().isEmpty() && modelData.strings().isEmpty(); } - if (!wrapper.floats().isEmpty()) { - final List floats = wrapper.floats() - .stream() - .map(holder::setPlaceholdersAndArguments) - .map(Float::parseFloat) - .collect(Collectors.toList()); + private boolean itemModelComponentContains(MenuHolder holder, @NotNull final CustomModelDataComponent modelData, @NotNull final com.extendedclip.deluxemenus.menu.options.CustomModelDataComponent wrapper) { + if (!wrapper.colors().isEmpty()) { + final List colors = wrapper.colors() + .stream() + .map(holder::setPlaceholdersAndArguments) + .map(StringUtils::parseRGBColor) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + for (Color color : colors) { + if (!modelData.getColors().contains(color)) { + return false; + } + } + } - for (Float floatValue : floats) { - if (!modelData.getFloats().contains(floatValue)) return false; - } - } + if (!wrapper.flags().isEmpty()) { + final List flags = wrapper.flags() + .stream() + .map(holder::setPlaceholdersAndArguments) + .map(Boolean::parseBoolean) + .collect(Collectors.toList()); - if (!wrapper.strings().isEmpty()) { - final List strings = wrapper.strings() - .stream() - .map(holder::setPlaceholdersAndArguments) - .collect(Collectors.toList()); + for (Boolean flag : flags) { + if (!modelData.getFlags().contains(flag)) { + return false; + } + } + } - for (String string : strings) { - if (!modelData.getStrings().contains(string)) return false; - } - } + if (!wrapper.floats().isEmpty()) { + final List floats = wrapper.floats() + .stream() + .map(holder::setPlaceholdersAndArguments) + .map(Float::parseFloat) + .collect(Collectors.toList()); + + for (Float floatValue : floats) { + if (!modelData.getFloats().contains(floatValue)) { + return false; + } + } + } - return true; - } + if (!wrapper.strings().isEmpty()) { + final List strings = wrapper.strings() + .stream() + .map(holder::setPlaceholdersAndArguments) + .collect(Collectors.toList()); + + for (String string : strings) { + if (!modelData.getStrings().contains(string)) { + return false; + } + } + } + + return true; + } } diff --git a/src/main/java/com/extendedclip/deluxemenus/requirement/wrappers/ItemWrapper.java b/src/main/java/com/extendedclip/deluxemenus/requirement/wrappers/ItemWrapper.java index 32dd5ff5..760a44c9 100644 --- a/src/main/java/com/extendedclip/deluxemenus/requirement/wrappers/ItemWrapper.java +++ b/src/main/java/com/extendedclip/deluxemenus/requirement/wrappers/ItemWrapper.java @@ -1,6 +1,7 @@ package com.extendedclip.deluxemenus.requirement.wrappers; import com.extendedclip.deluxemenus.menu.options.CustomModelDataComponent; +import org.jetbrains.annotations.NotNull; import java.util.List; @@ -13,7 +14,7 @@ public class ItemWrapper { private short data = 0; private boolean hasData = false; - private CustomModelDataComponent customDataComponent = null; + private CustomModelDataComponent customDataComponent = CustomModelDataComponent.builder(); private int customData = 0; private int amount = 1; @@ -83,11 +84,11 @@ public void setCustomData(int customData) { this.customData = customData; } - public CustomModelDataComponent getCustomModelDataComponent() { + public @NotNull CustomModelDataComponent getCustomModelDataComponent() { return this.customDataComponent; } - public void setCustomModelDataComponent(CustomModelDataComponent customDataComponent) { + public void setCustomModelDataComponent(@NotNull final CustomModelDataComponent customDataComponent) { this.customDataComponent = customDataComponent; } From 0bbe0effa75a14d848a16c3b5729e5719e9712a4 Mon Sep 17 00:00:00 2001 From: BlitzOffline <52609756+BlitzOffline@users.noreply.github.com> Date: Fri, 30 May 2025 02:36:13 +0300 Subject: [PATCH 4/5] fix has item with custom model data component --- .../deluxemenus/config/DeluxeMenusConfig.java | 113 ++++++++++++++++-- 1 file changed, 100 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java b/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java index e935baaa..5232c535 100644 --- a/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java +++ b/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java @@ -156,7 +156,13 @@ public boolean loadDefConfig() { FileConfiguration c = plugin.getConfig(); - c.options().header("DeluxeMenus " + plugin.getDescription().getVersion() + " main configuration file" + "\n" + "\nA full wiki on how to use this plugin can be found at:" + "\nhttps://wiki.helpch.at/helpchat-plugins/deluxemenus" + "\n"); + c.options().header( + "DeluxeMenus " + plugin.getDescription().getVersion() + " main configuration file" + + "\n" + + "\nA full wiki on how to use this plugin can be found at:" + + "\nhttps://wiki.helpch.at/helpchat-plugins/deluxemenus" + + "\n" + ); c.addDefault("debug", "LOW"); c.addDefault("check_updates", true); c.addDefault("use_admin_commands_in_menus_list", false); @@ -592,7 +598,40 @@ private Map> loadMenuItems(FileConfiguration checkForDeprecatedItemOptions(c.getConfigurationSection(currentPath), name); - MenuItemOptions.MenuItemOptionsBuilder builder = MenuItemOptions.builder().material(material).baseColor(Optional.ofNullable(c.getString(currentPath + "base_color")).map(String::toUpperCase).map(DyeColor::valueOf).orElse(null)).slot(c.getInt(currentPath + "slot", 0)).amount(c.getInt(currentPath + "amount", -1)).dynamicAmount(c.getString(currentPath + "dynamic_amount", null)).customModelData(c.getString(currentPath + "model_data", null)).lightLevel(c.getString(currentPath + "light_level", null)).displayName(c.getString(currentPath + "display_name")).lore(c.getStringList(currentPath + "lore")).hasLore(c.contains(currentPath + "lore")).rgb(c.getString(currentPath + "rgb", null)).unbreakable(c.getBoolean(currentPath + "unbreakable", false)).updatePlaceholders(c.getBoolean(currentPath + "update", false)).hideAttributes(c.getBoolean(currentPath + "hide_attributes", false)).hideUnbreakable(c.getBoolean(currentPath + "hide_unbreakable", false)).hideEnchants(c.getBoolean(currentPath + "hide_enchantments", false)).nbtString(c.getString(currentPath + "nbt_string", null)).nbtByte(c.getString(currentPath + "nbt_byte", null)).nbtShort(c.getString(currentPath + "nbt_short", null)).nbtInt(c.getString(currentPath + "nbt_int", null)).nbtStrings(c.getStringList(currentPath + "nbt_strings")).nbtBytes(c.getStringList(currentPath + "nbt_bytes")).nbtShorts(c.getStringList(currentPath + "nbt_shorts")).nbtInts(c.getStringList(currentPath + "nbt_ints")).priority(c.getInt(currentPath + "priority", 1)).hideTooltip(c.getString(currentPath + "hide_tooltip", null)).enchantmentGlintOverride(c.getString(currentPath + "enchantment_glint_override", null)).rarity(c.getString(currentPath + "rarity", null)).tooltipStyle(c.getString(currentPath + "tooltip_style", null)).itemModel(c.getString(currentPath + "item_model", null)); + MenuItemOptions.MenuItemOptionsBuilder builder = MenuItemOptions.builder() + .material(material) + .baseColor(Optional.ofNullable(c.getString(currentPath + "base_color")) + .map(String::toUpperCase) + .map(DyeColor::valueOf) + .orElse(null)) + .slot(c.getInt(currentPath + "slot", 0)) + .amount(c.getInt(currentPath + "amount", -1)) + .dynamicAmount(c.getString(currentPath + "dynamic_amount", null)) + .customModelData(c.getString(currentPath + "model_data", null)) + .lightLevel(c.getString(currentPath + "light_level", null)) + .displayName(c.getString(currentPath + "display_name")) + .lore(c.getStringList(currentPath + "lore")) + .hasLore(c.contains(currentPath + "lore")) + .rgb(c.getString(currentPath + "rgb", null)) + .unbreakable(c.getBoolean(currentPath + "unbreakable", false)) + .updatePlaceholders(c.getBoolean(currentPath + "update", false)) + .hideAttributes(c.getBoolean(currentPath + "hide_attributes", false)) + .hideUnbreakable(c.getBoolean(currentPath + "hide_unbreakable", false)) + .hideEnchants(c.getBoolean(currentPath + "hide_enchantments", false)) + .nbtString(c.getString(currentPath + "nbt_string", null)) + .nbtByte(c.getString(currentPath + "nbt_byte", null)) + .nbtShort(c.getString(currentPath + "nbt_short", null)) + .nbtInt(c.getString(currentPath + "nbt_int", null)) + .nbtStrings(c.getStringList(currentPath + "nbt_strings")) + .nbtBytes(c.getStringList(currentPath + "nbt_bytes")) + .nbtShorts(c.getStringList(currentPath + "nbt_shorts")) + .nbtInts(c.getStringList(currentPath + "nbt_ints")) + .priority(c.getInt(currentPath + "priority", 1)) + .hideTooltip(c.getString(currentPath + "hide_tooltip", null)) + .enchantmentGlintOverride(c.getString(currentPath + "enchantment_glint_override", null)) + .rarity(c.getString(currentPath + "rarity", null)) + .tooltipStyle(c.getString(currentPath + "tooltip_style", null)) + .itemModel(c.getString(currentPath + "item_model", null)); if (c.contains(currentPath + "model_data_component") && c.isConfigurationSection(currentPath + "model_data_component")) { final ConfigurationSection modelDataComponent = c.getConfigurationSection(currentPath + "model_data_component"); @@ -835,7 +874,11 @@ private RequirementList getRequirements(FileConfiguration c, String path) { if (c.contains(rPath + ".material")) { String materialName = c.getString(rPath + ".material"); try { - if (!containsPlaceholders(materialName) && plugin.getItemHooks().values().stream().filter(x -> materialName.toLowerCase().startsWith(x.getPrefix())).findFirst().orElse(null) == null) + if (!containsPlaceholders(materialName) && plugin.getItemHooks().values() + .stream() + .filter(x -> materialName.toLowerCase().startsWith(x.getPrefix())) + .findFirst() + .orElse(null) == null) Material.valueOf(materialName.toUpperCase()); } catch (Exception ex) { plugin.debug(DebugLevel.HIGHEST, Level.WARNING, "has item requirement at path: " + rPath + " does not specify a valid Material name!"); @@ -926,20 +969,36 @@ private RequirementList getRequirements(FileConfiguration c, String path) { invert = type == RequirementType.DOES_NOT_HAVE_PERMISSIONS; int minimum = -1; if (c.contains(rPath + ".minimum") && (minimum = c.getInt(rPath + ".minimum")) < 1) { - plugin.debug(DebugLevel.HIGHEST, Level.WARNING, "Has Permissions requirement at path: " + rPath + " has a minimum lower than 1. All permissions will be checked"); + plugin.debug( + DebugLevel.HIGHEST, + Level.WARNING, + "Has Permissions requirement at path: " + rPath + " has a minimum lower than 1. All permissions will be checked" + ); minimum = -1; } List permissions = c.getStringList(rPath + ".permissions"); if (permissions.isEmpty()) { - plugin.debug(DebugLevel.HIGHEST, Level.WARNING, "Has Permissions requirement at path: " + rPath + " has no permissions to check. Ignoring..."); + plugin.debug( + DebugLevel.HIGHEST, + Level.WARNING, + "Has Permissions requirement at path: " + rPath + " has no permissions to check. Ignoring..." + ); break; } else if (minimum > permissions.size()) { - plugin.debug(DebugLevel.HIGHEST, Level.WARNING, "Has Permissions requirement at path: " + rPath + " has a minimum higher than the amount of permissions. Using " + permissions.size() + " instead"); + plugin.debug( + DebugLevel.HIGHEST, + Level.WARNING, + "Has Permissions requirement at path: " + rPath + " has a minimum higher than the amount of permissions. Using " + permissions.size() + " instead" + ); minimum = permissions.size(); } req = new HasPermissionsRequirement(permissions, minimum, invert); } else { - plugin.debug(DebugLevel.HIGHEST, Level.WARNING, "Has Permissions requirement at path: " + rPath + " does not contain permissions: entry"); + plugin.debug( + DebugLevel.HIGHEST, + Level.WARNING, + "Has Permissions requirement at path: " + rPath + " does not contain permissions: entry" + ); } break; case JAVASCRIPT: @@ -1214,7 +1273,13 @@ public File getMenuDirector() { return menuDirectory; } - public void addEnchantmentsOptionToBuilder(final FileConfiguration c, final String currentPath, final String itemKey, final String menuName, final MenuItemOptions.MenuItemOptionsBuilder builder) { + public void addEnchantmentsOptionToBuilder( + final FileConfiguration c, + final String currentPath, + final String itemKey, + final String menuName, + final MenuItemOptions.MenuItemOptionsBuilder builder + ) { if (!c.contains(currentPath + "enchantments")) { return; } @@ -1224,32 +1289,54 @@ public void addEnchantmentsOptionToBuilder(final FileConfiguration c, final Stri for (final String configEnchantment : configEnchantments) { if (configEnchantment == null || !configEnchantment.contains(";")) { - plugin.debug(DebugLevel.HIGHEST, Level.WARNING, "Enchantment format '" + configEnchantment + "' is incorrect for item " + itemKey + " in GUI " + menuName + "!", "Correct format: - ';"); + plugin.debug( + DebugLevel.HIGHEST, + Level.WARNING, + "Enchantment format '" + configEnchantment + "' is incorrect for item " + itemKey + " in GUI " + menuName + "!", "Correct format: - ';" + ); continue; } String[] parts = configEnchantment.split(";", 2); if (parts.length != 2 || parts[0] == null || parts[1] == null) { - plugin.debug(DebugLevel.HIGHEST, Level.WARNING, "Enchantment format '" + configEnchantment + "' is incorrect for item " + itemKey + " in GUI " + menuName + "!", "Correct format: - ';"); + plugin.debug( + DebugLevel.HIGHEST, + Level.WARNING, + "Enchantment format '" + configEnchantment + "' is incorrect for item " + itemKey + " in GUI " + menuName + "!", "Correct format: - ';" + ); continue; } final Enchantment enchantment = Enchantment.getByName(parts[0].strip().toUpperCase()); if (enchantment == null) { - plugin.debug(DebugLevel.HIGHEST, Level.WARNING, "Enchantment '" + parts[0].strip() + "' for item " + itemKey + " in menu " + menuName + " is not a valid enchantment name!"); + plugin.debug( + DebugLevel.HIGHEST, + Level.WARNING, + "Enchantment '" + parts[0].strip() + "' for item " + itemKey + " in menu " + menuName + " is not a valid enchantment name!" + ); } Integer level = Ints.tryParse(parts[1].strip()); if (level == null) { level = 1; - plugin.debug(DebugLevel.HIGHEST, Level.WARNING, "Enchantment level '" + parts[1].strip() + "' is incorrect for item " + itemKey + " in menu " + menuName + "!"); + plugin.debug( + DebugLevel.HIGHEST, + Level.WARNING, + "Enchantment level '" + parts[1].strip() + "' is incorrect for item " + itemKey + " in menu " + menuName + "!" + ); } parsedEnchantments.put(enchantment, level); } builder.enchantments(parsedEnchantments); } - public void addDamageOptionToBuilder(final FileConfiguration c, final String currentPath, final String itemKey, final String menuName, final MenuItemOptions.MenuItemOptionsBuilder builder) { + public void addDamageOptionToBuilder( + final FileConfiguration c, + final String currentPath, + final String itemKey, + final String menuName, + final MenuItemOptions.MenuItemOptionsBuilder builder + ) { boolean damageOptionIsPresent = false; String damageValue = null; From 7d1fd1f36a411d1dfde23121d11e2364d2aee829 Mon Sep 17 00:00:00 2001 From: BlitzOffline <52609756+BlitzOffline@users.noreply.github.com> Date: Fri, 30 May 2025 02:47:09 +0300 Subject: [PATCH 5/5] fix has item with custom model data component --- src/main/java/com/extendedclip/deluxemenus/DeluxeMenus.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/extendedclip/deluxemenus/DeluxeMenus.java b/src/main/java/com/extendedclip/deluxemenus/DeluxeMenus.java index 642076f8..f812f937 100644 --- a/src/main/java/com/extendedclip/deluxemenus/DeluxeMenus.java +++ b/src/main/java/com/extendedclip/deluxemenus/DeluxeMenus.java @@ -66,7 +66,11 @@ public void onLoad() { return; } - this.debug(DebugLevel.HIGHEST, Level.WARNING, "Could not setup a NMS hook for your server version!"); + this.debug( + DebugLevel.HIGHEST, + Level.WARNING, + "Could not setup a NMS hook for your server version! The following Item options will not work: nbt_int, nbt_ints, nbt_string and nbt_strings." + ); } @Override