From e72605a4f618a89a89976cc645ed73c24905831c Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 15 Jun 2013 23:19:03 -0400 Subject: [PATCH] EMC ItemStack isSimiliar API to skip durability and name checks Skip Durability is useful if you simply want to see if an item type is the same for weapons Skip Item Name is useful if you want to treat a renamed item the same as an unrenamed item, when lore is involved For example, lore can be used to identify a custom item, but then if a player renames it, the isSimilar breaks. This new boolean allows you to verify if the item is the same ignoring the name field by temporarily nulling it during the check. --- .../java/org/bukkit/inventory/ItemStack.java | 66 ++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java index d7d6a3e8..291285aa 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java @@ -281,16 +281,80 @@ public class ItemStack implements Cloneable, ConfigurationSerializable { * @param stack the item stack to compare to * @return true if the two stacks are equal, ignoring the amount */ + // Paper start - add API to skip checking durability and item name @Utility public boolean isSimilar(@Nullable ItemStack stack) { + return isSimilar(stack, false); + } + + /** + * This method is the same as equals, but does not consider stack size + * (amount). + * + * @param stack the item stack to compare to + * @param skipDur Ignore differences in durability + * @return true if the two stacks are equal, ignoring the amount, and optionally durability + */ + @Utility + public boolean isSimilar(@Nullable ItemStack stack, boolean skipDur) { + return isSimilar(stack, skipDur, false); + } + + /** + * This method is the same as equals, but does not consider stack size + * (amount). + * + * @param stack the item stack to compare to + * @param skipDur Ignore differences in durability + * @param skipCheckingName Ignore differences in display name + * @return true if the two stacks are equal, ignoring the amount, and optionally durability/name + */ + @Utility + public boolean isSimilar(@Nullable ItemStack stack, boolean skipDur, boolean skipCheckingName) { if (stack == null) { return false; } if (stack == this) { return true; } + Material comparisonType = (this.type.isLegacy()) ? Bukkit.getUnsafe().fromLegacy(this.getData(), true) : this.type; // This may be called from legacy item stacks, try to get the right material - return comparisonType == stack.getType() && getDurability() == stack.getDurability() && hasItemMeta() == stack.hasItemMeta() && (hasItemMeta() ? Bukkit.getItemFactory().equals(getItemMeta(), stack.getItemMeta()) : true); + if (comparisonType != stack.getType() || (!skipDur && getDurability() != stack.getDurability())) { + return false; + } + final boolean hasMeta1 = hasItemMeta(); + final boolean hasMeta2 = stack.hasItemMeta(); + if (!hasMeta1 && !hasMeta2) { + return true; + } + + final ItemMeta meta1 = hasMeta1 ? getItemMeta() : null; + final ItemMeta meta2 = hasMeta2 ? stack.getItemMeta() : null; + + final String prevName1 = meta1 != null ? meta1.getDisplayName() : null; + final String prevName2 = meta2 != null ? meta2.getDisplayName() : null; + if (skipCheckingName) { + if (meta1 != null) { + meta1.setDisplayName(null); + } + if (meta2 != null) { + meta2.setDisplayName(null); + } + } + + try { + return Bukkit.getItemFactory().equals(meta1, meta2); + } finally { + if (skipCheckingName) { + if (meta1 != null) { + meta1.setDisplayName(prevName1); + } + if (meta2 != null) { + meta2.setDisplayName(prevName2); + } + } + } + // Paper end } @NotNull -- 2.25.1.windows.1