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] 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") }