diff --git a/NMS/API/src/main/java/com/willfp/ecoenchants/nms/api/FastGetEnchantsWrapper.java b/NMS/API/src/main/java/com/willfp/ecoenchants/nms/api/FastGetEnchantsWrapper.java new file mode 100644 index 00000000..010c197e --- /dev/null +++ b/NMS/API/src/main/java/com/willfp/ecoenchants/nms/api/FastGetEnchantsWrapper.java @@ -0,0 +1,10 @@ +package com.willfp.ecoenchants.nms.api; + +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; + +import java.util.Map; + +public interface FastGetEnchantsWrapper { + Map getEnchantmentsOnItem(ItemStack itemStack); +} diff --git a/NMS/v1_15_R1/src/main/java/com/willfp/ecoenchants/nms/v1_15_R1/FastGetEnchants.java b/NMS/v1_15_R1/src/main/java/com/willfp/ecoenchants/nms/v1_15_R1/FastGetEnchants.java new file mode 100644 index 00000000..050b1f9f --- /dev/null +++ b/NMS/v1_15_R1/src/main/java/com/willfp/ecoenchants/nms/v1_15_R1/FastGetEnchants.java @@ -0,0 +1,32 @@ +package com.willfp.ecoenchants.nms.v1_15_R1; + +import com.willfp.ecoenchants.nms.api.FastGetEnchantsWrapper; +import net.minecraft.server.v1_15_R1.NBTBase; +import net.minecraft.server.v1_15_R1.NBTTagCompound; +import net.minecraft.server.v1_15_R1.NBTTagList; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_15_R1.util.CraftNamespacedKey; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; +import java.util.Map; + +public class FastGetEnchants implements FastGetEnchantsWrapper { + @Override + public Map getEnchantmentsOnItem(ItemStack itemStack) { + net.minecraft.server.v1_15_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); + NBTTagList enchantmentNBT = nmsStack.getEnchantments(); + HashMap foundEnchantments = new HashMap<>(); + + for (NBTBase base : enchantmentNBT) { + NBTTagCompound compound = (NBTTagCompound) base; + String key = compound.getString("id"); + int level = '\uffff' & compound.getShort("lvl"); + + Enchantment found = Enchantment.getByKey(CraftNamespacedKey.fromStringOrNull(key)); + if(found != null) foundEnchantments.put(found, level); + } + return foundEnchantments; + } +} diff --git a/NMS/v1_16_R1/src/main/java/com/willfp/ecoenchants/nms/v1_16_R1/FastGetEnchants.java b/NMS/v1_16_R1/src/main/java/com/willfp/ecoenchants/nms/v1_16_R1/FastGetEnchants.java new file mode 100644 index 00000000..fb76e150 --- /dev/null +++ b/NMS/v1_16_R1/src/main/java/com/willfp/ecoenchants/nms/v1_16_R1/FastGetEnchants.java @@ -0,0 +1,32 @@ +package com.willfp.ecoenchants.nms.v1_16_R1; + +import com.willfp.ecoenchants.nms.api.FastGetEnchantsWrapper; +import net.minecraft.server.v1_16_R1.NBTBase; +import net.minecraft.server.v1_16_R1.NBTTagCompound; +import net.minecraft.server.v1_16_R1.NBTTagList; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_16_R1.util.CraftNamespacedKey; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; +import java.util.Map; + +public class FastGetEnchants implements FastGetEnchantsWrapper { + @Override + public Map getEnchantmentsOnItem(ItemStack itemStack) { + net.minecraft.server.v1_16_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); + NBTTagList enchantmentNBT = nmsStack.getEnchantments(); + HashMap foundEnchantments = new HashMap<>(); + + for (NBTBase base : enchantmentNBT) { + NBTTagCompound compound = (NBTTagCompound) base; + String key = compound.getString("id"); + int level = '\uffff' & compound.getShort("lvl"); + + Enchantment found = Enchantment.getByKey(CraftNamespacedKey.fromStringOrNull(key)); + if(found != null) foundEnchantments.put(found, level); + } + return foundEnchantments; + } +} diff --git a/NMS/v1_16_R2/src/main/java/com/willfp/ecoenchants/nms/v1_16_R2/FastGetEnchants.java b/NMS/v1_16_R2/src/main/java/com/willfp/ecoenchants/nms/v1_16_R2/FastGetEnchants.java new file mode 100644 index 00000000..ed5412f3 --- /dev/null +++ b/NMS/v1_16_R2/src/main/java/com/willfp/ecoenchants/nms/v1_16_R2/FastGetEnchants.java @@ -0,0 +1,32 @@ +package com.willfp.ecoenchants.nms.v1_16_R2; + +import com.willfp.ecoenchants.nms.api.FastGetEnchantsWrapper; +import net.minecraft.server.v1_16_R2.NBTBase; +import net.minecraft.server.v1_16_R2.NBTTagCompound; +import net.minecraft.server.v1_16_R2.NBTTagList; +import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_16_R2.util.CraftNamespacedKey; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; +import java.util.Map; + +public class FastGetEnchants implements FastGetEnchantsWrapper { + @Override + public Map getEnchantmentsOnItem(ItemStack itemStack) { + net.minecraft.server.v1_16_R2.ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); + NBTTagList enchantmentNBT = nmsStack.getEnchantments(); + HashMap foundEnchantments = new HashMap<>(); + + for (NBTBase base : enchantmentNBT) { + NBTTagCompound compound = (NBTTagCompound) base; + String key = compound.getString("id"); + int level = '\uffff' & compound.getShort("lvl"); + + Enchantment found = Enchantment.getByKey(CraftNamespacedKey.fromStringOrNull(key)); + if(found != null) foundEnchantments.put(found, level); + } + return foundEnchantments; + } +} diff --git a/NMS/v1_16_R3/src/main/java/com/willfp/ecoenchants/nms/v1_16_R3/FastGetEnchants.java b/NMS/v1_16_R3/src/main/java/com/willfp/ecoenchants/nms/v1_16_R3/FastGetEnchants.java new file mode 100644 index 00000000..5c465d34 --- /dev/null +++ b/NMS/v1_16_R3/src/main/java/com/willfp/ecoenchants/nms/v1_16_R3/FastGetEnchants.java @@ -0,0 +1,32 @@ +package com.willfp.ecoenchants.nms.v1_16_R3; + +import com.willfp.ecoenchants.nms.api.FastGetEnchantsWrapper; +import net.minecraft.server.v1_16_R3.NBTBase; +import net.minecraft.server.v1_16_R3.NBTTagCompound; +import net.minecraft.server.v1_16_R3.NBTTagList; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_16_R3.util.CraftNamespacedKey; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; +import java.util.Map; + +public class FastGetEnchants implements FastGetEnchantsWrapper { + @Override + public Map getEnchantmentsOnItem(ItemStack itemStack) { + net.minecraft.server.v1_16_R3.ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); + NBTTagList enchantmentNBT = nmsStack.getEnchantments(); + HashMap foundEnchantments = new HashMap<>(); + + for (NBTBase base : enchantmentNBT) { + NBTTagCompound compound = (NBTTagCompound) base; + String key = compound.getString("id"); + int level = '\uffff' & compound.getShort("lvl"); + + Enchantment found = Enchantment.getByKey(CraftNamespacedKey.fromStringOrNull(key)); + if(found != null) foundEnchantments.put(found, level); + } + return foundEnchantments; + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/util/EnchantChecks.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/util/EnchantChecks.java index e77fde75..de2880bb 100644 --- a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/util/EnchantChecks.java +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/util/EnchantChecks.java @@ -2,6 +2,7 @@ package com.willfp.ecoenchants.enchantments.util; import com.willfp.ecoenchants.enchantments.EcoEnchant; import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.FastGetEnchants; import com.willfp.ecoenchants.util.DurabilityUtils; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; @@ -45,10 +46,10 @@ public class EnchantChecks { public static int getItemLevel(ItemStack item, Enchantment enchantment) { if (item == null) return 0; if (item.getType().equals(Material.AIR)) return 0; - if (!item.hasItemMeta()) return 0; - if (item.getItemMeta() == null) return 0; - return item.getItemMeta().getEnchantLevel(enchantment); + Integer level = FastGetEnchants.getEnchantsOnItem(item).get(enchantment); + + return level == null ? 0 : level; } /** @@ -61,15 +62,12 @@ public class EnchantChecks { public static Map getEnchantsOnItem(ItemStack item) { if (item == null) return new HashMap<>(); if (item.getType().equals(Material.AIR)) return new HashMap<>(); - if (!item.hasItemMeta()) return new HashMap<>(); - if (item.getItemMeta() == null) return new HashMap<>(); Map ecoEnchants = new HashMap<>(); - item.getEnchantments().forEach(((enchantment, integer) -> { - if (EcoEnchants.getFromEnchantment(enchantment) != null) { - ecoEnchants.put(EcoEnchants.getFromEnchantment(enchantment), integer); - } - })); + for (Map.Entry enchantmentIntegerEntry : FastGetEnchants.getEnchantsOnItem(item).entrySet()) { + EcoEnchant enchant = EcoEnchants.getFromEnchantment(enchantmentIntegerEntry.getKey()); + if(enchant != null) ecoEnchants.put(enchant, enchantmentIntegerEntry.getValue()); + } return ecoEnchants; } @@ -177,16 +175,7 @@ public class EnchantChecks { ItemStack item = entity.getEquipment().getItemInMainHand(); - if (item == null) return new HashMap<>(); - - Map ecoEnchants = new HashMap<>(); - - for (Map.Entry entry : item.getEnchantments().entrySet()) { - EcoEnchant enchant = EcoEnchants.getFromEnchantment(entry.getKey()); - if(enchant != null) ecoEnchants.put(enchant, entry.getValue()); - } - - return ecoEnchants; + return getEnchantsOnItem(item); } /** @@ -231,17 +220,7 @@ public class EnchantChecks { ItemStack item = entity.getEquipment().getItemInOffHand(); - if (item == null) return new HashMap<>(); - - Map ecoEnchants = new HashMap<>(); - - item.getEnchantments().forEach(((enchantment, integer) -> { - if (EcoEnchants.getFromEnchantment(enchantment) != null) { - ecoEnchants.put(EcoEnchants.getFromEnchantment(enchantment), integer); - } - })); - - return ecoEnchants; + return getEnchantsOnItem(item); } /** diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/nms/FastGetEnchants.java b/Plugin/src/main/java/com/willfp/ecoenchants/nms/FastGetEnchants.java new file mode 100644 index 00000000..6df983b3 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/nms/FastGetEnchants.java @@ -0,0 +1,40 @@ +package com.willfp.ecoenchants.nms; + +import com.willfp.ecoenchants.EcoEnchantsPlugin; +import com.willfp.ecoenchants.nms.api.FastGetEnchantsWrapper; +import com.willfp.ecoenchants.util.internal.Logger; +import org.bukkit.Bukkit; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; + +import java.util.Map; + +/** + * Utility class to break a block as if the player had done it manually + */ +public class FastGetEnchants { + private static FastGetEnchantsWrapper fastGetEnchantsWrapper; + + /** + * Efficiently get enchantments on an item without instantiating ItemMeta + * + * @param item The item to query + * + * @return A map of all enchantments, where the integer is the level + */ + public static Map getEnchantsOnItem(ItemStack item) { + return fastGetEnchantsWrapper.getEnchantmentsOnItem(item); + } + + static { + try { + final Class class2 = Class.forName("com.willfp.ecoenchants.nms." + EcoEnchantsPlugin.NMS_VERSION + ".FastGetEnchants"); + if (FastGetEnchantsWrapper.class.isAssignableFrom(class2)) { + fastGetEnchantsWrapper = (FastGetEnchantsWrapper) class2.getConstructor().newInstance(); + } + } catch (Exception e) { + Logger.error("&cYou're running an unsupported server version: " + EcoEnchantsPlugin.NMS_VERSION); + Bukkit.getPluginManager().disablePlugin(EcoEnchantsPlugin.getInstance()); + } + } +}