From 962ce9cb4838e7e80dddc050de5a297d4329c590 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sun, 7 Jul 2024 19:08:31 +0200 Subject: [PATCH 01/18] Add enchantment register api. --- .../alexcrea/cuanvil/api/EnchantmentApi.java | 92 +++++++++++++++++++ .../enchant/CAEnchantmentRegistry.java | 13 ++- 2 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java new file mode 100644 index 0000000..5176eef --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java @@ -0,0 +1,92 @@ +package xyz.alexcrea.cuanvil.api; + +import org.bukkit.NamespacedKey; +import org.bukkit.enchantments.Enchantment; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.alexcrea.cuanvil.enchant.CAEnchantment; +import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry; +import xyz.alexcrea.cuanvil.enchant.wrapped.CAVanillaEnchantment; + +/** + * Custom Anvil api for enchantment registry. + */ +@SuppressWarnings("unused") +public class EnchantmentApi { + + private EnchantmentApi() {} + + /** + * Register an enchantment. + * + * @param enchantment the enchantment to register + * @return true if successful + */ + public static boolean registerEnchantment(@NotNull CAEnchantment enchantment){ + return CAEnchantmentRegistry.getInstance().register(enchantment); + } + + /** + * Register an enchantment by minecraft registered enchantment. + * + * @param enchantment the enchantment to register + * @return true if successful + */ + public static boolean registerEnchantment(@NotNull Enchantment enchantment){ + return registerEnchantment(new CAVanillaEnchantment(enchantment)); + } + + /** + * Unregister an enchantment by its key. + * + * @param key the enchantment key to unregister + * @return true if successful + */ + public static boolean unregisterEnchantment(@NotNull NamespacedKey key){ + CAEnchantment enchantment = CAEnchantmentRegistry.getInstance().getByKey(key); + return CAEnchantmentRegistry.getInstance().unregister(enchantment); + } + + /** + * Unregister an enchantment. + * + * @param enchantment the enchantment to unregister + * @return true if successful + */ + public static boolean unregisterEnchantment(@NotNull CAEnchantment enchantment){ + return CAEnchantmentRegistry.getInstance().unregister(enchantment); + } + + /** + * Unregister an enchantment by his bukkit enchantment. + * + * @param enchantment the enchantment to unregister + * @return true if successful + */ + public static boolean unregisterEnchantment(@NotNull Enchantment enchantment){ + return unregisterEnchantment(enchantment.getKey()); + } + + /** + * Get by key the enchantment. + * + * @param key the key used to fetch + * @return the custom anvil enchantment + */ + @Nullable + public static CAEnchantment getByKey(@NotNull NamespacedKey key){ + return CAEnchantmentRegistry.getInstance().getByKey(key); + } + + /** + * Get by name the enchantment. + * + * @param name the name used to fetch + * @return the custom anvil enchantment + */ + @Nullable + public static CAEnchantment getByName(@NotNull String name){ + return CAEnchantmentRegistry.getInstance().getByName(name); + } + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java index c00c7c2..1f29b4e 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java @@ -56,13 +56,14 @@ public class CAEnchantmentRegistry { * No guarantee that the enchantment will be present on the config gui if registered late. * (By late I mean after custom anvil startup.) * @param enchantment The enchantment to be registered. + * @return If the operation was successful. */ - public void register(@NotNull CAEnchantment enchantment){ + public boolean register(@NotNull CAEnchantment enchantment){ if(byKeyMap.containsKey(enchantment.getKey())){ CustomAnvil.instance.getLogger().log(Level.WARNING, "Duplicate registered enchantment. This should NOT happen.", new IllegalStateException(enchantment.getKey()+" enchantment was already registered")); - return; + return false; } if(byNameMap.containsKey(enchantment.getName())){ CustomAnvil.instance.getLogger().log(Level.WARNING, @@ -77,6 +78,7 @@ public class CAEnchantmentRegistry { if(!enchantment.isOptimised()){ unoptimisedValues.add(enchantment); } + return true; } /** @@ -87,13 +89,16 @@ public class CAEnchantmentRegistry { * No guarantee that the enchantment will absent if the config guis if unregistered late. * (By late I mean after custom anvil startup.) * @param enchantment The enchantment to be unregistered. + * @return If the operation was successful. */ - public void unregister(CAEnchantment enchantment){ - if(enchantment == null) return; + + public boolean unregister(CAEnchantment enchantment){ + if(enchantment == null) return false; byKeyMap.remove(enchantment.getKey()); byNameMap.remove(enchantment.getName()); unoptimisedValues.remove(enchantment); + return true; } /** From 06b3dc89c26602e8da2393b302e9f48402bdf167 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sun, 7 Jul 2024 22:42:52 +0200 Subject: [PATCH 02/18] Add api to add conflict. --- .../xyz/alexcrea/cuanvil/api/ConflictAPI.java | 164 ++++++++++++ .../alexcrea/cuanvil/api/ConflictBuilder.java | 253 ++++++++++++++++++ .../alexcrea/cuanvil/config/ConfigHolder.java | 8 +- .../cuanvil/gui/config/MainConfigGui.java | 2 +- .../gui/config/global/EnchantConflictGui.java | 2 +- .../config/list/MappedGuiListConfigGui.java | 2 +- .../cuanvil/group/EnchantConflictManager.kt | 4 +- 7 files changed, 426 insertions(+), 9 deletions(-) create mode 100644 src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java create mode 100644 src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java new file mode 100644 index 0000000..9551766 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java @@ -0,0 +1,164 @@ +package xyz.alexcrea.cuanvil.api; + +import io.delilaheve.CustomAnvil; +import org.bukkit.Bukkit; +import org.bukkit.NamespacedKey; +import org.bukkit.configuration.file.FileConfiguration; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.alexcrea.cuanvil.config.ConfigHolder; +import xyz.alexcrea.cuanvil.enchant.CAEnchantment; +import xyz.alexcrea.cuanvil.group.*; +import xyz.alexcrea.cuanvil.gui.config.global.EnchantConflictGui; + +/** + * Custom Anvil api for conflict registry. + */ +@SuppressWarnings("unused") +public class ConflictAPI { + + private static int saveChangeTask = -1; + private static int reloadChangeTask = -1; + + /** + * Write and add a conflict. + * + * @param builder the conflict builder to base on + * @return true if successful + */ + public boolean addConflict(@NotNull ConflictBuilder builder){ + FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.getConfig(); + if(config.contains(builder.getName())) return false; + + if(!writeConflict(builder, false)) return false; + + AbstractMaterialGroup materials = extractGroup(builder); + EnchantConflictGroup conflict = new EnchantConflictGroup(builder.getName(), materials, builder.getMaxBeforeConflict()); + appendEnchantments(builder, conflict); + + EnchantConflictGui.INSTANCE.updateValueForGeneric(conflict, true); + + return true; + } + + /** + * Append builders stored enchantments into conflict. + * + * @param builder the builder source + * @param conflict the conflict target + */ + protected void appendEnchantments(@NotNull ConflictBuilder builder, @NotNull EnchantConflictGroup conflict){ + for (String enchantmentName : builder.getEnchantmentNames()){ + if(appendEnchantment(conflict, EnchantmentApi.getByName(enchantmentName))){ + CustomAnvil.instance.getLogger().warning("Could not find enchantment " + enchantmentName + " for conflict " + builder.getName()); + } + } + for (NamespacedKey enchantmentKey : builder.getEnchantmentKeys()){ + if(!appendEnchantment(conflict, EnchantmentApi.getByKey(enchantmentKey))){ + CustomAnvil.instance.getLogger().warning("Could not find enchantment " + enchantmentKey + " for conflict " + builder.getName()); + } + } + } + + /** + * Append an enchantment. + * + * @param conflict the conflict target + * @param enchantment the enchantment + * @return true if successful + */ + protected boolean appendEnchantment(@NotNull EnchantConflictGroup conflict, @Nullable CAEnchantment enchantment){ + if(enchantment == null) + return false; + conflict.addEnchantment(enchantment); + return true; + } + + /** + * Extract group abstract material group. + * + * @param builder the builder source + * @return the abstract material group from the builder + */ + protected AbstractMaterialGroup extractGroup(@NotNull ConflictBuilder builder){ + ItemGroupManager itemGroupManager = ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager(); + IncludeGroup group = new IncludeGroup(EnchantConflictManager.DEFAULT_GROUP_NAME); + + for (String groupName : builder.getExcludedGroupNames()) { + AbstractMaterialGroup materialGroup = itemGroupManager.get(groupName); + + if(materialGroup == null){ + CustomAnvil.instance.getLogger().warning("Material group " + groupName + " do not exist but is ask by conflict " + builder.getName()); + continue; + } + + group.addToPolicy(materialGroup); + } + + return group; + } + + /** + * Write a conflict to the config file and plan an update of conflicts. + *

+ * You may want to use {@link #addConflict(ConflictBuilder)} instead as it is more performance in most case as this function will reload every conflict. + * + * @param builder the builder + * @return true if successful + */ + public boolean writeConflict(@NotNull ConflictBuilder builder){ + return writeConflict(builder, true); + } + + /** + * Write a conflict to the config file. + *

+ * You should use {@link #addConflict(ConflictBuilder)} or {@link #writeConflict(ConflictBuilder)} instead + * + * @param builder the builder + * @param updatePlanned if we should plan an update + * @return true if successful + */ + public boolean writeConflict(@NotNull ConflictBuilder builder, boolean updatePlanned){ + FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.getConfig(); + + String name = builder.getName(); + if(name.contains(".")) { + CustomAnvil.instance.getLogger().warning("Conflict \"" + name +"\" contain . in its name but should not. this conflict is ignored."); + return false; + } + + prepareSaveTask(); + if(updatePlanned) prepareUpdateTask(); + + return true; + } + + /** + * Prepare a task to reload every conflict. + */ + private static void prepareSaveTask() { + if(saveChangeTask != -1) return; + + saveChangeTask = Bukkit.getScheduler().scheduleSyncDelayedTask(CustomAnvil.instance, ()->{ + ConfigHolder.CONFLICT_HOLDER.saveToDisk(true); + saveChangeTask = -1; + }, 0L); + } + + /** + * Prepare a task to save configuration. + */ + private static void prepareUpdateTask() { + if(reloadChangeTask != -1) return; + + reloadChangeTask = Bukkit.getScheduler().scheduleSyncDelayedTask(CustomAnvil.instance, ()->{ + ConfigHolder.CONFLICT_HOLDER.reload(); + EnchantConflictGui.INSTANCE.reloadValues(); + reloadChangeTask = -1; + }, 0L); + + } + + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java new file mode 100644 index 0000000..8a320a1 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java @@ -0,0 +1,253 @@ +package xyz.alexcrea.cuanvil.api; + +import org.bukkit.NamespacedKey; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; +import xyz.alexcrea.cuanvil.enchant.CAEnchantment; +import xyz.alexcrea.cuanvil.group.AbstractMaterialGroup; + +import java.util.HashSet; +import java.util.Set; + +/** + * A Builder for material conflict. + */ +@SuppressWarnings("unused") +public class ConflictBuilder { + + private final @NotNull Plugin source; + private @NotNull String name; + + private final @NotNull Set enchantmentNames; + private final @NotNull Set enchantmentKeys; + + private final @NotNull Set excludedGroupNames; + + private int maxBeforeConflict; + + /** + * Instantiates a new Conflict builder. + * + * @param source the source + * @param name the name + */ + public ConflictBuilder(@NotNull Plugin source, @NotNull String name){ + this.source = source; + this.name = name; + + this.enchantmentNames = new HashSet<>(); + this.enchantmentKeys = new HashSet<>(); + + this.excludedGroupNames = new HashSet<>(); + } + + /** + * Gets conflict source. + * + * @return the source + */ + public @NotNull Plugin getSource() { + return source; + } + + /** + * Gets conflict name. + * + * @return the name + */ + public @NotNull String getName() { + return name; + } + + /** + * Gets stored enchantment names. + * + * @return the enchantment names + */ + public @NotNull Set getEnchantmentNames() { + return enchantmentNames; + } + + /** + * Gets stored enchantment keys. + * + * @return the enchantment keys + */ + public @NotNull Set getEnchantmentKeys() { + return enchantmentKeys; + } + + /** + * Gets stored group names. + * + * @return the group names + */ + public @NotNull Set getExcludedGroupNames() { + return excludedGroupNames; + } + + /** + * Gets max before conflict. + * + * @return the max before conflict + */ + public int getMaxBeforeConflict() { + return maxBeforeConflict; + } + + /** + * Sets name. + * + * @param name the name + * @return the name + */ + public ConflictBuilder setName(String name) { + this.name = name; + return this; + } + + /** + * Sets max before conflict. + * + * @param maxBeforeConflict the max before conflict + * @return the max before conflict + */ + public ConflictBuilder setMaxBeforeConflict(int maxBeforeConflict) { + this.maxBeforeConflict = maxBeforeConflict; + return this; + } + + /** + * Add enchantment by name. + * + * @param enchantmentName the enchantment name + * @return this conflict builder instance + */ + public ConflictBuilder addEnchantment(@NotNull String enchantmentName){ + enchantmentNames.add(enchantmentName); + return this; + } + + /** + * Add enchantment by key. + * + * @param enchantmentKey the enchantment key + * @return this conflict builder instance + */ + public ConflictBuilder addEnchantment(@NotNull NamespacedKey enchantmentKey){ + enchantmentKeys.add(enchantmentKey); + return this; + } + + /** + * Add enchantment by instance. + * + * @param enchantment the enchantment + * @return this conflict builder instance + */ + public ConflictBuilder addEnchantment(@NotNull CAEnchantment enchantment){ + addEnchantment(enchantment.getKey()); + return this; + } + + /** + * Remove enchantment by name. + * + * @param enchantmentName the enchantment name + * @return this conflict builder instance + */ + public ConflictBuilder removeEnchantment(@NotNull String enchantmentName){ + enchantmentNames.remove(enchantmentName); + return this; + } + + /** + * Remove enchantment by key. + * + * @param enchantmentKey the enchantment key + * @return this conflict builder instance + */ + public ConflictBuilder removeEnchantment(@NotNull NamespacedKey enchantmentKey){ + enchantmentKeys.remove(enchantmentKey); + return removeEnchantment(enchantmentKey.getKey()); + } + + /** + * Remove enchantment by instance. + * + * @param enchantment the enchantment + * @return this conflict builder instance + */ + public ConflictBuilder removeEnchantment(@NotNull CAEnchantment enchantment){ + return removeEnchantment(enchantment.getKey()); + } + + /** + * Add group by name. + * + * @param groupName the group name + * @return this conflict builder instance + */ + public ConflictBuilder addExcludedGroup(@NotNull String groupName){ + excludedGroupNames.add(groupName); + return this; + } + + /** + * Add group by instance. + * + * @param group the group + * @return this conflict builder instance + */ + public ConflictBuilder addExcludedGroup(@NotNull AbstractMaterialGroup group){ + return addExcludedGroup(group.getName()); + } + + /** + * Remove group by name. + * + * @param groupName the group name + * @return this conflict builder instance + */ + public ConflictBuilder removeGroup(@NotNull String groupName){ + excludedGroupNames.remove(groupName); + return this; + } + + /** + * Remove group by instance. + * + * @param group the group + * @return this conflict builder instance + */ + public ConflictBuilder removeGroup(@NotNull AbstractMaterialGroup group){ + return removeGroup(group.getName()); + } + + /** + * Copy this conflict builder. + * + * @return a copy of this conflict builder + */ + public ConflictBuilder copy() { + ConflictBuilder clone = new ConflictBuilder(this.source, this.name); + + setMaxBeforeConflict(this.maxBeforeConflict); + + // Set Enchantments + for (NamespacedKey key : this.enchantmentKeys) { + clone.addEnchantment(key); + } + for (String name : this.enchantmentNames) { + clone.addEnchantment(name); + } + + // Set Groups + for (String name : this.excludedGroupNames) { + clone.addExcludedGroup(name); + } + + return clone; + } + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/config/ConfigHolder.java b/src/main/java/xyz/alexcrea/cuanvil/config/ConfigHolder.java index 8999b8b..dc6a14e 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/config/ConfigHolder.java +++ b/src/main/java/xyz/alexcrea/cuanvil/config/ConfigHolder.java @@ -192,7 +192,7 @@ public abstract class ConfigHolder { // Class for itemGroupsManager config public static class ItemGroupConfigHolder extends ResourceConfigHolder { - private final static String FILE_NAME = "item_groups"; + private static final String FILE_NAME = "item_groups"; ItemGroupManager itemGroupsManager; @@ -219,7 +219,7 @@ public abstract class ConfigHolder { // Class for enchant conflict config public static class ConflictConfigHolder extends ResourceConfigHolder { - private final static String FILE_NAME = "enchant_conflict"; + private static final String FILE_NAME = "enchant_conflict"; EnchantConflictManager conflictManager; @@ -243,7 +243,7 @@ public abstract class ConfigHolder { // Class for unit repair config public static class UnitRepairHolder extends ResourceConfigHolder { - private final static String ITEM_GROUP_FILE_NAME = "unit_repair_item"; + private static final String ITEM_GROUP_FILE_NAME = "unit_repair_item"; private UnitRepairHolder() { @@ -259,7 +259,7 @@ public abstract class ConfigHolder { // Class for custom anvil craft public static class CustomAnvilCraftHolder extends ResourceConfigHolder { - private final static String CUSTOM_RECIPE_FILE_NAME = "custom_recipes"; + private static final String CUSTOM_RECIPE_FILE_NAME = "custom_recipes"; CustomAnvilRecipeManager recipeManager; private CustomAnvilCraftHolder() { diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java index 3b6ae2c..44617f0 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java @@ -16,7 +16,7 @@ import java.util.Collections; public class MainConfigGui extends ChestGui { - private final static MainConfigGui INSTANCE = new MainConfigGui(); + private static final MainConfigGui INSTANCE = new MainConfigGui(); public static MainConfigGui getInstance() { return INSTANCE; diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java index 6020df6..1526908 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java @@ -18,7 +18,7 @@ import java.util.Collection; public class EnchantConflictGui extends MappedGuiListConfigGui { - public final static EnchantConflictGui INSTANCE = new EnchantConflictGui(); + public static final EnchantConflictGui INSTANCE = new EnchantConflictGui(); static { INSTANCE.init(); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java index 5438600..9c73760 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java @@ -13,7 +13,7 @@ import java.util.function.Consumer; public abstract class MappedGuiListConfigGui< T, S extends ElementMappedToListGui> extends MappedElementListConfigGui< T, S > { - public MappedGuiListConfigGui(@NotNull String title) { + protected MappedGuiListConfigGui(@NotNull String title) { super(title); } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt index b2d54d4..b504c45 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt @@ -28,7 +28,7 @@ class EnchantConflictManager { private const val FUTURE_USE_PATH = "useInFuture" // Default name for a joining group - private const val DEFAULT_GROUP_NAME = "joinedGroup" + public const val DEFAULT_GROUP_NAME = "joinedGroup" // 1.20.5 compatibility TODO better update system private val SWEEPING_EDGE_ENCHANT = @@ -140,7 +140,7 @@ class EnchantConflictManager { ): AbstractMaterialGroup { val group = itemManager.get(groupName) if (group == null) { - CustomAnvil.instance.logger.warning("Group $groupName do not exist but is ask by conflict $conflictName") + CustomAnvil.instance.logger.warning("Material group $groupName do not exist but is ask by conflict $conflictName") return IncludeGroup("error_placeholder") } From e1f6c3f5a8560b29d662c722f6be520f8f24b549 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Mon, 8 Jul 2024 00:15:07 +0200 Subject: [PATCH 03/18] Write conflict to file when write conflict is called. Allow custom default rarity. Update ConflictBuilder javadoc. Allow null source for ConflictBuilder. Log conflict origin on warning. --- .../xyz/alexcrea/cuanvil/api/ConflictAPI.java | 36 ++++- .../alexcrea/cuanvil/api/ConflictBuilder.java | 137 ++++++++++++++---- .../alexcrea/cuanvil/api/EnchantmentApi.java | 17 ++- .../cuanvil/enchant/EnchantmentRarity.java | 22 +-- .../cuanvil/group/EnchantConflictManager.kt | 6 +- 5 files changed, 174 insertions(+), 44 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java index 9551766..b0f81c7 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java @@ -11,6 +11,9 @@ import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.group.*; import xyz.alexcrea.cuanvil.gui.config.global.EnchantConflictGui; +import java.util.HashSet; +import java.util.Set; + /** * Custom Anvil api for conflict registry. */ @@ -51,11 +54,13 @@ public class ConflictAPI { for (String enchantmentName : builder.getEnchantmentNames()){ if(appendEnchantment(conflict, EnchantmentApi.getByName(enchantmentName))){ CustomAnvil.instance.getLogger().warning("Could not find enchantment " + enchantmentName + " for conflict " + builder.getName()); + logConflictOrigin(builder); } } for (NamespacedKey enchantmentKey : builder.getEnchantmentKeys()){ if(!appendEnchantment(conflict, EnchantmentApi.getByKey(enchantmentKey))){ CustomAnvil.instance.getLogger().warning("Could not find enchantment " + enchantmentKey + " for conflict " + builder.getName()); + logConflictOrigin(builder); } } } @@ -89,6 +94,7 @@ public class ConflictAPI { if(materialGroup == null){ CustomAnvil.instance.getLogger().warning("Material group " + groupName + " do not exist but is ask by conflict " + builder.getName()); + logConflictOrigin(builder); continue; } @@ -124,16 +130,41 @@ public class ConflictAPI { String name = builder.getName(); if(name.contains(".")) { - CustomAnvil.instance.getLogger().warning("Conflict \"" + name +"\" contain . in its name but should not. this conflict is ignored."); + CustomAnvil.instance.getLogger().warning("Conflict " + name +" contain . in its name but should not. this conflict is ignored."); + logConflictOrigin(builder); return false; } + String basePath = name+"."; + + Set enchantments = extractEnchantments(builder); + Set excludedGroups = builder.getExcludedGroupNames(); + if(!enchantments.isEmpty()) config.set(basePath + "enchantments", enchantments); + if(!excludedGroups.isEmpty()) config.set(basePath + "notAffectedGroups", excludedGroups); + if(builder.getMaxBeforeConflict() > 0) config.set(basePath + "maxEnchantmentBeforeConflict", builder.getMaxBeforeConflict()); + + prepareSaveTask(); if(updatePlanned) prepareUpdateTask(); return true; } + /** + * Extract every enchantment names from a builder. + * @param builder the builder storing the enchantments + * @return builder's stored enchantment + */ + @NotNull + private Set extractEnchantments(@NotNull ConflictBuilder builder){ + Set result = new HashSet<>(builder.getEnchantmentNames()); + for (NamespacedKey enchantmentKey : builder.getEnchantmentKeys()) { + result.add(enchantmentKey.getKey()); + } + + return result; + } + /** * Prepare a task to reload every conflict. */ @@ -160,5 +191,8 @@ public class ConflictAPI { } + private void logConflictOrigin(@NotNull ConflictBuilder builder){ + CustomAnvil.instance.getLogger().warning("Conflict " + builder.getName() +" came from " + builder.getSourceName() + "."); + } } diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java index 8a320a1..0efffee 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java @@ -3,6 +3,7 @@ package xyz.alexcrea.cuanvil.api; import org.bukkit.NamespacedKey; import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.group.AbstractMaterialGroup; @@ -15,7 +16,7 @@ import java.util.Set; @SuppressWarnings("unused") public class ConflictBuilder { - private final @NotNull Plugin source; + private final @Nullable Plugin source; private @NotNull String name; private final @NotNull Set enchantmentNames; @@ -31,7 +32,7 @@ public class ConflictBuilder { * @param source the source * @param name the name */ - public ConflictBuilder(@NotNull Plugin source, @NotNull String name){ + public ConflictBuilder(@NotNull String name, @Nullable Plugin source){ this.source = source; this.name = name; @@ -39,64 +40,96 @@ public class ConflictBuilder { this.enchantmentKeys = new HashSet<>(); this.excludedGroupNames = new HashSet<>(); + + this.maxBeforeConflict = 0; + } + /** + * Instantiates a new Conflict builder. + * + * @param name the conflict name + */ + public ConflictBuilder(@NotNull String name){ + this(name, null); } /** * Gets conflict source. * - * @return the source + * @return the conflict source */ - public @NotNull Plugin getSource() { + @Nullable + public Plugin getSource() { return source; } + /** + * Gets conflict source name. + * + * @return the conflict source + */ + @NotNull + public String getSourceName() { + if(source == null) return "an unknown source"; + + return source.getName(); + } + /** * Gets conflict name. * * @return the name */ - public @NotNull String getName() { + @NotNull + public String getName() { return name; } /** - * Gets stored enchantment names. + * Gets stored conflicting enchantment names. * * @return the enchantment names */ - public @NotNull Set getEnchantmentNames() { + @NotNull + public Set getEnchantmentNames() { return enchantmentNames; } /** - * Gets stored enchantment keys. + * Gets stored conflicting enchantment keys. * * @return the enchantment keys */ - public @NotNull Set getEnchantmentKeys() { + @NotNull + public Set getEnchantmentKeys() { return enchantmentKeys; } /** - * Gets stored group names. + * Gets stored excluded group names. * * @return the group names */ - public @NotNull Set getExcludedGroupNames() { + @NotNull + public Set getExcludedGroupNames() { return excludedGroupNames; } /** - * Gets max before conflict. + * Gets max number of conflicting enchantment before conflict is active. + *

+ * This value represent how many enchantment contained on this conflict can be applied to before conflict is considered active. + * That mean new enchantment will not be able to be added to the item and present enchantment will not have its level upgraded. + *

+ * In vanilla. material restriction have this value set to 0 and enchantment conflict set to 1. * - * @return the max before conflict + * @return the max number of conflicting enchantment before conflict. 0 by default. */ public int getMaxBeforeConflict() { return maxBeforeConflict; } /** - * Sets name. + * Sets conflict name. * * @param name the name * @return the name @@ -107,7 +140,12 @@ public class ConflictBuilder { } /** - * Sets max before conflict. + * Sets max number of conflicting enchantment before conflict is active. + *

+ * This value represent how many enchantment contained on this conflict can be applied to before conflict is considered active. + * That mean new enchantment will not be able to be added to the item and present enchantment will not have its level upgraded. + *

+ * In vanilla. material restriction have this value set to 0 and enchantment conflict set to 1. * * @param maxBeforeConflict the max before conflict * @return the max before conflict @@ -118,55 +156,60 @@ public class ConflictBuilder { } /** - * Add enchantment by name. + * Add a conflicting enchantment by name. * * @param enchantmentName the enchantment name * @return this conflict builder instance */ + @NotNull public ConflictBuilder addEnchantment(@NotNull String enchantmentName){ enchantmentNames.add(enchantmentName); return this; } /** - * Add enchantment by key. + * Add a conflicting enchantment by key. * * @param enchantmentKey the enchantment key * @return this conflict builder instance */ + @NotNull public ConflictBuilder addEnchantment(@NotNull NamespacedKey enchantmentKey){ enchantmentKeys.add(enchantmentKey); return this; } /** - * Add enchantment by instance. + * Add a conflicting enchantment by instance. * * @param enchantment the enchantment * @return this conflict builder instance */ + @NotNull public ConflictBuilder addEnchantment(@NotNull CAEnchantment enchantment){ addEnchantment(enchantment.getKey()); return this; } /** - * Remove enchantment by name. + * Remove conflicting enchantment by name. * * @param enchantmentName the enchantment name * @return this conflict builder instance */ + @NotNull public ConflictBuilder removeEnchantment(@NotNull String enchantmentName){ enchantmentNames.remove(enchantmentName); return this; } /** - * Remove enchantment by key. + * Remove conflicting enchantment by key. * * @param enchantmentKey the enchantment key * @return this conflict builder instance */ + @NotNull public ConflictBuilder removeEnchantment(@NotNull NamespacedKey enchantmentKey){ enchantmentKeys.remove(enchantmentKey); return removeEnchantment(enchantmentKey.getKey()); @@ -178,50 +221,87 @@ public class ConflictBuilder { * @param enchantment the enchantment * @return this conflict builder instance */ + @NotNull public ConflictBuilder removeEnchantment(@NotNull CAEnchantment enchantment){ return removeEnchantment(enchantment.getKey()); } /** - * Add group by name. + * Add an excluded group by name. + *

+ * If left item of an anvil craft is included on one of the excluded group it will ignore this conflict. + *

+ * This allows to create conflict only for some item. Material restriction can be written like that. + *

+ * For example: If we exclude a material group containing every pickaxe and add efficiency enchantment + * with {@link #setMaxBeforeConflict(int) maxBeforeConflict} set to 0. + * Then only pickaxe will be able to have efficiency. * * @param groupName the group name * @return this conflict builder instance */ + @NotNull public ConflictBuilder addExcludedGroup(@NotNull String groupName){ excludedGroupNames.add(groupName); return this; } /** - * Add group by instance. + * Add an excluded group by instance. + *

+ * If left item of an anvil craft is included on one of the excluded group it will ignore this conflict. + *

+ * This allows to create conflict only for some item. Material restriction can be written like that. + *

+ * For example: If we exclude a material group containing every pickaxe and add efficiency enchantment + * with {@link #setMaxBeforeConflict(int) maxBeforeConflict} set to 0. + * Then only pickaxe will be able to have efficiency. * * @param group the group * @return this conflict builder instance */ + @NotNull public ConflictBuilder addExcludedGroup(@NotNull AbstractMaterialGroup group){ return addExcludedGroup(group.getName()); } /** - * Remove group by name. + * Remove an excluded group by name. + *

+ * If left item of an anvil craft is included on one of the excluded group it will ignore this conflict. + *

+ * This allows to create conflict only for some item. Material restriction can be written like that. + *

+ * For example: If we exclude a material group containing every pickaxe and add efficiency enchantment + * with {@link #setMaxBeforeConflict(int) maxBeforeConflict} set to 0. + * Then only pickaxe will be able to have efficiency. * * @param groupName the group name * @return this conflict builder instance */ - public ConflictBuilder removeGroup(@NotNull String groupName){ + @NotNull + public ConflictBuilder removeExcludedGroup(@NotNull String groupName){ excludedGroupNames.remove(groupName); return this; } /** - * Remove group by instance. + * Remove an excluded group by instance. + *

+ * If left item of an anvil craft is included on one of the excluded group it will ignore this conflict. + *

+ * This allows to create conflict only for some item. Material restriction can be written like that. + *

+ * For example: If we exclude a material group containing every pickaxe and add efficiency enchantment + * with {@link #setMaxBeforeConflict(int) maxBeforeConflict} set to 0. + * Then only pickaxe will be able to have efficiency. * * @param group the group * @return this conflict builder instance */ - public ConflictBuilder removeGroup(@NotNull AbstractMaterialGroup group){ - return removeGroup(group.getName()); + @NotNull + public ConflictBuilder removeExcludedGroup(@NotNull AbstractMaterialGroup group){ + return removeExcludedGroup(group.getName()); } /** @@ -229,8 +309,9 @@ public class ConflictBuilder { * * @return a copy of this conflict builder */ + @NotNull public ConflictBuilder copy() { - ConflictBuilder clone = new ConflictBuilder(this.source, this.name); + ConflictBuilder clone = new ConflictBuilder(this.name, this.source); setMaxBeforeConflict(this.maxBeforeConflict); diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java index 5176eef..cfa498c 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java @@ -6,6 +6,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry; +import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity; import xyz.alexcrea.cuanvil.enchant.wrapped.CAVanillaEnchantment; /** @@ -27,7 +28,21 @@ public class EnchantmentApi { } /** - * Register an enchantment by minecraft registered enchantment. + * Register an enchantment by minecraft registered enchantment instance. + * + * @param enchantment the enchantment to register + * @param defaultRarity the default rarity of the provided enchantment + * @return true if successful + */ + public static boolean registerEnchantment(@NotNull Enchantment enchantment, @Nullable EnchantmentRarity defaultRarity){ + if(defaultRarity == null) + return registerEnchantment(new CAVanillaEnchantment(enchantment)); + + return registerEnchantment(new CAVanillaEnchantment(enchantment, defaultRarity)); + } + + /** + * Register an enchantment by minecraft registered enchantment instance. * * @param enchantment the enchantment to register * @return true if successful diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/EnchantmentRarity.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/EnchantmentRarity.java index 50fdfdf..57ccb72 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/EnchantmentRarity.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/EnchantmentRarity.java @@ -1,31 +1,31 @@ package xyz.alexcrea.cuanvil.enchant; -// because spigot (1.18) do not support enchantment rarity, I need to do it myself... -public enum EnchantmentRarity { +// because spigot (1.18) do not look like to provide access to enchantment rarity I need to do it myself... +public class EnchantmentRarity { - NO_RARITY(0, 0), - COMMON(1), - UNCOMMON(2), - RARE(4), - VERY_RARE(8); + public static final EnchantmentRarity NO_RARITY = new EnchantmentRarity(0, 0); + public static final EnchantmentRarity COMMON = new EnchantmentRarity(1); + public static final EnchantmentRarity UNCOMMON = new EnchantmentRarity(2); + public static final EnchantmentRarity RARE = new EnchantmentRarity(4); + public static final EnchantmentRarity VERY_RARE = new EnchantmentRarity(8); private final int itemValue; private final int bookValue; - EnchantmentRarity(int itemValue, int bookValue) { + public EnchantmentRarity(int itemValue, int bookValue) { this.itemValue = itemValue; this.bookValue = bookValue; } - EnchantmentRarity(int itemValue) { + public EnchantmentRarity(int itemValue) { this(itemValue, Math.max(1, itemValue / 2)); } - public int getBookValue() { + public final int getBookValue() { return bookValue; } - public int getItemValue() { + public final int getItemValue() { return itemValue; } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt index b504c45..ea808aa 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt @@ -28,7 +28,7 @@ class EnchantConflictManager { private const val FUTURE_USE_PATH = "useInFuture" // Default name for a joining group - public const val DEFAULT_GROUP_NAME = "joinedGroup" + const val DEFAULT_GROUP_NAME = "joinedGroup" // 1.20.5 compatibility TODO better update system private val SWEEPING_EDGE_ENCHANT = @@ -175,7 +175,7 @@ class EnchantConflictManager { if(doConflict){ return ConflictType.ENCHANTMENT_CONFLICT } -; + } } @@ -188,7 +188,7 @@ class EnchantConflictManager { } - return result; + return result } private fun createPartialResult(item: ItemStack, enchantments: Map): ItemStack { From fca7bbb416b4c273d31d72942c859168f4e65382 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Mon, 8 Jul 2024 15:36:19 +0200 Subject: [PATCH 04/18] Added material group API. Also edited some javadoc. --- .../xyz/alexcrea/cuanvil/api/ConflictAPI.java | 5 +- .../alexcrea/cuanvil/api/EnchantmentApi.java | 4 +- .../cuanvil/api/MaterialGroupApi.java | 158 ++++++++++++++++++ .../cuanvil/enchant/CAEnchantment.java | 3 - .../cuanvil/enchant/CAEnchantmentBase.java | 4 - .../cuanvil/enchant/wrapped/CAEcoEnchant.java | 4 +- .../cuanvil/group/EnchantConflictManager.kt | 1 - 7 files changed, 164 insertions(+), 15 deletions(-) create mode 100644 src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java index b0f81c7..a0a077a 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java @@ -25,6 +25,7 @@ public class ConflictAPI { /** * Write and add a conflict. + * Will not write the conflict if it already exists. * * @param builder the conflict builder to base on * @return true if successful @@ -122,7 +123,7 @@ public class ConflictAPI { * You should use {@link #addConflict(ConflictBuilder)} or {@link #writeConflict(ConflictBuilder)} instead * * @param builder the builder - * @param updatePlanned if we should plan an update + * @param updatePlanned if we should plan a global update for conflicts * @return true if successful */ public boolean writeConflict(@NotNull ConflictBuilder builder, boolean updatePlanned){ @@ -135,7 +136,7 @@ public class ConflictAPI { return false; } - String basePath = name+"."; + String basePath = name + "."; Set enchantments = extractEnchantments(builder); Set excludedGroups = builder.getExcludedGroupNames(); diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java index cfa498c..08471a0 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java @@ -83,7 +83,7 @@ public class EnchantmentApi { } /** - * Get by key the enchantment. + * Get by key a enchantment. * * @param key the key used to fetch * @return the custom anvil enchantment @@ -94,7 +94,7 @@ public class EnchantmentApi { } /** - * Get by name the enchantment. + * Get by name a enchantment. * * @param name the name used to fetch * @return the custom anvil enchantment diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java new file mode 100644 index 0000000..3041675 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java @@ -0,0 +1,158 @@ +package xyz.alexcrea.cuanvil.api; + +import io.delilaheve.CustomAnvil; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.configuration.file.FileConfiguration; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.alexcrea.cuanvil.config.ConfigHolder; +import xyz.alexcrea.cuanvil.group.AbstractMaterialGroup; +import xyz.alexcrea.cuanvil.group.ExcludeGroup; +import xyz.alexcrea.cuanvil.group.IncludeGroup; +import xyz.alexcrea.cuanvil.group.ItemGroupManager; +import xyz.alexcrea.cuanvil.gui.config.global.GroupConfigGui; + +import java.util.EnumSet; +import java.util.Set; + +/** + * The type Material group api. + */ +@SuppressWarnings("unused") +public class MaterialGroupApi { + + private static int saveChangeTask = -1; + private static int reloadChangeTask = -1; + + /** + * Write and add a group. + * Will not write the group if it already exists. + * + * @param group the group to add + * @return true if successful + */ + public boolean addMaterialGroup(@NotNull AbstractMaterialGroup group){ + ItemGroupManager itemGroupManager = ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager(); + if(itemGroupManager.get(group.getName()) != null) return false; + + if(!writeMaterialGroup(group, false)) return false; + + if(group instanceof IncludeGroup includeGroup){ + GroupConfigGui.INSTANCE.updateValueForGeneric(includeGroup, true); + } + + return true; + } + + /** + * Write a material group to the config file and plan an update of groups. + *

+ * You may want to use {@link #addMaterialGroup(AbstractMaterialGroup)} instead as it is more performance in most case as this function will reload every conflict. + * + * @param group the group to write + * @return true if successful + */ + public boolean writeMaterialGroup(@NotNull AbstractMaterialGroup group){ + return writeMaterialGroup(group, true); + } + + /** + * Write a material group to the config file. + *

+ * You should use {@link #addMaterialGroup(AbstractMaterialGroup)} or {@link #writeMaterialGroup(AbstractMaterialGroup)} instead + * + * @param group the group to write + * @param updatePlanned if we should plan a global update for material groups + * @return true if successful + */ + public boolean writeMaterialGroup(@NotNull AbstractMaterialGroup group, boolean updatePlanned){ + String name = group.getName(); + if(name.contains(".")) { + CustomAnvil.instance.getLogger().warning("Group " + name +" contain . in its name but should not. this material group is ignored."); + return false; + } + + if(group instanceof IncludeGroup includeGroup){ + writeKnownGroup("include", includeGroup); + }else if(group instanceof ExcludeGroup excludeGroup){ + writeKnownGroup("exclude", excludeGroup); + }else{ + writeUnknownGroup(group); + } + + prepareSaveTask(); + if(updatePlanned) prepareUpdateTask(); + + return true; + } + + private void writeKnownGroup(@NotNull String groupType, @NotNull AbstractMaterialGroup group){ + FileConfiguration config = ConfigHolder.ITEM_GROUP_HOLDER.getConfig(); + + String basePath = group.getName() + "."; + Set materialSet = group.getNonGroupInheritedMaterials(); + Set groupSet = group.getGroups(); + + config.set(basePath + ItemGroupManager.GROUP_TYPE_PATH, groupType); + if(!materialSet.isEmpty()){ + config.set(basePath + ItemGroupManager.MATERIAL_LIST_PATH, materialSet); + } + if(!groupSet.isEmpty()){ + config.set(basePath + ItemGroupManager.GROUP_LIST_PATH, groupSet); + } + + } + + private void writeUnknownGroup(@NotNull AbstractMaterialGroup group) { + FileConfiguration config = ConfigHolder.ITEM_GROUP_HOLDER.getConfig(); + + String basePath = group.getName() + "."; + EnumSet materials = group.getMaterials(); + + config.set(basePath + ItemGroupManager.GROUP_TYPE_PATH, "include"); + if(!materials.isEmpty()){ + config.set(basePath + ItemGroupManager.MATERIAL_LIST_PATH, materials); + } + + } + + /** + * Prepare a task to reload every conflict. + */ + private static void prepareSaveTask() { + if(saveChangeTask != -1) return; + + saveChangeTask = Bukkit.getScheduler().scheduleSyncDelayedTask(CustomAnvil.instance, ()->{ + ConfigHolder.ITEM_GROUP_HOLDER.saveToDisk(true); + saveChangeTask = -1; + }, 0L); + } + + /** + * Prepare a task to save configuration. + */ + private static void prepareUpdateTask() { + if(reloadChangeTask != -1) return; + + reloadChangeTask = Bukkit.getScheduler().scheduleSyncDelayedTask(CustomAnvil.instance, ()->{ + ConfigHolder.ITEM_GROUP_HOLDER.reload(); + GroupConfigGui.INSTANCE.reloadValues(); + reloadChangeTask = -1; + }, 0L); + + } + + /** + * Get by name a group. + * + * @param groupName the group name used to fetch + * @return the abstract group of this name + */ + @Nullable + public static AbstractMaterialGroup getGroup(@NotNull String groupName){ + return ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager().get(groupName); + } + + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java index 4a9a766..826160d 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java @@ -1,7 +1,6 @@ package xyz.alexcrea.cuanvil.enchant; import io.delilaheve.util.ItemUtil; -import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.entity.HumanEntity; import org.bukkit.inventory.ItemStack; @@ -11,13 +10,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.dependency.DependencyManager; import xyz.alexcrea.cuanvil.dependency.EnchantmentSquaredDependency; -import xyz.alexcrea.cuanvil.group.ConflictType; import xyz.alexcrea.cuanvil.group.EnchantConflictGroup; import java.util.Collection; import java.util.HashMap; import java.util.Map; -import java.util.function.Supplier; /** * Represent an enchantment compatible with Custom Anvil. diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentBase.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentBase.java index 7ea4666..cec89bd 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentBase.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentBase.java @@ -1,20 +1,16 @@ package xyz.alexcrea.cuanvil.enchant; -import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.entity.HumanEntity; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import xyz.alexcrea.cuanvil.group.ConflictType; import xyz.alexcrea.cuanvil.group.EnchantConflictGroup; import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.Objects; -import java.util.function.Supplier; public abstract class CAEnchantmentBase implements CAEnchantment { diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEcoEnchant.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEcoEnchant.java index 31991f4..f4ae757 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEcoEnchant.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEcoEnchant.java @@ -5,13 +5,11 @@ import com.willfp.ecoenchants.target.EnchantmentTarget; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; +import xyz.alexcrea.cuanvil.enchant.AdditionalTestEnchantment; import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity; -import xyz.alexcrea.cuanvil.enchant.AdditionalTestEnchantment; -import xyz.alexcrea.cuanvil.group.ConflictType; import java.util.Map; -import java.util.function.Supplier; public class CAEcoEnchant extends CAVanillaEnchantment implements AdditionalTestEnchantment { diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt index ea808aa..2ff60a7 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt @@ -9,7 +9,6 @@ import xyz.alexcrea.cuanvil.enchant.AdditionalTestEnchantment import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry import java.util.* -import kotlin.collections.ArrayList class EnchantConflictManager { From 091fb23aace95cca6e5356a0795659241a4e4c15 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Mon, 8 Jul 2024 17:06:39 +0200 Subject: [PATCH 05/18] Add get every registered for Enchantment, Conflict and Material group. Also updated some javadoc. --- .../xyz/alexcrea/cuanvil/api/ConflictAPI.java | 45 ++++++---- .../alexcrea/cuanvil/api/ConflictBuilder.java | 88 +++++++++++-------- .../alexcrea/cuanvil/api/EnchantmentApi.java | 52 +++++++---- .../cuanvil/api/MaterialGroupApi.java | 20 +++-- .../cuanvil/enchant/CAEnchantment.java | 7 +- .../cuanvil/enchant/CAEnchantmentBase.java | 5 ++ .../enchant/CAEnchantmentRegistry.java | 18 ++-- .../wrapped/CAEnchantSquaredEnchantment.java | 4 +- .../enchant/wrapped/CAVanillaEnchantment.java | 3 + 9 files changed, 155 insertions(+), 87 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java index a0a077a..478b856 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java @@ -11,7 +11,9 @@ import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.group.*; import xyz.alexcrea.cuanvil.gui.config.global.EnchantConflictGui; +import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; /** @@ -27,8 +29,8 @@ public class ConflictAPI { * Write and add a conflict. * Will not write the conflict if it already exists. * - * @param builder the conflict builder to base on - * @return true if successful + * @param builder The conflict builder to base on + * @return True if successful. */ public boolean addConflict(@NotNull ConflictBuilder builder){ FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.getConfig(); @@ -48,8 +50,8 @@ public class ConflictAPI { /** * Append builders stored enchantments into conflict. * - * @param builder the builder source - * @param conflict the conflict target + * @param builder The builder source + * @param conflict The conflict target */ protected void appendEnchantments(@NotNull ConflictBuilder builder, @NotNull EnchantConflictGroup conflict){ for (String enchantmentName : builder.getEnchantmentNames()){ @@ -69,9 +71,9 @@ public class ConflictAPI { /** * Append an enchantment. * - * @param conflict the conflict target - * @param enchantment the enchantment - * @return true if successful + * @param conflict The conflict target + * @param enchantment The enchantment + * @return True if successful. */ protected boolean appendEnchantment(@NotNull EnchantConflictGroup conflict, @Nullable CAEnchantment enchantment){ if(enchantment == null) @@ -83,8 +85,8 @@ public class ConflictAPI { /** * Extract group abstract material group. * - * @param builder the builder source - * @return the abstract material group from the builder + * @param builder The builder source + * @return The abstract material group from the builder. */ protected AbstractMaterialGroup extractGroup(@NotNull ConflictBuilder builder){ ItemGroupManager itemGroupManager = ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager(); @@ -110,8 +112,8 @@ public class ConflictAPI { *

* You may want to use {@link #addConflict(ConflictBuilder)} instead as it is more performance in most case as this function will reload every conflict. * - * @param builder the builder - * @return true if successful + * @param builder The builder + * @return True if successful. */ public boolean writeConflict(@NotNull ConflictBuilder builder){ return writeConflict(builder, true); @@ -122,9 +124,9 @@ public class ConflictAPI { *

* You should use {@link #addConflict(ConflictBuilder)} or {@link #writeConflict(ConflictBuilder)} instead * - * @param builder the builder - * @param updatePlanned if we should plan a global update for conflicts - * @return true if successful + * @param builder The builder + * @param updatePlanned If we should plan a global update for conflicts + * @return True if successful. */ public boolean writeConflict(@NotNull ConflictBuilder builder, boolean updatePlanned){ FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.getConfig(); @@ -153,8 +155,8 @@ public class ConflictAPI { /** * Extract every enchantment names from a builder. - * @param builder the builder storing the enchantments - * @return builder's stored enchantment + * @param builder The builder storing the enchantments + * @return Builder's stored enchantment. */ @NotNull private Set extractEnchantments(@NotNull ConflictBuilder builder){ @@ -196,4 +198,15 @@ public class ConflictAPI { CustomAnvil.instance.getLogger().warning("Conflict " + builder.getName() +" came from " + builder.getSourceName() + "."); } + /** + * Get every registered conflict. + * @return An immutable collection of conflict. + */ + @NotNull + public List getRegisteredConflict(){ + List mutableList = ConfigHolder.CONFLICT_HOLDER.getConflictManager().getConflictList(); + return Collections.unmodifiableList(mutableList); + } + + } diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java index 0efffee..2ba973e 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java @@ -29,10 +29,11 @@ public class ConflictBuilder { /** * Instantiates a new Conflict builder. * - * @param source the source - * @param name the name + * @param name The conflict name + * @param maxBeforeConflict Maximum number of conflicting enchantment before conflict is active + * @param source The conflict source */ - public ConflictBuilder(@NotNull String name, @Nullable Plugin source){ + public ConflictBuilder(@NotNull String name, int maxBeforeConflict, @Nullable Plugin source){ this.source = source; this.name = name; @@ -41,12 +42,23 @@ public class ConflictBuilder { this.excludedGroupNames = new HashSet<>(); - this.maxBeforeConflict = 0; + this.maxBeforeConflict = maxBeforeConflict; } + /** * Instantiates a new Conflict builder. * - * @param name the conflict name + * @param name The conflict name + * @param source The conflict source + */ + public ConflictBuilder(@NotNull String name, @Nullable Plugin source){ + this(name, 0, source); + } + + /** + * Instantiates a new Conflict builder. + * + * @param name The conflict name */ public ConflictBuilder(@NotNull String name){ this(name, null); @@ -55,7 +67,7 @@ public class ConflictBuilder { /** * Gets conflict source. * - * @return the conflict source + * @return The conflict source. */ @Nullable public Plugin getSource() { @@ -65,7 +77,7 @@ public class ConflictBuilder { /** * Gets conflict source name. * - * @return the conflict source + * @return The conflict source name. */ @NotNull public String getSourceName() { @@ -77,7 +89,7 @@ public class ConflictBuilder { /** * Gets conflict name. * - * @return the name + * @return The conflict name. */ @NotNull public String getName() { @@ -87,7 +99,7 @@ public class ConflictBuilder { /** * Gets stored conflicting enchantment names. * - * @return the enchantment names + * @return The stored enchantment names. */ @NotNull public Set getEnchantmentNames() { @@ -97,7 +109,7 @@ public class ConflictBuilder { /** * Gets stored conflicting enchantment keys. * - * @return the enchantment keys + * @return The stored enchantment keys. */ @NotNull public Set getEnchantmentKeys() { @@ -107,7 +119,7 @@ public class ConflictBuilder { /** * Gets stored excluded group names. * - * @return the group names + * @return The stored group names. */ @NotNull public Set getExcludedGroupNames() { @@ -115,7 +127,7 @@ public class ConflictBuilder { } /** - * Gets max number of conflicting enchantment before conflict is active. + * Gets maximum number of conflicting enchantment before conflict is active. *

* This value represent how many enchantment contained on this conflict can be applied to before conflict is considered active. * That mean new enchantment will not be able to be added to the item and present enchantment will not have its level upgraded. @@ -131,8 +143,8 @@ public class ConflictBuilder { /** * Sets conflict name. * - * @param name the name - * @return the name + * @param name The name + * @return This conflict builder instance. */ public ConflictBuilder setName(String name) { this.name = name; @@ -140,15 +152,15 @@ public class ConflictBuilder { } /** - * Sets max number of conflicting enchantment before conflict is active. + * Sets maximum number of conflicting enchantment before conflict is active. *

* This value represent how many enchantment contained on this conflict can be applied to before conflict is considered active. * That mean new enchantment will not be able to be added to the item and present enchantment will not have its level upgraded. *

* In vanilla. material restriction have this value set to 0 and enchantment conflict set to 1. * - * @param maxBeforeConflict the max before conflict - * @return the max before conflict + * @param maxBeforeConflict The max before conflict + * @return This conflict builder instance. */ public ConflictBuilder setMaxBeforeConflict(int maxBeforeConflict) { this.maxBeforeConflict = maxBeforeConflict; @@ -158,8 +170,8 @@ public class ConflictBuilder { /** * Add a conflicting enchantment by name. * - * @param enchantmentName the enchantment name - * @return this conflict builder instance + * @param enchantmentName The enchantment name + * @return This conflict builder instance. */ @NotNull public ConflictBuilder addEnchantment(@NotNull String enchantmentName){ @@ -170,8 +182,8 @@ public class ConflictBuilder { /** * Add a conflicting enchantment by key. * - * @param enchantmentKey the enchantment key - * @return this conflict builder instance + * @param enchantmentKey The enchantment key + * @return This conflict builder instance. */ @NotNull public ConflictBuilder addEnchantment(@NotNull NamespacedKey enchantmentKey){ @@ -182,8 +194,8 @@ public class ConflictBuilder { /** * Add a conflicting enchantment by instance. * - * @param enchantment the enchantment - * @return this conflict builder instance + * @param enchantment The enchantment + * @return This conflict builder instance. */ @NotNull public ConflictBuilder addEnchantment(@NotNull CAEnchantment enchantment){ @@ -194,8 +206,8 @@ public class ConflictBuilder { /** * Remove conflicting enchantment by name. * - * @param enchantmentName the enchantment name - * @return this conflict builder instance + * @param enchantmentName The enchantment name + * @return This conflict builder instance. */ @NotNull public ConflictBuilder removeEnchantment(@NotNull String enchantmentName){ @@ -206,8 +218,8 @@ public class ConflictBuilder { /** * Remove conflicting enchantment by key. * - * @param enchantmentKey the enchantment key - * @return this conflict builder instance + * @param enchantmentKey The enchantment key + * @return This conflict builder instance. */ @NotNull public ConflictBuilder removeEnchantment(@NotNull NamespacedKey enchantmentKey){ @@ -218,8 +230,8 @@ public class ConflictBuilder { /** * Remove enchantment by instance. * - * @param enchantment the enchantment - * @return this conflict builder instance + * @param enchantment The enchantment + * @return This conflict builder instance. */ @NotNull public ConflictBuilder removeEnchantment(@NotNull CAEnchantment enchantment){ @@ -237,8 +249,8 @@ public class ConflictBuilder { * with {@link #setMaxBeforeConflict(int) maxBeforeConflict} set to 0. * Then only pickaxe will be able to have efficiency. * - * @param groupName the group name - * @return this conflict builder instance + * @param groupName The group name + * @return This conflict builder instance. */ @NotNull public ConflictBuilder addExcludedGroup(@NotNull String groupName){ @@ -257,8 +269,8 @@ public class ConflictBuilder { * with {@link #setMaxBeforeConflict(int) maxBeforeConflict} set to 0. * Then only pickaxe will be able to have efficiency. * - * @param group the group - * @return this conflict builder instance + * @param group The group + * @return this conflict builder instance. */ @NotNull public ConflictBuilder addExcludedGroup(@NotNull AbstractMaterialGroup group){ @@ -276,8 +288,8 @@ public class ConflictBuilder { * with {@link #setMaxBeforeConflict(int) maxBeforeConflict} set to 0. * Then only pickaxe will be able to have efficiency. * - * @param groupName the group name - * @return this conflict builder instance + * @param groupName The group name + * @return This conflict builder instance. */ @NotNull public ConflictBuilder removeExcludedGroup(@NotNull String groupName){ @@ -296,8 +308,8 @@ public class ConflictBuilder { * with {@link #setMaxBeforeConflict(int) maxBeforeConflict} set to 0. * Then only pickaxe will be able to have efficiency. * - * @param group the group - * @return this conflict builder instance + * @param group The group + * @return This conflict builder instance. */ @NotNull public ConflictBuilder removeExcludedGroup(@NotNull AbstractMaterialGroup group){ @@ -307,7 +319,7 @@ public class ConflictBuilder { /** * Copy this conflict builder. * - * @return a copy of this conflict builder + * @return A copy of this conflict builder. */ @NotNull public ConflictBuilder copy() { diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java index 08471a0..a41aa55 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java @@ -9,6 +9,9 @@ import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry; import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity; import xyz.alexcrea.cuanvil.enchant.wrapped.CAVanillaEnchantment; +import java.util.Collections; +import java.util.Map; + /** * Custom Anvil api for enchantment registry. */ @@ -20,8 +23,8 @@ public class EnchantmentApi { /** * Register an enchantment. * - * @param enchantment the enchantment to register - * @return true if successful + * @param enchantment The enchantment to register + * @return True if successful. */ public static boolean registerEnchantment(@NotNull CAEnchantment enchantment){ return CAEnchantmentRegistry.getInstance().register(enchantment); @@ -30,9 +33,9 @@ public class EnchantmentApi { /** * Register an enchantment by minecraft registered enchantment instance. * - * @param enchantment the enchantment to register - * @param defaultRarity the default rarity of the provided enchantment - * @return true if successful + * @param enchantment The enchantment to register + * @param defaultRarity The default rarity of the provided enchantment + * @return True if successful. */ public static boolean registerEnchantment(@NotNull Enchantment enchantment, @Nullable EnchantmentRarity defaultRarity){ if(defaultRarity == null) @@ -43,9 +46,11 @@ public class EnchantmentApi { /** * Register an enchantment by minecraft registered enchantment instance. + *

+ * Please note that this function assume the provided enchantment is registered into minecraft registry. * - * @param enchantment the enchantment to register - * @return true if successful + * @param enchantment The enchantment to register + * @return True if successful. */ public static boolean registerEnchantment(@NotNull Enchantment enchantment){ return registerEnchantment(new CAVanillaEnchantment(enchantment)); @@ -54,8 +59,8 @@ public class EnchantmentApi { /** * Unregister an enchantment by its key. * - * @param key the enchantment key to unregister - * @return true if successful + * @param key The enchantment key to unregister + * @return True if successful. */ public static boolean unregisterEnchantment(@NotNull NamespacedKey key){ CAEnchantment enchantment = CAEnchantmentRegistry.getInstance().getByKey(key); @@ -65,8 +70,8 @@ public class EnchantmentApi { /** * Unregister an enchantment. * - * @param enchantment the enchantment to unregister - * @return true if successful + * @param enchantment The enchantment to unregister + * @return True if successful. */ public static boolean unregisterEnchantment(@NotNull CAEnchantment enchantment){ return CAEnchantmentRegistry.getInstance().unregister(enchantment); @@ -75,18 +80,18 @@ public class EnchantmentApi { /** * Unregister an enchantment by his bukkit enchantment. * - * @param enchantment the enchantment to unregister - * @return true if successful + * @param enchantment The enchantment to unregister + * @return True if successful. */ public static boolean unregisterEnchantment(@NotNull Enchantment enchantment){ return unregisterEnchantment(enchantment.getKey()); } /** - * Get by key a enchantment. + * Get by key an enchantment. * - * @param key the key used to fetch - * @return the custom anvil enchantment + * @param key The key used to fetch + * @return The custom anvil enchantment of this key. null if not found. */ @Nullable public static CAEnchantment getByKey(@NotNull NamespacedKey key){ @@ -94,14 +99,23 @@ public class EnchantmentApi { } /** - * Get by name a enchantment. + * Get by name an enchantment. * - * @param name the name used to fetch - * @return the custom anvil enchantment + * @param name The name used to fetch + * @return The custom anvil enchantment of this name. null if not found. */ @Nullable public static CAEnchantment getByName(@NotNull String name){ return CAEnchantmentRegistry.getInstance().getByName(name); } + /** + * Get every registered custom anvil enchantments. + * @return An immutable map of enchantment key as map key and custom anvil enchantment as value. + */ + @NotNull + public Map getRegisteredEnchantments(){ + return Collections.unmodifiableMap(CAEnchantmentRegistry.getInstance().registeredEnchantments()); + } + } diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java index 3041675..495c9e0 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java @@ -13,11 +13,13 @@ import xyz.alexcrea.cuanvil.group.IncludeGroup; import xyz.alexcrea.cuanvil.group.ItemGroupManager; import xyz.alexcrea.cuanvil.gui.config.global.GroupConfigGui; +import java.util.Collections; import java.util.EnumSet; +import java.util.Map; import java.util.Set; /** - * The type Material group api. + * Custom Anvil api for material group registry. */ @SuppressWarnings("unused") public class MaterialGroupApi { @@ -30,7 +32,7 @@ public class MaterialGroupApi { * Will not write the group if it already exists. * * @param group the group to add - * @return true if successful + * @return true if successful. */ public boolean addMaterialGroup(@NotNull AbstractMaterialGroup group){ ItemGroupManager itemGroupManager = ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager(); @@ -51,7 +53,7 @@ public class MaterialGroupApi { * You may want to use {@link #addMaterialGroup(AbstractMaterialGroup)} instead as it is more performance in most case as this function will reload every conflict. * * @param group the group to write - * @return true if successful + * @return true if successful. */ public boolean writeMaterialGroup(@NotNull AbstractMaterialGroup group){ return writeMaterialGroup(group, true); @@ -64,7 +66,7 @@ public class MaterialGroupApi { * * @param group the group to write * @param updatePlanned if we should plan a global update for material groups - * @return true if successful + * @return true if successful. */ public boolean writeMaterialGroup(@NotNull AbstractMaterialGroup group, boolean updatePlanned){ String name = group.getName(); @@ -147,12 +149,20 @@ public class MaterialGroupApi { * Get by name a group. * * @param groupName the group name used to fetch - * @return the abstract group of this name + * @return the abstract group of this name. null if not found. */ @Nullable public static AbstractMaterialGroup getGroup(@NotNull String groupName){ return ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager().get(groupName); } + /** + * Get every registered material groups. + * @return An immutable map of group name as its key and group as mapped value. + */ + @NotNull + public Map getRegisteredGroups(){ + return Collections.unmodifiableMap(ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager().getGroupMap()); + } } diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java index 826160d..1162eda 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java @@ -18,7 +18,8 @@ import java.util.Map; /** * Represent an enchantment compatible with Custom Anvil. - * One issue with custom anvil is: it does not handle well duplicate key name (ignoring namespace) as the plugin was coded with vanilla enchantment in head + * One issue with custom anvil is: it does not handle well duplicate key name (ignoring namespace) + * as the plugin was initially coded with vanilla enchantment in head */ public interface CAEnchantment { @@ -89,6 +90,7 @@ public interface CAEnchantment { /** * Get current level of the enchantment. * @param item Item to search the level for. + * @return The enchantment level. */ int getLevel(@NotNull ItemStack item); @@ -223,6 +225,8 @@ public interface CAEnchantment { /** * Gets an array of all the registered enchantments. + * + * @param key The enchantment key * @return Array of enchantment. */ static @Nullable CAEnchantment getByKey(@NotNull NamespacedKey key){ @@ -231,6 +235,7 @@ public interface CAEnchantment { /** * Gets a list of all the unoptimised enchantments. + * @param name The enchantment name * @return List of enchantment. */ static @Nullable CAEnchantment getByName(@NotNull String name){ diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentBase.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentBase.java index cec89bd..0b367a7 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentBase.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentBase.java @@ -12,6 +12,11 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +/** + * Default implementation of an enchantment compatible with Custom Anvil. + * One issue with custom anvil is: it does not handle well duplicate key name (ignoring namespace) + * as the plugin was initially coded with vanilla enchantment in head + */ public abstract class CAEnchantmentBase implements CAEnchantment { @NotNull diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java index 1f29b4e..abd9bbb 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java @@ -8,10 +8,7 @@ import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.dependency.DependencyManager; import xyz.alexcrea.cuanvil.enchant.wrapped.CAVanillaEnchantment; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; +import java.util.*; import java.util.logging.Level; public class CAEnchantmentRegistry { @@ -121,20 +118,29 @@ public class CAEnchantmentRegistry { /** * Gets an array of all the registered enchantments. - * @return Array of enchantment. + * @return Array of enchantments. */ @NotNull public Collection values() { return byKeyMap.values(); } + /** + * Gets a map of all the registered enchantments. + * @return Map of enchantments. + */ + public Map registeredEnchantments() { + return byKeyMap; + } + /** * Gets a list of all the unoptimised enchantments. - * @return List of enchantment. + * @return List of unoptimised enchantments. */ @NotNull public List unoptimisedValues() { return unoptimisedValues; } + } diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEnchantSquaredEnchantment.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEnchantSquaredEnchantment.java index ffc9415..86f8914 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEnchantSquaredEnchantment.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEnchantSquaredEnchantment.java @@ -33,8 +33,8 @@ public class CAEnchantSquaredEnchantment extends CAEnchantmentBase { @Override public boolean isAllowed(@NotNull HumanEntity human) { - if(human instanceof Player){ - return this.enchant.hasPermission((Player) human); + if(human instanceof Player player){ + return this.enchant.hasPermission(player); } // Not really ideal for maintainability but will probably never be executed. (At least I hope) boolean required = CustomEnchantManager.getInstance().isRequirePermissions(); diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAVanillaEnchantment.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAVanillaEnchantment.java index 9fef4c1..ad19f5f 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAVanillaEnchantment.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAVanillaEnchantment.java @@ -13,6 +13,9 @@ import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity; import java.util.Locale; +/** + * Custom Anvil enchantment implementation for vanilla registered enchantment. + */ public class CAVanillaEnchantment extends CAEnchantmentBase { private final @NotNull Enchantment enchantment; From 0761c70286ae3ef692720acf57f42f967e417402 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Mon, 8 Jul 2024 17:15:39 +0200 Subject: [PATCH 06/18] Fix some api function not being static. --- .../xyz/alexcrea/cuanvil/api/ConflictAPI.java | 21 ++++++++++--------- .../alexcrea/cuanvil/api/EnchantmentApi.java | 2 +- .../cuanvil/api/MaterialGroupApi.java | 14 +++++++------ 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java index 478b856..0444403 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java @@ -22,6 +22,8 @@ import java.util.Set; @SuppressWarnings("unused") public class ConflictAPI { + private ConflictAPI() {} + private static int saveChangeTask = -1; private static int reloadChangeTask = -1; @@ -32,7 +34,7 @@ public class ConflictAPI { * @param builder The conflict builder to base on * @return True if successful. */ - public boolean addConflict(@NotNull ConflictBuilder builder){ + public static boolean addConflict(@NotNull ConflictBuilder builder){ FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.getConfig(); if(config.contains(builder.getName())) return false; @@ -53,7 +55,7 @@ public class ConflictAPI { * @param builder The builder source * @param conflict The conflict target */ - protected void appendEnchantments(@NotNull ConflictBuilder builder, @NotNull EnchantConflictGroup conflict){ + protected static void appendEnchantments(@NotNull ConflictBuilder builder, @NotNull EnchantConflictGroup conflict){ for (String enchantmentName : builder.getEnchantmentNames()){ if(appendEnchantment(conflict, EnchantmentApi.getByName(enchantmentName))){ CustomAnvil.instance.getLogger().warning("Could not find enchantment " + enchantmentName + " for conflict " + builder.getName()); @@ -75,7 +77,7 @@ public class ConflictAPI { * @param enchantment The enchantment * @return True if successful. */ - protected boolean appendEnchantment(@NotNull EnchantConflictGroup conflict, @Nullable CAEnchantment enchantment){ + protected static boolean appendEnchantment(@NotNull EnchantConflictGroup conflict, @Nullable CAEnchantment enchantment){ if(enchantment == null) return false; conflict.addEnchantment(enchantment); @@ -88,7 +90,7 @@ public class ConflictAPI { * @param builder The builder source * @return The abstract material group from the builder. */ - protected AbstractMaterialGroup extractGroup(@NotNull ConflictBuilder builder){ + protected static AbstractMaterialGroup extractGroup(@NotNull ConflictBuilder builder){ ItemGroupManager itemGroupManager = ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager(); IncludeGroup group = new IncludeGroup(EnchantConflictManager.DEFAULT_GROUP_NAME); @@ -115,7 +117,7 @@ public class ConflictAPI { * @param builder The builder * @return True if successful. */ - public boolean writeConflict(@NotNull ConflictBuilder builder){ + public static boolean writeConflict(@NotNull ConflictBuilder builder){ return writeConflict(builder, true); } @@ -128,7 +130,7 @@ public class ConflictAPI { * @param updatePlanned If we should plan a global update for conflicts * @return True if successful. */ - public boolean writeConflict(@NotNull ConflictBuilder builder, boolean updatePlanned){ + public static boolean writeConflict(@NotNull ConflictBuilder builder, boolean updatePlanned){ FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.getConfig(); String name = builder.getName(); @@ -159,7 +161,7 @@ public class ConflictAPI { * @return Builder's stored enchantment. */ @NotNull - private Set extractEnchantments(@NotNull ConflictBuilder builder){ + private static Set extractEnchantments(@NotNull ConflictBuilder builder){ Set result = new HashSet<>(builder.getEnchantmentNames()); for (NamespacedKey enchantmentKey : builder.getEnchantmentKeys()) { result.add(enchantmentKey.getKey()); @@ -194,7 +196,7 @@ public class ConflictAPI { } - private void logConflictOrigin(@NotNull ConflictBuilder builder){ + private static void logConflictOrigin(@NotNull ConflictBuilder builder){ CustomAnvil.instance.getLogger().warning("Conflict " + builder.getName() +" came from " + builder.getSourceName() + "."); } @@ -203,10 +205,9 @@ public class ConflictAPI { * @return An immutable collection of conflict. */ @NotNull - public List getRegisteredConflict(){ + public static List getRegisteredConflict(){ List mutableList = ConfigHolder.CONFLICT_HOLDER.getConflictManager().getConflictList(); return Collections.unmodifiableList(mutableList); } - } diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java index a41aa55..ae26176 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java @@ -114,7 +114,7 @@ public class EnchantmentApi { * @return An immutable map of enchantment key as map key and custom anvil enchantment as value. */ @NotNull - public Map getRegisteredEnchantments(){ + public static Map getRegisteredEnchantments(){ return Collections.unmodifiableMap(CAEnchantmentRegistry.getInstance().registeredEnchantments()); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java index 495c9e0..76030a8 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java @@ -24,6 +24,8 @@ import java.util.Set; @SuppressWarnings("unused") public class MaterialGroupApi { + private MaterialGroupApi(){} + private static int saveChangeTask = -1; private static int reloadChangeTask = -1; @@ -34,7 +36,7 @@ public class MaterialGroupApi { * @param group the group to add * @return true if successful. */ - public boolean addMaterialGroup(@NotNull AbstractMaterialGroup group){ + public static boolean addMaterialGroup(@NotNull AbstractMaterialGroup group){ ItemGroupManager itemGroupManager = ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager(); if(itemGroupManager.get(group.getName()) != null) return false; @@ -55,7 +57,7 @@ public class MaterialGroupApi { * @param group the group to write * @return true if successful. */ - public boolean writeMaterialGroup(@NotNull AbstractMaterialGroup group){ + public static boolean writeMaterialGroup(@NotNull AbstractMaterialGroup group){ return writeMaterialGroup(group, true); } @@ -68,7 +70,7 @@ public class MaterialGroupApi { * @param updatePlanned if we should plan a global update for material groups * @return true if successful. */ - public boolean writeMaterialGroup(@NotNull AbstractMaterialGroup group, boolean updatePlanned){ + public static boolean writeMaterialGroup(@NotNull AbstractMaterialGroup group, boolean updatePlanned){ String name = group.getName(); if(name.contains(".")) { CustomAnvil.instance.getLogger().warning("Group " + name +" contain . in its name but should not. this material group is ignored."); @@ -89,7 +91,7 @@ public class MaterialGroupApi { return true; } - private void writeKnownGroup(@NotNull String groupType, @NotNull AbstractMaterialGroup group){ + private static void writeKnownGroup(@NotNull String groupType, @NotNull AbstractMaterialGroup group){ FileConfiguration config = ConfigHolder.ITEM_GROUP_HOLDER.getConfig(); String basePath = group.getName() + "."; @@ -106,7 +108,7 @@ public class MaterialGroupApi { } - private void writeUnknownGroup(@NotNull AbstractMaterialGroup group) { + private static void writeUnknownGroup(@NotNull AbstractMaterialGroup group) { FileConfiguration config = ConfigHolder.ITEM_GROUP_HOLDER.getConfig(); String basePath = group.getName() + "."; @@ -161,7 +163,7 @@ public class MaterialGroupApi { * @return An immutable map of group name as its key and group as mapped value. */ @NotNull - public Map getRegisteredGroups(){ + public static Map getRegisteredGroups(){ return Collections.unmodifiableMap(ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager().getGroupMap()); } From 1bd3328281b0e889de85cc6d608bd32eac5080bd Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Mon, 8 Jul 2024 21:53:19 +0200 Subject: [PATCH 07/18] Update gui on enchantment registering. --- .../alexcrea/cuanvil/api/EnchantmentApi.java | 36 ++++++++++++------- .../enchant/CAEnchantmentRegistry.java | 8 +++-- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java index ae26176..5753d63 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java @@ -8,6 +8,8 @@ import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry; import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity; import xyz.alexcrea.cuanvil.enchant.wrapped.CAVanillaEnchantment; +import xyz.alexcrea.cuanvil.gui.config.global.EnchantCostConfigGui; +import xyz.alexcrea.cuanvil.gui.config.global.EnchantLimitConfigGui; import java.util.Collections; import java.util.Map; @@ -27,7 +29,13 @@ public class EnchantmentApi { * @return True if successful. */ public static boolean registerEnchantment(@NotNull CAEnchantment enchantment){ - return CAEnchantmentRegistry.getInstance().register(enchantment); + if(!CAEnchantmentRegistry.getInstance().register(enchantment)) return false; + + // Add enchantment to gui. + EnchantCostConfigGui.INSTANCE.updateValueForGeneric(enchantment, true); + EnchantLimitConfigGui.INSTANCE.updateValueForGeneric(enchantment, true); + + return true; } /** @@ -56,6 +64,20 @@ public class EnchantmentApi { return registerEnchantment(new CAVanillaEnchantment(enchantment)); } + /** + * Unregister an enchantment. + * + * @param enchantment The enchantment to unregister + * @return True if successful. + */ + public static boolean unregisterEnchantment(@Nullable CAEnchantment enchantment){ + // Remove from gui + EnchantCostConfigGui.INSTANCE.removeGeneric(enchantment); + EnchantLimitConfigGui.INSTANCE.removeGeneric(enchantment); + + return CAEnchantmentRegistry.getInstance().unregister(enchantment); + } + /** * Unregister an enchantment by its key. * @@ -64,17 +86,7 @@ public class EnchantmentApi { */ public static boolean unregisterEnchantment(@NotNull NamespacedKey key){ CAEnchantment enchantment = CAEnchantmentRegistry.getInstance().getByKey(key); - return CAEnchantmentRegistry.getInstance().unregister(enchantment); - } - - /** - * Unregister an enchantment. - * - * @param enchantment The enchantment to unregister - * @return True if successful. - */ - public static boolean unregisterEnchantment(@NotNull CAEnchantment enchantment){ - return CAEnchantmentRegistry.getInstance().unregister(enchantment); + return unregisterEnchantment(enchantment); } /** diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java index abd9bbb..22a0997 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java @@ -89,7 +89,7 @@ public class CAEnchantmentRegistry { * @return If the operation was successful. */ - public boolean unregister(CAEnchantment enchantment){ + public boolean unregister(@Nullable CAEnchantment enchantment){ if(enchantment == null) return false; byKeyMap.remove(enchantment.getKey()); byNameMap.remove(enchantment.getName()); @@ -103,7 +103,8 @@ public class CAEnchantmentRegistry { * @param key Key to fetch. * @return Registered enchantment. null if absent. */ - public @Nullable CAEnchantment getByKey(@NotNull NamespacedKey key){ + @Nullable + public CAEnchantment getByKey(@NotNull NamespacedKey key){ return byKeyMap.get(key); } @@ -112,7 +113,8 @@ public class CAEnchantmentRegistry { * @param name Name to fetch. * @return Registered enchantment. null if absent. */ - public @Nullable CAEnchantment getByName(@NotNull String name){ + @Nullable + public CAEnchantment getByName(@NotNull String name){ return byNameMap.get(name); } From bcd8b6ae6e8c1189e88e01e48966b32ca6c9fc33 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Mon, 8 Jul 2024 23:24:39 +0200 Subject: [PATCH 08/18] =?UTF-8?q?Make=20compatibility=20object=20with=20Ec?= =?UTF-8?q?oEnchant=20and=20Enchant=C2=B2=20use=20the=20api.=20Abstract=20?= =?UTF-8?q?material=20group=20now=20have=20varargs=20"addAll"=20function.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../alexcrea/cuanvil/api/ConflictBuilder.java | 9 ++ .../cuanvil/dependency/DependencyManager.kt | 10 ++ .../dependency/EcoEnchantDependency.kt | 17 +--- .../EnchantmentSquaredDependency.kt | 99 ++++++++----------- .../cuanvil/group/AbstractMaterialGroup.kt | 28 +++++- .../alexcrea/cuanvil/group/ExcludeGroup.kt | 8 +- .../alexcrea/cuanvil/group/IncludeGroup.kt | 8 +- 7 files changed, 100 insertions(+), 79 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java index 2ba973e..fa03b8c 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java @@ -343,4 +343,13 @@ public class ConflictBuilder { return clone; } + /** + * Register this conflict. + * Equivalent to {@link ConflictAPI#addConflict(ConflictBuilder)} + * @return True if successful. + */ + public boolean registerIfAbsent(){ + return ConflictAPI.addConflict(this); + } + } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt index 57e27d7..b86b314 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt @@ -1,10 +1,12 @@ package xyz.alexcrea.cuanvil.dependency import org.bukkit.Bukkit +import org.bukkit.configuration.file.FileConfiguration import org.bukkit.plugin.Plugin import xyz.alexcrea.cuanvil.dependency.protocolib.NoProtocoLib import xyz.alexcrea.cuanvil.dependency.protocolib.PacketManager import xyz.alexcrea.cuanvil.dependency.protocolib.ProtocoLibWrapper +import xyz.alexcrea.cuanvil.enchant.CAEnchantment import java.io.File object DependencyManager { @@ -43,4 +45,12 @@ object DependencyManager { } + fun writeDefaultConfig(defaultConfig: FileConfiguration, enchantment: CAEnchantment) { + defaultConfig["enchant_limits.${enchantment.key.key}"] = enchantment.defaultMaxLevel() + + val rarity = enchantment.defaultRarity() + defaultConfig["enchant_values.${enchantment.key.key}.item"] = rarity.itemValue + defaultConfig["enchant_values.${enchantment.key.key}.book"] = rarity.bookValue + } + } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EcoEnchantDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EcoEnchantDependency.kt index e37237e..8623689 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EcoEnchantDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EcoEnchantDependency.kt @@ -5,10 +5,9 @@ import io.delilaheve.CustomAnvil import org.bukkit.configuration.file.YamlConfiguration import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.plugin.Plugin +import xyz.alexcrea.cuanvil.api.EnchantmentApi import xyz.alexcrea.cuanvil.config.ConfigHolder -import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry -import xyz.alexcrea.cuanvil.enchant.wrapped.CAEcoEnchant import java.io.File class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) { @@ -22,12 +21,9 @@ class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) { } fun registerEnchantments() { - val registery = CAEnchantmentRegistry.getInstance() for (ecoEnchant in EcoEnchants.values()) { - val enchantments: CAEnchantment = CAEcoEnchant(ecoEnchant) - - registery.unregister(registery.getByKey(ecoEnchant.enchantment.key)) // As eco enchants are considered real enchantment, we need to unregister it. - registery.register(enchantments) + EnchantmentApi.unregisterEnchantment(ecoEnchant.enchantment) // As eco enchants is loaded before ca, we need to unregister old "vanilla" enchant. + EnchantmentApi.registerEnchantment(ecoEnchant.enchantment) } } @@ -57,12 +53,7 @@ class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) { doSave = true config[testPath] = true - defaultConfig["enchant_limits.${enchantment.key.key}"] = enchantment.defaultMaxLevel() - - val rarity = enchantment.defaultRarity() - defaultConfig["enchant_values.${enchantment.key.key}.item"] = rarity.itemValue - defaultConfig["enchant_values.${enchantment.key.key}.book"] = rarity.bookValue - + DependencyManager.writeDefaultConfig(defaultConfig, enchantment) } } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt index 15aa46e..2724dd0 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt @@ -3,14 +3,18 @@ package xyz.alexcrea.cuanvil.dependency import io.delilaheve.CustomAnvil import me.athlaeos.enchantssquared.enchantments.CustomEnchant import me.athlaeos.enchantssquared.managers.CustomEnchantManager +import org.bukkit.Material import org.bukkit.NamespacedKey import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.inventory.ItemStack import org.bukkit.plugin.Plugin +import xyz.alexcrea.cuanvil.api.ConflictBuilder +import xyz.alexcrea.cuanvil.api.MaterialGroupApi import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry import xyz.alexcrea.cuanvil.enchant.wrapped.CAEnchantSquaredEnchantment +import xyz.alexcrea.cuanvil.group.IncludeGroup import java.util.* class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin) { @@ -78,11 +82,7 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin) // Write default level limit and xp cost for (enchantment in esEnchantments) { - defaultConfig["enchant_limits.${enchantment.key.key}"] = enchantment.defaultMaxLevel() - - val rarity = enchantment.defaultRarity() - defaultConfig["enchant_values.${enchantment.key.key}.item"] = rarity.itemValue - defaultConfig["enchant_values.${enchantment.key.key}.book"] = rarity.bookValue + DependencyManager.writeDefaultConfig(defaultConfig, enchantment) } // Write groups and conflicts @@ -95,11 +95,6 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin) // Save ConfigHolder.DEFAULT_CONFIG.saveToDisk(true) - ConfigHolder.ITEM_GROUP_HOLDER.saveToDisk(true) - ConfigHolder.CONFLICT_HOLDER.saveToDisk(true) - - // Reload - ConfigHolder.ITEM_GROUP_HOLDER.reload() CustomAnvil.instance.logger.info("Enchantment Squared should now work as expected !") } @@ -107,60 +102,50 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin) private fun writeMissingGroups(){ // Write group that do not exist on custom anvil. // (Tools group regroup most of the tool items. I did not create a seperated group for theses) - val groupConfig = ConfigHolder.ITEM_GROUP_HOLDER.config - if(!groupConfig.isConfigurationSection("pickaxes")){ - groupConfig["pickaxes.type"] = "include" - groupConfig["pickaxes.items"] = listOf("wooden_pickaxe", "stone_pickaxe", "iron_pickaxe", "diamond_pickaxe", "golden_pickaxe", "netherite_pickaxe") - } + val pickaxes = IncludeGroup("pickaxes") + pickaxes.addAll(Material.WOODEN_PICKAXE, Material.STONE_PICKAXE, Material.IRON_PICKAXE, Material.DIAMOND_PICKAXE, Material.GOLDEN_PICKAXE, Material.NETHERITE_PICKAXE) + MaterialGroupApi.addMaterialGroup(pickaxes) - if(!groupConfig.isConfigurationSection("shovels")){ - groupConfig["shovels.type"] = "include" - groupConfig["shovels.items"] = listOf("wooden_shovel", "stone_shovel", "iron_shovel", "diamond_shovel", "golden_shovel", "netherite_shovel") - } + val shovels = IncludeGroup("shovels") + shovels.addAll(Material.WOODEN_SHOVEL, Material.STONE_SHOVEL, Material.IRON_SHOVEL, Material.DIAMOND_SHOVEL, Material.GOLDEN_SHOVEL, Material.NETHERITE_SHOVEL) + MaterialGroupApi.addMaterialGroup(shovels) - if(!groupConfig.isConfigurationSection("hoes")){ - groupConfig["hoes.type"] = "include" - groupConfig["hoes.items"] = listOf("wooden_hoe", "stone_hoe", "iron_hoe", "diamond_hoe", "golden_hoe", "netherite_hoe") - } + val hoes = IncludeGroup("hoes") + hoes.addAll(Material.WOODEN_HOE, Material.STONE_HOE, Material.IRON_HOE, Material.DIAMOND_HOE, Material.GOLDEN_HOE, Material.NETHERITE_HOE) + MaterialGroupApi.addMaterialGroup(hoes) - if(!groupConfig.isConfigurationSection("shield")){ - groupConfig["shield.type"] = "include" - groupConfig["shield.items"] = listOf("shield") - } + val shield = IncludeGroup("shield") + hoes.addToPolicy(Material.SHIELD) + MaterialGroupApi.addMaterialGroup(shield) - if(!groupConfig.isConfigurationSection("elytra")){ - groupConfig["elytra.type"] = "include" - groupConfig["elytra.items"] = listOf("elytra") - } + val elytra = IncludeGroup("elytra") + hoes.addToPolicy(Material.ELYTRA) + MaterialGroupApi.addMaterialGroup(elytra) - if(!groupConfig.isConfigurationSection("trinkets")){ - groupConfig["trinkets.type"] = "include" - groupConfig["trinkets.items"] = listOf("rotten_flesh") - } + val trinkets = IncludeGroup("trinkets") + hoes.addToPolicy(Material.ROTTEN_FLESH) + MaterialGroupApi.addMaterialGroup(trinkets) } private fun writeMaterialRestriction(esEnchantments: List){ - val conflictConfig = ConfigHolder.CONFLICT_HOLDER.config for (enchantment in esEnchantments) { - val restrictionName = "restriction_${enchantment.key.key}" - if(!conflictConfig.isConfigurationSection(restrictionName)){ - conflictConfig["$restrictionName.enchantments"] = listOf(enchantment.name) + val conflict = ConflictBuilder("restriction_${enchantment.key.key}") - // Get allowed groups - val listOfAllowed = ArrayList() - listOfAllowed.add("enchanted_book") // enchanted book is allowed in any case. + // enchanted book is allowed in any case. + conflict.addExcludedGroup("enchanted_book") - for (esGroup in enchantment.enchant.compatibleItems) { - val caGroup = esGroupToCAGroup(esGroup) - if(caGroup == null){ - CustomAnvil.instance.logger.info("Could not find equivalent custom anvil group for $esGroup") - continue - } - listOfAllowed.add(caGroup) + // Get allowed groups + for (esGroup in enchantment.enchant.compatibleItems) { + val caGroup = esGroupToCAGroup(esGroup) + if(caGroup == null){ + CustomAnvil.instance.logger.info("Could not find equivalent custom anvil group for $esGroup") + continue } - conflictConfig["$restrictionName.notAffectedGroups"] = listOfAllowed + conflict.addExcludedGroup(caGroup) } + + conflict.registerIfAbsent() } } @@ -181,18 +166,12 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin) } private fun writeConflict(enchantment1: CAEnchantment, enchantment2: CAEnchantment){ - val conflictConfig = ConfigHolder.CONFLICT_HOLDER.config - val conflictPath = "${enchantment1.name}_with_${enchantment2.name}_conflict" + val conflict = ConflictBuilder("${enchantment1.name}_with_${enchantment2.name}_conflict") - if(!conflictConfig.isConfigurationSection(conflictPath)){ - conflictConfig["$conflictPath.enchantments"] = listOf(enchantment1.name, enchantment2.name) - - val empty: List = Collections.emptyList() - conflictConfig["$conflictPath.notAffectedGroups"] = empty - - conflictConfig["$conflictPath.maxEnchantmentBeforeConflict"] = 1 - } + conflict.addEnchantment(enchantment1).addEnchantment(enchantment2) + conflict.setMaxBeforeConflict(1); + conflict.registerIfAbsent() } /** diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/group/AbstractMaterialGroup.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/group/AbstractMaterialGroup.kt index 289f058..ec6e7bc 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/group/AbstractMaterialGroup.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/group/AbstractMaterialGroup.kt @@ -25,13 +25,37 @@ abstract class AbstractMaterialGroup(private val name: String) { /** * Push a material to this group to follow this group policy + * @return this instance. */ - abstract fun addToPolicy(mat: Material) + abstract fun addToPolicy(mat: Material): AbstractMaterialGroup + + /** + * Push a list of material to this group to follow this group policy + * @return this instance. + */ + fun addAll(vararg materials: Material): AbstractMaterialGroup { + for (material in materials) { + addToPolicy(material) + } + return this + } /** * Push a group to this group to follow this group policy + * @return this instance. */ - abstract fun addToPolicy(other: AbstractMaterialGroup) + abstract fun addToPolicy(other: AbstractMaterialGroup): AbstractMaterialGroup + + /** + * Push a list of group to this group to follow this group policy + * @return this instance. + */ + fun addAll(vararg otherList: AbstractMaterialGroup): AbstractMaterialGroup { + for (group in otherList) { + addToPolicy(group) + } + return this + } /** * Get the group contained material as a set diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/group/ExcludeGroup.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/group/ExcludeGroup.kt index 247cb83..7684c3f 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/group/ExcludeGroup.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/group/ExcludeGroup.kt @@ -20,14 +20,18 @@ class ExcludeGroup(name: String) : AbstractMaterialGroup(name) { return false } - override fun addToPolicy(mat: Material) { + override fun addToPolicy(mat: Material): ExcludeGroup { includedMaterial.remove(mat) groupItems.remove(mat) + + return this } - override fun addToPolicy(other: AbstractMaterialGroup) { + override fun addToPolicy(other: AbstractMaterialGroup): ExcludeGroup { includedGroup.add(other) groupItems.removeAll(other.getMaterials()) + + return this } override fun setGroups(groups: MutableSet) { diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/group/IncludeGroup.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/group/IncludeGroup.kt index 968ceb1..848789f 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/group/IncludeGroup.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/group/IncludeGroup.kt @@ -20,14 +20,18 @@ class IncludeGroup(name: String) : AbstractMaterialGroup(name) { return false } - override fun addToPolicy(mat: Material) { + override fun addToPolicy(mat: Material): IncludeGroup { includedMaterial.add(mat) groupItems.add(mat) + + return this } - override fun addToPolicy(other: AbstractMaterialGroup) { + override fun addToPolicy(other: AbstractMaterialGroup): IncludeGroup { includedGroup.add(other) groupItems.addAll(other.getMaterials()) + + return this } override fun setGroups(groups: MutableSet) { From a40d2c6530de75044cec3c9b2c6e91abc32f3d37 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Tue, 9 Jul 2024 13:56:19 +0200 Subject: [PATCH 09/18] Added custom anvil recipe api & builder. Fixed Conflict not being registered. Build conflict on the builder instance instead of the ConflictAPI class. --- .../cuanvil/api/AnvilRecipeBuilder.java | 205 ++++++++++++++++++ .../xyz/alexcrea/cuanvil/api/ConflictAPI.java | 83 +------ .../alexcrea/cuanvil/api/ConflictBuilder.java | 75 ++++++- .../cuanvil/api/CustomAnvilRecipeApi.java | 82 +++++++ .../EnchantmentSquaredDependency.kt | 2 +- .../cuanvil/recipe/AnvilCustomRecipe.kt | 21 +- 6 files changed, 386 insertions(+), 82 deletions(-) create mode 100644 src/main/java/xyz/alexcrea/cuanvil/api/AnvilRecipeBuilder.java create mode 100644 src/main/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApi.java diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/AnvilRecipeBuilder.java b/src/main/java/xyz/alexcrea/cuanvil/api/AnvilRecipeBuilder.java new file mode 100644 index 0000000..74e8118 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/api/AnvilRecipeBuilder.java @@ -0,0 +1,205 @@ +package xyz.alexcrea.cuanvil.api; + +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe; + +/** + * A Builder for custom craft using anvil. + */ +@SuppressWarnings("unused") +public class AnvilRecipeBuilder { + + private @NotNull String name; + private boolean exactCount; + + private int xpCostPerCraft; + + private @Nullable ItemStack leftItem; + private @Nullable ItemStack rightItem; + private @Nullable ItemStack resultItem; + + /** + * Instantiates a new Anvil recipe builder. + * exact count default to true. + * xp cost per craft default to 1. + * + * @param name The recipe name + */ + public AnvilRecipeBuilder(@NotNull String name) { + this.name = name; + + this.exactCount = true; + this.xpCostPerCraft = 1; + + this.leftItem = null; + this.rightItem = null; + this.resultItem = null; + } + + /** + * Gets the recipe name. + * + * @return This recipe builder instance. + */ + @NotNull + public String getName() { + return name; + } + + /** + * Sets the recipe name. + * + * @param name The recipe name + * @return This recipe builder instance. + */ + public AnvilRecipeBuilder setName(String name) { + this.name = name; + return this; + } + + /** + * Get if the recipe is exact count. + *

+ * Exact count mean the recipe can only be crafted 1 by 1. + * If set to false, then it will craft as much as possible in 1 go and will keep unused material onto the anvil inventory. + * + * @return If the recipe is exact count. + */ + public boolean isExactCount() { + return exactCount; + } + + /** + * Sets if the recipe is exact count. + *

+ * Exact count mean the recipe can only be crafted 1 by 1. + * If set to false, then it will craft as much as possible in 1 go and will keep unused material onto the anvil inventory. + * + * @param exactCount If the recipe is exact count + * @return This recipe builder instance. + */ + public AnvilRecipeBuilder setExactCount(boolean exactCount) { + this.exactCount = exactCount; + return this; + } + + /** + * Get the xp level cost per craft. + * + * @return The xp level cost per craft + */ + public int getXpCostPerCraft() { + return xpCostPerCraft; + } + + /** + * Sets the xp level cost per craft. + * + * @param xpCostPerCraft The xp level cost per craft + * @return This recipe builder instance. + */ + public AnvilRecipeBuilder setXpCostPerCraft(int xpCostPerCraft) { + this.xpCostPerCraft = xpCostPerCraft; + return this; + } + + /** + * Get the left item of the recipe. + * If null (default) then the recipe will not be able to be registered. + * + * @return The left item + */ + @Nullable + public ItemStack getLeftItem() { + return leftItem; + } + + /** + * Set the left item. + * If null (default) then the recipe will not be able to be registered. + * + * @param leftItem the left item + * @return This recipe builder instance. + */ + public AnvilRecipeBuilder setLeftItem(ItemStack leftItem) { + this.leftItem = leftItem; + return this; + } + + /** + * Get the recipe right item. + * null on default new instance. + * + * @return The right item + */ + @Nullable + public ItemStack getRightItem() { + return rightItem; + } + + /** + * Set the recipe right item. + * null on default new instance. + * + * @param rightItem the right item + * @return This recipe builder instance. + */ + public AnvilRecipeBuilder setRightItem(ItemStack rightItem) { + this.rightItem = rightItem; + return this; + } + + /** + * Get the recipe result item. + * If null (default) then the recipe will not be able to be registered. + * + * @return The result item + */ + @Nullable + public ItemStack getResultItem() { + return resultItem; + } + + /** + * Set the recipe result item. + * If null (default) then the recipe will not be able to be registered. + * + * @param resultItem The result item + * @return This recipe builder instance. + */ + public AnvilRecipeBuilder setResultItem(ItemStack resultItem) { + this.resultItem = resultItem; + return this; + } + + /** + * Build the anvil custom recipe. + * Should probably use {@link #registerIfAbsent() registerIfAbsent} or {@link ConflictAPI#addConflict(ConflictBuilder) addConflict}. + * + * @return A new anvil custom recipe base on this builder. + */ + @Nullable // null if missing argument + public AnvilCustomRecipe build() { + if(leftItem == null || rightItem == null) return null; + + return new AnvilCustomRecipe( + this.name, + this.exactCount, + this.xpCostPerCraft, + this.leftItem, this.rightItem, this.resultItem + ); + } + + /** + * Register this recipe if absent. + * Equivalent to {@link ConflictAPI#addConflict(ConflictBuilder)} + * + * @return True if successful. + */ + public boolean registerIfAbsent(){ + return CustomAnvilRecipeApi.addRecipe(this); + } + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java index 0444403..bab98b8 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java @@ -5,10 +5,8 @@ import org.bukkit.Bukkit; import org.bukkit.NamespacedKey; import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.config.ConfigHolder; -import xyz.alexcrea.cuanvil.enchant.CAEnchantment; -import xyz.alexcrea.cuanvil.group.*; +import xyz.alexcrea.cuanvil.group.EnchantConflictGroup; import xyz.alexcrea.cuanvil.gui.config.global.EnchantConflictGui; import java.util.Collections; @@ -31,7 +29,7 @@ public class ConflictAPI { * Write and add a conflict. * Will not write the conflict if it already exists. * - * @param builder The conflict builder to base on + * @param builder The conflict builder to be based on * @return True if successful. */ public static boolean addConflict(@NotNull ConflictBuilder builder){ @@ -40,75 +38,17 @@ public class ConflictAPI { if(!writeConflict(builder, false)) return false; - AbstractMaterialGroup materials = extractGroup(builder); - EnchantConflictGroup conflict = new EnchantConflictGroup(builder.getName(), materials, builder.getMaxBeforeConflict()); - appendEnchantments(builder, conflict); + EnchantConflictGroup conflict = builder.build(); + // Register conflict + ConfigHolder.CONFLICT_HOLDER.getConflictManager().getConflictList().add(conflict); + + // Add conflict to gui EnchantConflictGui.INSTANCE.updateValueForGeneric(conflict, true); return true; } - /** - * Append builders stored enchantments into conflict. - * - * @param builder The builder source - * @param conflict The conflict target - */ - protected static void appendEnchantments(@NotNull ConflictBuilder builder, @NotNull EnchantConflictGroup conflict){ - for (String enchantmentName : builder.getEnchantmentNames()){ - if(appendEnchantment(conflict, EnchantmentApi.getByName(enchantmentName))){ - CustomAnvil.instance.getLogger().warning("Could not find enchantment " + enchantmentName + " for conflict " + builder.getName()); - logConflictOrigin(builder); - } - } - for (NamespacedKey enchantmentKey : builder.getEnchantmentKeys()){ - if(!appendEnchantment(conflict, EnchantmentApi.getByKey(enchantmentKey))){ - CustomAnvil.instance.getLogger().warning("Could not find enchantment " + enchantmentKey + " for conflict " + builder.getName()); - logConflictOrigin(builder); - } - } - } - - /** - * Append an enchantment. - * - * @param conflict The conflict target - * @param enchantment The enchantment - * @return True if successful. - */ - protected static boolean appendEnchantment(@NotNull EnchantConflictGroup conflict, @Nullable CAEnchantment enchantment){ - if(enchantment == null) - return false; - conflict.addEnchantment(enchantment); - return true; - } - - /** - * Extract group abstract material group. - * - * @param builder The builder source - * @return The abstract material group from the builder. - */ - protected static AbstractMaterialGroup extractGroup(@NotNull ConflictBuilder builder){ - ItemGroupManager itemGroupManager = ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager(); - IncludeGroup group = new IncludeGroup(EnchantConflictManager.DEFAULT_GROUP_NAME); - - for (String groupName : builder.getExcludedGroupNames()) { - AbstractMaterialGroup materialGroup = itemGroupManager.get(groupName); - - if(materialGroup == null){ - CustomAnvil.instance.getLogger().warning("Material group " + groupName + " do not exist but is ask by conflict " + builder.getName()); - logConflictOrigin(builder); - continue; - } - - group.addToPolicy(materialGroup); - } - - return group; - } - /** * Write a conflict to the config file and plan an update of conflicts. *

@@ -135,7 +75,7 @@ public class ConflictAPI { String name = builder.getName(); if(name.contains(".")) { - CustomAnvil.instance.getLogger().warning("Conflict " + name +" contain . in its name but should not. this conflict is ignored."); + CustomAnvil.instance.getLogger().warning("Conflict " + name +" contain \".\" in its name but should not. this conflict is ignored."); logConflictOrigin(builder); return false; } @@ -170,8 +110,9 @@ public class ConflictAPI { return result; } + /** - * Prepare a task to reload every conflict. + * Prepare a task to save conflict configuration. */ private static void prepareSaveTask() { if(saveChangeTask != -1) return; @@ -183,7 +124,7 @@ public class ConflictAPI { } /** - * Prepare a task to save configuration. + * Prepare a task to reload every conflict. */ private static void prepareUpdateTask() { if(reloadChangeTask != -1) return; @@ -196,7 +137,7 @@ public class ConflictAPI { } - private static void logConflictOrigin(@NotNull ConflictBuilder builder){ + static void logConflictOrigin(@NotNull ConflictBuilder builder){ CustomAnvil.instance.getLogger().warning("Conflict " + builder.getName() +" came from " + builder.getSourceName() + "."); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java index fa03b8c..2786dd9 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java @@ -1,11 +1,13 @@ package xyz.alexcrea.cuanvil.api; +import io.delilaheve.CustomAnvil; import org.bukkit.NamespacedKey; import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.enchant.CAEnchantment; -import xyz.alexcrea.cuanvil.group.AbstractMaterialGroup; +import xyz.alexcrea.cuanvil.group.*; import java.util.HashSet; import java.util.Set; @@ -342,9 +344,20 @@ public class ConflictBuilder { return clone; } + /** + * Build a new Enchant conflict group by this builder. + * @return An Enchant conflict group with this builder parameters. + */ + public EnchantConflictGroup build(){ + AbstractMaterialGroup materials = extractGroups(); + EnchantConflictGroup conflict = new EnchantConflictGroup(getName(), materials, getMaxBeforeConflict()); + appendEnchantments(conflict); + + return conflict; + } /** - * Register this conflict. + * Register this conflict if not yet registered. * Equivalent to {@link ConflictAPI#addConflict(ConflictBuilder)} * @return True if successful. */ @@ -352,4 +365,62 @@ public class ConflictBuilder { return ConflictAPI.addConflict(this); } + /** + * Append builders stored enchantments into conflict. + * + * @param conflict The conflict target + */ + protected void appendEnchantments(@NotNull EnchantConflictGroup conflict){ + for (String enchantmentName : getEnchantmentNames()){ + if(appendEnchantment(conflict, EnchantmentApi.getByName(enchantmentName))){ + CustomAnvil.instance.getLogger().warning("Could not find enchantment " + enchantmentName + " for conflict " + getName()); + ConflictAPI.logConflictOrigin(this); + } + } + for (NamespacedKey enchantmentKey : getEnchantmentKeys()){ + if(!appendEnchantment(conflict, EnchantmentApi.getByKey(enchantmentKey))){ + CustomAnvil.instance.getLogger().warning("Could not find enchantment " + enchantmentKey + " for conflict " + getName()); + ConflictAPI.logConflictOrigin(this); + } + } + } + + /** + * Append an enchantment. + * + * @param conflict The conflict target + * @param enchantment The enchantment + * @return True if successful. + */ + protected static boolean appendEnchantment(@NotNull EnchantConflictGroup conflict, @Nullable CAEnchantment enchantment){ + if(enchantment == null) + return false; + conflict.addEnchantment(enchantment); + return true; + } + + /** + * Extract group abstract material group. + * + * @return The abstract material group from the builder. + */ + protected AbstractMaterialGroup extractGroups(){ + ItemGroupManager itemGroupManager = ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager(); + IncludeGroup group = new IncludeGroup(EnchantConflictManager.DEFAULT_GROUP_NAME); + + for (String groupName : getExcludedGroupNames()) { + AbstractMaterialGroup materialGroup = itemGroupManager.get(groupName); + + if(materialGroup == null){ + CustomAnvil.instance.getLogger().warning("Material group " + groupName + " do not exist but is ask by conflict " + getName()); + ConflictAPI.logConflictOrigin(this); + continue; + } + + group.addToPolicy(materialGroup); + } + + return group; + } + } diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApi.java new file mode 100644 index 0000000..01682e6 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApi.java @@ -0,0 +1,82 @@ +package xyz.alexcrea.cuanvil.api; + +import io.delilaheve.CustomAnvil; +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.FileConfiguration; +import org.jetbrains.annotations.NotNull; +import xyz.alexcrea.cuanvil.config.ConfigHolder; +import xyz.alexcrea.cuanvil.gui.config.global.CustomRecipeConfigGui; +import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe; + +import java.util.Collections; +import java.util.List; + +@SuppressWarnings("unused") +public class CustomAnvilRecipeApi { + + private CustomAnvilRecipeApi(){} + + private static int saveChangeTask = -1; + + /** + * Write and add a custom anvil recipe. + * Will not write the recipe if it already exists. + * + * @param builder The recipe builder to be based on + * @return True if successful. + */ + public static boolean addRecipe(@NotNull AnvilRecipeBuilder builder){ + FileConfiguration config = ConfigHolder.CUSTOM_RECIPE_HOLDER.getConfig(); + String name = builder.getName(); + + if(config.contains(builder.getName())) return false; + if(builder.getName().contains(".")) { + CustomAnvil.instance.getLogger().warning("Custom anvil recipe " + name + " contain \".\" in its name but should not. this recipe is ignored."); + return false; + } + + AnvilCustomRecipe recipe = builder.build(); + if(recipe == null){ + CustomAnvil.instance.getLogger().warning("Custom anvil recipe " + name + " could not be parsed."); + if(builder.getLeftItem() == null){ + CustomAnvil.instance.getLogger().warning("It look like left item of the recipe is null."); + } + if(builder.getResultItem() == null){ + CustomAnvil.instance.getLogger().warning("It look like result item of the recipe is null."); + } + return false; + } + + // Save to file + recipe.saveToFile(false, false); + prepareSaveTask(); + + // Update gui + CustomRecipeConfigGui.INSTANCE.updateValueForGeneric(recipe, true); + + return true; + } + + /** + * Prepare a task to save custom recipe configuration. + */ + private static void prepareSaveTask() { + if(saveChangeTask != -1) return; + + saveChangeTask = Bukkit.getScheduler().scheduleSyncDelayedTask(CustomAnvil.instance, ()->{ + ConfigHolder.CONFLICT_HOLDER.saveToDisk(true); + saveChangeTask = -1; + }, 0L); + } + + /** + * Get every registered recipes. + * @return An immutable collection of recipes. + */ + @NotNull + public static List getRegisteredRecipes(){ + List mutableList = ConfigHolder.CUSTOM_RECIPE_HOLDER.getRecipeManager().getRecipeList(); + return Collections.unmodifiableList(mutableList); + } + +} diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt index 2724dd0..c303e34 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt @@ -170,7 +170,7 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin) conflict.addEnchantment(enchantment1).addEnchantment(enchantment2) - conflict.setMaxBeforeConflict(1); + conflict.setMaxBeforeConflict(1) conflict.registerIfAbsent() } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt index c7e3038..801a077 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt @@ -74,25 +74,30 @@ class AnvilCustomRecipe( } - fun saveToFile(){ + fun saveToFile(writeFile: Boolean, doBackup: Boolean){ val fileConfig = ConfigHolder.CUSTOM_RECIPE_HOLDER.config - fileConfig.set("$name.$EXACT_COUNT_CONFIG", exactCount) + fileConfig["$name.$EXACT_COUNT_CONFIG"] = exactCount //fileConfig.set("$name.$EXACT_LEFT_CONFIG", exactLeft) //fileConfig.set("$name.$EXACT_RIGHT_CONFIG", exactRight) - fileConfig.set("$name.$XP_COST_CONFIG", xpCostPerCraft) + fileConfig["$name.$XP_COST_CONFIG"] = xpCostPerCraft - fileConfig.set("$name.$LEFT_ITEM_CONFIG", leftItem) - fileConfig.set("$name.$RIGHT_ITEM_CONFIG", rightItem) - fileConfig.set("$name.$RESULT_ITEM_CONFIG", resultItem) + fileConfig["$name.$LEFT_ITEM_CONFIG"] = leftItem + fileConfig["$name.$RIGHT_ITEM_CONFIG"] = rightItem + fileConfig["$name.$RESULT_ITEM_CONFIG"] = resultItem - if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) { - ConfigHolder.CUSTOM_RECIPE_HOLDER.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE) + if (writeFile) { + ConfigHolder.CUSTOM_RECIPE_HOLDER.saveToDisk(doBackup) } } + @Deprecated("Should use saveToFile(Boolean, Boolean) instead") //TODO determine when an where to save/do backup and remove use of variable like TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE + fun saveToFile(){ + saveToFile(GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE, GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE) + } + fun updateFromFile(){ this.exactCount = ConfigHolder.CUSTOM_RECIPE_HOLDER.config.getBoolean( "$name.$EXACT_COUNT_CONFIG", From 6f1e53f68ec385d1d9bce8abfeb62b3fa7ac0be2 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Tue, 9 Jul 2024 20:21:36 +0200 Subject: [PATCH 10/18] Fix Custom Recipe not being registered. Fix conflict from api not working. Add remove api for custom recipe, material group and conflict. --- build.gradle.kts | 1 + .../xyz/alexcrea/cuanvil/api/ConflictAPI.java | 21 +++++++++++++- .../cuanvil/api/CustomAnvilRecipeApi.java | 28 ++++++++++++++++++- .../cuanvil/api/MaterialGroupApi.java | 24 ++++++++++++++++ .../EnchantConflictSubSettingGui.java | 5 +--- .../cuanvil/group/EnchantConflictGroup.kt | 2 +- .../cuanvil/group/EnchantConflictManager.kt | 20 +++++++++++-- .../cuanvil/recipe/AnvilCustomRecipe.kt | 2 +- 8 files changed, 93 insertions(+), 10 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index fc654d2..ab22355 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,7 @@ plugins { kotlin("jvm") version "1.9.24" java + id("org.jetbrains.dokka").version("1.9.20") id("com.github.johnrengelman.shadow").version("7.1.2") } diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java index bab98b8..4bdb6d2 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java @@ -41,7 +41,7 @@ public class ConflictAPI { EnchantConflictGroup conflict = builder.build(); // Register conflict - ConfigHolder.CONFLICT_HOLDER.getConflictManager().getConflictList().add(conflict); + ConfigHolder.CONFLICT_HOLDER.getConflictManager().addConflict(conflict); // Add conflict to gui EnchantConflictGui.INSTANCE.updateValueForGeneric(conflict, true); @@ -110,6 +110,25 @@ public class ConflictAPI { return result; } + /** + * Remove a conflict. + * + * @param conflict The conflict to remove + * @return True if successful. + */ + public static boolean removeConflict(@NotNull EnchantConflictGroup conflict){ + // Remove from registry + ConfigHolder.CONFLICT_HOLDER.getConflictManager().removeConflict(conflict); + + // Write as null and save to file + ConfigHolder.CONFLICT_HOLDER.getConfig().set(conflict.getName(), null); + prepareSaveTask(); + + // Remove from gui + EnchantConflictGui.INSTANCE.removeGeneric(conflict); + + return true; + } /** * Prepare a task to save conflict configuration. diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApi.java index 01682e6..69bfad2 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApi.java @@ -11,6 +11,9 @@ import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe; import java.util.Collections; import java.util.List; +/** + * Custom Anvil api for custom anvil recipes. + */ @SuppressWarnings("unused") public class CustomAnvilRecipeApi { @@ -47,16 +50,39 @@ public class CustomAnvilRecipeApi { return false; } + // Add to registry + ConfigHolder.CUSTOM_RECIPE_HOLDER.getRecipeManager().cleanAddNew(recipe); + // Save to file recipe.saveToFile(false, false); prepareSaveTask(); - // Update gui + // Add from gui CustomRecipeConfigGui.INSTANCE.updateValueForGeneric(recipe, true); return true; } + /** + * Remove a custom anvil recipe. + * + * @param recipe The recipe to remove + * @return True if successful. + */ + public static boolean removeRecipe(@NotNull AnvilCustomRecipe recipe){ + // Remove from registry + ConfigHolder.CUSTOM_RECIPE_HOLDER.getRecipeManager().cleanRemove(recipe); + + // Write as null and save to file + ConfigHolder.CUSTOM_RECIPE_HOLDER.getConfig().set(recipe.getName(), null); + prepareSaveTask(); + + // Remove from gui + CustomRecipeConfigGui.INSTANCE.removeGeneric(recipe); + + return true; + } + /** * Prepare a task to save custom recipe configuration. */ diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java index 76030a8..769b0bf 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java @@ -121,6 +121,30 @@ public class MaterialGroupApi { } + /** + * Remove a material group. + * Caution ! It will not be removed from depending conflict or other material group at runtime. + * For that reason, it is not recommended to use this function. + * + * @param group The recipe to remove + * @return True if successful. + */ + public static boolean removeGroup(@NotNull AbstractMaterialGroup group){ + // Remove from registry + ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager().groupMap.remove(group.getName()); + + // Write as null and save to file + ConfigHolder.ITEM_GROUP_HOLDER.getConfig().set(group.getName(), null); + prepareSaveTask(); + + // Remove from gui + if(group instanceof IncludeGroup includeGroup){ + GroupConfigGui.INSTANCE.removeGeneric(includeGroup); + } + + return true; + } + /** * Prepare a task to reload every conflict. */ diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/EnchantConflictSubSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/EnchantConflictSubSettingGui.java index 8c17f39..56c4420 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/EnchantConflictSubSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/EnchantConflictSubSettingGui.java @@ -118,10 +118,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl EnchantConflictManager manager = ConfigHolder.CONFLICT_HOLDER.getConflictManager(); // Remove from enchantment - for (CAEnchantment enchantment : this.enchantConflict.getEnchants()) { - enchantment.removeConflict(this.enchantConflict); - } - manager.conflictList.remove(this.enchantConflict); + manager.removeConflict(this.enchantConflict); // Remove from parent this.parent.removeGeneric(this.enchantConflict); diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictGroup.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictGroup.kt index be8d085..c58c6bf 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictGroup.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictGroup.kt @@ -5,7 +5,7 @@ import org.bukkit.Material import xyz.alexcrea.cuanvil.enchant.CAEnchantment class EnchantConflictGroup( - private val name: String, + val name: String, private val cantConflict: AbstractMaterialGroup, var minBeforeBlock: Int ) { diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt index 2ff60a7..dbe2374 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt @@ -52,12 +52,21 @@ class EnchantConflictManager { val section = config.getConfigurationSection(key)!! val conflict = createConflict(section, itemManager, key) - addConflictToEnchantments(conflict) - conflictList.add(conflict) + addConflict(conflict) } } + fun addConflict(conflict: EnchantConflictGroup){ + addConflictToEnchantments(conflict) + conflictList.add(conflict) + } + + fun removeConflict(conflict: EnchantConflictGroup){ + removeConflictFromEnchantments(conflict) + conflictList.remove(conflict) + } + // Add the conflict to enchantments private fun addConflictToEnchantments(conflict: EnchantConflictGroup) { conflict.getEnchants().forEach { enchant -> @@ -65,6 +74,13 @@ class EnchantConflictManager { } } + // Remove the conflict from enchantments + private fun removeConflictFromEnchantments(conflict: EnchantConflictGroup) { + conflict.getEnchants().forEach { enchant -> + enchant.removeConflict(conflict) + } + } + // create and read a conflict from a yaml section private fun createConflict( section: ConfigurationSection, diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt index 801a077..114dbe3 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt @@ -7,7 +7,7 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant class AnvilCustomRecipe( - private val name: String, + val name: String, var exactCount: Boolean, //var exactLeft: Boolean, //var exactRight: Boolean, From 365d0ea847af7c3a430f8e932fa01ee5ef5a1327 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Tue, 9 Jul 2024 21:21:10 +0200 Subject: [PATCH 11/18] Dependency enchantment registering now use the api. --- .../enchant/CAEnchantmentRegistry.java | 8 ----- .../gui/config/global/EnchantConflictGui.java | 2 +- src/main/kotlin/io/delilaheve/CustomAnvil.kt | 29 +++++++++---------- .../cuanvil/dependency/DependencyManager.kt | 8 ++++- .../dependency/EcoEnchantDependency.kt | 2 +- .../EnchantmentSquaredDependency.kt | 9 ++---- 6 files changed, 25 insertions(+), 33 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java index 22a0997..94c0f24 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java @@ -5,7 +5,6 @@ import org.bukkit.NamespacedKey; import org.bukkit.enchantments.Enchantment; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import xyz.alexcrea.cuanvil.dependency.DependencyManager; import xyz.alexcrea.cuanvil.enchant.wrapped.CAVanillaEnchantment; import java.util.*; @@ -38,13 +37,6 @@ public class CAEnchantmentRegistry { register(new CAVanillaEnchantment(enchantment)); } - if(DependencyManager.INSTANCE.getEnchantmentSquaredCompatibility() != null){ - DependencyManager.INSTANCE.getEnchantmentSquaredCompatibility().registerEnchantments(); - } - if(DependencyManager.INSTANCE.getEcoEnchantCompatibility() != null){ - DependencyManager.INSTANCE.getEcoEnchantCompatibility().registerEnchantments(); - } - } /** diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java index 1526908..c4181df 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java @@ -36,7 +36,7 @@ public class EnchantConflictGui extends MappedGuiListConfigGui Date: Wed, 10 Jul 2024 14:26:55 +0200 Subject: [PATCH 12/18] Add event for external enchantment and config registering. Fix startup. --- .../alexcrea/cuanvil/api/EnchantmentApi.java | 16 ++++-- .../cuanvil/api/event/CAConfigReadyEvent.java | 19 +++++++ .../event/CAEnchantRegistryReadyEvent.java | 18 ++++++ .../cuanvil/gui/config/MainConfigGui.java | 4 +- .../gui/config/global/BasicConfigGui.java | 6 +- .../config/global/EnchantCostConfigGui.java | 12 ++-- .../config/global/EnchantLimitConfigGui.java | 12 ++-- src/main/kotlin/io/delilaheve/CustomAnvil.kt | 57 ++++++++++++------- .../cuanvil/command/ReloadExecutor.kt | 4 +- 9 files changed, 108 insertions(+), 40 deletions(-) create mode 100644 src/main/java/xyz/alexcrea/cuanvil/api/event/CAConfigReadyEvent.java create mode 100644 src/main/java/xyz/alexcrea/cuanvil/api/event/CAEnchantRegistryReadyEvent.java diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java index 5753d63..57c3aa8 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java @@ -32,8 +32,12 @@ public class EnchantmentApi { if(!CAEnchantmentRegistry.getInstance().register(enchantment)) return false; // Add enchantment to gui. - EnchantCostConfigGui.INSTANCE.updateValueForGeneric(enchantment, true); - EnchantLimitConfigGui.INSTANCE.updateValueForGeneric(enchantment, true); + if(EnchantCostConfigGui.getInstance() != null){ + EnchantCostConfigGui.getInstance().updateValueForGeneric(enchantment, true); + } + if(EnchantLimitConfigGui.getInstance() != null){ + EnchantLimitConfigGui.getInstance().updateValueForGeneric(enchantment, true); + } return true; } @@ -72,8 +76,12 @@ public class EnchantmentApi { */ public static boolean unregisterEnchantment(@Nullable CAEnchantment enchantment){ // Remove from gui - EnchantCostConfigGui.INSTANCE.removeGeneric(enchantment); - EnchantLimitConfigGui.INSTANCE.removeGeneric(enchantment); + if(EnchantCostConfigGui.getInstance() != null){ + EnchantCostConfigGui.getInstance().removeGeneric(enchantment); + } + if(EnchantLimitConfigGui.getInstance() != null){ + EnchantLimitConfigGui.getInstance().removeGeneric(enchantment); + } return CAEnchantmentRegistry.getInstance().unregister(enchantment); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/event/CAConfigReadyEvent.java b/src/main/java/xyz/alexcrea/cuanvil/api/event/CAConfigReadyEvent.java new file mode 100644 index 0000000..24691db --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/api/event/CAConfigReadyEvent.java @@ -0,0 +1,19 @@ +package xyz.alexcrea.cuanvil.api.event; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class CAConfigReadyEvent extends Event { + + private static final HandlerList HANDLERS = new HandlerList(); + + public static HandlerList getHandlerList() { + return HANDLERS; + } + + @Override + public HandlerList getHandlers() { + return HANDLERS; + } + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/event/CAEnchantRegistryReadyEvent.java b/src/main/java/xyz/alexcrea/cuanvil/api/event/CAEnchantRegistryReadyEvent.java new file mode 100644 index 0000000..3e2fdf8 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/api/event/CAEnchantRegistryReadyEvent.java @@ -0,0 +1,18 @@ +package xyz.alexcrea.cuanvil.api.event; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class CAEnchantRegistryReadyEvent extends Event { + + private static final HandlerList HANDLERS = new HandlerList(); + + public static HandlerList getHandlerList() { + return HANDLERS; + } + + @Override + public HandlerList getHandlers() { + return HANDLERS; + } +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java index 44617f0..b6c1062 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java @@ -58,7 +58,7 @@ public class MainConfigGui extends ChestGui { enchantLimitMeta.setLore(Collections.singletonList("\u00A77Click here to open enchantment level limit menu")); enchantLimitItemstack.setItemMeta(enchantLimitMeta); - GuiItem enchantLimitItem = GuiGlobalItems.goToGuiItem(enchantLimitItemstack, EnchantLimitConfigGui.INSTANCE); + GuiItem enchantLimitItem = GuiGlobalItems.goToGuiItem(enchantLimitItemstack, new EnchantLimitConfigGui()); pane.bindItem('2', enchantLimitItem); // enchant cost item @@ -70,7 +70,7 @@ public class MainConfigGui extends ChestGui { enchantCostMeta.setLore(Collections.singletonList("\u00A77Click here to open enchantment costs menu")); enchantCostItemstack.setItemMeta(enchantCostMeta); - GuiItem enchantCostItem = GuiGlobalItems.goToGuiItem(enchantCostItemstack, EnchantCostConfigGui.INSTANCE); + GuiItem enchantCostItem = GuiGlobalItems.goToGuiItem(enchantCostItemstack, new EnchantCostConfigGui()); pane.bindItem('3', enchantCostItem); // Enchantment Conflicts item diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java index 513a6f9..4d900dc 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java @@ -12,6 +12,7 @@ import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.dependency.protocolib.PacketManager; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; @@ -31,8 +32,9 @@ import java.util.Collections; */ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { - private static BasicConfigGui INSTANCE; + private static BasicConfigGui INSTANCE = null; + @Nullable public static BasicConfigGui getInstance() { return INSTANCE; } @@ -43,7 +45,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { */ public BasicConfigGui(PacketManager packetManager) { super(4, "\u00A78Basic Config", CustomAnvil.instance); - INSTANCE = this; + if(INSTANCE == null) INSTANCE = this; this.packetManager = packetManager; init(); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantCostConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantCostConfigGui.java index 73e11ac..b45a7b3 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantCostConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantCostConfigGui.java @@ -4,6 +4,7 @@ import com.github.stefvanschie.inventoryframework.gui.GuiItem; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.enchant.EnchantmentProperties; @@ -24,18 +25,21 @@ public class EnchantCostConfigGui extends AbstractEnchantConfigGui Date: Wed, 10 Jul 2024 23:26:55 +0200 Subject: [PATCH 13/18] Write default config on enchant registering. Fix Enchantment Squared group not adding element. --- .../alexcrea/cuanvil/api/EnchantmentApi.java | 49 +++++++++++++++++++ .../alexcrea/cuanvil/config/ConfigHolder.java | 25 ++++++++-- src/main/kotlin/io/delilaheve/CustomAnvil.kt | 15 +++--- .../cuanvil/dependency/DependencyManager.kt | 19 +------ .../dependency/EcoEnchantDependency.kt | 47 ++---------------- .../EnchantmentSquaredDependency.kt | 27 ++-------- 6 files changed, 90 insertions(+), 92 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java index 57c3aa8..1c94e25 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java @@ -1,9 +1,13 @@ package xyz.alexcrea.cuanvil.api; +import io.delilaheve.CustomAnvil; +import org.bukkit.Bukkit; import org.bukkit.NamespacedKey; +import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.enchantments.Enchantment; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry; import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity; @@ -20,6 +24,8 @@ import java.util.Map; @SuppressWarnings("unused") public class EnchantmentApi { + private static int saveChangeTask = -1; + private EnchantmentApi() {} /** @@ -39,6 +45,9 @@ public class EnchantmentApi { EnchantLimitConfigGui.getInstance().updateValueForGeneric(enchantment, true); } + // Write default if do not exist + writeDefaultConfig(enchantment, false); + return true; } @@ -138,4 +147,44 @@ public class EnchantmentApi { return Collections.unmodifiableMap(CAEnchantmentRegistry.getInstance().registeredEnchantments()); } + /** + * Write the default level and rarity configuration of the enchantment. + * @param enchantment The enchantment to write default configuration + * @param override If it should override old configuration + * @return Return false if override is false and a configuration exist. true otherwise. + */ + public static boolean writeDefaultConfig(CAEnchantment enchantment, boolean override){ + FileConfiguration config = ConfigHolder.DEFAULT_CONFIG.getConfig(); + if(!override && config.contains(enchantment.getName())) return false; + + writeDefaultConfig(config, enchantment); + + prepareSaveTask(); + return true; + } + + + private static void writeDefaultConfig(FileConfiguration defaultConfig, CAEnchantment enchantment) { + defaultConfig.set("enchant_limits." + enchantment.getKey().getKey(), enchantment.defaultMaxLevel()); + + String basePath = "enchant_values." + enchantment.getKey().getKey(); + EnchantmentRarity rarity = enchantment.defaultRarity(); + + defaultConfig.set(basePath + ".item", rarity.getItemValue()); + defaultConfig.set(basePath + ".book", rarity.getBookValue()); + } + + /** + * Prepare a task to save custom recipe configuration. + */ + private static void prepareSaveTask() { + if(saveChangeTask != -1) return; + + saveChangeTask = Bukkit.getScheduler().scheduleSyncDelayedTask(CustomAnvil.instance, ()->{ + ConfigHolder.DEFAULT_CONFIG.saveToDisk(true); + saveChangeTask = -1; + }, 0L); + } + + } diff --git a/src/main/java/xyz/alexcrea/cuanvil/config/ConfigHolder.java b/src/main/java/xyz/alexcrea/cuanvil/config/ConfigHolder.java index dc6a14e..3cfaf03 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/config/ConfigHolder.java +++ b/src/main/java/xyz/alexcrea/cuanvil/config/ConfigHolder.java @@ -20,21 +20,38 @@ public abstract class ConfigHolder { public static UnitRepairHolder UNIT_REPAIR_HOLDER; public static CustomAnvilCraftHolder CUSTOM_RECIPE_HOLDER; - public static boolean loadConfig() { + /** + * Load default configuration. + * @return True if successful. + */ + public static boolean loadDefaultConfig() { DEFAULT_CONFIG = new DefaultConfigHolder(); + + return DEFAULT_CONFIG.reloadFromDisk(true); + } + + /** + * Load non default configuration. + * @return True if successful. + */ + public static boolean loadNonDefaultConfig() { ITEM_GROUP_HOLDER = new ItemGroupConfigHolder(); CONFLICT_HOLDER = new ConflictConfigHolder(); UNIT_REPAIR_HOLDER = new UnitRepairHolder(); CUSTOM_RECIPE_HOLDER = new CustomAnvilCraftHolder(); - return reloadAllFromDisk(true); + return removeNonDefaultFromDisk(true); } public static boolean reloadAllFromDisk(boolean hardfail) { - boolean sucess = DEFAULT_CONFIG.reloadFromDisk(hardfail); if (!sucess) return false; - sucess = ITEM_GROUP_HOLDER.reloadFromDisk(hardfail); + + return removeNonDefaultFromDisk(hardfail); + } + + private static boolean removeNonDefaultFromDisk(boolean hardfail){ + boolean sucess = ITEM_GROUP_HOLDER.reloadFromDisk(hardfail); if (!sucess) return false; sucess = CONFLICT_HOLDER.reloadFromDisk(hardfail); if (!sucess) return false; diff --git a/src/main/kotlin/io/delilaheve/CustomAnvil.kt b/src/main/kotlin/io/delilaheve/CustomAnvil.kt index c33cae6..1d5397d 100644 --- a/src/main/kotlin/io/delilaheve/CustomAnvil.kt +++ b/src/main/kotlin/io/delilaheve/CustomAnvil.kt @@ -97,19 +97,23 @@ class CustomAnvil : JavaPlugin() { chatListener = ChatEventListener() server.pluginManager.registerEvents(chatListener, this) + // Load dependency + DependencyManager.loadDependency() + // Register anvil events server.pluginManager.registerEvents(AnvilEventListener(DependencyManager.packetManager), this) // Load metrics Metrics(this, bstatsPluginId) - // Load other things + // Load other thing later. + // It is so other dependent plugins can implement there event listener before we fire them. Bukkit.getScheduler().scheduleSyncDelayedTask(this, {loadEnchantmentSystem()}, 0L) } private fun loadEnchantmentSystem(){ - // Load dependency - DependencyManager.loadDependency() + // Load default configuration + if (!ConfigHolder.loadDefaultConfig()) return // Register enchantments CAEnchantmentRegistry.getInstance().registerStartupEnchantments() @@ -119,8 +123,7 @@ class CustomAnvil : JavaPlugin() { server.pluginManager.callEvent(enchantReadyEvent) // Load config - val success = ConfigHolder.loadConfig() - if (!success) return + if (!ConfigHolder.loadNonDefaultConfig()) return // temporary: handle 1.21 update Update_1_21.handleUpdate() @@ -133,7 +136,7 @@ class CustomAnvil : JavaPlugin() { GuiSharedConstant.loadConstants() // Register enchantment of compatible plugin and load configuration change. - DependencyManager.handleCompatibilityConfig(this) + DependencyManager.handleCompatibilityConfig() } fun reloadResource( diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt index bede48f..f3962d5 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt @@ -1,13 +1,9 @@ package xyz.alexcrea.cuanvil.dependency import org.bukkit.Bukkit -import org.bukkit.configuration.file.FileConfiguration -import org.bukkit.plugin.Plugin import xyz.alexcrea.cuanvil.dependency.protocolib.NoProtocoLib import xyz.alexcrea.cuanvil.dependency.protocolib.PacketManager import xyz.alexcrea.cuanvil.dependency.protocolib.ProtocoLibWrapper -import xyz.alexcrea.cuanvil.enchant.CAEnchantment -import java.io.File object DependencyManager { @@ -21,7 +17,7 @@ object DependencyManager { // ProtocolLib dependency packetManager = if(pluginManager.isPluginEnabled("ProtocolLib")) ProtocoLibWrapper() - else NoProtocoLib() + else NoProtocoLib() // Enchantment Squared dependency if(pluginManager.isPluginEnabled("EnchantsSquared")){ @@ -37,22 +33,11 @@ object DependencyManager { } - fun handleCompatibilityConfig(plugin: Plugin) { - val folder = File(plugin.dataFolder, "compatibility") - + fun handleCompatibilityConfig() { enchantmentSquaredCompatibility?.registerPluginConfiguration() - ecoEnchantCompatibility?.registerPluginConfiguration(folder) } - fun writeDefaultConfig(defaultConfig: FileConfiguration, enchantment: CAEnchantment) { - defaultConfig["enchant_limits.${enchantment.key.key}"] = enchantment.defaultMaxLevel() - - val rarity = enchantment.defaultRarity() - defaultConfig["enchant_values.${enchantment.key.key}.item"] = rarity.itemValue - defaultConfig["enchant_values.${enchantment.key.key}.book"] = rarity.bookValue - } - fun registerEnchantments() { enchantmentSquaredCompatibility?.registerEnchantments() ecoEnchantCompatibility?.registerEnchantments() diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EcoEnchantDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EcoEnchantDependency.kt index 77e9792..89d0ca8 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EcoEnchantDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EcoEnchantDependency.kt @@ -2,13 +2,9 @@ package xyz.alexcrea.cuanvil.dependency import com.willfp.ecoenchants.enchant.EcoEnchants import io.delilaheve.CustomAnvil -import org.bukkit.configuration.file.YamlConfiguration import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.plugin.Plugin import xyz.alexcrea.cuanvil.api.EnchantmentApi -import xyz.alexcrea.cuanvil.config.ConfigHolder -import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry -import java.io.File class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) { @@ -21,49 +17,14 @@ class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) { } fun registerEnchantments() { + CustomAnvil.instance.logger.info("Preparing Eco Enchant compatibility...") + for (ecoEnchant in EcoEnchants.values()) { - EnchantmentApi.unregisterEnchantment(ecoEnchant.enchantment) // As eco enchants is loaded before ca, we need to unregister old "vanilla" enchant. + EnchantmentApi.unregisterEnchantment(ecoEnchant.enchantment) // As eco enchants is loaded before custom anvil and register enchantment to registry, we need to unregister old "vanilla" enchant. EnchantmentApi.registerEnchantment(ecoEnchant.enchantment) } - } - - fun registerPluginConfiguration(folder: File){ - val compatibilityFile = File(folder, "ecoEnchant.yml") - - if(compatibilityFile.exists()){ - folder.mkdirs() - compatibilityFile.createNewFile() - } - - val config = YamlConfiguration.loadConfiguration(compatibilityFile) - val defaultConfig = ConfigHolder.DEFAULT_CONFIG.config - var doSave = false - - for (ecoEnchant in EcoEnchants.values()) { - val enchantment = CAEnchantmentRegistry.getInstance().getByKey(ecoEnchant.enchantmentKey) - - if(enchantment == null){ - CustomAnvil.instance.logger.warning("Could not find " + ecoEnchant.enchantmentKey + "testing compatibility.") - continue - } - - // Write enchantment value if needed - val testPath = "default.${enchantment.key.key}" - if(!config.getBoolean(testPath, false)){ - doSave = true - config[testPath] = true - - DependencyManager.writeDefaultConfig(defaultConfig, enchantment) //TODO move to api register - } - } - - if(doSave){ - config.save(compatibilityFile) - ConfigHolder.DEFAULT_CONFIG.saveToDisk(true) - - CustomAnvil.instance.logger.info("Saved default for new eco enchant enchantments.") - } + CustomAnvil.instance.logger.info("Eco Enchant should now work as expected !") } } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt index f5e0fe1..3eacc2e 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt @@ -11,7 +11,6 @@ import org.bukkit.plugin.Plugin import xyz.alexcrea.cuanvil.api.ConflictBuilder import xyz.alexcrea.cuanvil.api.EnchantmentApi import xyz.alexcrea.cuanvil.api.MaterialGroupApi -import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry import xyz.alexcrea.cuanvil.enchant.wrapped.CAEnchantSquaredEnchantment @@ -36,6 +35,7 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin) } fun registerEnchantments(){ + CustomAnvil.instance.logger.info("Preparing Enchantment Squared compatibility...") for (enchant in CustomEnchantManager.getInstance().allEnchants.values) { EnchantmentApi.registerEnchantment(CAEnchantSquaredEnchantment(enchant)) } @@ -62,14 +62,8 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin) return CAEnchantment.getByKey(getKeyFromEnchant(enchant))!! } - - private val IS_READY_PATH = "enchantment_square_ready" fun registerPluginConfiguration(){ - val defaultConfig = ConfigHolder.DEFAULT_CONFIG.config - val isReady = defaultConfig.getBoolean(IS_READY_PATH, false) - if(isReady) return - - CustomAnvil.instance.logger.info("Preparing configuration for Enchantment Squared...") + CustomAnvil.instance.logger.info("Preparing Enchantment Squared config...") // Prepare enchantments val esEnchantments = ArrayList() @@ -77,22 +71,11 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin) esEnchantments.add(getWrappedEnchant(enchant) as CAEnchantSquaredEnchantment) } - // Write default level limit and xp cost - for (enchantment in esEnchantments) { //TODO move to api register - DependencyManager.writeDefaultConfig(defaultConfig, enchantment) - } - // Write groups and conflicts writeMissingGroups() writeMaterialRestriction(esEnchantments) writeEnchantmentConflicts(esEnchantments) - // Set ready - defaultConfig[IS_READY_PATH] = true - - // Save - ConfigHolder.DEFAULT_CONFIG.saveToDisk(true) - CustomAnvil.instance.logger.info("Enchantment Squared should now work as expected !") } @@ -112,15 +95,15 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin) MaterialGroupApi.addMaterialGroup(hoes) val shield = IncludeGroup("shield") - hoes.addToPolicy(Material.SHIELD) + shield.addToPolicy(Material.SHIELD) MaterialGroupApi.addMaterialGroup(shield) val elytra = IncludeGroup("elytra") - hoes.addToPolicy(Material.ELYTRA) + elytra.addToPolicy(Material.ELYTRA) MaterialGroupApi.addMaterialGroup(elytra) val trinkets = IncludeGroup("trinkets") - hoes.addToPolicy(Material.ROTTEN_FLESH) + trinkets.addToPolicy(Material.ROTTEN_FLESH) MaterialGroupApi.addMaterialGroup(trinkets) } From ac7f975b022bfae74d649393636583057b18ab2c Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Thu, 11 Jul 2024 00:52:13 +0200 Subject: [PATCH 14/18] Fix value written as set in yml. Fix material group not being added at to the registry. Fix EnchantmentSquared restriction not having enchantment. Added plugin's instance as conflict source. --- .../xyz/alexcrea/cuanvil/api/ConflictAPI.java | 13 ++++------ .../alexcrea/cuanvil/api/ConflictBuilder.java | 14 +++++------ .../cuanvil/api/MaterialGroupApi.java | 25 +++++++++++++------ .../EnchantmentSquaredDependency.kt | 5 ++-- 4 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java index 4bdb6d2..28fccd2 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java @@ -9,10 +9,7 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.group.EnchantConflictGroup; import xyz.alexcrea.cuanvil.gui.config.global.EnchantConflictGui; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; /** * Custom Anvil api for conflict registry. @@ -82,8 +79,8 @@ public class ConflictAPI { String basePath = name + "."; - Set enchantments = extractEnchantments(builder); - Set excludedGroups = builder.getExcludedGroupNames(); + List enchantments = extractEnchantments(builder); + List excludedGroups = new ArrayList<>(builder.getExcludedGroupNames()); if(!enchantments.isEmpty()) config.set(basePath + "enchantments", enchantments); if(!excludedGroups.isEmpty()) config.set(basePath + "notAffectedGroups", excludedGroups); if(builder.getMaxBeforeConflict() > 0) config.set(basePath + "maxEnchantmentBeforeConflict", builder.getMaxBeforeConflict()); @@ -101,8 +98,8 @@ public class ConflictAPI { * @return Builder's stored enchantment. */ @NotNull - private static Set extractEnchantments(@NotNull ConflictBuilder builder){ - Set result = new HashSet<>(builder.getEnchantmentNames()); + private static List extractEnchantments(@NotNull ConflictBuilder builder){ + List result = new ArrayList<>(builder.getEnchantmentNames()); for (NamespacedKey enchantmentKey : builder.getEnchantmentKeys()) { result.add(enchantmentKey.getKey()); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java index 2786dd9..3e63b36 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictBuilder.java @@ -325,24 +325,24 @@ public class ConflictBuilder { */ @NotNull public ConflictBuilder copy() { - ConflictBuilder clone = new ConflictBuilder(this.name, this.source); + ConflictBuilder copy = new ConflictBuilder(this.name, this.source); setMaxBeforeConflict(this.maxBeforeConflict); // Set Enchantments for (NamespacedKey key : this.enchantmentKeys) { - clone.addEnchantment(key); + copy.addEnchantment(key); } - for (String name : this.enchantmentNames) { - clone.addEnchantment(name); + for (String enchantName : this.enchantmentNames) { + copy.addEnchantment(enchantName); } // Set Groups - for (String name : this.excludedGroupNames) { - clone.addExcludedGroup(name); + for (String groupName : this.excludedGroupNames) { + copy.addExcludedGroup(groupName); } - return clone; + return copy; } /** * Build a new Enchant conflict group by this builder. diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java index 769b0bf..b3283aa 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java @@ -1,6 +1,7 @@ package xyz.alexcrea.cuanvil.api; import io.delilaheve.CustomAnvil; +import io.delilaheve.util.ConfigOptions; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.configuration.file.FileConfiguration; @@ -13,10 +14,7 @@ import xyz.alexcrea.cuanvil.group.IncludeGroup; import xyz.alexcrea.cuanvil.group.ItemGroupManager; import xyz.alexcrea.cuanvil.gui.config.global.GroupConfigGui; -import java.util.Collections; -import java.util.EnumSet; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * Custom Anvil api for material group registry. @@ -39,6 +37,7 @@ public class MaterialGroupApi { public static boolean addMaterialGroup(@NotNull AbstractMaterialGroup group){ ItemGroupManager itemGroupManager = ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager(); if(itemGroupManager.get(group.getName()) != null) return false; + itemGroupManager.getGroupMap().put(group.getName(), group); if(!writeMaterialGroup(group, false)) return false; @@ -46,6 +45,10 @@ public class MaterialGroupApi { GroupConfigGui.INSTANCE.updateValueForGeneric(includeGroup, true); } + if(ConfigOptions.INSTANCE.getVerboseDebugLog()){ + CustomAnvil.instance.getLogger().info("Registered group " + group.getName()); + } + return true; } @@ -100,10 +103,10 @@ public class MaterialGroupApi { config.set(basePath + ItemGroupManager.GROUP_TYPE_PATH, groupType); if(!materialSet.isEmpty()){ - config.set(basePath + ItemGroupManager.MATERIAL_LIST_PATH, materialSet); + config.set(basePath + ItemGroupManager.MATERIAL_LIST_PATH, materialSetToStringList(materialSet)); } if(!groupSet.isEmpty()){ - config.set(basePath + ItemGroupManager.GROUP_LIST_PATH, groupSet); + config.set(basePath + ItemGroupManager.GROUP_LIST_PATH, materialGroupSEtToStringList(groupSet)); } } @@ -116,11 +119,19 @@ public class MaterialGroupApi { config.set(basePath + ItemGroupManager.GROUP_TYPE_PATH, "include"); if(!materials.isEmpty()){ - config.set(basePath + ItemGroupManager.MATERIAL_LIST_PATH, materials); + config.set(basePath + ItemGroupManager.MATERIAL_LIST_PATH, materialSetToStringList(materials)); } } + public static List materialSetToStringList(@NotNull Set materials){ + return materials.stream().map(material -> material.getKey().getKey().toLowerCase()).toList(); + } + + public static List materialGroupSEtToStringList(@NotNull Set groups){ + return groups.stream().map(AbstractMaterialGroup::getName).toList(); + } + /** * Remove a material group. * Caution ! It will not be removed from depending conflict or other material group at runtime. diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt index 3eacc2e..e2618ae 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt @@ -110,7 +110,8 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin) private fun writeMaterialRestriction(esEnchantments: List){ for (enchantment in esEnchantments) { - val conflict = ConflictBuilder("restriction_${enchantment.key.key}") + val conflict = ConflictBuilder("restriction_${enchantment.key.key}", CustomAnvil.instance) + conflict.addEnchantment(enchantment) // enchanted book is allowed in any case. conflict.addExcludedGroup("enchanted_book") @@ -146,7 +147,7 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin) } private fun writeConflict(enchantment1: CAEnchantment, enchantment2: CAEnchantment){ - val conflict = ConflictBuilder("${enchantment1.name}_with_${enchantment2.name}_conflict") + val conflict = ConflictBuilder("${enchantment1.name}_with_${enchantment2.name}_conflict", CustomAnvil.instance) conflict.addEnchantment(enchantment1).addEnchantment(enchantment2) From 42a028f2fd5fcc227ce89a95d178dfa005faee1d Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Thu, 11 Jul 2024 12:36:06 +0200 Subject: [PATCH 15/18] Fix eco enchant not being registered as CAEcoEnchant. --- .../xyz/alexcrea/cuanvil/dependency/EcoEnchantDependency.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EcoEnchantDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EcoEnchantDependency.kt index 89d0ca8..713a03c 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EcoEnchantDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EcoEnchantDependency.kt @@ -5,6 +5,7 @@ import io.delilaheve.CustomAnvil import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.plugin.Plugin import xyz.alexcrea.cuanvil.api.EnchantmentApi +import xyz.alexcrea.cuanvil.enchant.wrapped.CAEcoEnchant class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) { @@ -21,7 +22,7 @@ class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) { for (ecoEnchant in EcoEnchants.values()) { EnchantmentApi.unregisterEnchantment(ecoEnchant.enchantment) // As eco enchants is loaded before custom anvil and register enchantment to registry, we need to unregister old "vanilla" enchant. - EnchantmentApi.registerEnchantment(ecoEnchant.enchantment) + EnchantmentApi.registerEnchantment(CAEcoEnchant(ecoEnchant)) } CustomAnvil.instance.logger.info("Eco Enchant should now work as expected !") From 0fd12b4185082946a3aa87144ae5e80c54ded18f Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Thu, 11 Jul 2024 12:42:33 +0200 Subject: [PATCH 16/18] Splited optimised get and clean into 2 category. Also changed getLevel(ItemStack) from CAEnchantmentBase to CAEnchantment --- .../cuanvil/enchant/CAEnchantment.java | 32 +++++++++++++------ .../cuanvil/enchant/CAEnchantmentBase.java | 13 ++++---- .../enchant/CAEnchantmentRegistry.java | 32 ++++++++++++++----- .../wrapped/CAEnchantSquaredEnchantment.java | 7 +++- .../enchant/wrapped/CAVanillaEnchantment.java | 7 +++- 5 files changed, 64 insertions(+), 27 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java index 1162eda..92b4442 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java @@ -21,6 +21,7 @@ import java.util.Map; * One issue with custom anvil is: it does not handle well duplicate key name (ignoring namespace) * as the plugin was initially coded with vanilla enchantment in head */ +@SuppressWarnings("unused") public interface CAEnchantment { @@ -52,10 +53,16 @@ public interface CAEnchantment { int defaultMaxLevel(); /** - * Check if the enchantment have specialised group operation. - * @return If the enchantment is optimised for group operation. + * Check if the enchantment have specialised get bulk operation. + * @return If the enchantment is optimised for get bulk operation. */ - boolean isOptimised(); + boolean isGetOptimised(); + + /** + * Check if the enchantment have specialised clean bulk operation. + * @return If the enchantment is optimised for clean bulk operation. + */ + boolean isCleanOptimised(); /** * Check if the player is allowed to use this enchantment. @@ -89,15 +96,20 @@ public interface CAEnchantment { /** * Get current level of the enchantment. - * @param item Item to search the level for. - * @return The enchantment level. + * @param item Item to search the level for. Should not get changed. + * @return Current leve of this enchantment on item. or 0 if absent. */ - int getLevel(@NotNull ItemStack item); + default int getLevel(@NotNull ItemStack item){ + ItemMeta meta = item.getItemMeta(); + if(meta == null) return 0; + + return getLevel(item, meta); + } /** * Get current level of the enchantment. - * @param item Item to search the level for. - * @param meta Meta of the provided item. It will not be changed and not be set on the item. + * @param item Item to search the level for. Should not get changed. + * @param meta Meta of the provided item. Should not get changed. * @return Current leve of this enchantment on item. or 0 if absent. */ int getLevel(@NotNull ItemStack item, @NotNull ItemMeta meta); @@ -158,7 +170,7 @@ public interface CAEnchantment { } // Clean unoptimised enchants - for (CAEnchantment enchant : CAEnchantmentRegistry.getInstance().unoptimisedValues()) { + for (CAEnchantment enchant : CAEnchantmentRegistry.getInstance().unoptimisedCleanValues()) { if(enchant.isEnchantmentPresent(item)){ enchant.removeFrom(item); } @@ -196,7 +208,7 @@ public interface CAEnchantment { } // Unoptimised enchantment get - findEnchantsFromSelectedList(item, meta, enchantments, registry.unoptimisedValues()); + findEnchantsFromSelectedList(item, meta, enchantments, registry.unoptimisedGetValues()); return enchantments; } diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentBase.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentBase.java index 0b367a7..05718d5 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentBase.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentBase.java @@ -72,7 +72,12 @@ public abstract class CAEnchantmentBase implements CAEnchantment { } @Override - public boolean isOptimised(){ + public boolean isGetOptimised(){ + return false; + } + + @Override + public boolean isCleanOptimised(){ return false; } @@ -81,12 +86,6 @@ public abstract class CAEnchantmentBase implements CAEnchantment { return true; } - public int getLevel(@NotNull ItemStack item){ - ItemMeta meta = item.getItemMeta(); - if(meta == null) return 0; - return getLevel(item, meta); - } - public boolean isEnchantmentPresent(@NotNull ItemStack item){ ItemMeta meta = item.getItemMeta(); if(meta == null) return false; diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java index 94c0f24..2acca50 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java @@ -20,12 +20,14 @@ public class CAEnchantmentRegistry { // Register enchantment functions private final HashMap byKeyMap; private final HashMap byNameMap; - private final List unoptimisedValues; + private final List unoptimisedGetValues; + private final List unoptimisedCleanValues; private CAEnchantmentRegistry() { byKeyMap = new HashMap<>(); byNameMap = new HashMap<>(); - unoptimisedValues = new ArrayList<>(); + unoptimisedGetValues = new ArrayList<>(); + unoptimisedCleanValues = new ArrayList<>(); } /** @@ -64,9 +66,13 @@ public class CAEnchantmentRegistry { byKeyMap.put(enchantment.getKey(), enchantment); byNameMap.put(enchantment.getName(), enchantment); - if(!enchantment.isOptimised()){ - unoptimisedValues.add(enchantment); + if(!enchantment.isGetOptimised()){ + unoptimisedGetValues.add(enchantment); } + if(!enchantment.isCleanOptimised()){ + unoptimisedCleanValues.add(enchantment); + } + return true; } @@ -86,7 +92,8 @@ public class CAEnchantmentRegistry { byKeyMap.remove(enchantment.getKey()); byNameMap.remove(enchantment.getName()); - unoptimisedValues.remove(enchantment); + unoptimisedGetValues.remove(enchantment); + unoptimisedCleanValues.remove(enchantment); return true; } @@ -128,12 +135,21 @@ public class CAEnchantmentRegistry { } /** - * Gets a list of all the unoptimised enchantments. + * Gets a list of all the unoptimised get operation enchantments. * @return List of unoptimised enchantments. */ @NotNull - public List unoptimisedValues() { - return unoptimisedValues; + public List unoptimisedGetValues() { + return unoptimisedGetValues; + } + + /** + * Gets a list of all the unoptimised clean operation enchantments. + * @return List of unoptimised enchantments. + */ + @NotNull + public List unoptimisedCleanValues() { + return unoptimisedCleanValues; } diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEnchantSquaredEnchantment.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEnchantSquaredEnchantment.java index 86f8914..b3f91a9 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEnchantSquaredEnchantment.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEnchantSquaredEnchantment.java @@ -27,7 +27,12 @@ public class CAEnchantSquaredEnchantment extends CAEnchantmentBase { } @Override - public boolean isOptimised() { + public boolean isGetOptimised() { + return true; + } + + @Override + public boolean isCleanOptimised() { return true; } diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAVanillaEnchantment.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAVanillaEnchantment.java index ad19f5f..136abc3 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAVanillaEnchantment.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAVanillaEnchantment.java @@ -32,7 +32,12 @@ public class CAVanillaEnchantment extends CAEnchantmentBase { } @Override - public boolean isOptimised() { + public boolean isGetOptimised() { + return true; + } + + @Override + public boolean isCleanOptimised() { return true; } From d3252eecbd9f2f0253924587295e85e432d311e2 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Thu, 11 Jul 2024 14:02:05 +0200 Subject: [PATCH 17/18] Add Bulk enchantment operation interface. --- .../bulk/BukkitEnchantBulkOperation.java | 47 +++++++++++++++++++ .../bulk/BulkCleanEnchantOperation.java | 28 +++++++++++ .../enchant/bulk/BulkGetEnchantOperation.java | 23 +++++++++ .../bulk/EnchantSquaredBulkOperation.java | 37 +++++++++++++++ .../kotlin/io/delilaheve/util/ItemUtil.kt | 1 - .../cuanvil/group/EnchantConflictManager.kt | 2 +- 6 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BukkitEnchantBulkOperation.java create mode 100644 src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BulkCleanEnchantOperation.java create mode 100644 src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BulkGetEnchantOperation.java create mode 100644 src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/EnchantSquaredBulkOperation.java diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BukkitEnchantBulkOperation.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BukkitEnchantBulkOperation.java new file mode 100644 index 0000000..d34bd49 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BukkitEnchantBulkOperation.java @@ -0,0 +1,47 @@ +package xyz.alexcrea.cuanvil.enchant.bulk; + +import io.delilaheve.util.ItemUtil; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.EnchantmentStorageMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; +import xyz.alexcrea.cuanvil.api.EnchantmentApi; +import xyz.alexcrea.cuanvil.enchant.CAEnchantment; + +import java.util.Map; + +public class BukkitEnchantBulkOperation implements BulkGetEnchantOperation, BulkCleanEnchantOperation { + + @Override + public void bulkGet(@NotNull Map enchantmentList, @NotNull ItemStack item, @NotNull ItemMeta meta) { + if (ItemUtil.INSTANCE.isEnchantedBook(item)) { + ((EnchantmentStorageMeta)meta).getStoredEnchants().forEach((enchantment, level) -> + enchantmentList.put(EnchantmentApi.getByKey(enchantment.getKey()), level) + ); + } else { + item.getEnchantments().forEach((enchantment, level) -> + enchantmentList.put(EnchantmentApi.getByKey(enchantment.getKey()), level) + ); + } + } + + @Override + public void bulkClear(@NotNull ItemStack item) { + if (item.getType() != Material.ENCHANTED_BOOK) { + item.getEnchantments().forEach((enchantment, leve) -> + item.removeEnchantment(enchantment) + ); + } + } + + @Override + public void bulkClear(@NotNull ItemStack item, @NotNull ItemMeta meta) { + if (item.getType() == Material.ENCHANTED_BOOK) { + EnchantmentStorageMeta bookMeta = (EnchantmentStorageMeta) meta; + bookMeta.getStoredEnchants().forEach((enchantment, leve) -> + bookMeta.removeStoredEnchant(enchantment) + ); + } + } +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BulkCleanEnchantOperation.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BulkCleanEnchantOperation.java new file mode 100644 index 0000000..4b1a225 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BulkCleanEnchantOperation.java @@ -0,0 +1,28 @@ +package xyz.alexcrea.cuanvil.enchant.bulk; + +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; + +/** + * Bulk operation for clean enchantments operations. + */ +public interface BulkCleanEnchantOperation { + + /** + * Bulk clear part of the enchantments from this item. + * The item can be edited freely. If you need the meta it is preferred to use {@link #bulkClear(ItemStack, ItemMeta)} if possible + * @param item The item to clear enchantment from. + */ + void bulkClear(@NotNull ItemStack item); + + /** + * Bulk clear part of the enchantments from this item meta. + * Item should not be edited as meta will be applied later. + * If you need to edit the item and do not need the meta use {@link #bulkClear(ItemStack)} + * @param item The item source of the item meta. should not be edited. + * @param meta The item meta to clear enchantment from. + */ + void bulkClear(@NotNull ItemStack item, @NotNull ItemMeta meta); + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BulkGetEnchantOperation.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BulkGetEnchantOperation.java new file mode 100644 index 0000000..a985edd --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BulkGetEnchantOperation.java @@ -0,0 +1,23 @@ +package xyz.alexcrea.cuanvil.enchant.bulk; + +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; +import xyz.alexcrea.cuanvil.enchant.CAEnchantment; + +import java.util.Map; + +/** + * Bulk operation for get enchantments operations. + */ +public interface BulkGetEnchantOperation { + + /** + * Bulk get part of the stored enchantment of this item. + * @param enchantmentList Mutable map of collected enchantment. should b + * @param item The item to get enchantment from. Should not get edited. + * @param meta The item meta to get enchantment from. Should not get edited. + */ + void bulkGet(@NotNull Map enchantmentList, @NotNull ItemStack item, @NotNull ItemMeta meta); + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/EnchantSquaredBulkOperation.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/EnchantSquaredBulkOperation.java new file mode 100644 index 0000000..59bd6ec --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/EnchantSquaredBulkOperation.java @@ -0,0 +1,37 @@ +package xyz.alexcrea.cuanvil.enchant.bulk; + +import me.athlaeos.enchantssquared.managers.CustomEnchantManager; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; +import xyz.alexcrea.cuanvil.dependency.DependencyManager; +import xyz.alexcrea.cuanvil.dependency.EnchantmentSquaredDependency; +import xyz.alexcrea.cuanvil.enchant.CAEnchantment; + +import java.util.Collections; +import java.util.Map; + +public class EnchantSquaredBulkOperation implements BulkGetEnchantOperation, BulkCleanEnchantOperation { + + @Override + public void bulkGet(@NotNull Map enchantmentList, @NotNull ItemStack item, @NotNull ItemMeta meta) { + EnchantmentSquaredDependency enchantmentSquared = DependencyManager.INSTANCE.getEnchantmentSquaredCompatibility(); + if(enchantmentSquared != null){ + enchantmentSquared.getEnchantmentsSquared(item, enchantmentList); + } + } + + + @Override + public void bulkClear(@NotNull ItemStack item) { + EnchantmentSquaredDependency enchantmentSquared = DependencyManager.INSTANCE.getEnchantmentSquaredCompatibility(); + if(enchantmentSquared != null){ + CustomEnchantManager.getInstance().setItemEnchants(item, Collections.emptyMap()); + } + } + + @Override + public void bulkClear(@NotNull ItemStack item, @NotNull ItemMeta meta) { + // item meta is not preferred for enchantment squared clear + } +} diff --git a/src/main/kotlin/io/delilaheve/util/ItemUtil.kt b/src/main/kotlin/io/delilaheve/util/ItemUtil.kt index 3c415f6..a85af39 100644 --- a/src/main/kotlin/io/delilaheve/util/ItemUtil.kt +++ b/src/main/kotlin/io/delilaheve/util/ItemUtil.kt @@ -29,7 +29,6 @@ object ItemUtil { fun ItemStack.setEnchantmentsUnsafe(enchantments: Map) { CAEnchantment.clearEnchants(this) - //TODO maybe faster methode to add vanilla enchantment. maybe move this function to wrapped enchantment enchantments.forEach { (enchantment, level) -> enchantment.addEnchantmentUnsafe(this, level) } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt index dbe2374..abebcbc 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt @@ -210,7 +210,7 @@ class EnchantConflictManager { val newItem = item.clone() CAEnchantment.clearEnchants(newItem) - enchantments.forEach{//TODO maybe bulk add if possible + enchantments.forEach{ enchantment -> enchantment.key.addEnchantmentUnsafe(newItem, enchantment.value) } From b89a8951b72aab87c7d4f641aa76fcffd560e28e Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Thu, 11 Jul 2024 16:19:10 +0200 Subject: [PATCH 18/18] =?UTF-8?q?Use=20Bulk=20operation=20object=20for=20b?= =?UTF-8?q?ukkit=20and=20enchantment=C2=B2=20enchants.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../alexcrea/cuanvil/api/EnchantmentApi.java | 17 +++++++ .../cuanvil/enchant/CAEnchantment.java | 48 ++++++------------- .../enchant/CAEnchantmentRegistry.java | 34 ++++++++++++- src/main/kotlin/io/delilaheve/CustomAnvil.kt | 2 +- .../EnchantmentSquaredDependency.kt | 12 +++-- 5 files changed, 73 insertions(+), 40 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java index 1c94e25..b950938 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java @@ -11,6 +11,8 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry; import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity; +import xyz.alexcrea.cuanvil.enchant.bulk.BulkCleanEnchantOperation; +import xyz.alexcrea.cuanvil.enchant.bulk.BulkGetEnchantOperation; import xyz.alexcrea.cuanvil.enchant.wrapped.CAVanillaEnchantment; import xyz.alexcrea.cuanvil.gui.config.global.EnchantCostConfigGui; import xyz.alexcrea.cuanvil.gui.config.global.EnchantLimitConfigGui; @@ -186,5 +188,20 @@ public class EnchantmentApi { }, 0L); } + /** + * Add a bulk get operator. + * @param operation An optimised get enchantments operation + */ + public static void addBulkGet(@NotNull BulkGetEnchantOperation operation){ + CAEnchantmentRegistry.getInstance().getOptimisedGetOperators().add(operation); + } + + /** + * Add a bulk clean operator. + * @param operation An optimised clean enchantments operation + */ + public static void addBulkClean(@NotNull BulkCleanEnchantOperation operation){ + CAEnchantmentRegistry.getInstance().getOptimisedCleanOperators().add(operation); + } } diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java index 92b4442..0303733 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java @@ -1,15 +1,13 @@ package xyz.alexcrea.cuanvil.enchant; -import io.delilaheve.util.ItemUtil; import org.bukkit.NamespacedKey; import org.bukkit.entity.HumanEntity; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.EnchantmentStorageMeta; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import xyz.alexcrea.cuanvil.dependency.DependencyManager; -import xyz.alexcrea.cuanvil.dependency.EnchantmentSquaredDependency; +import xyz.alexcrea.cuanvil.enchant.bulk.BulkCleanEnchantOperation; +import xyz.alexcrea.cuanvil.enchant.bulk.BulkGetEnchantOperation; import xyz.alexcrea.cuanvil.group.EnchantConflictGroup; import java.util.Collection; @@ -148,26 +146,20 @@ public interface CAEnchantment { * @param item Item to be cleared from enchantments. */ static void clearEnchants(@NotNull ItemStack item){ + // Optimised enchantment clean using item stack + for (BulkCleanEnchantOperation cleanOperator : CAEnchantmentRegistry.getInstance().getOptimisedCleanOperators()) { + cleanOperator.bulkClear(item); + } + ItemMeta meta = item.getItemMeta(); if(meta == null) return; - // Clean Vanilla enchants - if (ItemUtil.INSTANCE.isEnchantedBook(item)) { - EnchantmentStorageMeta bookMeta = (EnchantmentStorageMeta) meta; - bookMeta.getStoredEnchants().forEach( - (enchantment, leve) -> bookMeta.removeStoredEnchant(enchantment) - ); - } else { - item.getEnchantments().forEach( - (enchantment, leve) -> item.removeEnchantment(enchantment) - ); + // Optimised enchantment clean using item meta + for (BulkCleanEnchantOperation cleanOperator : CAEnchantmentRegistry.getInstance().getOptimisedCleanOperators()) { + cleanOperator.bulkClear(item, meta); } - // Clean Enchant Squared enchants - EnchantmentSquaredDependency enchantmentSquared = DependencyManager.INSTANCE.getEnchantmentSquaredCompatibility(); - if(enchantmentSquared != null){ - enchantmentSquared.clearEnchantments(item); - } + item.setItemMeta(meta); // Clean unoptimised enchants for (CAEnchantment enchant : CAEnchantmentRegistry.getInstance().unoptimisedCleanValues()) { @@ -190,21 +182,9 @@ public interface CAEnchantment { ItemMeta meta = item.getItemMeta(); if(meta == null) return enchantments; - // Vanilla optimised get - if (ItemUtil.INSTANCE.isEnchantedBook(item)) { - ((EnchantmentStorageMeta)meta).getStoredEnchants().forEach( - (enchantment, level) -> enchantments.put(registry.getByKey(enchantment.getKey()), level) - ); - } else { - item.getEnchantments().forEach( - (enchantment, level) -> enchantments.put(registry.getByKey(enchantment.getKey()), level) - ); - } - - // Enchants Squared get - EnchantmentSquaredDependency enchantmentSquared = DependencyManager.INSTANCE.getEnchantmentSquaredCompatibility(); - if(enchantmentSquared != null){ - enchantmentSquared.getEnchantmentsSquared(item, enchantments); + // Optimised enchantment get + for (BulkGetEnchantOperation getOperator : CAEnchantmentRegistry.getInstance().getOptimisedGetOperators()) { + getOperator.bulkGet(enchantments, item, meta); } // Unoptimised enchantment get diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java index 2acca50..1e7cd54 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java @@ -5,6 +5,9 @@ import org.bukkit.NamespacedKey; import org.bukkit.enchantments.Enchantment; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import xyz.alexcrea.cuanvil.enchant.bulk.BukkitEnchantBulkOperation; +import xyz.alexcrea.cuanvil.enchant.bulk.BulkCleanEnchantOperation; +import xyz.alexcrea.cuanvil.enchant.bulk.BulkGetEnchantOperation; import xyz.alexcrea.cuanvil.enchant.wrapped.CAVanillaEnchantment; import java.util.*; @@ -20,25 +23,39 @@ public class CAEnchantmentRegistry { // Register enchantment functions private final HashMap byKeyMap; private final HashMap byNameMap; + private final List unoptimisedGetValues; private final List unoptimisedCleanValues; + private final List optimisedGetOperators; + private final List optimisedCleanOperators; + private CAEnchantmentRegistry() { byKeyMap = new HashMap<>(); byNameMap = new HashMap<>(); + unoptimisedGetValues = new ArrayList<>(); unoptimisedCleanValues = new ArrayList<>(); + + optimisedGetOperators = new ArrayList<>(); + optimisedCleanOperators = new ArrayList<>(); } /** * This should only be called on main of custom anvil. * If called more than one time, chance of thing being broken will be high. */ - public void registerStartupEnchantments(){ + public void registerBukkit(){ + // Register enchantment for (Enchantment enchantment : Enchantment.values()) { register(new CAVanillaEnchantment(enchantment)); } + // Add bukkit enchantment bulk operation + BukkitEnchantBulkOperation bukkitOperation = new BukkitEnchantBulkOperation(); + optimisedGetOperators.add(bukkitOperation); + optimisedCleanOperators.add(bukkitOperation); + } /** @@ -152,5 +169,20 @@ public class CAEnchantmentRegistry { return unoptimisedCleanValues; } + /** + * Get "clean optimised operation" for get enchantments. + * @return Get mutable "clean enchantments optimised operation" list. + */ + public List getOptimisedCleanOperators() { + return optimisedCleanOperators; + } + + /** + * Get "get optimised operation" for get enchantments. + * @return Get mutable "get enchantments optimised operation" list. + */ + public List getOptimisedGetOperators() { + return optimisedGetOperators; + } } diff --git a/src/main/kotlin/io/delilaheve/CustomAnvil.kt b/src/main/kotlin/io/delilaheve/CustomAnvil.kt index 1d5397d..6c4facf 100644 --- a/src/main/kotlin/io/delilaheve/CustomAnvil.kt +++ b/src/main/kotlin/io/delilaheve/CustomAnvil.kt @@ -116,7 +116,7 @@ class CustomAnvil : JavaPlugin() { if (!ConfigHolder.loadDefaultConfig()) return // Register enchantments - CAEnchantmentRegistry.getInstance().registerStartupEnchantments() + CAEnchantmentRegistry.getInstance().registerBukkit() DependencyManager.registerEnchantments() val enchantReadyEvent = CAEnchantRegistryReadyEvent() diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt index e2618ae..6a913ec 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt @@ -13,6 +13,7 @@ import xyz.alexcrea.cuanvil.api.EnchantmentApi import xyz.alexcrea.cuanvil.api.MaterialGroupApi import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry +import xyz.alexcrea.cuanvil.enchant.bulk.EnchantSquaredBulkOperation import xyz.alexcrea.cuanvil.enchant.wrapped.CAEnchantSquaredEnchantment import xyz.alexcrea.cuanvil.group.IncludeGroup import java.util.* @@ -36,10 +37,17 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin) fun registerEnchantments(){ CustomAnvil.instance.logger.info("Preparing Enchantment Squared compatibility...") + + // Register enchantments for (enchant in CustomEnchantManager.getInstance().allEnchants.values) { EnchantmentApi.registerEnchantment(CAEnchantSquaredEnchantment(enchant)) } + // Register bulk operation + val bulkOpperations = EnchantSquaredBulkOperation() + EnchantmentApi.addBulkGet(bulkOpperations) + EnchantmentApi.addBulkClean(bulkOpperations) + } fun getEnchantmentsSquared(item: ItemStack, enchantments: MutableMap) { @@ -51,10 +59,6 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin) } - fun clearEnchantments(item: ItemStack) { - CustomEnchantManager.getInstance().removeAllEnchants(item) - } - fun getKeyFromEnchant(enchant: CustomEnchant): NamespacedKey{ return NamespacedKey.fromString(enchant.type.lowercase(Locale.getDefault()), this.enchantmentSquaredPlugin)!! }