diff --git a/src/main/java/com/garbagemule/MobArena/util/ItemParser.java b/src/main/java/com/garbagemule/MobArena/util/ItemParser.java index 906b159..824fc1d 100644 --- a/src/main/java/com/garbagemule/MobArena/util/ItemParser.java +++ b/src/main/java/com/garbagemule/MobArena/util/ItemParser.java @@ -7,6 +7,9 @@ import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.EnchantmentStorageMeta; import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.material.Dye; +import org.bukkit.material.MaterialData; +import org.bukkit.material.Wool; import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionType; @@ -14,12 +17,10 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; public class ItemParser { - private static final int WOOL_ID = Material.WOOL.getId(); - private static final int DYE_ID = Material.INK_SACK.getId(); - private static final Map POTION_TYPE_MAP = new HashMap<>(); static { POTION_TYPE_MAP.put((short) 8193, PotionType.REGEN); @@ -80,7 +81,7 @@ public class ItemParser result = withDataAndAmount(parts[0], parts[1], parts[2]); break; } - if (result == null || result.getTypeId() == 0) { + if (result == null || result.getType() == Material.AIR) { if (logFailure) { Bukkit.getLogger().warning("[MobArena] Failed to parse item: " + item); } @@ -95,70 +96,136 @@ public class ItemParser } private static ItemStack singleItem(String item) { - int id = getTypeId(item); - return new ItemStack(id); + return getType(item) + .map(ItemStack::new) + .orElse(null); } private static ItemStack withAmount(String item, String amount) { - int id = getTypeId(item); - int a = getAmount(amount); - return new ItemStack(id,a); + return getType(item) + .map(type -> new ItemStack(type, getAmount(amount))) + .orElse(null); } private static ItemStack withDataAndAmount(String item, String data, String amount) { - int id = getTypeId(item); - short d = getData(data, id); - int a = getAmount(amount); - - if (id == Material.LINGERING_POTION.getId() || id == Material.TIPPED_ARROW.getId() || id == Material.SPLASH_POTION.getId()) { - return withPotionMeta(id, d, a); + ItemStack stack = withAmount(item, amount); + if (stack == null) { + return null; } - return new ItemStack(id,a,d); + + Material type = stack.getType(); + if (type == Material.POTION || type == Material.LINGERING_POTION || type == Material.SPLASH_POTION|| type == Material.TIPPED_ARROW) { + return withPotionMeta(stack, data); + } + + MaterialData md = getData(data, type); + if (md == null) { + return null; + } + + return md.toItemStack(stack.getAmount()); } - private static ItemStack withPotionMeta(int id, short d, int a) { - ItemStack result = new ItemStack(id, a); - PotionMeta meta = (PotionMeta) result.getItemMeta(); - - boolean extended = (d & 64) > 0; - boolean upgraded = (d & 32) > 0; - if (extended) { - d -= 64; - } - if (upgraded) { - d -= 32; + private static ItemStack withPotionMeta(ItemStack stack, String data) { + PotionType type = getPotionType(data); + if (type == null) { + return null; } + PotionMeta meta = (PotionMeta) stack.getItemMeta(); + meta.setBasePotionData(new PotionData(type)); + stack.setItemMeta(meta); + return stack; + } - PotionType type = POTION_TYPE_MAP.get(d); - if (type != null) { - PotionData pData = new PotionData(type, extended, upgraded); - meta.setBasePotionData(pData); - result.setItemMeta(meta); - return result; + private static PotionType getPotionType(String data) { + if (data.matches("[0-9]+")) { + short d = Short.parseShort(data); + + // Compensate for splash potions + if (d > (2 * 8192)) { + d -= 8192; + } + + boolean extended = (d & 64) > 0; + boolean upgraded = (d & 32) > 0; + if (extended) { + d -= 64; + } + if (upgraded) { + d -= 32; + } + + PotionType type = POTION_TYPE_MAP.get(d); + if (type != null) { + warn(type.name(), data); + } + return type; + } + try { + return PotionType.valueOf(data.toUpperCase()); + } catch (IllegalArgumentException e) { + return null; + } + } + + private static Optional getType(String item) { + if (item.matches("(-)?[1-9][0-9]*")) { + Material type = Material.getMaterial(Integer.parseInt(item)); + if (type == null) { + return Optional.empty(); + } + + warn(type.name(), item); + + return Optional.of(type); + } + return Optional.ofNullable(Material.getMaterial(item.toUpperCase())); + } + + private static MaterialData getData(String data, Material type) { + if (type == Material.INK_SACK) { + return getDyeData(data); + } + if (type == Material.WOOL) { + return getWoolData(data); } return null; } - private static int getTypeId(String item) { - if (item.matches("(-)?[0-9]*")) { - return Integer.parseInt(item); + private static Wool getWoolData(String data) { + if (data.matches("(-)?[1-9][0-9]*")) { + DyeColor color = DyeColor.getByWoolData(Byte.parseByte(data)); + if (color == null) { + return null; + } + + warn(color.name(), data); + + return new Wool(color); + } + try { + return new Wool(DyeColor.valueOf(data.toUpperCase())); + } catch (IllegalArgumentException e) { + return null; } - Material m = Enums.getEnumFromString(Material.class, item); - return (m != null ? m.getId() : 0); } - - private static short getData(String data, int id) { - // Wool and ink are special - if (id == WOOL_ID) { - DyeColor dye = Enums.getEnumFromString(DyeColor.class, data); - if (dye == null) dye = DyeColor.getByWoolData(Byte.parseByte(data)); - return dye.getWoolData(); - } else if (id == DYE_ID) { - DyeColor dye = Enums.getEnumFromString(DyeColor.class, data); - if (dye == null) dye = DyeColor.getByDyeData(Byte.parseByte(data)); - return dye.getDyeData(); + + private static Dye getDyeData(String data) { + if (data.matches("(-)?[1-9][0-9]*")) { + DyeColor color = DyeColor.getByDyeData(Byte.parseByte(data)); + if (color == null) { + return null; + } + + warn(color.name(), data); + + return new Dye(color); + } + try { + return new Dye(DyeColor.valueOf(data.toUpperCase())); + } catch (IllegalArgumentException e) { + return null; } - return (data.matches("(-)?[0-9]+") ? Short.parseShort(data) : 0); } private static int getAmount(String amount) { @@ -179,24 +246,45 @@ public class ItemParser private static void addEnchantment(ItemStack stack, String ench) { String[] parts = ench.split(":"); - if (parts.length != 2 || !(parts[0].matches("[0-9]*") && parts[1].matches("[0-9]*"))) { + if (parts.length != 2 || !parts[1].matches("[0-9]*")) { + return; + } + + Enchantment enchantment = getEnchantment(parts[0]); + if (enchantment == null) { return; } - - int id = Integer.parseInt(parts[0]); int lvl = Integer.parseInt(parts[1]); - - Enchantment e = Enchantment.getById(id); - if (e == null) {// || !e.canEnchantItem(stack) || lvl > e.getMaxLevel() || lvl < e.getStartLevel()) { - return; - } - + if (stack.getType() == Material.ENCHANTED_BOOK) { EnchantmentStorageMeta esm = (EnchantmentStorageMeta) stack.getItemMeta(); - esm.addStoredEnchant(e, lvl, true); + esm.addStoredEnchant(enchantment, lvl, true); stack.setItemMeta(esm); } else { - stack.addUnsafeEnchantment(e, lvl); + stack.addUnsafeEnchantment(enchantment, lvl); } } + + private static Enchantment getEnchantment(String ench) { + if (ench.matches("[1-9][0-9]*")) { + Enchantment enchantment = Enchantment.getById(Integer.parseInt(ench)); + if (enchantment == null) { + return null; + } + + warn(enchantment.getName(), ench); + + return enchantment; + } + return Enchantment.getByName(ench.toUpperCase()); + } + + private static void warn(String name, String value) { + String msg = String.format( + "Consider using '%s' instead of '%s'", + name.toLowerCase(), + value + ); + Bukkit.getLogger().warning("[MobArena] " + msg); + } }