From 8f62e0fb3158817d412ee7f6aa901c00b0966623 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Sun, 13 Apr 2025 11:41:59 +0200 Subject: [PATCH] Correctly order getArmorContents Mojangs EQUIPMENT_SLOT_MAPPING uses an Int2ObjectArrayMap and hence technically does provide iteration stability, however it is filled from a MapN, which destroys the well order of the entries. To iterate from smallest to largest inventory index correctly, this commit introduces a sorted array based on the EQUIPMENT_SLOT_MAPPING. --- ...rove-exact-choice-recipe-ingredients.patch | 4 ++-- .../world/entity/player/Inventory.java.patch | 24 +++++++++++-------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/paper-server/patches/features/0019-Improve-exact-choice-recipe-ingredients.patch b/paper-server/patches/features/0019-Improve-exact-choice-recipe-ingredients.patch index 28472a8e3..733a8ab4d 100644 --- a/paper-server/patches/features/0019-Improve-exact-choice-recipe-ingredients.patch +++ b/paper-server/patches/features/0019-Improve-exact-choice-recipe-ingredients.patch @@ -204,10 +204,10 @@ index 6d3e3ec045d5b15a435f7217369968b33e082724..b7a3758af337270737041f84d10eb437 int i = this.inventory.findSlotMatchingCraftingIngredient(item, item1); if (i == -1) { diff --git a/net/minecraft/world/entity/player/Inventory.java b/net/minecraft/world/entity/player/Inventory.java -index 24d32c0163d27a7886bd4048d508591b89f714a4..dd406c5becacbc2d05b062726a8af88a1d6faba9 100644 +index e25e0bd410f8822cb9a1118b39a786f44aabef7b..d9cb4f0ed0c4f63362c837aeef3c4194911455c9 100644 --- a/net/minecraft/world/entity/player/Inventory.java +++ b/net/minecraft/world/entity/player/Inventory.java -@@ -230,12 +230,12 @@ public class Inventory implements Container, Nameable { +@@ -234,12 +234,12 @@ public class Inventory implements Container, Nameable { return !stack.isDamaged() && !stack.isEnchanted() && !stack.has(DataComponents.CUSTOM_NAME); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/player/Inventory.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/player/Inventory.java.patch index fe6d389be..7cc58e6e4 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/player/Inventory.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/player/Inventory.java.patch @@ -1,10 +1,14 @@ --- a/net/minecraft/world/entity/player/Inventory.java +++ b/net/minecraft/world/entity/player/Inventory.java -@@ -49,6 +_,66 @@ +@@ -49,6 +_,70 @@ public final Player player; public final EntityEquipment equipment; private int timesChanged; -+ // CraftBukkit start - add fields and methods ++ // Paper start - add fields and methods ++ public static final EquipmentSlot[] EQUIPMENT_SLOTS_SORTED_BY_INDEX = EQUIPMENT_SLOT_MAPPING.int2ObjectEntrySet() ++ .stream() ++ .sorted(java.util.Comparator.comparingInt(it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry::getIntKey)) ++ .map(java.util.Map.Entry::getValue).toArray(EquipmentSlot[]::new); + public java.util.List transaction = new java.util.ArrayList<>(); + private int maxStack = MAX_STACK; + @@ -12,20 +16,20 @@ + public java.util.List getContents() { + java.util.List combined = new java.util.ArrayList<>(this.items.size() + EQUIPMENT_SLOT_MAPPING.size()); + combined.addAll(this.items); -+ EQUIPMENT_SLOT_MAPPING.int2ObjectEntrySet().forEach(entry -> { -+ ItemStack itemStack = this.equipment.get(entry.getValue()); ++ for (EquipmentSlot equipmentSlot : EQUIPMENT_SLOTS_SORTED_BY_INDEX) { ++ ItemStack itemStack = this.equipment.get(equipmentSlot); + combined.add(itemStack); // Include empty items -+ }); ++ }; + return combined; + } + + public java.util.List getArmorContents() { + java.util.List items = new java.util.ArrayList<>(); -+ EQUIPMENT_SLOT_MAPPING.int2ObjectEntrySet().forEach(entry -> { -+ if (entry.getValue().isArmor()) { -+ items.add(this.equipment.get(entry.getValue())); ++ for (EquipmentSlot equipmentSlot : EQUIPMENT_SLOTS_SORTED_BY_INDEX) { ++ if (equipmentSlot.isArmor()) { ++ items.add(this.equipment.get(equipmentSlot)); + } -+ }); ++ } + return items; + } + @@ -63,7 +67,7 @@ + public org.bukkit.Location getLocation() { + return this.player.getBukkitEntity().getLocation(); + } -+ // CraftBukkit end ++ // Paper end - add fields and methods public Inventory(Player player, EntityEquipment equipment) { this.player = player;