diff --git a/core/src/main/java/tc/oc/pgm/shops/ShopKeeper.java b/core/src/main/java/tc/oc/pgm/shops/ShopKeeper.java index 11edc6769b..101900e8f7 100644 --- a/core/src/main/java/tc/oc/pgm/shops/ShopKeeper.java +++ b/core/src/main/java/tc/oc/pgm/shops/ShopKeeper.java @@ -11,6 +11,7 @@ import tc.oc.pgm.api.PGM; import tc.oc.pgm.api.match.Match; import tc.oc.pgm.points.PointProvider; +import tc.oc.pgm.util.bukkit.MetadataUtils; import tc.oc.pgm.util.nms.NMSHacks; public class ShopKeeper { @@ -60,7 +61,7 @@ public static boolean isKeeper(Entity entity) { } public static String getKeeperId(Entity entity) { - MetadataValue meta = entity.getMetadata(ShopKeeper.METADATA_KEY, PGM.get()); + MetadataValue meta = MetadataUtils.getMetadata(entity, ShopKeeper.METADATA_KEY, PGM.get()); if (meta.asString() != null) { return meta.asString(); } diff --git a/core/src/main/java/tc/oc/pgm/shops/menu/Payment.java b/core/src/main/java/tc/oc/pgm/shops/menu/Payment.java index 0a8d270ae5..be1de3b603 100644 --- a/core/src/main/java/tc/oc/pgm/shops/menu/Payment.java +++ b/core/src/main/java/tc/oc/pgm/shops/menu/Payment.java @@ -5,6 +5,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.jetbrains.annotations.Nullable; +import tc.oc.pgm.util.material.Materials; public class Payment { @@ -43,6 +44,8 @@ public boolean hasPayment(PlayerInventory inventory) { } public boolean matches(ItemStack item) { - return this.item != null ? item.isSimilar(this.item, true) : item.getType() == currency; + return this.item != null + ? Materials.itemsSimilar(item, this.item, true, false) + : item.getType() == currency; } } diff --git a/core/src/main/java/tc/oc/pgm/util/MethodHandleUtils.java b/core/src/main/java/tc/oc/pgm/util/MethodHandleUtils.java index ed63aeb245..ef903c9031 100644 --- a/core/src/main/java/tc/oc/pgm/util/MethodHandleUtils.java +++ b/core/src/main/java/tc/oc/pgm/util/MethodHandleUtils.java @@ -6,6 +6,7 @@ import java.util.HashMap; import java.util.Map; import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; @@ -31,10 +32,15 @@ public final class MethodHandleUtils { // #getPlayer covers events which does not provide Entity // as the lower boundary private static final String[] entityGetterNames = - new String[] {"getPlayer", "getActor", "getActor"}; + new String[] {"getPlayer", "getActor", "getActor", "getEntity"}; private static final MethodType playerMethodType = MethodType.methodType(Player.class); private static final MethodType[] entityMethodTypes = - new MethodType[] {playerMethodType, playerMethodType, MethodType.methodType(Entity.class)}; + new MethodType[] { + playerMethodType, + playerMethodType, + MethodType.methodType(Entity.class), + MethodType.methodType(LivingEntity.class) + }; public static MethodHandle getHandle(Class event) throws NoSuchMethodException, IllegalAccessException { diff --git a/util/src/main/java/tc/oc/pgm/util/inventory/ItemMatcher.java b/util/src/main/java/tc/oc/pgm/util/inventory/ItemMatcher.java index f8a3d2a456..2ee0099957 100644 --- a/util/src/main/java/tc/oc/pgm/util/inventory/ItemMatcher.java +++ b/util/src/main/java/tc/oc/pgm/util/inventory/ItemMatcher.java @@ -3,6 +3,7 @@ import com.google.common.collect.Range; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import tc.oc.pgm.util.material.Materials; public class ItemMatcher { @@ -48,7 +49,7 @@ private ItemStack stripMeta(ItemStack item) { } public boolean matches(ItemStack query) { - return base.isSimilar(stripMeta(query), ignoreDurability, ignoreName) + return Materials.itemsSimilar(base, stripMeta(query), ignoreDurability, ignoreName) && amount.contains(query.getAmount()); } } diff --git a/util/src/main/java/tc/oc/pgm/util/material/Materials.java b/util/src/main/java/tc/oc/pgm/util/material/Materials.java index 7ae5abb589..78e05bc228 100644 --- a/util/src/main/java/tc/oc/pgm/util/material/Materials.java +++ b/util/src/main/java/tc/oc/pgm/util/material/Materials.java @@ -9,6 +9,7 @@ import org.bukkit.block.BlockState; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.BannerMeta; +import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.material.MaterialData; import tc.oc.pgm.util.block.BlockFaces; @@ -88,6 +89,51 @@ static boolean isSolid(Material material) { } } + static boolean itemsSimilar( + ItemStack first, ItemStack second, boolean skipDur, boolean skipCheckingName) { + if (first == second) { + return true; + } + if (second == null + || first == null + || !first.getType().equals(second.getType()) + || (!skipDur && first.getDurability() != second.getDurability())) { + return false; + } + final boolean hasMeta1 = first.hasItemMeta(); + final boolean hasMeta2 = second.hasItemMeta(); + if (!hasMeta1 && !hasMeta2) { + return true; + } + + final ItemMeta meta1 = hasMeta1 ? first.getItemMeta() : null; + final ItemMeta meta2 = hasMeta2 ? second.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); + } + } + } + } + static boolean isSolid(MaterialData material) { return isSolid(material.getItemType()); }