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.
This commit is contained in:
Max Roncace 2018-08-25 06:33:17 -04:00 committed by md678685
parent bad02729db
commit 935b5cfe0f

View file

@ -164,7 +164,7 @@ public class MetaItemStack {
try { try {
// 1.8 // 1.8
banner = Material.valueOf("BANNER"); banner = Material.valueOf("BANNER");
// 1.9 // 1.9
shield = Material.valueOf("SHIELD"); shield = Material.valueOf("SHIELD");
} catch(IllegalArgumentException ignored){} } catch(IllegalArgumentException ignored){}
@ -183,7 +183,7 @@ public class MetaItemStack {
meta.setLore(lore); meta.setLore(lore);
stack.setItemMeta(meta); stack.setItemMeta(meta);
} else if (split[0].equalsIgnoreCase("unbreakable") && hasMetaPermission(sender, "unbreakable", false, true, ess)) { } 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); 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)) { } 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) { if (stack.getDurability() == 3) {
@ -488,7 +488,7 @@ public class MetaItemStack {
if (split.length < 2) { if (split.length < 2) {
throw new Exception(tl("invalidBanner", split[1])); throw new Exception(tl("invalidBanner", split[1]));
} }
PatternType patternType = null; PatternType patternType = null;
try { try {
patternType = PatternType.valueOf(split[0]); patternType = PatternType.valueOf(split[0]);
@ -554,22 +554,36 @@ public class MetaItemStack {
} }
} }
private static int bukkitUnbreakableSupport = -1;
private static Method spigotMethod; private static Method spigotMethod;
private static Method setUnbreakableMethod; private static Method setUnbreakableMethod;
private void setUnbreakable(ItemStack is, boolean unbreakable) { private void setUnbreakable(ItemStack is, boolean unbreakable) {
ItemMeta meta = is.getItemMeta(); ItemMeta meta = is.getItemMeta();
try { try {
if (spigotMethod == null) { if (bukkitUnbreakableSupport == -1) {
spigotMethod = meta.getClass().getDeclaredMethod("spigot"); try {
spigotMethod.setAccessible(true); ItemMeta.class.getDeclaredMethod("setUnbreakable", boolean.class);
bukkitUnbreakableSupport = 1;
} catch (NoSuchMethodException | SecurityException ex) {
bukkitUnbreakableSupport = 0;
}
} }
Object itemStackSpigot = spigotMethod.invoke(meta);
if (setUnbreakableMethod == null) { if (bukkitUnbreakableSupport == 1) {
setUnbreakableMethod = itemStackSpigot.getClass().getDeclaredMethod("setUnbreakable", Boolean.TYPE); meta.setUnbreakable(unbreakable);
setUnbreakableMethod.setAccessible(true); } 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); is.setItemMeta(meta);
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();