diff --git a/nmshandler/pom.xml b/nmshandler/pom.xml index 74e5ad8d05..6deb5ae91d 100644 --- a/nmshandler/pom.xml +++ b/nmshandler/pom.xml @@ -36,7 +36,7 @@ org.apache.maven.plugins maven-compiler-plugin - 2.3.2 + 3.8.0 1.8 1.8 diff --git a/nmshandler/src/main/java/net/aufdemrand/denizen/nms/interfaces/ItemHelper.java b/nmshandler/src/main/java/net/aufdemrand/denizen/nms/interfaces/ItemHelper.java index fb26a20120..c631f73f03 100644 --- a/nmshandler/src/main/java/net/aufdemrand/denizen/nms/interfaces/ItemHelper.java +++ b/nmshandler/src/main/java/net/aufdemrand/denizen/nms/interfaces/ItemHelper.java @@ -5,6 +5,7 @@ import net.aufdemrand.denizen.nms.util.PlayerProfile; import net.aufdemrand.denizen.nms.util.jnbt.CompoundTag; import net.aufdemrand.denizen.nms.util.jnbt.Tag; +import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import java.util.List; @@ -12,7 +13,9 @@ public interface ItemHelper { - String getVanillaName(ItemStack itemStack); + String getInternalNameFromMaterial(Material material); + + Material getMaterialFromInternalName(String internalName); String getJsonString(ItemStack itemStack); diff --git a/plugin/pom.xml b/plugin/pom.xml index e70c651ec1..2fe2f7e246 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -154,7 +154,7 @@ org.apache.maven.plugins maven-shade-plugin - 2.1 + 3.2.0 package @@ -191,7 +191,7 @@ org.apache.maven.plugins maven-jar-plugin - 2.2 + 3.1.0 ../target @@ -206,7 +206,7 @@ org.apache.maven.plugins maven-compiler-plugin - 2.5.1 + 3.8.0 1.8 1.8 diff --git a/plugin/src/main/java/net/aufdemrand/denizen/Denizen.java b/plugin/src/main/java/net/aufdemrand/denizen/Denizen.java index fdd2723af4..d4dad602e5 100644 --- a/plugin/src/main/java/net/aufdemrand/denizen/Denizen.java +++ b/plugin/src/main/java/net/aufdemrand/denizen/Denizen.java @@ -808,6 +808,7 @@ public Property get(dObject o) { PropertyParser.registerProperty(EntityColor.class, dEntity.class); PropertyParser.registerProperty(EntityCritical.class, dEntity.class); PropertyParser.registerProperty(EntityCustomName.class, dEntity.class); + PropertyParser.registerProperty(EntityDisabledSlots.class, dEntity.class); PropertyParser.registerProperty(EntityPotionEffects.class, dEntity.class); PropertyParser.registerProperty(EntityElder.class, dEntity.class); PropertyParser.registerProperty(EntityEquipment.class, dEntity.class); @@ -847,6 +848,8 @@ public Property get(dObject o) { PropertyParser.registerProperty(ItemBook.class, dItem.class); PropertyParser.registerProperty(ItemDisplayname.class, dItem.class); PropertyParser.registerProperty(ItemDurability.class, dItem.class); + PropertyParser.registerProperty(ItemCanDestroy.class, dItem.class); + PropertyParser.registerProperty(ItemCanPlaceOn.class, dItem.class); PropertyParser.registerProperty(ItemColor.class, dItem.class); PropertyParser.registerProperty(ItemEnchantments.class, dItem.class); PropertyParser.registerProperty(ItemFirework.class, dItem.class); diff --git a/plugin/src/main/java/net/aufdemrand/denizen/objects/properties/entity/EntityDisabledSlots.java b/plugin/src/main/java/net/aufdemrand/denizen/objects/properties/entity/EntityDisabledSlots.java new file mode 100644 index 0000000000..3d3953751c --- /dev/null +++ b/plugin/src/main/java/net/aufdemrand/denizen/objects/properties/entity/EntityDisabledSlots.java @@ -0,0 +1,197 @@ +package net.aufdemrand.denizen.objects.properties.entity; + +import net.aufdemrand.denizen.objects.dEntity; +import net.aufdemrand.denizen.utilities.debugging.dB; +import net.aufdemrand.denizen.utilities.nbt.CustomNBT; +import net.aufdemrand.denizencore.objects.Element; +import net.aufdemrand.denizencore.objects.Mechanism; +import net.aufdemrand.denizencore.objects.dList; +import net.aufdemrand.denizencore.objects.dObject; +import net.aufdemrand.denizencore.objects.properties.Property; +import net.aufdemrand.denizencore.tags.Attribute; +import net.aufdemrand.denizencore.utilities.CoreUtilities; +import org.bukkit.entity.EntityType; +import org.bukkit.inventory.EquipmentSlot; + +import java.util.*; + +public class EntityDisabledSlots implements Property { + + public static boolean describes(dObject entity) { + return entity instanceof dEntity && ((dEntity) entity).getBukkitEntityType() == EntityType.ARMOR_STAND; + } + + public static EntityDisabledSlots getFrom(dObject entity) { + if (!describes(entity)) { + return null; + } + else { + return new EntityDisabledSlots((dEntity) entity); + } + } + + /////////////////// + // Instance Fields and Methods + ///////////// + + private EntityDisabledSlots(dEntity entity) { + dentity = entity; + } + + dEntity dentity; + + public enum Action { + ALL(0), REMOVE(8), PLACE(16); + + private final int id; + + Action(int id) { + this.id = id; + } + + public int getId() { + return id; + } + } + + private dList getDisabledSlots() { + Map> map = CustomNBT.getDisabledSlots(dentity.getBukkitEntity()); + dList list = new dList(); + for (Map.Entry> entry : map.entrySet()) { + for (Action action : entry.getValue()) { + list.add(CoreUtilities.toLowerCase(entry.getKey().name() + "/" + action.name())); + } + } + return list; + } + + ///////// + // Property Methods + /////// + + @Override + public String getPropertyString() { + dList list = getDisabledSlots(); + return list.isEmpty() ? null : list.identify(); + } + + @Override + public String getPropertyId() { + return "disabled_slots"; + } + + /////////// + // dObject Attributes + //////// + + @Override + public String getAttribute(Attribute attribute) { + + if (attribute == null) { + return "null"; + } + + // <--[tag] + // @attribute + // @returns Element(Integer) + // @mechanism dEntity.disabled_slots_raw + // @group properties + // @description + // If the entity is an armor stand, returns its raw disabled slots value. + // See <@link url https://minecraft.gamepedia.com/Armor_Stand/ED> + // --> + if (attribute.startsWith("disabled_slots.raw")) { + return new Element(CustomNBT.getCustomIntNBT(dentity.getBukkitEntity(), CustomNBT.KEY_DISABLED_SLOTS)) + .getAttribute(attribute.fulfill(2)); + } + + // <--[tag] + // @attribute + // @returns dList + // @mechanism dEntity.disabled_slots + // @group properties + // @description + // If the entity is an armor stand, returns a list of its disabled slots in the form li@slot/action|... + // --> + if (attribute.startsWith("disabled_slots")) { + return getDisabledSlots().getAttribute(attribute.fulfill(1)); + } + + return null; + } + + @Override + public void adjust(Mechanism mechanism) { + + // <--[mechanism] + // @object dEntity + // @name disabled_slots_raw + // @input Element(Integer) + // @description + // Sets the raw disabled slots value of an armor stand. + // See <@link url https://minecraft.gamepedia.com/Armor_Stand/ED> + // @tags + // + // + // --> + if (mechanism.matches("disabled_slots_raw") && mechanism.requireInteger()) { + CustomNBT.addCustomNBT(dentity.getBukkitEntity(), CustomNBT.KEY_DISABLED_SLOTS, mechanism.getValue().asInt()); + } + + // <--[mechanism] + // @object dEntity + // @name disabled_slots + // @input dList + // @description + // Sets the disabled slots of an armor stand in the form li@slot(/action)|... + // Optionally include an action to disable specific interactions (defaults to ALL). + // Leave empty to enable all slots. + // Slots: <@link url https://hub.spigotmc.org/javadocs/spigot/org/bukkit/inventory/EquipmentSlot.html> + // Actions: ALL, REMOVE, PLACE + // NOTE: Minecraft contains a bug where disabling HAND/ALL still allows item removal. + // To fully disable hand interaction, disable HAND/ALL and HAND/REMOVE. + // @tags + // + // + // --> + if (mechanism.matches("disabled_slots")) { + if (!mechanism.hasValue()) { + CustomNBT.removeCustomNBT(dentity.getBukkitEntity(), CustomNBT.KEY_DISABLED_SLOTS); + return; + } + + dList list = mechanism.getValue().asType(dList.class); + Map> map = new HashMap<>(); + + for (String string : list) { + String[] split = string.toUpperCase().split("/", 2); + + EquipmentSlot slot; + Action action = null; + + try { + slot = EquipmentSlot.valueOf(split[0]); + } + catch (IllegalArgumentException e) { + dB.echoError("Invalid equipment slot specified: " + split[0]); + continue; + } + + if (split.length == 2) { + try { + action = Action.valueOf(split[1]); + } + catch (IllegalArgumentException e) { + dB.echoError("Invalid action specified: " + split[1]); + continue; + } + } + + Set set = map.computeIfAbsent(slot, k -> new HashSet<>()); + set.add(action == null ? Action.ALL : action); + } + + CustomNBT.setDisabledSlots(dentity.getBukkitEntity(), map); + } + } +} diff --git a/plugin/src/main/java/net/aufdemrand/denizen/objects/properties/item/ItemAttributeNBT.java b/plugin/src/main/java/net/aufdemrand/denizen/objects/properties/item/ItemAttributeNBT.java index ba00c40960..46e550c498 100644 --- a/plugin/src/main/java/net/aufdemrand/denizen/objects/properties/item/ItemAttributeNBT.java +++ b/plugin/src/main/java/net/aufdemrand/denizen/objects/properties/item/ItemAttributeNBT.java @@ -108,7 +108,7 @@ public void adjust(Mechanism mechanism) { } dList list = mechanism.getValue().asType(dList.class); ItemStack itemStack = item.getItemStack(); - itemStack = CustomNBT.clearAttributes(itemStack); + itemStack = CustomNBT.clearNBT(itemStack, CustomNBT.KEY_ATTRIBUTES); for (String string : list) { String[] split = string.split("/"); String attribute = EscapeTags.unEscape(split[0]); diff --git a/plugin/src/main/java/net/aufdemrand/denizen/objects/properties/item/ItemCanDestroy.java b/plugin/src/main/java/net/aufdemrand/denizen/objects/properties/item/ItemCanDestroy.java new file mode 100644 index 0000000000..729e327967 --- /dev/null +++ b/plugin/src/main/java/net/aufdemrand/denizen/objects/properties/item/ItemCanDestroy.java @@ -0,0 +1,121 @@ +package net.aufdemrand.denizen.objects.properties.item; + +import net.aufdemrand.denizen.objects.dItem; +import net.aufdemrand.denizen.objects.dMaterial; +import net.aufdemrand.denizen.utilities.debugging.dB; +import net.aufdemrand.denizen.utilities.nbt.CustomNBT; +import net.aufdemrand.denizencore.objects.Mechanism; +import net.aufdemrand.denizencore.objects.dList; +import net.aufdemrand.denizencore.objects.dObject; +import net.aufdemrand.denizencore.objects.properties.Property; +import net.aufdemrand.denizencore.tags.Attribute; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import java.util.List; +import java.util.stream.Collectors; + +public class ItemCanDestroy implements Property { + + public static boolean describes(dObject item) { + return item instanceof dItem; + } + + public static ItemCanDestroy getFrom(dObject item) { + if (!describes(item)) { + return null; + } + else { + return new ItemCanDestroy((dItem) item); + } + } + + private ItemCanDestroy(dItem item) { + this.item = item; + } + + dItem item; + + private dList getMaterials() { + ItemStack itemStack = item.getItemStack(); + List materials = CustomNBT.getNBTMaterials(itemStack, CustomNBT.KEY_CAN_DESTROY); + if (materials != null && !materials.isEmpty()) { + dList list = new dList(); + for (Material material : materials) { + list.addObject(dMaterial.getMaterialFrom(material)); + } + return list; + } + return null; + } + + @Override + public String getAttribute(Attribute attribute) { + + if (attribute == null) { + return null; + } + + // <--[tag] + // @attribute + // @returns dList(dMaterial) + // @group properties + // @mechanism dItem.can_destroy + // @description + // Returns a list of materials this item can destroy while in adventure mode, if any. + // --> + if (attribute.startsWith("can_destroy")) { + dList materials = getMaterials(); + if (materials != null) { + return materials.getAttribute(attribute.fulfill(1)); + } + } + + return null; + } + + @Override + public String getPropertyString() { + dList materials = getMaterials(); + return materials != null ? materials.identify() : null; + } + + @Override + public String getPropertyId() { + return "can_destroy"; + } + + @Override + public void adjust(Mechanism mechanism) { + + // <--[mechanism] + // @object dItem + // @name can_destroy + // @input dList(dMaterial) + // @description + // Sets the materials this item can destroy while in adventure mode. + // Leave empty to remove this property. + // @tags + // + // --> + if (mechanism.matches("can_destroy")) { + if (item.getMaterial().getMaterial() == Material.AIR) { + dB.echoError("Cannot apply NBT to AIR!"); + return; + } + + ItemStack itemStack = item.getItemStack(); + + if (mechanism.hasValue()) { + List materials = mechanism.getValue().asType(dList.class).filter(dMaterial.class) + .stream().map(dMaterial::getMaterial).collect(Collectors.toList()); + itemStack = CustomNBT.setNBTMaterials(itemStack, CustomNBT.KEY_CAN_DESTROY, materials); + } + else { + itemStack = CustomNBT.clearNBT(itemStack, CustomNBT.KEY_CAN_DESTROY); + } + + item.setItemStack(itemStack); + } + } +} diff --git a/plugin/src/main/java/net/aufdemrand/denizen/objects/properties/item/ItemCanPlaceOn.java b/plugin/src/main/java/net/aufdemrand/denizen/objects/properties/item/ItemCanPlaceOn.java new file mode 100644 index 0000000000..f248e5841f --- /dev/null +++ b/plugin/src/main/java/net/aufdemrand/denizen/objects/properties/item/ItemCanPlaceOn.java @@ -0,0 +1,121 @@ +package net.aufdemrand.denizen.objects.properties.item; + +import net.aufdemrand.denizen.objects.dItem; +import net.aufdemrand.denizen.objects.dMaterial; +import net.aufdemrand.denizen.utilities.debugging.dB; +import net.aufdemrand.denizen.utilities.nbt.CustomNBT; +import net.aufdemrand.denizencore.objects.Mechanism; +import net.aufdemrand.denizencore.objects.dList; +import net.aufdemrand.denizencore.objects.dObject; +import net.aufdemrand.denizencore.objects.properties.Property; +import net.aufdemrand.denizencore.tags.Attribute; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import java.util.List; +import java.util.stream.Collectors; + +public class ItemCanPlaceOn implements Property { + + public static boolean describes(dObject item) { + return item instanceof dItem; + } + + public static ItemCanPlaceOn getFrom(dObject item) { + if (!describes(item)) { + return null; + } + else { + return new ItemCanPlaceOn((dItem) item); + } + } + + private ItemCanPlaceOn(dItem item) { + this.item = item; + } + + dItem item; + + private dList getMaterials() { + ItemStack itemStack = item.getItemStack(); + List materials = CustomNBT.getNBTMaterials(itemStack, CustomNBT.KEY_CAN_PLACE_ON); + if (materials != null && !materials.isEmpty()) { + dList list = new dList(); + for (Material material : materials) { + list.addObject(dMaterial.getMaterialFrom(material)); + } + return list; + } + return null; + } + + @Override + public String getAttribute(Attribute attribute) { + + if (attribute == null) { + return null; + } + + // <--[tag] + // @attribute + // @returns dList(dMaterial) + // @group properties + // @mechanism dItem.can_place_on + // @description + // Returns a list of materials this item can be placed on while in adventure mode, if any. + // --> + if (attribute.startsWith("can_place_on")) { + dList materials = getMaterials(); + if (materials != null) { + return materials.getAttribute(attribute.fulfill(1)); + } + } + + return null; + } + + @Override + public String getPropertyString() { + dList materials = getMaterials(); + return materials != null ? materials.identify() : null; + } + + @Override + public String getPropertyId() { + return "can_place_on"; + } + + @Override + public void adjust(Mechanism mechanism) { + + // <--[mechanism] + // @object dItem + // @name can_place_on + // @input dList(dMaterial) + // @description + // Sets the materials this item can be placed on while in adventure mode. + // Leave empty to remove this property. + // @tags + // + // --> + if (mechanism.matches("can_place_on")) { + if (item.getMaterial().getMaterial() == Material.AIR) { + dB.echoError("Cannot apply NBT to AIR!"); + return; + } + + ItemStack itemStack = item.getItemStack(); + + if (mechanism.hasValue()) { + List materials = mechanism.getValue().asType(dList.class).filter(dMaterial.class) + .stream().map(dMaterial::getMaterial).collect(Collectors.toList()); + itemStack = CustomNBT.setNBTMaterials(itemStack, CustomNBT.KEY_CAN_PLACE_ON, materials); + } + else { + itemStack = CustomNBT.clearNBT(itemStack, CustomNBT.KEY_CAN_PLACE_ON); + } + + item.setItemStack(itemStack); + } + } +} diff --git a/plugin/src/main/java/net/aufdemrand/denizen/utilities/nbt/CustomNBT.java b/plugin/src/main/java/net/aufdemrand/denizen/utilities/nbt/CustomNBT.java index 8e3c501146..d43a546074 100644 --- a/plugin/src/main/java/net/aufdemrand/denizen/utilities/nbt/CustomNBT.java +++ b/plugin/src/main/java/net/aufdemrand/denizen/utilities/nbt/CustomNBT.java @@ -1,26 +1,43 @@ package net.aufdemrand.denizen.utilities.nbt; import net.aufdemrand.denizen.nms.NMSHandler; +import net.aufdemrand.denizen.nms.NMSVersion; import net.aufdemrand.denizen.nms.util.jnbt.*; +import net.aufdemrand.denizen.objects.properties.entity.EntityDisabledSlots.Action; import net.aufdemrand.denizencore.utilities.CoreUtilities; import org.bukkit.Material; import org.bukkit.entity.Entity; +import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; +import java.util.*; public class CustomNBT { public static final String KEY_DENIZEN = "Denizen NBT"; - public static final String KEY_ATTRIBUTES = "AttributeModifiers"; + public static final String KEY_CAN_PLACE_ON = "CanPlaceOn"; + public static final String KEY_CAN_DESTROY = "CanDestroy"; + public static final String KEY_DISABLED_SLOTS = "DisabledSlots"; public static MapOfEnchantments getEnchantments(ItemStack item) { return new MapOfEnchantments(item); } + private static final Map slotMap; + + static { + slotMap = new HashMap<>(); + slotMap.put(EquipmentSlot.HAND, 0); + slotMap.put(EquipmentSlot.FEET, 1); + slotMap.put(EquipmentSlot.LEGS, 2); + slotMap.put(EquipmentSlot.CHEST, 3); + slotMap.put(EquipmentSlot.HEAD, 4); + if (NMSHandler.getVersion().isAtLeast(NMSVersion.v1_9_R2)) { + slotMap.put(EquipmentSlot.OFF_HAND, 5); + } + } + /* * Some static methods for dealing with Minecraft NBT data, which is used to store * custom NBT. @@ -145,6 +162,47 @@ public static ItemStack addAttribute(ItemStack itemStack, String attr, String sl return NMSHandler.getInstance().getItemHelper().setNbtData(itemStack, compoundTag); } + public static List getNBTMaterials(ItemStack itemStack, String key) { + if (itemStack == null || itemStack.getType() == Material.AIR) { + return null; + } + + CompoundTag compoundTag = NMSHandler.getInstance().getItemHelper().getNbtData(itemStack); + + List materials = new ArrayList<>(); + if (compoundTag.getValue().containsKey(key)) { + List temp = (List) compoundTag.getValue().get(key).getValue(); + for (StringTag tag : temp) { + materials.add(NMSHandler.getInstance().getItemHelper().getMaterialFromInternalName(tag.getValue())); + } + } + + return materials; + } + + public static ItemStack setNBTMaterials(ItemStack itemStack, String key, List materials) { + if (itemStack == null || itemStack.getType() == Material.AIR) { + return null; + } + + CompoundTag compoundTag = NMSHandler.getInstance().getItemHelper().getNbtData(itemStack); + compoundTag = compoundTag.createBuilder().remove(key).build(); + + if (materials.isEmpty()) { + return NMSHandler.getInstance().getItemHelper().setNbtData(itemStack, compoundTag); + } + + List internalMaterials = new ArrayList<>(); + for (Material material : materials) { + internalMaterials.add(new StringTag(NMSHandler.getInstance().getItemHelper().getInternalNameFromMaterial(material))); + } + + ListTag lt = new ListTag(StringTag.class, internalMaterials); + compoundTag = compoundTag.createBuilder().put(key, lt).build(); + + return NMSHandler.getInstance().getItemHelper().setNbtData(itemStack, compoundTag); + } + public static ItemStack addCustomNBT(ItemStack itemStack, String key, String value, String basekey) { if (itemStack == null || itemStack.getType() == Material.AIR) { return null; @@ -168,13 +226,13 @@ public static ItemStack addCustomNBT(ItemStack itemStack, String key, String val return NMSHandler.getInstance().getItemHelper().setNbtData(itemStack, compoundTag); } - public static ItemStack clearAttributes(ItemStack itemStack) { + public static ItemStack clearNBT(ItemStack itemStack, String key) { if (itemStack == null || itemStack.getType() == Material.AIR) { return null; } CompoundTag compoundTag = NMSHandler.getInstance().getItemHelper().getNbtData(itemStack); - compoundTag = compoundTag.createBuilder().remove(KEY_ATTRIBUTES).build(); + compoundTag = compoundTag.createBuilder().remove(key).build(); // Write tag back return NMSHandler.getInstance().getItemHelper().setNbtData(itemStack, compoundTag); @@ -252,9 +310,9 @@ public static List listNBT(ItemStack itemStack, String basekey) { return nbt; } - public static Entity addCustomNBT(Entity entity, String key, String value) { + public static void addCustomNBT(Entity entity, String key, String value) { if (entity == null) { - return null; + return; } CompoundTag compoundTag = NMSHandler.getInstance().getEntityHelper().getNbtData(entity); @@ -263,12 +321,24 @@ public static Entity addCustomNBT(Entity entity, String key, String value) { // Write tag back NMSHandler.getInstance().getEntityHelper().setNbtData(entity, compoundTag); - return entity; } - public static Entity removeCustomNBT(Entity entity, String key) { + public static void addCustomNBT(Entity entity, String key, int value) { if (entity == null) { - return null; + return; + } + CompoundTag compoundTag = NMSHandler.getInstance().getEntityHelper().getNbtData(entity); + + // Add custom NBT + compoundTag = compoundTag.createBuilder().putInt(key, value).build(); + + // Write tag back + NMSHandler.getInstance().getEntityHelper().setNbtData(entity, compoundTag); + } + + public static void removeCustomNBT(Entity entity, String key) { + if (entity == null) { + return; } CompoundTag compoundTag = NMSHandler.getInstance().getEntityHelper().getNbtData(entity); @@ -277,7 +347,6 @@ public static Entity removeCustomNBT(Entity entity, String key) { // Write tag back NMSHandler.getInstance().getEntityHelper().setNbtData(entity, compoundTag); - return entity; } public static boolean hasCustomNBT(Entity entity, String key) { @@ -299,6 +368,62 @@ public static String getCustomNBT(Entity entity, String key) { // Return contents of the tag return compoundTag.getString(key); } + + public static int getCustomIntNBT(Entity entity, String key) { + if (entity == null) { + return 0; + } + CompoundTag compoundTag = NMSHandler.getInstance().getEntityHelper().getNbtData(entity); + + // Return contents of the tag + return compoundTag.getInt(key); + } + + public static void setDisabledSlots(Entity entity, Map> map) { + int sum = 0; + for (Map.Entry> entry : map.entrySet()) { + if (!slotMap.containsKey(entry.getKey())) continue; + for (Action action : entry.getValue()) { + sum += 1 << (slotMap.get(entry.getKey()) + action.getId()); + } + } + addCustomNBT(entity, KEY_DISABLED_SLOTS, sum); + } + + public static Map> getDisabledSlots(Entity entity) { + if (entity == null) { + return null; + } + + Map> map = new HashMap>(); + CompoundTag compoundTag = NMSHandler.getInstance().getEntityHelper().getNbtData(entity); + int disabledSlots = compoundTag.getInt(KEY_DISABLED_SLOTS); + + if (disabledSlots == 0) { + return map; + } + + slotLoop: + for (EquipmentSlot slot : slotMap.keySet()) { + for (Action action : Action.values()) { + int matchedSlot = disabledSlots & 1 << slotMap.get(slot) + action.getId(); + + if (matchedSlot != 0) { + Set set = map.get(slot); + if (set == null) { + set = new HashSet(); + map.put(slot, set); + } + set.add(action); + + disabledSlots -= matchedSlot; + if (disabledSlots == 0) break slotLoop; + } + } + } + + return map; + } } diff --git a/pom.xml b/pom.xml index 6b44191eb8..96dfac863d 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ org.apache.maven.plugins maven-compiler-plugin - 2.5.1 + 3.8.0 1.8 1.8 diff --git a/v1_10_R1/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_10_R1.java b/v1_10_R1/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_10_R1.java index 92f765f318..f8d4145e9c 100644 --- a/v1_10_R1/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_10_R1.java +++ b/v1_10_R1/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_10_R1.java @@ -11,6 +11,8 @@ import net.aufdemrand.denizen.nms.util.jnbt.*; import net.minecraft.server.v1_10_R1.GameProfileSerializer; import net.minecraft.server.v1_10_R1.NBTTagCompound; +import org.bukkit.Bukkit; +import org.bukkit.Material; import org.bukkit.craftbukkit.v1_10_R1.inventory.CraftItemStack; import org.bukkit.inventory.ItemStack; @@ -23,8 +25,13 @@ public class ItemHelper_v1_10_R1 implements ItemHelper { @Override - public String getVanillaName(ItemStack itemStack) { - return CraftItemStack.asNMSCopy(itemStack).save(new NBTTagCompound()).getString("id"); + public String getInternalNameFromMaterial(Material material) { + return CraftItemStack.asNMSCopy(new ItemStack(material)).save(new NBTTagCompound()).getString("id"); + } + + @Override + public Material getMaterialFromInternalName(String internalName) { + return Bukkit.getUnsafe().getMaterialFromInternalName(internalName); } @Override diff --git a/v1_11_R1/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_11_R1.java b/v1_11_R1/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_11_R1.java index 6c9d18d973..502b374a87 100644 --- a/v1_11_R1/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_11_R1.java +++ b/v1_11_R1/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_11_R1.java @@ -11,6 +11,8 @@ import net.aufdemrand.denizen.nms.util.jnbt.*; import net.minecraft.server.v1_11_R1.GameProfileSerializer; import net.minecraft.server.v1_11_R1.NBTTagCompound; +import org.bukkit.Bukkit; +import org.bukkit.Material; import org.bukkit.craftbukkit.v1_11_R1.inventory.CraftItemStack; import org.bukkit.inventory.ItemStack; @@ -23,8 +25,13 @@ public class ItemHelper_v1_11_R1 implements ItemHelper { @Override - public String getVanillaName(ItemStack itemStack) { - return CraftItemStack.asNMSCopy(itemStack).save(new NBTTagCompound()).getString("id"); + public String getInternalNameFromMaterial(Material material) { + return CraftItemStack.asNMSCopy(new ItemStack(material)).save(new NBTTagCompound()).getString("id"); + } + + @Override + public Material getMaterialFromInternalName(String internalName) { + return Bukkit.getUnsafe().getMaterialFromInternalName(internalName); } @Override diff --git a/v1_12_R1/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_12_R1.java b/v1_12_R1/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_12_R1.java index 90b9be9219..28b3079d95 100644 --- a/v1_12_R1/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_12_R1.java +++ b/v1_12_R1/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_12_R1.java @@ -11,6 +11,8 @@ import net.aufdemrand.denizen.nms.util.jnbt.*; import net.minecraft.server.v1_12_R1.GameProfileSerializer; import net.minecraft.server.v1_12_R1.NBTTagCompound; +import org.bukkit.Bukkit; +import org.bukkit.Material; import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack; import org.bukkit.inventory.ItemStack; @@ -23,8 +25,13 @@ public class ItemHelper_v1_12_R1 implements ItemHelper { @Override - public String getVanillaName(ItemStack itemStack) { - return CraftItemStack.asNMSCopy(itemStack).save(new NBTTagCompound()).getString("id"); + public String getInternalNameFromMaterial(Material material) { + return CraftItemStack.asNMSCopy(new ItemStack(material)).save(new NBTTagCompound()).getString("id"); + } + + @Override + public Material getMaterialFromInternalName(String internalName) { + return Bukkit.getUnsafe().getMaterialFromInternalName(internalName); } @Override diff --git a/v1_13_R2/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_13_R2.java b/v1_13_R2/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_13_R2.java index e009170652..a8850a839f 100644 --- a/v1_13_R2/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_13_R2.java +++ b/v1_13_R2/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_13_R2.java @@ -9,8 +9,10 @@ import net.aufdemrand.denizen.nms.util.EntityAttributeModifier; import net.aufdemrand.denizen.nms.util.PlayerProfile; import net.aufdemrand.denizen.nms.util.jnbt.*; +import net.aufdemrand.denizencore.utilities.CoreUtilities; import net.minecraft.server.v1_13_R2.GameProfileSerializer; import net.minecraft.server.v1_13_R2.NBTTagCompound; +import org.bukkit.Material; import org.bukkit.craftbukkit.v1_13_R2.inventory.CraftItemStack; import org.bukkit.inventory.ItemStack; @@ -23,8 +25,14 @@ public class ItemHelper_v1_13_R2 implements ItemHelper { @Override - public String getVanillaName(ItemStack itemStack) { - return CraftItemStack.asNMSCopy(itemStack).save(new NBTTagCompound()).getString("id"); + public String getInternalNameFromMaterial(Material material) { + // In 1.13+ Material names match their internal name + return "minecraft:" + CoreUtilities.toLowerCase(material.name()); + } + + @Override + public Material getMaterialFromInternalName(String internalName) { + return Material.matchMaterial(internalName); } @Override diff --git a/v1_8_R3/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_8_R3.java b/v1_8_R3/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_8_R3.java index a5539951ad..7f27a79e90 100644 --- a/v1_8_R3/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_8_R3.java +++ b/v1_8_R3/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_8_R3.java @@ -11,6 +11,8 @@ import net.aufdemrand.denizen.nms.util.jnbt.*; import net.minecraft.server.v1_8_R3.GameProfileSerializer; import net.minecraft.server.v1_8_R3.NBTTagCompound; +import org.bukkit.Bukkit; +import org.bukkit.Material; import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack; import org.bukkit.inventory.ItemStack; @@ -23,8 +25,13 @@ public class ItemHelper_v1_8_R3 implements ItemHelper { @Override - public String getVanillaName(ItemStack itemStack) { - return CraftItemStack.asNMSCopy(itemStack).save(new NBTTagCompound()).getString("id"); + public String getInternalNameFromMaterial(Material material) { + return CraftItemStack.asNMSCopy(new ItemStack(material)).save(new NBTTagCompound()).getString("id"); + } + + @Override + public Material getMaterialFromInternalName(String internalName) { + return Bukkit.getUnsafe().getMaterialFromInternalName(internalName); } @Override diff --git a/v1_9_R2/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_9_R2.java b/v1_9_R2/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_9_R2.java index e7c675e443..aeb40a377d 100644 --- a/v1_9_R2/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_9_R2.java +++ b/v1_9_R2/src/main/java/net/aufdemrand/denizen/nms/helpers/ItemHelper_v1_9_R2.java @@ -11,6 +11,8 @@ import net.aufdemrand.denizen.nms.util.jnbt.*; import net.minecraft.server.v1_9_R2.GameProfileSerializer; import net.minecraft.server.v1_9_R2.NBTTagCompound; +import org.bukkit.Bukkit; +import org.bukkit.Material; import org.bukkit.craftbukkit.v1_9_R2.inventory.CraftItemStack; import org.bukkit.inventory.ItemStack; @@ -23,8 +25,13 @@ public class ItemHelper_v1_9_R2 implements ItemHelper { @Override - public String getVanillaName(ItemStack itemStack) { - return CraftItemStack.asNMSCopy(itemStack).save(new NBTTagCompound()).getString("id"); + public String getInternalNameFromMaterial(Material material) { + return CraftItemStack.asNMSCopy(new ItemStack(material)).save(new NBTTagCompound()).getString("id"); + } + + @Override + public Material getMaterialFromInternalName(String internalName) { + return Bukkit.getUnsafe().getMaterialFromInternalName(internalName); } @Override