From 07f4e10b62e970412527bf0de886a6a695bf7f2d Mon Sep 17 00:00:00 2001 From: Pim van der Loos Date: Mon, 23 Nov 2020 11:48:35 +0100 Subject: [PATCH] Implement modular enchantment system - Added new enchantment management system that makes it easier to add support for custom enchantment plugins. --- .../armorequip/ArmorListener.java | 50 +++---- .../armoredElytra/ArmoredElytra.java | 9 +- .../enchantment/EnchantmentContainer.java | 69 +++++++++ .../enchantment/EnchantmentManager.java | 73 ++++++++++ .../EnchantmentPlatformManager.java | 30 ++++ .../enchantment/IEnchantmentPlatform.java | 22 +++ .../VanillaEnchantmentPlatform.java | 131 ++++++++++++++++++ .../armoredElytra/handlers/EventHandlers.java | 122 ++-------------- .../armoredElytra/util/ConfigLoader.java | 20 ++- 9 files changed, 369 insertions(+), 157 deletions(-) create mode 100644 src/main/java/nl/pim16aap2/armoredElytra/enchantment/EnchantmentContainer.java create mode 100644 src/main/java/nl/pim16aap2/armoredElytra/enchantment/EnchantmentManager.java create mode 100644 src/main/java/nl/pim16aap2/armoredElytra/enchantment/EnchantmentPlatformManager.java create mode 100644 src/main/java/nl/pim16aap2/armoredElytra/enchantment/IEnchantmentPlatform.java create mode 100644 src/main/java/nl/pim16aap2/armoredElytra/enchantment/VanillaEnchantmentPlatform.java diff --git a/src/main/java/com/codingforcookies/armorequip/ArmorListener.java b/src/main/java/com/codingforcookies/armorequip/ArmorListener.java index f37eda3..725aeec 100644 --- a/src/main/java/com/codingforcookies/armorequip/ArmorListener.java +++ b/src/main/java/com/codingforcookies/armorequip/ArmorListener.java @@ -1,7 +1,6 @@ package com.codingforcookies.armorequip; -import java.util.List; - +import com.codingforcookies.armorequip.ArmorEquipEvent.EquipMethod; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -20,7 +19,7 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerItemBreakEvent; import org.bukkit.inventory.ItemStack; -import com.codingforcookies.armorequip.ArmorEquipEvent.EquipMethod; +import java.util.List; /** * @author Arnah @@ -72,16 +71,20 @@ public class ArmorListener implements Listener equipping = false; if (newArmorType.equals(ArmorType.HELMET) && (equipping ? isAirOrNull(e.getWhoClicked().getInventory().getHelmet()) : - !isAirOrNull(e.getWhoClicked().getInventory().getHelmet())) || + !isAirOrNull(e.getWhoClicked().getInventory().getHelmet())) || newArmorType.equals(ArmorType.CHESTPLATE) && (equipping ? - isAirOrNull(e.getWhoClicked().getInventory().getChestplate()) : - !isAirOrNull(e.getWhoClicked().getInventory().getChestplate())) || + isAirOrNull(e.getWhoClicked().getInventory() + .getChestplate()) : + !isAirOrNull(e.getWhoClicked().getInventory() + .getChestplate())) || newArmorType.equals(ArmorType.LEGGINGS) && (equipping ? - isAirOrNull(e.getWhoClicked().getInventory().getLeggings()) : - !isAirOrNull(e.getWhoClicked().getInventory().getLeggings())) || + isAirOrNull( + e.getWhoClicked().getInventory().getLeggings()) : + !isAirOrNull( + e.getWhoClicked().getInventory().getLeggings())) || newArmorType.equals(ArmorType.BOOTS) && (equipping ? - isAirOrNull(e.getWhoClicked().getInventory().getBoots()) : - !isAirOrNull(e.getWhoClicked().getInventory().getBoots()))) + isAirOrNull(e.getWhoClicked().getInventory().getBoots()) : + !isAirOrNull(e.getWhoClicked().getInventory().getBoots()))) { ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) e.getWhoClicked(), EquipMethod.SHIFT_CLICK, newArmorType, @@ -118,16 +121,12 @@ public class ArmorListener implements Listener newArmorType = ArmorType .matchType(!isAirOrNull(e.getCurrentItem()) ? e.getCurrentItem() : e.getCursor()); } - else - { - if (isAirOrNull(e.getCursor()) && !isAirOrNull(e.getCurrentItem())) - // unequip with no new item going into the slot. - newArmorType = ArmorType.matchType(e.getCurrentItem()); - // e.getCurrentItem() == Unequip - // e.getCursor() == Equip - // newArmorType = ArmorType.matchType(!isAirOrNull(e.getCurrentItem()) ? - // e.getCurrentItem() : e.getCursor()); - } + else + { + if (isAirOrNull(e.getCursor()) && !isAirOrNull(e.getCurrentItem())) + // unequip with no new item going into the slot. + newArmorType = ArmorType.matchType(e.getCurrentItem()); + } if (newArmorType != null && e.getRawSlot() == newArmorType.getSlot()) { EquipMethod method = EquipMethod.PICK_DROP; @@ -204,15 +203,6 @@ public class ArmorListener implements Listener event.setCancelled(true); } } - // Debug shit - /* - * System.out.println("Slots: " + event.getInventorySlots().toString()); - * System.out.println("Raw Slots: " + event.getRawSlots().toString()); - * if(event.getCursor() != null){ System.out.println("Cursor: " + - * event.getCursor().getType().name()); } if(event.getOldCursor() != null){ - * System.out.println("OldCursor: " + event.getOldCursor().getType().name()); } - * System.out.println("Type: " + event.getType().name()); - */ } @EventHandler @@ -251,7 +241,7 @@ public class ArmorListener implements Listener ArmorType type = ArmorType.matchType(oldArmor); Bukkit.getServer().getPluginManager().callEvent(new ArmorEquipEvent(p, EquipMethod.DEATH, type, oldArmor, null)); - // No way to cancel a death event. + // No way to cancel a death event. } } diff --git a/src/main/java/nl/pim16aap2/armoredElytra/ArmoredElytra.java b/src/main/java/nl/pim16aap2/armoredElytra/ArmoredElytra.java index 0f85678..a2717d9 100644 --- a/src/main/java/nl/pim16aap2/armoredElytra/ArmoredElytra.java +++ b/src/main/java/nl/pim16aap2/armoredElytra/ArmoredElytra.java @@ -41,7 +41,6 @@ public class ArmoredElytra extends JavaPlugin implements Listener private final Map armorTierNames = new EnumMap<>(ArmorTier.class); private boolean upToDate; - private boolean is1_9; private UpdateManager updateManager; private INBTEditor nbtEditor; @@ -57,13 +56,6 @@ public class ArmoredElytra extends JavaPlugin implements Listener return; } -//// Material mat = Material.ELYTRA; -//// n3kas.ae.Core.canApplyTo(mat); -// for (String str : n3kas.ae.api.getAllEnchantments()) -// System.out.println(str); -// System.exit(0); - - nbtEditor = new NBTEditor(); if (isBlacklistedVersion()) { myLogger(Level.SEVERE, @@ -74,6 +66,7 @@ public class ArmoredElytra extends JavaPlugin implements Listener "blacklisted version of Spiogt! Please update Spigot!"), this); return; } + nbtEditor = new NBTEditor(); config = new ConfigLoader(this); messages = new Messages(this); diff --git a/src/main/java/nl/pim16aap2/armoredElytra/enchantment/EnchantmentContainer.java b/src/main/java/nl/pim16aap2/armoredElytra/enchantment/EnchantmentContainer.java new file mode 100644 index 0000000..8e2d3ba --- /dev/null +++ b/src/main/java/nl/pim16aap2/armoredElytra/enchantment/EnchantmentContainer.java @@ -0,0 +1,69 @@ +package nl.pim16aap2.armoredElytra.enchantment; + +import org.bukkit.inventory.ItemStack; + +import java.util.Collection; +import java.util.Map; + +class EnchantmentContainer +{ + private Map enchantments; + private final IEnchantmentPlatform manager; + + public EnchantmentContainer(final Map enchantments, final IEnchantmentPlatform manager) + { + this.enchantments = enchantments; + this.manager = manager; + } + + /** + * Removes any entries from the list of enchantments that do not exist in the provided filter. + * + * @param allowed The names of enchantments (upper case) that are allowed. Any names not in this list are removed. + * @return This instance. + */ + public EnchantmentContainer filter(final Collection allowed) + { + if (!enchantments.isEmpty()) + enchantments.keySet().retainAll(allowed); + return this; + } + + /** + * Applies the enchantments to an itemstack. + * + * @param is The itemstack to apply the enchantments to. + */ + public void apply(final ItemStack is) + { + manager.applyEnchantments(is, enchantments); + } + + /** + * Merges this container with another one. + */ + public void merge(EnchantmentContainer other) + { + if (!(manager.getClass() == other.manager.getClass())) + throw new RuntimeException("Trying to add enchantment containers of different types!"); + enchantments = manager.merge(enchantments, other.enchantments); + } + + /** + * Gets the number of enchantments in this container. + */ + public int size() + { + return enchantments.size(); + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder("["); + enchantments.forEach((k, v) -> sb.append("\"").append(k).append("\" (").append(v).append("), ")); + String ret = sb.toString(); + ret = ret.length() > 1 ? ret.substring(0, ret.length() - 2) : ret; + return ret + "]"; + } +} diff --git a/src/main/java/nl/pim16aap2/armoredElytra/enchantment/EnchantmentManager.java b/src/main/java/nl/pim16aap2/armoredElytra/enchantment/EnchantmentManager.java new file mode 100644 index 0000000..3facecd --- /dev/null +++ b/src/main/java/nl/pim16aap2/armoredElytra/enchantment/EnchantmentManager.java @@ -0,0 +1,73 @@ +package nl.pim16aap2.armoredElytra.enchantment; + +import nl.pim16aap2.armoredElytra.ArmoredElytra; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class EnchantmentManager +{ + private final ArmoredElytra armoredElytra; + private final List containers = new ArrayList<>(); + private Integer count = null; + + public EnchantmentManager(final ItemStack is) + { + armoredElytra = ArmoredElytra.getInstance(); + EnchantmentPlatformManager.get().getPlatforms().forEach(platform -> + containers.add(platform.getEnchantments(is))); + + Collection filter = armoredElytra.getConfigLoader().allowedEnchantments(); + containers.forEach(container -> container.filter(filter)); + } + + /** + * Merges this EnchantmentManager with another one. + * + * @param other The EnchantmentManager to merge into the current one. + * @return The instance of the current EnchantmentManager. + */ + public EnchantmentManager merge(final EnchantmentManager other) + { + for (int idx = 0; idx < containers.size(); ++idx) + containers.get(idx).merge(other.containers.get(idx)); + count = null; // Reset count, as it's no longer up-to-date. + return this; + } + + /** + * Applies all the enchantments to the provided itemstack. + * + * @param is The itemstack to apply all enchantments to. + */ + public void apply(final ItemStack is) + { + containers.forEach(container -> container.apply(is)); + } + + /** + * Gets the total number of enchantments. + * + * @return The total number of enchantments. + */ + public int getEnchantmentCount() + { + if (count != null) + return count; + + count = 0; + for (EnchantmentContainer container : containers) + count += container.size(); + return count; + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder("Enchantments: \n"); + containers.forEach(container -> sb.append(container.toString()).append("\n")); + return sb.toString(); + } +} diff --git a/src/main/java/nl/pim16aap2/armoredElytra/enchantment/EnchantmentPlatformManager.java b/src/main/java/nl/pim16aap2/armoredElytra/enchantment/EnchantmentPlatformManager.java new file mode 100644 index 0000000..b03a8b4 --- /dev/null +++ b/src/main/java/nl/pim16aap2/armoredElytra/enchantment/EnchantmentPlatformManager.java @@ -0,0 +1,30 @@ +package nl.pim16aap2.armoredElytra.enchantment; + +import java.util.ArrayList; +import java.util.List; + +public class EnchantmentPlatformManager +{ + private static final EnchantmentPlatformManager INSTANCE = new EnchantmentPlatformManager(); + private final List platforms = new ArrayList<>(); + + private EnchantmentPlatformManager() + { + addPlatform(new VanillaEnchantmentPlatform()); + } + + public static EnchantmentPlatformManager get() + { + return INSTANCE; + } + + public void addPlatform(final IEnchantmentPlatform platform) + { + platforms.add(platform); + } + + public List getPlatforms() + { + return platforms; + } +} diff --git a/src/main/java/nl/pim16aap2/armoredElytra/enchantment/IEnchantmentPlatform.java b/src/main/java/nl/pim16aap2/armoredElytra/enchantment/IEnchantmentPlatform.java new file mode 100644 index 0000000..ac2d714 --- /dev/null +++ b/src/main/java/nl/pim16aap2/armoredElytra/enchantment/IEnchantmentPlatform.java @@ -0,0 +1,22 @@ +package nl.pim16aap2.armoredElytra.enchantment; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import java.util.Map; + +interface IEnchantmentPlatform +{ + EnchantmentContainer getEnchantmentsFromItem(final ItemStack is); + + EnchantmentContainer getEnchantmentsFromBook(final ItemStack is); + + default EnchantmentContainer getEnchantments(final ItemStack is) + { + return is.getType() == Material.ENCHANTED_BOOK ? getEnchantmentsFromBook(is) : getEnchantmentsFromItem(is); + } + + void applyEnchantments(final ItemStack is, final Map enchantments); + + Map merge(final Map first, final Map second); +} diff --git a/src/main/java/nl/pim16aap2/armoredElytra/enchantment/VanillaEnchantmentPlatform.java b/src/main/java/nl/pim16aap2/armoredElytra/enchantment/VanillaEnchantmentPlatform.java new file mode 100644 index 0000000..32e7239 --- /dev/null +++ b/src/main/java/nl/pim16aap2/armoredElytra/enchantment/VanillaEnchantmentPlatform.java @@ -0,0 +1,131 @@ +package nl.pim16aap2.armoredElytra.enchantment; + +import nl.pim16aap2.armoredElytra.ArmoredElytra; +import nl.pim16aap2.armoredElytra.util.Util; +import org.bukkit.Bukkit; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.EnchantmentStorageMeta; + +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; + +class VanillaEnchantmentPlatform implements IEnchantmentPlatform +{ + private Map getNamedEnchantments(final Map enchantments) + { + final Map enchantmentsStr = new HashMap<>(enchantments.size()); + enchantments.forEach((k, v) -> enchantmentsStr.put(k.getName(), v)); + return enchantmentsStr; + } + + private Map getEnchantments(final Map enchantments) + { + final Map enchantmentsStr = new HashMap<>(enchantments.size()); + enchantments.forEach((k, v) -> enchantmentsStr.put(Enchantment.getByName(k), v)); + return enchantmentsStr; + } + + @Override + public EnchantmentContainer getEnchantmentsFromItem(final ItemStack is) + { + return new EnchantmentContainer(getNamedEnchantments(is.getEnchantments()), this); + } + + @Override + public EnchantmentContainer getEnchantmentsFromBook(final ItemStack is) + { + if (!is.hasItemMeta()) + return new EnchantmentContainer(new HashMap<>(0), this); + + EnchantmentStorageMeta meta = (EnchantmentStorageMeta) is.getItemMeta(); + if (meta == null || !meta.hasStoredEnchants()) + return new EnchantmentContainer(new HashMap<>(0), this); + + return new EnchantmentContainer(getNamedEnchantments(meta.getStoredEnchants()), this); + } + + @Override + public void applyEnchantments(final ItemStack is, final Map enchantments) + { + enchantments.forEach( + (enchantmentName, level) -> + { + Enchantment enchantment = Enchantment.getByName(enchantmentName); + if (enchantment == null) + { + Bukkit.getLogger().log(Level.INFO, "Failed to find enchantment: \"" + enchantmentName + "\""); + return; + } + is.addUnsafeEnchantment(enchantment, level); + } + ); + } + + @Override + public Map merge(final Map first, final Map second) + { + if (second == null || second.isEmpty()) + return first; + + if (first == null || first.isEmpty()) + return second; + + Map enchantments0 = getEnchantments(first); + Map enchantments1 = getEnchantments(second); + Map combined = new HashMap<>(enchantments0); + + for (Map.Entry entry : enchantments1.entrySet()) + { + Integer enchantLevel = enchantments0.get(entry.getKey()); + if (enchantLevel != null) + { + if (entry.getValue().equals(enchantLevel) && entry.getValue() < entry.getKey().getMaxLevel()) + enchantLevel = entry.getValue() + 1; + else if (entry.getValue() > enchantLevel) + enchantLevel = entry.getValue(); + + // If the enchantment level has changed, + if (!enchantLevel.equals(enchantments0.get(entry.getKey()))) + { + combined.remove(entry.getKey()); + combined.put(entry.getKey(), enchantLevel); + } + } + else + combined.put(entry.getKey(), entry.getValue()); + } + + if (!ArmoredElytra.getInstance().getConfigLoader().allowMultipleProtectionEnchantments()) + { + // Get the protection enchantment rating for both enchantment sets. + int protVal0 = Util.getProtectionEnchantmentsVal(enchantments0); + int protVal1 = Util.getProtectionEnchantmentsVal(enchantments1); + + // If they have different protection enchantments, keep enchantment1's enchantments + // And remove the protection enchantment from enchantments0. + if (protVal0 != 0 && protVal1 != 0 && protVal0 != protVal1) + switch (protVal0) + { + case 1: + combined.remove(Enchantment.PROTECTION_ENVIRONMENTAL); + break; + case 2: + combined.remove(Enchantment.PROTECTION_EXPLOSIONS); + break; + case 4: + combined.remove(Enchantment.PROTECTION_FALL); + break; + case 8: + combined.remove(Enchantment.PROTECTION_FIRE); + break; + case 16: + combined.remove(Enchantment.PROTECTION_PROJECTILE); + break; + } + } + + return getNamedEnchantments(combined); + } +} diff --git a/src/main/java/nl/pim16aap2/armoredElytra/handlers/EventHandlers.java b/src/main/java/nl/pim16aap2/armoredElytra/handlers/EventHandlers.java index 4291c7e..feb2e5f 100644 --- a/src/main/java/nl/pim16aap2/armoredElytra/handlers/EventHandlers.java +++ b/src/main/java/nl/pim16aap2/armoredElytra/handlers/EventHandlers.java @@ -5,6 +5,7 @@ import com.codingforcookies.armorequip.ArmorListener; import com.codingforcookies.armorequip.ArmorType; import com.codingforcookies.armorequip.DispenserArmorListener; import nl.pim16aap2.armoredElytra.ArmoredElytra; +import nl.pim16aap2.armoredElytra.enchantment.EnchantmentManager; import nl.pim16aap2.armoredElytra.util.Action; import nl.pim16aap2.armoredElytra.util.AllowedToWearEnum; import nl.pim16aap2.armoredElytra.util.ArmorTier; @@ -24,11 +25,8 @@ import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.inventory.PrepareAnvilEvent; import org.bukkit.inventory.AnvilInventory; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.EnchantmentStorageMeta; import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; import java.util.Random; import java.util.logging.Level; @@ -78,85 +76,6 @@ public class EventHandlers implements Listener anvilInventory.getItem(2).setAmount(0); } - // Check if the enchantment is allowed on elytras. - private boolean isAllowedEnchantment(Enchantment enchant) - { - for (String s : plugin.getConfigLoader().allowedEnchantments()) - if (Enchantment.getByName(s) != null) - if (Enchantment.getByName(s).equals(enchant)) - return true; - return false; - } - - // Combine 2 maps of enchantments (and remove any invalid ones). - private Map combineEnchantments(Map enchantments0, - Map enchantments1) - { - enchantments0 = fixEnchantments(enchantments0); - Map combined = new HashMap<>(fixEnchantments(enchantments0)); - - // If the second set of enchantments is null, the combined enchantments are just - // the first enchantments. - if (enchantments1 == null) - return combined; - - enchantments1 = fixEnchantments(enchantments1); - // Loop through the enchantments of item1. - for (Map.Entry entry : enchantments1.entrySet()) - { - Integer enchantLevel = enchantments0.get(entry.getKey()); - if (enchantLevel != null) - { - if (entry.getValue().equals(enchantLevel) && entry.getValue() < entry.getKey().getMaxLevel()) - enchantLevel = entry.getValue() + 1; - else if (entry.getValue() > enchantLevel) - enchantLevel = entry.getValue(); - - // If the enchantment level has changed, - if (!enchantLevel.equals(enchantments0.get(entry.getKey()))) - { - combined.remove(entry.getKey()); - combined.put(entry.getKey(), enchantLevel); - } - } - else - combined.put(entry.getKey(), entry.getValue()); - } - - if (!plugin.getConfigLoader().allowMultipleProtectionEnchantments()) - { - // Get the protection enchantment rating for both enchantment sets. - int protVal0 = Util.getProtectionEnchantmentsVal(enchantments0); - int protVal1 = Util.getProtectionEnchantmentsVal(enchantments1); - - // If they have different protection enchantments, keep enchantment1's - // enchantments - // And remove the protection enchantment from enchantments0. Yes, this system - // only works - // If there is 1 protection enchantment on - if (protVal0 != 0 && protVal1 != 0 && protVal0 != protVal1) - switch (protVal0) - { - case 1: - combined.remove(Enchantment.PROTECTION_ENVIRONMENTAL); - break; - case 2: - combined.remove(Enchantment.PROTECTION_EXPLOSIONS); - break; - case 4: - combined.remove(Enchantment.PROTECTION_FALL); - break; - case 8: - combined.remove(Enchantment.PROTECTION_FIRE); - break; - case 16: - combined.remove(Enchantment.PROTECTION_PROJECTILE); - break; - } - } - return combined; - } - // Repair an Armored Elytra private short repairItem(short curDur, ItemStack repairItem) { @@ -182,32 +101,12 @@ public class EventHandlers implements Listener return (short) (newDurability <= 0 ? 0 : newDurability); } - // Remove any disallowed enchantments in the map. - private Map fixEnchantments(Map enchantments) - { - Map ret = new HashMap<>(enchantments); - for (Map.Entry entry : enchantments.entrySet()) - if (!isAllowedEnchantment(entry.getKey())) - ret.remove(entry.getKey()); - return ret; - } - - // Verify there aren't any disallowed enchantments in the map. - private int verifyEnchantments(Map enchantments) - { - int ret = 0; - for (Map.Entry entry : enchantments.entrySet()) - if (!isAllowedEnchantment(entry.getKey())) - ++ret; - return ret; - } - // Valid inputs: // - Elytra (armored or not) + chestplate -> Create Armored Elytra // - Elytra (armored) + enchanted book -> Enchant // - Elytra (armored) + its repair item -> Repair // - Elytra (armored) + other elytra (armored) -> Combine (Enchant + Repair) - // ! Elytra (armored, !leather) + leather -> Block + // ! Elytra (armored, !leather) + leather/membrane -> Block // // Ignoring: // - Elytra (not armored) + !chestplate -> None @@ -288,8 +187,7 @@ public class EventHandlers implements Listener ArmorTier newTier = ArmorTier.NONE; ArmorTier curTier = ArmoredElytra.getInstance().getNbtEditor().getArmorTier(itemA); short durability = 0; - Map enchantments = itemA.getEnchantments(); - enchantments = fixEnchantments(enchantments); + EnchantmentManager enchantments = new EnchantmentManager(itemA); switch (action) { @@ -302,22 +200,23 @@ public class EventHandlers implements Listener durability = (short) (-itemA.getType().getMaxDurability() - itemA.getDurability() - itemB.getDurability()); durability = durability < 0 ? 0 : durability; - enchantments = combineEnchantments(enchantments, itemB.getEnchantments()); + enchantments.merge(new EnchantmentManager(itemB)); break; case CREATE: newTier = Util.armorToTier(itemB.getType()); durability = 0; - enchantments = combineEnchantments(enchantments, itemB.getEnchantments()); + enchantments.merge(new EnchantmentManager(itemB)); break; case ENCHANT: - EnchantmentStorageMeta meta = (EnchantmentStorageMeta) itemB.getItemMeta(); newTier = curTier; durability = itemA.getDurability(); + // If there aren't any illegal enchantments on the book, continue as normal. // Otherwise... Block. - if (verifyEnchantments(meta.getStoredEnchants()) != meta.getStoredEnchants().size()) + EnchantmentManager enchantmentsB = new EnchantmentManager(itemB); + if (enchantmentsB.getEnchantmentCount() > 0) { - enchantments = combineEnchantments(enchantments, meta.getStoredEnchants()); + enchantments.merge(enchantmentsB); break; } //$FALL-THROUGH$ @@ -332,8 +231,7 @@ public class EventHandlers implements Listener if (plugin.playerHasCraftPerm(player, newTier)) { result = new ItemStack(Material.ELYTRA, 1); - if (enchantments != null) - result.addUnsafeEnchantments(enchantments); + enchantments.apply(result); result.setDurability(durability); result = ArmoredElytra.getInstance().getNbtEditor() diff --git a/src/main/java/nl/pim16aap2/armoredElytra/util/ConfigLoader.java b/src/main/java/nl/pim16aap2/armoredElytra/util/ConfigLoader.java index 7b5268b..b2814cd 100644 --- a/src/main/java/nl/pim16aap2/armoredElytra/util/ConfigLoader.java +++ b/src/main/java/nl/pim16aap2/armoredElytra/util/ConfigLoader.java @@ -10,6 +10,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; +import java.util.LinkedHashSet; import java.util.List; import java.util.logging.Level; @@ -28,7 +29,7 @@ public class ConfigLoader private int DIAMONDS_TO_FULL; private int NETHERITE_TO_FULL; private boolean noFlightDurability; - private List allowedEnchantments; + private LinkedHashSet allowedEnchantments; private boolean allowMultipleProtectionEnchantments; private boolean craftingInSmithingTable; private boolean bypassWearPerm; @@ -117,9 +118,11 @@ public class ConfigLoader // Set default list of allowed enchantments. - allowedEnchantments = new ArrayList<>(Arrays.asList("DURABILITY", "PROTECTION_FIRE", "PROTECTION_EXPLOSIONS", - "PROTECTION_PROJECTILE", "PROTECTION_ENVIRONMENTAL", - "THORNS", "BINDING_CURSE", "VANISHING_CURSE", "MENDING")); + List defaultAllowedEnchantments = new ArrayList<>( + Arrays.asList("DURABILITY", "PROTECTION_FIRE", "PROTECTION_EXPLOSIONS", + "PROTECTION_PROJECTILE", "PROTECTION_ENVIRONMENTAL", + "THORNS", "BINDING_CURSE", "VANISHING_CURSE", "MENDING")); + FileConfiguration config = plugin.getConfig(); unbreakable = addNewConfigOption(config, "unbreakable", false, unbreakableComment); @@ -133,8 +136,11 @@ public class ConfigLoader // craftingInSmithingTable = addNewConfigOption(config, "craftingInSmithingTable", true, craftingInSmithingTableComment); craftingInSmithingTable = false; - allowedEnchantments = addNewConfigOption(config, "allowedEnchantments", allowedEnchantments, - enchantmentsComment); + defaultAllowedEnchantments = addNewConfigOption(config, "allowedEnchantments", defaultAllowedEnchantments, + enchantmentsComment); + defaultAllowedEnchantments.replaceAll(String::toUpperCase); + allowedEnchantments = new LinkedHashSet<>(defaultAllowedEnchantments); + allowMultipleProtectionEnchantments = addNewConfigOption(config, "allowMultipleProtectionEnchantments", false, allowMultipleProtectionEnchantmentsComment); checkForUpdates = addNewConfigOption(config, "checkForUpdates", true, updateComment); @@ -267,7 +273,7 @@ public class ConfigLoader return noFlightDurability; } - public List allowedEnchantments() + public LinkedHashSet allowedEnchantments() { return allowedEnchantments; }