aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorBjarne Koll <[email protected]>2024-10-24 17:16:31 +0200
committerBjarne Koll <[email protected]>2024-10-24 17:20:12 +0200
commitfc0543071997267d28cf3c7c4c428d6762b78688 (patch)
treec34504e2360c17ff4f8fe3f36f4b0fa6c24a0760
parentb2375286c9615fa5fd01ac876d0d35d6d74959ce (diff)
downloadPaper-fc0543071997267d28cf3c7c4c428d6762b78688.tar.gz
Paper-fc0543071997267d28cf3c7c4c428d6762b78688.zip
963
-rw-r--r--patches/server/0954-General-ItemMeta-fixes.patch (renamed from patches/unapplied/server/0960-General-ItemMeta-fixes.patch)165
-rw-r--r--patches/server/0955-More-Chest-Block-API.patch (renamed from patches/unapplied/server/0963-More-Chest-Block-API.patch)10
-rw-r--r--patches/server/0956-Print-data-component-type-on-encoding-error.patch (renamed from patches/unapplied/server/0964-Print-data-component-type-on-encoding-error.patch)2
-rw-r--r--patches/server/0957-Brigadier-based-command-API.patch (renamed from patches/unapplied/server/0965-Brigadier-based-command-API.patch)106
-rw-r--r--patches/server/0958-Fix-issues-with-Recipe-API.patch94
-rw-r--r--patches/server/0959-Fix-equipment-slot-and-group-API.patch (renamed from patches/unapplied/server/0967-Fix-equipment-slot-and-group-API.patch)12
-rw-r--r--patches/server/0960-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch (renamed from patches/unapplied/server/0968-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch)0
-rw-r--r--patches/server/0961-Prevent-sending-oversized-item-data-in-equipment-and.patch (renamed from patches/unapplied/server/0969-Prevent-sending-oversized-item-data-in-equipment-and.patch)24
-rw-r--r--patches/server/0962-Prevent-NPE-if-hooked-entity-was-cleared.patch (renamed from patches/unapplied/server/0970-Prevent-NPE-if-hooked-entity-was-cleared.patch)4
-rw-r--r--patches/server/0963-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch (renamed from patches/unapplied/server/0971-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch)26
-rw-r--r--patches/server/0964-Add-missing-fishing-event-state.patch (renamed from patches/unapplied/server/0972-Add-missing-fishing-event-state.patch)4
-rw-r--r--patches/server/0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch (renamed from patches/unapplied/server/0973-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch)4
-rw-r--r--patches/server/0966-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch (renamed from patches/unapplied/server/0974-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch)0
-rw-r--r--patches/server/0967-Adopt-MaterialRerouting.patch (renamed from patches/unapplied/server/0975-Adopt-MaterialRerouting.patch)0
-rw-r--r--patches/server/0968-Suspicious-Effect-Entry-API.patch (renamed from patches/unapplied/server/0976-Suspicious-Effect-Entry-API.patch)4
-rw-r--r--patches/server/0969-check-if-itemstack-is-stackable-first.patch (renamed from patches/unapplied/server/0977-check-if-itemstack-is-stackable-first.patch)4
-rw-r--r--patches/server/0970-Fix-removing-recipes-from-RecipeIterator.patch (renamed from patches/unapplied/server/0978-Fix-removing-recipes-from-RecipeIterator.patch)4
-rw-r--r--patches/server/0971-Configurable-damage-tick-when-blocking-with-shield.patch (renamed from patches/unapplied/server/0979-Configurable-damage-tick-when-blocking-with-shield.patch)4
-rw-r--r--patches/server/0972-Properly-remove-the-experimental-smithing-inventory-.patch (renamed from patches/unapplied/server/0980-Properly-remove-the-experimental-smithing-inventory-.patch)0
-rw-r--r--patches/unapplied/server/0966-Fix-issues-with-Recipe-API.patch118
20 files changed, 260 insertions, 325 deletions
diff --git a/patches/unapplied/server/0960-General-ItemMeta-fixes.patch b/patches/server/0954-General-ItemMeta-fixes.patch
index d61cc57b53..70bbb2f9d4 100644
--- a/patches/unapplied/server/0960-General-ItemMeta-fixes.patch
+++ b/patches/server/0954-General-ItemMeta-fixes.patch
@@ -12,10 +12,10 @@ public net/minecraft/world/level/block/entity/BlockEntity saveId(Lnet/minecraft/
Co-authored-by: GhastCraftHD <[email protected]>
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
-index 256e5232425985502c0f9cb9258494555118687e..f09ef12023b1bbbf0c9c94487a705abda94db70b 100644
+index bba4fbde31ef25bc086fefaa86f9a479ef6ccf26..62529e61c8751433a8b6abe6cfb2cc414c8c3cf2 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
-@@ -1275,6 +1275,11 @@ public final class ItemStack implements DataComponentHolder {
+@@ -1356,6 +1356,11 @@ public final class ItemStack implements DataComponentHolder {
public void setItem(Item item) {
this.bukkitStack = null; // Paper
this.item = item;
@@ -28,13 +28,13 @@ index 256e5232425985502c0f9cb9258494555118687e..f09ef12023b1bbbf0c9c94487a705abd
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
-index 41f43d7d12a47563360f48a793e63db8cf92ac69..a1d7ae987327382d9566860b991dc361225c7938 100644
+index 63e234fb72952dcede4eeaa5d3d3390d137d88a2..b4aff394694417cff1930cf8fbd6696b9f9c9d01 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
@@ -152,6 +152,11 @@ public abstract class BlockEntity {
CompoundTag nbttagcompound = new CompoundTag();
- this.saveAdditional(nbttagcompound, registryLookup);
+ this.saveAdditional(nbttagcompound, registries);
+ // Paper start - store PDC here as well
+ if (this.persistentDataContainer != null && !this.persistentDataContainer.isEmpty()) {
+ nbttagcompound.put("PublicBukkitValues", this.persistentDataContainer.toTagCompound());
@@ -68,10 +68,10 @@ index fe7e3e0628783d8d1be9635b689da8a9cb46c5d7..04ae258a2f8e98421340d29d5cceedec
protected void load(T tileEntity) {
if (tileEntity != null && tileEntity != this.snapshot) {
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
-index 6a449bfc765bf427d82df4a90bc60471b5de2fd3..efb7fb8dbaa7446e394f55b021692c11a25fd29f 100644
+index dfdabf86433d323966a748baef769cf0462d3f38..bb2b4528692aed8e3341428697a60c0abee13779 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
-@@ -279,7 +279,9 @@ public final class CraftItemStack extends ItemStack {
+@@ -291,7 +291,9 @@ public final class CraftItemStack extends ItemStack {
@Override
public void removeEnchantments() {
@@ -82,7 +82,7 @@ index 6a449bfc765bf427d82df4a90bc60471b5de2fd3..efb7fb8dbaa7446e394f55b021692c11
}
@Override
-@@ -341,7 +343,14 @@ public final class CraftItemStack extends ItemStack {
+@@ -353,7 +355,14 @@ public final class CraftItemStack extends ItemStack {
// Paper end - improve handled tags on type change
// Paper start
public static void applyMetaToItem(net.minecraft.world.item.ItemStack itemStack, ItemMeta itemMeta) {
@@ -98,7 +98,7 @@ index 6a449bfc765bf427d82df4a90bc60471b5de2fd3..efb7fb8dbaa7446e394f55b021692c11
((CraftMetaItem) itemMeta).applyToItem(tag);
itemStack.applyComponents(tag.build());
}
-@@ -389,15 +398,20 @@ public final class CraftItemStack extends ItemStack {
+@@ -401,15 +410,20 @@ public final class CraftItemStack extends ItemStack {
if (itemMeta == null) return true;
if (!((CraftMetaItem) itemMeta).isEmpty()) {
@@ -577,7 +577,7 @@ index 2736a87a6c481da0575e6e29ea08faa539c24378..51da0db4da3549efd69f367e28450408
if (this.items == null) {
this.items = new ArrayList<>();
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java
-index 6517ec4933b0eae761fceb117ea1db175755d0b1..299f2f4f143f753f3cd8a020c8e6ae46298e0f6f 100644
+index dc6398cfbd6e749733c3a681e1eb8ce15c3b2c5e..51d7263cdd34359d9cdf72cc01ba654b519f838d 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java
@@ -11,16 +11,30 @@ import org.bukkit.inventory.meta.ColorableArmorMeta;
@@ -1049,10 +1049,10 @@ index 566d893a413fd04b99e83dc2da8fe958a48492a8..a944803771d514572f94b4e98a6d4435
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
-index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd2cde76f6 100644
+index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411fcb433c8c 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
-@@ -182,9 +182,10 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -199,9 +199,10 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
}
}
@@ -1065,16 +1065,16 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
<T> Applicator put(ItemMetaKeyType<T> key, T value) {
this.builder.set(key.TYPE, value);
-@@ -271,7 +272,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
- private CraftFoodComponent food;
+@@ -308,7 +309,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
private CraftToolComponent tool;
+ private CraftEquippableComponent equippable;
private CraftJukeboxComponent jukebox;
- private int damage;
+ private Integer damage; // Paper - may not be set
private Integer maxDamage;
private static final Set<DataComponentType> HANDLED_TAGS = Sets.newHashSet();
-@@ -303,7 +304,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -341,7 +342,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
this.enchantments = new EnchantmentMap(meta.enchantments); // Paper
}
@@ -1083,7 +1083,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
this.attributeModifiers = LinkedHashMultimap.create(meta.attributeModifiers);
}
-@@ -340,6 +341,11 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -390,6 +391,11 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
}
CraftMetaItem(DataComponentPatch tag, Set<DataComponentType<?>> extraHandledTags) { // Paper - improve handled tags on type changes
@@ -1095,7 +1095,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
CraftMetaItem.getOrEmpty(tag, CraftMetaItem.NAME).ifPresent((component) -> {
this.displayName = component;
});
-@@ -798,7 +804,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -906,7 +912,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
Map<?, ?> mods = SerializableMeta.getObject(Map.class, map, key.BUKKIT, true);
Multimap<Attribute, AttributeModifier> result = LinkedHashMultimap.create();
if (mods == null) {
@@ -1104,7 +1104,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
}
for (Object obj : mods.keySet()) {
-@@ -901,7 +907,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1037,7 +1043,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
itemTag.put(CraftMetaItem.JUKEBOX_PLAYABLE, this.jukebox.getHandle());
}
@@ -1113,7 +1113,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
itemTag.put(CraftMetaItem.DAMAGE, this.damage);
}
-@@ -951,7 +957,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1087,7 +1093,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
}
void applyEnchantments(Map<Enchantment, Integer> enchantments, CraftMetaItem.Applicator tag, ItemMetaKeyType<ItemEnchantments> key, ItemFlag itemFlag) {
@@ -1122,7 +1122,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
return;
}
-@@ -968,10 +974,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1104,10 +1110,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
}
void applyModifiers(Multimap<Attribute, AttributeModifier> modifiers, CraftMetaItem.Applicator tag) {
@@ -1135,16 +1135,16 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
return;
}
-@@ -1008,7 +1012,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1144,7 +1148,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
@Overridden
boolean isEmpty() {
-- return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.removedTags.isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasTool() || this.hasJukeboxPlayable() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null || this.canPlaceOnPredicates != null || this.canBreakPredicates != null); // Paper
-+ return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.removedTags.isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasTool() || this.hasJukeboxPlayable() || this.hasDamageValue() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null || this.canPlaceOnPredicates != null || this.canBreakPredicates != null); // Paper
+- return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasEnchantable() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.removedTags.isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.hasTooltipStyle() || this.hasItemModel() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isGlider() || this.hasDamageResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasUseRemainder() || this.hasUseCooldown() || this.hasFood() || this.hasTool() || this.hasJukeboxPlayable() || this.hasEquippable() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null || this.canPlaceOnPredicates != null || this.canBreakPredicates != null); // Paper
++ return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasEnchantable() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.removedTags.isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.hasTooltipStyle() || this.hasItemModel() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isGlider() || this.hasDamageResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasUseRemainder() || this.hasUseCooldown() || this.hasFood() || this.hasTool() || this.hasJukeboxPlayable() || this.hasEquippable() || this.hasDamageValue() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null || this.canPlaceOnPredicates != null || this.canBreakPredicates != null); // Paper
}
// Paper start
-@@ -1104,6 +1108,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1240,6 +1244,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
@Override
public void lore(final List<? extends net.kyori.adventure.text.Component> lore) {
@@ -1152,7 +1152,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
this.lore = lore != null ? io.papermc.paper.adventure.PaperAdventure.asVanilla(lore) : null;
}
// Paper end
-@@ -1162,7 +1167,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1298,7 +1303,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
@Override
public void removeEnchantments() {
if (this.hasEnchants()) {
@@ -1161,7 +1161,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
}
}
-@@ -1228,6 +1233,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1364,6 +1369,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
// Paper end
@Override
public void setLore(List<String> lore) {
@@ -1169,7 +1169,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
if (lore == null || lore.isEmpty()) {
this.lore = null;
} else {
-@@ -1243,6 +1249,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1379,6 +1385,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
// Paper start
@Override
public void setLoreComponents(List<net.md_5.bungee.api.chat.BaseComponent[]> lore) {
@@ -1177,16 +1177,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
if (lore == null) {
this.lore = null;
} else {
-@@ -1384,7 +1391,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
-
- @Override
- public FoodComponent getFood() {
-- return (this.hasFood()) ? new CraftFoodComponent(this.food) : new CraftFoodComponent(new FoodProperties(0, 0, false, 0, Optional.empty(), Collections.emptyList()));
-+ return (this.hasFood()) ? new CraftFoodComponent(this.food) : new CraftFoodComponent(new FoodProperties(0, 0, false, FoodProperties.DEFAULT_EAT_SECONDS, Optional.empty(), Collections.emptyList())); // Paper - create a valid food properties
- }
-
- @Override
-@@ -1440,7 +1447,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1692,7 +1699,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
@Override
public Multimap<Attribute, AttributeModifier> getAttributeModifiers(@Nullable EquipmentSlot slot) {
@@ -1195,7 +1186,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
SetMultimap<Attribute, AttributeModifier> result = LinkedHashMultimap.create();
for (Map.Entry<Attribute, AttributeModifier> entry : this.attributeModifiers.entries()) {
if (entry.getValue().getSlot() == null || entry.getValue().getSlot() == slot) {
-@@ -1453,6 +1460,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1705,6 +1712,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
@Override
public Collection<AttributeModifier> getAttributeModifiers(@Nonnull Attribute attribute) {
Preconditions.checkNotNull(attribute, "Attribute cannot be null");
@@ -1203,7 +1194,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
return this.attributeModifiers.containsKey(attribute) ? ImmutableList.copyOf(this.attributeModifiers.get(attribute)) : null;
}
-@@ -1460,22 +1468,33 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1712,22 +1720,33 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
public boolean addAttributeModifier(@Nonnull Attribute attribute, @Nonnull AttributeModifier modifier) {
Preconditions.checkNotNull(attribute, "Attribute cannot be null");
Preconditions.checkNotNull(modifier, "AttributeModifier cannot be null");
@@ -1241,7 +1232,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
Iterator<Map.Entry<Attribute, AttributeModifier>> iterator = attributeModifiers.entries().iterator();
while (iterator.hasNext()) {
-@@ -1485,6 +1504,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1737,6 +1756,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
iterator.remove();
continue;
}
@@ -1249,7 +1240,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
this.attributeModifiers.put(next.getKey(), next.getValue());
}
}
-@@ -1492,13 +1512,13 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1744,13 +1764,13 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
@Override
public boolean removeAttributeModifier(@Nonnull Attribute attribute) {
Preconditions.checkNotNull(attribute, "Attribute cannot be null");
@@ -1265,7 +1256,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
int removed = 0;
Iterator<Map.Entry<Attribute, AttributeModifier>> iter = this.attributeModifiers.entries().iterator();
-@@ -1518,7 +1538,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1770,7 +1790,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
public boolean removeAttributeModifier(@Nonnull Attribute attribute, @Nonnull AttributeModifier modifier) {
Preconditions.checkNotNull(attribute, "Attribute cannot be null");
Preconditions.checkNotNull(modifier, "AttributeModifier cannot be null");
@@ -1274,7 +1265,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
int removed = 0;
Iterator<Map.Entry<Attribute, AttributeModifier>> iter = this.attributeModifiers.entries().iterator();
-@@ -1540,7 +1560,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1792,7 +1812,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
@Override
public String getAsString() {
@@ -1282,8 +1273,8 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
+ CraftMetaItem.Applicator tag = new CraftMetaItem.Applicator() {}; // Paper - support updating profile after resolving it
this.applyToItem(tag);
DataComponentPatch patch = tag.build();
- Tag nbt = DataComponentPatch.CODEC.encodeStart(MinecraftServer.getDefaultRegistryAccess().createSerializationContext(NbtOps.INSTANCE), patch).getOrThrow();
-@@ -1549,7 +1569,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+ net.minecraft.nbt.Tag nbt = DataComponentPatch.CODEC.encodeStart(MinecraftServer.getDefaultRegistryAccess().createSerializationContext(NbtOps.INSTANCE), patch).getOrThrow();
+@@ -1801,7 +1821,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
@Override
public String getAsComponentString() {
@@ -1292,7 +1283,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
this.applyToItem(tag);
DataComponentPatch patch = tag.build();
-@@ -1589,6 +1609,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1841,6 +1861,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
if (first == null || second == null) {
return false;
}
@@ -1300,7 +1291,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
for (Map.Entry<Attribute, AttributeModifier> entry : first.entries()) {
if (!second.containsEntry(entry.getKey(), entry.getValue())) {
return false;
-@@ -1604,19 +1625,33 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1856,19 +1877,33 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
@Override
public boolean hasDamage() {
@@ -1336,7 +1327,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
@Override
public boolean hasMaxDamage() {
return this.maxDamage != null;
-@@ -1630,6 +1665,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1882,6 +1917,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
@Override
public void setMaxDamage(Integer maxDamage) {
@@ -1344,8 +1335,8 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
this.maxDamage = maxDamage;
}
-@@ -1661,7 +1697,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
- && (this.hasCustomModelData() ? that.hasCustomModelData() && this.customModelData.equals(that.customModelData) : !that.hasCustomModelData())
+@@ -1914,7 +1950,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+ && (this.hasEnchantable() ? that.hasEnchantable() && this.enchantableValue.equals(that.enchantableValue) : !that.hasEnchantable())
&& (this.hasBlockData() ? that.hasBlockData() && this.blockData.equals(that.blockData) : !that.hasBlockData())
&& (this.hasRepairCost() ? that.hasRepairCost() && this.repairCost == that.repairCost : !that.hasRepairCost())
- && (this.hasAttributeModifiers() ? that.hasAttributeModifiers() && CraftMetaItem.compareModifiers(this.attributeModifiers, that.attributeModifiers) : !that.hasAttributeModifiers())
@@ -1353,19 +1344,19 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
&& (this.unhandledTags.equals(that.unhandledTags))
&& (this.removedTags.equals(that.removedTags))
&& (Objects.equals(this.customTag, that.customTag))
-@@ -1676,7 +1712,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
- && (this.hasFood() ? that.hasFood() && this.food.equals(that.food) : !that.hasFood())
+@@ -1935,7 +1971,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
&& (this.hasTool() ? that.hasTool() && this.tool.equals(that.tool) : !that.hasTool())
+ && (this.hasEquippable() ? that.hasEquippable() && this.equippable.equals(that.equippable) : !that.hasEquippable())
&& (this.hasJukeboxPlayable() ? that.hasJukeboxPlayable() && this.jukebox.equals(that.jukebox) : !that.hasJukeboxPlayable())
- && (this.hasDamage() ? that.hasDamage() && this.damage == that.damage : !that.hasDamage())
+ && (Objects.equals(this.damage, that.damage)) // Paper - preserve empty/0 damage
&& (this.hasMaxDamage() ? that.hasMaxDamage() && this.maxDamage.equals(that.maxDamage) : !that.hasMaxDamage())
&& (this.canPlaceOnPredicates != null ? that.canPlaceOnPredicates != null && this.canPlaceOnPredicates.equals(that.canPlaceOnPredicates) : that.canPlaceOnPredicates == null) // Paper
&& (this.canBreakPredicates != null ? that.canBreakPredicates != null && this.canBreakPredicates.equals(that.canBreakPredicates) : that.canBreakPredicates == null) // Paper
-@@ -1722,9 +1758,9 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
- hash = 61 * hash + (this.hasFood() ? this.food.hashCode() : 0);
+@@ -1988,9 +2024,9 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
hash = 61 * hash + (this.hasTool() ? this.tool.hashCode() : 0);
hash = 61 * hash + (this.hasJukeboxPlayable() ? this.jukebox.hashCode() : 0);
+ hash = 61 * hash + (this.hasEquippable() ? this.equippable.hashCode() : 0);
- hash = 61 * hash + (this.hasDamage() ? this.damage : 0);
- hash = 61 * hash + (this.hasMaxDamage() ? 1231 : 1237);
- hash = 61 * hash + (this.hasAttributeModifiers() ? this.attributeModifiers.hashCode() : 0);
@@ -1375,7 +1366,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
hash = 61 * hash + (this.canPlaceOnPredicates != null ? this.canPlaceOnPredicates.hashCode() : 0); // Paper
hash = 61 * hash + (this.canBreakPredicates != null ? this.canBreakPredicates.hashCode() : 0); // Paper
hash = 61 * hash + this.version;
-@@ -1744,7 +1780,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -2011,7 +2047,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
if (this.enchantments != null) {
clone.enchantments = new EnchantmentMap(this.enchantments); // Paper
}
@@ -1384,7 +1375,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
clone.attributeModifiers = LinkedHashMultimap.create(this.attributeModifiers);
}
if (this.customTag != null) {
-@@ -1872,7 +1908,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -2178,7 +2214,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
builder.put(CraftMetaItem.JUKEBOX_PLAYABLE.BUKKIT, this.jukebox);
}
@@ -1393,7 +1384,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
builder.put(CraftMetaItem.DAMAGE.BUKKIT, this.damage);
}
-@@ -1973,7 +2009,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -2279,7 +2315,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
}
static void serializeModifiers(Multimap<Attribute, AttributeModifier> modifiers, ImmutableMap.Builder<String, Object> builder, ItemMetaKey key) {
@@ -1402,7 +1393,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
return;
}
-@@ -2055,7 +2091,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -2361,7 +2397,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
// Paper start - improve checking handled tags
@org.jetbrains.annotations.VisibleForTesting
public static final Map<Class<? extends CraftMetaItem>, Set<DataComponentType<?>>> HANDLED_DCTS_PER_TYPE = new HashMap<>();
@@ -1411,7 +1402,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
CraftMetaItem.NAME.TYPE,
CraftMetaItem.ITEM_NAME.TYPE,
CraftMetaItem.LORE.TYPE,
-@@ -2124,7 +2160,12 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -2437,7 +2473,12 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
// Paper end - improve checking handled data component types
protected static <T> Optional<? extends T> getOrEmpty(DataComponentPatch tag, ItemMetaKeyType<T> type) {
@@ -1426,7 +1417,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd
return (result != null) ? result : Optional.empty();
}
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java
-index e8c950aa74d31bf7a9128f4acc4bccee26bbcd7f..f1dbfba7ec11b12ead627f098a0b833f49be8000 100644
+index e76749bffaf5a0bbd3a8d35f882edcc3598351b9..49889026661fb2a558e14569324016d637de27a0 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java
@@ -18,16 +18,30 @@ class CraftMetaLeatherArmor extends CraftMetaItem implements LeatherArmorMeta {
@@ -1586,10 +1577,10 @@ index 149356981e586e4f67d4543d3df94a2ea99333fc..06c72ed83dab9492b70bfd13f7f9c1a4
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java
-index 90c554dcbfe2bcca3f742379499f1e8e8665c512..14acdd2bd02de7e99b7f237151633ed71396db5f 100644
+index b118d8ecb505d187c02bb158f14df333f487a87f..fa1d1a7f37aadf2750f03a0e215fb25fa948f9aa 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java
-@@ -69,6 +69,7 @@ public class CraftMetaOminousBottle extends CraftMetaItem implements OminousBott
+@@ -70,6 +70,7 @@ public class CraftMetaOminousBottle extends CraftMetaItem implements OminousBott
@Override
public int getAmplifier() {
@@ -1598,19 +1589,19 @@ index 90c554dcbfe2bcca3f742379499f1e8e8665c512..14acdd2bd02de7e99b7f237151633ed7
}
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java
-index 1a18779f9796704c8690226dbe491b0fa6ba99ea..c2476232b5472f1a0b1862588de2abf879b82ede 100644
+index 6f0eebcaffa20337cf5a7f8485f891c690d948ae..18dc2e83dab0821e5129bd68361de189363823b3 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java
-@@ -37,7 +37,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta {
+@@ -38,7 +38,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta {
private PotionType type;
private List<PotionEffect> customEffects;
- private Color color;
+ private Integer color; // Paper - keep color component consistent with vanilla (top byte is ignored)
+ private String customName;
CraftMetaPotion(CraftMetaItem meta) {
- super(meta);
-@@ -60,7 +60,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta {
+@@ -63,7 +63,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta {
potionContents.customColor().ifPresent((customColor) -> {
try {
@@ -1619,16 +1610,16 @@ index 1a18779f9796704c8690226dbe491b0fa6ba99ea..c2476232b5472f1a0b1862588de2abf8
} catch (IllegalArgumentException ex) {
// Invalid colour
}
-@@ -120,7 +120,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta {
+@@ -132,7 +132,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta {
}
Optional<Holder<Potion>> defaultPotion = (this.hasBasePotionType()) ? Optional.of(CraftPotionType.bukkitToMinecraftHolder(this.type)) : Optional.empty();
- Optional<Integer> potionColor = (this.hasColor()) ? Optional.of(this.color.asRGB()) : Optional.empty();
+ Optional<Integer> potionColor = (this.hasColor()) ? Optional.of(this.color) : Optional.empty(); // Paper
+ Optional<String> customName = Optional.ofNullable(this.customName);
List<MobEffectInstance> effectList = new ArrayList<>();
- if (this.customEffects != null) {
-@@ -284,12 +284,12 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta {
+@@ -297,12 +297,12 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta {
@Override
public Color getColor() {
@@ -2036,39 +2027,11 @@ index e00b757d6059715e8697428008fcb3e6e7abbe2e..dcf02bd0f7f4c67f5ab98003cc932b96
+ }
+ // Paper end - General ItemMeta Fixes
}
-diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftFoodComponent.java b/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftFoodComponent.java
-index 92cad73219e11dc5922630769f9dd3a329ea6da1..bde61de7eda72b2e24ddef56ff93a0b46c08670c 100644
---- a/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftFoodComponent.java
-+++ b/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftFoodComponent.java
-@@ -114,6 +114,7 @@ public final class CraftFoodComponent implements FoodComponent {
-
- @Override
- public void setEatSeconds(float eatSeconds) {
-+ Preconditions.checkArgument(eatSeconds > 0, "Eat seconds must be positive"); // Paper - validate eat_seconds
- this.handle = new FoodProperties(this.handle.nutrition(), this.handle.saturation(), this.handle.canAlwaysEat(), eatSeconds, this.handle.usingConvertsTo(), this.handle.effects());
- }
-
-@@ -124,6 +125,7 @@ public final class CraftFoodComponent implements FoodComponent {
-
- @Override
- public void setUsingConvertsTo(ItemStack item) {
-+ Preconditions.checkArgument(item == null || !item.isEmpty(), "Item cannot be empty"); // Paper - validate using_converts_to
- this.handle = new FoodProperties(this.handle.nutrition(), this.handle.saturation(), this.handle.canAlwaysEat(), this.handle.eatSeconds(), Optional.ofNullable(item).map(CraftItemStack::asNMSCopy), this.handle.effects());
- }
-
-@@ -139,6 +141,7 @@ public final class CraftFoodComponent implements FoodComponent {
-
- @Override
- public FoodEffect addEffect(PotionEffect effect, float probability) {
-+ Preconditions.checkArgument(0 <= probability && probability <= 1, "Probability cannot be outside range [0,1]"); // Paper
- List<FoodProperties.PossibleEffect> effects = new ArrayList<>(this.handle.effects());
-
- FoodProperties.PossibleEffect newEffect = new net.minecraft.world.food.FoodProperties.PossibleEffect(CraftPotionUtil.fromBukkit(effect), probability);
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftToolComponent.java b/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftToolComponent.java
-index 6c477913406a0dded8ca00295b8f4928e31404ae..2750c46c535d5b10afcaca109fc89d73d6485fd0 100644
+index 9a4a1d903c22e9d2a0cbda95ceb8b1dcfb29112e..4f7914f96207feda67cd910213bb624df4802a06 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftToolComponent.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftToolComponent.java
-@@ -108,6 +108,7 @@ public final class CraftToolComponent implements ToolComponent {
+@@ -106,6 +106,7 @@ public final class CraftToolComponent implements ToolComponent {
public ToolRule addRule(Material block, Float speed, Boolean correctForDrops) {
Preconditions.checkArgument(block != null, "block must not be null");
Preconditions.checkArgument(block.isBlock(), "block must be a block type, given %s", block.getKey());
@@ -2076,7 +2039,7 @@ index 6c477913406a0dded8ca00295b8f4928e31404ae..2750c46c535d5b10afcaca109fc89d73
Holder.Reference<Block> nmsBlock = CraftBlockType.bukkitToMinecraft(block).builtInRegistryHolder();
return this.addRule(HolderSet.direct(nmsBlock), speed, correctForDrops);
-@@ -115,6 +116,7 @@ public final class CraftToolComponent implements ToolComponent {
+@@ -113,6 +114,7 @@ public final class CraftToolComponent implements ToolComponent {
@Override
public ToolRule addRule(Collection<Material> blocks, Float speed, Boolean correctForDrops) {
@@ -2084,7 +2047,7 @@ index 6c477913406a0dded8ca00295b8f4928e31404ae..2750c46c535d5b10afcaca109fc89d73
List<Holder.Reference<Block>> nmsBlocks = new ArrayList<>(blocks.size());
for (Material material : blocks) {
-@@ -128,6 +130,7 @@ public final class CraftToolComponent implements ToolComponent {
+@@ -126,6 +128,7 @@ public final class CraftToolComponent implements ToolComponent {
@Override
public ToolRule addRule(Tag<Material> tag, Float speed, Boolean correctForDrops) {
Preconditions.checkArgument(tag instanceof CraftBlockTag, "tag must be a block tag");
@@ -2092,7 +2055,7 @@ index 6c477913406a0dded8ca00295b8f4928e31404ae..2750c46c535d5b10afcaca109fc89d73
return this.addRule(((CraftBlockTag) tag).getHandle(), speed, correctForDrops);
}
-@@ -290,6 +293,7 @@ public final class CraftToolComponent implements ToolComponent {
+@@ -258,6 +261,7 @@ public final class CraftToolComponent implements ToolComponent {
@Override
public void setSpeed(Float speed) {
diff --git a/patches/unapplied/server/0963-More-Chest-Block-API.patch b/patches/server/0955-More-Chest-Block-API.patch
index 020d97d086..d7c00f61e1 100644
--- a/patches/unapplied/server/0963-More-Chest-Block-API.patch
+++ b/patches/server/0955-More-Chest-Block-API.patch
@@ -7,18 +7,18 @@ Subject: [PATCH] More Chest Block API
public net.minecraft.world.level.block.ChestBlock isBlockedChestByBlock(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Z
diff --git a/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java
-index 5f9858ef8d0ec1a74d469ab4426eb1db068873fd..ca92d49ef2010ba00c623491671dcde8ebe697c1 100644
+index b376f7d3b632d6aaea5c4d93382238074559d56a..ef0d469176ee74b6bb5f9e9cc508735145fda5b8 100644
--- a/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java
@@ -83,7 +83,7 @@ public class EnderChestBlock extends AbstractChestBlock<EnderChestBlockEntity> i
- BlockEntity blockEntity = world.getBlockEntity(pos);
- if (playerEnderChestContainer != null && blockEntity instanceof EnderChestBlockEntity) {
+ PlayerEnderChestContainer playerEnderChestContainer = player.getEnderChestInventory();
+ if (playerEnderChestContainer != null && world.getBlockEntity(pos) instanceof EnderChestBlockEntity enderChestBlockEntity) {
BlockPos blockPos = pos.above();
- if (world.getBlockState(blockPos).isRedstoneConductor(world, blockPos)) {
+ if (world.getBlockState(blockPos).isRedstoneConductor(world, blockPos)) { // Paper - diff on change; make sure that EnderChest#isBlocked uses the same logic
- return InteractionResult.sidedSuccess(world.isClientSide);
- } else if (world.isClientSide) {
return InteractionResult.SUCCESS;
+ } else {
+ if (world instanceof ServerLevel serverLevel) {
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java
index 6e98a00d526b734992ce39b15768c5820dce4ca8..cc7bf4d39b834fba472bc163226a01a0cd4b6010 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java
diff --git a/patches/unapplied/server/0964-Print-data-component-type-on-encoding-error.patch b/patches/server/0956-Print-data-component-type-on-encoding-error.patch
index a60bdfee87..f003f33b92 100644
--- a/patches/unapplied/server/0964-Print-data-component-type-on-encoding-error.patch
+++ b/patches/server/0956-Print-data-component-type-on-encoding-error.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Print data component type on encoding error
diff --git a/src/main/java/net/minecraft/core/component/DataComponentPatch.java b/src/main/java/net/minecraft/core/component/DataComponentPatch.java
-index 87dd1f570fd294daf826ef7e6403776e42ed4f61..cee4a0639b3c73e300a8450f8a831cb4a71958ba 100644
+index 9de958d769a52a8df794988781f8601a4e6a73a4..9dec1c74d10f82636b7176e8f725b8acd1b52e4f 100644
--- a/src/main/java/net/minecraft/core/component/DataComponentPatch.java
+++ b/src/main/java/net/minecraft/core/component/DataComponentPatch.java
@@ -144,7 +144,13 @@ public final class DataComponentPatch {
diff --git a/patches/unapplied/server/0965-Brigadier-based-command-API.patch b/patches/server/0957-Brigadier-based-command-API.patch
index 6334fcc1c8..6eb0d9779c 100644
--- a/patches/unapplied/server/0965-Brigadier-based-command-API.patch
+++ b/patches/server/0957-Brigadier-based-command-API.patch
@@ -2024,10 +2024,10 @@ index 5ba0ef6eda157c4e61d1de99c6b017ceb34430ec..bc5fc57018e347caa5ca453430a45669
// CraftBukkit end
};
diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java
-index 3c0d2332207ba638faaaa4280bce18c334a01271..4017b82e72fefd6685e9250a936686fd8a0891f1 100644
+index fc0c60b22844ed010aede2fa125b9fa440d3de80..3549ffea451b932602efb113844ba21a7bc72371 100644
--- a/src/main/java/net/minecraft/commands/CommandSourceStack.java
+++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java
-@@ -45,8 +45,7 @@ import net.minecraft.world.phys.Vec2;
+@@ -47,8 +47,7 @@ import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3;
import com.mojang.brigadier.tree.CommandNode; // CraftBukkit
@@ -2037,7 +2037,7 @@ index 3c0d2332207ba638faaaa4280bce18c334a01271..4017b82e72fefd6685e9250a936686fd
public static final SimpleCommandExceptionType ERROR_NOT_PLAYER = new SimpleCommandExceptionType(Component.translatable("permissions.requires.player"));
public static final SimpleCommandExceptionType ERROR_NOT_ENTITY = new SimpleCommandExceptionType(Component.translatable("permissions.requires.entity"));
public final CommandSource source;
-@@ -170,26 +169,6 @@ public class CommandSourceStack implements ExecutionCommandSource<CommandSourceS
+@@ -172,26 +171,6 @@ public class CommandSourceStack implements ExecutionCommandSource<CommandSourceS
return this.textName;
}
@@ -2064,7 +2064,7 @@ index 3c0d2332207ba638faaaa4280bce18c334a01271..4017b82e72fefd6685e9250a936686fd
@Override
public boolean hasPermission(int level) {
// CraftBukkit start
-@@ -457,6 +436,12 @@ public class CommandSourceStack implements ExecutionCommandSource<CommandSourceS
+@@ -464,6 +443,12 @@ public class CommandSourceStack implements ExecutionCommandSource<CommandSourceS
return this.silent;
}
@@ -2078,10 +2078,10 @@ index 3c0d2332207ba638faaaa4280bce18c334a01271..4017b82e72fefd6685e9250a936686fd
public org.bukkit.command.CommandSender getBukkitSender() {
return this.source.getBukkitSender(this);
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
-index 7b86e064564d3a285e3971fd08ea6168bac0720e..74fcdc74dc6c5cbf81abb7d46fc700473bd00eff 100644
+index fe9f638db3525893beed565ef9b7ac2fc76318bd..b1571c162fd8ab7239a7f4aafea5187feb694761 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
-@@ -155,7 +155,7 @@ public class Commands {
+@@ -159,7 +159,7 @@ public class Commands {
private final com.mojang.brigadier.CommandDispatcher<CommandSourceStack> dispatcher = new com.mojang.brigadier.CommandDispatcher();
public Commands(Commands.CommandSelection environment, CommandBuildContext commandRegistryAccess) {
@@ -2090,7 +2090,7 @@ index 7b86e064564d3a285e3971fd08ea6168bac0720e..74fcdc74dc6c5cbf81abb7d46fc70047
AdvancementCommands.register(this.dispatcher);
AttributeCommand.register(this.dispatcher, commandRegistryAccess);
ExecuteCommand.register(this.dispatcher, commandRegistryAccess);
-@@ -263,11 +263,24 @@ public class Commands {
+@@ -268,11 +268,24 @@ public class Commands {
}
}
// Paper end - Vanilla command permission fixes
@@ -2120,7 +2120,7 @@ index 7b86e064564d3a285e3971fd08ea6168bac0720e..74fcdc74dc6c5cbf81abb7d46fc70047
this.dispatcher.setConsumer(ExecutionCommandSource.resultConsumer());
}
-@@ -323,6 +336,11 @@ public class Commands {
+@@ -328,6 +341,11 @@ public class Commands {
}
public void performCommand(ParseResults<CommandSourceStack> parseresults, String s, String label) { // CraftBukkit
@@ -2131,8 +2131,8 @@ index 7b86e064564d3a285e3971fd08ea6168bac0720e..74fcdc74dc6c5cbf81abb7d46fc70047
+ // Paper end
CommandSourceStack commandlistenerwrapper = (CommandSourceStack) parseresults.getContext().getSource();
- commandlistenerwrapper.getServer().getProfiler().push(() -> {
-@@ -337,10 +355,11 @@ public class Commands {
+ Profiler.get().push(() -> {
+@@ -342,10 +360,11 @@ public class Commands {
});
}
} catch (Exception exception) {
@@ -2145,7 +2145,7 @@ index 7b86e064564d3a285e3971fd08ea6168bac0720e..74fcdc74dc6c5cbf81abb7d46fc70047
StackTraceElement[] astacktraceelement = exception.getStackTrace();
for (int i = 0; i < Math.min(astacktraceelement.length, 3); ++i) {
-@@ -473,13 +492,7 @@ public class Commands {
+@@ -478,13 +497,7 @@ public class Commands {
private void sendAsync(ServerPlayer player) {
// Paper end - Perf: Async command map building
Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> map = Maps.newIdentityHashMap(); // Use identity to prevent aliasing issues
@@ -2160,7 +2160,7 @@ index 7b86e064564d3a285e3971fd08ea6168bac0720e..74fcdc74dc6c5cbf81abb7d46fc70047
RootCommandNode<SharedSuggestionProvider> rootcommandnode = new RootCommandNode();
map.put(this.dispatcher.getRoot(), rootcommandnode);
-@@ -513,6 +526,7 @@ public class Commands {
+@@ -518,6 +531,7 @@ public class Commands {
}
private void fillUsableCommands(CommandNode<CommandSourceStack> tree, CommandNode<SharedSuggestionProvider> result, CommandSourceStack source, Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> resultNodes) {
@@ -2168,7 +2168,7 @@ index 7b86e064564d3a285e3971fd08ea6168bac0720e..74fcdc74dc6c5cbf81abb7d46fc70047
Iterator iterator = tree.getChildren().iterator();
while (iterator.hasNext()) {
-@@ -526,6 +540,42 @@ public class Commands {
+@@ -531,6 +545,42 @@ public class Commands {
if (commandnode2.canUse(source)) {
ArgumentBuilder argumentbuilder = commandnode2.createBuilder(); // CraftBukkit - decompile error
@@ -2228,10 +2228,10 @@ index 55484826fc5ddd04ae024e25a0251796d7fa9c28..237e4f7b24908e9ade9a483eb7ae05fa
Component component = message.resolveComponent(commandSourceStack);
CommandSigningContext commandSigningContext = commandSourceStack.getSigningContext();
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 42a74f5471da882d63c194b1e212f78a94b103ec..a093f29a0b75b5a9e2db2238698d2f3f4ac14ed1 100644
+index f575c0042f67c70df0ddb1d1db68e0138cf0b534..21660e4284cfabb333a3edf9224c892ef80b2403 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -306,7 +306,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -317,7 +317,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public static int currentTick; // Paper - improve tick loop
public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
public int autosavePeriod;
@@ -2240,7 +2240,7 @@ index 42a74f5471da882d63c194b1e212f78a94b103ec..a093f29a0b75b5a9e2db2238698d2f3f
private boolean forceTicks;
// CraftBukkit end
// Spigot start
-@@ -392,7 +392,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -407,7 +407,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// CraftBukkit start
this.options = options;
this.worldLoader = worldLoader;
@@ -2248,7 +2248,7 @@ index 42a74f5471da882d63c194b1e212f78a94b103ec..a093f29a0b75b5a9e2db2238698d2f3f
// Paper start - Handled by TerminalConsoleAppender
// Try to see if we're actually running in a terminal, disable jline if not
/*
-@@ -677,6 +676,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -693,6 +692,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.POSTWORLD);
if (io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper != null) io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper.pluginsEnabled(); // Paper - Remap plugins
@@ -2258,7 +2258,7 @@ index 42a74f5471da882d63c194b1e212f78a94b103ec..a093f29a0b75b5a9e2db2238698d2f3f
this.server.getPluginManager().callEvent(new ServerLoadEvent(ServerLoadEvent.LoadType.STARTUP));
this.connection.acceptConnections();
}
-@@ -2179,9 +2181,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -2259,9 +2261,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
return new MinecraftServer.ReloadableResources(resourcemanager, datapackresources);
});
}).thenAcceptAsync((minecraftserver_reloadableresources) -> {
@@ -2269,13 +2269,10 @@ index 42a74f5471da882d63c194b1e212f78a94b103ec..a093f29a0b75b5a9e2db2238698d2f3f
this.packRepository.setSelected(dataPacks);
WorldDataConfiguration worlddataconfiguration = new WorldDataConfiguration(MinecraftServer.getSelectedPacks(this.packRepository, true), this.worldData.enabledFeatures());
-@@ -2192,8 +2194,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
- this.getPlayerList().reloadResources();
- this.functionManager.replaceLibrary(this.resources.managers.getFunctionLibrary());
+@@ -2275,6 +2277,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.structureTemplateManager.onResourceManagerReload(this.resources.resourceManager);
-- org.bukkit.craftbukkit.block.data.CraftBlockData.reloadCache(); // Paper - cache block data strings; they can be defined by datapacks so refresh it here
-- new io.papermc.paper.event.server.ServerResourcesReloadedEvent(cause).callEvent(); // Paper - Add ServerResourcesReloadedEvent; fire after everything has been reloaded
-+ org.bukkit.craftbukkit.block.data.CraftBlockData.reloadCache(); // Paper - cache block data strings, they can be defined by datapacks so refresh it here
+ this.fuelValues = FuelValues.vanillaBurnTimes(this.registries.compositeAccess(), this.worldData.enabledFeatures());
+ org.bukkit.craftbukkit.block.data.CraftBlockData.reloadCache(); // Paper - cache block data strings; they can be defined by datapacks so refresh it here
+ // Paper start - brigadier command API
+ io.papermc.paper.command.brigadier.PaperCommands.INSTANCE.setValid(); // reset invalid state for event fire below
+ io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner.INSTANCE.callReloadableRegistrarEvent(io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents.COMMANDS, io.papermc.paper.command.brigadier.PaperCommands.INSTANCE, org.bukkit.plugin.Plugin.class, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.RELOAD); // call commands event for regular plugins
@@ -2285,25 +2282,24 @@ index 42a74f5471da882d63c194b1e212f78a94b103ec..a093f29a0b75b5a9e2db2238698d2f3f
+ helpMap.initializeCommands();
+ this.server.syncCommands(); // Refresh commands after event
+ // Paper end
-+ new io.papermc.paper.event.server.ServerResourcesReloadedEvent(cause).callEvent(); // Paper - fire after everything has been reloaded
+ new io.papermc.paper.event.server.ServerResourcesReloadedEvent(cause).callEvent(); // Paper - Add ServerResourcesReloadedEvent; fire after everything has been reloaded
}, this);
- if (this.isSameThread()) {
diff --git a/src/main/java/net/minecraft/server/ReloadableServerResources.java b/src/main/java/net/minecraft/server/ReloadableServerResources.java
-index 84b4bfe8363adc015821e9cabedfabed98c0336c..6de563b7adea957a7ead1c00c4900060fa5df277 100644
+index ac9a706dd92f15406299b8fc4ed567ffcc736169..47d5d5fcc8623969c6ab7c148c043bc367f1d6cf 100644
--- a/src/main/java/net/minecraft/server/ReloadableServerResources.java
+++ b/src/main/java/net/minecraft/server/ReloadableServerResources.java
-@@ -48,6 +48,7 @@ public class ReloadableServerResources {
- this.recipes = new RecipeManager(this.registryLookup);
- this.tagManager = new TagManager(dynamicRegistryManager);
- this.commands = new Commands(environment, CommandBuildContext.simple(this.registryLookup, enabledFeatures));
-+ io.papermc.paper.command.brigadier.PaperCommands.INSTANCE.setDispatcher(this.commands, CommandBuildContext.simple(this.registryLookup, enabledFeatures)); // Paper - Brigadier Command API
- this.advancements = new ServerAdvancementManager(this.registryLookup);
+@@ -39,6 +39,7 @@ public class ReloadableServerResources {
+ this.postponedTags = pendingTagLoads;
+ this.recipes = new RecipeManager(registries);
+ this.commands = new Commands(environment, CommandBuildContext.simple(registries, enabledFeatures));
++ io.papermc.paper.command.brigadier.PaperCommands.INSTANCE.setDispatcher(this.commands, CommandBuildContext.simple(registries, enabledFeatures)); // Paper - Brigadier Command API
+ this.advancements = new ServerAdvancementManager(registries);
this.functionLibrary = new ServerFunctionLibrary(functionPermissionLevel, this.commands.getDispatcher());
}
-@@ -91,6 +92,14 @@ public class ReloadableServerResources {
+@@ -83,6 +84,14 @@ public class ReloadableServerResources {
ReloadableServerResources reloadableServerResources = new ReloadableServerResources(
- reloadedDynamicRegistries.compositeAccess(), enabledFeatures, environment, functionPermissionLevel
+ reloadResult.layers(), reloadResult.lookupWithUpdatedTags(), enabledFeatures, environment, pendingTagLoads, functionPermissionLevel
);
+ // Paper start - call commands event for bootstraps
+ //noinspection ConstantValue
@@ -2314,13 +2310,13 @@ index 84b4bfe8363adc015821e9cabedfabed98c0336c..6de563b7adea957a7ead1c00c4900060
+ MinecraftServer.getServer() == null ? io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.INITIAL : io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.RELOAD);
+ // Paper end - call commands event
return SimpleReloadInstance.create(
- manager, reloadableServerResources.listeners(), prepareExecutor, applyExecutor, DATA_RELOAD_INITIAL_TASK, LOGGER.isDebugEnabled()
- )
+ resourceManager,
+ reloadableServerResources.listeners(),
diff --git a/src/main/java/net/minecraft/server/ServerFunctionManager.java b/src/main/java/net/minecraft/server/ServerFunctionManager.java
-index ec29e95d796305b8d44c2075629a8147a05f48c1..9cd4f7c6910727c849ac7f5d675dc6105c4bbba2 100644
+index 02e00819970eda49196641520870fc31d08b1a38..0b348f701b61c7b7ed0190eff8b2d73f3a3d5c74 100644
--- a/src/main/java/net/minecraft/server/ServerFunctionManager.java
+++ b/src/main/java/net/minecraft/server/ServerFunctionManager.java
-@@ -36,7 +36,7 @@ public class ServerFunctionManager {
+@@ -37,7 +37,7 @@ public class ServerFunctionManager {
}
public CommandDispatcher<CommandSourceStack> getDispatcher() {
@@ -2330,10 +2326,10 @@ index ec29e95d796305b8d44c2075629a8147a05f48c1..9cd4f7c6910727c849ac7f5d675dc610
public void tick() {
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
-index b4af03c4bdd1ce0861f36c3b75fc7e89d701c46a..0761d5bc5f2813bb4a9f664ac7a05b9744d0a778 100644
+index eb9dab7be7da11ab1c4046a7fc4a29d5bddf31d2..39c9c0dad159744da8322c3dfa3bfae448f73241 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
-@@ -237,7 +237,6 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
+@@ -236,7 +236,6 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command
com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now
@@ -2342,10 +2338,10 @@ index b4af03c4bdd1ce0861f36c3b75fc7e89d701c46a..0761d5bc5f2813bb4a9f664ac7a05b97
this.setPvpAllowed(dedicatedserverproperties.pvp);
this.setFlightAllowed(dedicatedserverproperties.allowFlight);
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index e0c46e548a34c963750c9411dfd3c0946d67a7c7..5215783353021583e7a726d281e4d1734398f073 100644
+index 74b70c7a41d03bae57e1b2863b7ce947f951da46..7508434475ea93f9153f3976c5fa95c7678807e9 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -2407,33 +2407,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
+@@ -2421,33 +2421,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
}
@@ -2392,10 +2388,10 @@ index e0c46e548a34c963750c9411dfd3c0946d67a7c7..5215783353021583e7a726d281e4d173
// CraftBukkit end
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 0fc6e659915a4547c2db9205fed205a1d28f21d4..35d1dcabb182b0a31727e5ddefe33955c804603b 100644
+index 97850b3111dfa86d15186fa200937b28bec428de..6235d7caede85f4cf21dadde18d8080004672349 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-@@ -272,11 +272,11 @@ public final class CraftServer implements Server {
+@@ -275,11 +275,11 @@ public final class CraftServer implements Server {
private final Logger logger = Logger.getLogger("Minecraft");
private final ServicesManager servicesManager = new SimpleServicesManager();
private final CraftScheduler scheduler = new CraftScheduler();
@@ -2410,7 +2406,7 @@ index 0fc6e659915a4547c2db9205fed205a1d28f21d4..35d1dcabb182b0a31727e5ddefe33955
private final StructureManager structureManager;
protected final DedicatedServer console;
protected final DedicatedPlayerList playerList;
-@@ -404,6 +404,12 @@ public final class CraftServer implements Server {
+@@ -407,6 +407,12 @@ public final class CraftServer implements Server {
this.serverLinks = new CraftServerLinks(console);
Bukkit.setServer(this);
@@ -2423,7 +2419,7 @@ index 0fc6e659915a4547c2db9205fed205a1d28f21d4..35d1dcabb182b0a31727e5ddefe33955
CraftRegistry.setMinecraftRegistry(console.registryAccess());
-@@ -603,48 +609,11 @@ public final class CraftServer implements Server {
+@@ -606,48 +612,11 @@ public final class CraftServer implements Server {
}
private void setVanillaCommands(boolean first) { // Spigot
@@ -2474,7 +2470,7 @@ index 0fc6e659915a4547c2db9205fed205a1d28f21d4..35d1dcabb182b0a31727e5ddefe33955
// Refresh commands
for (ServerPlayer player : this.getHandle().players) {
-@@ -1031,17 +1000,31 @@ public final class CraftServer implements Server {
+@@ -1034,17 +1003,31 @@ public final class CraftServer implements Server {
return true;
}
@@ -2516,7 +2512,7 @@ index 0fc6e659915a4547c2db9205fed205a1d28f21d4..35d1dcabb182b0a31727e5ddefe33955
return false;
}
-@@ -1050,7 +1033,7 @@ public final class CraftServer implements Server {
+@@ -1053,7 +1036,7 @@ public final class CraftServer implements Server {
public void reload() {
// Paper start - lifecycle events
if (io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner.INSTANCE.blocksPluginReloading()) {
@@ -2525,7 +2521,7 @@ index 0fc6e659915a4547c2db9205fed205a1d28f21d4..35d1dcabb182b0a31727e5ddefe33955
}
// Paper end - lifecycle events
org.spigotmc.WatchdogThread.hasStarted = false; // Paper - Disable watchdog early timeout on reload
-@@ -1105,8 +1088,9 @@ public final class CraftServer implements Server {
+@@ -1108,8 +1091,9 @@ public final class CraftServer implements Server {
}
Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper
@@ -2536,7 +2532,7 @@ index 0fc6e659915a4547c2db9205fed205a1d28f21d4..35d1dcabb182b0a31727e5ddefe33955
// Paper start
for (Plugin plugin : pluginClone) {
entityMetadata.removeAll(plugin);
-@@ -1146,6 +1130,12 @@ public final class CraftServer implements Server {
+@@ -1149,6 +1133,12 @@ public final class CraftServer implements Server {
this.enablePlugins(PluginLoadOrder.STARTUP);
this.enablePlugins(PluginLoadOrder.POSTWORLD);
if (io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper != null) io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper.pluginsEnabled(); // Paper - Remap plugins
@@ -2575,11 +2571,11 @@ index 4b1ac1fe7ea07f419ae2818251900e7ba434ee16..90ed57a7fbcd0625b64084347460e986
public Map<String, Command> getKnownCommands() {
diff --git a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
-index 2ee33c55890fa659f6d251e486264c85d9e89802..d7a41421784cf9066518310e00031e26d9817171 100644
+index a35e2d2f53e8308d51e5a07b34c56d05a707bc14..945878e989f136ac516eb1c539c0626547c465fb 100644
--- a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
+++ b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
-@@ -23,14 +23,26 @@ import org.bukkit.craftbukkit.entity.CraftMinecartCommand;
- import org.bukkit.entity.Entity;
+@@ -23,14 +23,26 @@ import org.bukkit.craftbukkit.entity.CraftEntity;
+ import org.bukkit.craftbukkit.entity.CraftMinecartCommand;
import org.bukkit.entity.minecart.CommandMinecart;
-public final class VanillaCommandWrapper extends BukkitCommand {
@@ -2821,7 +2817,7 @@ index 0000000000000000000000000000000000000000..4b419ce023f61d5af9ff7a34e6879de1
+ }
+}
diff --git a/src/test/java/org/bukkit/support/DummyServerHelper.java b/src/test/java/org/bukkit/support/DummyServerHelper.java
-index 5d24b95e3eec351ec1e9444533dd5f9d376ec4c6..fb4b7625b4ea4b4918ade95829e10e98d1bac70f 100644
+index 2fed099bc91a8591a2415493b333f9c18bfe35f6..55c05c16a80c489cdda2fd03c943921d38d978e9 100644
--- a/src/test/java/org/bukkit/support/DummyServerHelper.java
+++ b/src/test/java/org/bukkit/support/DummyServerHelper.java
@@ -87,7 +87,7 @@ public final class DummyServerHelper {
diff --git a/patches/server/0958-Fix-issues-with-Recipe-API.patch b/patches/server/0958-Fix-issues-with-Recipe-API.patch
new file mode 100644
index 0000000000..bcc33fc956
--- /dev/null
+++ b/patches/server/0958-Fix-issues-with-Recipe-API.patch
@@ -0,0 +1,94 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jake Potrebic <[email protected]>
+Date: Sun, 12 May 2024 15:49:36 -0700
+Subject: [PATCH] Fix issues with Recipe API
+
+
+diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
+index dd02af6574dd97404bc9c02c9ead84e1dd537efe..980fea65899ef5f37808506b822fd3de5830d2c7 100644
+--- a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
++++ b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
+@@ -98,7 +98,7 @@ public class ShapedRecipe implements CraftingRecipe {
+ char c = 'a';
+ for (Optional<Ingredient> list : this.pattern.ingredients()) {
+ RecipeChoice choice = CraftRecipe.toBukkit(list);
+- if (choice != null) {
++ if (choice != RecipeChoice.empty()) { // Paper
+ recipe.setIngredient(c, choice);
+ }
+
+diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
+index a68e036a12b354c4f04b6596dfb9cd6e7663718b..d8af6522f7516de93e33cb9da8490f5ec14e7553 100644
+--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
+@@ -38,6 +38,10 @@ public interface CraftRecipe extends Recipe {
+ stack = Ingredient.of(((RecipeChoice.MaterialChoice) bukkit).getChoices().stream().map((mat) -> CraftItemType.bukkitToMinecraft(mat)));
+ } else if (bukkit instanceof RecipeChoice.ExactChoice) {
+ stack = Ingredient.ofStacks(((RecipeChoice.ExactChoice) bukkit).getChoices().stream().map((mat) -> CraftItemStack.asNMSCopy(mat)));
++ // Paper start - support "empty" choices
++ } else if (bukkit == RecipeChoice.empty()) {
++ stack = Ingredient.of();
++ // Paper end
+ } else {
+ throw new IllegalArgumentException("Unknown recipe stack instance " + bukkit);
+ }
+@@ -58,7 +62,7 @@ public interface CraftRecipe extends Recipe {
+ List<Holder<Item>> items = list.items();
+
+ if (items.isEmpty()) {
+- return null;
++ return RecipeChoice.empty(); // Paper - null breaks API contracts
+ }
+
+ if (list.isExact()) {
+diff --git a/src/test/java/io/papermc/paper/inventory/recipe/TestRecipeChoice.java b/src/test/java/io/papermc/paper/inventory/recipe/TestRecipeChoice.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..45ab2b6d32b29cb663df848534e1aa68293dd613
+--- /dev/null
++++ b/src/test/java/io/papermc/paper/inventory/recipe/TestRecipeChoice.java
+@@ -0,0 +1,25 @@
++package io.papermc.paper.inventory.recipe;
++
++import java.util.Iterator;
++import org.bukkit.Bukkit;
++import org.bukkit.inventory.Recipe;
++import org.bukkit.support.environment.AllFeatures;
++import org.junit.jupiter.api.Test;
++
++import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
++import static org.junit.jupiter.api.Assertions.assertTrue;
++
++@AllFeatures
++class TestRecipeChoice {
++
++ @Test
++ void testRecipeChoices() {
++ final Iterator<Recipe> iter = Bukkit.recipeIterator();
++ boolean foundRecipes = false;
++ while (iter.hasNext()) {
++ foundRecipes = true;
++ assertDoesNotThrow(iter::next, "Failed to convert a recipe to Bukkit recipe!");
++ }
++ assertTrue(foundRecipes, "No recipes found!");
++ }
++}
+diff --git a/src/test/java/org/bukkit/support/DummyServerHelper.java b/src/test/java/org/bukkit/support/DummyServerHelper.java
+index 55c05c16a80c489cdda2fd03c943921d38d978e9..6855816ec5fd232b53622c316e45b3c081297085 100644
+--- a/src/test/java/org/bukkit/support/DummyServerHelper.java
++++ b/src/test/java/org/bukkit/support/DummyServerHelper.java
+@@ -92,6 +92,15 @@ public final class DummyServerHelper {
+ // Paper end - testing additions
+
+ io.papermc.paper.configuration.GlobalConfigTestingBase.setupGlobalConfigForTest(); // Paper - configuration files - setup global configuration test base
++
++ // Paper start - add test for recipe conversion
++ when(instance.recipeIterator()).thenAnswer(ignored ->
++ com.google.common.collect.Iterators.transform(
++ RegistryHelper.getDataPack().getRecipeManager().byType.entries().iterator(),
++ input -> input.getValue().toBukkitRecipe()
++ )
++ );
++ // Paper end - add test for recipe conversion
+ return instance;
+ }
+ }
diff --git a/patches/unapplied/server/0967-Fix-equipment-slot-and-group-API.patch b/patches/server/0959-Fix-equipment-slot-and-group-API.patch
index e45968e407..ecc15fdf24 100644
--- a/patches/unapplied/server/0967-Fix-equipment-slot-and-group-API.patch
+++ b/patches/server/0959-Fix-equipment-slot-and-group-API.patch
@@ -10,10 +10,10 @@ Adds the following:
Co-authored-by: SoSeDiK <[email protected]>
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
-index fb6465bbb2a8bb7597c15d7ac8375f696b897e43..34641a6356876c46d05188a988c02835d0c06dc6 100644
+index a62d17b72c675120b447e625cb3dc437681bdf20..f16067b674118a47735ad22797988d50b4415040 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
-@@ -1211,4 +1211,11 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
+@@ -1230,4 +1230,11 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
this.getHandle().setYBodyRot(bodyYaw);
}
// Paper end - body yaw API
@@ -26,7 +26,7 @@ index fb6465bbb2a8bb7597c15d7ac8375f696b897e43..34641a6356876c46d05188a988c02835
+ // Paper end - Expose canUseSlot
}
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java
-index 9d74577af071954e1e37201a96368c1360076209..eafa54c870c3e2aef30c3f9f96f516607a7cae24 100644
+index 46d0b324498510c73a8439611f44269edee62313..69982103d8ea31e9b83b18c4c03a7b021bb983b9 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java
@@ -135,6 +135,10 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i
@@ -52,10 +52,10 @@ index 9d74577af071954e1e37201a96368c1360076209..eafa54c870c3e2aef30c3f9f96f51660
throw new IllegalArgumentException("Not implemented. This is a bug");
}
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
-index 88e1156510f3a43dd37e279205e5ed5dd120c1db..7f6f404f5a2be7876ae239355979e8c8a7a198ce 100644
+index 63567251d101b5e50ffd7e2825b1411fcb433c8c..450c5aa14b4195eb7123492c7a111ec6f40ce412 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
-@@ -1450,7 +1450,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1702,7 +1702,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
if (this.attributeModifiers == null) return LinkedHashMultimap.create(); // Paper - don't change the components
SetMultimap<Attribute, AttributeModifier> result = LinkedHashMultimap.create();
for (Map.Entry<Attribute, AttributeModifier> entry : this.attributeModifiers.entries()) {
@@ -64,7 +64,7 @@ index 88e1156510f3a43dd37e279205e5ed5dd120c1db..7f6f404f5a2be7876ae239355979e8c8
result.put(entry.getKey(), entry.getValue());
}
}
-@@ -1524,9 +1524,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+@@ -1776,9 +1776,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
while (iter.hasNext()) {
Map.Entry<Attribute, AttributeModifier> entry = iter.next();
diff --git a/patches/unapplied/server/0968-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch b/patches/server/0960-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch
index 8b39d13b43..8b39d13b43 100644
--- a/patches/unapplied/server/0968-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch
+++ b/patches/server/0960-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch
diff --git a/patches/unapplied/server/0969-Prevent-sending-oversized-item-data-in-equipment-and.patch b/patches/server/0961-Prevent-sending-oversized-item-data-in-equipment-and.patch
index 121b75eca6..b2a9a23cfe 100644
--- a/patches/unapplied/server/0969-Prevent-sending-oversized-item-data-in-equipment-and.patch
+++ b/patches/server/0961-Prevent-sending-oversized-item-data-in-equipment-and.patch
@@ -120,10 +120,10 @@ index 0000000000000000000000000000000000000000..72483dedd3b1864fca3463d3ba3f6fad
+ }
+}
diff --git a/src/main/java/net/minecraft/core/component/DataComponents.java b/src/main/java/net/minecraft/core/component/DataComponents.java
-index c9aef759c1485da753e820f9b509117ca50a31e4..60757f8df706cba92350d73503b73913cff3bcfc 100644
+index a7f6a53cd1168bfc53b616cb0586a546fb9793e7..5e3bfd4a06b4a547a5f813f3d0c533fb7f4451f3 100644
--- a/src/main/java/net/minecraft/core/component/DataComponents.java
+++ b/src/main/java/net/minecraft/core/component/DataComponents.java
-@@ -138,10 +138,10 @@ public class DataComponents {
+@@ -180,10 +180,10 @@ public class DataComponents {
"map_post_processing", builder -> builder.networkSynchronized(MapPostProcessing.STREAM_CODEC)
);
public static final DataComponentType<ChargedProjectiles> CHARGED_PROJECTILES = register(
@@ -136,7 +136,7 @@ index c9aef759c1485da753e820f9b509117ca50a31e4..60757f8df706cba92350d73503b73913
);
public static final DataComponentType<PotionContents> POTION_CONTENTS = register(
"potion_contents", builder -> builder.persistent(PotionContents.CODEC).networkSynchronized(PotionContents.STREAM_CODEC).cacheEncoding()
-@@ -208,7 +208,7 @@ public class DataComponents {
+@@ -250,7 +250,7 @@ public class DataComponents {
"pot_decorations", builder -> builder.persistent(PotDecorations.CODEC).networkSynchronized(PotDecorations.STREAM_CODEC).cacheEncoding()
);
public static final DataComponentType<ItemContainerContents> CONTAINER = register(
@@ -162,7 +162,7 @@ index 59c1c103545f04fd35e6932df64a9910a1d74cd7..56bde49e6b7790155b032d0be40961d5
buf.writeByte(255);
}
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java
-index 2ea7e90d582866b4e29db80836e250163d811763..d152871142d3def2ac04f50037db53b0527f7894 100644
+index e46030178b3b54168a3532def308a08b10888723..830bd76916e26a3a54954d3cf7b7520af52a2258 100644
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java
@@ -19,6 +19,13 @@ public class ClientboundSetEquipmentPacket implements Packet<ClientGamePacketLis
@@ -179,7 +179,7 @@ index 2ea7e90d582866b4e29db80836e250163d811763..d152871142d3def2ac04f50037db53b0
this.entity = entityId;
this.slots = equipmentList;
}
-@@ -41,6 +48,7 @@ public class ClientboundSetEquipmentPacket implements Packet<ClientGamePacketLis
+@@ -40,6 +47,7 @@ public class ClientboundSetEquipmentPacket implements Packet<ClientGamePacketLis
buf.writeVarInt(this.entity);
int i = this.slots.size();
@@ -187,7 +187,7 @@ index 2ea7e90d582866b4e29db80836e250163d811763..d152871142d3def2ac04f50037db53b0
for (int j = 0; j < i; j++) {
Pair<EquipmentSlot, ItemStack> pair = this.slots.get(j);
EquipmentSlot equipmentSlot = pair.getFirst();
-@@ -49,6 +57,7 @@ public class ClientboundSetEquipmentPacket implements Packet<ClientGamePacketLis
+@@ -48,6 +56,7 @@ public class ClientboundSetEquipmentPacket implements Packet<ClientGamePacketLis
buf.writeByte(bl ? k | -128 : k);
ItemStack.OPTIONAL_STREAM_CODEC.encode(buf, pair.getSecond());
}
@@ -196,10 +196,10 @@ index 2ea7e90d582866b4e29db80836e250163d811763..d152871142d3def2ac04f50037db53b0
@Override
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
-index 0e7ace92522fbd4cef7b2c2b8a0f8b86c2cce192..1d849ce4e2c85f149af25318b8ffb6dcef6c6788 100644
+index f3456aeeab7eee5b6d0383a4bf1338dd8cc95bb3..b2fd3e936559c8fcb8b02ae3ef63c4f3bd0edb08 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
-@@ -349,7 +349,7 @@ public class ServerEntity {
+@@ -388,7 +388,7 @@ public class ServerEntity {
}
if (!list.isEmpty()) {
@@ -209,10 +209,10 @@ index 0e7ace92522fbd4cef7b2c2b8a0f8b86c2cce192..1d849ce4e2c85f149af25318b8ffb6dc
((LivingEntity) this.entity).detectEquipmentUpdatesPublic(); // CraftBukkit - SPIGOT-3789: sync again immediately after sending
}
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index 5215783353021583e7a726d281e4d1734398f073..0fe4c3ff5dd855aea58292c16ba9a2f5d23c00f5 100644
+index 7508434475ea93f9153f3976c5fa95c7678807e9..dc8f2d0bc3adc87088e7289a90c9186483e21cf4 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -2731,7 +2731,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
+@@ -2743,7 +2743,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
entity.refreshEntityData(ServerGamePacketListenerImpl.this.player);
// SPIGOT-7136 - Allays
if (entity instanceof Allay || entity instanceof net.minecraft.world.entity.animal.horse.AbstractHorse) { // Paper - Fix horse armor desync
@@ -222,10 +222,10 @@ index 5215783353021583e7a726d281e4d1734398f073..0fe4c3ff5dd855aea58292c16ba9a2f5
ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote(); // Paper - fix slot desync - always refresh player inventory
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
-index b1e894e9a9cd87f7259302d15d5b5b0e2b32c4ea..7b6d067eb8b22a8e0a82a2969c92ba243230733a 100644
+index 6f9c4a5a87bdfb8ce32ce40c4a34997695d15ce3..5a992419f9847480ca6e431b5402d99ac411c15e 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
-@@ -3353,7 +3353,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -3462,7 +3462,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
});
diff --git a/patches/unapplied/server/0970-Prevent-NPE-if-hooked-entity-was-cleared.patch b/patches/server/0962-Prevent-NPE-if-hooked-entity-was-cleared.patch
index 8d3547db93..f51092a291 100644
--- a/patches/unapplied/server/0970-Prevent-NPE-if-hooked-entity-was-cleared.patch
+++ b/patches/server/0962-Prevent-NPE-if-hooked-entity-was-cleared.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Prevent NPE if hooked entity was cleared
diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
-index 270f4c94912b16c7d4a2d62670847cbb5e011819..6ce65e5b336be9b49db84f1c4755c2e2ce7f8378 100644
+index 5b49b11d2d88b33731df582b119ef7a680d862e9..762deff3bef8ec478d83139e8193aba35e39807d 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
-@@ -504,11 +504,13 @@ public class FishingHook extends Projectile {
+@@ -509,11 +509,13 @@ public class FishingHook extends Projectile {
if (playerFishEvent.isCancelled()) {
return 0;
}
diff --git a/patches/unapplied/server/0971-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch b/patches/server/0963-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch
index cee7f11394..a7fee3a0b4 100644
--- a/patches/unapplied/server/0971-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch
+++ b/patches/server/0963-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch
@@ -5,26 +5,26 @@ Subject: [PATCH] Fix cancelling BlockPlaceEvent calling onRemove
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
-index 58786dd7b51d17c1b602756c4c44840ab75ad0a7..96b24c1415af531feef7d8ab4724f7fed3ae8388 100644
+index 62529e61c8751433a8b6abe6cfb2cc414c8c3cf2..4f20e5bb143e152e19e5fb57f66d0344001ffbd9 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
-@@ -494,9 +494,11 @@ public final class ItemStack implements DataComponentHolder {
+@@ -500,9 +500,11 @@ public final class ItemStack implements DataComponentHolder {
world.capturedTileEntities.clear(); // Paper - Allow chests to be placed with NBT data; clear out block entities as chests and such will pop loot
- // revert back all captured blocks
- world.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710
+ // revert back all captured blocks
+ world.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710
+ world.isBlockPlaceCancelled = true; // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent
- for (BlockState blockstate : blocks) {
- blockstate.update(true, false);
- }
+ for (BlockState blockstate : blocks) {
+ blockstate.update(true, false);
+ }
+ world.isBlockPlaceCancelled = false; // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent
- world.preventPoiUpdated = false;
+ world.preventPoiUpdated = false;
- // Brute force all possible updates
+ // Brute force all possible updates
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
-index a2877f3eb206ab9ccb93e3606f1c9b3401def5d6..e5abde76c354c3dd9940dd4e5ae3fe8b6a2b4680 100644
+index 35b9a6d382e420844fc21c88b7d8044e3b8b8368..1b899473c6deeaa1aef9007d8b7bcec98580e61c 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
-@@ -151,6 +151,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+@@ -152,6 +152,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
public boolean preventPoiUpdated = false; // CraftBukkit - SPIGOT-5710
public boolean captureBlockStates = false;
public boolean captureTreeGeneration = false;
@@ -33,10 +33,10 @@ index a2877f3eb206ab9ccb93e3606f1c9b3401def5d6..e5abde76c354c3dd9940dd4e5ae3fe8b
public Map<BlockPos, BlockEntity> capturedTileEntities = new java.util.LinkedHashMap<>(); // Paper - Retain block place order when capturing blockstates
public List<ItemEntity> captureDrops;
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-index 86eb9029969f4de3ada7be9e135e9764172b85f5..21946a93b6a2a3c79d15af1d6e7eabc537ba0125 100644
+index 5dd1df0da1f954778aebe0f40611ae0f3a7866ab..325d1e38a72a4b30f30261267e9adfb8a8726b11 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-@@ -345,7 +345,7 @@ public class LevelChunk extends ChunkAccess {
+@@ -369,7 +369,7 @@ public class LevelChunk extends ChunkAccess {
boolean flag3 = iblockdata1.hasBlockEntity();
diff --git a/patches/unapplied/server/0972-Add-missing-fishing-event-state.patch b/patches/server/0964-Add-missing-fishing-event-state.patch
index 6ad1a92dd0..5bc1574135 100644
--- a/patches/unapplied/server/0972-Add-missing-fishing-event-state.patch
+++ b/patches/server/0964-Add-missing-fishing-event-state.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Add missing fishing event state
diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
-index 6ce65e5b336be9b49db84f1c4755c2e2ce7f8378..1223c5d23d0ea6aed068bdf0f5725e2ad49fc82c 100644
+index 762deff3bef8ec478d83139e8193aba35e39807d..4daa69c6be6d48563e30343a7e40e4da9ec7e5ad 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
-@@ -411,6 +411,15 @@ public class FishingHook extends Projectile {
+@@ -416,6 +416,15 @@ public class FishingHook extends Projectile {
this.fishAngle = Mth.nextFloat(this.random, this.minLureAngle, this.maxLureAngle);
this.timeUntilHooked = Mth.nextInt(this.random, this.minLureTime, this.maxLureTime);
// CraftBukkit end
diff --git a/patches/unapplied/server/0973-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch b/patches/server/0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch
index 23a507f4bf..fedf5ac805 100644
--- a/patches/unapplied/server/0973-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch
+++ b/patches/server/0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Deprecate InvAction#HOTBAR_MOVE_AND_READD
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index 0fe4c3ff5dd855aea58292c16ba9a2f5d23c00f5..0034483685ba626e5883b857de96ffd36e57e150 100644
+index dc8f2d0bc3adc87088e7289a90c9186483e21cf4..2533c0a54e74666a55a8478c7d4da12d26e31fd4 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -2997,14 +2997,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
+@@ -3014,14 +3014,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
Slot clickedSlot = this.player.containerMenu.getSlot(packet.getSlotNum());
if (clickedSlot.mayPickup(this.player)) {
ItemStack hotbar = this.player.getInventory().getItem(packet.getButtonNum());
diff --git a/patches/unapplied/server/0974-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch b/patches/server/0966-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch
index 1abf467e7e..1abf467e7e 100644
--- a/patches/unapplied/server/0974-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch
+++ b/patches/server/0966-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch
diff --git a/patches/unapplied/server/0975-Adopt-MaterialRerouting.patch b/patches/server/0967-Adopt-MaterialRerouting.patch
index 648057e1dd..648057e1dd 100644
--- a/patches/unapplied/server/0975-Adopt-MaterialRerouting.patch
+++ b/patches/server/0967-Adopt-MaterialRerouting.patch
diff --git a/patches/unapplied/server/0976-Suspicious-Effect-Entry-API.patch b/patches/server/0968-Suspicious-Effect-Entry-API.patch
index bc26031199..d2599dfa85 100644
--- a/patches/unapplied/server/0976-Suspicious-Effect-Entry-API.patch
+++ b/patches/server/0968-Suspicious-Effect-Entry-API.patch
@@ -14,7 +14,7 @@ in which it replaces PotionEffect.
Co-authored-by: Yannick Lamprecht <[email protected]>
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java
-index 9cc81bcccbf1141f66fedada1359b7c0dfa8e22a..5c5b64bd058684520fa175bfd10622ff57856b7c 100644
+index bfe39c7a9d2910bee9b40cf5ab4c154711d5cbb0..596146ad7899c21645df8834ce5f0afd6c1b0604 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java
@@ -37,16 +37,24 @@ public class CraftMushroomCow extends CraftCow implements MushroomCow, io.paperm
@@ -47,7 +47,7 @@ index 9cc81bcccbf1141f66fedada1359b7c0dfa8e22a..5c5b64bd058684520fa175bfd10622ff
return true;
}
@@ -101,6 +109,43 @@ public class CraftMushroomCow extends CraftCow implements MushroomCow, io.paperm
- this.getHandle().setVariant(net.minecraft.world.entity.animal.MushroomCow.MushroomType.values()[variant.ordinal()]);
+ this.getHandle().setVariant(net.minecraft.world.entity.animal.MushroomCow.Variant.values()[variant.ordinal()]);
}
+ // Paper start
diff --git a/patches/unapplied/server/0977-check-if-itemstack-is-stackable-first.patch b/patches/server/0969-check-if-itemstack-is-stackable-first.patch
index 8e11960bdd..a7ddd8df5b 100644
--- a/patches/unapplied/server/0977-check-if-itemstack-is-stackable-first.patch
+++ b/patches/server/0969-check-if-itemstack-is-stackable-first.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] check if itemstack is stackable first
diff --git a/src/main/java/net/minecraft/world/entity/player/Inventory.java b/src/main/java/net/minecraft/world/entity/player/Inventory.java
-index a62e7354bf67a66bdf9cd7c8f5d2e8f6bcacc74f..6e66141dca61f777b354854b5d0bac2570b8bf3b 100644
+index aaff1592876ac4a967e4fd47e4b6619a17d57867..ad82e5aeb565b23c3ec565fa60e1f31d1710bd4e 100644
--- a/src/main/java/net/minecraft/world/entity/player/Inventory.java
+++ b/src/main/java/net/minecraft/world/entity/player/Inventory.java
-@@ -111,7 +111,7 @@ public class Inventory implements Container, Nameable {
+@@ -110,7 +110,7 @@ public class Inventory implements Container, Nameable {
}
private boolean hasRemainingSpaceForItem(ItemStack existingStack, ItemStack stack) {
diff --git a/patches/unapplied/server/0978-Fix-removing-recipes-from-RecipeIterator.patch b/patches/server/0970-Fix-removing-recipes-from-RecipeIterator.patch
index 461c3eb854..636f3d2440 100644
--- a/patches/unapplied/server/0978-Fix-removing-recipes-from-RecipeIterator.patch
+++ b/patches/server/0970-Fix-removing-recipes-from-RecipeIterator.patch
@@ -7,7 +7,7 @@ Subject: [PATCH] Fix removing recipes from RecipeIterator
public net.minecraft.world.item.crafting.RecipeManager byName
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java b/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java
-index 78a2afa981407de793ac940d6eb7315c5cd53b8f..33cd12d55786356dc89ab9d3872b2f7d266c3de2 100644
+index 4e0f7564f04d5d566660a2623fb1b325e3b4e67c..39d2d67bf478beb4c72e41e6f59337893cf47e69 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java
@@ -9,6 +9,7 @@ import org.bukkit.inventory.Recipe;
@@ -17,7 +17,7 @@ index 78a2afa981407de793ac940d6eb7315c5cd53b8f..33cd12d55786356dc89ab9d3872b2f7d
+ private Recipe currentRecipe; // Paper - fix removing recipes from RecipeIterator
public RecipeIterator() {
- this.recipes = MinecraftServer.getServer().getRecipeManager().byType.entries().iterator();
+ this.recipes = MinecraftServer.getServer().getRecipeManager().recipes.byType.entries().iterator();
@@ -21,11 +22,19 @@ public class RecipeIterator implements Iterator<Recipe> {
@Override
diff --git a/patches/unapplied/server/0979-Configurable-damage-tick-when-blocking-with-shield.patch b/patches/server/0971-Configurable-damage-tick-when-blocking-with-shield.patch
index 7f58a8291d..0c36cdb62d 100644
--- a/patches/unapplied/server/0979-Configurable-damage-tick-when-blocking-with-shield.patch
+++ b/patches/server/0971-Configurable-damage-tick-when-blocking-with-shield.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Configurable damage tick when blocking with shield
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
-index 7b6d067eb8b22a8e0a82a2969c92ba243230733a..5f1c585c819d25319a4fefd30abde3de7620cf6d 100644
+index 5a992419f9847480ca6e431b5402d99ac411c15e..6195b207159c638e98a33c3142ed6b0720c8e14d 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
-@@ -2411,7 +2411,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -2488,7 +2488,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
CriteriaTriggers.PLAYER_HURT_ENTITY.trigger((ServerPlayer) damagesource.getEntity(), this, damagesource, originalDamage, f, true); // Paper - fix taken/dealt param order
}
diff --git a/patches/unapplied/server/0980-Properly-remove-the-experimental-smithing-inventory-.patch b/patches/server/0972-Properly-remove-the-experimental-smithing-inventory-.patch
index 9ede88caa7..9ede88caa7 100644
--- a/patches/unapplied/server/0980-Properly-remove-the-experimental-smithing-inventory-.patch
+++ b/patches/server/0972-Properly-remove-the-experimental-smithing-inventory-.patch
diff --git a/patches/unapplied/server/0966-Fix-issues-with-Recipe-API.patch b/patches/unapplied/server/0966-Fix-issues-with-Recipe-API.patch
deleted file mode 100644
index 415b2d65ba..0000000000
--- a/patches/unapplied/server/0966-Fix-issues-with-Recipe-API.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jake Potrebic <[email protected]>
-Date: Sun, 12 May 2024 15:49:36 -0700
-Subject: [PATCH] Fix issues with Recipe API
-
-
-diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
-index 63cf2b66f51df68aa3f6d98c69368ce454869d64..1bf54b0142fe41b29b21c8b97d3f52bb24a36a92 100644
---- a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
-+++ b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
-@@ -90,7 +90,7 @@ public class ShapedRecipe extends io.papermc.paper.inventory.recipe.RecipeBookEx
- char c = 'a';
- for (Ingredient list : this.pattern.ingredients()) {
- RecipeChoice choice = CraftRecipe.toBukkit(list);
-- if (choice != null) {
-+ if (choice != RecipeChoice.empty()) { // Paper
- recipe.setIngredient(c, choice);
- }
-
-diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
-index 6ba29875d78ede4aa7978ff689e588f7fed11528..c76c78bb7757d407102271463e14716a1b012deb 100644
---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
-+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
-@@ -29,6 +29,10 @@ public interface CraftRecipe extends Recipe {
- } else if (bukkit instanceof RecipeChoice.ExactChoice) {
- stack = new Ingredient(((RecipeChoice.ExactChoice) bukkit).getChoices().stream().map((mat) -> new net.minecraft.world.item.crafting.Ingredient.ItemValue(CraftItemStack.asNMSCopy(mat))));
- stack.exact = true;
-+ // Paper start - support "empty" choices
-+ } else if (bukkit == RecipeChoice.empty()) {
-+ stack = Ingredient.EMPTY;
-+ // Paper end
- } else {
- throw new IllegalArgumentException("Unknown recipe stack instance " + bukkit);
- }
-@@ -45,7 +49,7 @@ public interface CraftRecipe extends Recipe {
- list.getItems();
-
- if (list.itemStacks.length == 0) {
-- return null;
-+ return RecipeChoice.empty(); // Paper - null breaks API contracts
- }
-
- if (list.exact) {
-diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java
-index 37b39a2c696a59b0f52324cc222b83c0c9f341e6..3aec771478a6b17353d57e82baac53dd24779e7b 100644
---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java
-+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java
-@@ -30,6 +30,6 @@ public class CraftSmithingTransformRecipe extends SmithingTransformRecipe implem
- public void addToCraftingManager() {
- ItemStack result = this.getResult();
-
-- MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTransformRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), CraftItemStack.asNMSCopy(result), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy
-+ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTransformRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), CraftItemStack.asNMSCopy(result), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy & support empty RecipeChoice
- }
- }
-diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java
-index 389fa313f811279091cace76faaabf8bdb0fc94c..61af2fe3534ff67f10310c6c7dec39cff0f93ee3 100644
---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java
-+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java
-@@ -28,6 +28,6 @@ public class CraftSmithingTrimRecipe extends SmithingTrimRecipe implements Craft
-
- @Override
- public void addToCraftingManager() {
-- MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTrimRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy
-+ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTrimRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy & support empty RecipeChoice
- }
- }
-diff --git a/src/test/java/io/papermc/paper/inventory/recipe/TestRecipeChoice.java b/src/test/java/io/papermc/paper/inventory/recipe/TestRecipeChoice.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..45ab2b6d32b29cb663df848534e1aa68293dd613
---- /dev/null
-+++ b/src/test/java/io/papermc/paper/inventory/recipe/TestRecipeChoice.java
-@@ -0,0 +1,25 @@
-+package io.papermc.paper.inventory.recipe;
-+
-+import java.util.Iterator;
-+import org.bukkit.Bukkit;
-+import org.bukkit.inventory.Recipe;
-+import org.bukkit.support.environment.AllFeatures;
-+import org.junit.jupiter.api.Test;
-+
-+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
-+import static org.junit.jupiter.api.Assertions.assertTrue;
-+
-+@AllFeatures
-+class TestRecipeChoice {
-+
-+ @Test
-+ void testRecipeChoices() {
-+ final Iterator<Recipe> iter = Bukkit.recipeIterator();
-+ boolean foundRecipes = false;
-+ while (iter.hasNext()) {
-+ foundRecipes = true;
-+ assertDoesNotThrow(iter::next, "Failed to convert a recipe to Bukkit recipe!");
-+ }
-+ assertTrue(foundRecipes, "No recipes found!");
-+ }
-+}
-diff --git a/src/test/java/org/bukkit/support/DummyServerHelper.java b/src/test/java/org/bukkit/support/DummyServerHelper.java
-index fb4b7625b4ea4b4918ade95829e10e98d1bac70f..cb2b39c562f609375b9e5b20cb5899780995373d 100644
---- a/src/test/java/org/bukkit/support/DummyServerHelper.java
-+++ b/src/test/java/org/bukkit/support/DummyServerHelper.java
-@@ -92,6 +92,15 @@ public final class DummyServerHelper {
- // Paper end - testing additions
-
- io.papermc.paper.configuration.GlobalConfigTestingBase.setupGlobalConfigForTest(); // Paper - configuration files - setup global configuration test base
-+
-+ // Paper start - add test for recipe conversion
-+ when(instance.recipeIterator()).thenAnswer(ignored ->
-+ com.google.common.collect.Iterators.transform(
-+ RegistryHelper.getDataPack().getRecipeManager().byType.entries().iterator(),
-+ input -> input.getValue().toBukkitRecipe()
-+ )
-+ );
-+ // Paper end - add test for recipe conversion
- return instance;
- }
- }