From 59922ceb3450e6c308cea875e979ff2b848c2b63 Mon Sep 17 00:00:00 2001 From: Zefir Kirilov Date: Mon, 29 Dec 2025 13:03:14 +0200 Subject: [PATCH 1/4] Code quality improvements --- pom.xml | 20 -- .../ConfigEnchantmentEntry.java | 186 ++++++++++++------ .../smp/enchantbookplus/EnchantBookPlus.java | 48 +++-- .../smp/enchantbookplus/MainCommand.java | 33 +++- .../smp/enchantbookplus/Permissions.java | 14 +- .../enchantbookplus/event/PrepareAnvil.java | 114 ++++++++--- 6 files changed, 265 insertions(+), 150 deletions(-) diff --git a/pom.xml b/pom.xml index ff5b534..9f34833 100644 --- a/pom.xml +++ b/pom.xml @@ -27,22 +27,6 @@ ${java.version} - - org.apache.maven.plugins - maven-shade-plugin - 3.6.1 - - - package - - shade - - - false - - - - @@ -57,10 +41,6 @@ papermc-repo https://repo.papermc.io/repository/maven-public/ - - sonatype - https://oss.sonatype.org/content/groups/public/ - diff --git a/src/main/java/pro/cloudnode/smp/enchantbookplus/ConfigEnchantmentEntry.java b/src/main/java/pro/cloudnode/smp/enchantbookplus/ConfigEnchantmentEntry.java index 3910363..f48a60b 100644 --- a/src/main/java/pro/cloudnode/smp/enchantbookplus/ConfigEnchantmentEntry.java +++ b/src/main/java/pro/cloudnode/smp/enchantbookplus/ConfigEnchantmentEntry.java @@ -1,13 +1,14 @@ package pro.cloudnode.smp.enchantbookplus; import org.bukkit.NamespacedKey; +import org.bukkit.Registry; import org.bukkit.enchantments.Enchantment; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @@ -38,19 +39,16 @@ public class ConfigEnchantmentEntry { */ protected final boolean multiplyCostByLevel; - /** - * Name of the enchantment. - */ - public final @NotNull String getName() { - return name; - } - /** * Maximum level of the enchantment. */ - public final @NotNull Optional<@NotNull Integer> getMaxLevel() { - if (Optional.ofNullable(maxLevel).isEmpty()) return Optional.empty(); - if (maxLevelRelative) return Optional.of(getEnchantment().getMaxLevel() + maxLevel); + public final @NotNull Optional getMaxLevel() { + if (Optional.ofNullable(maxLevel).isEmpty()) + return Optional.empty(); + + if (maxLevelRelative) + return Optional.of(getEnchantment().getMaxLevel() + maxLevel); + return Optional.of(maxLevel); } @@ -72,7 +70,7 @@ public final boolean getMultiplyCostByLevel() { * Get enchantment */ public final Enchantment getEnchantment() { - return Enchantment.getByKey(NamespacedKey.minecraft(name)); + return Registry.ENCHANTMENT.get(NamespacedKey.minecraft(name)); } /** @@ -91,7 +89,13 @@ public final boolean isEnchantment(final @NotNull Enchantment enchantment) { * @param cost Cost of the enchantment. * @param multiplyCostByLevel Multiply cost by level. */ - public ConfigEnchantmentEntry(final @NotNull String name, final @Nullable Integer maxLevel, final boolean maxLevelRelative, final int cost, final boolean multiplyCostByLevel) { + public ConfigEnchantmentEntry( + final @NotNull String name, + final @Nullable Integer maxLevel, + final boolean maxLevelRelative, + final int cost, + final boolean multiplyCostByLevel + ) { this.name = name; this.maxLevel = maxLevel; this.maxLevelRelative = maxLevelRelative; @@ -104,12 +108,27 @@ public ConfigEnchantmentEntry(final @NotNull String name, final @Nullable Intege * * @param configValue Config object */ - public static @NotNull ConfigEnchantmentEntry configValue(final @NotNull HashMap<@NotNull String, @NotNull Object> configValue) { - final @NotNull String name = (String) Objects.requireNonNull(configValue.get("name")); + public static @NotNull ConfigEnchantmentEntry configValue( + final @NotNull Map<@NotNull String, @NotNull Object> configValue + ) throws NumberFormatException, IndexOutOfBoundsException, ClassCastException { + final String name = (String) Objects.requireNonNull(configValue.get("name")); + final @Nullable Integer maxLevel; + final boolean maxLevelRelative; - if (configValue.containsKey("max-level")) { - if (configValue.get("max-level") instanceof final @NotNull String string) { + + if (!configValue.containsKey("max-level")) { + maxLevel = null; + maxLevelRelative = false; + } + + else { + if (!(configValue.get("max-level") instanceof final String string)) { + maxLevel = (Integer) configValue.get("max-level"); + maxLevelRelative = false; + } + + else { if (string.startsWith("+")) { maxLevel = Integer.parseInt(string.substring(1)); maxLevelRelative = true; @@ -119,38 +138,36 @@ public ConfigEnchantmentEntry(final @NotNull String name, final @Nullable Intege maxLevelRelative = false; } } - else { - maxLevel = (Integer) configValue.get("max-level"); - maxLevelRelative = false; - } - } - else { - maxLevel = null; - maxLevelRelative = false; - } - final boolean multiplyCostByLevel; - final int cost; - if (configValue.containsKey("cost")) { - if (configValue.get("cost") instanceof final @NotNull String costString) { - if (costString.startsWith("*")) { - multiplyCostByLevel = true; - cost = Integer.parseInt(costString.substring(1)); - } - else { - multiplyCostByLevel = false; - cost = Integer.parseInt(costString); - } - } - else { - multiplyCostByLevel = false; - cost = (Integer) configValue.get("cost"); - } - } - else { - multiplyCostByLevel = false; - cost = 0; } - return new ConfigEnchantmentEntry(name, maxLevel, maxLevelRelative, cost, multiplyCostByLevel); + + if (!configValue.containsKey("cost")) + return new ConfigEnchantmentEntry(name, maxLevel, maxLevelRelative, 0, false); + + if (!(configValue.get("cost") instanceof final @NotNull String costString)) + return new ConfigEnchantmentEntry( + name, + maxLevel, + maxLevelRelative, + (Integer) configValue.get("cost"), + false + ); + + if (costString.startsWith("*")) + return new ConfigEnchantmentEntry( + name, + maxLevel, + maxLevelRelative, + Integer.parseInt(costString.substring(1)), + true + ); + + return new ConfigEnchantmentEntry( + name, + maxLevel, + maxLevelRelative, + Integer.parseInt(costString), + false + ); } @@ -159,7 +176,9 @@ public ConfigEnchantmentEntry(final @NotNull String name, final @Nullable Intege * * @param configValue Config object array */ - public static @NotNull List<@NotNull ConfigEnchantmentEntry> configArray(final @NotNull ArrayList<@NotNull HashMap<@NotNull String, @NotNull Object>> configValue) { + public static @NotNull List<@NotNull ConfigEnchantmentEntry> configArray( + final @NotNull ArrayList<@NotNull Map<@NotNull String, @NotNull Object>> configValue + ) throws NumberFormatException, IndexOutOfBoundsException, ClassCastException { return configValue.stream().map(ConfigEnchantmentEntry::configValue).collect(Collectors.toList()); } @@ -169,17 +188,33 @@ public ConfigEnchantmentEntry(final @NotNull String name, final @Nullable Intege * @param configValue Config object */ private static boolean isValidConfigValue(final @Nullable Object configValue) { - if (configValue == null) return false; - if (!(configValue instanceof final @NotNull ArrayList arrayList)) return false; - for (final @NotNull Object object : arrayList) { - if (!(object instanceof final @NotNull HashMap hashMap)) return false; - if (!hashMap.containsKey("name")) return false; - if (!(hashMap.get("name") instanceof String)) return false; - if (hashMap.containsKey("max-level") && !(hashMap.get("max-level") instanceof String) && !(hashMap.get("max-level") instanceof Integer)) + if (configValue == null) + return false; + + if (!(configValue instanceof final ArrayList arrayList)) + return false; + + for (final Object object : arrayList) { + if (!(object instanceof final Map hashMap)) return false; - if (hashMap.containsKey("cost") && !(hashMap.get("cost") instanceof String) && !(hashMap.get("cost") instanceof Integer)) + + if (!hashMap.containsKey("name")) + return false; + + if (!(hashMap.get("name") instanceof String)) + return false; + + if (hashMap.containsKey("max-level") && + !(hashMap.get("max-level") instanceof String) && + !(hashMap.get("max-level") instanceof Integer)) + return false; + + if (hashMap.containsKey("cost") && + !(hashMap.get("cost") instanceof String) && + !(hashMap.get("cost") instanceof Integer)) return false; } + return true; } @@ -188,22 +223,45 @@ private static boolean isValidConfigValue(final @Nullable Object configValue) { * * @param configValue Config object */ - public static @NotNull List<@NotNull ConfigEnchantmentEntry> config(final @Nullable Object configValue) throws IllegalArgumentException { - if (!isValidConfigValue(configValue)) throw new IllegalArgumentException("Invalid config value"); - return configArray((ArrayList>) configValue); + public static @NotNull List<@NotNull ConfigEnchantmentEntry> config( + final @Nullable Object configValue + ) throws IllegalArgumentException, IndexOutOfBoundsException, ClassCastException { + if (!isValidConfigValue(configValue)) + throw new IllegalArgumentException("Invalid config value"); + + //noinspection unchecked + return configArray((ArrayList>) configValue); } public static final class AllConfigEnchantmentEntry extends ConfigEnchantmentEntry { - private AllConfigEnchantmentEntry(final @Nullable Integer maxLevel, final boolean maxLevelRelative, final int cost, final boolean multiplyCostByLevel) { + private AllConfigEnchantmentEntry( + final @Nullable Integer maxLevel, + final boolean maxLevelRelative, + final int cost, + final boolean multiplyCostByLevel + ) { super("ALL", maxLevel, maxLevelRelative, cost, multiplyCostByLevel); } - public static @NotNull AllConfigEnchantmentEntry from(final @NotNull ConfigEnchantmentEntry configEnchantmentEntry) { - return new AllConfigEnchantmentEntry(configEnchantmentEntry.maxLevel, configEnchantmentEntry.maxLevelRelative, configEnchantmentEntry.cost, configEnchantmentEntry.multiplyCostByLevel); + public static @NotNull AllConfigEnchantmentEntry from( + final @NotNull ConfigEnchantmentEntry configEnchantmentEntry + ) { + return new AllConfigEnchantmentEntry( + configEnchantmentEntry.maxLevel, + configEnchantmentEntry.maxLevelRelative, + configEnchantmentEntry.cost, + configEnchantmentEntry.multiplyCostByLevel + ); } public @NotNull ConfigEnchantmentEntry enchant(final @NotNull Enchantment enchantment) { - return new ConfigEnchantmentEntry(enchantment.getKey().getKey(), this.maxLevel, maxLevelRelative, cost, multiplyCostByLevel); + return new ConfigEnchantmentEntry( + enchantment.getKey().getKey(), + this.maxLevel, + maxLevelRelative, + cost, + multiplyCostByLevel + ); } } } diff --git a/src/main/java/pro/cloudnode/smp/enchantbookplus/EnchantBookPlus.java b/src/main/java/pro/cloudnode/smp/enchantbookplus/EnchantBookPlus.java index 606a777..cdc6e1d 100644 --- a/src/main/java/pro/cloudnode/smp/enchantbookplus/EnchantBookPlus.java +++ b/src/main/java/pro/cloudnode/smp/enchantbookplus/EnchantBookPlus.java @@ -14,18 +14,11 @@ import java.util.stream.Collectors; public final class EnchantBookPlus extends JavaPlugin { - /** - * Get plugin instance. - */ - public static EnchantBookPlus getInstance() { - return getPlugin(EnchantBookPlus.class); - } - /** * Register event listeners. */ private void registerEvents() { - getServer().getPluginManager().registerEvents(new PrepareAnvil(), this); + getServer().getPluginManager().registerEvents(new PrepareAnvil(this), this); } /** @@ -36,7 +29,7 @@ private void registerEvents() { /** * Config enchantments cache */ - public @NotNull List<@NotNull ConfigEnchantmentEntry> getConfigEnchantments() { + @NotNull List<@NotNull ConfigEnchantmentEntry> getConfigEnchantments() { return configEnchantments; } @@ -48,7 +41,7 @@ private void registerEvents() { /** * "ALL" enchantment cache */ - public @NotNull Optional getAllConfigEnchantment() { + public @NotNull Optional getAllConfigEnchantment() { return Optional.ofNullable(allConfigEnchantment); } @@ -58,33 +51,47 @@ private void registerEvents() { * @param enchantment The Minecraft enchantment */ public @NotNull Optional<@NotNull ConfigEnchantmentEntry> getConfigEnchantment(final @NotNull Enchantment enchantment) { - final @NotNull Optional<@NotNull ConfigEnchantmentEntry> entry = getConfigEnchantments().stream().filter(c -> c.isEnchantment(enchantment)).findFirst(); - return entry.isEmpty() ? getAllConfigEnchantment().map(a -> a.enchant(enchantment)) : entry; + final Optional entry = getConfigEnchantments().stream() + .filter(c -> c.isEnchantment(enchantment)) + .findFirst(); + + return entry.isEmpty() + ? getAllConfigEnchantment().map(a -> a.enchant(enchantment)) + : entry; } /** * Reload config */ - public void reload() { + void reload() { reloadConfig(); - final @NotNull List<@NotNull ConfigEnchantmentEntry> enchants; + + final List enchants; + try { enchants = ConfigEnchantmentEntry.config(getConfig().get("enchantments")); } - catch (final @NotNull Exception exception) { + catch (final IllegalArgumentException | IndexOutOfBoundsException | ClassCastException exception) { getLogger().log(Level.SEVERE, "Failed to load config", exception); getServer().getPluginManager().disablePlugin(this); return; } + allConfigEnchantment = enchants.stream() - .filter(c -> c.name.equalsIgnoreCase("ALL")).findFirst().map(ConfigEnchantmentEntry.AllConfigEnchantmentEntry::from).orElse(null); - configEnchantments = enchants.stream().filter(c -> !c.name.equalsIgnoreCase("ALL")).collect(Collectors.toList()); + .filter(c -> c.name.equalsIgnoreCase("ALL")) + .findFirst() + .map(ConfigEnchantmentEntry.AllConfigEnchantmentEntry::from) + .orElse(null); + + configEnchantments = enchants.stream() + .filter(c -> !c.name.equalsIgnoreCase("ALL")) + .collect(Collectors.toList()); } @Override public void onEnable() { - Permissions.init(); - Objects.requireNonNull(getCommand("enchantbookplus")).setExecutor(new MainCommand()); + Permissions.init(this); + Objects.requireNonNull(getCommand("enchantbookplus")).setExecutor(new MainCommand(this)); registerEvents(); saveDefaultConfig(); @@ -93,6 +100,7 @@ public void onEnable() { @Override public void onDisable() { - // Plugin shutdown logic + allConfigEnchantment = null; + configEnchantments.clear(); } } diff --git a/src/main/java/pro/cloudnode/smp/enchantbookplus/MainCommand.java b/src/main/java/pro/cloudnode/smp/enchantbookplus/MainCommand.java index 854cf3d..514fda0 100644 --- a/src/main/java/pro/cloudnode/smp/enchantbookplus/MainCommand.java +++ b/src/main/java/pro/cloudnode/smp/enchantbookplus/MainCommand.java @@ -12,10 +12,17 @@ import java.util.Optional; public final class MainCommand implements CommandExecutor, TabCompleter { + private final @NotNull EnchantBookPlus plugin; + + public MainCommand(final @NotNull EnchantBookPlus plugin) { + this.plugin = plugin; + } + @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String @NotNull [] args) { if (args.length == 1 && args[0].equalsIgnoreCase("reload")) return reload(sender, command); + return overview(sender); } @@ -23,19 +30,22 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command public @NotNull List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String @NotNull [] args) { if (sender.hasPermission(Permissions.RELOAD)) return List.of("reload"); + return List.of(); } /** * Plugin overview */ - public static boolean overview(final @NotNull CommandSender sender) { - final @NotNull EnchantBookPlus plugin = EnchantBookPlus.getInstance(); + @SuppressWarnings({"UnstableApiUsage", "SameReturnValue"}) + public boolean overview(final @NotNull CommandSender sender) { sender.sendMessage(MiniMessage.miniMessage() - .deserialize(" v by ", Placeholder.unparsed("name", plugin - .getPluginMeta().getName()), Placeholder.unparsed("version", plugin.getPluginMeta() - .getVersion()), Placeholder.unparsed("author", String.join(", ", plugin.getPluginMeta() - .getAuthors())))); + .deserialize( + " v by ", + Placeholder.unparsed("name", plugin.getPluginMeta().getName()), + Placeholder.unparsed("version", plugin.getPluginMeta().getVersion()), + Placeholder.unparsed("author", String.join(", ", plugin.getPluginMeta().getAuthors())) + )); return true; } @@ -43,13 +53,18 @@ public static boolean overview(final @NotNull CommandSender sender) { /** * Reload plugin configuration */ - public static boolean reload(final @NotNull CommandSender sender, final @NotNull Command command) { + @SuppressWarnings("SameReturnValue") + public boolean reload(final @NotNull CommandSender sender, final @NotNull Command command) { if (!sender.hasPermission(Permissions.RELOAD)) { - sender.sendMessage(Optional.ofNullable(command.permissionMessage()).orElse(sender.getServer().permissionMessage())); + sender.sendMessage(Optional.ofNullable(command.permissionMessage()) + .orElse(sender.getServer().permissionMessage())); return true; } - EnchantBookPlus.getInstance().reload(); + + plugin.reload(); + sender.sendMessage(MiniMessage.miniMessage().deserialize("(!) Plugin configuration reloaded.")); + return true; } } diff --git a/src/main/java/pro/cloudnode/smp/enchantbookplus/Permissions.java b/src/main/java/pro/cloudnode/smp/enchantbookplus/Permissions.java index 60761eb..1e28772 100644 --- a/src/main/java/pro/cloudnode/smp/enchantbookplus/Permissions.java +++ b/src/main/java/pro/cloudnode/smp/enchantbookplus/Permissions.java @@ -12,19 +12,23 @@ public final class Permissions { return "enchantbookplus.enchant." + enchantment.getKey().getKey(); } - public static @NotNull String RELOAD = "enchantbookplus.reload"; + public final static @NotNull String RELOAD = "enchantbookplus.reload"; + + public static void init(final @NotNull EnchantBookPlus plugin) { + final PluginManager pm = plugin.getServer().getPluginManager(); - public static void init() { - final @NotNull PluginManager pm = EnchantBookPlus.getInstance().getServer().getPluginManager(); pm.addPermission(new Permission( RELOAD, - "Reload plugin config using `/enchantbookplus reload`", + "Reload plugin config using ‘/enchantbookplus reload’", PermissionDefault.OP )); + for (Enchantment enchantment : Registry.ENCHANTMENT) pm.addPermission(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 )); } diff --git a/src/main/java/pro/cloudnode/smp/enchantbookplus/event/PrepareAnvil.java b/src/main/java/pro/cloudnode/smp/enchantbookplus/event/PrepareAnvil.java index 79557bb..a5ed3b7 100644 --- a/src/main/java/pro/cloudnode/smp/enchantbookplus/event/PrepareAnvil.java +++ b/src/main/java/pro/cloudnode/smp/enchantbookplus/event/PrepareAnvil.java @@ -19,55 +19,105 @@ import java.util.Optional; public final class PrepareAnvil implements Listener { + final @NotNull EnchantBookPlus plugin; + + public PrepareAnvil(final @NotNull EnchantBookPlus plugin) { + this.plugin = plugin; + } + @EventHandler public void onPrepareAnvil(final @NotNull PrepareAnvilEvent event) { - final @NotNull Optional<@NotNull ItemStack> result = Optional.ofNullable(event.getResult()); - if (result.isEmpty()) return; - final @NotNull AnvilInventory inventory = event.getInventory(); + final Optional result = Optional.ofNullable(event.getResult()); + if (result.isEmpty()) + return; + + final AnvilInventory inventory = event.getInventory(); + final @Nullable ItemStack item = inventory.getItem(0); - if (item == null) return; + if (item == null) + return; + final @Nullable ItemStack upgrade = inventory.getItem(1); - if (upgrade == null) return; - final @NotNull Map<@NotNull Enchantment, @NotNull Integer> itemEnchants = - item.getType() == Material.ENCHANTED_BOOK && item.getItemMeta() instanceof final @NotNull EnchantmentStorageMeta itemMeta ? - itemMeta.getStoredEnchants() : item.getEnchantments(); - final @NotNull Map<@NotNull Enchantment, @NotNull Integer> upgradeEnchants = - upgrade.getType() == Material.ENCHANTED_BOOK && upgrade.getItemMeta() instanceof final @NotNull EnchantmentStorageMeta upgradeMeta ? - upgradeMeta.getStoredEnchants() : upgrade.getEnchantments(); - if (upgradeEnchants.isEmpty()) return; - final @NotNull HashMap<@NotNull Enchantment, @NotNull Integer> upgrades = new HashMap<>(); + if (upgrade == null) + return; + + final Map itemEnchants = item.getType() == Material.ENCHANTED_BOOK && + item.getItemMeta() instanceof final EnchantmentStorageMeta itemMeta + ? itemMeta.getStoredEnchants() + : item.getEnchantments(); + + final Map upgradeEnchants = upgrade.getType() == Material.ENCHANTED_BOOK && + upgrade.getItemMeta() instanceof final EnchantmentStorageMeta upgradeMeta + ? upgradeMeta.getStoredEnchants() + : upgrade.getEnchantments(); + if (upgradeEnchants.isEmpty()) + return; + + final Map upgrades = new HashMap<>(); + int cost = 0; - for (final @NotNull Map.Entry<@NotNull Enchantment, @NotNull Integer> entry : upgradeEnchants.entrySet()) { - final @NotNull Enchantment enchantment = entry.getKey(); - if (!event.getView().getPlayer().hasPermission(Permissions.enchant(enchantment))) continue; - if (enchantment.getMaxLevel() == 1) continue; - final @NotNull Optional<@NotNull ConfigEnchantmentEntry> configEnchantment = EnchantBookPlus.getInstance().getConfigEnchantment(enchantment); - if (configEnchantment.isEmpty()) continue; + + for (final Map.Entry entry : upgradeEnchants.entrySet()) { + final Enchantment enchantment = entry.getKey(); + + if (!event.getView().getPlayer().hasPermission(Permissions.enchant(enchantment))) + continue; + + if (enchantment.getMaxLevel() == 1) + continue; + + final Optional configEnchantment = plugin.getConfigEnchantment(enchantment); + if (configEnchantment.isEmpty()) + continue; + final int upgradeLevel = entry.getValue(); + final int finalLevel; + if (itemEnchants.containsKey(enchantment)) { final int itemLevel = itemEnchants.get(enchantment); - if (itemLevel > upgradeLevel) finalLevel = itemLevel; - else if (itemLevel == upgradeLevel) finalLevel = upgradeLevel + 1; - else finalLevel = upgradeLevel; + if (itemLevel > upgradeLevel) + finalLevel = itemLevel; + else if (itemLevel == upgradeLevel) + finalLevel = upgradeLevel + 1; + else + finalLevel = upgradeLevel; } - else finalLevel = upgradeLevel; - if (finalLevel <= enchantment.getMaxLevel()) continue; - if (configEnchantment.get().getMaxLevel().isPresent() && finalLevel > configEnchantment.get().getMaxLevel().get()) continue; - if (finalLevel > upgradeLevel) cost += configEnchantment.get().getMultiplyCostByLevel() ? configEnchantment.get().getCost() * (finalLevel - enchantment.getMaxLevel()) : configEnchantment.get().getCost(); + else + finalLevel = upgradeLevel; + + if (finalLevel <= enchantment.getMaxLevel()) + continue; + + if (configEnchantment.get().getMaxLevel().isPresent() && + finalLevel > configEnchantment.get().getMaxLevel().get()) + continue; + + if (finalLevel > upgradeLevel) + cost += configEnchantment.get().getMultiplyCostByLevel() + ? configEnchantment.get().getCost() * (finalLevel - enchantment.getMaxLevel()) + : configEnchantment.get().getCost(); + upgrades.put(enchantment, finalLevel); } + if (upgrades.isEmpty()) return; - final int vanillaCost = inventory.getRepairCost(); - inventory.setRepairCost(vanillaCost + cost); - for (final @NotNull Map.Entry<@NotNull Enchantment, @NotNull Integer> entry : upgrades.entrySet()) { - if (result.get().getItemMeta() instanceof final @NotNull EnchantmentStorageMeta resultMeta) { - if (!resultMeta.getStoredEnchants().containsKey(entry.getKey())) continue; + + inventory.setRepairCost(inventory.getRepairCost() + cost); + + for (final Map.Entry entry : upgrades.entrySet()) { + if (result.get().getItemMeta() instanceof final EnchantmentStorageMeta resultMeta) { + if (!resultMeta.getStoredEnchants().containsKey(entry.getKey())) + continue; + resultMeta.addStoredEnchant(entry.getKey(), entry.getValue(), true); + result.get().setItemMeta(resultMeta); } else { - if (!result.get().getEnchantments().containsKey(entry.getKey())) continue; + if (!result.get().getEnchantments().containsKey(entry.getKey())) + continue; + result.get().addUnsafeEnchantment(entry.getKey(), entry.getValue()); } } From 84bb71f11ef6f2c659f110a659e24c624f7fbcdf Mon Sep 17 00:00:00 2001 From: Zefir Kirilov Date: Mon, 29 Dec 2025 13:46:54 +0200 Subject: [PATCH 2/4] =?UTF-8?q?add=20support=20for=20Spigot=20and=20older?= =?UTF-8?q?=20versions=20(1.17=E2=80=931.21.11)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/codeql.yaml | 2 +- .github/workflows/maven.yaml | 4 +- .github/workflows/release.yaml | 5 ++- .idea/jarRepositories.xml | 5 +++ pom.xml | 18 ++++++--- .../smp/enchantbookplus/MainCommand.java | 39 ++++++++++--------- src/main/resources/plugin.yml | 2 +- 7 files changed, 45 insertions(+), 30 deletions(-) diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 063a789..01cc6b5 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -52,7 +52,7 @@ jobs: - uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: 17 + java-version: 16 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/maven.yaml b/.github/workflows/maven.yaml index 11d146c..3cd9887 100644 --- a/.github/workflows/maven.yaml +++ b/.github/workflows/maven.yaml @@ -24,10 +24,10 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Set up JDK 17 + - name: Set up JDK 16 uses: actions/setup-java@v4 with: - java-version: '17' + java-version: '16' distribution: 'temurin' cache: maven - name: Build with Maven diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 76572e9..99a340b 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -16,7 +16,7 @@ jobs: - name: Set up Java uses: actions/setup-java@v4 with: - java-version: 17 + java-version: 16 distribution: temurin cache: maven @@ -50,6 +50,9 @@ jobs: changelog: ${{ github.event.release.body }} loaders: paper game-versions: |- + 1.17.x + 1.18.x + 1.19.x 1.20.x 1.21.x files: target/EnchantBookPlus-${{ steps.version.outputs.VERSION }}.jar diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml index 8c89be5..a397e0f 100644 --- a/.idea/jarRepositories.xml +++ b/.idea/jarRepositories.xml @@ -11,6 +11,11 @@