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] 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 {