55import com .github .retrooper .packetevents .protocol .player .Equipment ;
66import com .github .retrooper .packetevents .protocol .player .EquipmentSlot ;
77import com .github .retrooper .packetevents .wrapper .play .server .WrapperPlayServerEntityEquipment ;
8+ import me .tofaa .entitylib .EntityLib ;
89import org .jetbrains .annotations .NotNull ;
910import org .jetbrains .annotations .Nullable ;
1011
@@ -21,8 +22,7 @@ public class WrapperEntityEquipment {
2122 private final WrapperLivingEntity entity ;
2223 private boolean notifyChanges = true ;
2324
24- // 0 = main hand, 1 = offhand, 2 = boots, 3 = leggings, 4 = chestplate, 5 = helmet
25- private final ItemStack [] equipment = new ItemStack [6 ];
25+ private final ItemStack [] equipment = new ItemStack [EQUIPMENT_SLOTS .length ];
2626
2727 public WrapperEntityEquipment (WrapperLivingEntity entity ) {
2828 this .entity = entity ;
@@ -41,37 +41,31 @@ public void clearAll() {
4141 }
4242
4343 public void setHelmet (@ Nullable ItemStack itemStack ) {
44- equipment [5 ] = itemStack == null ? ItemStack .EMPTY : itemStack ;
45- refresh ();
44+ setItem (EquipmentSlot .HELMET , itemStack );
4645 }
4746
4847 public void setChestplate (@ Nullable ItemStack itemStack ) {
49- equipment [4 ] = itemStack == null ? ItemStack .EMPTY : itemStack ;
50- refresh ();
48+ setItem (EquipmentSlot .CHEST_PLATE , itemStack );
5149 }
5250
5351 public void setLeggings (@ Nullable ItemStack itemStack ) {
54- equipment [3 ] = itemStack == null ? ItemStack .EMPTY : itemStack ;
55- refresh ();
52+ setItem (EquipmentSlot .LEGGINGS , itemStack );
5653 }
5754
5855 public void setBoots (@ Nullable ItemStack itemStack ) {
59- equipment [2 ] = itemStack == null ? ItemStack .EMPTY : itemStack ;
60- refresh ();
56+ setItem (EquipmentSlot .BOOTS , itemStack );
6157 }
6258
6359 public void setMainHand (@ Nullable ItemStack itemStack ) {
64- equipment [0 ] = itemStack == null ? ItemStack .EMPTY : itemStack ;
65- refresh ();
60+ setItem (EquipmentSlot .MAIN_HAND , itemStack );
6661 }
6762
6863 public void setOffhand (@ Nullable ItemStack itemStack ) {
69- equipment [1 ] = itemStack == null ? ItemStack .EMPTY : itemStack ;
70- refresh ();
64+ setItem (EquipmentSlot .OFF_HAND , itemStack );
7165 }
7266
7367 public void setItem (@ NotNull EquipmentSlot slot , @ Nullable ItemStack itemStack ) {
74- equipment [slot .ordinal ()] = itemStack == null ? ItemStack .EMPTY : itemStack ;
68+ equipment [slot .ordinal ()] = itemStack == null ? ItemStack .EMPTY : itemStack ;
7569 refresh ();
7670 }
7771
@@ -108,11 +102,45 @@ public void setItem(@NotNull EquipmentSlot slot, @Nullable ItemStack itemStack)
108102 return getItem (EquipmentSlot .OFF_HAND );
109103 }
110104
105+ /**
106+ * Whether the running server version knows the given equipment slot.
107+ *
108+ * @param slot the slot to check
109+ * @return true when the slot can be sent to a client of the server version
110+ */
111+ public static boolean isSlotSupported (@ NotNull EquipmentSlot slot ) {
112+ return isSlotSupported (slot , EntityLib .getApi ().getPacketEvents ().getServerManager ().getVersion ());
113+ }
114+
115+ /**
116+ * Whether the given server version knows the given equipment slot.
117+ * A slot travels in the equipment packet as its ordinal, so a slot that the version does not
118+ * have yet has no number a client of that version could map back to it.
119+ *
120+ * @param slot the slot to check
121+ * @param version the server version to check the slot against
122+ * @return true when the slot can be sent to a client of that version
123+ */
124+ public static boolean isSlotSupported (@ NotNull EquipmentSlot slot , @ NotNull ServerVersion version ) {
125+ switch (slot ) {
126+ case OFF_HAND :
127+ return version .isNewerThanOrEquals (ServerVersion .V_1_9 );
128+ case BODY :
129+ return version .isNewerThanOrEquals (ServerVersion .V_1_20_5 );
130+ case SADDLE :
131+ return version .isNewerThanOrEquals (ServerVersion .V_1_21_5 );
132+ default :
133+ return true ;
134+ }
135+ }
136+
111137 public WrapperPlayServerEntityEquipment createPacket () {
112- List <Equipment > equipment = new ArrayList <>();
138+ ServerVersion version = EntityLib .getApi ().getPacketEvents ().getServerManager ().getVersion ();
139+ List <Equipment > equipment = new ArrayList <>(this .equipment .length );
113140 for (int i = 0 ; i < this .equipment .length ; i ++) {
114- ItemStack itemStack = this .equipment [i ];
115- equipment .add (new Equipment (EQUIPMENT_SLOTS [i ], itemStack ));
141+ EquipmentSlot slot = EQUIPMENT_SLOTS [i ];
142+ if (!isSlotSupported (slot , version )) continue ;
143+ equipment .add (new Equipment (slot , this .equipment [i ]));
116144 }
117145 return new WrapperPlayServerEntityEquipment (
118146 entity .getEntityId (),
0 commit comments