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