fix: EquipmentSlot ordering was wrong for sending item components e.g. Equippable

This commit is contained in:
steank 2024-12-04 19:34:15 -08:00 committed by Matt Worzala
parent 13d74663f1
commit 0668be90c5
2 changed files with 38 additions and 10 deletions

View File

@ -2,23 +2,26 @@ package net.minestom.server.entity;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.nbt.BinaryTagSerializer;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import net.minestom.server.item.component.Equippable;
import net.minestom.server.network.packet.server.play.EntityEquipmentPacket;
import static net.minestom.server.utils.inventory.PlayerInventoryUtils.*;
public enum EquipmentSlot {
MAIN_HAND(false, -1, "mainhand"),
OFF_HAND(false, -1, "offhand"),
BOOTS(true, BOOTS_SLOT, "feet"),
LEGGINGS(true, LEGGINGS_SLOT, "legs"),
CHESTPLATE(true, CHESTPLATE_SLOT, "chest"),
HELMET(true, HELMET_SLOT, "head"),
BODY(false, -1, "body");
MAIN_HAND(false, -1, "mainhand", 0),
BOOTS(true, BOOTS_SLOT, "feet", 2),
LEGGINGS(true, LEGGINGS_SLOT, "legs", 3),
CHESTPLATE(true, CHESTPLATE_SLOT, "chest", 4),
HELMET(true, HELMET_SLOT, "head", 5),
OFF_HAND(false, -1, "offhand", 1),
BODY(false, -1, "body", 6);
private static final List<EquipmentSlot> ARMORS = List.of(BOOTS, LEGGINGS, CHESTPLATE, HELMET);
private static final Map<String, EquipmentSlot> BY_NBT_NAME = Arrays.stream(values())
@ -31,11 +34,13 @@ public enum EquipmentSlot {
private final boolean armor;
private final int armorSlot;
private final String nbtName;
private final int equipmentSlot;
EquipmentSlot(boolean armor, int armorSlot, String nbtName) {
EquipmentSlot(boolean armor, int armorSlot, String nbtName, int equipmentSlot) {
this.armor = armor;
this.armorSlot = armorSlot;
this.nbtName = nbtName;
this.equipmentSlot = equipmentSlot;
}
public boolean isHand() {
@ -46,6 +51,16 @@ public enum EquipmentSlot {
return armor;
}
/**
* Differs from the ordinal only slightly - the ordinal is used for sending components such as {@link Equippable},
* but this value needs to be used instead for {@link EntityEquipmentPacket}.
*
* @return the equipment slot
*/
public int equipmentSlot() {
return equipmentSlot;
}
public int armorSlot() {
return armorSlot;
}
@ -58,4 +73,17 @@ public enum EquipmentSlot {
return ARMORS;
}
@ApiStatus.Internal
public static @NotNull EquipmentSlot fromEquipmentSlot(int equipmentSlot) {
return switch (equipmentSlot) {
case 0 -> EquipmentSlot.MAIN_HAND;
case 1 -> EquipmentSlot.OFF_HAND;
case 2 -> EquipmentSlot.BOOTS;
case 3 -> EquipmentSlot.LEGGINGS;
case 4 -> EquipmentSlot.CHESTPLATE;
case 5 -> EquipmentSlot.HELMET;
case 6 -> EquipmentSlot.BODY;
default -> throw new IllegalStateException("Unexpected value: " + equipmentSlot);
};
}
}

View File

@ -28,7 +28,7 @@ public record EntityEquipmentPacket(int entityId,
int index = 0;
for (var entry : value.equipments.entrySet()) {
final boolean last = index++ == value.equipments.size() - 1;
byte slotEnum = (byte) entry.getKey().ordinal();
byte slotEnum = (byte) entry.getKey().equipmentSlot();
if (!last) slotEnum |= 0x80;
buffer.write(BYTE, slotEnum);
buffer.write(ItemStack.NETWORK_TYPE, entry.getValue());
@ -62,7 +62,7 @@ public record EntityEquipmentPacket(int entityId,
byte slot;
do {
slot = reader.read(BYTE);
equipments.put(EquipmentSlot.values()[slot & 0x7F], reader.read(ItemStack.NETWORK_TYPE));
equipments.put(EquipmentSlot.fromEquipmentSlot(slot & 0x7F), reader.read(ItemStack.NETWORK_TYPE));
} while ((slot & 0x80) == 0x80);
return equipments;
}