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 001/517] 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 002/517] 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 003/517] 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 004/517] 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 005/517] 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 006/517] 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 0da9d48ee9e0cb5a8dd02f58e79160e523d12216 Mon Sep 17 00:00:00 2001
From: alexcrea <42614139+alexcrea@users.noreply.github.com>
Date: Mon, 8 Jul 2024 19:32:00 +0200
Subject: [PATCH 007/517] Fix EcoEnchant enchantment disappearing on rename.
---
src/main/kotlin/io/delilaheve/AnvilEventListener.kt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt
index e432dca..5837e98 100644
--- a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt
+++ b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt
@@ -87,8 +87,8 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener {
event.result = null
return
}
- // We don't manually set item here as vanilla do it (renaming)
- //event.result = null
+
+ event.result = resultItem
anvilCost += calculatePenalty(first, null, resultItem)
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 008/517] 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 009/517] =?UTF-8?q?Make=20compatibility=20object=20with=20?=
=?UTF-8?q?EcoEnchant=20and=20Enchant=C2=B2=20use=20the=20api.=20Abstract?=
=?UTF-8?q?=20material=20group=20now=20have=20varargs=20"addAll"=20functio?=
=?UTF-8?q?n.?=
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 010/517] 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 011/517] 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 012/517] 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 013/517] 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 014/517] 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 015/517] 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 016/517] 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 017/517] 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 018/517] 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 019/517] =?UTF-8?q?Use=20Bulk=20operation=20object=20for?=
=?UTF-8?q?=20bukkit=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)!!
}
From ff60e2bef7dd220996bbcd9672dba44108958fc7 Mon Sep 17 00:00:00 2001
From: alexcrea <42614139+alexcrea@users.noreply.github.com>
Date: Thu, 11 Jul 2024 16:54:50 +0200
Subject: [PATCH 020/517] Update enchantment squared.
---
libs/EnchantsSquared.jar | Bin 436260 -> 491580 bytes
.../wrapped/CAEnchantSquaredEnchantment.java | 9 +--------
.../EnchantmentSquaredDependency.kt | 2 +-
3 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/libs/EnchantsSquared.jar b/libs/EnchantsSquared.jar
index e8df965ef8c1c010593fb812f10d5b2dae092799..f77c49e665b685af011037aa88fb1f6a9671539e 100644
GIT binary patch
delta 430239
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