From 3438e96192ddca2d8cf5a483ed3b1347c32ac503 Mon Sep 17 00:00:00 2001 From: pkt77 Date: Fri, 10 Nov 2017 23:46:55 -0500 Subject: [PATCH] Add PlayerArmorChangeEvent Closes GH-928 --- .../0072-Add-PlayerArmorChangeEvent.patch | 150 ++++++++++++++++++ .../0250-Add-PlayerArmorChangeEvent.patch | 34 ++++ 2 files changed, 184 insertions(+) create mode 100644 Spigot-API-Patches/0072-Add-PlayerArmorChangeEvent.patch create mode 100644 Spigot-Server-Patches/0250-Add-PlayerArmorChangeEvent.patch diff --git a/Spigot-API-Patches/0072-Add-PlayerArmorChangeEvent.patch b/Spigot-API-Patches/0072-Add-PlayerArmorChangeEvent.patch new file mode 100644 index 0000000000..11eaa4f6a5 --- /dev/null +++ b/Spigot-API-Patches/0072-Add-PlayerArmorChangeEvent.patch @@ -0,0 +1,150 @@ +From feabeac37f30a2a99bbf59e58386a2585aabe8e2 Mon Sep 17 00:00:00 2001 +From: pkt77 +Date: Fri, 10 Nov 2017 23:45:59 -0500 +Subject: [PATCH] Add PlayerArmorChangeEvent + + +diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerArmorChangeEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerArmorChangeEvent.java +new file mode 100644 +index 00000000..9d56a9e7 +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerArmorChangeEvent.java +@@ -0,0 +1,135 @@ ++package com.destroystokyo.paper.event.player; ++ ++import org.bukkit.Material; ++import org.bukkit.entity.Player; ++import org.bukkit.event.HandlerList; ++import org.bukkit.event.player.PlayerEvent; ++import org.bukkit.inventory.ItemStack; ++ ++import javax.annotation.Nonnull; ++import javax.annotation.Nullable; ++import java.util.Arrays; ++import java.util.Collections; ++import java.util.HashSet; ++import java.util.Set; ++ ++import static org.bukkit.Material.*; ++ ++/** ++ * Called when the player themselves change their armor items ++ *

++ * Not currently called for environmental factors though it MAY BE IN THE FUTURE ++ */ ++public class PlayerArmorChangeEvent extends PlayerEvent { ++ private static final HandlerList HANDLERS = new HandlerList(); ++ ++ private final SlotType slotType; ++ private final ItemStack oldItem; ++ private final ItemStack newItem; ++ ++ public PlayerArmorChangeEvent(Player player, SlotType slotType, ItemStack oldItem, ItemStack newItem) { ++ super(player); ++ this.slotType = slotType; ++ this.oldItem = oldItem; ++ this.newItem = newItem; ++ } ++ ++ /** ++ * Gets the type of slot being altered. ++ * ++ * @return type of slot being altered ++ */ ++ @Nonnull ++ public SlotType getSlotType() { ++ return this.slotType; ++ } ++ ++ /** ++ * Gets the existing item that's being replaced ++ * ++ * @return old item ++ */ ++ @Nullable ++ public ItemStack getOldItem() { ++ return this.oldItem; ++ } ++ ++ /** ++ * Gets the new item that's replacing the old ++ * ++ * @return new item ++ */ ++ @Nullable ++ public ItemStack getNewItem() { ++ return this.newItem; ++ } ++ ++ @Override ++ public String toString() { ++ return "ArmorChangeEvent{" + "player=" + player + ", slotType=" + slotType + ", oldItem=" + oldItem + ", newItem=" + newItem + '}'; ++ } ++ ++ @Override ++ public HandlerList getHandlers() { ++ return HANDLERS; ++ } ++ ++ public static HandlerList getHandlerList() { ++ return HANDLERS; ++ } ++ ++ public enum SlotType { ++ HEAD(DIAMOND_HELMET, GOLD_HELMET, IRON_HELMET, CHAINMAIL_HELMET, LEATHER_HELMET, PUMPKIN, JACK_O_LANTERN), ++ CHEST(DIAMOND_CHESTPLATE, GOLD_CHESTPLATE, IRON_CHESTPLATE, CHAINMAIL_CHESTPLATE, LEATHER_CHESTPLATE, ELYTRA), ++ LEGS(DIAMOND_LEGGINGS, GOLD_LEGGINGS, IRON_LEGGINGS, CHAINMAIL_LEGGINGS, LEATHER_LEGGINGS), ++ FEET(DIAMOND_BOOTS, GOLD_BOOTS, IRON_BOOTS, CHAINMAIL_BOOTS, LEATHER_BOOTS); ++ ++ private final Set mutableTypes = new HashSet<>(); ++ private Set immutableTypes; ++ ++ SlotType(Material... types) { ++ this.mutableTypes.addAll(Arrays.asList(types)); ++ } ++ ++ /** ++ * Gets an immutable set of all allowed material types that can be placed in an ++ * armor slot. ++ * ++ * @return immutable set of material types ++ */ ++ @Nonnull ++ public Set getTypes() { ++ if (immutableTypes == null) { ++ immutableTypes = Collections.unmodifiableSet(mutableTypes); ++ } ++ ++ return immutableTypes; ++ } ++ ++ /** ++ * Gets the type of slot via the specified material ++ * ++ * @param material material to get slot by ++ * @return slot type the material will go in, or null if it won't ++ */ ++ @Nullable ++ public static SlotType getByMaterial(Material material) { ++ for (SlotType slotType : values()) { ++ if (slotType.getTypes().contains(material)) { ++ return slotType; ++ } ++ } ++ return null; ++ } ++ ++ /** ++ * Gets whether or not this material can be equipped to a slot ++ * ++ * @param material material to check ++ * @return whether or not this material can be equipped ++ */ ++ public static boolean isEquipable(Material material) { ++ return getByMaterial(material) != null; ++ } ++ } ++} +-- +2.14.2 + diff --git a/Spigot-Server-Patches/0250-Add-PlayerArmorChangeEvent.patch b/Spigot-Server-Patches/0250-Add-PlayerArmorChangeEvent.patch new file mode 100644 index 0000000000..62f728e073 --- /dev/null +++ b/Spigot-Server-Patches/0250-Add-PlayerArmorChangeEvent.patch @@ -0,0 +1,34 @@ +From e2873d6dbc62fb4bfa94eb918e83c606937d95ae Mon Sep 17 00:00:00 2001 +From: pkt77 +Date: Fri, 10 Nov 2017 23:46:34 -0500 +Subject: [PATCH] Add PlayerArmorChangeEvent + + +diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java +index 135a9c0e..5e17d107 100644 +--- a/src/main/java/net/minecraft/server/EntityLiving.java ++++ b/src/main/java/net/minecraft/server/EntityLiving.java +@@ -1,5 +1,6 @@ + package net.minecraft.server; + ++import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent; + import com.google.common.base.Objects; + import com.google.common.collect.Maps; + import java.util.Collection; +@@ -1929,6 +1930,13 @@ public abstract class EntityLiving extends Entity { + ItemStack itemstack1 = this.getEquipment(enumitemslot); + + if (!ItemStack.matches(itemstack1, itemstack)) { ++ // Paper start - PlayerArmorChangeEvent ++ if (this instanceof EntityPlayer && enumitemslot.a() == EnumItemSlot.Function.ARMOR && !itemstack.getItem().equals(itemstack1.getItem())) { ++ final org.bukkit.inventory.ItemStack oldItem = CraftItemStack.asBukkitCopy(itemstack); ++ final org.bukkit.inventory.ItemStack newItem = CraftItemStack.asBukkitCopy(itemstack1); ++ new PlayerArmorChangeEvent((Player) this.getBukkitEntity(), PlayerArmorChangeEvent.SlotType.valueOf(enumitemslot.name()), oldItem, newItem).callEvent(); ++ } ++ // Paper end + ((WorldServer) this.world).getTracker().a((Entity) this, (Packet) (new PacketPlayOutEntityEquipment(this.getId(), enumitemslot, itemstack1))); + if (!itemstack.isEmpty()) { + this.getAttributeMap().a(itemstack.a(enumitemslot)); +-- +2.14.2 +