From 1cce32d7792c69e31bacf2f1a21b8fe576920d4e Mon Sep 17 00:00:00 2001 From: 1robie Date: Thu, 4 Dec 2025 13:31:24 +0100 Subject: [PATCH 01/14] feat: add default pattern values loading in ZButtonLoader --- .../fr/maxlego08/menu/loader/ZButtonLoader.java | 13 +++++++++++++ .../java/fr/maxlego08/menu/zcore/utils/ZUtils.java | 3 ++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/fr/maxlego08/menu/loader/ZButtonLoader.java b/src/main/java/fr/maxlego08/menu/loader/ZButtonLoader.java index 3f1237ce..3e769d4f 100644 --- a/src/main/java/fr/maxlego08/menu/loader/ZButtonLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/ZButtonLoader.java @@ -80,6 +80,7 @@ public Button load(YamlConfiguration configuration, String path, Object... objec if (!patternFile.exists()) { throw new InventoryButtonException("Impossible to load the pattern " + fileName + ", file doesnt exist"); } + loadDefaultPatternValues(patternFile, mapPlaceholders); mapPlaceholders.putAll(this.plugin.getGlobalPlaceholders()); YamlConfiguration patternConfiguration = loadAndReplaceConfiguration(patternFile, mapPlaceholders); @@ -389,6 +390,18 @@ public Button load(YamlConfiguration configuration, String path, Object... objec return button; } + private void loadDefaultPatternValues(File patternFile, Map mapPlaceholders) { + YamlConfiguration patternConfig = YamlConfiguration.loadConfiguration(patternFile); + if (patternConfig.isConfigurationSection("default-values.")) { + Map defaultValues = patternConfig.getConfigurationSection("default-values.").getValues(false); + for (String key : defaultValues.keySet()) { + if (!mapPlaceholders.containsKey(key)) { + mapPlaceholders.put(key, defaultValues.get(key)); + } + } + } + } + /** * Allows to load clicks requirements * diff --git a/src/main/java/fr/maxlego08/menu/zcore/utils/ZUtils.java b/src/main/java/fr/maxlego08/menu/zcore/utils/ZUtils.java index 46f346aa..ee88219a 100644 --- a/src/main/java/fr/maxlego08/menu/zcore/utils/ZUtils.java +++ b/src/main/java/fr/maxlego08/menu/zcore/utils/ZUtils.java @@ -40,7 +40,8 @@ import org.bukkit.profile.PlayerProfile; import org.bukkit.profile.PlayerTextures; -import java.io.*; +import java.io.File; +import java.io.IOException; import java.lang.reflect.Field; import java.net.MalformedURLException; import java.net.URISyntaxException; From 62ccc4c35ac6f21420278bf62a3b1a944e157bcd Mon Sep 17 00:00:00 2001 From: 1robie Date: Tue, 9 Dec 2025 21:14:19 +0100 Subject: [PATCH 02/14] fix: reload edit cached item --- .../java/fr/maxlego08/menu/ZItemManager.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/java/fr/maxlego08/menu/ZItemManager.java b/src/main/java/fr/maxlego08/menu/ZItemManager.java index 2ef3e0b5..68aacb06 100644 --- a/src/main/java/fr/maxlego08/menu/ZItemManager.java +++ b/src/main/java/fr/maxlego08/menu/ZItemManager.java @@ -71,7 +71,7 @@ public void loadCustomItems() { try (Stream stream = Files.walk(Paths.get(itemsFolder.getPath()))) { stream.skip(1).map(Path::toFile).filter(File::isFile).filter(e -> e.getName().endsWith(".yml")).forEach(this::loadCustomItem); ZMenuItemsLoad event = new ZMenuItemsLoad(new HashSet<>(customItems.keySet()), !isFirstLoad); - menuPlugin.getServer().getPluginManager().callEvent(event); + this.menuPlugin.getServer().getPluginManager().callEvent(event); if (isFirstLoad) { isFirstLoad = false; } @@ -87,7 +87,7 @@ public void loadCustomItem(File file) { YamlConfiguration config = YamlConfiguration.loadConfiguration(file); for (String itemId : config.getKeys(false)) { String path = itemId + "."; - MenuItemStack menuItemStack = menuPlugin.loadItemStack(config, path, file); + MenuItemStack menuItemStack = this.menuPlugin.loadItemStack(config, path, file); if (menuItemStack != null) { Set mechanicIds = new HashSet<>(); @@ -95,7 +95,7 @@ public void loadCustomItem(File file) { if (mechanicSection != null) { path += "mechanics."; for (String mechanicId : mechanicSection.getKeys(false)) { - MechanicFactory factory = mechanicFactories.get(mechanicId); + MechanicFactory factory = this.mechanicFactories.get(mechanicId); if (factory != null) { factory.parse(this.menuPlugin, itemId, mechanicSection.getConfigurationSection(mechanicId), config, file, path + mechanicId + "."); mechanicIds.add(mechanicId); @@ -105,7 +105,7 @@ public void loadCustomItem(File file) { } } - customItems.put(itemId, new CustomItemData(menuItemStack, mechanicIds)); + this.customItems.put(itemId, new CustomItemData(menuItemStack, mechanicIds)); } else { if (Config.enableDebug){ Logger.info("Impossible to load item " + itemId + " from file " + file.getName()); @@ -116,7 +116,7 @@ public void loadCustomItem(File file) { @Override public void reloadCustomItems() { - customItems.clear(); + this.customItems.clear(); for (MechanicFactory factory : mechanicFactories.values()) { factory.clearMechanics(); } @@ -125,7 +125,7 @@ public void reloadCustomItems() { @Override public boolean isCustomItem(String itemId) { - return customItems.containsKey(itemId); + return this.customItems.containsKey(itemId); } @Override @@ -182,9 +182,9 @@ public void giveItem(Player player, String itemId) { return; } - CustomItemData itemData = customItems.get(itemId); + CustomItemData itemData = this.customItems.get(itemId); MenuItemStack menuItemStack = itemData.menuItemStack(); - ItemStack itemStack = menuItemStack.build(player); + ItemStack itemStack = menuItemStack.build(player).clone(); ItemMeta itemMeta = itemStack.getItemMeta(); if (itemMeta != null) { PersistentDataContainer persistentDataContainer = itemMeta.getPersistentDataContainer(); @@ -241,8 +241,7 @@ public void executeCheckInventoryItems(Player player) { Player owner = this.menuPlugin.getServer().getPlayer(UUID.fromString(ownerUuid)); if (owner == null) continue; - ItemStack built = menuItemStack.build(owner); - if (built == null) continue; + ItemStack built = menuItemStack.build(owner).clone(); built.setAmount(itemStack.getAmount()); From e0a1dee1b3c28882083df7d6ec8d77bc5aa85fc5 Mon Sep 17 00:00:00 2001 From: 1robie Date: Wed, 7 Jan 2026 10:52:40 +0100 Subject: [PATCH 03/14] feat: add saveOwnerInPDC flag to CustomItemData and update item handling logic --- .../java/fr/maxlego08/menu/ZItemManager.java | 32 +++++++++++++------ .../maxlego08/menu/item/CustomItemData.java | 2 +- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/main/java/fr/maxlego08/menu/ZItemManager.java b/src/main/java/fr/maxlego08/menu/ZItemManager.java index 68aacb06..99cf4799 100644 --- a/src/main/java/fr/maxlego08/menu/ZItemManager.java +++ b/src/main/java/fr/maxlego08/menu/ZItemManager.java @@ -104,8 +104,13 @@ public void loadCustomItem(File file) { } } } + ConfigurationSection itemSection = config.getConfigurationSection(itemId); + boolean saveOwnerInPDC = true; + if (itemSection != null) { + saveOwnerInPDC = itemSection.getBoolean("save-owner-in-pdc", true); + } - this.customItems.put(itemId, new CustomItemData(menuItemStack, mechanicIds)); + this.customItems.put(itemId, new CustomItemData(menuItemStack, mechanicIds, saveOwnerInPDC)); } else { if (Config.enableDebug){ Logger.info("Impossible to load item " + itemId + " from file " + file.getName()); @@ -161,7 +166,7 @@ public void registerListeners(Plugin plugin, String mechanicId, MechanicListener @Override public void unloadListeners() { - for (Listener listener: mechanicListeners.values()) { + for (Listener listener: this.mechanicListeners.values()) { HandlerList.unregisterAll(listener); } } @@ -172,7 +177,7 @@ public void registerMechanicFactory(MechanicFactory factory) { Logger.info("MechanicFactory " + factory.getMechanicId() + " is already registered.", Logger.LogType.WARNING); return; } - mechanicFactories.put(factory.getMechanicId(), factory); + this.mechanicFactories.put(factory.getMechanicId(), factory); } @Override @@ -189,13 +194,15 @@ public void giveItem(Player player, String itemId) { if (itemMeta != null) { PersistentDataContainer persistentDataContainer = itemMeta.getPersistentDataContainer(); persistentDataContainer.set(itemIdKey, PersistentDataType.STRING, itemId); - persistentDataContainer.set(ownerKey, PersistentDataType.STRING, player.getUniqueId().toString()); + if (itemData.saveOwnerInPDC()) { + persistentDataContainer.set(ownerKey, PersistentDataType.STRING, player.getUniqueId().toString()); + } itemStack.setItemMeta(itemMeta); } boolean shouldCancel = false; for (String mechanicId : itemData.mechanicIds()) { - MechanicListener mechanicListener = mechanicListeners.get(mechanicId); + MechanicListener mechanicListener = this.mechanicListeners.get(mechanicId); if (mechanicListener != null) { boolean cancel = mechanicListener.onItemGive(player, itemStack, itemId); if (cancel) shouldCancel = true; @@ -237,19 +244,24 @@ public void executeCheckInventoryItems(Player player) { MenuItemStack menuItemStack = itemData.menuItemStack(); String ownerUuid = meta.getPersistentDataContainer().get(ownerKey, PersistentDataType.STRING); - if (ownerUuid == null) continue; - Player owner = this.menuPlugin.getServer().getPlayer(UUID.fromString(ownerUuid)); + Player owner; + if (itemData.saveOwnerInPDC()){ + if (ownerUuid == null) continue; + owner = this.menuPlugin.getServer().getPlayer(UUID.fromString(ownerUuid)); + } else { + owner = player; + } if (owner == null) continue; ItemStack built = menuItemStack.build(owner).clone(); - built.setAmount(itemStack.getAmount()); ItemMeta builtMeta = built.getItemMeta(); if (builtMeta == null) continue; builtMeta.getPersistentDataContainer().set(itemIdKey, PersistentDataType.STRING, itemId); - builtMeta.getPersistentDataContainer().set(ownerKey, PersistentDataType.STRING, owner.getUniqueId().toString()); - + if (itemData.saveOwnerInPDC()) { + builtMeta.getPersistentDataContainer().set(ownerKey, PersistentDataType.STRING, owner.getUniqueId().toString()); + } built.setItemMeta(builtMeta); if (!built.isSimilar(itemStack)) { diff --git a/src/main/java/fr/maxlego08/menu/item/CustomItemData.java b/src/main/java/fr/maxlego08/menu/item/CustomItemData.java index f280d2a4..0d717250 100644 --- a/src/main/java/fr/maxlego08/menu/item/CustomItemData.java +++ b/src/main/java/fr/maxlego08/menu/item/CustomItemData.java @@ -11,7 +11,7 @@ * @param menuItemStack the ItemStack configuration for this custom item * @param mechanicIds set of mechanic IDs that are implemented for this item */ -public record CustomItemData(MenuItemStack menuItemStack, Set mechanicIds) { +public record CustomItemData(MenuItemStack menuItemStack, Set mechanicIds, boolean saveOwnerInPDC) { /** * Check if this item has a specific mechanic implemented. From c0a60bcb72a0b1322651661f248589402818b4ae Mon Sep 17 00:00:00 2001 From: 1robie Date: Wed, 7 Jan 2026 19:52:03 +0100 Subject: [PATCH 04/14] feat: add resin trim material to TrimHelper --- API/src/main/java/fr/maxlego08/menu/api/utils/TrimHelper.java | 1 + 1 file changed, 1 insertion(+) diff --git a/API/src/main/java/fr/maxlego08/menu/api/utils/TrimHelper.java b/API/src/main/java/fr/maxlego08/menu/api/utils/TrimHelper.java index 06b625d5..fe1b5c18 100644 --- a/API/src/main/java/fr/maxlego08/menu/api/utils/TrimHelper.java +++ b/API/src/main/java/fr/maxlego08/menu/api/utils/TrimHelper.java @@ -23,6 +23,7 @@ public TrimHelper() { trimMaterials.put("diamond", TrimMaterial.DIAMOND); trimMaterials.put("lapis", TrimMaterial.LAPIS); trimMaterials.put("amethyst", TrimMaterial.AMETHYST); + trimMaterials.put("resin", TrimMaterial.RESIN); trimPatterns.put("sentry", TrimPattern.SENTRY); trimPatterns.put("dune", TrimPattern.DUNE); From f23c1d658c720aa3ab7c35f39cb1033ea568f696 Mon Sep 17 00:00:00 2001 From: 1robie Date: Wed, 7 Jan 2026 20:34:02 +0100 Subject: [PATCH 05/14] feat: implement action patterns and enhance action loading logic --- .../fr/maxlego08/menu/api/ButtonManager.java | 6 ++ .../menu/api/loader/PermissibleLoader.java | 20 ++++- .../menu/api/pattern/ActionPattern.java | 12 +++ .../menu/api/pattern/PatternManager.java | 16 ++++ .../menu/api/requirement/Action.java | 13 +++ .../headdatabase/HeadDatabaseListener.java | 1 + .../maxlego08/menu/hooks/ComponentMeta.java | 3 +- .../fr/maxlego08/menu/ZButtonManager.java | 32 +++++++- .../fr/maxlego08/menu/ZInventoryManager.java | 1 + .../commands/reload/CommandMenuReload.java | 5 +- .../reload/CommandMenuReloadConfig.java | 5 +- .../menu/loader/ActionPatternLoader.java | 34 ++++++++ .../menu/loader/InventoryLoader.java | 20 ++++- .../menu/loader/RequirementLoader.java | 11 ++- .../maxlego08/menu/loader/ZButtonLoader.java | 30 +++++-- .../menu/pattern/ZActionsPattern.java | 9 ++ .../menu/pattern/ZPatternManager.java | 82 ++++++++++++++++--- .../actions_patterns/default-actions.yml | 7 ++ .../resources/inventories/basic_inventory.yml | 7 ++ 19 files changed, 282 insertions(+), 32 deletions(-) create mode 100644 API/src/main/java/fr/maxlego08/menu/api/pattern/ActionPattern.java create mode 100644 src/main/java/fr/maxlego08/menu/loader/ActionPatternLoader.java create mode 100644 src/main/java/fr/maxlego08/menu/pattern/ZActionsPattern.java create mode 100644 src/main/resources/actions_patterns/default-actions.yml diff --git a/API/src/main/java/fr/maxlego08/menu/api/ButtonManager.java b/API/src/main/java/fr/maxlego08/menu/api/ButtonManager.java index 8e13e8fb..0d8fbf39 100644 --- a/API/src/main/java/fr/maxlego08/menu/api/ButtonManager.java +++ b/API/src/main/java/fr/maxlego08/menu/api/ButtonManager.java @@ -5,12 +5,14 @@ import fr.maxlego08.menu.api.loader.ActionLoader; import fr.maxlego08.menu.api.loader.ButtonLoader; import fr.maxlego08.menu.api.loader.PermissibleLoader; +import fr.maxlego08.menu.api.pattern.ActionPattern; import fr.maxlego08.menu.api.requirement.Action; import fr.maxlego08.menu.api.requirement.Permissible; import fr.maxlego08.menu.api.requirement.Requirement; import fr.maxlego08.menu.api.utils.Loader; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; import java.io.File; import java.util.Collection; @@ -142,6 +144,8 @@ public interface ButtonManager { */ List loadActions(List> elements, String path, File file); + List loadActions(List> elements, String path, File file, @NotNull List defaultActions, boolean useSuccess, boolean stopOnEmpty); + /** * Converts a list of map elements from a configuration file into a list of {@link Action} objects. * @@ -154,6 +158,8 @@ public interface ButtonManager { */ List loadActions(YamlConfiguration configuration, String path, File file); + List loadActions(YamlConfiguration configuration, String path, File file, @NotNull List defaultActions, boolean useSuccess, boolean stopOnEmpty); + List loadRequirements(YamlConfiguration configuration, String path, File file) throws InventoryException; Requirement loadRequirement(YamlConfiguration configuration, String path, File file) throws InventoryException; diff --git a/API/src/main/java/fr/maxlego08/menu/api/loader/PermissibleLoader.java b/API/src/main/java/fr/maxlego08/menu/api/loader/PermissibleLoader.java index 040211a5..9ff0f8db 100644 --- a/API/src/main/java/fr/maxlego08/menu/api/loader/PermissibleLoader.java +++ b/API/src/main/java/fr/maxlego08/menu/api/loader/PermissibleLoader.java @@ -1,9 +1,11 @@ package fr.maxlego08.menu.api.loader; import fr.maxlego08.menu.api.ButtonManager; +import fr.maxlego08.menu.api.pattern.ActionPattern; import fr.maxlego08.menu.api.requirement.Action; import fr.maxlego08.menu.api.requirement.Permissible; import fr.maxlego08.menu.api.utils.TypedMapAccessor; +import org.jetbrains.annotations.NotNull; import java.io.File; import java.util.ArrayList; @@ -53,6 +55,23 @@ protected List loadAction(ButtonManager buttonManager, TypedMapAccessor return buttonManager.loadActions((List>) accessor.getObject(key, new ArrayList>()), path, file); } + /** + * Load a list of Action from a configuration node with action patterns and success flag. + * + * @param buttonManager the button manager used to load the actions. + * @param accessor the typed map accessor to access the configuration. + * @param key the key of the list of actions. + * @param path the path of the file. + * @param file the file of the configuration. + * @param actionPatterns the list of action patterns to use. + * @param useSuccess whether to use success actions or not. + * @return a list of Action. + */ + @SuppressWarnings("unchecked") + protected List loadAction(ButtonManager buttonManager, TypedMapAccessor accessor, String key, String path, File file, @NotNull List actionPatterns, boolean useSuccess, boolean stopOnEmpty) { + return buttonManager.loadActions((List>) accessor.getObject(key, new ArrayList>()), path, file, actionPatterns, useSuccess, stopOnEmpty); + + } /** * Load a list of Permissible from a configuration node. * @@ -67,5 +86,4 @@ protected List loadAction(ButtonManager buttonManager, TypedMapAccessor protected List loadPermissible(ButtonManager buttonManager, TypedMapAccessor accessor, String key, String path, File file) { return buttonManager.loadPermissible((List>) accessor.getObject(key, new ArrayList>()), path, file); } - } diff --git a/API/src/main/java/fr/maxlego08/menu/api/pattern/ActionPattern.java b/API/src/main/java/fr/maxlego08/menu/api/pattern/ActionPattern.java new file mode 100644 index 00000000..3e5c4095 --- /dev/null +++ b/API/src/main/java/fr/maxlego08/menu/api/pattern/ActionPattern.java @@ -0,0 +1,12 @@ +package fr.maxlego08.menu.api.pattern; + +import fr.maxlego08.menu.api.requirement.Action; + +import java.util.List; + +public interface ActionPattern { + String name(); + + List actions(); + List denyActions(); +} diff --git a/API/src/main/java/fr/maxlego08/menu/api/pattern/PatternManager.java b/API/src/main/java/fr/maxlego08/menu/api/pattern/PatternManager.java index 8ffa3c94..5dbf523f 100644 --- a/API/src/main/java/fr/maxlego08/menu/api/pattern/PatternManager.java +++ b/API/src/main/java/fr/maxlego08/menu/api/pattern/PatternManager.java @@ -1,6 +1,7 @@ package fr.maxlego08.menu.api.pattern; import fr.maxlego08.menu.api.exceptions.InventoryException; +import org.jetbrains.annotations.NotNull; import java.io.File; import java.util.Collection; @@ -18,6 +19,8 @@ public interface PatternManager { */ Collection getPatterns(); + Collection getActionPatterns(); + /** * Retrieves a pattern by its name. * @@ -26,6 +29,8 @@ public interface PatternManager { */ Optional getPattern(String name); + Optional getActionPattern(String name); + /** * Registers a new pattern. * @@ -33,6 +38,8 @@ public interface PatternManager { */ void registerPattern(Pattern pattern); + void registerActionPattern(@NotNull ActionPattern pattern); + /** * Unregisters a pattern. * @@ -40,6 +47,8 @@ public interface PatternManager { */ void unregisterPattern(Pattern pattern); + void unregisterActionPattern(ActionPattern pattern); + /** * Loads a pattern from a file. * @@ -49,9 +58,16 @@ public interface PatternManager { */ Pattern loadPattern(File file) throws InventoryException; + ActionPattern loadActionPattern(File file) throws InventoryException; + /** * Loads all registered patterns. */ void loadPatterns(); + /** + * Loads all registered action patterns. + */ + void loadActionsPatterns(); + } diff --git a/API/src/main/java/fr/maxlego08/menu/api/requirement/Action.java b/API/src/main/java/fr/maxlego08/menu/api/requirement/Action.java index 158b7e09..3dbb0a60 100644 --- a/API/src/main/java/fr/maxlego08/menu/api/requirement/Action.java +++ b/API/src/main/java/fr/maxlego08/menu/api/requirement/Action.java @@ -22,6 +22,11 @@ public abstract class Action { private int delay; private float chance; + /** + * The type of the action. + */ + private String type; + /** * Executes the action for the specified player. * @@ -111,4 +116,12 @@ protected List parseAndFlattenCommands(List liste, Player player } return commands; } + + public void setType(String type) { + this.type = type; + } + + public String getType() { + return this.type; + } } diff --git a/Hooks/HeadDataBase/src/main/java/fr/maxlego08/menu/hooks/headdatabase/HeadDatabaseListener.java b/Hooks/HeadDataBase/src/main/java/fr/maxlego08/menu/hooks/headdatabase/HeadDatabaseListener.java index f8151e0c..6364811e 100644 --- a/Hooks/HeadDataBase/src/main/java/fr/maxlego08/menu/hooks/headdatabase/HeadDatabaseListener.java +++ b/Hooks/HeadDataBase/src/main/java/fr/maxlego08/menu/hooks/headdatabase/HeadDatabaseListener.java @@ -16,6 +16,7 @@ public HeadDatabaseListener(MenuPlugin plugin) { @EventHandler public void onRead(DatabaseLoadEvent event) { + this.plugin.getPatternManager().loadActionsPatterns(); this.plugin.getPatternManager().loadPatterns(); this.plugin.getInventoryManager().loadInventories(); } diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/hooks/ComponentMeta.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/hooks/ComponentMeta.java index c151874d..3c9ec2c9 100644 --- a/Hooks/Paper/src/main/java/fr/maxlego08/menu/hooks/ComponentMeta.java +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/hooks/ComponentMeta.java @@ -204,7 +204,8 @@ private String colorMiniMessage(String message) { // &#a1b2c3 → <#a1b2c3> newMessage = convertShorLegacyHex(newMessage); // #a1b2c3 → <#a1b2c3> - newMessage = newMessage.replaceAll("(?"); + newMessage = newMessage.replaceAll("(?"); + // &a → , §c → , etc. newMessage = replaceLegacyColors(newMessage); diff --git a/src/main/java/fr/maxlego08/menu/ZButtonManager.java b/src/main/java/fr/maxlego08/menu/ZButtonManager.java index 92e433f5..3b3c5410 100644 --- a/src/main/java/fr/maxlego08/menu/ZButtonManager.java +++ b/src/main/java/fr/maxlego08/menu/ZButtonManager.java @@ -9,6 +9,7 @@ import fr.maxlego08.menu.api.loader.ActionLoader; import fr.maxlego08.menu.api.loader.ButtonLoader; import fr.maxlego08.menu.api.loader.PermissibleLoader; +import fr.maxlego08.menu.api.pattern.ActionPattern; import fr.maxlego08.menu.api.requirement.Action; import fr.maxlego08.menu.api.requirement.Permissible; import fr.maxlego08.menu.api.requirement.Requirement; @@ -21,6 +22,7 @@ import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; import java.io.File; import java.util.*; @@ -152,7 +154,7 @@ public List loadPermissible(List> elements, Str return permissibles; } - @Override + @Override @SuppressWarnings("unchecked") public List loadPermissible(YamlConfiguration configuration, String path, File file) { List> elements = (List>) configuration.getList(path, new ArrayList<>()); return loadPermissible(elements, path, file); @@ -160,7 +162,13 @@ public List loadPermissible(YamlConfiguration configuration, String @Override public List loadActions(List> elements, String path, File file) { + return loadActions(elements, path, file, new ArrayList<>(), true, true); + } + + @Override + public List loadActions(List> elements, String path, File file, @NotNull List defaultActions, boolean useSuccess, boolean stopOnEmpty) { List actions = new ArrayList<>(); + Set seenTypes = new HashSet<>(); for (Map map : elements) { String type = (String) map.getOrDefault("type", null); if (type == null) { @@ -175,28 +183,46 @@ public List loadActions(List> elements, String path, if (action != null) { action.setDelay(accessor.getInt("delay", 0)); action.setChance(accessor.getFloat("chance", 100)); + action.setType(type); List> denyChanceAction = accessor.getMapList("deny-chance-actions"); if (!denyChanceAction.isEmpty()) { - List denyActions = loadActions(denyChanceAction, path + ".deny-chance-actions", file); + List denyActions = loadActions(denyChanceAction, path + ".deny-chance-actions", file, defaultActions, useSuccess, stopOnEmpty); if (!denyActions.isEmpty()) { action.setDenyChanceActions(denyActions); } } actions.add(action); + seenTypes.add(type); } } else { Logger.info("Error, an element is invalid in " + path + " with type " + type + ", he doesn't exist!", Logger.LogType.ERROR); } } + if (stopOnEmpty && actions.isEmpty()) { + return actions; + } + for (ActionPattern actionPattern : defaultActions) { + for (Action action : useSuccess ? actionPattern.actions() : actionPattern.denyActions()){ + if (!seenTypes.contains(action.getType())){ + actions.add(action); + } + } + } return actions; } - @Override + @Override @SuppressWarnings("unchecked") public List loadActions(YamlConfiguration configuration, String path, File file) { List> elements = (List>) configuration.getList(path, new ArrayList<>()); return loadActions(elements, path, file); } + @Override @SuppressWarnings("unchecked") + public List loadActions(YamlConfiguration configuration, String path, File file, @NotNull List defaultActions, boolean useSuccess, boolean stopOnEmpty) { + List> elements = (List>) configuration.getList(path, new ArrayList<>()); + return loadActions(elements, path, file, defaultActions, useSuccess, stopOnEmpty); + } + @Override public List loadRequirements(YamlConfiguration configuration, String path, File file) throws InventoryException { if (configuration == null) return List.of(); diff --git a/src/main/java/fr/maxlego08/menu/ZInventoryManager.java b/src/main/java/fr/maxlego08/menu/ZInventoryManager.java index 55d536bc..6459b6b3 100644 --- a/src/main/java/fr/maxlego08/menu/ZInventoryManager.java +++ b/src/main/java/fr/maxlego08/menu/ZInventoryManager.java @@ -96,6 +96,7 @@ public ZInventoryManager(ZMenuPlugin plugin) { @Override public void load() { this.loadButtons(); + this.plugin.getPatternManager().loadActionsPatterns(); this.plugin.getPatternManager().loadPatterns(); this.loadInventories(); DialogManager dialogManager = this.plugin.getDialogManager(); diff --git a/src/main/java/fr/maxlego08/menu/command/commands/reload/CommandMenuReload.java b/src/main/java/fr/maxlego08/menu/command/commands/reload/CommandMenuReload.java index bc77dd01..a3cd1d74 100644 --- a/src/main/java/fr/maxlego08/menu/command/commands/reload/CommandMenuReload.java +++ b/src/main/java/fr/maxlego08/menu/command/commands/reload/CommandMenuReload.java @@ -5,6 +5,7 @@ import fr.maxlego08.menu.api.ItemManager; import fr.maxlego08.menu.api.command.CommandManager; import fr.maxlego08.menu.api.configuration.Config; +import fr.maxlego08.menu.api.pattern.PatternManager; import fr.maxlego08.menu.api.utils.Message; import fr.maxlego08.menu.command.VCommand; import fr.maxlego08.menu.zcore.enums.Permission; @@ -41,7 +42,9 @@ protected CommandType perform(ZMenuPlugin plugin) { config.load(plugin.getConfig()); plugin.getVInventoryManager().close(); - plugin.getPatternManager().loadPatterns(); + PatternManager patternManager = plugin.getPatternManager(); + patternManager.loadActionsPatterns(); + patternManager.loadPatterns(); inventoryManager.deleteInventories(plugin); inventoryManager.loadInventories(); diff --git a/src/main/java/fr/maxlego08/menu/command/commands/reload/CommandMenuReloadConfig.java b/src/main/java/fr/maxlego08/menu/command/commands/reload/CommandMenuReloadConfig.java index 35c070cb..79441f46 100644 --- a/src/main/java/fr/maxlego08/menu/command/commands/reload/CommandMenuReloadConfig.java +++ b/src/main/java/fr/maxlego08/menu/command/commands/reload/CommandMenuReloadConfig.java @@ -2,6 +2,7 @@ import fr.maxlego08.menu.ZMenuPlugin; import fr.maxlego08.menu.api.configuration.Config; +import fr.maxlego08.menu.api.pattern.PatternManager; import fr.maxlego08.menu.api.utils.Message; import fr.maxlego08.menu.command.VCommand; import fr.maxlego08.menu.zcore.enums.Permission; @@ -24,7 +25,9 @@ protected CommandType perform(ZMenuPlugin plugin) { config.save(plugin.getConfig(),plugin.getConfigFile()); config.load(plugin.getConfig()); - plugin.getPatternManager().loadPatterns(); + PatternManager patternManager = plugin.getPatternManager(); + patternManager.loadActionsPatterns(); + patternManager.loadPatterns(); message(plugin, this.sender, Message.RELOAD_FILES); diff --git a/src/main/java/fr/maxlego08/menu/loader/ActionPatternLoader.java b/src/main/java/fr/maxlego08/menu/loader/ActionPatternLoader.java new file mode 100644 index 00000000..7a508804 --- /dev/null +++ b/src/main/java/fr/maxlego08/menu/loader/ActionPatternLoader.java @@ -0,0 +1,34 @@ +package fr.maxlego08.menu.loader; + +import fr.maxlego08.menu.ZMenuPlugin; +import fr.maxlego08.menu.api.exceptions.InventoryException; +import fr.maxlego08.menu.api.pattern.ActionPattern; +import fr.maxlego08.menu.api.utils.Loader; +import fr.maxlego08.menu.pattern.ZActionsPattern; +import fr.maxlego08.menu.zcore.utils.ZUtils; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; + +public class ActionPatternLoader extends ZUtils implements Loader { + private final ZMenuPlugin plugin; + + public ActionPatternLoader(ZMenuPlugin plugin) { + this.plugin = plugin; + } + + @Override + public ActionPattern load(YamlConfiguration configuration, String path, Object... objects) throws InventoryException { + File file = (File) objects[0]; + String name = configuration.getString("name"); + if (name == null) { + throw new InventoryException("ActionPattern name is missing in configuration at path: " + path); + } + return new ZActionsPattern(name,plugin.getButtonManager().loadActions(configuration,"actions", file),plugin.getButtonManager().loadActions(configuration,"deny-actions", file)); + } + + @Override + public void save(ActionPattern object, YamlConfiguration configuration, String path, File file, Object... objects) { + + } +} diff --git a/src/main/java/fr/maxlego08/menu/loader/InventoryLoader.java b/src/main/java/fr/maxlego08/menu/loader/InventoryLoader.java index 8822663b..84dfff18 100644 --- a/src/main/java/fr/maxlego08/menu/loader/InventoryLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/InventoryLoader.java @@ -11,6 +11,7 @@ import fr.maxlego08.menu.api.exceptions.InventorySizeException; import fr.maxlego08.menu.api.exceptions.InventoryTypeException; import fr.maxlego08.menu.api.itemstack.ItemStackSimilar; +import fr.maxlego08.menu.api.pattern.ActionPattern; import fr.maxlego08.menu.api.pattern.Pattern; import fr.maxlego08.menu.api.pattern.PatternManager; import fr.maxlego08.menu.api.requirement.Requirement; @@ -27,7 +28,10 @@ import java.io.File; import java.lang.reflect.Constructor; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; public class InventoryLoader extends ZUtils implements Loader { @@ -70,6 +74,8 @@ public Inventory load(YamlConfiguration configuration, String path, Object... ob List