Files
MagicGem-Reforged/src/main/java/cn/infstar/magicgem/item/ItemMatcher.java
T

82 lines
3.9 KiB
Java

package cn.infstar.magicgem.item;
import de.tr7zw.changeme.nbtapi.NBT;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.Locale;
import java.util.Set;
public final class ItemMatcher {
private final ItemCodec codec;
public ItemMatcher(ItemCodec codec) {
this.codec = codec;
}
public boolean matches(ItemStack item, Set<String> requirements) {
if (item == null || item.getType().isAir()) return false;
if (requirements.isEmpty()) return true;
for (String requirement : requirements) {
if (matches(item, requirement)) return true;
}
return false;
}
public boolean matches(ItemStack item, String rawRequirement) {
if (item == null || item.getType().isAir()) return false;
String requirement = rawRequirement.toUpperCase(Locale.ROOT);
Material material = item.getType();
if (requirement.equals("NOTHING")) return false;
if (requirement.equals("ALL") || requirement.equals("ANY")) return true;
if (requirement.startsWith("LORE:")) return loreContains(item, rawRequirement.substring(5));
if (requirement.startsWith("NAME:")) {
ItemMeta meta = item.getItemMeta();
return meta.hasDisplayName() && strip(meta.getDisplayName()).contains(strip(rawRequirement.substring(5)));
}
if (requirement.startsWith("GEM:")) {
String expected = rawRequirement.substring(4);
return codec.embedded(item).entrySet().stream().anyMatch(entry -> entry.getValue() > 0
&& (expected.equalsIgnoreCase("ALL") || expected.equalsIgnoreCase("ANY")
|| entry.getKey().equalsIgnoreCase(expected)));
}
if (requirement.startsWith("NBT:")) {
String[] parts = rawRequirement.substring(4).split(":", 2);
return NBT.get(item, nbt -> {
if (!nbt.hasTag(parts[0])) return false;
return parts.length == 1 || nbt.getString(parts[0]).equals(parts[1]);
});
}
if (material.name().equals(requirement) || material.name().endsWith('_' + requirement)) return true;
return switch (requirement) {
case "ARMOR" -> material.name().endsWith("_HELMET") || material.name().endsWith("_CHESTPLATE")
|| material.name().endsWith("_LEGGINGS") || material.name().endsWith("_BOOTS")
|| material == Material.ELYTRA;
case "WEAPON" -> material.name().endsWith("_SWORD") || material.name().endsWith("_AXE")
|| material == Material.BOW || material == Material.CROSSBOW || material == Material.TRIDENT
|| material == Material.MACE;
case "TOOL" -> material.name().endsWith("_PICKAXE") || material.name().endsWith("_AXE")
|| material.name().endsWith("_SHOVEL") || material.name().endsWith("_HOE")
|| material == Material.SHEARS || material == Material.FISHING_ROD;
case "HELMET", "HEAD" -> material.name().endsWith("_HELMET");
case "CHEST", "CHESTPLATE" -> material.name().endsWith("_CHESTPLATE") || material == Material.ELYTRA;
case "LEGS", "LEGGINGS" -> material.name().endsWith("_LEGGINGS");
case "FEET", "BOOTS" -> material.name().endsWith("_BOOTS");
default -> false;
};
}
private boolean loreContains(ItemStack item, String expected) {
ItemMeta meta = item.getItemMeta();
if (!meta.hasLore() || meta.getLore() == null) return false;
String clean = strip(expected);
return meta.getLore().stream().map(this::strip).anyMatch(line -> line.contains(clean));
}
private String strip(String value) {
return ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&', value == null ? "" : value));
}
}