From 018f08699d883adee329aaf0367cda78e9b679fb Mon Sep 17 00:00:00 2001 From: Driftay Date: Mon, 20 Jan 2020 03:46:53 -0500 Subject: [PATCH] 1.15 Item Conversion Complete --- .../massivecraft/factions/FactionsPlugin.java | 7 +- .../factions/cmd/audit/FLogType.java | 2 +- .../cmd/check/CheckSettingsFrame.java | 6 +- .../factions/cmd/wild/WildGUI.java | 4 +- .../listeners/FactionsBlockListener.java | 7 +- .../listeners/FactionsPlayerListener.java | 2 +- .../factions/missions/MissionGUI.java | 10 +- .../factions/shop/ShopGUIFrame.java | 4 +- .../factions/struct/Relation.java | 2 +- .../massivecraft/factions/struct/Role.java | 2 +- .../factions/util/FactionWarpsFrame.java | 4 +- .../massivecraft/factions/util/XMaterial.java | 2426 ++++++++++------- .../zcore/fdisband/FDisbandFrame.java | 4 +- .../zcore/fperms/PermissableAction.java | 2 +- .../fperms/gui/PermissableActionFrame.java | 4 +- .../fperms/gui/PermissableRelationFrame.java | 4 +- .../zcore/fupgrades/FUpgradeFrame.java | 2 +- .../factions/zcore/fupgrades/UpgradeType.java | 2 +- 18 files changed, 1460 insertions(+), 1034 deletions(-) diff --git a/src/main/java/com/massivecraft/factions/FactionsPlugin.java b/src/main/java/com/massivecraft/factions/FactionsPlugin.java index 0837bd48..c7b33995 100755 --- a/src/main/java/com/massivecraft/factions/FactionsPlugin.java +++ b/src/main/java/com/massivecraft/factions/FactionsPlugin.java @@ -78,6 +78,7 @@ public class FactionsPlugin extends MPlugin { public boolean mc112 = false; public boolean mc113 = false; public boolean mc114 = false; + public boolean mc115 = false; public boolean useNonPacketParticles = false; public boolean factionsFlight = false; SkriptAddon skriptAddon; @@ -164,6 +165,10 @@ public class FactionsPlugin extends MPlugin { FactionsPlugin.instance.log("Minecraft Version 1.14 found."); mc114 = true; break; + case 15: + FactionsPlugin.instance.log("Minecraft Version 1.15 found."); + mc115 = true; + break; } migrateFPlayerLeaders(); log("==== End Setup ===="); @@ -464,7 +469,7 @@ public class FactionsPlugin extends MPlugin { } public ItemStack createItem(Material material, int amount, short datavalue, String name, List lore) { - ItemStack item = new ItemStack(XMaterial.matchXMaterial(material.toString()).parseMaterial(), amount, datavalue); + ItemStack item = new ItemStack(XMaterial.matchXMaterial(material.toString()).get().parseMaterial(), amount, datavalue); ItemMeta meta = item.getItemMeta(); meta.setDisplayName(color(name)); meta.setLore(colorList(lore)); diff --git a/src/main/java/com/massivecraft/factions/cmd/audit/FLogType.java b/src/main/java/com/massivecraft/factions/cmd/audit/FLogType.java index 1d48e824..837045ed 100644 --- a/src/main/java/com/massivecraft/factions/cmd/audit/FLogType.java +++ b/src/main/java/com/massivecraft/factions/cmd/audit/FLogType.java @@ -62,7 +62,7 @@ public enum FLogType { } public Material getMaterial() { - return XMaterial.matchXMaterial(FactionsPlugin.getInstance().getConfig().getString("faudit-gui.materials." + name().toLowerCase())).parseMaterial(); + return XMaterial.matchXMaterial(FactionsPlugin.getInstance().getConfig().getString("faudit-gui.materials." + name().toLowerCase())).get().parseMaterial(); } public String getMsg() { diff --git a/src/main/java/com/massivecraft/factions/cmd/check/CheckSettingsFrame.java b/src/main/java/com/massivecraft/factions/cmd/check/CheckSettingsFrame.java index 7fa69ab3..f8d2235b 100644 --- a/src/main/java/com/massivecraft/factions/cmd/check/CheckSettingsFrame.java +++ b/src/main/java/com/massivecraft/factions/cmd/check/CheckSettingsFrame.java @@ -52,19 +52,19 @@ public class CheckSettingsFrame implements InventoryHolder, FactionGUI { public void build() { Faction faction = fPlayer.getFaction(); - ItemStack wallsStack = XMaterial.matchXMaterial(FactionsPlugin.getInstance().getConfig().getString("f-check.wall-check.Type")).parseItem(); + ItemStack wallsStack = XMaterial.matchXMaterial(FactionsPlugin.getInstance().getConfig().getString("f-check.wall-check.Type")).get().parseItem(); ItemMeta wallsMeta = wallsStack.getItemMeta(); wallsMeta.setDisplayName(TL.CHECK_WALL_CHECK_GUI_ICON.toString()); wallsMeta.setLore(Collections.singletonList(TL.CHECK_CHECK_LORE_LINE.format(getFormatted(faction.getWallCheckMinutes())))); wallsStack.setItemMeta(wallsMeta); inventory.setItem(FactionsPlugin.getInstance().getConfig().getInt("f-check.wall-check.slot"), wallsStack); - ItemStack bufferStack = XMaterial.matchXMaterial(FactionsPlugin.getInstance().getConfig().getString("f-check.buffer-check.Type")).parseItem(); + ItemStack bufferStack = XMaterial.matchXMaterial(FactionsPlugin.getInstance().getConfig().getString("f-check.buffer-check.Type")).get().parseItem(); ItemMeta bufferMeta = bufferStack.getItemMeta(); bufferMeta.setDisplayName(TL.CHECK_BUFFER_CHECK_GUI_ICON.toString()); bufferMeta.setLore(Collections.singletonList(TL.CHECK_CHECK_LORE_LINE.format(getFormatted(faction.getBufferCheckMinutes())))); bufferStack.setItemMeta(bufferMeta); inventory.setItem(FactionsPlugin.getInstance().getConfig().getInt("f-check.buffer-check.slot"), bufferStack); - ItemStack historyStack = XMaterial.matchXMaterial(FactionsPlugin.getInstance().getConfig().getString("f-check.history.Type")).parseItem(); + ItemStack historyStack = XMaterial.matchXMaterial(FactionsPlugin.getInstance().getConfig().getString("f-check.history.Type")).get().parseItem(); ItemMeta historyMeta = historyStack.getItemMeta(); historyMeta.setDisplayName(TL.CHECK_HISTORY_GUI_ICON.toString()); historyStack.setItemMeta(historyMeta); diff --git a/src/main/java/com/massivecraft/factions/cmd/wild/WildGUI.java b/src/main/java/com/massivecraft/factions/cmd/wild/WildGUI.java index ff691853..ca36ddef 100644 --- a/src/main/java/com/massivecraft/factions/cmd/wild/WildGUI.java +++ b/src/main/java/com/massivecraft/factions/cmd/wild/WildGUI.java @@ -46,7 +46,7 @@ public class WildGUI implements FactionGUI { @Override public void build() { inv = Bukkit.createInventory(this, FactionsPlugin.getInstance().getConfig().getInt("Wild.GUI.Size"), FactionsPlugin.getInstance().color(FactionsPlugin.getInstance().getConfig().getString("Wild.GUI.Name"))); - ItemStack fillItem = XMaterial.matchXMaterial(FactionsPlugin.getInstance().getConfig().getString("Wild.GUI.FillMaterial")).parseItem(); + ItemStack fillItem = XMaterial.matchXMaterial(FactionsPlugin.getInstance().getConfig().getString("Wild.GUI.FillMaterial")).get().parseItem(); ItemMeta meta = fillItem.getItemMeta(); if (meta == null) return; meta.setDisplayName(""); @@ -55,7 +55,7 @@ public class WildGUI implements FactionGUI { inv.setItem(fill, fillItem); } for (String key : Objects.requireNonNull(FactionsPlugin.getInstance().getConfig().getConfigurationSection("Wild.Zones")).getKeys(false)) { - ItemStack zoneItem = XMaterial.matchXMaterial(FactionsPlugin.getInstance().getConfig().getString("Wild.Zones." + key + ".Material")).parseItem(); + ItemStack zoneItem = XMaterial.matchXMaterial(FactionsPlugin.getInstance().getConfig().getString("Wild.Zones." + key + ".Material")).get().parseItem(); ItemMeta zoneMeta = zoneItem.getItemMeta(); if (zoneMeta == null) return; List lore = new ArrayList<>(); diff --git a/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java b/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java index b11ea16f..15b6d8bc 100644 --- a/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java +++ b/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java @@ -40,6 +40,7 @@ import org.bukkit.potion.PotionEffectType; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -377,7 +378,7 @@ public class FactionsBlockListener implements Listener { int radius = FactionsPlugin.getInstance().getConfig().getInt("fbanners.Banner-Effect-Radius"); List effects = FactionsPlugin.getInstance().getConfig().getStringList("fbanners.Effects"); int affectorTask = Bukkit.getScheduler().scheduleSyncRepeatingTask(FactionsPlugin.getInstance(), () -> { - for (Entity e1 : banner.getLocation().getWorld().getNearbyEntities(banner.getLocation(), radius, 255.0, radius)) { + for (Entity e1 : Objects.requireNonNull(banner.getLocation().getWorld()).getNearbyEntities(banner.getLocation(), radius, 255.0, radius)) { if (e1 instanceof Player) { Player player = (Player) e1; FPlayer fplayer = FPlayers.getInstance().getByPlayer(player); @@ -386,7 +387,7 @@ public class FactionsBlockListener implements Listener { } for (String effect : effects) { String[] components = effect.split(":"); - player.addPotionEffect(new PotionEffect(PotionEffectType.getByName(components[0]), 100, Integer.parseInt(components[1]))); + player.addPotionEffect(new PotionEffect(Objects.requireNonNull(PotionEffectType.getByName(components[0])), 100, Integer.parseInt(components[1]))); } ParticleEffect.LAVA.display(1.0f, 1.0f, 1.0f, 1.0f, 10, banner.getLocation(), 16.0); ParticleEffect.FLAME.display(1.0f, 1.0f, 1.0f, 1.0f, 10, banner.getLocation(), 16.0); @@ -499,7 +500,7 @@ public class FactionsBlockListener implements Listener { return; } if (block != null && isSpawner) { - ItemStack item = new ItemStack(block.getType(), 1, (short) block.getData()); + ItemStack item = new ItemStack(block.getType(), 1, block.getData()); if (at != null && at.isNormal()) { FPlayer fplayer = FPlayers.getInstance().getByPlayer(event.getPlayer()); if (fplayer != null) { diff --git a/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java b/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java index c113a93b..8ac4053c 100644 --- a/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java +++ b/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java @@ -819,7 +819,7 @@ public class FactionsPlayerListener implements Listener { Material type; if (event.getItem() != null) { // Convert 1.8 Material Names -> 1.14 - type = XMaterial.matchXMaterial(event.getItem().getType().toString()).parseMaterial(); + type = XMaterial.matchXMaterial(event.getItem().getType().toString()).get().parseMaterial(); } else { type = null; } diff --git a/src/main/java/com/massivecraft/factions/missions/MissionGUI.java b/src/main/java/com/massivecraft/factions/missions/MissionGUI.java index 066e4b87..2ba7365b 100644 --- a/src/main/java/com/massivecraft/factions/missions/MissionGUI.java +++ b/src/main/java/com/massivecraft/factions/missions/MissionGUI.java @@ -96,7 +96,7 @@ public class MissionGUI implements FactionGUI { if (configurationSection == null) { return; } - ItemStack fillItem = XMaterial.matchXMaterial(configurationSection.getString("FillItem.Material")).parseItem(); + ItemStack fillItem = XMaterial.matchXMaterial(configurationSection.getString("FillItem.Material")).get().parseItem(); ItemMeta fillmeta = fillItem.getItemMeta(); fillmeta.setDisplayName(""); fillItem.setItemMeta(fillmeta); @@ -109,7 +109,7 @@ public class MissionGUI implements FactionGUI { ConfigurationSection section = configurationSection.getConfigurationSection(key); int slot = section.getInt("Slot"); - ItemStack itemStack = XMaterial.matchXMaterial(section.getString("Material")).parseItem(); + ItemStack itemStack = XMaterial.matchXMaterial(section.getString("Material")).get().parseItem(); ItemMeta itemMeta = itemStack.getItemMeta(); itemMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', section.getString("Name"))); List loreLines = new ArrayList<>(); @@ -134,7 +134,7 @@ public class MissionGUI implements FactionGUI { if (plugin.getConfig().getBoolean("Randomization.Enabled")) { ItemStack start; ItemMeta meta; - start = XMaterial.matchXMaterial(plugin.getConfig().getString("Randomization.Start-Item.Allowed.Material")).parseItem(); + start = XMaterial.matchXMaterial(plugin.getConfig().getString("Randomization.Start-Item.Allowed.Material")).get().parseItem(); meta = start.getItemMeta(); meta.setDisplayName(plugin.color(plugin.getConfig().getString("Randomization.Start-Item.Allowed.Name"))); List loree = new ArrayList<>(); @@ -144,7 +144,7 @@ public class MissionGUI implements FactionGUI { meta.setLore(loree); start.setItemMeta(meta); if (fPlayer.getFaction().getCompletedMissions().size() >= configurationSection.getKeys(false).size() - 1 && plugin.getConfig().getBoolean("DenyMissionsMoreThenOnce")) { - start = XMaterial.matchXMaterial(plugin.getConfig().getString("Randomization.Start-Item.Disallowed.Material")).parseItem(); + start = XMaterial.matchXMaterial(plugin.getConfig().getString("Randomization.Start-Item.Disallowed.Material")).get().parseItem(); meta = start.getItemMeta(); meta.setDisplayName(plugin.color(plugin.getConfig().getString("Randomization.Start-Item.Disallowed.Name"))); List lore = new ArrayList<>(); @@ -155,7 +155,7 @@ public class MissionGUI implements FactionGUI { start.setItemMeta(meta); } if (fPlayer.getFaction().getMissions().size() >= plugin.getConfig().getInt("MaximumMissionsAllowedAtOnce")) { - start = XMaterial.matchXMaterial(plugin.getConfig().getString("Randomization.Start-Item.Disallowed.Material")).parseItem(); + start = XMaterial.matchXMaterial(plugin.getConfig().getString("Randomization.Start-Item.Disallowed.Material")).get().parseItem(); meta = start.getItemMeta(); meta.setDisplayName(plugin.color(plugin.getConfig().getString("Randomization.Start-Item.Disallowed.Name"))); List lore = new ArrayList<>(); diff --git a/src/main/java/com/massivecraft/factions/shop/ShopGUIFrame.java b/src/main/java/com/massivecraft/factions/shop/ShopGUIFrame.java index 2fc473d1..4e963d9e 100644 --- a/src/main/java/com/massivecraft/factions/shop/ShopGUIFrame.java +++ b/src/main/java/com/massivecraft/factions/shop/ShopGUIFrame.java @@ -47,7 +47,7 @@ public class ShopGUIFrame { for (int a = 1; a <= items; a++) { String s = a + ""; int slot = ShopConfig.getShop().getInt("items." + s + ".slot"); - Material material = XMaterial.matchXMaterial(ShopConfig.getShop().getString("items." + s + ".block")).parseMaterial(); + Material material = XMaterial.matchXMaterial(ShopConfig.getShop().getString("items." + s + ".block")).get().parseMaterial(); int cost = ShopConfig.getShop().getInt("items." + s + ".cost"); String name = ShopConfig.getShop().getString("items." + s + ".name"); boolean glowing = ShopConfig.getShop().getBoolean("items." + s + ".glowing"); @@ -93,7 +93,7 @@ public class ShopGUIFrame { private ItemStack buildDummyItem(Faction f) { ConfigurationSection config = FactionsPlugin.getInstance().getConfig().getConfigurationSection("F-Shop.GUI.dummy-item"); - ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).parseItem(); + ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).get().parseItem(); ItemMeta meta = item.getItemMeta(); if (meta != null) { meta.setLore(FactionsPlugin.getInstance().colorList(config.getStringList("Lore"))); diff --git a/src/main/java/com/massivecraft/factions/struct/Relation.java b/src/main/java/com/massivecraft/factions/struct/Relation.java index 3c095603..cca06296 100644 --- a/src/main/java/com/massivecraft/factions/struct/Relation.java +++ b/src/main/java/com/massivecraft/factions/struct/Relation.java @@ -210,7 +210,7 @@ public enum Relation implements Permissable { String displayName = replacePlaceholders(RELATION_CONFIG.getString("placeholder-item.name", "")); List lore = new ArrayList<>(); - Material material = XMaterial.matchXMaterial(RELATION_CONFIG.getString("materials." + name().toLowerCase())).parseMaterial(); + Material material = XMaterial.matchXMaterial(RELATION_CONFIG.getString("materials." + name().toLowerCase())).get().parseMaterial(); if (material == null) { return null; } diff --git a/src/main/java/com/massivecraft/factions/struct/Role.java b/src/main/java/com/massivecraft/factions/struct/Role.java index 4675998e..ed7910e2 100644 --- a/src/main/java/com/massivecraft/factions/struct/Role.java +++ b/src/main/java/com/massivecraft/factions/struct/Role.java @@ -128,7 +128,7 @@ public enum Role implements Permissable { String displayName = replacePlaceholders(RELATION_CONFIG.getString("placeholder-item.name", "")); List lore = new ArrayList<>(); - Material material = XMaterial.matchXMaterial(RELATION_CONFIG.getString("materials." + name().toLowerCase(), "STAINED_CLAY")).parseMaterial(); + Material material = XMaterial.matchXMaterial(RELATION_CONFIG.getString("materials." + name().toLowerCase(), "STAINED_CLAY")).get().parseMaterial(); if (material == null) { return null; } diff --git a/src/main/java/com/massivecraft/factions/util/FactionWarpsFrame.java b/src/main/java/com/massivecraft/factions/util/FactionWarpsFrame.java index 8dbd8425..08a27006 100644 --- a/src/main/java/com/massivecraft/factions/util/FactionWarpsFrame.java +++ b/src/main/java/com/massivecraft/factions/util/FactionWarpsFrame.java @@ -72,7 +72,7 @@ public class FactionWarpsFrame { private ItemStack buildWarpAsset(final Map.Entry warp, final Faction faction) { final ConfigurationSection config = this.section.getConfigurationSection("warp-item"); - final ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).parseItem(); + final ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).get().parseItem(); final ItemMeta meta = item.getItemMeta(); meta.setLore(FactionsPlugin.getInstance().colorList(FactionsPlugin.getInstance().replacePlaceholders(config.getStringList("Lore"), new Placeholder("{warp-protected}", faction.hasWarpPassword(warp.getKey()) ? "Enabled" : "Disabled"), new Placeholder("{warp-cost}", FactionsPlugin.getInstance().getConfig().getBoolean("warp-cost.enabled", false) ? Integer.toString(FactionsPlugin.getInstance().getConfig().getInt("warp-cost.warp", 5)) : "Disabled")))); meta.setDisplayName(FactionsPlugin.getInstance().color(config.getString("Name").replace("{warp}", warp.getKey()))); @@ -82,7 +82,7 @@ public class FactionWarpsFrame { private ItemStack buildDummyItem() { final ConfigurationSection config = this.section.getConfigurationSection("dummy-item"); - final ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).parseItem(); + final ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).get().parseItem(); final ItemMeta meta = item.getItemMeta(); meta.setLore(FactionsPlugin.getInstance().colorList(config.getStringList("Lore"))); meta.setDisplayName(FactionsPlugin.getInstance().color(config.getString("Name"))); diff --git a/src/main/java/com/massivecraft/factions/util/XMaterial.java b/src/main/java/com/massivecraft/factions/util/XMaterial.java index a238aa61..18aa08dc 100644 --- a/src/main/java/com/massivecraft/factions/util/XMaterial.java +++ b/src/main/java/com/massivecraft/factions/util/XMaterial.java @@ -3,133 +3,163 @@ package com.massivecraft.factions.util; /* * The MIT License (MIT) * - * Original work Copyright (c) 2018 Hex_27 - * v2.0 Copyright (c) 2019 Crypto Morin + * Copyright (c) 2018 Hex_27 + * Copyright (c) 2020 Crypto Morin * * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE + * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - +import com.google.common.base.Enums; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; +import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; +import org.apache.commons.lang.WordUtils; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; /* * References * - * * * GitHub: https://github.com/CryptoMorin/XMaterial/blob/master/XMaterial.java - * * Thread: https://www.spigotmc.org/threads/378136/ - * https://minecraft.gamepedia.com/Java_Edition_data_values/Pre-flattening - * https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html - * http://docs.codelanx.com/Bukkit/1.8/org/bukkit/Material.html - * https://www.spigotmc.org/threads/1-8-to-1-13-itemstack-material-version-support.329630/ - * https://minecraft-ids.grahamedgecombe.com/ - * v1: https://pastebin.com/Fe65HZnN - * v2: 6/15/2019 + * * * GitHub: https://github.com/CryptoMorin/XSeries/blob/master/XMaterial.java + * * XSeries: https://www.spigotmc.org/threads/378136/ + * Pre-flattening: https://minecraft.gamepedia.com/Java_Edition_data_values/Pre-flattening + * Materials: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html + * Materials (1.12): https://helpch.at/docs/1.12.2/index.html?org/bukkit/Material.html + * Material IDs: https://minecraft-ids.grahamedgecombe.com/ + * Material Source Code: https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/browse/src/main/java/org/bukkit/Material.java + * XMaterial v1: https://www.spigotmc.org/threads/329630/ */ /** - * XMaterial v2.2 - Data Values/Pre-flattening - * Supports 1.8-1.14 + * XMaterial - Data Values/Pre-flattening
+ * Supports 1.8-1.15
* 1.13 and above as priority. + *

+ * This class is mainly designed to support ItemStacks. + * If you want to use it on blocks you'll have to + * use XBlock + * + * @author Crypto Morin + * @version 4.0.0 + * @see Material + * @see ItemStack */ public enum XMaterial { - ACACIA_BOAT(0, "BOAT_ACACIA"), - ACACIA_BUTTON(0, "WOOD_BUTTON"), - ACACIA_DOOR(0, "ACACIA_DOOR_ITEM"), - ACACIA_FENCE(0, ""), - ACACIA_FENCE_GATE(0, ""), - ACACIA_LEAVES(0, "LEAVES_2"), - ACACIA_LOG(0, "LOG_2"), + ACACIA_BOAT("BOAT_ACACIA"), + ACACIA_BUTTON("WOOD_BUTTON"), + ACACIA_DOOR("ACACIA_DOOR_ITEM"), + ACACIA_FENCE, + ACACIA_FENCE_GATE, + ACACIA_LEAVES("LEAVES_2"), + ACACIA_LOG("LOG_2"), ACACIA_PLANKS(4, "WOOD"), - ACACIA_PRESSURE_PLATE(0, "WOOD_PLATE"), + ACACIA_PRESSURE_PLATE("WOOD_PLATE"), ACACIA_SAPLING(4, "SAPLING"), - ACACIA_SIGN(0, "SIGN"), + ACACIA_SIGN("SIGN"), ACACIA_SLAB(4, "WOOD_STEP", "WOODEN_SLAB", "WOOD_DOUBLE_STEP"), - ACACIA_STAIRS(0, ""), - ACACIA_TRAPDOOR(0, "TRAP_DOOR"), - ACACIA_WALL_SIGN(0, "SIGN_POST", "WALL_SIGN"), - ACACIA_WOOD(0, "LOG_2"), - ACTIVATOR_RAIL(0, ""), - AIR(0, ""), + ACACIA_STAIRS, + ACACIA_TRAPDOOR("TRAP_DOOR"), + ACACIA_WALL_SIGN("SIGN_POST", "WALL_SIGN"), + ACACIA_WOOD("LOG_2"), + ACTIVATOR_RAIL, + /** + * https://minecraft.gamepedia.com/Air + * {@link Material#isAir()} + * + * @see #VOID_AIR + * @see #CAVE_AIR + */ + AIR, ALLIUM(2, "RED_ROSE"), - ANDESITE(5, "STONEZ"), - ANDESITE_SLAB(0, ""), - ANDESITE_STAIRS(0, ""), - ANDESITE_WALL(0, ""), - ANVIL(0, ""), - APPLE(0, ""), - ARMOR_STAND(0, ""), - ARROW(0, ""), + ANDESITE(5, "STONE"), + ANDESITE_SLAB, + ANDESITE_STAIRS, + ANDESITE_WALL, + ANVIL, + APPLE, + ARMOR_STAND, + ARROW, ATTACHED_MELON_STEM(7, "MELON_STEM"), ATTACHED_PUMPKIN_STEM(7, "PUMPKIN_STEM"), AZURE_BLUET(3, "RED_ROSE"), - BAKED_POTATO(0, ""), - BAMBOO(0, "1.14", "SUGAR_CANE"), - BAMBOO_SAPLING(0, "1.14"), - BARREL(0, "1.14", "CHEST"), - BARRIER(0, ""), + BAKED_POTATO, + BAMBOO("1.14", "SUGAR_CANE", ""), + BAMBOO_SAPLING("1.14"), + BARREL("1.14", "CHEST", ""), + BARRIER, BAT_SPAWN_EGG(65, "MONSTER_EGG"), - BEACON(0, ""), - BEDROCK(0, ""), - BEEF(0, "RAW_BEEF"), - BEETROOT(0, "BEETROOT_BLOCK"), - BEETROOTS(0, "BEETROOT"), - BEETROOT_SEEDS(0, ""), - BEETROOT_SOUP(0, ""), - BELL(0, "1.14"), - BIRCH_BOAT(0, "BOAT_BIRCH"), - BIRCH_BUTTON(0, "WOOD_BUTTON"), - BIRCH_DOOR(0, "BIRCH_DOOR_ITEM"), - BIRCH_FENCE(0, ""), - BIRCH_FENCE_GATE(0, ""), + BEACON, + BEDROCK, + BEEF("RAW_BEEF"), + BEEHIVE("1.15"), + /** + * Beetroot is a known material in pre-1.13 + * Use XBlock when comparing block types. + */ + BEETROOT("BEETROOT_BLOCK"), + BEETROOTS("BEETROOT"), + BEETROOT_SEEDS, + BEETROOT_SOUP, + BEE_NEST("1.15"), + BEE_SPAWN_EGG("1.15"), + BELL("1.14"), + BIRCH_BOAT("BOAT_BIRCH"), + BIRCH_BUTTON("WOOD_BUTTON"), + BIRCH_DOOR("BIRCH_DOOR_ITEM"), + BIRCH_FENCE, + BIRCH_FENCE_GATE, BIRCH_LEAVES(2, "LEAVES"), BIRCH_LOG(2, "LOG"), BIRCH_PLANKS(2, "WOOD"), - BIRCH_PRESSURE_PLATE(0, "WOOD_PLATE"), + BIRCH_PRESSURE_PLATE("WOOD_PLATE"), BIRCH_SAPLING(2, "SAPLING"), - BIRCH_SIGN(0, "SIGN"), + BIRCH_SIGN("SIGN"), BIRCH_SLAB(2, "WOOD_STEP", "WOODEN_SLAB", "WOOD_DOUBLE_STEP"), - BIRCH_STAIRS(0, "BIRCH_WOOD_STAIRS"), - BIRCH_TRAPDOOR(0, "TRAP_DOOR"), - BIRCH_WALL_SIGN(0, "SIGN_POST", "WALL_SIGN"), + BIRCH_STAIRS("BIRCH_WOOD_STAIRS"), + BIRCH_TRAPDOOR("TRAP_DOOR"), + BIRCH_WALL_SIGN("SIGN_POST", "WALL_SIGN"), BIRCH_WOOD(2, "LOG"), - BLACK_BANNER(0, "BANNER", "STANDING_BANNER"), + BLACK_BANNER("BANNER", "STANDING_BANNER"), BLACK_BED(15, "BED", "BED_BLOCK"), BLACK_CARPET(15, "CARPET"), BLACK_CONCRETE(15, "CONCRETE"), BLACK_CONCRETE_POWDER(15, "CONCRETE_POWDER"), - BLACK_DYE(0, "1.14", "INK_SACK"), + BLACK_DYE("1.14", "INK_SACK"), BLACK_GLAZED_TERRACOTTA(15, "1.12", "HARD_CLAY", "STAINED_CLAY", "BLACK_TERRACOTTA"), - BLACK_SHULKER_BOX(0, ""), + BLACK_SHULKER_BOX, BLACK_STAINED_GLASS(15, "STAINED_GLASS"), BLACK_STAINED_GLASS_PANE(15, "STAINED_GLASS_PANE"), BLACK_TERRACOTTA(15, "HARD_CLAY", "STAINED_CLAY"), - BLACK_WALL_BANNER(0, "WALL_BANNER"), + BLACK_WALL_BANNER("WALL_BANNER"), BLACK_WOOL(15, "WOOL"), - BLAST_FURNACE(0, "1.14", "FURNACE"), - BLAZE_POWDER(0, ""), - BLAZE_ROD(0, ""), + BLAST_FURNACE("1.14", "FURNACE", ""), + BLAZE_POWDER, + BLAZE_ROD, BLAZE_SPAWN_EGG(61, "MONSTER_EGG"), BLUE_BANNER(11, "BANNER", "STANDING_BANNER"), BLUE_BED(4, "BED", "BED_BLOCK"), @@ -138,126 +168,132 @@ public enum XMaterial { BLUE_CONCRETE_POWDER(11, "CONCRETE_POWDER"), BLUE_DYE(4, "INK_SACK", "LAPIS_LAZULI"), BLUE_GLAZED_TERRACOTTA(11, "1.12", "HARD_CLAY", "STAINED_CLAY", "BLUE_TERRACOTTA"), - BLUE_ICE(0, "1.13", "PACKED_ICE"), + BLUE_ICE("1.13", "PACKED_ICE", ""), BLUE_ORCHID(1, "RED_ROSE"), - BLUE_SHULKER_BOX(0, ""), + BLUE_SHULKER_BOX, BLUE_STAINED_GLASS(11, "STAINED_GLASS"), BLUE_STAINED_GLASS_PANE(11, "THIN_GLASS", "STAINED_GLASS_PANE"), BLUE_TERRACOTTA(11, "STAINED_CLAY"), BLUE_WALL_BANNER(11, "WALL_BANNER"), BLUE_WOOL(11, "WOOL"), - BONE(0, ""), - BONE_BLOCK(0, ""), + BONE, + BONE_BLOCK, BONE_MEAL(15, "INK_SACK"), - BOOK(0, ""), - BOOKSHELF(0, ""), - BOW(0, ""), - BOWL(0, ""), - BRAIN_CORAL(0, "1.13"), - BRAIN_CORAL_BLOCK(0, "1.13"), - BRAIN_CORAL_FAN(0, "1.13"), - BRAIN_CORAL_WALL_FAN(0, ""), - BREAD(0, ""), - BREWING_STAND(0, "BREWING_STAND_ITEM"), - BRICK(0, "CLAY_BRICK"), - BRICKS(0, "BRICK"), + BOOK, + BOOKSHELF, + BOW, + BOWL, + BRAIN_CORAL("1.13"), + BRAIN_CORAL_BLOCK("1.13"), + BRAIN_CORAL_FAN("1.13"), + BRAIN_CORAL_WALL_FAN, + BREAD, + BREWING_STAND("BREWING_STAND_ITEM"), + BRICK("CLAY_BRICK"), + BRICKS("BRICK"), BRICK_SLAB(4, "STEP"), - BRICK_STAIRS(0, ""), - BRICK_WALL(0, ""), + BRICK_STAIRS, + BRICK_WALL, BROWN_BANNER(3, "BANNER", "STANDING_BANNER"), BROWN_BED(12, "BED", "BED_BLOCK"), - BROWN_DYE(3, "INK_SACK", "COCOA", "COCOA_BEANS"), BROWN_CARPET(12, "CARPET"), BROWN_CONCRETE(12, "CONCRETE"), BROWN_CONCRETE_POWDER(12, "CONCRETE_POWDER"), + BROWN_DYE(3, "INK_SACK", "COCOA", "COCOA_BEANS"), BROWN_GLAZED_TERRACOTTA(12, "1.12", "HARD_CLAY", "STAINED_CLAY", "BROWN_TERRACOTTA"), - BROWN_MUSHROOM(0, ""), - BROWN_MUSHROOM_BLOCK(0, "BROWN_MUSHROOM", "HUGE_MUSHROOM_1"), - BROWN_SHULKER_BOX(0, ""), + BROWN_MUSHROOM, + BROWN_MUSHROOM_BLOCK("BROWN_MUSHROOM", "HUGE_MUSHROOM_1"), + BROWN_SHULKER_BOX, BROWN_STAINED_GLASS(12, "STAINED_GLASS"), BROWN_STAINED_GLASS_PANE(12, "THIN_GLASS", "STAINED_GLASS_PANE"), BROWN_TERRACOTTA(12, "STAINED_CLAY"), BROWN_WALL_BANNER(3, "WALL_BANNER"), BROWN_WOOL(12, "WOOL"), - BUBBLE_COLUMN(0, "1.13"), - BUBBLE_CORAL(0, "1.13"), - BUBBLE_CORAL_BLOCK(0, "1.13"), - BUBBLE_CORAL_FAN(0, "1.13"), - BUBBLE_CORAL_WALL_FAN(0, ""), - BUCKET(0, ""), - CACTUS(0, ""), - CAKE(0, "CAKE_BLOCK"), - CAMPFIRE(0, "1.14"), - CARROT(0, "CARROT_ITEM"), - CARROTS(0, "CARROT"), - CARROT_ON_A_STICK(0, "CARROT_STICK"), - CARTOGRAPHY_TABLE(0, "1.14", "CRAFTING_TABLE"), - CARVED_PUMPKIN(1, "PUMPKIN"), - CAT_SPAWN_EGG(0, ""), - CAULDRON(0, "CAULDRON_ITEM"), - CAVE_AIR(0, "AIR"), + BUBBLE_COLUMN("1.13"), + BUBBLE_CORAL("1.13"), + BUBBLE_CORAL_BLOCK("1.13"), + BUBBLE_CORAL_FAN("1.13"), + BUBBLE_CORAL_WALL_FAN, + BUCKET, + CACTUS, + CAKE("CAKE_BLOCK"), + CAMPFIRE("1.14"), + CARROT("CARROT_ITEM"), + CARROTS("CARROT"), + CARROT_ON_A_STICK("CARROT_STICK"), + CARTOGRAPHY_TABLE("1.14", "CRAFTING_TABLE", ""), + CARVED_PUMPKIN(1, "1.13", "PUMPKIN", ""), + CAT_SPAWN_EGG, + CAULDRON("CAULDRON_ITEM"), + /** + * 1.13 tag is not added because it's the same thing as {@link #AIR} + * + * @see #VOID_AIR + */ + CAVE_AIR("AIR"), CAVE_SPIDER_SPAWN_EGG(59, "MONSTER_EGG"), - CHAINMAIL_BOOTS(0, ""), - CHAINMAIL_CHESTPLATE(0, ""), - CHAINMAIL_HELMET(0, ""), - CHAINMAIL_LEGGINGS(0, ""), - CHAIN_COMMAND_BLOCK(0, "COMMAND", "COMMAND_CHAIN"), + CHAINMAIL_BOOTS, + CHAINMAIL_CHESTPLATE, + CHAINMAIL_HELMET, + CHAINMAIL_LEGGINGS, + CHAIN_COMMAND_BLOCK("COMMAND", "COMMAND_CHAIN"), CHARCOAL(1, "COAL"), - CHEST(0, "LOCKED_CHEST"), - CHEST_MINECART(0, "STORAGE_MINECART"), - CHICKEN(0, "RAW_CHICKEN"), + CHEST("LOCKED_CHEST"), + CHEST_MINECART("STORAGE_MINECART"), + CHICKEN("RAW_CHICKEN"), CHICKEN_SPAWN_EGG(93, "MONSTER_EGG"), CHIPPED_ANVIL(1, "ANVIL"), CHISELED_QUARTZ_BLOCK(1, "QUARTZ_BLOCK"), CHISELED_RED_SANDSTONE(1, "RED_SANDSTONE"), CHISELED_SANDSTONE(1, "SANDSTONE"), CHISELED_STONE_BRICKS(3, "SMOOTH_BRICK"), - CHORUS_FLOWER(0, ""), - CHORUS_FRUIT(0, ""), - CHORUS_PLANT(0, ""), - CLAY(0, ""), - CLAY_BALL(0, ""), - CLOCK(0, "WATCH"), - COAL(0, ""), - COAL_BLOCK(0, ""), - COAL_ORE(0, ""), + CHORUS_FLOWER("1.9"), + CHORUS_FRUIT("1.9"), + CHORUS_PLANT("1.9"), + CLAY, + CLAY_BALL, + CLOCK("WATCH"), + COAL, + COAL_BLOCK, + COAL_ORE, COARSE_DIRT(1, "DIRT"), - COBBLESTONE(0, ""), + COBBLESTONE, COBBLESTONE_SLAB(3, "STEP"), - COBBLESTONE_STAIRS(0, ""), - COBBLESTONE_WALL(0, "COBBLE_WALL"), - COBWEB(0, "WEB"), + COBBLESTONE_STAIRS, + COBBLESTONE_WALL("COBBLE_WALL"), + COBWEB("WEB"), + COCOA("1.15"), COCOA_BEANS(3, "INK_SACK", "COCOA"), - COD(0, "RAW_FISH"), - COD_BUCKET(0, "1.13", "BUCKET", "WATER_BUCKET"), - COD_SPAWN_EGG(0, "1.13", "MONSTER_EGG"), - COMMAND_BLOCK(0, "COMMAND"), - COMMAND_BLOCK_MINECART(0, "COMMAND_MINECART"), - COMPARATOR(0, "REDSTONE_COMPARATOR", "REDSTONE_COMPARATOR_ON", "REDSTONE_COMPARATOR_OFF"), - COMPASS(0, ""), - COMPOSTER(0, "1.14", "CAULDRON"), - CONDUIT(0, "1.13"), - COOKED_BEEF(0, ""), - COOKED_CHICKEN(0, ""), - COOKED_COD(0, "COOKED_FISH"), - COOKED_MUTTON(0, ""), - COOKED_PORKCHOP(0, "PORK", "GRILLED_PORK"), - COOKED_RABBIT(0, ""), + COD("RAW_FISH"), + COD_BUCKET("1.13", "BUCKET", "WATER_BUCKET", ""), + COD_SPAWN_EGG("1.13", "MONSTER_EGG", ""), + COMMAND_BLOCK("COMMAND"), + COMMAND_BLOCK_MINECART("COMMAND_MINECART"), + COMPARATOR("REDSTONE_COMPARATOR", "REDSTONE_COMPARATOR_ON", "REDSTONE_COMPARATOR_OFF"), + COMPASS, + COMPOSTER("1.14", "CAULDRON", ""), + CONDUIT("1.13", "BEACON"), + COOKED_BEEF, + COOKED_CHICKEN, + COOKED_COD("COOKED_FISH"), + COOKED_MUTTON, + COOKED_PORKCHOP("PORK", "GRILLED_PORK"), + COOKED_RABBIT, COOKED_SALMON(1, "COOKED_FISH"), - COOKIE(0, ""), - CORNFLOWER(4, "1.14", "BLUE_DYE"), + COOKIE, + CORNFLOWER(4, "1.14", "BLUE_DYE", ""), COW_SPAWN_EGG(92, "MONSTER_EGG"), CRACKED_STONE_BRICKS(2, "SMOOTH_BRICK"), - CRAFTING_TABLE(0, "WORKBENCH"), - CREEPER_BANNER_PATTERN(0, ""), + CRAFTING_TABLE("WORKBENCH"), + CREEPER_BANNER_PATTERN, CREEPER_HEAD(4, "SKULL", "SKULL_ITEM"), CREEPER_SPAWN_EGG(50, "MONSTER_EGG"), CREEPER_WALL_HEAD(4, "SKULL", "SKULL_ITEM"), - CROSSBOW(0, ""), - CUT_RED_SANDSTONE(0, "1.13"), - CUT_RED_SANDSTONE_SLAB(0, "STONE_SLAB2"), - CUT_SANDSTONE(0, "1.13"), - CUT_SANDSTONE_SLAB(0, "STEP"), + CROSSBOW, + CUT_RED_SANDSTONE("1.13"), + CUT_RED_SANDSTONE_SLAB("STONE_SLAB2"), + CUT_SANDSTONE("1.13"), + CUT_SANDSTONE_SLAB("STEP"), CYAN_BANNER(6, "BANNER", "STANDING_BANNER"), CYAN_BED(9, "BED", "BED_BLOCK"), CYAN_CARPET(9, "CARPET"), @@ -265,168 +301,171 @@ public enum XMaterial { CYAN_CONCRETE_POWDER(9, "CONCRETE_POWDER"), CYAN_DYE(6, "INK_SACK"), CYAN_GLAZED_TERRACOTTA(9, "1.12", "HARD_CLAY", "STAINED_CLAY", "CYAN_TERRACOTTA"), - CYAN_SHULKER_BOX(0, ""), + CYAN_SHULKER_BOX, CYAN_STAINED_GLASS(9, "STAINED_GLASS"), CYAN_STAINED_GLASS_PANE(9, "STAINED_GLASS_PANE"), CYAN_TERRACOTTA(9, "HARD_CLAY", "STAINED_CLAY"), CYAN_WALL_BANNER(6, "WALL_BANNER"), CYAN_WOOL(9, "WOOL"), DAMAGED_ANVIL(2, "ANVIL"), - DANDELION(0, "YELLOW_FLOWER"), - DARK_OAK_BOAT(0, "BOAT_DARK_OAK"), - DARK_OAK_BUTTON(0, "WOOD_BUTTON"), - DARK_OAK_DOOR(0, "DARK_OAK_DOOR_ITEM"), - DARK_OAK_FENCE(0, ""), - DARK_OAK_FENCE_GATE(0, ""), + DANDELION("YELLOW_FLOWER"), + DARK_OAK_BOAT("BOAT_DARK_OAK"), + DARK_OAK_BUTTON("WOOD_BUTTON"), + DARK_OAK_DOOR("DARK_OAK_DOOR_ITEM"), + DARK_OAK_FENCE, + DARK_OAK_FENCE_GATE, DARK_OAK_LEAVES(1, "LEAVES", "LEAVES_2"), DARK_OAK_LOG(1, "LOG", "LOG_2"), DARK_OAK_PLANKS(5, "WOOD"), - DARK_OAK_PRESSURE_PLATE(0, "WOOD_PLATE"), + DARK_OAK_PRESSURE_PLATE("WOOD_PLATE"), DARK_OAK_SAPLING(5, "SAPLING"), - DARK_OAK_SIGN(0, "SIGN"), - DARK_OAK_SLAB(0, "WOOD_STEP", "WOODEN_SLAB", "WOOD_DOUBLE_STEP"), - DARK_OAK_STAIRS(0, ""), - DARK_OAK_TRAPDOOR(0, "TRAP_DOOR"), - DARK_OAK_WALL_SIGN(0, "SIGN_POST", "WALL_SIGN"), + DARK_OAK_SIGN("SIGN"), + DARK_OAK_SLAB("WOOD_STEP", "WOODEN_SLAB", "WOOD_DOUBLE_STEP"), + DARK_OAK_STAIRS, + DARK_OAK_TRAPDOOR("TRAP_DOOR"), + DARK_OAK_WALL_SIGN("SIGN_POST", "WALL_SIGN"), DARK_OAK_WOOD(1, "LOG", "LOG_2"), DARK_PRISMARINE(1, "PRISMARINE"), - DARK_PRISMARINE_SLAB(0, "1.13"), - DARK_PRISMARINE_STAIRS(0, "1.13"), - DAYLIGHT_DETECTOR(0, "DAYLIGHT_DETECTOR_INVERTED"), - DEAD_BRAIN_CORAL(0, ""), - DEAD_BRAIN_CORAL_BLOCK(0, "1.13"), - DEAD_BRAIN_CORAL_FAN(0, ""), - DEAD_BRAIN_CORAL_WALL_FAN(0, ""), - DEAD_BUBBLE_CORAL(0, ""), - DEAD_BUBBLE_CORAL_BLOCK(0, "1.13"), - DEAD_BUBBLE_CORAL_FAN(0, ""), - DEAD_BUBBLE_CORAL_WALL_FAN(0, ""), - DEAD_BUSH(0, ""), - DEAD_FIRE_CORAL(0, ""), - DEAD_FIRE_CORAL_BLOCK(0, "1.13"), - DEAD_FIRE_CORAL_FAN(0, ""), - DEAD_FIRE_CORAL_WALL_FAN(0, ""), - DEAD_HORN_CORAL(0, ""), - DEAD_HORN_CORAL_BLOCK(0, "1.13"), - DEAD_HORN_CORAL_FAN(0, ""), - DEAD_HORN_CORAL_WALL_FAN(0, ""), - DEAD_TUBE_CORAL(0, ""), - DEAD_TUBE_CORAL_BLOCK(0, "1.13"), - DEAD_TUBE_CORAL_FAN(0, ""), - DEAD_TUBE_CORAL_WALL_FAN(0, ""), - DEBUG_STICK(0, "1.13", "STICK"), - DETECTOR_RAIL(0, ""), - DIAMOND(0, ""), - DIAMOND_AXE(0, ""), - DIAMOND_BLOCK(0, ""), - DIAMOND_BOOTS(0, ""), - DIAMOND_CHESTPLATE(0, ""), - DIAMOND_HELMET(0, ""), - DIAMOND_HOE(0, ""), - DIAMOND_HORSE_ARMOR(0, "DIAMOND_BARDING"), - DIAMOND_LEGGINGS(0, ""), - DIAMOND_ORE(0, ""), - DIAMOND_PICKAXE(0, ""), - DIAMOND_SHOVEL(0, "DIAMOND_SPADE"), - DIAMOND_SWORD(0, ""), - DIORITE(3, "1.13"), - DIORITE_SLAB(0, ""), - DIORITE_STAIRS(0, ""), - DIORITE_WALL(0, ""), - DIRT(0, ""), - DISPENSER(0, ""), - DOLPHIN_SPAWN_EGG(0, "1.13", "MONSTER_EGG"), + DARK_PRISMARINE_SLAB("1.13"), + DARK_PRISMARINE_STAIRS("1.13"), + DAYLIGHT_DETECTOR("DAYLIGHT_DETECTOR_INVERTED"), + DEAD_BRAIN_CORAL("1.13"), + DEAD_BRAIN_CORAL_BLOCK("1.13"), + DEAD_BRAIN_CORAL_FAN("1.13"), + DEAD_BRAIN_CORAL_WALL_FAN("1.13"), + DEAD_BUBBLE_CORAL("1.13"), + DEAD_BUBBLE_CORAL_BLOCK("1.13"), + DEAD_BUBBLE_CORAL_FAN("1.13"), + DEAD_BUBBLE_CORAL_WALL_FAN("1.13"), + DEAD_BUSH, + DEAD_FIRE_CORAL("1.13"), + DEAD_FIRE_CORAL_BLOCK("1.13"), + DEAD_FIRE_CORAL_FAN("1.13"), + DEAD_FIRE_CORAL_WALL_FAN("1.13"), + DEAD_HORN_CORAL("1.13"), + DEAD_HORN_CORAL_BLOCK("1.13"), + DEAD_HORN_CORAL_FAN("1.13"), + DEAD_HORN_CORAL_WALL_FAN("1.13"), + DEAD_TUBE_CORAL("1.13"), + DEAD_TUBE_CORAL_BLOCK("1.13"), + DEAD_TUBE_CORAL_FAN("1.13"), + DEAD_TUBE_CORAL_WALL_FAN("1.13"), + DEBUG_STICK("1.13", "STICK", ""), + DETECTOR_RAIL, + DIAMOND, + DIAMOND_AXE, + DIAMOND_BLOCK, + DIAMOND_BOOTS, + DIAMOND_CHESTPLATE, + DIAMOND_HELMET, + DIAMOND_HOE, + DIAMOND_HORSE_ARMOR("DIAMOND_BARDING"), + DIAMOND_LEGGINGS, + DIAMOND_ORE, + DIAMOND_PICKAXE, + DIAMOND_SHOVEL("DIAMOND_SPADE"), + DIAMOND_SWORD, + DIORITE(3, "STONE"), + DIORITE_SLAB, + DIORITE_STAIRS, + DIORITE_WALL, + DIRT, + DISPENSER, + DOLPHIN_SPAWN_EGG("1.13", "MONSTER_EGG", ""), DONKEY_SPAWN_EGG(32, "MONSTER_EGG"), - DRAGON_BREATH(0, "DRAGONS_BREATH"), - DRAGON_EGG(0, ""), - DRAGON_HEAD(5, "SKULL", "SKULL_ITEM"), + DRAGON_BREATH("DRAGONS_BREATH"), + DRAGON_EGG, + DRAGON_HEAD(5, "1.9", "SKULL", "SKULL_ITEM"), DRAGON_WALL_HEAD(5, "SKULL", "SKULL_ITEM"), - DRIED_KELP(0, "1.13"), - DRIED_KELP_BLOCK(0, "1.13"), - DROPPER(0, ""), - DROWNED_SPAWN_EGG(0, "1.13", "MONSTER_EGG"), - EGG(0, ""), + DRIED_KELP("1.13"), + DRIED_KELP_BLOCK("1.13"), + DROPPER, + DROWNED_SPAWN_EGG("1.13", "MONSTER_EGG", ""), + EGG, ELDER_GUARDIAN_SPAWN_EGG(4, "MONSTER_EGG"), - ELYTRA(0, ""), - EMERALD(0, ""), - EMERALD_BLOCK(0, ""), - EMERALD_ORE(0, ""), - ENCHANTED_BOOK(0, ""), + ELYTRA, + EMERALD, + EMERALD_BLOCK, + EMERALD_ORE, + ENCHANTED_BOOK, ENCHANTED_GOLDEN_APPLE(1, "GOLDEN_APPLE"), - ENCHANTING_TABLE(0, "ENCHANTMENT_TABLE"), + ENCHANTING_TABLE("ENCHANTMENT_TABLE"), ENDERMAN_SPAWN_EGG(58, "MONSTER_EGG"), ENDERMITE_SPAWN_EGG(67, "MONSTER_EGG"), - ENDER_CHEST(0, ""), - ENDER_EYE(0, "EYE_OF_ENDER"), - ENDER_PEARL(0, ""), - END_CRYSTAL(0, ""), - END_GATEWAY(0, ""), - END_PORTAL(0, "ENDER_PORTAL"), - END_PORTAL_FRAME(0, "ENDER_PORTAL_FRAME"), - END_ROD(0, ""), - END_STONE(0, "ENDER_STONE"), - END_STONE_BRICKS(0, "END_BRICKS"), + ENDER_CHEST, + ENDER_EYE("EYE_OF_ENDER"), + ENDER_PEARL, + END_CRYSTAL, + END_GATEWAY("1.9"), + END_PORTAL("ENDER_PORTAL"), + END_PORTAL_FRAME("ENDER_PORTAL_FRAME"), + END_ROD("1.9", "BLAZE_ROD", ""), + END_STONE("ENDER_STONE"), + END_STONE_BRICKS("END_BRICKS"), END_STONE_BRICK_SLAB(4, "STEP"), - END_STONE_BRICK_STAIRS(0, "SMOOTH_STAIRS"), - END_STONE_BRICK_WALL(0, ""), + END_STONE_BRICK_STAIRS("SMOOTH_STAIRS"), + END_STONE_BRICK_WALL, EVOKER_SPAWN_EGG(34, "MONSTER_EGG"), - EXPERIENCE_BOTTLE(0, "EXP_BOTTLE"), - FARMLAND(0, "SOIL"), - FEATHER(0, ""), - FERMENTED_SPIDER_EYE(0, ""), + EXPERIENCE_BOTTLE("EXP_BOTTLE"), + FARMLAND("SOIL"), + FEATHER, + FERMENTED_SPIDER_EYE, FERN(2, "LONG_GRASS"), - FILLED_MAP(0, "MAP"), - FIRE(0, ""), - FIREWORK_ROCKET(0, "FIREWORK"), - FIREWORK_STAR(0, "FIREWORK_CHARGE"), - FIRE_CHARGE(0, "FIREBALL"), - FIRE_CORAL(0, "1.13"), - FIRE_CORAL_BLOCK(0, "1.13"), - FIRE_CORAL_FAN(0, "1.13"), - FIRE_CORAL_WALL_FAN(0, ""), - FISHING_ROD(0, ""), - FLETCHING_TABLE(0, "1.14", "CRAFTING_TABLE"), - FLINT(0, ""), - FLINT_AND_STEEL(0, ""), - FLOWER_BANNER_PATTERN(0, ""), - FLOWER_POT(0, "FLOWER_POT_ITEM"), - FOX_SPAWN_EGG(0, "1.14"), - FROSTED_ICE(0, ""), - FURNACE(0, "BURNING_FURNACE"), - FURNACE_MINECART(0, "POWERED_MINECART"), + FILLED_MAP("MAP"), + FIRE, + FIREWORK_ROCKET("FIREWORK"), + FIREWORK_STAR("FIREWORK_CHARGE"), + FIRE_CHARGE("FIREBALL"), + FIRE_CORAL("1.13"), + FIRE_CORAL_BLOCK("1.13"), + FIRE_CORAL_FAN("1.13"), + FIRE_CORAL_WALL_FAN, + FISHING_ROD, + FLETCHING_TABLE("1.14", "CRAFTING_TABLE", ""), + FLINT, + FLINT_AND_STEEL, + FLOWER_BANNER_PATTERN, + FLOWER_POT("FLOWER_POT_ITEM"), + FOX_SPAWN_EGG("1.14"), + /** + * This special material cannot be obtained as an item. + */ + FROSTED_ICE("1.9", "PACKED_ICE", ""), + FURNACE("BURNING_FURNACE"), + FURNACE_MINECART("POWERED_MINECART"), GHAST_SPAWN_EGG(56, "MONSTER_EGG"), - GHAST_TEAR(0, ""), - GLASS(0, ""), - GLASS_BOTTLE(0, ""), - GLASS_PANE(0, "THIN_GLASS"), - GLISTERING_MELON_SLICE(0, "SPECKLED_MELON"), - GLOBE_BANNER_PATTERN(0, ""), - GLOWSTONE(0, ""), - GLOWSTONE_DUST(0, ""), - GOLDEN_APPLE(0, ""), - GOLDEN_AXE(0, "GOLD_AXE"), - GOLDEN_BOOTS(0, "GOLD_BOOTS"), - GOLDEN_CARROT(0, ""), - GOLDEN_CHESTPLATE(0, "GOLD_CHESTPLATE"), - GOLDEN_HELMET(0, "GOLD_HELMET"), - GOLDEN_HOE(0, "GOLD_HOE"), - GOLDEN_HORSE_ARMOR(0, "GOLD_BARDING"), - GOLDEN_LEGGINGS(0, "GOLD_LEGGINGS"), - GOLDEN_PICKAXE(0, "GOLD_PICKAXE"), - GOLDEN_SHOVEL(0, "GOLD_SPADE"), - GOLDEN_SWORD(0, "GOLD_SWORD"), - GOLD_BLOCK(0, ""), - GOLD_INGOT(0, ""), - GOLD_NUGGET(0, ""), - GOLD_ORE(0, ""), - GRANITE(1, "1.13"), - GRANITE_SLAB(0, ""), - GRANITE_STAIRS(0, ""), - GRANITE_WALL(0, ""), - GRASS(0, ""), - GRASS_BLOCK(0, "GRASS"), - GRASS_PATH(0, ""), - GRAVEL(0, ""), + GHAST_TEAR, + GLASS, + GLASS_BOTTLE, + GLASS_PANE("THIN_GLASS"), + GLISTERING_MELON_SLICE("SPECKLED_MELON"), + GLOBE_BANNER_PATTERN, + GLOWSTONE, + GLOWSTONE_DUST, + GOLDEN_APPLE, + GOLDEN_AXE("GOLD_AXE"), + GOLDEN_BOOTS("GOLD_BOOTS"), + GOLDEN_CARROT, + GOLDEN_CHESTPLATE("GOLD_CHESTPLATE"), + GOLDEN_HELMET("GOLD_HELMET"), + GOLDEN_HOE("GOLD_HOE"), + GOLDEN_HORSE_ARMOR("GOLD_BARDING"), + GOLDEN_LEGGINGS("GOLD_LEGGINGS"), + GOLDEN_PICKAXE("GOLD_PICKAXE"), + GOLDEN_SHOVEL("GOLD_SPADE"), + GOLDEN_SWORD("GOLD_SWORD"), + GOLD_BLOCK, + GOLD_INGOT, + GOLD_NUGGET, + GOLD_ORE, + GRANITE(1, "STONE"), + GRANITE_SLAB, + GRANITE_STAIRS, + GRANITE_WALL, + GRASS, + GRASS_BLOCK("GRASS"), + GRASS_PATH, + GRAVEL, GRAY_BANNER(8, "BANNER", "STANDING_BANNER"), GRAY_BED(7, "BED", "BED_BLOCK"), GRAY_CARPET(7, "CARPET"), @@ -434,12 +473,12 @@ public enum XMaterial { GRAY_CONCRETE_POWDER(7, "CONCRETE_POWDER"), GRAY_DYE(8, "INK_SACK"), GRAY_GLAZED_TERRACOTTA(7, "1.12", "HARD_CLAY", "STAINED_CLAY", "GRAY_TERRACOTTA"), - GRAY_SHULKER_BOX(0, ""), - GRAY_STAINED_GLASS(8, "STAINED_GLASS"), + GRAY_SHULKER_BOX, + GRAY_STAINED_GLASS(7, "STAINED_GLASS"), GRAY_STAINED_GLASS_PANE(7, "THIN_GLASS", "STAINED_GLASS_PANE"), GRAY_TERRACOTTA(7, "HARD_CLAY", "STAINED_CLAY"), GRAY_WALL_BANNER(8, "WALL_BANNER"), - GRAY_WOOL(8, "WOOL"), + GRAY_WOOL(7, "WOOL"), GREEN_BANNER(2, "BANNER", "STANDING_BANNER"), GREEN_BED(13, "BED", "BED_BLOCK"), GREEN_CARPET(13, "CARPET"), @@ -447,121 +486,129 @@ public enum XMaterial { GREEN_CONCRETE_POWDER(13, "CONCRETE_POWDER"), GREEN_DYE(2, "INK_SACK", "CACTUS_GREEN"), GREEN_GLAZED_TERRACOTTA(13, "1.12", "HARD_CLAY", "STAINED_CLAY", "GREEN_TERRACOTTA"), - GREEN_SHULKER_BOX(0, ""), + GREEN_SHULKER_BOX, GREEN_STAINED_GLASS(13, "STAINED_GLASS"), GREEN_STAINED_GLASS_PANE(13, "THIN_GLASS", "STAINED_GLASS_PANE"), GREEN_TERRACOTTA(13, "HARD_CLAY", "STAINED_CLAY"), GREEN_WALL_BANNER(2, "WALL_BANNER"), GREEN_WOOL(13, "WOOL"), - GRINDSTONE(0, "1.14", "ANVIL"), + GRINDSTONE("1.14", "ANVIL", ""), GUARDIAN_SPAWN_EGG(68, "MONSTER_EGG"), - GUNPOWDER(0, "SULPHUR"), - HAY_BLOCK(0, ""), - HEART_OF_THE_SEA(0, "1.13"), - HEAVY_WEIGHTED_PRESSURE_PLATE(0, "IRON_PLATE"), - HOPPER(0, ""), - HOPPER_MINECART(0, ""), - HORN_CORAL(0, "1.13"), - HORN_CORAL_BLOCK(0, "1.13"), - HORN_CORAL_FAN(0, "1.13"), - HORN_CORAL_WALL_FAN(0, ""), + GUNPOWDER("SULPHUR"), + HAY_BLOCK, + HEART_OF_THE_SEA("1.13"), + HEAVY_WEIGHTED_PRESSURE_PLATE("IRON_PLATE"), + HONEYCOMB("1.15"), + HONEYCOMB_BLOCK("1.15"), + HONEY_BLOCK("1.15", "SLIME_BLOCK", ""), + HONEY_BOTTLE("1.15", "GLASS_BOTTLE", ""), + HOPPER, + HOPPER_MINECART, + HORN_CORAL("1.13"), + HORN_CORAL_BLOCK("1.13"), + HORN_CORAL_FAN("1.13"), + HORN_CORAL_WALL_FAN, HORSE_SPAWN_EGG(100, "MONSTER_EGG"), HUSK_SPAWN_EGG(23, "MONSTER_EGG"), - ICE(0, ""), + ICE, INFESTED_CHISELED_STONE_BRICKS(5, "MONSTER_EGGS", "SMOOTH_BRICK"), INFESTED_COBBLESTONE(1, "MONSTER_EGGS"), INFESTED_CRACKED_STONE_BRICKS(4, "MONSTER_EGGS", "SMOOTH_BRICK"), INFESTED_MOSSY_STONE_BRICKS(3, "MONSTER_EGGS"), - INFESTED_STONE(0, "MONSTER_EGGS"), + INFESTED_STONE("MONSTER_EGGS"), INFESTED_STONE_BRICKS(2, "MONSTER_EGGS", "SMOOTH_BRICK"), - INK_SAC(0, "INK_SACK"), - IRON_AXE(0, ""), - IRON_BARS(0, "IRON_FENCE"), - IRON_BLOCK(0, ""), - IRON_BOOTS(0, ""), - IRON_CHESTPLATE(0, ""), - IRON_DOOR(0, "IRON_DOOR_BLOCK"), - IRON_HELMET(0, ""), - IRON_HOE(0, ""), - IRON_HORSE_ARMOR(0, "IRON_BARDING"), - IRON_INGOT(0, ""), - IRON_LEGGINGS(0, ""), - IRON_NUGGET(0, ""), - IRON_ORE(0, ""), - IRON_PICKAXE(0, ""), - IRON_SHOVEL(0, "IRON_SPADE"), - IRON_SWORD(0, ""), - IRON_TRAPDOOR(0, ""), - ITEM_FRAME(0, ""), - JACK_O_LANTERN(0, ""), - JIGSAW(0, "1.14", "COMMAND_BLOCK", "STRUCTURE_BLOCK"), - JUKEBOX(0, ""), - JUNGLE_BOAT(0, "BOAT_JUNGLE"), - JUNGLE_BUTTON(0, "WOOD_BUTTON"), - JUNGLE_DOOR(0, "JUNGLE_DOOR_ITEM"), - JUNGLE_FENCE(0, ""), - JUNGLE_FENCE_GATE(0, ""), + INK_SAC("INK_SACK"), + IRON_AXE, + IRON_BARS("IRON_FENCE"), + IRON_BLOCK, + IRON_BOOTS, + IRON_CHESTPLATE, + IRON_DOOR("IRON_DOOR_BLOCK"), + IRON_HELMET, + IRON_HOE, + IRON_HORSE_ARMOR("IRON_BARDING"), + IRON_INGOT, + IRON_LEGGINGS, + IRON_NUGGET, + IRON_ORE, + IRON_PICKAXE, + IRON_SHOVEL("IRON_SPADE"), + IRON_SWORD, + IRON_TRAPDOOR, + ITEM_FRAME, + JACK_O_LANTERN, + JIGSAW("1.14", "COMMAND_BLOCK", "STRUCTURE_BLOCK", ""), + JUKEBOX, + JUNGLE_BOAT("BOAT_JUNGLE"), + JUNGLE_BUTTON("WOOD_BUTTON"), + JUNGLE_DOOR("JUNGLE_DOOR_ITEM"), + JUNGLE_FENCE, + JUNGLE_FENCE_GATE, JUNGLE_LEAVES(3, "LEAVES"), JUNGLE_LOG(3, "LOG"), JUNGLE_PLANKS(3, "WOOD"), - JUNGLE_PRESSURE_PLATE(0, "WOOD_PLATE"), + JUNGLE_PRESSURE_PLATE("WOOD_PLATE"), JUNGLE_SAPLING(3, "SAPLING"), - JUNGLE_SIGN(0, "SIGN"), + JUNGLE_SIGN("SIGN"), JUNGLE_SLAB(3, "WOOD_STEP", "WOODEN_SLAB", "WOOD_DOUBLE_STEP"), - JUNGLE_STAIRS(0, "JUNGLE_WOOD_STAIRS"), - JUNGLE_TRAPDOOR(0, "TRAP_DOOR"), - JUNGLE_WALL_SIGN(0, "SIGN_POST", "WALL_SIGN"), + JUNGLE_STAIRS("JUNGLE_WOOD_STAIRS"), + JUNGLE_TRAPDOOR("TRAP_DOOR"), + JUNGLE_WALL_SIGN("SIGN_POST", "WALL_SIGN"), JUNGLE_WOOD(3, "LOG"), - KELP(0, "1.13"), - KELP_PLANT(0, "1.13"), - KNOWLEDGE_BOOK(0, ""), - LADDER(0, ""), - LANTERN(0, "1.14", "SEA_LANTERN"), - LAPIS_BLOCK(0, ""), + KELP("1.13"), + KELP_PLANT("1.13"), + KNOWLEDGE_BOOK("1.12", "BOOK"), + LADDER, + LANTERN("1.14", "SEA_LANTERN", ""), + LAPIS_BLOCK, LAPIS_LAZULI(4, "INK_SACK"), - LAPIS_ORE(0, ""), + LAPIS_ORE, LARGE_FERN(3, "DOUBLE_PLANT"), - LAVA(0, "STATIONARY_LAVA"), - LAVA_BUCKET(0, ""), - LEAD(0, "LEASH"), - LEATHER(0, ""), - LEATHER_BOOTS(0, ""), - LEATHER_CHESTPLATE(0, ""), - LEATHER_HELMET(0, ""), - LEATHER_HORSE_ARMOR(0, "1.14", "IRON_HORSE_ARMOR"), - LEATHER_LEGGINGS(0, ""), - LECTERN(0, "1.14", "BOOKSHELF"), - LEVER(0, ""), - LIGHT_BLUE_BANNER(11, "BANNER", "STANDING_BANNER"), + LAVA("STATIONARY_LAVA"), + LAVA_BUCKET, + LEAD("LEASH"), + LEATHER, + LEATHER_BOOTS, + LEATHER_CHESTPLATE, + LEATHER_HELMET, + LEATHER_HORSE_ARMOR("1.14", "IRON_HORSE_ARMOR", ""), + LEATHER_LEGGINGS, + LECTERN("1.14", "BOOKSHELF", ""), + LEVER, + LIGHT_BLUE_BANNER(3, "BANNER", "STANDING_BANNER"), LIGHT_BLUE_BED(3, "BED", "BED_BLOCK"), LIGHT_BLUE_CARPET(3, "CARPET"), LIGHT_BLUE_CONCRETE(3, "CONCRETE"), LIGHT_BLUE_CONCRETE_POWDER(3, "CONCRETE_POWDER"), LIGHT_BLUE_DYE(12, "INK_SACK"), LIGHT_BLUE_GLAZED_TERRACOTTA(3, "1.12", "HARD_CLAY", "STAINED_CLAY", "LIGHT_BLUE_TERRACOTTA"), - LIGHT_BLUE_SHULKER_BOX(0, ""), - LIGHT_BLUE_STAINED_GLASS(11, "STAINED_GLASS"), + LIGHT_BLUE_SHULKER_BOX, + LIGHT_BLUE_STAINED_GLASS(3, "STAINED_GLASS"), LIGHT_BLUE_STAINED_GLASS_PANE(3, "THIN_GLASS", "STAINED_GLASS_PANE"), LIGHT_BLUE_TERRACOTTA(3, "STAINED_CLAY"), LIGHT_BLUE_WALL_BANNER(12, "WALL_BANNER", "BANNER", "STANDING_BANNER"), - LIGHT_BLUE_WOOL(11, "WOOL"), + LIGHT_BLUE_WOOL(3, "WOOL"), LIGHT_GRAY_BANNER(7, "BANNER", "STANDING_BANNER"), - LIGHT_GRAY_BED(7, "BED", "BED_BLOCK"), + LIGHT_GRAY_BED(8, "BED", "BED_BLOCK"), LIGHT_GRAY_CARPET(8, "CARPET"), LIGHT_GRAY_CONCRETE(8, "CONCRETE"), LIGHT_GRAY_CONCRETE_POWDER(8, "CONCRETE_POWDER"), LIGHT_GRAY_DYE(7, "INK_SACK"), - LIGHT_GRAY_GLAZED_TERRACOTTA(8, "1.12", "HARD_CLAY", "STAINED_CLAY", "LIGHT_GRAY_TERRACOTTA", "SILVER_GLAZED_TERRACOTTA/1.13"), - LIGHT_GRAY_SHULKER_BOX(0, "SILVER_SHULKER_BOX"), + /** + * Renamed to SILVER_GLAZED_TERRACOTTA in 1.13 + * Renamed to LIGHT_GRAY_GLAZED_TERRACOTTA in 1.14 + */ + LIGHT_GRAY_GLAZED_TERRACOTTA(8, "1.12", "HARD_CLAY", "STAINED_CLAY", "LIGHT_GRAY_TERRACOTTA", "SILVER_GLAZED_TERRACOTTA"), + LIGHT_GRAY_SHULKER_BOX("SILVER_SHULKER_BOX"), LIGHT_GRAY_STAINED_GLASS(8, "STAINED_GLASS"), LIGHT_GRAY_STAINED_GLASS_PANE(8, "THIN_GLASS", "STAINED_GLASS_PANE"), LIGHT_GRAY_TERRACOTTA(8, "HARD_CLAY", "STAINED_CLAY"), LIGHT_GRAY_WALL_BANNER(7, "WALL_BANNER"), LIGHT_GRAY_WOOL(8, "WOOL"), - LIGHT_WEIGHTED_PRESSURE_PLATE(0, "GOLD_PLATE"), + LIGHT_WEIGHTED_PRESSURE_PLATE("GOLD_PLATE"), LILAC(1, "DOUBLE_PLANT"), - LILY_OF_THE_VALLEY(15, "1.14", "WHITE_DYE"), - LILY_PAD(0, "WATER_LILY"), + LILY_OF_THE_VALLEY(15, "1.14", "WHITE_DYE", ""), + LILY_PAD("WATER_LILY"), LIME_BANNER(10, "BANNER", "STANDING_BANNER"), LIME_BED(5, "BED", "BED_BLOCK"), LIME_CARPET(5, "CARPET"), @@ -569,15 +616,15 @@ public enum XMaterial { LIME_CONCRETE_POWDER(5, "CONCRETE_POWDER"), LIME_DYE(10, "INK_SACK"), LIME_GLAZED_TERRACOTTA(5, "1.12", "HARD_CLAY", "STAINED_CLAY", "LIME_TERRACOTTA"), - LIME_SHULKER_BOX(0, ""), + LIME_SHULKER_BOX, LIME_STAINED_GLASS(5, "STAINED_GLASS"), LIME_STAINED_GLASS_PANE(5, "STAINED_GLASS_PANE"), LIME_TERRACOTTA(5, "HARD_CLAY", "STAINED_CLAY"), LIME_WALL_BANNER(10, "WALL_BANNER"), LIME_WOOL(5, "WOOL"), - LINGERING_POTION(0, ""), + LINGERING_POTION, LLAMA_SPAWN_EGG(103, "MONSTER_EGG"), - LOOM(0, "1.14"), + LOOM("1.14"), MAGENTA_BANNER(13, "BANNER", "STANDING_BANNER"), MAGENTA_BED(2, "BED", "BED_BLOCK"), MAGENTA_CARPET(2, "CARPET"), @@ -585,83 +632,88 @@ public enum XMaterial { MAGENTA_CONCRETE_POWDER(2, "CONCRETE_POWDER"), MAGENTA_DYE(13, "INK_SACK"), MAGENTA_GLAZED_TERRACOTTA(2, "1.12", "HARD_CLAY", "STAINED_CLAY", "MAGENTA_TERRACOTTA"), - MAGENTA_SHULKER_BOX(0, ""), + MAGENTA_SHULKER_BOX, MAGENTA_STAINED_GLASS(2, "STAINED_GLASS"), MAGENTA_STAINED_GLASS_PANE(2, "THIN_GLASS", "STAINED_GLASS_PANE"), MAGENTA_TERRACOTTA(2, "HARD_CLAY", "STAINED_CLAY"), MAGENTA_WALL_BANNER(13, "WALL_BANNER"), MAGENTA_WOOL(2, "WOOL"), - MAGMA_BLOCK(0, "MAGMA"), - MAGMA_CREAM(0, ""), + MAGMA_BLOCK("1.10", "MAGMA"), + MAGMA_CREAM, MAGMA_CUBE_SPAWN_EGG(62, "MONSTER_EGG"), - MAP(0, "EMPTY_MAP"), - MELON(0, "MELON_BLOCK"), - MELON_SEEDS(0, ""), - MELON_SLICE(0, "MELON"), - MELON_STEM(0, ""), - MILK_BUCKET(0, ""), - MINECART(0, ""), - MOJANG_BANNER_PATTERN(0, ""), + MAP("EMPTY_MAP"), + MELON("MELON_BLOCK"), + MELON_SEEDS, + MELON_SLICE("MELON"), + MELON_STEM, + MILK_BUCKET, + MINECART, + MOJANG_BANNER_PATTERN, MOOSHROOM_SPAWN_EGG(96, "MONSTER_EGG"), - MOSSY_COBBLESTONE(0, ""), + MOSSY_COBBLESTONE, MOSSY_COBBLESTONE_SLAB(3, "STEP"), - MOSSY_COBBLESTONE_STAIRS(0, ""), + MOSSY_COBBLESTONE_STAIRS, MOSSY_COBBLESTONE_WALL(1, "COBBLE_WALL", "COBBLESTONE_WALL"), MOSSY_STONE_BRICKS(1, "SMOOTH_BRICK"), MOSSY_STONE_BRICK_SLAB(4, "STEP"), - MOSSY_STONE_BRICK_STAIRS(0, "SMOOTH_STAIRS"), - MOSSY_STONE_BRICK_WALL(0, ""), - MOVING_PISTON(0, "PISTON_BASE", "PISTON_MOVING_PIECE"), + MOSSY_STONE_BRICK_STAIRS("SMOOTH_STAIRS"), + MOSSY_STONE_BRICK_WALL, + MOVING_PISTON("PISTON_BASE", "PISTON_MOVING_PIECE"), MULE_SPAWN_EGG(32, "MONSTER_EGG"), - MUSHROOM_STEM(0, "BROWN_MUSHROOM"), - MUSHROOM_STEW(0, "MUSHROOM_SOUP"), - MUSIC_DISC_11(0, "GOLD_RECORD"), - MUSIC_DISC_13(0, "GREEN_RECORD"), - MUSIC_DISC_BLOCKS(0, "RECORD_3"), - MUSIC_DISC_CAT(0, "RECORD_4"), - MUSIC_DISC_CHIRP(0, "RECORD_5"), - MUSIC_DISC_FAR(0, "RECORD_6"), - MUSIC_DISC_MALL(0, "RECORD_7"), - MUSIC_DISC_MELLOHI(0, "RECORD_8"), - MUSIC_DISC_STAL(0, "RECORD_9"), - MUSIC_DISC_STRAD(0, "RECORD_10"), - MUSIC_DISC_WAIT(0, "RECORD_11"), - MUSIC_DISC_WARD(0, "RECORD_12"), - MUTTON(0, ""), - MYCELIUM(0, "MYCEL"), - NAME_TAG(0, ""), - NAUTILUS_SHELL(0, "1.13"), - NETHERRACK(0, ""), - NETHER_BRICK(0, "NETHER_BRICK_ITEM"), - NETHER_BRICKS(0, "NETHER_BRICK"), - NETHER_BRICK_FENCE(0, "NETHER_FENCE"), + MUSHROOM_STEM("BROWN_MUSHROOM"), + MUSHROOM_STEW("MUSHROOM_SOUP"), + MUSIC_DISC_11("GOLD_RECORD"), + MUSIC_DISC_13("GREEN_RECORD"), + MUSIC_DISC_BLOCKS("RECORD_3"), + MUSIC_DISC_CAT("RECORD_4"), + MUSIC_DISC_CHIRP("RECORD_5"), + MUSIC_DISC_FAR("RECORD_6"), + MUSIC_DISC_MALL("RECORD_7"), + MUSIC_DISC_MELLOHI("RECORD_8"), + MUSIC_DISC_STAL("RECORD_9"), + MUSIC_DISC_STRAD("RECORD_10"), + MUSIC_DISC_WAIT("RECORD_11"), + MUSIC_DISC_WARD("RECORD_12"), + MUTTON, + MYCELIUM("MYCEL"), + NAME_TAG, + NAUTILUS_SHELL("1.13"), + NETHERRACK, + NETHER_BRICK("NETHER_BRICK_ITEM"), + NETHER_BRICKS("NETHER_BRICK"), + NETHER_BRICK_FENCE("NETHER_FENCE"), NETHER_BRICK_SLAB(4, "STEP"), - NETHER_BRICK_STAIRS(0, ""), - NETHER_BRICK_WALL(0, ""), - NETHER_PORTAL(0, "PORTAL"), - NETHER_QUARTZ_ORE(0, "QUARTZ_ORE"), - NETHER_STAR(0, ""), - NETHER_WART(0, "NETHER_STALK"), - NETHER_WART_BLOCK(0, "NETHER_WARTS"), - NOTE_BLOCK(0, ""), - OAK_BOAT(0, "BOAT"), - OAK_BUTTON(0, "WOOD_BUTTON"), - OAK_DOOR(0, "WOOD_DOOR", "WOODEN_DOOR"), - OAK_FENCE(0, "FENCE"), - OAK_FENCE_GATE(0, "FENCE_GATE"), - OAK_LEAVES(0, "LEAVES"), - OAK_LOG(0, "LOG"), - OAK_PLANKS(0, "WOOD"), - OAK_PRESSURE_PLATE(0, "WOOD_PLATE"), - OAK_SAPLING(0, "SAPLING"), - OAK_SIGN(0, "SIGN"), - OAK_SLAB(0, "WOOD_STEP", "WOODEN_SLAB", "WOOD_DOUBLE_STEP"), - OAK_STAIRS(0, "WOOD_STAIRS"), - OAK_TRAPDOOR(0, "TRAP_DOOR"), - OAK_WALL_SIGN(0, "SIGN_POST", "WALL_SIGN"), - OAK_WOOD(0, "LOG"), - OBSERVER(0, ""), - OBSIDIAN(0, ""), + NETHER_BRICK_STAIRS, + NETHER_BRICK_WALL, + NETHER_PORTAL("PORTAL"), + NETHER_QUARTZ_ORE("QUARTZ_ORE"), + NETHER_STAR, + /** + * Just like mentioned in https://minecraft.gamepedia.com/Nether_Wart + * Nether wart is also known as nether stalk in the code. + * NETHER_STALK is the planted state of nether warts. + */ + NETHER_WART("NETHER_WARTS", "NETHER_STALK"), + NETHER_WART_BLOCK, + NOTE_BLOCK, + OAK_BOAT("BOAT"), + OAK_BUTTON("WOOD_BUTTON"), + OAK_DOOR("WOOD_DOOR", "WOODEN_DOOR"), + OAK_FENCE("FENCE"), + OAK_FENCE_GATE("FENCE_GATE"), + OAK_LEAVES("LEAVES"), + OAK_LOG("LOG"), + OAK_PLANKS("WOOD"), + OAK_PRESSURE_PLATE("WOOD_PLATE"), + OAK_SAPLING("SAPLING"), + OAK_SIGN("SIGN"), + OAK_SLAB("WOOD_STEP", "WOODEN_SLAB", "WOOD_DOUBLE_STEP"), + OAK_STAIRS("WOOD_STAIRS"), + OAK_TRAPDOOR("TRAP_DOOR"), + OAK_WALL_SIGN("SIGN_POST", "WALL_SIGN"), + OAK_WOOD("LOG"), + OBSERVER, + OBSIDIAN, OCELOT_SPAWN_EGG(98, "MONSTER_EGG"), ORANGE_BANNER(14, "BANNER", "STANDING_BANNER"), ORANGE_BED(1, "BED", "BED_BLOCK"), @@ -670,7 +722,7 @@ public enum XMaterial { ORANGE_CONCRETE_POWDER(1, "CONCRETE_POWDER"), ORANGE_DYE(14, "INK_SACK"), ORANGE_GLAZED_TERRACOTTA(1, "1.12", "HARD_CLAY", "STAINED_CLAY", "ORANGE_TERRACOTTA"), - ORANGE_SHULKER_BOX(0, ""), + ORANGE_SHULKER_BOX, ORANGE_STAINED_GLASS(1, "STAINED_GLASS"), ORANGE_STAINED_GLASS_PANE(1, "STAINED_GLASS_PANE"), ORANGE_TERRACOTTA(1, "HARD_CLAY", "STAINED_CLAY"), @@ -678,17 +730,17 @@ public enum XMaterial { ORANGE_WALL_BANNER(14, "WALL_BANNER"), ORANGE_WOOL(1, "WOOL"), OXEYE_DAISY(8, "RED_ROSE"), - PACKED_ICE(0, ""), - PAINTING(0, ""), - PANDA_SPAWN_EGG(0, "1.14"), - PAPER(0, ""), + PACKED_ICE, + PAINTING, + PANDA_SPAWN_EGG("1.14"), + PAPER, PARROT_SPAWN_EGG(105, "MONSTER_EGG"), PEONY(5, "DOUBLE_PLANT"), - PETRIFIED_OAK_SLAB(0, "WOOD_STEP"), - PHANTOM_MEMBRANE(0, "1.13"), - PHANTOM_SPAWN_EGG(0, "1.13", "MONSTER_EGG"), + PETRIFIED_OAK_SLAB("WOOD_STEP"), + PHANTOM_MEMBRANE("1.13"), + PHANTOM_SPAWN_EGG("1.13", "MONSTER_EGG", ""), PIG_SPAWN_EGG(90, "MONSTER_EGG"), - PILLAGER_SPAWN_EGG(0, "1.14"), + PILLAGER_SPAWN_EGG("1.14"), PINK_BANNER(9, "BANNER", "STANDING_BANNER"), PINK_BED(6, "BED", "BED_BLOCK"), PINK_CARPET(6, "CARPET"), @@ -696,77 +748,77 @@ public enum XMaterial { PINK_CONCRETE_POWDER(6, "CONCRETE_POWDER"), PINK_DYE(9, "INK_SACK"), PINK_GLAZED_TERRACOTTA(6, "1.12", "HARD_CLAY", "STAINED_CLAY", "PINK_TERRACOTTA"), - PINK_SHULKER_BOX(0, ""), + PINK_SHULKER_BOX, PINK_STAINED_GLASS(6, "STAINED_GLASS"), PINK_STAINED_GLASS_PANE(6, "THIN_GLASS", "STAINED_GLASS_PANE"), PINK_TERRACOTTA(6, "HARD_CLAY", "STAINED_CLAY"), PINK_TULIP(7, "RED_ROSE"), PINK_WALL_BANNER(14, "WALL_BANNER"), PINK_WOOL(6, "WOOL"), - PISTON(0, "PISTON_BASE"), - PISTON_HEAD(0, "PISTON_EXTENSION"), + PISTON("PISTON_BASE"), + PISTON_HEAD("PISTON_EXTENSION"), PLAYER_HEAD(3, "SKULL", "SKULL_ITEM"), PLAYER_WALL_HEAD(3, "SKULL", "SKULL_ITEM"), PODZOL(2, "DIRT"), - POISONOUS_POTATO(0, ""), + POISONOUS_POTATO, POLAR_BEAR_SPAWN_EGG(102, "MONSTER_EGG"), - POLISHED_ANDESITE(6, "1.13"), - POLISHED_ANDESITE_SLAB(0, ""), - POLISHED_ANDESITE_STAIRS(0, ""), - POLISHED_DIORITE(4, "1.13"), - POLISHED_DIORITE_SLAB(0, ""), - POLISHED_DIORITE_STAIRS(0, ""), - POLISHED_GRANITE(2, "1.13"), - POLISHED_GRANITE_SLAB(0, ""), - POLISHED_GRANITE_STAIRS(0, ""), - POPPED_CHORUS_FRUIT(0, "CHORUS_FRUIT_POPPED"), - POPPY(0, "RED_ROSE"), - PORKCHOP(0, "PORK"), - POTATO(0, "POTATO_ITEM"), - POTATOES(0, "POTATO"), - POTION(0, ""), + POLISHED_ANDESITE(6, "STONE"), + POLISHED_ANDESITE_SLAB, + POLISHED_ANDESITE_STAIRS, + POLISHED_DIORITE(4, "STONE"), + POLISHED_DIORITE_SLAB, + POLISHED_DIORITE_STAIRS, + POLISHED_GRANITE(2, "STONE"), + POLISHED_GRANITE_SLAB, + POLISHED_GRANITE_STAIRS, + POPPED_CHORUS_FRUIT("CHORUS_FRUIT_POPPED"), + POPPY("RED_ROSE"), + PORKCHOP("PORK"), + POTATO("POTATO_ITEM"), + POTATOES("POTATO"), + POTION, POTTED_ACACIA_SAPLING(4, "SAPLING", "FLOWER_POT"), POTTED_ALLIUM(2, "RED_ROSE", "FLOWER_POT"), POTTED_AZURE_BLUET(3, "RED_ROSE", "FLOWER_POT"), - POTTED_BAMBOO(0, ""), + POTTED_BAMBOO, POTTED_BIRCH_SAPLING(2, "SAPLING", "FLOWER_POT"), POTTED_BLUE_ORCHID(1, "RED_ROSE", "FLOWER_POT"), - POTTED_BROWN_MUSHROOM(0, "FLOWER_POT"), - POTTED_CACTUS(0, "FLOWER_POT"), - POTTED_CORNFLOWER(0, ""), - POTTED_DANDELION(0, "YELLOW_FLOWER", "FLOWER_POT"), + POTTED_BROWN_MUSHROOM("FLOWER_POT"), + POTTED_CACTUS("FLOWER_POT"), + POTTED_CORNFLOWER, + POTTED_DANDELION("YELLOW_FLOWER", "FLOWER_POT"), POTTED_DARK_OAK_SAPLING(5, "SAPLING", "FLOWER_POT"), - POTTED_DEAD_BUSH(0, "FLOWER_POT"), + POTTED_DEAD_BUSH("FLOWER_POT"), POTTED_FERN(2, "LONG_GRASS", "FLOWER_POT"), POTTED_JUNGLE_SAPLING(3, "SAPLING", "FLOWER_POT"), - POTTED_LILY_OF_THE_VALLEY(0, ""), - POTTED_OAK_SAPLING(0, "SAPLING", "FLOWER_POT"), + POTTED_LILY_OF_THE_VALLEY, + POTTED_OAK_SAPLING("SAPLING", "FLOWER_POT"), POTTED_ORANGE_TULIP(5, "RED_ROSE", "FLOWER_POT"), POTTED_OXEYE_DAISY(8, "RED_ROSE", "FLOWER_POT"), POTTED_PINK_TULIP(7, "RED_ROSE", "FLOWER_POT"), - POTTED_POPPY(0, "RED_ROSE", "FLOWER_POT"), - POTTED_RED_MUSHROOM(0, "FLOWER_POT"), + POTTED_POPPY("RED_ROSE", "FLOWER_POT"), + POTTED_RED_MUSHROOM("FLOWER_POT"), POTTED_RED_TULIP(4, "RED_ROSE", "FLOWER_POT"), POTTED_SPRUCE_SAPLING(1, "SAPLING", "FLOWER_POT"), POTTED_WHITE_TULIP(6, "RED_ROSE", "FLOWER_POT"), - POTTED_WITHER_ROSE(0, ""), - POWERED_RAIL(0, ""), - PRISMARINE(0, ""), + POTTED_WITHER_ROSE, + POWERED_RAIL, + PRISMARINE, PRISMARINE_BRICKS(2, "PRISMARINE"), PRISMARINE_BRICK_SLAB(4, "STEP"), - PRISMARINE_BRICK_STAIRS(0, "1.13"), - PRISMARINE_CRYSTALS(0, ""), - PRISMARINE_SHARD(0, ""), - PRISMARINE_SLAB(0, "1.13"), - PRISMARINE_STAIRS(0, "1.13"), - PRISMARINE_WALL(0, ""), + PRISMARINE_BRICK_STAIRS("1.13"), + PRISMARINE_CRYSTALS, + PRISMARINE_SHARD, + PRISMARINE_SLAB("1.13"), + PRISMARINE_STAIRS("1.13"), + PRISMARINE_WALL, PUFFERFISH(3, "RAW_FISH"), - PUFFERFISH_BUCKET(0, "1.13", "BUCKET", "WATER_BUCKET"), - PUFFERFISH_SPAWN_EGG(0, "1.13", "MONSTER_EGG"), - PUMPKIN(0, ""), - PUMPKIN_PIE(0, ""), - PUMPKIN_SEEDS(0, ""), - PUMPKIN_STEM(0, ""), + PUFFERFISH_BUCKET("1.13", "BUCKET", "WATER_BUCKET", ""), + PUFFERFISH_SPAWN_EGG("1.13", "MONSTER_EGG", ""), + PUMPKIN, + PUMPKIN_PIE, + PUMPKIN_SEEDS, + PUMPKIN_STEM, PURPLE_BANNER(5, "BANNER", "STANDING_BANNER"), PURPLE_BED(10, "BED", "BED_BLOCK"), PURPLE_CARPET(10, "CARPET"), @@ -774,35 +826,35 @@ public enum XMaterial { PURPLE_CONCRETE_POWDER(10, "CONCRETE_POWDER"), PURPLE_DYE(5, "INK_SACK"), PURPLE_GLAZED_TERRACOTTA(10, "1.12", "HARD_CLAY", "STAINED_CLAY", "PURPLE_TERRACOTTA"), - PURPLE_SHULKER_BOX(0, ""), + PURPLE_SHULKER_BOX, PURPLE_STAINED_GLASS(10, "STAINED_GLASS"), PURPLE_STAINED_GLASS_PANE(10, "THIN_GLASS", "STAINED_GLASS_PANE"), PURPLE_TERRACOTTA(10, "HARD_CLAY", "STAINED_CLAY"), PURPLE_WALL_BANNER(5, "WALL_BANNER"), PURPLE_WOOL(10, "WOOL"), - PURPUR_BLOCK(0, ""), - PURPUR_PILLAR(0, ""), - PURPUR_SLAB(0, "PURPUR_DOUBLE_SLAB"), - PURPUR_STAIRS(0, ""), - QUARTZ(0, ""), - QUARTZ_BLOCK(0, ""), + PURPUR_BLOCK, + PURPUR_PILLAR, + PURPUR_SLAB("PURPUR_DOUBLE_SLAB"), + PURPUR_STAIRS, + QUARTZ, + QUARTZ_BLOCK, QUARTZ_PILLAR(2, "QUARTZ_BLOCK"), QUARTZ_SLAB(7, "STEP"), - QUARTZ_STAIRS(0, ""), - RABBIT(0, ""), - RABBIT_FOOT(0, ""), - RABBIT_HIDE(0, ""), + QUARTZ_STAIRS, + RABBIT, + RABBIT_FOOT, + RABBIT_HIDE, RABBIT_SPAWN_EGG(101, "MONSTER_EGG"), - RABBIT_STEW(0, ""), - RAIL(0, "RAILS"), - RAVAGER_SPAWN_EGG(0, "1.14"), - REDSTONE(0, ""), - REDSTONE_BLOCK(0, ""), - REDSTONE_LAMP(0, "REDSTONE_LAMP_OFF", "REDSTONE_LAMP_ON"), - REDSTONE_ORE(0, "GLOWING_REDSTONE_ORE"), - REDSTONE_TORCH(0, "REDSTONE_TORCH_ON", "REDSTONE_TORCH_OFF"), + RABBIT_STEW, + RAIL("RAILS"), + RAVAGER_SPAWN_EGG("1.14"), + REDSTONE, + REDSTONE_BLOCK, + REDSTONE_LAMP("REDSTONE_LAMP_OFF", "REDSTONE_LAMP_ON"), + REDSTONE_ORE("GLOWING_REDSTONE_ORE"), + REDSTONE_TORCH("REDSTONE_TORCH_ON", "REDSTONE_TORCH_OFF"), REDSTONE_WALL_TORCH(1, "REDSTONE_TORCH_ON", "REDSTONE_TORCH_OFF"), - REDSTONE_WIRE(0, ""), + REDSTONE_WIRE, RED_BANNER(1, "BANNER", "STANDING_BANNER"), RED_BED(14, "BED", "BED_BLOCK"), RED_CARPET(14, "CARPET"), @@ -810,198 +862,222 @@ public enum XMaterial { RED_CONCRETE_POWDER(14, "CONCRETE_POWDER"), RED_DYE(1, "ROSE_RED"), RED_GLAZED_TERRACOTTA(14, "1.12", "HARD_CLAY", "STAINED_CLAY", "RED_TERRACOTTA"), - RED_MUSHROOM(0, ""), - RED_MUSHROOM_BLOCK(0, "RED_MUSHROOM", "HUGE_MUSHROOM_2"), - RED_NETHER_BRICKS(0, "RED_NETHER_BRICK"), + RED_MUSHROOM, + RED_MUSHROOM_BLOCK("RED_MUSHROOM", "HUGE_MUSHROOM_2"), + RED_NETHER_BRICKS("RED_NETHER_BRICK"), RED_NETHER_BRICK_SLAB(4, "STEP"), - RED_NETHER_BRICK_STAIRS(0, ""), - RED_NETHER_BRICK_WALL(0, ""), + RED_NETHER_BRICK_STAIRS, + RED_NETHER_BRICK_WALL, RED_SAND(1, "SAND"), - RED_SANDSTONE(0, ""), - RED_SANDSTONE_SLAB(0, "STONE_SLAB2", "DOUBLE_STONE_SLAB2"), - RED_SANDSTONE_STAIRS(0, ""), - RED_SANDSTONE_WALL(0, ""), - RED_SHULKER_BOX(0, ""), + RED_SANDSTONE, + RED_SANDSTONE_SLAB("STONE_SLAB2", "DOUBLE_STONE_SLAB2"), + RED_SANDSTONE_STAIRS, + RED_SANDSTONE_WALL, + RED_SHULKER_BOX, RED_STAINED_GLASS(14, "STAINED_GLASS"), RED_STAINED_GLASS_PANE(14, "THIN_GLASS", "STAINED_GLASS_PANE"), RED_TERRACOTTA(14, "HARD_CLAY", "STAINED_CLAY"), RED_TULIP(4, "RED_ROSE"), RED_WALL_BANNER(1, "WALL_BANNER"), RED_WOOL(14, "WOOL"), - REPEATER(0, "DIODE", "DIODE_BLOCK_ON", "DIODE_BLOCK_OFF"), - REPEATING_COMMAND_BLOCK(0, "COMMAND", "COMMAND_REPEATING"), + REPEATER("DIODE", "DIODE_BLOCK_ON", "DIODE_BLOCK_OFF"), + REPEATING_COMMAND_BLOCK("COMMAND", "COMMAND_REPEATING"), ROSE_BUSH(4, "DOUBLE_PLANT"), - ROTTEN_FLESH(0, ""), - SADDLE(0, ""), + ROTTEN_FLESH, + SADDLE, SALMON(1, "RAW_FISH"), - SALMON_BUCKET(0, "1.13", "BUCKET", "WATER_BUCKET"), - SALMON_SPAWN_EGG(0, "1.13", "MONSTER_EGG"), - SAND(0, ""), - SANDSTONE(0, ""), + SALMON_BUCKET("1.13", "BUCKET", "WATER_BUCKET", ""), + SALMON_SPAWN_EGG("1.13", "MONSTER_EGG", ""), + SAND, + SANDSTONE, SANDSTONE_SLAB(1, "STEP", "STONE_SLAB", "DOUBLE_STEP"), - SANDSTONE_STAIRS(0, ""), - SANDSTONE_WALL(0, ""), - SCAFFOLDING(0, "1.14", "SLIME_BLOCK"), - SCUTE(0, "1.13"), - SEAGRASS(0, "1.13"), - SEA_LANTERN(0, ""), - SEA_PICKLE(0, "1.13"), - SHEARS(0, ""), + SANDSTONE_STAIRS, + SANDSTONE_WALL, + SCAFFOLDING("1.14", "SLIME_BLOCK", ""), + SCUTE("1.13"), + SEAGRASS("1.13", "GRASS", ""), + SEA_LANTERN, + SEA_PICKLE("1.13"), + SHEARS, SHEEP_SPAWN_EGG(91, "MONSTER_EGG"), - SHIELD(0, ""), - SHULKER_BOX(0, "PURPLE_SHULKER_BOX"), - SHULKER_SHELL(0, ""), + SHIELD, + SHULKER_BOX("PURPLE_SHULKER_BOX"), + SHULKER_SHELL, SHULKER_SPAWN_EGG(69, "MONSTER_EGG"), SILVERFISH_SPAWN_EGG(60, "MONSTER_EGG"), SKELETON_HORSE_SPAWN_EGG(28, "MONSTER_EGG"), - SKELETON_SKULL(0, "SKULL", "SKULL_ITEM"), + SKELETON_SKULL("SKULL", "SKULL_ITEM"), SKELETON_SPAWN_EGG(51, "MONSTER_EGG"), - SKELETON_WALL_SKULL(0, "SKULL", "SKULL_ITEM"), - SKULL_BANNER_PATTERN(0, ""), - SLIME_BALL(0, ""), - SLIME_BLOCK(0, ""), + SKELETON_WALL_SKULL("SKULL", "SKULL_ITEM"), + SKULL_BANNER_PATTERN, + SLIME_BALL, + SLIME_BLOCK, SLIME_SPAWN_EGG(55, "MONSTER_EGG"), - SMITHING_TABLE(0, ""), - SMOKER(0, "1.14", "FURNACE"), - SMOOTH_QUARTZ(0, "1.13"), + SMITHING_TABLE, + SMOKER("1.14", "FURNACE", ""), + SMOOTH_QUARTZ("1.13", "QUARTZ", ""), SMOOTH_QUARTZ_SLAB(7, "STEP"), - SMOOTH_QUARTZ_STAIRS(0, ""), + SMOOTH_QUARTZ_STAIRS, SMOOTH_RED_SANDSTONE(2, "RED_SANDSTONE"), - SMOOTH_RED_SANDSTONE_SLAB(0, "STONE_SLAB2"), - SMOOTH_RED_SANDSTONE_STAIRS(0, ""), + SMOOTH_RED_SANDSTONE_SLAB("STONE_SLAB2"), + SMOOTH_RED_SANDSTONE_STAIRS, SMOOTH_SANDSTONE(2, "SANDSTONE"), - SMOOTH_SANDSTONE_SLAB(0, "STEP"), - SMOOTH_SANDSTONE_STAIRS(0, ""), - SMOOTH_STONE(0, "STEP"), - SMOOTH_STONE_SLAB(0, "STEP"), - SNOW(0, ""), - SNOWBALL(0, "SNOW_BALL"), - SNOW_BLOCK(0, ""), - SOUL_SAND(0, ""), - SPAWNER(0, "MOB_SPAWNER"), - SPECTRAL_ARROW(0, ""), - SPIDER_EYE(0, ""), + SMOOTH_SANDSTONE_SLAB("STEP"), + SMOOTH_SANDSTONE_STAIRS, + SMOOTH_STONE("STEP"), + SMOOTH_STONE_SLAB("STEP"), + SNOW, + SNOWBALL("SNOW_BALL"), + SNOW_BLOCK, + SOUL_SAND, + SPAWNER("MOB_SPAWNER"), + SPECTRAL_ARROW("1.9", "ARROW", ""), + SPIDER_EYE, SPIDER_SPAWN_EGG(52, "MONSTER_EGG"), - SPLASH_POTION(0, ""), - SPONGE(0, ""), - SPRUCE_BOAT(0, "BOAT_SPRUCE"), - SPRUCE_BUTTON(0, "WOOD_BUTTON"), - SPRUCE_DOOR(0, "SPRUCE_DOOR_ITEM"), - SPRUCE_FENCE(0, ""), - SPRUCE_FENCE_GATE(0, ""), + SPLASH_POTION, + SPONGE, + SPRUCE_BOAT("BOAT_SPRUCE"), + SPRUCE_BUTTON("WOOD_BUTTON"), + SPRUCE_DOOR("SPRUCE_DOOR_ITEM"), + SPRUCE_FENCE, + SPRUCE_FENCE_GATE, SPRUCE_LEAVES(1, "LEAVES"), SPRUCE_LOG(1, "LOG"), SPRUCE_PLANKS(1, "WOOD"), - SPRUCE_PRESSURE_PLATE(0, "WOOD_PLATE"), + SPRUCE_PRESSURE_PLATE("WOOD_PLATE"), SPRUCE_SAPLING(1, "SAPLING"), - SPRUCE_SIGN(0, "SIGN"), + SPRUCE_SIGN("SIGN"), SPRUCE_SLAB(1, "WOOD_STEP", "WOODEN_SLAB", "WOOD_DOUBLE_STEP"), - SPRUCE_STAIRS(0, "SPRUCE_WOOD_STAIRS"), - SPRUCE_TRAPDOOR(0, "TRAP_DOOR"), - SPRUCE_WALL_SIGN(0, "SIGN_POST", "WALL_SIGN"), + SPRUCE_STAIRS("SPRUCE_WOOD_STAIRS"), + SPRUCE_TRAPDOOR("TRAP_DOOR"), + SPRUCE_WALL_SIGN("SIGN_POST", "WALL_SIGN"), SPRUCE_WOOD(1, "LOG"), SQUID_SPAWN_EGG(94, "MONSTER_EGG"), - STICK(0, ""), - STICKY_PISTON(0, "PISTON_BASE", "PISTON_STICKY_BASE"), - STONE(0, ""), - STONECUTTER(0, "1.14"), - STONE_AXE(0, ""), - STONE_BRICKS(0, "SMOOTH_BRICK"), + STICK, + STICKY_PISTON("PISTON_BASE", "PISTON_STICKY_BASE"), + STONE, + STONECUTTER("1.14"), + STONE_AXE, + STONE_BRICKS("SMOOTH_BRICK"), STONE_BRICK_SLAB(4, "STEP", "STONE_SLAB", "DOUBLE_STEP"), - STONE_BRICK_STAIRS(0, "SMOOTH_STAIRS"), - STONE_BRICK_WALL(0, ""), - STONE_BUTTON(0, ""), - STONE_HOE(0, ""), - STONE_PICKAXE(0, ""), - STONE_PRESSURE_PLATE(0, "STONE_PLATE"), - STONE_SHOVEL(0, "STONE_SPADE"), - STONE_SLAB(0, "STEP", "DOUBLE_STEP"), - STONE_STAIRS(0, ""), - STONE_SWORD(0, ""), + STONE_BRICK_STAIRS("SMOOTH_STAIRS"), + STONE_BRICK_WALL, + STONE_BUTTON, + STONE_HOE, + STONE_PICKAXE, + STONE_PRESSURE_PLATE("STONE_PLATE"), + STONE_SHOVEL("STONE_SPADE"), + STONE_SLAB("STEP", "DOUBLE_STEP"), + STONE_STAIRS, + STONE_SWORD, STRAY_SPAWN_EGG(6, "MONSTER_EGG"), - STRING(0, ""), - STRIPPED_ACACIA_LOG(0, "LOG_2"), - STRIPPED_ACACIA_WOOD(0, "LOG_2"), + STRING, + STRIPPED_ACACIA_LOG("LOG_2"), + STRIPPED_ACACIA_WOOD("LOG_2"), STRIPPED_BIRCH_LOG(2, "LOG"), STRIPPED_BIRCH_WOOD(2, "LOG"), - STRIPPED_DARK_OAK_LOG(0, "LOG"), - STRIPPED_DARK_OAK_WOOD(0, "LOG"), + STRIPPED_DARK_OAK_LOG("LOG"), + STRIPPED_DARK_OAK_WOOD("LOG"), STRIPPED_JUNGLE_LOG(3, "LOG"), STRIPPED_JUNGLE_WOOD(3, "LOG"), - STRIPPED_OAK_LOG(0, "LOG"), - STRIPPED_OAK_WOOD(0, "LOG"), + STRIPPED_OAK_LOG("LOG"), + STRIPPED_OAK_WOOD("LOG"), STRIPPED_SPRUCE_LOG(1, "LOG"), STRIPPED_SPRUCE_WOOD(1, "LOG"), - STRUCTURE_BLOCK(0, ""), - STRUCTURE_VOID(0, "1.10", "BARRIER/1.9"), // Originally developers used barrier blocks for its purpose. - SUGAR(0, ""), - SUGAR_CANE(0, "SUGAR_CANE_BLOCK"), - SUNFLOWER(0, "DOUBLE_PLANT"), - SUSPICIOUS_STEW(0, "1.14", "MUSHROOM_STEW"), - SWEET_BERRIES(0, "1.14"), - SWEET_BERRY_BUSH(0, "1.14", "GRASS"), + STRUCTURE_BLOCK, + /** + * Originally developers used barrier blocks for its purpose. + * So technically this isn't really considered as a suggested material. + */ + STRUCTURE_VOID("1.10", "", "BARRIER"), + SUGAR, + /** + * Sugar Cane is a known material in pre-1.13 + * Use XBlock when comparing block types. + */ + SUGAR_CANE("SUGAR_CANE_BLOCK"), + SUNFLOWER("DOUBLE_PLANT"), + SUSPICIOUS_STEW("1.14", "MUSHROOM_STEW", ""), + SWEET_BERRIES("1.14"), + SWEET_BERRY_BUSH("1.14", "GRASS", ""), TALL_GRASS(2, "DOUBLE_PLANT"), - TALL_SEAGRASS(0, "1.13"), - TERRACOTTA(0, "HARD_CLAY"), - TIPPED_ARROW(0, ""), - TNT(0, ""), - TNT_MINECART(0, "EXPLOSIVE_MINECART"), - TORCH(0, ""), - TOTEM_OF_UNDYING(0, "TOTEM"), - TRADER_LLAMA_SPAWN_EGG(103, "1.14", "MONSTER_EGG"), - TRAPPED_CHEST(0, ""), - TRIDENT(0, "1.13"), - TRIPWIRE(0, ""), - TRIPWIRE_HOOK(0, ""), + TALL_SEAGRASS(2, "1.13", "TALL_GRASS", ""), + TERRACOTTA("HARD_CLAY"), + TIPPED_ARROW("1.9", "ARROW", ""), + TNT, + TNT_MINECART("EXPLOSIVE_MINECART"), + TORCH, + TOTEM_OF_UNDYING("TOTEM"), + TRADER_LLAMA_SPAWN_EGG(103, "1.14", "MONSTER_EGG", ""), + TRAPPED_CHEST, + TRIDENT("1.13"), + TRIPWIRE, + TRIPWIRE_HOOK, TROPICAL_FISH(2, "RAW_FISH"), - TROPICAL_FISH_BUCKET(0, "1.13", "BUCKET", "WATER_BUCKET"), - TROPICAL_FISH_SPAWN_EGG(0, "1.13", "MONSTER_EGG"), - TUBE_CORAL(0, "1.13"), - TUBE_CORAL_BLOCK(0, "1.13"), - TUBE_CORAL_FAN(0, "1.13"), - TUBE_CORAL_WALL_FAN(0, ""), - TURTLE_EGG(0, "1.13", "EGG"), - TURTLE_HELMET(0, "1.13"), - TURTLE_SPAWN_EGG(0, "1.13", "MONSTER_EGG"), + TROPICAL_FISH_BUCKET("1.13", "BUCKET", "WATER_BUCKET"), + TROPICAL_FISH_SPAWN_EGG("1.13", "MONSTER_EGG"), + TUBE_CORAL("1.13"), + TUBE_CORAL_BLOCK("1.13"), + TUBE_CORAL_FAN("1.13"), + TUBE_CORAL_WALL_FAN, + TURTLE_EGG("1.13", "EGG", ""), + TURTLE_HELMET("1.13", "IRON_HELMET", ""), + TURTLE_SPAWN_EGG("1.13", "CHICKEN_SPAWN_EGG", ""), VEX_SPAWN_EGG(35, "MONSTER_EGG"), VILLAGER_SPAWN_EGG(120, "MONSTER_EGG"), VINDICATOR_SPAWN_EGG(36, "MONSTER_EGG"), - VINE(0, ""), - VOID_AIR(0, "AIR"), - WALL_TORCH(0, "TORCH"), - WANDERING_TRADER_SPAWN_EGG(0, "1.14", "VILLAGER_SPAWN_EGG"), - WATER(0, "STATIONARY_WATER"), - WATER_BUCKET(0, ""), + VINE, + /** + * 1.13 tag is not added because it's the same thing as {@link #AIR} + * + * @see #CAVE_AIR + */ + VOID_AIR("AIR"), + WALL_TORCH("TORCH"), + WANDERING_TRADER_SPAWN_EGG("1.14", "VILLAGER_SPAWN_EGG", ""), + /** + * This is used for blocks only. + * In 1.13- WATER will turn into STATIONARY_WATER after it finished spreading. + * After 1.13+ this uses + * https://hub.spigotmc.org/javadocs/spigot/org/bukkit/block/data/Levelled.html water flowing system. + * Use XBlock for this instead. + */ + WATER("STATIONARY_WATER"), + WATER_BUCKET, WET_SPONGE(1, "SPONGE"), - WHEAT(0, "CROPS"), - WHEAT_SEEDS(0, "SEEDS"), + /** + * Wheat is a known material in pre-1.13 + * Use XBlock when comparing block types. + */ + WHEAT("CROPS"), + WHEAT_SEEDS("SEEDS"), WHITE_BANNER(15, "BANNER", "STANDING_BANNER"), - WHITE_BED(0, "BED", "BED_BLOCK"), - WHITE_CARPET(0, "CARPET"), - WHITE_CONCRETE(0, "CONCRETE"), - WHITE_CONCRETE_POWDER(0, "CONCRETE_POWDER"), + WHITE_BED("BED", "BED_BLOCK"), + WHITE_CARPET("CARPET"), + WHITE_CONCRETE("CONCRETE"), + WHITE_CONCRETE_POWDER("CONCRETE_POWDER"), WHITE_DYE(15, "1.14", "INK_SACK", "BONE_MEAL"), - WHITE_GLAZED_TERRACOTTA(0, "1.12", "HARD_CLAY", "STAINED_CLAY", "WHITE_TERRACOTTA"), - WHITE_SHULKER_BOX(0, ""), - WHITE_STAINED_GLASS(0, "STAINED_GLASS"), - WHITE_STAINED_GLASS_PANE(0, "THIN_GLASS", "STAINED_GLASS_PANE"), - WHITE_TERRACOTTA(0, "HARD_CLAY", "TERRACOTTA"), + WHITE_GLAZED_TERRACOTTA("1.12", "HARD_CLAY", "STAINED_CLAY", "WHITE_TERRACOTTA"), + WHITE_SHULKER_BOX, + WHITE_STAINED_GLASS("STAINED_GLASS"), + WHITE_STAINED_GLASS_PANE("THIN_GLASS", "STAINED_GLASS_PANE"), + WHITE_TERRACOTTA("HARD_CLAY", "TERRACOTTA"), WHITE_TULIP(6, "RED_ROSE"), WHITE_WALL_BANNER(15, "WALL_BANNER"), - WHITE_WOOL(0, "WOOL"), + WHITE_WOOL("WOOL"), WITCH_SPAWN_EGG(66, "MONSTER_EGG"), - WITHER_ROSE(0, "1.14", "BLACK_DYE"), + WITHER_ROSE("1.14", "BLACK_DYE", ""), WITHER_SKELETON_SKULL(1, "SKULL", "SKULL_ITEM"), WITHER_SKELETON_SPAWN_EGG(5, "MONSTER_EGG"), WITHER_SKELETON_WALL_SKULL(1, "SKULL", "SKULL_ITEM"), WOLF_SPAWN_EGG(95, "MONSTER_EGG"), - WOODEN_AXE(0, "WOOD_AXE"), - WOODEN_HOE(0, "WOOD_HOE"), - WOODEN_PICKAXE(0, "WOOD_PICKAXE"), - WOODEN_SHOVEL(0, "WOOD_SPADE"), - WOODEN_SWORD(0, "WOOD_SWORD"), - WRITABLE_BOOK(0, "BOOK_AND_QUILL"), - WRITTEN_BOOK(0, ""), + WOODEN_AXE("WOOD_AXE"), + WOODEN_HOE("WOOD_HOE"), + WOODEN_PICKAXE("WOOD_PICKAXE"), + WOODEN_SHOVEL("WOOD_SPADE"), + WOODEN_SWORD("WOOD_SWORD"), + WRITABLE_BOOK("BOOK_AND_QUILL"), + WRITTEN_BOOK, YELLOW_BANNER(11, "BANNER", "STANDING_BANNER"), YELLOW_BED(4, "BED", "BED_BLOCK"), YELLOW_CARPET(4, "CARPET"), @@ -1009,7 +1085,7 @@ public enum XMaterial { YELLOW_CONCRETE_POWDER(4, "CONCRETE_POWDER"), YELLOW_DYE(11, "INK_SACK", "DANDELION_YELLOW"), YELLOW_GLAZED_TERRACOTTA(4, "1.12", "HARD_CLAY", "STAINED_CLAY", "YELLOW_TERRACOTTA"), - YELLOW_SHULKER_BOX(0, ""), + YELLOW_SHULKER_BOX, YELLOW_STAINED_GLASS(4, "STAINED_GLASS"), YELLOW_STAINED_GLASS_PANE(4, "THIN_GLASS", "STAINED_GLASS_PANE"), YELLOW_TERRACOTTA(4, "HARD_CLAY", "STAINED_CLAY"), @@ -1024,39 +1100,118 @@ public enum XMaterial { /** - * A list of material names that can be damaged. - * Some names are not complete as this list needs to be - * checked with {@link String#contains}. + * An immutable cached set of {@link XMaterial#values()} to avoid allocating memory for + * calling the method every time. + * + * @since 2.0.0 */ - public static final String[] DAMAGEABLE = { + public static final EnumSet VALUES = EnumSet.allOf(XMaterial.class); + /** + * A set of material names that can be damaged. + *

+ * Most of the names are not complete as this list is intended to be + * checked with {@link String#contains} for memory usage. + * + * @since 1.0.0 + */ + private static final ImmutableSet DAMAGEABLE = ImmutableSet.of( "HELMET", "CHESTPLATE", "LEGGINGS", "BOOTS", "SWORD", "AXE", "PICKAXE", "SHOVEL", "HOE", "ELYTRA", "TRIDENT", "HORSE_ARMOR", "BARDING", "SHEARS", "FLINT_AND_STEEL", "BOW", "FISHING_ROD", - "CARROT_ON_A_STICK", "CARROT_STICK" - }; + "CARROT_ON_A_STICK", "CARROT_STICK", "SPADE", "SHIELD" + ); /** - * A list of duplicated items in 1.13 and 1.12 with different purpose. + * XMaterial Paradox (Duplication Check) + *

+ * A map of duplicated material names in 1.13 and 1.12 that will conflict with the legacy names. * Values are the new material names. - * Duplicates are only checked by keys not values. - * Checked with {@link String#equals} + *
+ * Duplicates are normally only checked by keys, not values. + * + * @since 3.0.0 + */ + @SuppressWarnings("UnstableApiUsage") + private static final ImmutableMap DUPLICATED = Maps.immutableEnumMap(ImmutableMap.builder() + .put(MELON, MELON_SLICE) + .put(CARROT, CARROTS) + .put(POTATO, POTATOES) + .put(BEETROOT, BEETROOTS) + .put(BROWN_MUSHROOM, BROWN_MUSHROOM_BLOCK) + .put(BRICK, BRICKS) + .put(RED_MUSHROOM, RED_MUSHROOM_BLOCK) + .put(MAP, FILLED_MAP) + .put(NETHER_BRICK, NETHER_BRICKS) + .build() + ); + /* + * A set of all the legacy names without duplicates. + *

+ * It'll help to free up a lot of memory if it's not used. + * Add it back if you need it. + * + * @see #containsLegacy(String) + * @since 2.2.0 + * + private static final ImmutableSet LEGACY_VALUES = VALUES.stream().map(XMaterial::getLegacy) + .flatMap(Arrays::stream) + .filter(m -> m.charAt(1) == '.') + .collect(Collectors.collectingAndThen(Collectors.toSet(), ImmutableSet::copyOf)); + */ + + /** + * Guava (Google Core Libraries for Java)'s cache for performance and timed caches. + * For strings that match a certain XMaterial. Mostly cached for configs. + * + * @since 1.0.0 + */ + private static final Cache NAME_CACHE = CacheBuilder.newBuilder() + .softValues() + .expireAfterAccess(15, TimeUnit.MINUTES) + .build(); + /** + * Guava (Google Core Libraries for Java)'s cache for performance and timed caches. + * For XMaterials that are already parsed once. + * + * @since 3.0.0 + */ + private static final Cache> PARSED_CACHE = CacheBuilder.newBuilder() + .softValues() + .expireAfterAccess(10, TimeUnit.MINUTES) + .concurrencyLevel(Runtime.getRuntime().availableProcessors()) + .build(); + + /** + * Pre-compiled RegEx pattern. + * Include both replacements to avoid recreating string multiple times with multiple RegEx checks. + * + * @since 3.0.0 + */ + private static final Pattern FORMAT_PATTERN = Pattern.compile("\\W+"); + /** + * The current version of the server in the a form of a major version. + * + * @since 1.0.0 + */ + private static final int VERSION = Integer.parseInt(getMajorVersion(Bukkit.getVersion()).substring(2)); + /** + * Cached result if the server version is after the v1.13 flattening update. + * Please don't mistake this with flat-chested people. It happened. + * + * @since 3.0.0 + */ + private static final boolean ISFLAT = supports(13); + /** + * The data value of this material https://minecraft.gamepedia.com/Java_Edition_data_values/Pre-flattening + * + * @see #getData() */ - public static final HashMap DUPLICATED = new HashMap() {{ - put(XMaterial.MELON, XMaterial.MELON_SLICE); - put(XMaterial.CARROT, XMaterial.CARROTS); - put(XMaterial.POTATO, XMaterial.POTATOES); - put(XMaterial.BEETROOT, XMaterial.BEETROOTS); - put(XMaterial.BROWN_MUSHROOM, XMaterial.BROWN_MUSHROOM_BLOCK); - put(XMaterial.BRICK, XMaterial.BRICKS); - put(XMaterial.RED_MUSHROOM, XMaterial.RED_MUSHROOM_BLOCK); - put(XMaterial.MAP, XMaterial.FILLED_MAP); - put(XMaterial.NETHER_BRICK, XMaterial.NETHER_BRICKS); - }}; - public static final XMaterial[] VALUES = XMaterial.values(); - private static final HashMap CACHED_SEARCH = new HashMap<>(); - private static MinecraftVersion version; - private static Boolean isNewVersion; private final byte data; + /** + * A list of material names that was being used for older verions. + * + * @see #getLegacy() + */ private final String[] legacy; XMaterial(int data, String... legacy) { @@ -1064,250 +1219,390 @@ public enum XMaterial { this.legacy = legacy; } + XMaterial() { + this(0); + } + + XMaterial(String... legacy) { + this(0, legacy); + } + /** - * Checks if the version is 1.13 (Aquatic Update) or higher. + * Checks if the version is 1.13 Aquatic Update or higher. + * An invocation of this method yields the cached result from the expression: + *

+ *

+ * {@link #supports(int 13)}} + *
* * @return true if 1.13 or higher. + * @see #getVersion() + * @see #supports(int) + * @since 1.0.0 */ public static boolean isNewVersion() { - if (isNewVersion != null) return isNewVersion; - return isNewVersion = isVersionOrHigher(MinecraftVersion.VERSION_1_13); + return ISFLAT; } + /** + * This is just an extra method that method that can be used for many cases. + * It can be used in {@link org.bukkit.event.player.PlayerInteractEvent} + * or when accessing {@link org.bukkit.entity.Player#getMainHand()}, + * or other compatibility related methods. + *

+ * An invocation of this method yields exactly the same result as the expression: + *

+ *

+ * {@link #getVersion()} == 1.8 + *
+ * + * @since 2.0.0 + */ public static boolean isOneEight() { - return getVersion() == MinecraftVersion.VERSION_1_8; + return !supports(9); } /** - * Uses newly added materials to minecraft to detect the server version. + * The current version of the server. * - * @return the current server version. + * @return the current server version or 0.0 if unknown. + * @see #isNewVersion() + * @since 2.0.0 */ - public static MinecraftVersion getVersion() { - if (version != null) return version; - return version = valueOfVersion(Bukkit.getVersion()); + public static double getVersion() { + return VERSION; } /** - * When using newer versions of Minecraft {@link #isNewVersion()} this helps - * to find the old material name with its data using a cached search for optimization. + * When using newer versions of Minecraft ({@link #isNewVersion()}), helps + * to find the old material name with its data value using a cached search for optimization. * - * @see #matchXMaterial(String, byte) + * @see #matchDefinedXMaterial(String, byte) + * @since 1.0.0 */ - private static XMaterial requestOldXMaterial(String name, byte data) { - XMaterial cached = CACHED_SEARCH.get(name + "," + data); + @Nullable + private static XMaterial requestOldXMaterial(@Nonnull String name, byte data) { + String holder = name + data; + XMaterial material = NAME_CACHE.getIfPresent(holder); + if (material != null) return material; - if (cached != null) return cached; - Optional search = data == -1 ? Arrays.stream(XMaterial.VALUES).filter(mat -> mat.matchAnyLegacy(name)).findFirst() - : Arrays.stream(XMaterial.VALUES).filter(mat -> mat.matchAnyLegacy(name) && mat.data == data).findFirst(); - - if (search.isPresent()) { - XMaterial found = search.get(); - CACHED_SEARCH.put(found.legacy[0] + "," + found.getData(), found); - return found; + for (XMaterial materials : VALUES) { + if ((data == -1 || data == materials.data) && materials.anyMatchLegacy(name)) { + NAME_CACHE.put(holder, materials); + return materials; + } } + return null; } /** - * Checks if XMaterial enum contains a material with this name. + * Checks if XMaterial enum contains a material with the given name. + *

+ * You should use {@link #matchXMaterial(String)} instead if you're going + * to get the XMaterial object after checking if it's available in the list + * by doing a simple {@link Optional#isPresent()} check. + * This is just to avoid multiple loops for maximum performance. * - * @param name name of the material + * @param name name of the material. * @return true if XMaterial enum has this material. + * @since 1.0.0 */ - public static boolean contains(String name) { - String formatted = format(name); - return Arrays.stream(XMaterial.VALUES).anyMatch(mat -> mat.name().equals(formatted)); + public static boolean contains(@Nonnull String name) { + Validate.notEmpty(name, "Cannot check for null or empty material name"); + name = format(name); + + for (XMaterial materials : VALUES) + if (materials.name().equals(name)) return true; + return false; } /** - * Checks if the given material matches any of the legacy names. + * Parses the given material name as an XMaterial with unspecified data value. * - * @param name the material name. - * @return true if it's a legacy name. - */ - public static boolean containsLegacy(String name) { - String formatted = format(name); - return Arrays.stream(Arrays.stream(XMaterial.VALUES).map(m -> m.legacy).toArray(String[]::new)).anyMatch(mat - -> parseLegacyVersionMaterialName(mat).equals(formatted)); - } - - /** * @see #matchXMaterial(String, byte) + * @since 2.0.0 */ - public static XMaterial matchXMaterial(Material material) { - return matchXMaterial(material.name()); - } - - /** - * @see #matchXMaterial(String, byte) - */ - public static XMaterial matchXMaterial(String name) { - // -1 Determines whether the item's data is unknown and only the name is given. - // Checking if the item is damageable won't do anything as the data is not going to be checked in requestOldMaterial anyway. + @Nonnull + public static Optional matchXMaterial(@Nonnull String name) { return matchXMaterial(name, (byte) -1); } /** - * Parses the material name and data argument as a {@link Material}. + * Parses the given material name as an XMaterial. + * Can also be used like: MATERIAL:DATA + *

+ * Examples + *

+     *     INK_SACK:1 -> RED_DYE
+     *     WOOL, 14  -> RED_WOOL
+     * 
* - * @param name name of the material - * @param data data of the material + * @see #matchDefinedXMaterial(String, byte) + * @see #matchXMaterial(ItemStack) + * @since 2.0.0 */ - public static Material parseMaterial(String name, byte data) { - return matchXMaterial(name, data).parseMaterial(); + @Nonnull + public static Optional matchXMaterial(@Nonnull String name, byte data) { + Validate.notEmpty(name, "Cannot match a material with null or empty material name"); + Optional oldMatch = matchXMaterialWithData(name); + if (oldMatch.isPresent()) return oldMatch; + + // -1 Determines whether the item's data value is unknown and only the name is given. + // Checking if the item is damageable won't do anything as the data is not going to be checked in requestOldMaterial anyway. + return matchDefinedXMaterial(format(name), data); } /** - * @param item the ItemStack to match its material and data. - * @see #matchXMaterial(String, byte) + * Parses material name and data value from the specified string. + * The seperators are: , or : + * Spaces are allowed. Mostly used when getting materials from config for old school minecrafters. + *

+ * Examples + *

+     *     INK_SACK:1 -> RED_DYE
+     *     WOOL, 14  -> RED_WOOL
+     * 
+ * + * @param name the material string that consists of the material name, data and separator character. + * @return the parsed XMaterial. + * @see #matchXMaterial(String) + * @since 3.0.0 */ + private static Optional matchXMaterialWithData(String name) { + for (char separator : new char[]{',', ':'}) { + int index = name.indexOf(separator); + if (index == -1) continue; + + String mat = format(name.substring(0, index)); + byte data = Byte.parseByte(StringUtils.deleteWhitespace(name.substring(index + 1))); + return matchDefinedXMaterial(mat, data); + } + + return Optional.empty(); + } + + /** + * Parses the given material as an XMaterial. + * + * @throws IllegalArgumentException may be thrown as an unexpected exception. + * @see #matchDefinedXMaterial(String, byte) + * @see #matchXMaterial(ItemStack) + * @since 2.0.0 + */ + @Nonnull + public static XMaterial matchXMaterial(@Nonnull Material material) { + Objects.requireNonNull(material, "Cannot match null material"); + return matchDefinedXMaterial(material.name(), (byte) -1) + .orElseThrow(() -> new IllegalArgumentException("Unsupported Material: " + material)); + } + + /** + * Parses the given item as an XMaterial using its material and data value (durability). + * + * @param item the ItemStack to match. + * @return an XMaterial if matched any. + * @throws IllegalArgumentException may be thrown as an unexpected exception. + * @see #matchDefinedXMaterial(String, byte) + * @since 2.0.0 + */ + @Nonnull @SuppressWarnings("deprecation") - public static XMaterial matchXMaterial(ItemStack item) { - return isDamageable(item.getType().name()) ? matchXMaterial(item.getType().name(), (byte) 0) : - matchXMaterial(item.getType().name(), (byte) item.getDurability()); + public static XMaterial matchXMaterial(@Nonnull ItemStack item) { + Objects.requireNonNull(item, "Cannot match null ItemStack"); + String material = item.getType().name(); + return matchDefinedXMaterial(material, + isDamageable(material) ? (byte) 0 : (byte) item.getDurability()) + .orElseThrow(() -> new IllegalArgumentException("Unsupported Material: " + material)); } /** - * Matches the argument string and its data with a XMaterial. + * Parses the given material name and data value as an XMaterial. + * All the values passed to this method will not be null or empty and are formatted correctly. * - * @param name the name of the material - * @param data the data byte of the material - * @return a XMaterial from the enum (with the same legacy name and data if in older versions.) + * @param name the formatted name of the material. + * @param data the data value of the material. + * @return an XMaterial (with the same data value if specified) + * @see #matchXMaterial(String, byte) + * @see #matchXMaterial(Material) + * @see #matchXMaterial(int, byte) + * @see #matchXMaterial(ItemStack) + * @since 3.0.0 */ - public static XMaterial matchXMaterial(String name, byte data) { - Validate.notEmpty(name, "Material name cannot be null or empty"); + @Nonnull + private static Optional matchDefinedXMaterial(@Nonnull String name, byte data) { + boolean duplicated = isDuplicated(name); + + // Do basic number and boolean checks before accessing more complex enum stuff. + // Maybe we can simplify (ISFLAT || !duplicated) with the (!ISFLAT && duplicated) under it to save a few nanoseconds? + // if (!Boolean.valueOf(Boolean.getBoolean(Boolean.TRUE.toString())).equals(Boolean.FALSE.booleanValue())) return null; + if (data <= 0 && (ISFLAT || !duplicated)) { + // Apparently the transform method is more efficient than toJavaUtil() + // toJavaUtil isn't even supported in older versions. + Optional xMat = Enums.getIfPresent(XMaterial.class, name).transform(Optional::of).or(Optional.empty()); + if (xMat.isPresent()) return xMat; + } + + // XMaterial Paradox (Duplication Check) + // I've concluded that this is just an infinite loop that keeps + // going around the Singular Form and the Plural Form materials. A waste of brain cells and a waste of time. + // This solution works just fine anyway. + if (!ISFLAT && duplicated) return Optional.ofNullable(requestDuplicatedXMaterial(name, data)); + return Optional.ofNullable(requestOldXMaterial(name, data)); + } + + /** + * XMaterial Paradox (Duplication Check) + * Checks if the material has any duplicates. + *

+ * Example: + *

{@code MELON, CARROT, POTATO, BEETROOT -> true} + * + * @param name the name of the material to check. + * @return true if there's a duplicated material for this material, otherwise false. + * @see #isDuplicated() + * @since 2.0.0 + */ + public static boolean isDuplicated(@Nonnull String name) { + Validate.notEmpty(name, "Cannot check duplication for null or empty material name"); name = format(name); - if ((contains(name) && data <= 0) && (isNewVersion() || !isDuplicated(name))) - return valueOf(name); - - // TODO Temporary but works - Please find a more reasonable fix for duplicated materials. - if (isDuplicated(name) && !isNewVersion()) - return requestDuplicatedXMaterial(name, data); - - return requestOldXMaterial(name, data); + // Don't use matchXMaterial() since this method is being called from matchXMaterial() itself and will cause a StackOverflowError. + for (Map.Entry duplicated : DUPLICATED.entrySet()) + if (duplicated.getKey().name().equals(name) || duplicated.getKey().anyMatchLegacy(name)) return true; + return false; } /** - * Gets the XMaterial based on the Material's ID and data. - * You should avoid using this for performance reasons. + * Gets the XMaterial based on the material's ID (Magic Value) and data value.
+ * You should avoid using this for performance issues. * * @param id the ID (Magic value) of the material. - * @param data the data of the material. - * @return some XMaterial, or null. + * @param data the data value of the material. + * @return a parsed XMaterial with the same ID and data value. + * @see #matchXMaterial(ItemStack) + * @since 2.0.0 */ - public static XMaterial matchXMaterial(int id, byte data) { + @Nonnull + public static Optional matchXMaterial(int id, byte data) { + if (id < 0 || data < 0) return Optional.empty(); + // Looping through Material.values() will take longer. - return Arrays.stream(XMaterial.VALUES).filter(mat -> mat.getId() == id && mat.data == data).findFirst().orElse(null); + for (XMaterial materials : VALUES) + if (materials.data == data && materials.getId() == id) return Optional.of(materials); + return Optional.empty(); } /** - * This method is temporary. Do not use this. + * A solution for XMaterial Paradox. * Manually parses the duplicated materials to find the exact material based on the server version. * * @param name the name of the material. * @return the duplicated XMaterial based on the version. + * @throws IllegalArgumentException may be thrown. If thrown, it's a bug. + * @since 2.0.0 */ - private static XMaterial requestDuplicatedXMaterial(String name, byte data) { + @Nullable + private static XMaterial requestDuplicatedXMaterial(@Nonnull String name, byte data) { XMaterial mat = requestOldXMaterial(name, data); - return mat == null ? null : mat.name().endsWith("S") ? valueOf(name) : mat; + // If ends with "S" -> Plural Form Material + return mat.name().charAt(mat.name().length() - 1) == 'S' ? Enums.getIfPresent(XMaterial.class, name).orNull() : mat; } /** - * Always returns the value. + * Always returns the value with the given duplicated material key name. * * @param name the name of the material. * @return the new XMaterial of this duplicated material. * @see #getXMaterialIfDuplicated(String) + * @since 2.0.0 */ - public static XMaterial getNewXMaterialIfDuplicated(String name) { - return DUPLICATED.entrySet().stream() - .filter(m -> m.getKey().name().equals(format(name))) - .findFirst() - .map(Map.Entry::getValue) - .orElse(null); + @Nonnull + public static Optional getNewXMaterialIfDuplicated(@Nonnull String name) { + Validate.notEmpty(name, "Cannot get new duplicated material for null or empty material name"); + name = format(name); + + for (Map.Entry duplicated : DUPLICATED.entrySet()) + if (duplicated.getKey().name().equals(name)) return Optional.of(duplicated.getKey()); + return Optional.empty(); } /** * Checks if the item is duplicated for a different purpose in new versions from {@link #DUPLICATED}. * * @param name the name of the material. - * @return the other XMaterial (key or value) of the XMaterial (key or value) which the name was equals to. + * @return the other XMaterial (key or value) of the XMaterial (key or value). * @see #matchXMaterial(String, byte) + * @since 2.0.0 */ - public static XMaterial getXMaterialIfDuplicated(String name) { - String formatted = format(name); - Optional> mat = DUPLICATED.entrySet().stream().filter(m - -> m.getKey().name().equals(formatted) || m.getValue().name().equals(formatted)).findFirst(); + @Nullable + public static XMaterial getXMaterialIfDuplicated(@Nonnull String name) { + Validate.notEmpty(name, "Cannot get duplicated material for null or empty material name"); + name = format(name); + + for (Map.Entry duplicated : DUPLICATED.entrySet()) + if (duplicated.getKey().name().equals(name)) return duplicated.getValue(); + else if (duplicated.getValue().name().equals(name)) return duplicated.getKey(); - if (mat.isPresent()) { - Map.Entry found = mat.get(); - return formatted.equals(found.getKey().name()) ? found.getValue() : found.getKey(); - } return null; } /** * Attempts to build the string like an enum name. + * Removes all the spaces, numbers and extra non-English characters. Also removes some config/in-game based strings. * * @param name the material name to modify. * @return a Material enum name. + * @since 2.0.0 */ - private static String format(String name) { - return name.toUpperCase().replace("MINECRAFT:", "").replace('-', '_').replaceAll("\\s+", "_").replaceAll("\\W", ""); + @Nonnull + private static String format(@Nonnull String name) { + return FORMAT_PATTERN.matcher( + name.trim().replace('-', '_').replace(' ', '_')).replaceAll("").toUpperCase(Locale.ENGLISH); } /** - * Parses the material name if the legacy name has a version attached to it. + * Checks if the specified version is the same version or higher than the current server version. * - * @param name the material name to parse. - * @return the material name with the version removed. - */ - private static String parseLegacyVersionMaterialName(String name) { - if (!name.contains("/")) return name; - return name.substring(0, name.indexOf('/')); - } - - /** - * Checks if the version argument is the same or higher than the current server version. - * - * @param version the version to be checked. + * @param version the major version to be checked. "1." is ignored -> 1.12 = 12 | 1.9 = 9 * @return true of the version is equal or higher than the current version. + * @since 2.0.0 */ - public static boolean isVersionOrHigher(MinecraftVersion version) { - MinecraftVersion current = getVersion(); - - if (version == current) return true; - if (version == MinecraftVersion.UNKNOWN) return false; - if (current == MinecraftVersion.UNKNOWN) return true; - - int ver = Integer.parseInt(version.name().replace("VERSION_", "").replace("_", "")); - int currentVer = Integer.parseInt(current.name().replace("VERSION_", "").replace("_", "")); - - return currentVer >= ver; + public static boolean supports(int version) { + return VERSION >= version; } /** - * Converts the material's name to a string with the first letter uppercase. + * Converts the enum names to a more friendly and readable string. * - * @return a converted string. + * @return a formatted string. + * @see #toWord(String) + * @since 2.1.0 */ - public static String toWord(Material material) { - return material.name().charAt(0) + material.name().substring(1).toLowerCase(); + @Nonnull + public static String toWord(@Nonnull Material material) { + Objects.requireNonNull(material, "Cannot translate a null material to a word"); + return toWord(material.name()); } /** - * Compares two major versions. The current server version and the given version. + * Parses an enum name to a normal word. + * Normal names have underlines removed and each word capitalized. + *

+ * Examples: + *

+     *     EMERALD                 -> Emerald
+     *     EMERALD_BLOCK           -> Emerald Block
+     *     ENCHANTED_GOLDEN_APPLE  -> Enchanted Golden Apple
+     * 
* - * @param version the version to check. - * @return true if is the same as the current version or higher. + * @param name the name of the enum. + * @return a cleaned more readable enum name. + * @since 2.1.0 */ - public static boolean isVersionOrHigher(String version) { - int currentVer = Integer.parseInt(getExactMajorVersion(Bukkit.getVersion()).replace(".", "")); - int versionNumber = Integer.parseInt(version.replace(".", "")); - - return currentVer >= versionNumber; + @Nonnull + private static String toWord(@Nonnull String name) { + return WordUtils.capitalize(name.replace('_', ' ').toLowerCase(Locale.ENGLISH)); } /** @@ -1315,303 +1610,428 @@ public enum XMaterial { * * @param version Supports {@link Bukkit#getVersion()}, {@link Bukkit#getBukkitVersion()} and normal formats such as "1.14" * @return the exact major version. + * @since 2.0.0 */ - public static String getExactMajorVersion(String version) { - // getBukkitVersion() - if (version.contains("SNAPSHOT") || version.contains("-R")) - version = version.substring(0, version.indexOf("-")); + @Nonnull + public static String getMajorVersion(@Nonnull String version) { + Validate.notEmpty(version, "Cannot get major Minecraft version from null or empty string"); + // getVersion() - if (version.contains("git")) version = version.substring(version.indexOf("MC:") + 4).replace(")", ""); - if (version.split(Pattern.quote(".")).length > 2) version = version.substring(0, version.lastIndexOf(".")); + int index = version.lastIndexOf("MC:"); + if (index != -1) { + version = version.substring(index + 4, version.length() - 1); + } else if (version.endsWith("SNAPSHOT")) { + // getBukkitVersion() + index = version.indexOf('-'); + version = version.substring(0, index); + } + + // 1.13.2, 1.14.4, etc... + int lastDot = version.lastIndexOf('.'); + if (version.indexOf('.') != lastDot) version = version.substring(0, lastDot); + return version; } /** - * Parses the string arugment to a version. - * Supports {@link Bukkit#getVersion()}, {@link Bukkit#getBukkitVersion()} and normal formats such as "1.14" - * - * @param version the server version. - * @return the Minecraft version represented by the string. - */ - private static MinecraftVersion valueOfVersion(String version) { - version = getExactMajorVersion(version); - if (version.equals("1.10") || version.equals("1.11") || version.equals("1.12")) - return MinecraftVersion.VERSION_1_9; - version = version.replace(".", "_"); - if (!version.startsWith("VERSION_")) version = "VERSION_" + version; - String check = version; - return Arrays.stream(MinecraftVersion.VALUES).anyMatch(v -> v.name().equals(check)) ? MinecraftVersion.valueOf(version) : MinecraftVersion.UNKNOWN; - } - - /** - * Checks if the material can be damaged from {@link #DAMAGEABLE}. + * Checks if the material can be damaged by using it. + * Names going through this method are not formatted. * * @param name the name of the material. * @return true of the material can be damaged. + * @see #isDamageable() + * @since 1.0.0 */ - public static boolean isDamageable(String name) { - return Arrays.stream(DAMAGEABLE).anyMatch(name::contains); + public static boolean isDamageable(@Nonnull String name) { + Objects.requireNonNull(name, "Material name cannot be null"); + for (String damageable : DAMAGEABLE) + if (name.contains(damageable)) return true; + return false; } - public static boolean isDuplicated(String name) { - String formatted = format(name); - return DUPLICATED.entrySet().stream().anyMatch(x -> x.getKey().name().equals(formatted)); + /** + * Checks if the list of given material names matches the given base material. + * Mostly used for configs. + *

+ * Supports {@link String#contains} {@code CONTAINS:NAME} and Regular Expression {@code REGEX:PATTERN} formats. + *

+ * Example: + *

+     *     XMaterial material = {@link #matchXMaterial(ItemStack)};
+     *     if (material.isOneOf(plugin.getConfig().getStringList("disabled-items")) return;
+     * 
+ *
+ * {@code CONTAINS} Examples: + *
+     *     "CONTAINS:CHEST" -> CHEST, ENDERCHEST, TRAPPED_CHEST -> true
+     *     "cOnTaINS:dYe" -> GREEN_DYE, YELLOW_DYE, BLUE_DYE, INK_SACK -> true
+     * 
+ *

+ * {@code REGEX} Examples + *

+     *     "REGEX:^.+_.+_.+$" -> Every Material with 3 underlines or more: SHULKER_SPAWN_EGG, SILVERFISH_SPAWN_EGG, SKELETON_HORSE_SPAWN_EGG
+     *     "REGEX:^.{1,3}$" -> Material names that have 3 letters only: BED, MAP, AIR
+     * 
+ *

+ * The reason that there are tags for {@code CONTAINS} and {@code REGEX} + * is for the performance. + * Please avoid using the {@code REGEX} tag if you can use the {@code CONTAINS} tag. + * It'll have a huge impact on performance. + * Please avoid using {@code (capturing groups)} there's no use for them in this case. + * If you want to use groups, use {@code (?: non-capturing groups)}. It's faster. + *

+ * You can make a cache for pre-compiled RegEx patterns from your config. + * It's better, but not much faster since these patterns are not that complex. + *

+ * Want to learn RegEx? You can mess around in RegExr website. + * + * @param material the base material to match other materials with. + * @param materials the material names to check base material on. + * @return true if one of the given material names is similar to the base material. + * @since 3.1.1 + */ + public static boolean isOneOf(@Nonnull Material material, @Nullable List materials) { + if (materials == null || materials.isEmpty()) return false; + Objects.requireNonNull(material, "Cannot match materials with a null material"); + String name = material.name(); + + for (String comp : materials) { + comp = comp.toUpperCase(); + if (comp.startsWith("CONTAINS:")) { + comp = format(comp.substring(9)); + if (name.contains(comp)) return true; + continue; + } + if (comp.startsWith("REGEX:")) { + comp = comp.substring(6); + if (name.matches(comp)) return true; + continue; + } + + // Direct Object Equals + Optional mat = matchXMaterial(comp); + if (mat.isPresent() && mat.get().parseMaterial() == material) return true; + } + return false; + } + + /** + * Gets the version which this material was added in. + * If the material doesn't have a version it'll return 0; + * + * @return the Minecraft version which tihs material was added in. + * @since 3.0.0 + */ + public int getMaterialVersion() { + if (this.legacy.length == 0) return 0; + String version = this.legacy[0]; + if (version.charAt(1) != '.') return 0; + + return Integer.parseInt(version.substring(2)); + } + + /** + * Sets the {@link Material} (and data value on older versions) of an item. + * Damageable materials will not have their durability changed. + *

+ * Use {@link #parseItem()} instead when creating new ItemStacks. + * + * @param item the item to change its type. + * @see #parseItem() + * @since 3.0.0 + */ + @Nonnull + @SuppressWarnings("deprecation") + public ItemStack setType(@Nonnull ItemStack item) { + Objects.requireNonNull(item, "Cannot set material for null ItemStack"); + + item.setType(this.parseMaterial()); + if (!ISFLAT && !this.isDamageable()) item.setDurability(this.data); + return item; + } + + /** + * Checks if the list of given material names matches the given base material. + * Mostly used for configs. + * + * @param materials the material names to check base material on. + * @return true if one of the given material names is similar to the base material. + * @see #isOneOf(Material, List) + * @since 3.0.0 + */ + public boolean isOneOf(@Nullable List materials) { + Material material = this.parseMaterial(); + if (material == null) return false; + return isOneOf(material, materials); + } + + /** + * Checks if the given string matches any of this material's legacy material names. + * All the values passed to this method will not be null or empty and are formatted correctly. + * + * @param name the name to check + * @return true if it's one of the legacy names. + * @since 2.0.0 + */ + private boolean anyMatchLegacy(@Nonnull String name) { + for (String legacy : this.legacy) { + if (legacy.isEmpty()) break; // Left-side suggestion list + if (name.equals(legacy)) return true; + } + return false; + } + + /** + * User-friendly readable name for this material + * In most cases you should be using {@link #name()} instead. + * + * @return string of this object. + * @see #toWord(String) + * @since 3.0.0 + */ + @Override + public String toString() { + return toWord(this.name()); } /** * Gets the ID (Magic value) of the material. - * If an {@link IllegalArgumentException} was thrown from this method, - * you should definitely report it. * - * @return the ID of the material. -1 if it's a new block. + * @return the ID of the material or -1 if it's a new block or the material is not supported. + * @see #matchXMaterial(int, byte) + * @since 2.2.0 */ @SuppressWarnings("deprecation") public int getId() { - return this.isNew() ? -1 : this.parseMaterial().getId(); + if (this.data != 0 || (this.legacy.length != 0 && Integer.parseInt(this.legacy[0].substring(2)) >= 13)) return -1; + Material material = this.parseMaterial(); + return material == null ? -1 : material.getId(); } + /** + * Checks if the material has any duplicates. + * + * @return true if there is a duplicated name for this material, otherwise false. + * @see #getXMaterialIfDuplicated() + * @see #isDuplicated(String) + * @since 2.0.0 + */ public boolean isDuplicated() { return DUPLICATED.containsKey(this); } /** - * Checks if the given string matches any of this material's legacy material names. + * Checks if the item is duplicated for a different purpose in new versions. * - * @param name the name to check - * @return true if it's one of the legacy names. - */ - public boolean matchAnyLegacy(String name) { - String formatted = format(name); - return Arrays.asList(this.legacy).contains(formatted); - } - - /** - * Converts the material's name to a string with the first letter uppercase. - * - * @return a converted string. - */ - public String toWord() { - return this.name().charAt(0) + this.name().substring(1).toLowerCase(); - } - - /** - * Checks if the item is duplicated for a different purpose in new versions from {@link #DUPLICATED}. - * - * @return true if the item's name is duplicated. - * @see #matchXMaterial(String, byte) + * @return true if the item's name is duplicated, otherwise false. + * @see #isDuplicated() + * @see #getNewXMaterialIfDuplicated(String) + * @since 2.0.0 */ + @Nullable public XMaterial getXMaterialIfDuplicated() { - Optional> mat = DUPLICATED.entrySet().stream().filter(m -> m.getKey() == this).findFirst(); - return mat.map(Map.Entry::getValue).orElse(null); + return DUPLICATED.get(this); } /** - * @return true if the item can be damaged. + * Checks if the material can be damaged by using it. + * Names going through this method are not formatted. + * + * @return true if the item can be damaged (have its durability changed), otherwise false. * @see #isDamageable(String) + * @since 1.0.0 */ public boolean isDamageable() { return isDamageable(this.name()); } /** - * Get the {@link ItemStack} data of this material in older versions. - * Which can be accessed with {@link ItemStack#getData()} then MaterialData#getData() + * The data value of this material pre-flattening. + *

+ * Can be accessed with {@link ItemStack#getData()} then {@code MaterialData#getData()} * or {@link ItemStack#getDurability()} if not damageable. * - * @return data of this material. + * @return data of this material, or 0 if none. + * @since 1.0.0 */ - public int getData() { - return this.data; + @SuppressWarnings("deprecation") + public byte getData() { + return data; } /** * Get a list of materials names that was previously used by older versions. + * If the material was added in a new version {@link #isNewVersion()}, + * then the first element will indicate which version the material was added in. * - * @return a list of string of legacy material names. + * @return a list of legacy material names and the first element as the version the material was added in if new. + * @since 1.0.0 */ + @Nonnull public String[] getLegacy() { - return this.legacy; + return legacy; } /** - * Parses the XMaterial as an {@link ItemStack}. + * Parses an item from this XMaterial. + * Uses data values on older versions. * - * @return an ItemStack with the same material (and data if in older versions.) + * @return an ItemStack with the same material (and data value if in older versions.) + * @see #parseItem(boolean) + * @see #setType(ItemStack) + * @since 1.0.0 */ + @Nullable public ItemStack parseItem() { return parseItem(false); } /** - * Parses the XMaterial as an {@link ItemStack}. + * Parses an item from this XMaterial. + * Uses data values on older versions. * - * @param suggest if true {@link #parseMaterial(boolean)} - * @return an ItemStack with the same material (and data if in older versions.) + * @param suggest if true {@link #parseMaterial(boolean true)} will be used. + * @return an ItemStack with the same material (and data value if in older versions.) + * @see #setType(ItemStack) + * @since 2.0.0 */ + @Nullable @SuppressWarnings("deprecation") public ItemStack parseItem(boolean suggest) { Material material = this.parseMaterial(suggest); - return isNewVersion() ? new ItemStack(material) : new ItemStack(material, 1, this.data); + if (material == null) return null; + return ISFLAT ? new ItemStack(material) : new ItemStack(material, 1, this.data); } /** - * Parses the XMaterial as a {@link Material}. + * Parses the material of this XMaterial. * - * @return the Material related to this XMaterial based on the server version. + * @return the material related to this XMaterial based on the server version. + * @see #parseMaterial(boolean) + * @since 1.0.0 */ + @Nullable public Material parseMaterial() { return parseMaterial(false); } /** - * Parses the XMaterial as a {@link Material}. + * Parses the material of this XMaterial and accepts suggestions. * - * @param suggest Use a suggested material if the material is added in the new version. - * @return the Material related to this XMaterial based on the server version. + * @param suggest use a suggested material (from older materials) if the material is added in a later version of Minecraft. + * @return the material related to this XMaterial based on the server version. * @see #matchXMaterial(String, byte) + * @since 2.0.0 */ + @SuppressWarnings("OptionalAssignedToNull") + @Nullable public Material parseMaterial(boolean suggest) { - Material newMat = Material.getMaterial(this.name()); + Optional cache = PARSED_CACHE.getIfPresent(this); + if (cache != null) return cache.orElse(null); + Material mat; - // If the name is not null it's probably the new version. - // So you can still use this name even if it's a duplicated name. - // Since duplicated names only apply to older versions. - if (newMat != null && (isNewVersion() || !this.isDuplicated())) return newMat; - return requestOldMaterial(suggest); + if (!ISFLAT && this.isDuplicated()) mat = requestOldMaterial(suggest); + else { + mat = Material.getMaterial(this.name()); + if (mat == null) mat = requestOldMaterial(suggest); + } + + if (mat != null) PARSED_CACHE.put(this, Optional.ofNullable(mat)); + return mat; } /** - * Parses from old material names and can accept suggestions. + * Parses a material for older versions of Minecraft. + * Accepts suggestions if specified. * - * @param suggest Accept suggestions for newly added blocks - * @return A parsed Material suitable for this minecraft version. + * @param suggest if true suggested materials will be considered for old versions. + * @return a parsed material suitable for the current Minecraft version. + * @see #parseMaterial(boolean) + * @since 2.0.0 */ + @Nullable private Material requestOldMaterial(boolean suggest) { - Material oldMat; - boolean isNew = getVersionIfNew() != MinecraftVersion.UNKNOWN; for (int i = this.legacy.length - 1; i >= 0; i--) { - String legacyName = this.legacy[i]; - // Slash means it's just another name for the material in another version. - if (legacyName.contains("/")) { - oldMat = Material.getMaterial(parseLegacyVersionMaterialName(legacyName)); + String legacy = this.legacy[i]; - if (oldMat != null) return oldMat; - else continue; + // Check if we've reached the end and the last string is our + // material version. + if (i == 0 && legacy.charAt(1) == '.') return null; + + // According to the suggestion list format, all the other names continuing + // from here are considered as a "suggestion" + // The empty string is an indicator for suggestion list on the left side. + if (legacy.isEmpty()) { + if (suggest) continue; + break; } - if (isNew) { - if (suggest) { - oldMat = Material.getMaterial(legacyName); - if (oldMat != null) return oldMat; - } else return null; - // According to the suggestion format list, all the other names continuing - // from here are considered as a "suggestion" if there's no slash anymore. - } - oldMat = Material.getMaterial(legacyName); - if (oldMat != null) return oldMat; + + Material material = Material.getMaterial(legacy); + if (material != null) return material; } return null; } /** - * Checks if an item is similar to the material and its data (if in older versions.) + * Checks if an item has the same material (and data value on older versions). * * @param item item to check. - * @return true if the material is the same as the item's material (and data if in older versions.) + * @return true if the material is the same as the item's material (and data value if on older versions), otherwise false. + * @since 1.0.0 */ @SuppressWarnings("deprecation") - public boolean isSimilar(ItemStack item) { - Objects.requireNonNull(item, "ItemStack cannot be null"); - Objects.requireNonNull(item.getType(), "ItemStack's material cannot be null"); - return (isNewVersion() || this.isDamageable()) ? item.getType() == this.parseMaterial() : item.getType() == this.parseMaterial() && item.getDurability() == this.data; + public boolean isSimilar(@Nonnull ItemStack item) { + Objects.requireNonNull(item, "Cannot compare with null ItemStack"); + if (item.getType() != this.parseMaterial()) return false; + return ISFLAT || this.isDamageable() || item.getDurability() == this.data; } /** - * Get the suggested material names that can be used instead of this material. + * Gets the suggested material names that can be used + * if the material is not supported in the current version. * * @return a list of suggested material names. + * @see #parseMaterial(boolean) + * @since 2.0.0 */ - public String[] getSuggestions() { - if (!this.legacy[0].contains(".")) return new String[0]; - return Arrays.stream(this.legacy).filter(mat -> !mat.contains(".")).toArray(String[]::new); + @Nonnull + public List getSuggestions() { + if (this.legacy.length == 0 || this.legacy[0].charAt(1) != '.') return new ArrayList<>(); + List suggestions = new ArrayList<>(); + for (String legacy : this.legacy) { + if (legacy.isEmpty()) break; + suggestions.add(legacy); + } + return suggestions; } /** * Checks if this material is supported in the current version. - * It'll check both the newest matetrial name and for legacy names. + * Suggested materials will be ignored. + *

+ * Note that you should use {@link #parseMaterial()} and check if it's null + * if you're going to parse and use the material later. * * @return true if the material exists in {@link Material} list. + * @since 2.0.0 */ public boolean isSupported() { - return Arrays.stream(Material.values()).anyMatch(mat -> mat.name().equals(this.name()) || this.matchAnyLegacy(mat.name())); - } + int version = this.getMaterialVersion(); + if (version != 0) return supports(version); - /** - * Gets the added version if the material is newly added after the 1.13 Aquatic Update and higher. - * - * @return the version which the material was added in. {@link MinecraftVersion#UNKNOWN} if not new. - * @see #isNew() - */ - public MinecraftVersion getVersionIfNew() { - return this.isNew() ? valueOfVersion(this.legacy[0]) : MinecraftVersion.UNKNOWN; + Material material = Material.getMaterial(this.name()); + if (material != null) return true; + return requestOldMaterial(false) != null; } /** * Checks if the material is newly added after the 1.13 Aquatic Update. * - * @return true if it was newly added. + * @return true if the material was newly added, otherwise false. + * @see #getMaterialVersion() + * @since 2.0.0 */ - public boolean isNew() { - return this.legacy[0].contains("."); + public boolean isFromNewSystem() { + return this.legacy.length != 0 && Integer.parseInt(this.legacy[0].substring(2)) > 13; } - - /** - * Gets the suggested material instead of returning null for unsupported versions. - * This is somehow similar to what ProtcolSupport and ViaVersion are doing to new materials. - * Don't use this if you want to parse to a {@link Material} - * - * @return The suggested material that is similar. - * @see #parseMaterial() - */ - public XMaterial suggestOldMaterialIfNew() { - if (getVersionIfNew() == MinecraftVersion.UNKNOWN || this.legacy.length == 1) return null; - - // We need a loop because: Newest -> Oldest - for (int i = this.legacy.length - 1; i >= 0; i--) { - String legacyName = this.legacy[i]; - - if (legacyName.contains("/")) continue; - XMaterial mat = matchXMaterial(parseLegacyVersionMaterialName(legacyName), this.data); - if (mat != null && this != mat) return mat; - } - return null; - } - - /** - * Only major versions related to material changes. - */ - public enum MinecraftVersion { - /** - * Bountiful Update - */ - VERSION_1_8, - /** - * Combat Update (Pitiful Update?) - */ - VERSION_1_9, - /** - * Aquatic Update - */ - VERSION_1_13, - /** - * Village Pillage Update - */ - VERSION_1_14, - /** - * 1.7 or below. - * Using {@link #getVersionIfNew()} it means 1.12 or below. - */ - UNKNOWN; - - public static final MinecraftVersion[] VALUES = MinecraftVersion.values(); - } -} +} \ No newline at end of file diff --git a/src/main/java/com/massivecraft/factions/zcore/fdisband/FDisbandFrame.java b/src/main/java/com/massivecraft/factions/zcore/fdisband/FDisbandFrame.java index 0356c229..b6003170 100644 --- a/src/main/java/com/massivecraft/factions/zcore/fdisband/FDisbandFrame.java +++ b/src/main/java/com/massivecraft/factions/zcore/fdisband/FDisbandFrame.java @@ -61,7 +61,7 @@ public class FDisbandFrame { private ItemStack buildConfirmDummyItem(Faction faction) { ConfigurationSection config = FactionsPlugin.getInstance().getConfig().getConfigurationSection("f-disband-gui.confirm-item"); - ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).parseItem(); + ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).get().parseItem(); ItemMeta meta = item.getItemMeta(); if (meta != null) { List lore = new ArrayList<>(); @@ -77,7 +77,7 @@ public class FDisbandFrame { private ItemStack buildDenyDummyItem() { ConfigurationSection config = FactionsPlugin.getInstance().getConfig().getConfigurationSection("f-disband-gui.deny-item"); - ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).parseItem(); + ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).get().parseItem(); ItemMeta meta = item.getItemMeta(); if (meta != null) { meta.setLore(FactionsPlugin.getInstance().colorList(config.getStringList("Lore"))); diff --git a/src/main/java/com/massivecraft/factions/zcore/fperms/PermissableAction.java b/src/main/java/com/massivecraft/factions/zcore/fperms/PermissableAction.java index e0928999..d0b00f4a 100644 --- a/src/main/java/com/massivecraft/factions/zcore/fperms/PermissableAction.java +++ b/src/main/java/com/massivecraft/factions/zcore/fperms/PermissableAction.java @@ -104,7 +104,7 @@ public enum PermissableAction { public ItemStack buildAsset(FPlayer fme, Permissable perm) { ConfigurationSection section = FactionsPlugin.getInstance().getConfig().getConfigurationSection("fperm-gui.action"); - ItemStack item = XMaterial.matchXMaterial(section.getString("Materials." + this.name)).parseItem(); + ItemStack item = XMaterial.matchXMaterial(section.getString("Materials." + this.name)).get().parseItem(); ItemMeta meta = item.getItemMeta(); meta.setDisplayName(FactionsPlugin.getInstance().color(section.getString("placeholder-item.name").replace("{action}", this.name))); diff --git a/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableActionFrame.java b/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableActionFrame.java index df3f3e40..2c36ed2b 100644 --- a/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableActionFrame.java +++ b/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableActionFrame.java @@ -91,7 +91,7 @@ public class PermissableActionFrame { private ItemStack buildDummyItem() { ConfigurationSection config = FactionsPlugin.getInstance().getConfig().getConfigurationSection("fperm-gui.dummy-item"); - ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).parseItem(); + ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).get().parseItem(); ItemMeta meta = item.getItemMeta(); meta.setLore(FactionsPlugin.getInstance().colorList(config.getStringList("Lore"))); meta.setDisplayName(FactionsPlugin.getInstance().color(config.getString("Name"))); @@ -101,7 +101,7 @@ public class PermissableActionFrame { private ItemStack buildBackItem() { ConfigurationSection config = FactionsPlugin.getInstance().getConfig().getConfigurationSection("fperm-gui.back-item"); - ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).parseItem(); + ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).get().parseItem(); ItemMeta meta = item.getItemMeta(); meta.setLore(FactionsPlugin.getInstance().colorList(config.getStringList("Lore"))); meta.setDisplayName(FactionsPlugin.getInstance().color(config.getString("Name"))); diff --git a/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableRelationFrame.java b/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableRelationFrame.java index 6ef61803..95e14f0a 100644 --- a/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableRelationFrame.java +++ b/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableRelationFrame.java @@ -56,7 +56,7 @@ public class PermissableRelationFrame { } private ItemStack buildAsset(String loc, String relation) { - ItemStack item = XMaterial.matchXMaterial(FactionsPlugin.getInstance().getConfig().getString(loc)).parseItem(); + ItemStack item = XMaterial.matchXMaterial(FactionsPlugin.getInstance().getConfig().getString(loc)).get().parseItem(); ItemMeta meta = item.getItemMeta(); meta.setDisplayName(FactionsPlugin.getInstance().color(FactionsPlugin.getInstance().getConfig().getString("fperm-gui.relation.Placeholder-Item.Name").replace("{relation}", relation))); item.setItemMeta(meta); @@ -65,7 +65,7 @@ public class PermissableRelationFrame { private ItemStack buildDummyItem() { ConfigurationSection config = FactionsPlugin.getInstance().getConfig().getConfigurationSection("fperm-gui.dummy-item"); - ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).parseItem(); + ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).get().parseItem(); ItemMeta meta = item.getItemMeta(); meta.setLore(FactionsPlugin.getInstance().colorList(config.getStringList("Lore"))); meta.setDisplayName(FactionsPlugin.getInstance().color(config.getString("Name"))); diff --git a/src/main/java/com/massivecraft/factions/zcore/fupgrades/FUpgradeFrame.java b/src/main/java/com/massivecraft/factions/zcore/fupgrades/FUpgradeFrame.java index 9329017b..e3d17197 100644 --- a/src/main/java/com/massivecraft/factions/zcore/fupgrades/FUpgradeFrame.java +++ b/src/main/java/com/massivecraft/factions/zcore/fupgrades/FUpgradeFrame.java @@ -101,7 +101,7 @@ public class FUpgradeFrame { private ItemStack buildDummyItem() { ConfigurationSection config = FactionsPlugin.getInstance().getConfig().getConfigurationSection("fupgrades.MainMenu.DummyItem"); - ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).parseItem(); + ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).get().parseItem(); ItemMeta meta = item.getItemMeta(); if (meta != null) { meta.setLore(FactionsPlugin.getInstance().colorList(config.getStringList("Lore"))); diff --git a/src/main/java/com/massivecraft/factions/zcore/fupgrades/UpgradeType.java b/src/main/java/com/massivecraft/factions/zcore/fupgrades/UpgradeType.java index 8a100afe..9c84f6db 100644 --- a/src/main/java/com/massivecraft/factions/zcore/fupgrades/UpgradeType.java +++ b/src/main/java/com/massivecraft/factions/zcore/fupgrades/UpgradeType.java @@ -58,7 +58,7 @@ public enum UpgradeType { public ItemStack buildAsset(Faction f) { ConfigurationSection config = FactionsPlugin.getInstance().getConfig().getConfigurationSection("fupgrades.MainMenu." + this.id + ".DisplayItem"); - ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).parseItem(); + ItemStack item = XMaterial.matchXMaterial(config.getString("Type")).get().parseItem(); int level = f.getUpgrade(this); ItemMeta meta = item.getItemMeta(); if (meta != null) {