From 64d5bafc7a6c759fd9bf20d5a99883d7b7a40452 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sun, 27 Apr 2025 10:06:18 +0200 Subject: [PATCH 01/20] replace density conflict and use sword conflict instead --- .../alexcrea/cuanvil/update/Update_1_21.java | 5 +- .../cuanvil/update/plugin/PUpdate_1_11_0.java | 67 +++++++++++++++++++ .../cuanvil/update/plugin/PluginUpdates.java | 9 ++- src/main/resources/config.yml | 2 +- 4 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_11_0.java diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/Update_1_21.java b/src/main/java/xyz/alexcrea/cuanvil/update/Update_1_21.java index 8180b07..28c7197 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/Update_1_21.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/Update_1_21.java @@ -59,9 +59,8 @@ public class Update_1_21 { addToStringList(conflictConfig, "restriction_smite.notAffectedGroups", "mace"); addToStringList(conflictConfig, "restriction_bane_of_arthropods.notAffectedGroups", "mace"); - addToStringList(conflictConfig, "mace_enchant_conflict.enchantments", - "minecraft:density", "minecraft:breach", "minecraft:smite", "minecraft:bane_of_arthropods"); - conflictConfig.set("mace_enchant_conflict.maxEnchantmentBeforeConflict", 1); + addToStringList(conflictConfig, "sword_enchant_conflict.enchantments", + "minecraft:density", "minecraft:breach"); // Add level limit baseConfig.set("enchant_limits.minecraft:density", 5); diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_11_0.java b/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_11_0.java new file mode 100644 index 0000000..ff28d75 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_11_0.java @@ -0,0 +1,67 @@ +package xyz.alexcrea.cuanvil.update.plugin; + +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import xyz.alexcrea.cuanvil.config.ConfigHolder; + +import javax.annotation.Nonnull; +import java.util.List; +import java.util.Set; + +import static xyz.alexcrea.cuanvil.update.UpdateUtils.addToStringList; + +public class PUpdate_1_11_0 { + + private static final List mace_expected = List.of( + "density", + "breach", + "smite", + "bane_of_arthropods" + ); + private static final List sword_expected = List.of( + "sharpness", + "smite", + "bane_of_arthropods" + ); + + public static void handleUpdate(@Nonnull Set toSave) { + FileConfiguration config = ConfigHolder.DEFAULT_CONFIG.getConfig(); + + // We migrate the mace conflict if exist and unmodified + if (!config.isConfigurationSection("sword_enchant_conflict")) return; + if (!config.isConfigurationSection("mace_enchant_conflict")) return; + + ConfigurationSection mace_conflict = config.getConfigurationSection("mace_enchant_conflict"); + // Test mace conflict if default + if (mace_conflict == null) return; + if (mace_conflict.getInt("maxEnchantmentBeforeConflict", 0) != 1) return; + + if (mace_conflict.isList("notAffectedGroups") && !mace_conflict.getList("notAffectedGroups").isEmpty()) return; + + List enchantments = mace_conflict.getStringList("enchantments"); + if (enchantments.size() != 4) return; + for (String ench : mace_expected) { + if(!enchantments.contains(ench) && !enchantments.contains("minecraft:" + ench)) return; + } + + // Test sword_enchant_conflict is default + ConfigurationSection sword_conflict = config.getConfigurationSection("sword_enchant_conflict"); + if (sword_conflict.getInt("maxEnchantmentBeforeConflict", 0) != 1) return; + + if (sword_conflict.isList("notAffectedGroups") && !sword_conflict.getList("notAffectedGroups").isEmpty()) return; + + enchantments = sword_conflict.getStringList("enchantments"); + if (enchantments.size() != 3) return; + for (String ench : sword_expected) { + if(!enchantments.contains(ench) && !enchantments.contains("minecraft:" + ench)) return; + } + + // Finally we know both conflict are default. so we fix + addToStringList(config, "sword_enchant_conflict.enchantments", + "minecraft:density", "minecraft:breach"); + + config.set("mace_enchant_conflict", null); + + } + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PluginUpdates.java b/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PluginUpdates.java index 548c6d1..03c858e 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PluginUpdates.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PluginUpdates.java @@ -20,18 +20,21 @@ public class PluginUpdates { if (new Version(1, 6, 2).greaterThan(current)) { PUpdate_1_6_2.handleUpdate(toSave); - // We assume 1.6.7 will run. TODO a better system instead of that I guess } if (new Version(1, 6, 7).greaterThan(current)) { PUpdate_1_6_7.handleUpdate(toSave); - // We assume 1.8.0 will run. } if (new Version(1, 8, 0).greaterThan(current)) { PUpdate_1_8_0.handleUpdate(toSave); + // We assume 1.11.0 will run. + } - finishConfiguration("1.8.0", toSave); + if (new Version(1, 11, 0).greaterThan(current)) { + PUpdate_1_11_0.handleUpdate(toSave); + + finishConfiguration("1.11.0", toSave); } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 9c1ad67..0bad067 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -367,4 +367,4 @@ debug_log_verbose: false # ProtocoLib may also be used if the server is in an "unsupported" version even if this option is disabled. force_protocolib: false -configVersion: 1.8.0 +configVersion: 1.11.0 From 012e6b1368cbfd0c90ce5dd13d2e39795b7da6f0 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sun, 27 Apr 2025 15:42:15 +0200 Subject: [PATCH 02/20] work on datapack support --- .../dependency/datapack/DataPackTester.kt | 30 +++ .../enchant/wrapped/CABukkitEnchantment.java | 34 ++-- .../wrapped/CAIncompatibleAllEnchant.java | 35 ++++ .../alexcrea/cuanvil/update/UpdateUtils.java | 19 +- .../alexcrea/cuanvil/update/Update_1_21.java | 26 +-- .../xyz/alexcrea/cuanvil/update/Version.java | 9 +- .../cuanvil/update/plugin/PUpdate_1_11_0.java | 4 +- .../cuanvil/update/plugin/PUpdate_1_6_2.java | 5 +- .../cuanvil/dependency/DependencyManager.kt | 4 +- .../dependency/datapack/DataPackTest.kt | 183 ++++++++++++++++++ .../datapack/bracken/enchant_conflict.yml | 35 ++++ .../datapack/bracken/item_conflict.yml | 54 ++++++ 12 files changed, 397 insertions(+), 41 deletions(-) create mode 100644 nms/v1_20R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTester.kt create mode 100644 src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAIncompatibleAllEnchant.java create mode 100644 src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTest.kt create mode 100644 src/main/resources/datapack/bracken/enchant_conflict.yml create mode 100644 src/main/resources/datapack/bracken/item_conflict.yml diff --git a/nms/v1_20R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTester.kt b/nms/v1_20R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTester.kt new file mode 100644 index 0000000..831ba58 --- /dev/null +++ b/nms/v1_20R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTester.kt @@ -0,0 +1,30 @@ +package xyz.alexcrea.cuanvil.dependency.datapack + +import io.papermc.paper.datapack.Datapack +import org.bukkit.Bukkit +import java.util.* + +object DataPackTester { + val legacyNames: List + get() = Bukkit.getDataPackManager().dataPacks + .stream().filter { obj -> obj.isEnabled } + .map { pack -> pack.key.key } + .toList() + + val enabledPacks: List + get() { + try { + // will throw error if do not exist + Bukkit::class.java.getDeclaredMethod("getDatapackManager") + + return Bukkit.getDatapackManager().enabledPacks + .stream().map { obj: Datapack -> obj.name } + .toList() + } catch (e: NoSuchMethodException) { + return legacyNames + } catch (e: Exception){ + // Assume cause UnimplementedOperationException on mock server + return Collections.emptyList() + } + } +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CABukkitEnchantment.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CABukkitEnchantment.java index 585c276..db809ce 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CABukkitEnchantment.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CABukkitEnchantment.java @@ -25,17 +25,17 @@ import java.util.logging.Level; */ public class CABukkitEnchantment extends CAEnchantmentBase { - private final @NotNull Enchantment enchantment; + public final @NotNull Enchantment bukkit; - public CABukkitEnchantment(@NotNull Enchantment enchantment, @Nullable EnchantmentRarity rarity){ - super(enchantment.getKey(), + public CABukkitEnchantment(@NotNull Enchantment bukkit, @Nullable EnchantmentRarity rarity){ + super(bukkit.getKey(), rarity, - enchantment.getMaxLevel()); - this.enchantment = enchantment; + bukkit.getMaxLevel()); + this.bukkit = bukkit; } - public CABukkitEnchantment(@NotNull Enchantment enchantment){ - this(enchantment, getRarity(enchantment)); + public CABukkitEnchantment(@NotNull Enchantment bukkit){ + this(bukkit, getRarity(bukkit)); } @Override @@ -51,9 +51,9 @@ public class CABukkitEnchantment extends CAEnchantmentBase { @Override public int getLevel(@NotNull ItemStack item, @NotNull ItemMeta meta) { if (ItemUtil.INSTANCE.isEnchantedBook(item)) { - return ((EnchantmentStorageMeta)meta).getStoredEnchantLevel(this.enchantment); + return ((EnchantmentStorageMeta)meta).getStoredEnchantLevel(this.bukkit); } else { - return meta.getEnchantLevel(this.enchantment); + return meta.getEnchantLevel(this.bukkit); } } @@ -62,9 +62,9 @@ public class CABukkitEnchantment extends CAEnchantmentBase { if (ItemUtil.INSTANCE.isEnchantedBook(item)) { EnchantmentStorageMeta bookMeta = ((EnchantmentStorageMeta)meta); - return bookMeta.getStoredEnchants().containsKey(this.enchantment); + return bookMeta.getStoredEnchants().containsKey(this.bukkit); }else{ - return item.containsEnchantment(this.enchantment); + return item.containsEnchantment(this.bukkit); } } @@ -74,10 +74,10 @@ public class CABukkitEnchantment extends CAEnchantmentBase { EnchantmentStorageMeta bookMeta = ((EnchantmentStorageMeta)item.getItemMeta()); assert bookMeta != null; - bookMeta.addStoredEnchant(this.enchantment, level, true); + bookMeta.addStoredEnchant(this.bukkit, level, true); item.setItemMeta(bookMeta); } else { - item.addUnsafeEnchantment(this.enchantment, level); + item.addUnsafeEnchantment(this.bukkit, level); } } @@ -88,10 +88,10 @@ public class CABukkitEnchantment extends CAEnchantmentBase { EnchantmentStorageMeta bookMeta = ((EnchantmentStorageMeta)item.getItemMeta()); assert bookMeta != null; - bookMeta.removeStoredEnchant(this.enchantment); + bookMeta.removeStoredEnchant(this.bukkit); item.setItemMeta(bookMeta); }else{ - item.removeEnchantment(this.enchantment); + item.removeEnchantment(this.bukkit); } } @@ -107,7 +107,7 @@ public class CABukkitEnchantment extends CAEnchantmentBase { @NotNull protected Enchantment getEnchant() { - return this.enchantment; + return this.bukkit; } private static Method getAnvilCostMethod; @@ -163,7 +163,7 @@ public class CABukkitEnchantment extends CAEnchantmentBase { return false; } - return this.enchantment.equals(other.getEnchant()); + return this.bukkit.equals(other.getEnchant()); } } diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAIncompatibleAllEnchant.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAIncompatibleAllEnchant.java new file mode 100644 index 0000000..7aeae2d --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAIncompatibleAllEnchant.java @@ -0,0 +1,35 @@ +package xyz.alexcrea.cuanvil.enchant.wrapped; + +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.alexcrea.cuanvil.enchant.*; + +import java.util.Map; + +/** + * Represent an enchantment incompatible with every other enchantments + */ +public class CAIncompatibleAllEnchant extends CABukkitEnchantment implements AdditionalTestEnchantment { + + public CAIncompatibleAllEnchant(@NotNull Enchantment enchantment, @Nullable EnchantmentRarity rarity) { + super(enchantment, rarity); + } + + public CAIncompatibleAllEnchant(@NotNull Enchantment enchantment) { + super(enchantment); + } + + + @Override + public boolean isEnchantConflict(@NotNull Map enchantments, @NotNull Material itemMat) { + return true; + } + + @Override + public boolean isItemConflict(@NotNull Map enchantments, @NotNull Material itemMat, @NotNull ItemStack item) { + return false; + } +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/UpdateUtils.java b/src/main/java/xyz/alexcrea/cuanvil/update/UpdateUtils.java index 93d37aa..c13515f 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/UpdateUtils.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/UpdateUtils.java @@ -10,18 +10,18 @@ import java.util.List; public class UpdateUtils { public static final String MINECRAFT_VERSION_PATH = "lowMinecraftVersion"; - public static Version currentMinecraftVersion(){ + public static Version currentMinecraftVersion() { String versionString = Bukkit.getServer().getBukkitVersion().split("-")[0]; return Version.fromString(versionString); } @Deprecated - public static int[] currentMinecraftVersionArray(){ + public static int[] currentMinecraftVersionArray() { String versionString = Bukkit.getServer().getBukkitVersion().split("-")[0]; return UpdateUtils.readVersionFromString(versionString); } - public static int[] readVersionFromString(String versionString){ + public static int[] readVersionFromString(String versionString) { String[] partialVersion = versionString.split("\\."); int[] versionParts = new int[]{0, 0, 0}; @@ -31,11 +31,22 @@ public class UpdateUtils { return versionParts; } - public static void addToStringList(FileConfiguration config, String path, String... toAdd){ + public static void addToStringList(FileConfiguration config, String path, String... toAdd) { List groups = new ArrayList<>(config.getStringList(path)); groups.addAll(Arrays.asList(toAdd)); config.set(path, groups); } + public static void addAbsentToList(FileConfiguration config, String path, String... toAdd) { + List groups = new ArrayList<>(config.getStringList(path)); + for (String val : toAdd) { + if (groups.contains(val)) continue; + + groups.add(val); + } + config.set(path, groups); + + } + } diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/Update_1_21.java b/src/main/java/xyz/alexcrea/cuanvil/update/Update_1_21.java index 28c7197..332b5fe 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/Update_1_21.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/Update_1_21.java @@ -4,7 +4,7 @@ import io.delilaheve.CustomAnvil; import org.bukkit.configuration.file.FileConfiguration; import xyz.alexcrea.cuanvil.config.ConfigHolder; -import static xyz.alexcrea.cuanvil.update.UpdateUtils.addToStringList; +import static xyz.alexcrea.cuanvil.update.UpdateUtils.addAbsentToList; // This is a temporary class that aim to handle 1.21 update. // It will be replaced by a better system later. @@ -40,26 +40,26 @@ public class Update_1_21 { // Add mace to groups groupConfig.set("mace.type", "include"); - addToStringList(groupConfig, "mace.items", "mace"); + addAbsentToList(groupConfig, "mace.items", "mace"); - addToStringList(groupConfig, "can_unbreak.groups", "mace"); + addAbsentToList(groupConfig, "can_unbreak.groups", "mace"); // Add new enchant conflicts - addToStringList(conflictConfig, "restriction_density.enchantments", "minecraft:density"); - addToStringList(conflictConfig, "restriction_density.notAffectedGroups", "mace", "enchanted_book"); + addAbsentToList(conflictConfig, "restriction_density.enchantments", "minecraft:density"); + addAbsentToList(conflictConfig, "restriction_density.notAffectedGroups", "mace", "enchanted_book"); - addToStringList(conflictConfig, "restriction_breach.enchantments", "minecraft:breach"); - addToStringList(conflictConfig, "restriction_breach.notAffectedGroups", "mace", "enchanted_book"); + addAbsentToList(conflictConfig, "restriction_breach.enchantments", "minecraft:breach"); + addAbsentToList(conflictConfig, "restriction_breach.notAffectedGroups", "mace", "enchanted_book"); - addToStringList(conflictConfig, "restriction_wind_burst.enchantments", "minecraft:wind_burst"); - addToStringList(conflictConfig, "restriction_wind_burst.notAffectedGroups", "mace", "enchanted_book"); + addAbsentToList(conflictConfig, "restriction_wind_burst.enchantments", "minecraft:wind_burst"); + addAbsentToList(conflictConfig, "restriction_wind_burst.notAffectedGroups", "mace", "enchanted_book"); // Add mace to conflicts - addToStringList(conflictConfig, "restriction_fire_aspect.notAffectedGroups", "mace"); - addToStringList(conflictConfig, "restriction_smite.notAffectedGroups", "mace"); - addToStringList(conflictConfig, "restriction_bane_of_arthropods.notAffectedGroups", "mace"); + addAbsentToList(conflictConfig, "restriction_fire_aspect.notAffectedGroups", "mace"); + addAbsentToList(conflictConfig, "restriction_smite.notAffectedGroups", "mace"); + addAbsentToList(conflictConfig, "restriction_bane_of_arthropods.notAffectedGroups", "mace"); - addToStringList(conflictConfig, "sword_enchant_conflict.enchantments", + addAbsentToList(conflictConfig, "sword_enchant_conflict.enchantments", "minecraft:density", "minecraft:breach"); // Add level limit diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/Version.java b/src/main/java/xyz/alexcrea/cuanvil/update/Version.java index ffa8660..e6f63cf 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/Version.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/Version.java @@ -1,6 +1,7 @@ package xyz.alexcrea.cuanvil.update; import javax.annotation.Nonnull; +import javax.annotation.Nullable; public record Version(int major, int minor, int patch) { @@ -11,7 +12,9 @@ public record Version(int major, int minor, int patch) { this(major, 0, 0); } - public static Version fromString(@Nonnull String versionString){ + public static Version fromString(@Nullable String versionString){ + if(versionString == null) return new Version(0, 0, 0); + String[] partialVersion = versionString.split("\\."); int[] versionParts = new int[]{0, 0, 0}; @@ -45,4 +48,8 @@ public record Version(int major, int minor, int patch) { this.patch <= other.patch))); } + @Override + public String toString() { + return major + "." + minor + "." + patch; + } } diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_11_0.java b/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_11_0.java index ff28d75..ac83977 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_11_0.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_11_0.java @@ -8,7 +8,7 @@ import javax.annotation.Nonnull; import java.util.List; import java.util.Set; -import static xyz.alexcrea.cuanvil.update.UpdateUtils.addToStringList; +import static xyz.alexcrea.cuanvil.update.UpdateUtils.addAbsentToList; public class PUpdate_1_11_0 { @@ -57,7 +57,7 @@ public class PUpdate_1_11_0 { } // Finally we know both conflict are default. so we fix - addToStringList(config, "sword_enchant_conflict.enchantments", + addAbsentToList(config, "sword_enchant_conflict.enchantments", "minecraft:density", "minecraft:breach"); config.set("mace_enchant_conflict", null); diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_6_2.java b/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_6_2.java index d004d2d..a4078de 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_6_2.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_6_2.java @@ -1,13 +1,12 @@ package xyz.alexcrea.cuanvil.update.plugin; -import io.delilaheve.CustomAnvil; import org.bukkit.configuration.file.FileConfiguration; import xyz.alexcrea.cuanvil.config.ConfigHolder; import javax.annotation.Nonnull; import java.util.Set; -import static xyz.alexcrea.cuanvil.update.UpdateUtils.addToStringList; +import static xyz.alexcrea.cuanvil.update.UpdateUtils.addAbsentToList; public class PUpdate_1_6_2 { @@ -30,7 +29,7 @@ public class PUpdate_1_6_2 { } if(!contained){ - addToStringList(config, path, "enchanted_book"); + addAbsentToList(config, path, "enchanted_book"); conflictUpdated = true; } } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt index b962b03..1eaaa0e 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt @@ -9,6 +9,7 @@ import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.inventory.AnvilInventory import org.bukkit.inventory.ItemStack import xyz.alexcrea.cuanvil.config.ConfigHolder +import xyz.alexcrea.cuanvil.dependency.datapack.DataPackTest import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester import xyz.alexcrea.cuanvil.dependency.gui.GuiTesterSelector import xyz.alexcrea.cuanvil.dependency.packet.PacketManager @@ -78,12 +79,13 @@ object DependencyManager { havenBagsCompatibility = HavenBagsDependency() havenBagsCompatibility!!.redirectListeners() } - } fun handleCompatibilityConfig() { enchantmentSquaredCompatibility?.registerPluginConfiguration() + // datapacks + DataPackTest.handleDatapackConfigs() } fun registerEnchantments() { diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTest.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTest.kt new file mode 100644 index 0000000..13a29c2 --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTest.kt @@ -0,0 +1,183 @@ +package xyz.alexcrea.cuanvil.dependency.datapack + +import io.delilaheve.CustomAnvil +import org.bukkit.NamespacedKey +import org.bukkit.configuration.file.FileConfiguration +import org.bukkit.configuration.file.YamlConfiguration +import xyz.alexcrea.cuanvil.api.ConflictBuilder +import xyz.alexcrea.cuanvil.api.EnchantmentApi +import xyz.alexcrea.cuanvil.config.ConfigHolder +import xyz.alexcrea.cuanvil.enchant.wrapped.CABukkitEnchantment +import xyz.alexcrea.cuanvil.enchant.wrapped.CAIncompatibleAllEnchant +import xyz.alexcrea.cuanvil.update.UpdateUtils +import xyz.alexcrea.cuanvil.update.Version +import java.io.InputStreamReader + +object DataPackTest { + private val START_DETECT_VERSION = Version(1, 19, 0) + + /** + * Map of the latest CA update related to the pack + */ + private val LASTEST_VERSION = mapOf( + Pair("bracken", Version(1, 11, 0)) + ) + + val enabledDatapack: List + get() { + val version: Version = UpdateUtils.currentMinecraftVersion() + if (version.lesserThan(START_DETECT_VERSION)) return emptyList() + + return DataPackTester.enabledPacks + } + + fun handleDatapackConfigs() { + val enabledDatapack = enabledDatapack + for (packName in enabledDatapack) { + // Handling of pack name is horrible: it is based on file name + // So if someone rename a datapack it will make me sad + + if (packName.startsWith("file/bp_post_scarcity")) { + handlePack("bracken") + continue + } + + } + } + + private fun handlePack(pack: String) { + val defConfig = ConfigHolder.DEFAULT_CONFIG + val version = LASTEST_VERSION[pack] + + val currentVersion = Version.fromString(defConfig.config.getString("datapack.$pack")) + if (currentVersion.greaterEqual(version!!)) return + + // Add pack value or do update from previous version + // note: update thingy is not yet implemented + configureDatapack(pack) + + // Finally, set current pack version to config + //defConfig.config.set("datapack.$pack", version.toString()) // temporary disabled for easier test + defConfig.saveToDisk(true) + } + + private fun configureDatapack(pack: String) { + val itemConflict = javaClass.getResource("/datapack/$pack/item_conflict.yml") + val enchantConflict = javaClass.getResource("/datapack/$pack/enchant_conflict.yml") + + val newConflictList = ArrayList() + var needSave = false + if (itemConflict != null) { + val reader = InputStreamReader(itemConflict.openStream()) + val yml = YamlConfiguration.loadConfiguration(reader) + + addItemConflicts(yml, newConflictList) + } + + if (enchantConflict != null) { + val reader = InputStreamReader(enchantConflict.openStream()) + val yml = YamlConfiguration.loadConfiguration(reader) + + needSave = needSave || addEnchantConflict(yml, newConflictList) + } + + for (conflict in newConflictList) { + needSave = !conflict.registerIfAbsent() && needSave + } + + if (needSave) { + ConfigHolder.CONFLICT_HOLDER.saveToDisk(true) + } + } + + private fun addItemConflicts(yml: FileConfiguration, conflictList: MutableList) { + for (ench in yml.getKeys(false)) { + val groups = yml.getStringList(ench) + + val conflict = ConflictBuilder( + "restriction_${ench.replace(":", "_")}", + CustomAnvil.instance) + conflict.addEnchantment(NamespacedKey.fromString(ench)!!) + for (group in groups) { + conflict.addExcludedGroup(group) + } + conflict.addExcludedGroup("enchanted_book") + + conflictList.add(conflict) + } + } + + private fun addEnchantConflict(yml: YamlConfiguration, conflictList: MutableList): Boolean { + var needSave = false + + val conflicts = HashMap() + for (ench in yml.getKeys(false)) { + val groups = yml.getStringList(ench) + + for (group in groups) { + if (group.startsWith('#')) { + needSave = needSave || joinGroup(conflicts, group.substring(1), ench) + } else { + createConflict(conflictList, ench, group) + } + } + } + + conflictList.addAll(conflicts.values) + return needSave + } + + private fun createConflict(conflictList: MutableList, ench: String, other: String) { + + val conflict = ConflictBuilder( + "conflict_" + + "${ench.replace(":", "_")}_" + + other.replace(":", "_"), + CustomAnvil.instance + ) + conflict.addEnchantment(NamespacedKey.fromString(ench)!!) + conflict.addEnchantment(NamespacedKey.fromString(other)!!) + + conflict.setMaxBeforeConflict(1) + + conflictList.add(conflict) + } + + private fun joinGroup(conflicts: HashMap, group: String, ench: String): Boolean { + if ("all".equals(group, ignoreCase = true)) { + // We assume current is not null and of type CABukkitEnchantment + val current = EnchantmentApi.getByKey(NamespacedKey.fromString(ench)!!) as CABukkitEnchantment + + // We need to replace current wrapped enchantment with the all conflict wrapper + EnchantmentApi.unregisterEnchantment(current) + EnchantmentApi.registerEnchantment(CAIncompatibleAllEnchant(current.bukkit, current.defaultRarity())) + + return false + } else { + val config = ConfigHolder.CONFLICT_HOLDER.config + + // If conflict do not yet exist + if(!config.isConfigurationSection(group)) { + val conflict = conflicts.getOrPut(group) { + val conflict = ConflictBuilder(group, CustomAnvil.instance) + conflict.setMaxBeforeConflict(1) + conflict + } + + conflict.addEnchantment(NamespacedKey.fromString(ench)!!) + } + // Find current conflict + val manager = ConfigHolder.CONFLICT_HOLDER.conflictManager + + // This assumes that: + // - the conflict existing in the config exist in the runtime config + // - the enchantment exist and is provided correctly + val conflict = manager.conflictList.find { it.name == group }!! + conflict.addEnchantment(EnchantmentApi.getByKey(NamespacedKey.fromString(ench)!!)!!) + + UpdateUtils.addAbsentToList(config, "$group.enchantments", ench) + + return true + } + } +} diff --git a/src/main/resources/datapack/bracken/enchant_conflict.yml b/src/main/resources/datapack/bracken/enchant_conflict.yml new file mode 100644 index 0000000..851a398 --- /dev/null +++ b/src/main/resources/datapack/bracken/enchant_conflict.yml @@ -0,0 +1,35 @@ +"bracken:abstraction": ['#sword_enchant_conflict'] +"bracken:antivenom": ['#protection_enchant_conflict'] +"bracken:blinding_fix": ['minecraft:fire_aspect'] +"bracken:boldness": ['#protection_enchant_conflict'] +"bracken:butchering": ['#sword_enchant_conflict'] +"bracken:defusing": ['#sword_enchant_conflict'] +"bracken:dentine_touch": ['#tool_conflict'] +"bracken:dullness_curse": ['minecraft:sharpness'] +"bracken:famine_walker": ['#boot_conflict'] +"bracken:ferocity": ['#sword_enchant_conflict'] +"bracken:flame_walker": ['#boot_conflict'] +"bracken:float_walker": ['#boot_conflict'] +"bracken:flood_walker": ['#boot_conflict'] +"bracken:fragility_curse": ['minecraft:unbreaking'] +"bracken:freezing_fix": ['minecraft:fire_aspect'] +"bracken:guarding": ['#sword_enchant_conflict'] +"bracken:huskiness": ['#bracken_pet_armor'] +"bracken:infused_fire_aspect_fix": ['minecraft:fire_aspect'] +"bracken:infused_frost_walker_fix": ['#boot_conflict'] +"bracken:infused_mending_fix": ['minecraft:mending'] +"bracken:infused_thorns_fix": ['minecraft:thorns'] +"bracken:lethargy_curse": ['bracken:ferocity'] +"bracken:lifesteal": ['#bow_conflict'] +"bracken:litheness": ['#bracken_pet_armor'] +"bracken:lunar_concordance_armor": ['#bracken_lunarite_armor'] +"bracken:lunar_concordance_weapon": ['#bracken_lunarite_weapons'] +"bracken:maiming_curse": ['bracken:vitality_fix'] +"bracken:mortality": ['#sword_enchant_conflict'] +"bracken:poisoning_fix": ['minecraft:fire_aspect'] +"bracken:pugnacity": ['#bracken_pet_armor'] +"bracken:rending": ['#crossbow_conflict'] +"bracken:silvered_fix": ['#all'] +"bracken:vitality_fix": ['bracken:maiming_curse'] +"bracken:weakening_fix": ['minecraft:fire_aspect'] +"bracken:withering_fix": ['minecraft:fire_aspect'] diff --git a/src/main/resources/datapack/bracken/item_conflict.yml b/src/main/resources/datapack/bracken/item_conflict.yml new file mode 100644 index 0000000..1c4d9da --- /dev/null +++ b/src/main/resources/datapack/bracken/item_conflict.yml @@ -0,0 +1,54 @@ +"bracken:abstraction": ['melee_weapons', 'mace'] +"bracken:antivenom": ['armors'] +"bracken:astuteness_fix": ['armors'] +"bracken:blinding_fix": ['can_unbreak'] +"bracken:boldness": ['armors'] +"bracken:butchering": ['melee_weapons', 'mace'] +"bracken:chiseling_fix": ['axes', 'pickaxes', 'shovels', 'hoes'] +"bracken:decaying_fix": ['can_unbreak'] +"bracken:defusing": ['melee_weapons', 'mace'] +"bracken:dentine_touch": ['axes', 'pickaxes', 'shovels', 'hoes'] +"bracken:devouring_curse": ['melee_weapons', 'mace'] +"bracken:dullness_curse": ['melee_weapons', 'mace'] +"bracken:famine_walker": ['boots'] +"bracken:ferocity": ['melee_weapons', 'mace'] +"bracken:flame_walker": ['boots'] +"bracken:float_walker": ['boots'] +"bracken:flood_walker": ['boots'] +"bracken:fragility_curse": ['can_unbreak'] +"bracken:freezing_fix": ['can_unbreak'] +"bracken:guarding": ['melee_weapons', 'mace'] +"bracken:huskiness": ['pet_armor'] +"bracken:infused_fire_aspect_fix": ['melee_weapons', 'mace'] +"bracken:infused_frost_walker_fix": ['boots'] +"bracken:infused_mending_fix": ['can_unbreak'] +"bracken:infused_thorns_fix": ['armors'] +"bracken:integrity_fix": ['armors'] +"bracken:lethargy_curse": ['melee_weapons', 'mace'] +"bracken:lifesteal": ['bow'] +"bracken:litheness": ['pet_armor'] +"bracken:maiming_curse": ['armors'] +"bracken:mortality": ['melee_weapons', 'mace'] +"bracken:poisoning_fix": ['can_unbreak'] +"bracken:pugnacity": ['wolf_armor'] +"bracken:pushback": ['armors'] +"bracken:quenching_fix": ['armors'] +"bracken:rending": ['crossbow'] +"bracken:reverse_thorns": ['axes'] +"bracken:searing_surface": ['armors'] +"bracken:sentience_curse_1": ['can_unbreak'] +"bracken:sentience_curse_2": ['can_unbreak'] +"bracken:sentience_curse_3": ['can_unbreak'] +"bracken:sentience_curse_4": ['can_unbreak'] +"bracken:sentience_curse_5": ['can_unbreak'] +"bracken:sentience_curse_6": ['can_unbreak'] +"bracken:sentience_curse_7": ['can_unbreak'] +"bracken:shrewdness": ['swords'] +"bracken:silvered_fix": ['can_unbreak'] +"bracken:spectrality_fix": ['melee_weapons', 'mace'] +"bracken:splintering": ['bow'] +"bracken:trampling": ['horse_armor'] +"bracken:vitality_fix": ['armors'] +"bracken:weakening_fix": ['can_unbreak'] +"bracken:wisdom": ['tools'] +"bracken:withering_fix": ['can_unbreak'] From 0adc84df8903a641739d788e7b06ab299d7e3664 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sun, 27 Apr 2025 17:35:30 +0200 Subject: [PATCH 03/20] migrate pickaxes, shovels and hoe to there own group --- .../cuanvil/update/plugin/PUpdate_1_11_0.java | 75 +++++++++++++++++-- .../EnchantmentSquaredDependency.kt | 14 ---- src/main/resources/item_groups.yml | 16 +++- 3 files changed, 84 insertions(+), 21 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_11_0.java b/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_11_0.java index ac83977..77b5be2 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_11_0.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_11_0.java @@ -1,8 +1,14 @@ package xyz.alexcrea.cuanvil.update.plugin; +import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.alexcrea.cuanvil.api.MaterialGroupApi; import xyz.alexcrea.cuanvil.config.ConfigHolder; +import xyz.alexcrea.cuanvil.group.AbstractMaterialGroup; +import xyz.alexcrea.cuanvil.group.IncludeGroup; import javax.annotation.Nonnull; import java.util.List; @@ -24,10 +30,66 @@ public class PUpdate_1_11_0 { "bane_of_arthropods" ); - public static void handleUpdate(@Nonnull Set toSave) { - FileConfiguration config = ConfigHolder.DEFAULT_CONFIG.getConfig(); + private static final Material[] PICKAXES = new Material[]{ + Material.WOODEN_PICKAXE, Material.STONE_PICKAXE, + Material.IRON_PICKAXE, Material.DIAMOND_PICKAXE, + Material.GOLDEN_PICKAXE, Material.NETHERITE_PICKAXE + }; + private static final Material[] SHOVELS = new Material[]{ + Material.WOODEN_SHOVEL, Material.STONE_SHOVEL, + Material.IRON_SHOVEL, Material.DIAMOND_SHOVEL, + Material.GOLDEN_SHOVEL, Material.NETHERITE_SHOVEL + }; + + private static final Material[] HOES = new Material[]{ + Material.WOODEN_HOE, Material.STONE_HOE, + Material.IRON_HOE, Material.DIAMOND_HOE, + Material.GOLDEN_HOE, Material.NETHERITE_HOE + }; + + public static void handleUpdate(@Nonnull Set toSave) { + handleToolsMigration(); + handleMaceMigration(toSave); + } + + private static void handleToolsMigration() { // We migrate the mace conflict if exist and unmodified + AbstractMaterialGroup tools = MaterialGroupApi.getGroup("tools"); + + migrateTools(tools, "pickaxes", PICKAXES); + migrateTools(tools, "shovels", SHOVELS); + migrateTools(tools, "hoes", HOES); + } + + private static void migrateTools( + @Nullable AbstractMaterialGroup tools, + @NotNull String toolset, + @NotNull Material[] toolMats) { + + // Create new group + IncludeGroup group = new IncludeGroup(toolset); + group.addAll(toolMats); + + MaterialGroupApi.addMaterialGroup(group, true); + + // Try to see if all the materials was in the tools group. and if so, replace it with the new group + if (tools == null) return; + if (!(tools instanceof IncludeGroup include)) return; + + List mats = List.of(toolMats); + Set matSet = include.getNonGroupInheritedMaterials(); + if (!matSet.containsAll(mats)) return; + + mats.forEach(matSet::remove); + tools.addToPolicy(group); + MaterialGroupApi.writeMaterialGroup(tools); + } + + private static void handleMaceMigration(@Nonnull Set toSave) { + // We migrate the mace conflict if exist and unmodified + FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.getConfig(); + if (!config.isConfigurationSection("sword_enchant_conflict")) return; if (!config.isConfigurationSection("mace_enchant_conflict")) return; @@ -41,19 +103,20 @@ public class PUpdate_1_11_0 { List enchantments = mace_conflict.getStringList("enchantments"); if (enchantments.size() != 4) return; for (String ench : mace_expected) { - if(!enchantments.contains(ench) && !enchantments.contains("minecraft:" + ench)) return; + if (!enchantments.contains(ench) && !enchantments.contains("minecraft:" + ench)) return; } // Test sword_enchant_conflict is default ConfigurationSection sword_conflict = config.getConfigurationSection("sword_enchant_conflict"); if (sword_conflict.getInt("maxEnchantmentBeforeConflict", 0) != 1) return; - if (sword_conflict.isList("notAffectedGroups") && !sword_conflict.getList("notAffectedGroups").isEmpty()) return; + if (sword_conflict.isList("notAffectedGroups") && !sword_conflict.getList("notAffectedGroups").isEmpty()) + return; enchantments = sword_conflict.getStringList("enchantments"); if (enchantments.size() != 3) return; for (String ench : sword_expected) { - if(!enchantments.contains(ench) && !enchantments.contains("minecraft:" + ench)) return; + if (!enchantments.contains(ench) && !enchantments.contains("minecraft:" + ench)) return; } // Finally we know both conflict are default. so we fix @@ -61,7 +124,7 @@ public class PUpdate_1_11_0 { "minecraft:density", "minecraft:breach"); config.set("mace_enchant_conflict", null); - + toSave.add(ConfigHolder.DEFAULT_CONFIG); } } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt index e630e8c..96b485a 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt @@ -101,19 +101,6 @@ 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 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) - - 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) - - 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) - val shield = IncludeGroup("shield") shield.addToPolicy(Material.SHIELD) MaterialGroupApi.addMaterialGroup(shield) @@ -125,7 +112,6 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin) val trinkets = IncludeGroup("trinkets") trinkets.addToPolicy(Material.ROTTEN_FLESH) MaterialGroupApi.addMaterialGroup(trinkets) - } private fun writeMaterialRestriction(esEnchantments: List){ diff --git a/src/main/resources/item_groups.yml b/src/main/resources/item_groups.yml index 3c1eb5d..8a62f3d 100644 --- a/src/main/resources/item_groups.yml +++ b/src/main/resources/item_groups.yml @@ -126,7 +126,7 @@ wearable: groups: - armors -tools: +pickaxes: type: include items: - wooden_pickaxe @@ -135,19 +135,33 @@ tools: - diamond_pickaxe - golden_pickaxe - netherite_pickaxe + +shovels: + type: include + items: - wooden_shovel - stone_shovel - iron_shovel - diamond_shovel - golden_shovel - netherite_shovel + +hoes: + type: include + items: - wooden_hoe - stone_hoe - iron_hoe - diamond_hoe - golden_hoe - netherite_hoe + +tools: + type: include groups: + - pickaxes + - shovels + - hoes - axes enchanted_book: From 43b4e72c49a25cafd2ce407b31782a461f7033ba Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sun, 27 Apr 2025 17:59:04 +0200 Subject: [PATCH 04/20] add missing groups --- .../cuanvil/dependency/DependencyManager.kt | 4 +- ...{DataPackTest.kt => DataPackDependency.kt} | 52 ++++++++++++++++++- .../datapack/bracken/item_groups.yml | 15 ++++++ 3 files changed, 68 insertions(+), 3 deletions(-) rename src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/{DataPackTest.kt => DataPackDependency.kt} (78%) create mode 100644 src/main/resources/datapack/bracken/item_groups.yml diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt index 1eaaa0e..cb612a4 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt @@ -9,7 +9,7 @@ import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.inventory.AnvilInventory import org.bukkit.inventory.ItemStack import xyz.alexcrea.cuanvil.config.ConfigHolder -import xyz.alexcrea.cuanvil.dependency.datapack.DataPackTest +import xyz.alexcrea.cuanvil.dependency.datapack.DataPackDependency import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester import xyz.alexcrea.cuanvil.dependency.gui.GuiTesterSelector import xyz.alexcrea.cuanvil.dependency.packet.PacketManager @@ -85,7 +85,7 @@ object DependencyManager { enchantmentSquaredCompatibility?.registerPluginConfiguration() // datapacks - DataPackTest.handleDatapackConfigs() + DataPackDependency.handleDatapackConfigs() } fun registerEnchantments() { diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTest.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt similarity index 78% rename from src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTest.kt rename to src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt index 13a29c2..8538224 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTest.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt @@ -1,19 +1,22 @@ package xyz.alexcrea.cuanvil.dependency.datapack import io.delilaheve.CustomAnvil +import org.bukkit.Material import org.bukkit.NamespacedKey import org.bukkit.configuration.file.FileConfiguration import org.bukkit.configuration.file.YamlConfiguration 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.wrapped.CABukkitEnchantment import xyz.alexcrea.cuanvil.enchant.wrapped.CAIncompatibleAllEnchant +import xyz.alexcrea.cuanvil.group.IncludeGroup import xyz.alexcrea.cuanvil.update.UpdateUtils import xyz.alexcrea.cuanvil.update.Version import java.io.InputStreamReader -object DataPackTest { +object DataPackDependency { private val START_DETECT_VERSION = Version(1, 19, 0) /** @@ -62,9 +65,17 @@ object DataPackTest { } private fun configureDatapack(pack: String) { + val itemGroups = javaClass.getResource("/datapack/$pack/item_groups.yml") val itemConflict = javaClass.getResource("/datapack/$pack/item_conflict.yml") val enchantConflict = javaClass.getResource("/datapack/$pack/enchant_conflict.yml") + if (itemGroups != null) { + val reader = InputStreamReader(itemGroups.openStream()) + val yml = YamlConfiguration.loadConfiguration(reader) + + handleItemGroups(yml) + } + val newConflictList = ArrayList() var needSave = false if (itemConflict != null) { @@ -90,6 +101,45 @@ object DataPackTest { } } + // Order matter for this file + // Could rewrite to not matter but not really important, so I keep it like that + private fun handleItemGroups(yml: YamlConfiguration) { + for (groupName in yml.getKeys(false)) { + val section = yml.getConfigurationSection(groupName) ?: continue + + var group = MaterialGroupApi.getGroup(groupName) + val exist = group != null + + if(group == null) group = IncludeGroup(groupName) + + for (name in section.getStringList("items")) { + val mat = Material.getMaterial(name.uppercase()) + if(mat == null){ + CustomAnvil.instance.logger.warning("Could not find material $name for item group $groupName") + continue + } + group.addToPolicy(mat) + } + for (name in section.getStringList("groups")) { + val otherGroup = MaterialGroupApi.getGroup(name) + if(otherGroup == null){ + CustomAnvil.instance.logger.warning("Could not find sub group $name for group $groupName") + continue + } + + group.addToPolicy(otherGroup) + } + + group.updateMaterials() + + if(exist){ + MaterialGroupApi.writeMaterialGroup(group) + }else{ + MaterialGroupApi.addMaterialGroup(group, true) + } + } + } + private fun addItemConflicts(yml: FileConfiguration, conflictList: MutableList) { for (ench in yml.getKeys(false)) { val groups = yml.getStringList(ench) diff --git a/src/main/resources/datapack/bracken/item_groups.yml b/src/main/resources/datapack/bracken/item_groups.yml new file mode 100644 index 0000000..8248f0c --- /dev/null +++ b/src/main/resources/datapack/bracken/item_groups.yml @@ -0,0 +1,15 @@ +horse_armor: + items: + - leather_horse_armor + - iron_horse_armor + - golden_horse_armor + - diamond_horse_armor + +wolf_armor: + items: + - wolf_armor + +pet_armor: + groups: + - wolf_armor + - horse_armor \ No newline at end of file From 92960ca819a10c938568046cfc57c30388081d8a Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sun, 27 Apr 2025 19:17:15 +0200 Subject: [PATCH 05/20] make sure "all" conflict are always registered --- .../dependency/datapack/DataPackDependency.kt | 59 +++++++++++++------ 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt index 8538224..9d0bc68 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt @@ -53,14 +53,17 @@ object DataPackDependency { val version = LASTEST_VERSION[pack] val currentVersion = Version.fromString(defConfig.config.getString("datapack.$pack")) - if (currentVersion.greaterEqual(version!!)) return + if (currentVersion.greaterEqual(version!!)) { + handleEnchantAllConflict(pack) + return + } // Add pack value or do update from previous version // note: update thingy is not yet implemented configureDatapack(pack) // Finally, set current pack version to config - //defConfig.config.set("datapack.$pack", version.toString()) // temporary disabled for easier test + defConfig.config.set("datapack.$pack", version.toString()) defConfig.saveToDisk(true) } @@ -89,7 +92,7 @@ object DataPackDependency { val reader = InputStreamReader(enchantConflict.openStream()) val yml = YamlConfiguration.loadConfiguration(reader) - needSave = needSave || addEnchantConflict(yml, newConflictList) + needSave = addEnchantConflict(yml, newConflictList) } for (conflict in newConflictList) { @@ -110,11 +113,11 @@ object DataPackDependency { var group = MaterialGroupApi.getGroup(groupName) val exist = group != null - if(group == null) group = IncludeGroup(groupName) + if (group == null) group = IncludeGroup(groupName) for (name in section.getStringList("items")) { val mat = Material.getMaterial(name.uppercase()) - if(mat == null){ + if (mat == null) { CustomAnvil.instance.logger.warning("Could not find material $name for item group $groupName") continue } @@ -122,7 +125,7 @@ object DataPackDependency { } for (name in section.getStringList("groups")) { val otherGroup = MaterialGroupApi.getGroup(name) - if(otherGroup == null){ + if (otherGroup == null) { CustomAnvil.instance.logger.warning("Could not find sub group $name for group $groupName") continue } @@ -132,9 +135,9 @@ object DataPackDependency { group.updateMaterials() - if(exist){ + if (exist) { MaterialGroupApi.writeMaterialGroup(group) - }else{ + } else { MaterialGroupApi.addMaterialGroup(group, true) } } @@ -146,7 +149,8 @@ object DataPackDependency { val conflict = ConflictBuilder( "restriction_${ench.replace(":", "_")}", - CustomAnvil.instance) + CustomAnvil.instance + ) conflict.addEnchantment(NamespacedKey.fromString(ench)!!) for (group in groups) { conflict.addExcludedGroup(group) @@ -166,7 +170,7 @@ object DataPackDependency { for (group in groups) { if (group.startsWith('#')) { - needSave = needSave || joinGroup(conflicts, group.substring(1), ench) + needSave = joinGroup(conflicts, group.substring(1), ench) || needSave } else { createConflict(conflictList, ench, group) } @@ -193,21 +197,24 @@ object DataPackDependency { conflictList.add(conflict) } + private fun setEnchantAsAll(ench: String) { + // We assume current is not null and of type CABukkitEnchantment + val current = EnchantmentApi.getByKey(NamespacedKey.fromString(ench)!!) as CABukkitEnchantment + + // We need to replace current wrapped enchantment with the all conflict wrapper + EnchantmentApi.unregisterEnchantment(current) + EnchantmentApi.registerEnchantment(CAIncompatibleAllEnchant(current.bukkit, current.defaultRarity())) + } + private fun joinGroup(conflicts: HashMap, group: String, ench: String): Boolean { if ("all".equals(group, ignoreCase = true)) { - // We assume current is not null and of type CABukkitEnchantment - val current = EnchantmentApi.getByKey(NamespacedKey.fromString(ench)!!) as CABukkitEnchantment - - // We need to replace current wrapped enchantment with the all conflict wrapper - EnchantmentApi.unregisterEnchantment(current) - EnchantmentApi.registerEnchantment(CAIncompatibleAllEnchant(current.bukkit, current.defaultRarity())) - + setEnchantAsAll(ench) return false } else { val config = ConfigHolder.CONFLICT_HOLDER.config // If conflict do not yet exist - if(!config.isConfigurationSection(group)) { + if (!config.isConfigurationSection(group)) { val conflict = conflicts.getOrPut(group) { val conflict = ConflictBuilder(group, CustomAnvil.instance) conflict.setMaxBeforeConflict(1) @@ -230,4 +237,20 @@ object DataPackDependency { return true } } + + private fun handleEnchantAllConflict(pack: String) { + val enchantConflict = javaClass.getResource("/datapack/$pack/enchant_conflict.yml") ?: return + + val reader = InputStreamReader(enchantConflict.openStream()) + val yml = YamlConfiguration.loadConfiguration(reader) + + for (ench in yml.getKeys(false)) { + val groups = yml.getStringList(ench) + + if (groups.contains("#all")) { + setEnchantAsAll(ench) + } + } + } + } From 007f6be7f186402fcd2b5803ae32fc9f4ca42140 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sun, 27 Apr 2025 19:32:36 +0200 Subject: [PATCH 06/20] fix missing return statement --- .../cuanvil/dependency/datapack/DataPackDependency.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt index 9d0bc68..a2426e4 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt @@ -222,6 +222,7 @@ object DataPackDependency { } conflict.addEnchantment(NamespacedKey.fromString(ench)!!) + return false } // Find current conflict val manager = ConfigHolder.CONFLICT_HOLDER.conflictManager @@ -229,11 +230,12 @@ object DataPackDependency { // This assumes that: // - the conflict existing in the config exist in the runtime config // - the enchantment exist and is provided correctly - val conflict = manager.conflictList.find { it.name == group }!! - conflict.addEnchantment(EnchantmentApi.getByKey(NamespacedKey.fromString(ench)!!)!!) + val conflict = manager.conflictList.find { + it.name.equals(group, ignoreCase = true) + } + conflict!!.addEnchantment(EnchantmentApi.getByKey(NamespacedKey.fromString(ench)!!)!!) UpdateUtils.addAbsentToList(config, "$group.enchantments", ench) - return true } } From c9d95b69af16e262ba74da992becd7c80bc4175a Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sun, 27 Apr 2025 20:00:41 +0200 Subject: [PATCH 07/20] write correctly group on the api --- .../alexcrea/cuanvil/api/MaterialGroupApi.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java index 250f797..48dd500 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java @@ -105,7 +105,9 @@ public class MaterialGroupApi { if (group instanceof IncludeGroup includeGroup) { changed = writeKnownGroup("include", includeGroup); } else if (group instanceof ExcludeGroup excludeGroup) { - changed = writeKnownGroup("exclude", excludeGroup); + throw new UnsupportedOperationException("exclude group is temporarily disable for the time being. sorry"); + // This code do not do what is intended ? idk why do it exist + //changed = writeKnownGroup("exclude", excludeGroup); } else { changed = writeUnknownGroup(group); } @@ -124,13 +126,24 @@ public class MaterialGroupApi { Set materialSet = group.getNonGroupInheritedMaterials(); Set groupSet = group.getGroups(); + boolean empty = true; if (!materialSet.isEmpty()) { config.set(basePath + ItemGroupManager.MATERIAL_LIST_PATH, materialSetToStringList(materialSet)); + empty = false; + } else { + config.set(basePath + ItemGroupManager.MATERIAL_LIST_PATH, null); } if (!groupSet.isEmpty()) { config.set(basePath + ItemGroupManager.GROUP_LIST_PATH, materialGroupSetToStringList(groupSet)); + empty = false; + } else { + config.set(basePath + ItemGroupManager.GROUP_LIST_PATH, null); + } + + if (empty) { + config.set(basePath + ItemGroupManager.GROUP_TYPE_PATH, null); + return false; } - if (!config.isConfigurationSection(group.getName())) return false; config.set(basePath + ItemGroupManager.GROUP_TYPE_PATH, groupType); return true; From 431e61b2f223140e02986e842cece09f0f90b8fa Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sun, 27 Apr 2025 20:03:39 +0200 Subject: [PATCH 08/20] use correct config holder --- .../java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_11_0.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_11_0.java b/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_11_0.java index 77b5be2..6d6baca 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_11_0.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_11_0.java @@ -124,7 +124,7 @@ public class PUpdate_1_11_0 { "minecraft:density", "minecraft:breach"); config.set("mace_enchant_conflict", null); - toSave.add(ConfigHolder.DEFAULT_CONFIG); + toSave.add(ConfigHolder.CONFLICT_HOLDER); } } From 1ba5d8d38d71fcaf48f3a5f70f1f8147163c0bb0 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sun, 27 Apr 2025 20:05:55 +0200 Subject: [PATCH 09/20] version up --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 49e296c..ed4b5df 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -16,7 +16,7 @@ plugins { } group = "xyz.alexcrea" -version = "1.10.1" +version = "1.11.0" repositories { // EcoEnchants From 5f5339a669d86757a29673b2120cab31a8cb6ce4 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Wed, 30 Apr 2025 16:20:54 +0200 Subject: [PATCH 10/20] made pack detection more leniant --- .../cuanvil/dependency/datapack/DataPackDependency.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt index a2426e4..96350a9 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt @@ -39,8 +39,10 @@ object DataPackDependency { for (packName in enabledDatapack) { // Handling of pack name is horrible: it is based on file name // So if someone rename a datapack it will make me sad + if(!packName.startsWith("file/")) continue - if (packName.startsWith("file/bp_post_scarcity")) { + if (packName.contains("bp_post_scarcity", ignoreCase = true) + || packName.contains("bracken", ignoreCase = true)) { handlePack("bracken") continue } From f9da8ad6ef88a5db16a2c1ed11b7246e680118f4 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Wed, 30 Apr 2025 16:31:35 +0200 Subject: [PATCH 11/20] fix conflict with all --- .../cuanvil/enchant/wrapped/CAIncompatibleAllEnchant.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAIncompatibleAllEnchant.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAIncompatibleAllEnchant.java index 7aeae2d..71df9db 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAIncompatibleAllEnchant.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAIncompatibleAllEnchant.java @@ -25,7 +25,7 @@ public class CAIncompatibleAllEnchant extends CABukkitEnchantment implements Add @Override public boolean isEnchantConflict(@NotNull Map enchantments, @NotNull Material itemMat) { - return true; + return !enchantments.isEmpty(); } @Override From 41f785a6f69ed3a9cdb87a7894690db7c1e878ca Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Wed, 30 Apr 2025 16:42:37 +0200 Subject: [PATCH 12/20] better log --- .../cuanvil/group/EnchantConflictManager.kt | 57 +++++++++++-------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt index 1273c8e..169d9e9 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt @@ -31,8 +31,9 @@ class EnchantConflictManager { // 1.20.5 compatibility TODO better update system private val SWEEPING_EDGE_ENCHANT = Collections.singletonList( - CAEnchantment.getByKey(NamespacedKey.minecraft("sweeping_edge")) ?: - CAEnchantment.getByKey(Enchantment.SWEEPING_EDGE.key)) + CAEnchantment.getByKey(NamespacedKey.minecraft("sweeping_edge")) + ?: CAEnchantment.getByKey(Enchantment.SWEEPING_EDGE.key) + ) } @@ -46,7 +47,7 @@ class EnchantConflictManager { for (enchant in CAEnchantmentRegistry.getInstance().values()) { enchant.clearConflict() } - + val keys = config.getKeys(false) for (key in keys) { val section = config.getConfigurationSection(key)!! @@ -57,12 +58,12 @@ class EnchantConflictManager { } - fun addConflict(conflict: EnchantConflictGroup){ + fun addConflict(conflict: EnchantConflictGroup) { addConflictToEnchantments(conflict) conflictList.add(conflict) } - fun removeConflict(conflict: EnchantConflictGroup){ + fun removeConflict(conflict: EnchantConflictGroup) { removeConflictFromEnchantments(conflict) conflictList.remove(conflict) } @@ -114,14 +115,14 @@ class EnchantConflictManager { private fun getEnchantByIdentifier(enchantName: String): List { val key = NamespacedKey.fromString(enchantName) - if(key != null){ + if (key != null) { val enchantment = CAEnchantment.getByKey(key) - if(enchantment != null) return Collections.singletonList(enchantment) + if (enchantment != null) return Collections.singletonList(enchantment) } // Temporary solution for 1.20.5 - when(enchantName){ + when (enchantName) { "minecraft:sweeping", "sweeping", "minecraft:sweeping_edge", "sweeping_edge" -> { return SWEEPING_EDGE_ENCHANT @@ -169,22 +170,31 @@ class EnchantConflictManager { return group } - fun isConflicting(appliedEnchants: Map, item: ItemStack, newEnchant: CAEnchantment): ConflictType { + fun isConflicting( + appliedEnchants: Map, + item: ItemStack, + newEnchant: CAEnchantment + ): ConflictType { val mat = item.type CustomAnvil.verboseLog("Testing conflict for ${newEnchant.key} on ${mat.key}") val conflictList = newEnchant.conflicts var result = ConflictType.NO_CONFLICT for (conflict in conflictList) { - CustomAnvil.verboseLog("Is against $conflict") + val isBigConflict = conflict.getEnchants().size > 1 + if (result == ConflictType.ITEM_CONFLICT && !isBigConflict) { + CustomAnvil.verboseLog("skipping small conflict ${conflict.name}") + continue + } + val allowed = conflict.allowed(appliedEnchants.keys, mat) CustomAnvil.verboseLog("Was against $conflict and conflicting: ${!allowed} ") if (!allowed) { if (conflict.getEnchants().size <= 1) { result = ConflictType.ITEM_CONFLICT - CustomAnvil.verboseLog("Small conflict, continuing") + CustomAnvil.verboseLog("Small conflict (${conflict.name}), continuing") } else { - CustomAnvil.verboseLog("Big conflict, probably stoping") + CustomAnvil.verboseLog("Big conflict (${conflict.name}), stopping") return ConflictType.ENCHANTMENT_CONFLICT } } @@ -192,19 +202,20 @@ class EnchantConflictManager { val immutableEnchants = Collections.unmodifiableMap(appliedEnchants) for (appliedEnchant in appliedEnchants.keys) { - if(appliedEnchant is AdditionalTestEnchantment){ + if (appliedEnchant is AdditionalTestEnchantment) { val doConflict = appliedEnchant.isEnchantConflict(immutableEnchants, mat) - if(doConflict){ + if (doConflict) { + CustomAnvil.verboseLog("Big conflict by additional test, stopping") return ConflictType.ENCHANTMENT_CONFLICT } } } - if((result != ConflictType.ITEM_CONFLICT) && (newEnchant is AdditionalTestEnchantment)){ + if ((result != ConflictType.ITEM_CONFLICT) && (newEnchant is AdditionalTestEnchantment)) { val partialItem = createPartialResult(item, immutableEnchants) - if(newEnchant.isItemConflict(immutableEnchants, mat, partialItem)){ + if (newEnchant.isItemConflict(immutableEnchants, mat, partialItem)) { return ConflictType.ITEM_CONFLICT } @@ -214,14 +225,14 @@ class EnchantConflictManager { } private fun createPartialResult(item: ItemStack, enchantments: Map): ItemStack { - val newItem = item.clone() + val newItem = item.clone() - CAEnchantment.clearEnchants(newItem) - enchantments.forEach{ - enchantment -> enchantment.key.addEnchantmentUnsafe(newItem, enchantment.value) - } + CAEnchantment.clearEnchants(newItem) + enchantments.forEach { enchantment -> + enchantment.key.addEnchantmentUnsafe(newItem, enchantment.value) + } - return newItem + return newItem } } @@ -247,7 +258,7 @@ enum class ConflictType(private val importance: Int) { ENCHANTMENT_CONFLICT(2); fun getWorstConflict(otherConflict: ConflictType): ConflictType { - return if(this.importance > otherConflict.importance) this + return if (this.importance > otherConflict.importance) this else otherConflict } From 2df791877b138fb7995d839fa52c273e1e553d80 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Wed, 30 Apr 2025 16:49:32 +0200 Subject: [PATCH 13/20] fix all conflict issue once again --- .../cuanvil/enchant/wrapped/CAIncompatibleAllEnchant.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAIncompatibleAllEnchant.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAIncompatibleAllEnchant.java index 71df9db..218ce87 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAIncompatibleAllEnchant.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAIncompatibleAllEnchant.java @@ -25,7 +25,7 @@ public class CAIncompatibleAllEnchant extends CABukkitEnchantment implements Add @Override public boolean isEnchantConflict(@NotNull Map enchantments, @NotNull Material itemMat) { - return !enchantments.isEmpty(); + return !enchantments.isEmpty() && !(enchantments.size() == 1 && enchantments.containsKey(this)); } @Override From ee5c31ad40a822c3e4cc67950fb660a0e46bef96 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Thu, 1 May 2025 11:13:31 +0200 Subject: [PATCH 14/20] add write default for braken enchantments --- .../cuanvil/dependency/datapack/DataPackDependency.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt index 96350a9..3766e2b 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt @@ -44,6 +44,7 @@ object DataPackDependency { if (packName.contains("bp_post_scarcity", ignoreCase = true) || packName.contains("bracken", ignoreCase = true)) { handlePack("bracken") + writeDefaultByNamespace("bracken") continue } @@ -257,4 +258,13 @@ object DataPackDependency { } } + private fun writeDefaultByNamespace(namespace: String) { + for (enchantment in EnchantmentApi.getRegisteredEnchantments().values) { + if(!enchantment.key.namespace.equals(namespace, ignoreCase = true)) continue + + EnchantmentApi.writeDefaultConfig(enchantment, false) + } + + } + } From b67d956e3951be1c9a43edc24ba106e7b0ee436a Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Thu, 1 May 2025 19:01:16 +0200 Subject: [PATCH 15/20] fix inverted equal logic --- .../xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java | 4 ++-- .../alexcrea/cuanvil/enchant/wrapped/CABukkitEnchantment.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java index 5e2b1c1..4634a11 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java @@ -76,12 +76,12 @@ public class CAEnchantmentRegistry { */ public boolean register(@NotNull CAEnchantment enchantment) { if (byKeyMap.containsKey(enchantment.getKey())) { - if (!enchantment.equals(byKeyMap.get(enchantment.getKey()))) { + if (Objects.equals(enchantment, byKeyMap.get(enchantment.getKey()))) { // We are trying to register the exact same enchantment. so we just skip it. return false; } - if(ConfigHolder.DEFAULT_CONFIG.getConfig().getBoolean("caution_secret_do_not_log_duplicated_registered_key", false)){ + if (ConfigHolder.DEFAULT_CONFIG.getConfig().getBoolean("caution_secret_do_not_log_duplicated_registered_key", false)) { return false; } diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CABukkitEnchantment.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CABukkitEnchantment.java index db809ce..1a72458 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CABukkitEnchantment.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CABukkitEnchantment.java @@ -18,6 +18,7 @@ import java.lang.reflect.Method; import java.util.HashMap; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.logging.Level; /** @@ -163,7 +164,7 @@ public class CABukkitEnchantment extends CAEnchantmentBase { return false; } - return this.bukkit.equals(other.getEnchant()); + return Objects.equals(this.bukkit, other.getEnchant()); } } From f4ce267e445bceb351c26a848721e0673d7a0f3d Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Thu, 1 May 2025 19:31:21 +0200 Subject: [PATCH 16/20] add immutable list --- .../io/delilaheve/util/ConfigOptions.kt | 16 +++ .../cuanvil/listener/PrepareAnvilListener.kt | 107 +++++++++++++----- 2 files changed, 93 insertions(+), 30 deletions(-) diff --git a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt index d9d1f87..980999f 100644 --- a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt +++ b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt @@ -2,6 +2,7 @@ package io.delilaheve.util import io.delilaheve.CustomAnvil import io.delilaheve.util.EnchantmentUtil.enchantmentName +import org.bukkit.NamespacedKey import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.config.WorkPenaltyType import xyz.alexcrea.cuanvil.config.WorkPenaltyType.WorkPenaltyPart @@ -51,6 +52,8 @@ object ConfigOptions { const val DISABLE_MERGE_OVER_ROOT = "disable-merge-over" + const val IMMUTABLE_ENCHANTMENT_LIST = "immutable_enchantments" + // Keys for specific enchantment values private const val KEY_BOOK = "book" private const val KEY_ITEM = "item" @@ -478,4 +481,17 @@ object ConfigOptions { .takeIf { it in ENCHANT_LIMIT_RANGE } } + fun isImmutable(key: NamespacedKey): Boolean { + val immutables = ConfigHolder.DEFAULT_CONFIG.config.getStringList(IMMUTABLE_ENCHANTMENT_LIST) + + // We need to ignore case so can't just check "contain" + for (ench in immutables) { + if (ench.equals(key.toString(), ignoreCase = true) || + ench.equals(key.key, ignoreCase = true) + ) + return true + } + return false + } + } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt index 5708126..4cae038 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt @@ -19,6 +19,8 @@ import org.bukkit.event.Listener import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.inventory.AnvilInventory import org.bukkit.inventory.ItemStack +import org.bukkit.inventory.meta.EnchantmentStorageMeta +import org.bukkit.inventory.meta.ItemMeta import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.util.* import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair @@ -52,13 +54,21 @@ class PrepareAnvilListener : Listener { val first = inventory.getItem(ANVIL_INPUT_LEFT) ?: return val second = inventory.getItem(ANVIL_INPUT_RIGHT) + if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return + if (isImmutable(first) || isImmutable(second)) { + CustomAnvil.verboseLog("Skipping anvil process as one of the two item is immutable") + + event.result = null + return + } + // Test custom recipe - if(testCustomRecipe(event, inventory, player, first, second)) return + if (testCustomRecipe(event, inventory, player, first, second)) return // Test rename lonely item - if(second == null) { + if (second == null) { doRenaming(event, inventory, player, first) return } @@ -70,23 +80,51 @@ class PrepareAnvilListener : Listener { } // Test for unit repair - if(testUnitRepair(event, inventory, player, first, second)) return + if (testUnitRepair(event, inventory, player, first, second)) return // Test for lore edit - if(testLoreEdit(event, inventory, player, first, second)) return + if (testLoreEdit(event, inventory, player, first, second)) return CustomAnvil.log("no anvil fuse type found") event.result = null } + private fun isImmutable(item: ItemStack?): Boolean { + if (item == null) return false + + val meta = item.itemMeta + return meta != null && + (hasImmutableEnchants(meta) || hasImmutableStoredEnchants(meta)) + } + + private fun hasImmutableEnchants(meta: ItemMeta): Boolean { + if (!meta.hasEnchants()) return false + + for (enchant in meta.enchants.keys) { + if (ConfigOptions.isImmutable(enchant.key)) return true + } + return false + } + + private fun hasImmutableStoredEnchants(meta: ItemMeta): Boolean { + if (meta !is EnchantmentStorageMeta || !meta.hasStoredEnchants()) return false + + for (enchant in meta.storedEnchants.keys) { + if (ConfigOptions.isImmutable(enchant.key)) return true + } + return false + } + // return true if a custom recipe exist with these ingredients - private fun testCustomRecipe(event: PrepareAnvilEvent, inventory: AnvilInventory, - player: HumanEntity, - first: ItemStack, second: ItemStack?): Boolean { + private fun testCustomRecipe( + event: PrepareAnvilEvent, inventory: AnvilInventory, + player: HumanEntity, + first: ItemStack, second: ItemStack? + ): Boolean { val recipe = CustomRecipeUtil.getCustomRecipe(first, second) CustomAnvil.verboseLog("custom recipe not null? ${recipe != null}") - if(recipe == null) return false + if (recipe == null) return false val amount = CustomRecipeUtil.getCustomRecipeAmount(recipe, first, second) @@ -94,7 +132,7 @@ class PrepareAnvilListener : Listener { resultItem.amount *= amount event.result = resultItem - if(DependencyManager.tryTreatAnvilResult(event, resultItem)) return true + if (DependencyManager.tryTreatAnvilResult(event, resultItem)) return true // Maybe add an option on custom craft to ignore/not ignore penalty ?? var xpCost = recipe.xpCostPerCraft * amount @@ -105,8 +143,10 @@ class PrepareAnvilListener : Listener { return true } - private fun doRenaming(event: PrepareAnvilEvent, inventory: AnvilInventory, - player: HumanEntity, first: ItemStack) { + private fun doRenaming( + event: PrepareAnvilEvent, inventory: AnvilInventory, + player: HumanEntity, first: ItemStack + ) { val resultItem = first.clone() var anvilCost = handleRename(resultItem, inventory, player) @@ -118,7 +158,7 @@ class PrepareAnvilListener : Listener { } event.result = resultItem - if(DependencyManager.tryTreatAnvilResult(event, resultItem)) return + if (DependencyManager.tryTreatAnvilResult(event, resultItem)) return anvilCost += AnvilXpUtil.calculatePenalty(first, null, resultItem, AnvilUseType.RENAME_ONLY) @@ -131,18 +171,20 @@ class PrepareAnvilListener : Listener { var sumCost = 0 var useColor = false - if(ConfigOptions.renameColorPossible && inventoryName != null){ + if (ConfigOptions.renameColorPossible && inventoryName != null) { val resultString = StringBuilder(inventoryName) - useColor = AnvilColorUtil.handleColor(resultString, player, + useColor = AnvilColorUtil.handleColor( + resultString, player, ConfigOptions.permissionNeededForColor, ConfigOptions.allowColorCode, ConfigOptions.allowHexadecimalColor, - AnvilColorUtil.ColorUseType.RENAME) + AnvilColorUtil.ColorUseType.RENAME + ) - if(useColor) { + if (useColor) { inventoryName = resultString.toString() - sumCost+= ConfigOptions.useOfColorCost + sumCost += ConfigOptions.useOfColorCost } } @@ -165,9 +207,11 @@ class PrepareAnvilListener : Listener { return 0 } - private fun doMerge(event: PrepareAnvilEvent, inventory: AnvilInventory, - player: HumanEntity, - first: ItemStack, second: ItemStack) { + private fun doMerge( + event: PrepareAnvilEvent, inventory: AnvilInventory, + player: HumanEntity, + first: ItemStack, second: ItemStack + ) { val newEnchants = first.findEnchantments() .combineWith(second.findEnchantments(), first, player) val resultItem = first.clone() @@ -195,14 +239,16 @@ class PrepareAnvilListener : Listener { // Finally, we set result event.result = resultItem - if(DependencyManager.tryTreatAnvilResult(event, resultItem)) return + if (DependencyManager.tryTreatAnvilResult(event, resultItem)) return AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost) } // return true if there is a valid unit repair with these ingredients - private fun testUnitRepair(event: PrepareAnvilEvent, inventory: AnvilInventory, player: HumanEntity, - first: ItemStack, second: ItemStack): Boolean { + private fun testUnitRepair( + event: PrepareAnvilEvent, inventory: AnvilInventory, player: HumanEntity, + first: ItemStack, second: ItemStack + ): Boolean { val unitRepairAmount = first.getRepair(second) ?: return false val resultItem = first.clone() @@ -222,26 +268,27 @@ class PrepareAnvilListener : Listener { return true } event.result = resultItem - if(DependencyManager.tryTreatAnvilResult(event, resultItem)) return true + if (DependencyManager.tryTreatAnvilResult(event, resultItem)) return true AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost) return true } - private fun testLoreEdit(event: PrepareAnvilEvent, inventory: AnvilInventory, player: HumanEntity, - first: ItemStack, second: ItemStack): Boolean { + private fun testLoreEdit( + event: PrepareAnvilEvent, inventory: AnvilInventory, player: HumanEntity, + first: ItemStack, second: ItemStack + ): Boolean { val type = second.type var result: ItemStack? = null val xpCost = AtomicInteger() - if(Material.WRITABLE_BOOK == type) { + if (Material.WRITABLE_BOOK == type) { result = AnvilLoreEditUtil.tryLoreEditByBook(player, first, second, xpCost) - } - else if(Material.PAPER == type) { + } else if (Material.PAPER == type) { result = AnvilLoreEditUtil.tryLoreEditByPaper(player, first, second, xpCost) } - if(result == null || first == result) { + if (result == null || first == result) { CustomAnvil.log("lore edit, But input is same as output") event.result = null return false From 8f408438dcc5321659128a1583ae374c163291ed Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Thu, 1 May 2025 19:44:07 +0200 Subject: [PATCH 17/20] make immutability test before pre anvil bypass event --- .../alexcrea/cuanvil/listener/PrepareAnvilListener.kt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt index 4cae038..138546a 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt @@ -47,16 +47,10 @@ class PrepareAnvilListener : Listener { // Should find player val player: HumanEntity = InventoryViewUtil.getInstance().getPlayer(event.view) - // Test if the event should bypass custom anvil. - if (DependencyManager.tryEventPreAnvilBypass(event, player)) return - val inventory = event.inventory val first = inventory.getItem(ANVIL_INPUT_LEFT) ?: return val second = inventory.getItem(ANVIL_INPUT_RIGHT) - - if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return - if (isImmutable(first) || isImmutable(second)) { CustomAnvil.verboseLog("Skipping anvil process as one of the two item is immutable") @@ -64,6 +58,11 @@ class PrepareAnvilListener : Listener { return } + // Test if the event should bypass custom anvil. + if (DependencyManager.tryEventPreAnvilBypass(event, player)) return + + if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return + // Test custom recipe if (testCustomRecipe(event, inventory, player, first, second)) return From 368b4b2c841823c6aa0d6bf0148e2b477115f27d Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Fri, 2 May 2025 12:46:19 +0200 Subject: [PATCH 18/20] made early bypass --- .../cuanvil/dependency/DependencyManager.kt | 33 ++++++++++++++++--- .../cuanvil/listener/PrepareAnvilListener.kt | 3 ++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt index cb612a4..71dce33 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt @@ -102,6 +102,35 @@ object DependencyManager { // Then handle plugin reload ecoEnchantCompatibility?.handleConfigReload() } + // Return true if should bypass (either by a dependency or error) + // called before immutability test + fun earlyTryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean { + try { + return earlyUnsafeTryEventPreAnvilBypass(event, player) + } catch (e: Exception) { + CustomAnvil.instance.logger.log( + Level.SEVERE, + "Error while trying to handle custom anvil supported plugin: ", + e + ) + + // Just in case to avoid illegal items + event.inventory.setItem(ANVIL_OUTPUT_SLOT, null) + + // Finally, warn the player, maybe a lot of time but better warn than do nothing + event.view.player.sendMessage(ChatColor.RED.toString() + "Error while handling the anvil.") + return true + } + } + + private fun earlyUnsafeTryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean { + var bypass = false + + // Test if the inventory is a gui(version specific) + if (externGuiTester?.testIfGui(event.view) == true) bypass = true + + return bypass + } // Return true if should bypass (either by a dependency or error) fun tryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean { @@ -135,10 +164,6 @@ object DependencyManager { // Test excellent enchantments used prepare anvil if (!bypass && (excellentEnchantsCompatibility?.testPrepareAnvil(event) == true)) bypass = true - // Test if the inventory is a gui(version specific) - if (!bypass && (externGuiTester?.testIfGui(event.view) == true)) bypass = true - - return bypass } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt index 138546a..9d7245a 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt @@ -47,6 +47,9 @@ class PrepareAnvilListener : Listener { // Should find player val player: HumanEntity = InventoryViewUtil.getInstance().getPlayer(event.view) + // Test if custom anvil is bypassed before immutability test + if (DependencyManager.earlyTryEventPreAnvilBypass(event, player)) return + val inventory = event.inventory val first = inventory.getItem(ANVIL_INPUT_LEFT) ?: return val second = inventory.getItem(ANVIL_INPUT_RIGHT) From e25723d921cf2690ccebc75781328024c11de98d Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sat, 3 May 2025 05:44:28 +0200 Subject: [PATCH 19/20] small changes --- .../dependency/datapack/DataPackDependency.kt | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt index 3766e2b..22b9252 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt @@ -20,13 +20,13 @@ object DataPackDependency { private val START_DETECT_VERSION = Version(1, 19, 0) /** - * Map of the latest CA update related to the pack + * Map of the latest CustomAnvil update related to the pack */ private val LASTEST_VERSION = mapOf( Pair("bracken", Version(1, 11, 0)) ) - val enabledDatapack: List + val enabledDatapacks: List get() { val version: Version = UpdateUtils.currentMinecraftVersion() if (version.lesserThan(START_DETECT_VERSION)) return emptyList() @@ -35,7 +35,7 @@ object DataPackDependency { } fun handleDatapackConfigs() { - val enabledDatapack = enabledDatapack + val enabledDatapack = enabledDatapacks for (packName in enabledDatapack) { // Handling of pack name is horrible: it is based on file name // So if someone rename a datapack it will make me sad @@ -44,14 +44,20 @@ object DataPackDependency { if (packName.contains("bp_post_scarcity", ignoreCase = true) || packName.contains("bracken", ignoreCase = true)) { handlePack("bracken") - writeDefaultByNamespace("bracken") continue } } } - private fun handlePack(pack: String) { + private fun handlePack(pack: String){ + CustomAnvil.instance.logger.info("handling datapack $pack") + handlePackInitialConfig(pack) + writeDefaultByNamespace(pack) + CustomAnvil.instance.logger.info("configuration done for $pack") + } + + private fun handlePackInitialConfig(pack: String) { val defConfig = ConfigHolder.DEFAULT_CONFIG val version = LASTEST_VERSION[pack] From 3427c8f381d789b127f54ed20379b5d84a7ec647 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sat, 3 May 2025 06:32:20 +0200 Subject: [PATCH 20/20] add warning on unexpected issues --- .../dependency/datapack/DataPackDependency.kt | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt index 22b9252..bf39295 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt @@ -51,7 +51,7 @@ object DataPackDependency { } private fun handlePack(pack: String){ - CustomAnvil.instance.logger.info("handling datapack $pack") + CustomAnvil.instance.logger.info("trying to handle datapack $pack") handlePackInitialConfig(pack) writeDefaultByNamespace(pack) CustomAnvil.instance.logger.info("configuration done for $pack") @@ -237,12 +237,25 @@ object DataPackDependency { val manager = ConfigHolder.CONFLICT_HOLDER.conflictManager // This assumes that: - // - the conflict existing in the config exist in the runtime config + // - the conflict existing in the config exist in the runtime config (as configuration section exist) // - the enchantment exist and is provided correctly val conflict = manager.conflictList.find { it.name.equals(group, ignoreCase = true) } - conflict!!.addEnchantment(EnchantmentApi.getByKey(NamespacedKey.fromString(ench)!!)!!) + if(conflict == null) { + // This should not happen as configuration section + CustomAnvil.instance.logger.severe("Could not find $group while its configuration section exist... this should NOT happen") + return false + } + + val key = NamespacedKey.fromString(ench)!! + val enchant = EnchantmentApi.getByKey(key) + if (enchant == null){ + CustomAnvil.instance.logger.severe("Could not find enchantment $ench while configuring pack a datapack") + return false + } + + conflict.addEnchantment(enchant) UpdateUtils.addAbsentToList(config, "$group.enchantments", ench) return true @@ -268,6 +281,7 @@ object DataPackDependency { for (enchantment in EnchantmentApi.getRegisteredEnchantments().values) { if(!enchantment.key.namespace.equals(namespace, ignoreCase = true)) continue + CustomAnvil.log("Writing default for $enchantment") EnchantmentApi.writeDefaultConfig(enchantment, false) }