From 935b5cfe0fe279703187114d6309024f5a9ef057 Mon Sep 17 00:00:00 2001 From: Max Roncace Date: Sat, 25 Aug 2018 06:33:17 -0400 Subject: [PATCH] Fix unbreakable attribute for kits (#2071) @caseif This PR fixes the `unbreakable` attribute on kit items. Previously, Essentials was exclusively using an internal Spigot method to set this on `ItemMeta` objects; however, this solution seems to be non-functional on more recent Spigot builds (1.12.2). I have altered the `MetaItemStack#setUnbreakable` method to use the native Bukkit method, available for [some time now](https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/commits/d986a3f), by default. Essentials will still use the old solution as a fallback in case of an older Bukkit version which does not have native support for the attribute. --- .../earth2me/essentials/MetaItemStack.java | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/Essentials/src/com/earth2me/essentials/MetaItemStack.java b/Essentials/src/com/earth2me/essentials/MetaItemStack.java index bb4e7c03e..b426bbcfb 100644 --- a/Essentials/src/com/earth2me/essentials/MetaItemStack.java +++ b/Essentials/src/com/earth2me/essentials/MetaItemStack.java @@ -164,7 +164,7 @@ public class MetaItemStack { try { // 1.8 banner = Material.valueOf("BANNER"); - + // 1.9 shield = Material.valueOf("SHIELD"); } catch(IllegalArgumentException ignored){} @@ -183,7 +183,7 @@ public class MetaItemStack { meta.setLore(lore); stack.setItemMeta(meta); } else if (split[0].equalsIgnoreCase("unbreakable") && hasMetaPermission(sender, "unbreakable", false, true, ess)) { - boolean value = split.length > 1 ? Boolean.valueOf(split[1]) : true; + boolean value = split.length > 1 ? Boolean.valueOf(split[1]) : true; setUnbreakable(stack, value); } else if (split.length > 1 && (split[0].equalsIgnoreCase("player") || split[0].equalsIgnoreCase("owner")) && stack.getType() == Material.SKULL_ITEM && hasMetaPermission(sender, "head", false, true, ess)) { if (stack.getDurability() == 3) { @@ -488,7 +488,7 @@ public class MetaItemStack { if (split.length < 2) { throw new Exception(tl("invalidBanner", split[1])); } - + PatternType patternType = null; try { patternType = PatternType.valueOf(split[0]); @@ -554,22 +554,36 @@ public class MetaItemStack { } } + private static int bukkitUnbreakableSupport = -1; private static Method spigotMethod; private static Method setUnbreakableMethod; private void setUnbreakable(ItemStack is, boolean unbreakable) { ItemMeta meta = is.getItemMeta(); try { - if (spigotMethod == null) { - spigotMethod = meta.getClass().getDeclaredMethod("spigot"); - spigotMethod.setAccessible(true); + if (bukkitUnbreakableSupport == -1) { + try { + ItemMeta.class.getDeclaredMethod("setUnbreakable", boolean.class); + bukkitUnbreakableSupport = 1; + } catch (NoSuchMethodException | SecurityException ex) { + bukkitUnbreakableSupport = 0; + } } - Object itemStackSpigot = spigotMethod.invoke(meta); - if (setUnbreakableMethod == null) { - setUnbreakableMethod = itemStackSpigot.getClass().getDeclaredMethod("setUnbreakable", Boolean.TYPE); - setUnbreakableMethod.setAccessible(true); + + if (bukkitUnbreakableSupport == 1) { + meta.setUnbreakable(unbreakable); + } else { + if (spigotMethod == null) { + spigotMethod = meta.getClass().getDeclaredMethod("spigot"); + spigotMethod.setAccessible(true); + } + Object itemStackSpigot = spigotMethod.invoke(meta); + if (setUnbreakableMethod == null) { + setUnbreakableMethod = itemStackSpigot.getClass().getDeclaredMethod("setUnbreakable", Boolean.TYPE); + setUnbreakableMethod.setAccessible(true); + } + setUnbreakableMethod.invoke(itemStackSpigot, unbreakable); } - setUnbreakableMethod.invoke(itemStackSpigot, unbreakable); is.setItemMeta(meta); } catch (Throwable t) { t.printStackTrace();