From 97b714a9ac27e34b66ddcf99f9d869b471c2e77d Mon Sep 17 00:00:00 2001 From: Zefir Kirilov Date: Sat, 13 Jun 2026 22:28:31 +0300 Subject: [PATCH 1/5] unregister permissions on disable --- .../smp/enchantbookplus/EnchantBookPlus.java | 3 ++- .../smp/enchantbookplus/Permissions.java | 24 ++++++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/main/java/pro/cloudnode/smp/enchantbookplus/EnchantBookPlus.java b/src/main/java/pro/cloudnode/smp/enchantbookplus/EnchantBookPlus.java index 695d27e..7bb5615 100644 --- a/src/main/java/pro/cloudnode/smp/enchantbookplus/EnchantBookPlus.java +++ b/src/main/java/pro/cloudnode/smp/enchantbookplus/EnchantBookPlus.java @@ -87,7 +87,7 @@ void reload() { @Override public void onEnable() { - Permissions.init(this); + Permissions.register(this); Objects.requireNonNull(getCommand("enchantbookplus")).setExecutor(new MainCommand(this)); registerEvents(); @@ -99,5 +99,6 @@ public void onEnable() { public void onDisable() { allConfigEnchantment = null; configEnchantments.clear(); + Permissions.unregister(this); } } diff --git a/src/main/java/pro/cloudnode/smp/enchantbookplus/Permissions.java b/src/main/java/pro/cloudnode/smp/enchantbookplus/Permissions.java index fe0c9a7..1a05007 100644 --- a/src/main/java/pro/cloudnode/smp/enchantbookplus/Permissions.java +++ b/src/main/java/pro/cloudnode/smp/enchantbookplus/Permissions.java @@ -7,27 +7,39 @@ import org.bukkit.plugin.PluginManager; import org.jspecify.annotations.NullMarked; +import java.util.function.Consumer; + @NullMarked public final class Permissions { - public final static String RELOAD = "enchantbookplus.reload"; + public static final String RELOAD = "enchantbookplus.reload"; public static String enchant(final Enchantment enchantment) { return "enchantbookplus.enchant." + enchantment.getKey().getKey(); } - public static void init(final EnchantBookPlus plugin) { + + public static void register(final EnchantBookPlus plugin) { + final PluginManager pm = plugin.getServer().getPluginManager(); + forEach(pm::addPermission); + } + + public static void unregister(final EnchantBookPlus plugin) { final PluginManager pm = plugin.getServer().getPluginManager(); + forEach(pm::removePermission); + } - pm.addPermission(new Permission( + private static void forEach(final Consumer consumer) { + consumer.accept(new Permission( RELOAD, "Reload plugin config using ‘/enchantbookplus reload’", PermissionDefault.OP )); - for (Enchantment enchantment : Registry.ENCHANTMENT) { - pm.addPermission(new Permission( + for (final Enchantment enchantment : Registry.ENCHANTMENT) { + consumer.accept(new Permission( enchant(enchantment), - "Allow enchanting " + enchantment.getKey() + "above the vanilla level, as configured in the plugin", + "Allow enchanting " + enchantment.getKey() + + " above the vanilla level, as configured in the plugin", PermissionDefault.TRUE )); } From 7041d68a4b2348c7dacb37d185b0c113b601d44d Mon Sep 17 00:00:00 2001 From: Zefir Kirilov Date: Fri, 17 Jul 2026 14:36:25 +0300 Subject: [PATCH 2/5] add custom enchant namespace to permission node --- .../pro/cloudnode/smp/enchantbookplus/Permissions.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/pro/cloudnode/smp/enchantbookplus/Permissions.java b/src/main/java/pro/cloudnode/smp/enchantbookplus/Permissions.java index 1a05007..844b297 100644 --- a/src/main/java/pro/cloudnode/smp/enchantbookplus/Permissions.java +++ b/src/main/java/pro/cloudnode/smp/enchantbookplus/Permissions.java @@ -1,5 +1,6 @@ package pro.cloudnode.smp.enchantbookplus; +import org.bukkit.NamespacedKey; import org.bukkit.Registry; import org.bukkit.enchantments.Enchantment; import org.bukkit.permissions.Permission; @@ -14,9 +15,12 @@ public final class Permissions { public static final String RELOAD = "enchantbookplus.reload"; public static String enchant(final Enchantment enchantment) { - return "enchantbookplus.enchant." + enchantment.getKey().getKey(); - } + if (enchantment.getKey().getNamespace().equals(NamespacedKey.MINECRAFT)) { + return "enchantbookplus.enchant." + enchantment.getKey().getKey(); + } + return "enchantbookplus.enchant." + enchantment.getKey().getNamespace() + "." + enchantment.getKey().getKey(); + } public static void register(final EnchantBookPlus plugin) { final PluginManager pm = plugin.getServer().getPluginManager(); From 1b9c62693c0542bb0e3c1bb8cdd293cdff465fbf Mon Sep 17 00:00:00 2001 From: Zefir Kirilov Date: Fri, 17 Jul 2026 15:03:39 +0300 Subject: [PATCH 3/5] allow specifying namespace in enchants config --- .../smp/enchantbookplus/ConfigEnchantmentEntry.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/pro/cloudnode/smp/enchantbookplus/ConfigEnchantmentEntry.java b/src/main/java/pro/cloudnode/smp/enchantbookplus/ConfigEnchantmentEntry.java index a305ac3..4741ffe 100644 --- a/src/main/java/pro/cloudnode/smp/enchantbookplus/ConfigEnchantmentEntry.java +++ b/src/main/java/pro/cloudnode/smp/enchantbookplus/ConfigEnchantmentEntry.java @@ -219,7 +219,7 @@ public final boolean getMultiplyCostByLevel() { * Get enchantment */ public final Enchantment getEnchantment() { - return Objects.requireNonNull(Registry.ENCHANTMENT.get(NamespacedKey.minecraft(name))); + return Objects.requireNonNull(Registry.ENCHANTMENT.get(Objects.requireNonNull(NamespacedKey.fromString(name)))); } /** @@ -228,7 +228,12 @@ public final Enchantment getEnchantment() { * @param enchantment The enchantment */ public final boolean isEnchantment(final Enchantment enchantment) { - return name.equalsIgnoreCase(enchantment.getKey().getKey()); + if (!enchantment.getKey().getNamespace().equals(NamespacedKey.MINECRAFT)) { + return name.equalsIgnoreCase(enchantment.getKey().getNamespace() + ":" + enchantment.getKey().getKey()); + } + + return name.equalsIgnoreCase(enchantment.getKey().getKey()) + || name.equalsIgnoreCase(enchantment.getKey().getNamespace() + ":" + enchantment.getKey().getKey()); } public static final class AllConfigEnchantmentEntry extends ConfigEnchantmentEntry { @@ -252,7 +257,7 @@ public static AllConfigEnchantmentEntry from(final ConfigEnchantmentEntry config public ConfigEnchantmentEntry enchant(final Enchantment enchantment) { return new ConfigEnchantmentEntry( - enchantment.getKey().getKey(), + enchantment.getKey().getNamespace() + ":" + enchantment.getKey().getKey(), this.maxLevel, maxLevelRelative, cost, From 78128c40e90790d3eb6d2f60e7afa68c74486d91 Mon Sep 17 00:00:00 2001 From: Zefir Kirilov Date: Thu, 22 Oct 2026 11:30:58 +0300 Subject: [PATCH 4/5] add custom enchants to docs --- README.md | 17 +++++++++++------ src/main/resources/config.yml | 4 ++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 2cc7829..3c2f036 100644 --- a/README.md +++ b/README.md @@ -26,12 +26,17 @@ See the [default config](https://github.com/cloudnode-pro/EnchantBookPlus/blob/m > [!NOTE] > `` is the enchantment ID, e.g. `swift_sneak`, `efficiency`, etc. Replace with `*` for all enchantments. > -> Example: `enchantbookplus.enchant.*` or `enchantbookplus.enchant.unbreaking` - -| Permission | Description | Default | -|-----------------------------------------|----------------------------------------------------------------------------------------|----------| -| `enchantbookplus.enchant.` | Allow enchanting `` above the vanilla level, as configured in the plugin. | Everyone | -| `enchantbookplus.reload` | Reload plugin config using `/enchantbookplus reload` | OP | +> For custom enchantments, the `` prefix is required and must specify the namespace of the plugin or datapack +> which registered the enchantment. +> +> Example: `enchantbookplus.enchant.*`, `enchantbookplus.enchant.unbreaking`, or +> `enchantbookplus.enchant.someplugin.enchantname`. + +| Permission | Description | Default | +|-----------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|----------| +| `enchantbookplus.enchant.` | Allow enchanting `` above the vanilla level, as configured in the plugin. | Everyone | +| `enchantbookplus.enchant..` | Allow enchanting the custom enchantment `` from the `` plugin/datapack above its maximum level, as configured in this plugin. | Everyone | +| `enchantbookplus.reload` | Reload plugin config using `/enchantbookplus reload` | OP | ## Reporting issues Fixing bugs is the utmost priority for this project. diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 80ee22a..8904676 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,8 +1,8 @@ # List of enchantments for which to enable upgrading above the vanilla max levels using an anvil. enchantments: # Enchantment name (same as in the /enchant command). - # Set this to "ALL" to enable upgrading for all other enchantments not listed here. - # NOTE: Enchantments that on Vanilla have a max level of 1 (e.g. Silk Touch, Mending, Curse of Vanishing, Infinity) etc. are always ignored by this plugin. + # Vanilla enchantments can be written with or without the namespace, e.g. "efficiency" or "minecraft:efficiency". + # Custom enchantments must include their plugin or datapack namespace, in the form "namespace:key". - name: efficiency # Maximum level to which the enchantment can be upgraded. # For relative levels above the vanilla max level, use e.g. "+1". E.g. +1 for Protection will allow upgrading to Protection V. For Efficiency, +1 will allow upgrading to Efficiency VI. From 12d5f8ab90882175f3789bc2a71a7cf0c36cd803 Mon Sep 17 00:00:00 2001 From: Zefir Kirilov Date: Thu, 22 Oct 2026 12:02:53 +0300 Subject: [PATCH 5/5] add note about ALL --- src/main/resources/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 8904676..3e87168 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -16,6 +16,7 @@ enchantments: # You can also just provide a flat value for all levels, e.g. "10" will cost 10 XP levels regardless of the enchantment level cost: "*150" + # "ALL" affects all other enchantments not listed above. - name: ALL max-level: "+1" cost: 100