diff --git a/patches/api/Add-ArmorStand-Item-Meta.patch b/patches/api/Add-ArmorStand-Item-Meta.patch
index ce87a5ebb3..78cb5cbb68 100644
--- a/patches/api/Add-ArmorStand-Item-Meta.patch
+++ b/patches/api/Add-ArmorStand-Item-Meta.patch
@@ -94,3 +94,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     */
 +    void setMarker(boolean marker);
 +}
+diff --git a/src/main/java/org/bukkit/inventory/ItemType.java b/src/main/java/org/bukkit/inventory/ItemType.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/inventory/ItemType.java
++++ b/src/main/java/org/bukkit/inventory/ItemType.java
+@@ -0,0 +0,0 @@ public interface ItemType extends Keyed, Translatable {
+     ItemType.Typed<ItemMeta> RABBIT_STEW = getItemType("rabbit_stew");
+     ItemType.Typed<ItemMeta> RABBIT_FOOT = getItemType("rabbit_foot");
+     ItemType.Typed<ItemMeta> RABBIT_HIDE = getItemType("rabbit_hide");
+-    ItemType.Typed<ItemMeta> ARMOR_STAND = getItemType("armor_stand");
++    ItemType.Typed<com.destroystokyo.paper.inventory.meta.ArmorStandMeta> ARMOR_STAND = getItemType("armor_stand");
+     ItemType.Typed<ItemMeta> IRON_HORSE_ARMOR = getItemType("iron_horse_armor");
+     ItemType.Typed<ItemMeta> GOLDEN_HORSE_ARMOR = getItemType("golden_horse_armor");
+     ItemType.Typed<ItemMeta> DIAMOND_HORSE_ARMOR = getItemType("diamond_horse_armor");
diff --git a/patches/api/Add-RegistryAccess-for-managing-registries.patch b/patches/api/Add-RegistryAccess-for-managing-registries.patch
index 3965dd7f1d..51d225812e 100644
--- a/patches/api/Add-RegistryAccess-for-managing-registries.patch
+++ b/patches/api/Add-RegistryAccess-for-managing-registries.patch
@@ -209,6 +209,15 @@ diff --git a/src/main/java/org/bukkit/Registry.java b/src/main/java/org/bukkit/R
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/Registry.java
 +++ b/src/main/java/org/bukkit/Registry.java
+@@ -0,0 +0,0 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
+      * @apiNote BlockType is not ready for public usage yet
+      */
+     @ApiStatus.Internal
+-    Registry<BlockType> BLOCK = Objects.requireNonNull(Bukkit.getRegistry(BlockType.class), "No registry present for BlockType. This is a bug.");
++    Registry<BlockType> BLOCK = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.BLOCK); // Paper
+     /**
+      * Custom boss bars.
+      *
 @@ -0,0 +0,0 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
       *
       * @see Enchantment
@@ -224,6 +233,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
       */
 -    Registry<MusicInstrument> INSTRUMENT = Objects.requireNonNull(Bukkit.getRegistry(MusicInstrument.class), "No registry present for MusicInstrument. This is a bug.");
 +    Registry<MusicInstrument> INSTRUMENT = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.INSTRUMENT); // Paper
+     /**
+      * Server item types.
+      *
+@@ -0,0 +0,0 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
+      * @apiNote ItemType is not ready for public usage yet
+      */
+     @ApiStatus.Internal
+-    Registry<ItemType> ITEM = Objects.requireNonNull(Bukkit.getRegistry(ItemType.class), "No registry present for ItemType. This is a bug.");
++    Registry<ItemType> ITEM = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.ITEM); // Paper
      /**
       * Default server loot tables.
       *
diff --git a/patches/api/Add-exploded-block-state-to-EntityDamageByBlockEvent.patch b/patches/api/Add-exploded-block-state-to-EntityDamageByBlockEvent.patch
deleted file mode 100644
index 3483daaa0b..0000000000
--- a/patches/api/Add-exploded-block-state-to-EntityDamageByBlockEvent.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jake Potrebic <jake.m.potrebic@gmail.com>
-Date: Fri, 22 Oct 2021 16:24:17 -0700
-Subject: [PATCH] Add exploded block state to EntityDamageByBlockEvent
-
-
-diff --git a/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java b/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java
-+++ b/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java
-@@ -0,0 +0,0 @@ public class BlockExplodeEvent extends BlockEvent implements Cancellable {
-         this.cancel = false;
-     }
- 
-+    @io.papermc.paper.annotation.DoNotUse // Paper
-     @Deprecated(forRemoval = true)
-     public BlockExplodeEvent(@NotNull final Block what, @NotNull final List<Block> blocks, final float yield) {
-         this(what, what.getState(), blocks, yield);
-diff --git a/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java b/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java
-+++ b/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java
-@@ -0,0 +0,0 @@ import org.jetbrains.annotations.Nullable;
- 
- /**
-  * Called when an entity is damaged by a block
-+ * <p>
-+ * For explosions, the Block returned by {@link #getDamager()} has
-+ * already been cleared. See {@link #getDamagerBlockState()} for a snapshot
-+ * of the block if it has already been changed.
-  */
- public class EntityDamageByBlockEvent extends EntityDamageEvent {
-     private final Block damager;
-+    private final org.bukkit.block.BlockState damagerBlockState; // Paper
- 
-     @Deprecated(forRemoval = true)
-     public EntityDamageByBlockEvent(@Nullable final Block damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, final double damage) {
--        this(damager, damagee, cause, (damager != null) ? DamageSource.builder(DamageType.GENERIC).withDamageLocation(damager.getLocation()).build() : DamageSource.builder(DamageType.GENERIC).build(), damage);
-+        this(damager, damagee, cause, (damager != null) ? DamageSource.builder(DamageType.GENERIC).withDamageLocation(damager.getLocation()).build() : DamageSource.builder(DamageType.GENERIC).build(), damage, null); // Paper
-     }
- 
--    public EntityDamageByBlockEvent(@Nullable final Block damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final DamageSource damageSource, final double damage) {
-+    public EntityDamageByBlockEvent(@Nullable final Block damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final DamageSource damageSource, final double damage, final @Nullable org.bukkit.block.BlockState damagerBlockState) { // Paper
-         super(damagee, cause, damageSource, damage);
-         this.damager = damager;
-+        this.damagerBlockState = damagerBlockState; // Paper
-     }
- 
-     @Deprecated(forRemoval = true)
-     public EntityDamageByBlockEvent(@Nullable final Block damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final Map<DamageModifier, Double> modifiers, @NotNull final Map<DamageModifier, ? extends Function<? super Double, Double>> modifierFunctions) {
--        this(damager, damagee, cause, (damager != null) ? DamageSource.builder(DamageType.GENERIC).withDamageLocation(damager.getLocation()).build() : DamageSource.builder(DamageType.GENERIC).build(), modifiers, modifierFunctions);
-+        this(damager, damagee, cause, (damager != null) ? DamageSource.builder(DamageType.GENERIC).withDamageLocation(damager.getLocation()).build() : DamageSource.builder(DamageType.GENERIC).build(), modifiers, modifierFunctions, null); // Paper
-     }
- 
--    public EntityDamageByBlockEvent(@Nullable final Block damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final DamageSource damageSource, @NotNull final Map<DamageModifier, Double> modifiers, @NotNull final Map<DamageModifier, ? extends Function<? super Double, Double>> modifierFunctions) {
-+    public EntityDamageByBlockEvent(@Nullable final Block damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final DamageSource damageSource, @NotNull final Map<DamageModifier, Double> modifiers, @NotNull final Map<DamageModifier, ? extends Function<? super Double, Double>> modifierFunctions, final @Nullable org.bukkit.block.BlockState damagerBlockState) { // Paper
-         super(damagee, cause, damageSource, modifiers, modifierFunctions);
-         this.damager = damager;
-+        this.damagerBlockState = damagerBlockState; // Paper
-     }
- 
-     /**
-@@ -0,0 +0,0 @@ public class EntityDamageByBlockEvent extends EntityDamageEvent {
-     public Block getDamager() {
-         return damager;
-     }
-+
-+    // Paper start
-+    /**
-+    * Get a capture of the block that directly caused
-+    * the damage, like a bed or respawn anchor. This
-+    * block state is not placed so {@link org.bukkit.block.BlockState#isPlaced}
-+    * will be false.
-+    * <p>
-+    * Can be null if the block wasn't changed before the event
-+    *
-+    * @return the damager block state or null if not applicable
-+    */
-+    public @Nullable org.bukkit.block.BlockState getDamagerBlockState() {
-+        return this.damagerBlockState;
-+    }
-+    // Paper end
- }
diff --git a/patches/api/Add-methods-to-get-translation-keys.patch b/patches/api/Add-methods-to-get-translation-keys.patch
index 451778d9df..89bc88a36c 100644
--- a/patches/api/Add-methods-to-get-translation-keys.patch
+++ b/patches/api/Add-methods-to-get-translation-keys.patch
@@ -183,7 +183,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated(forRemoval = true) // Paper
      public String getTranslationKey() {
          if (this.isItem()) {
-             return Bukkit.getUnsafe().getItemTranslationKey(this);
+             return asItemType().getTranslationKey();
 diff --git a/src/main/java/org/bukkit/MusicInstrument.java b/src/main/java/org/bukkit/MusicInstrument.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/MusicInstrument.java
diff --git a/patches/api/Adventure.patch b/patches/api/Adventure.patch
index 587b686919..1437c86869 100644
--- a/patches/api/Adventure.patch
+++ b/patches/api/Adventure.patch
@@ -3185,18 +3185,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      private boolean keepInventory = false;
 +    // Paper start - adventure
 +    @org.jetbrains.annotations.ApiStatus.Internal
-+    public PlayerDeathEvent(final @NotNull Player player, final @NotNull List<ItemStack> drops, final int droppedExp, final @Nullable net.kyori.adventure.text.Component deathMessage) {
-+        this(player, drops, droppedExp, 0, deathMessage);
++    public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List<ItemStack> drops, final int droppedExp, final @Nullable net.kyori.adventure.text.Component deathMessage) {
++        this(player, damageSource, drops, droppedExp, 0, deathMessage);
 +    }
 +
 +    @org.jetbrains.annotations.ApiStatus.Internal
-+    public PlayerDeathEvent(final @NotNull Player player, final @NotNull List<ItemStack> drops, final int droppedExp, final int newExp, final @Nullable net.kyori.adventure.text.Component deathMessage) {
-+        this(player, drops, droppedExp, newExp, 0, 0, deathMessage);
++    public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List<ItemStack> drops, final int droppedExp, final int newExp, final @Nullable net.kyori.adventure.text.Component deathMessage) {
++        this(player, damageSource, drops, droppedExp, newExp, 0, 0, deathMessage);
 +    }
 +
 +    @org.jetbrains.annotations.ApiStatus.Internal
-+    public PlayerDeathEvent(final @NotNull Player player, final @NotNull List<ItemStack> drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, final @Nullable net.kyori.adventure.text.Component deathMessage) {
-+        super(player, drops, droppedExp);
++    public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List<ItemStack> drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, final @Nullable net.kyori.adventure.text.Component deathMessage) {
++        super(player, damageSource, drops, droppedExp);
 +        this.newExp = newExp;
 +        this.newTotalExp = newTotalExp;
 +        this.newLevel = newLevel;
@@ -3205,18 +3205,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    // Paper end - adventure
  
 +    @Deprecated // Paper
-     public PlayerDeathEvent(@NotNull final Player player, @NotNull final List<ItemStack> drops, final int droppedExp, @Nullable final String deathMessage) {
-         this(player, drops, droppedExp, 0, deathMessage);
+     public PlayerDeathEvent(@NotNull final Player player, @NotNull DamageSource damageSource, @NotNull final List<ItemStack> drops, final int droppedExp, @Nullable final String deathMessage) {
+         this(player, damageSource, drops, droppedExp, 0, deathMessage);
      }
  
 +    @Deprecated // Paper
-     public PlayerDeathEvent(@NotNull final Player player, @NotNull final List<ItemStack> drops, final int droppedExp, final int newExp, @Nullable final String deathMessage) {
-         this(player, drops, droppedExp, newExp, 0, 0, deathMessage);
+     public PlayerDeathEvent(@NotNull final Player player, @NotNull DamageSource damageSource, @NotNull final List<ItemStack> drops, final int droppedExp, final int newExp, @Nullable final String deathMessage) {
+         this(player, damageSource, drops, droppedExp, newExp, 0, 0, deathMessage);
      }
  
 +    @Deprecated // Paper
-     public PlayerDeathEvent(@NotNull final Player player, @NotNull final List<ItemStack> drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, @Nullable final String deathMessage) {
-         super(player, drops, droppedExp);
+     public PlayerDeathEvent(@NotNull final Player player, @NotNull DamageSource damageSource, @NotNull final List<ItemStack> drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, @Nullable final String deathMessage) {
+         super(player, damageSource, drops, droppedExp);
          this.newExp = newExp;
          this.newTotalExp = newTotalExp;
          this.newLevel = newLevel;
diff --git a/patches/api/Cache-the-result-of-Material-isBlock.patch b/patches/api/Cache-the-result-of-Material-isBlock.patch
deleted file mode 100644
index bf400a5790..0000000000
--- a/patches/api/Cache-the-result-of-Material-isBlock.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
-Date: Tue, 2 Mar 2021 15:24:58 -0800
-Subject: [PATCH] Cache the result of Material#isBlock
-
-
-diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/Material.java
-+++ b/src/main/java/org/bukkit/Material.java
-@@ -0,0 +0,0 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla
-     public final Class<?> data;
-     private final boolean legacy;
-     private final NamespacedKey key;
-+    private boolean isBlock; // Paper
- 
-     private Material(final int id) {
-         this(id, 64);
-@@ -0,0 +0,0 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla
-      * @return true if this material is a block
-      */
-     public boolean isBlock() {
-+    // Paper start - cache isBlock
-+        return this.isBlock;
-+    }
-+    private boolean isBlock0() {
-+    // Paper end
-         switch (this) {
-             //<editor-fold defaultstate="collapsed" desc="isBlock">
-             case ACACIA_BUTTON:
-@@ -0,0 +0,0 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla
-     static {
-         for (Material material : values()) {
-             BY_NAME.put(material.name(), material);
-+            material.isBlock = material.isBlock0(); // Paper
-         }
-     }
- 
diff --git a/patches/api/Code-Generation.patch b/patches/api/Code-Generation.patch
index 787a87fe49..255daf5519 100644
--- a/patches/api/Code-Generation.patch
+++ b/patches/api/Code-Generation.patch
@@ -100,6 +100,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.Sound;
 +import org.bukkit.attribute.Attribute;
 +import org.bukkit.block.Biome;
++import org.bukkit.block.BlockType;
 +import org.bukkit.block.banner.PatternType;
 +import org.bukkit.damage.DamageType;
 +import org.bukkit.enchantments.Enchantment;
@@ -111,11 +112,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.entity.memory.MemoryKey;
 +import org.bukkit.generator.structure.Structure;
 +import org.bukkit.generator.structure.StructureType;
++import org.bukkit.inventory.ItemType;
 +import org.bukkit.inventory.meta.trim.TrimMaterial;
 +import org.bukkit.inventory.meta.trim.TrimPattern;
 +import org.bukkit.map.MapCursor;
 +import org.bukkit.potion.PotionEffectType;
 +import org.bukkit.potion.PotionType;
++import org.jetbrains.annotations.ApiStatus;
 +
 +import static io.papermc.paper.registry.RegistryKeyImpl.create;
 +
@@ -162,6 +165,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @see io.papermc.paper.registry.keys.MobEffectKeys
 +     */
 +    RegistryKey<PotionEffectType> MOB_EFFECT = create("mob_effect");
++    /**
++     * @apiNote DO NOT USE
++     */
++    @ApiStatus.Internal
++    RegistryKey<BlockType> BLOCK = create("block");
++    /**
++     * @apiNote DO NOT USE
++     */
++    @ApiStatus.Internal
++    RegistryKey<ItemType> ITEM = create("item");
 +
 +
 +    /* ********************** *
diff --git a/patches/api/Fix-Spigot-annotation-mistakes.patch b/patches/api/Fix-Spigot-annotation-mistakes.patch
index ffbb5e6e09..2a1a334ba0 100644
--- a/patches/api/Fix-Spigot-annotation-mistakes.patch
+++ b/patches/api/Fix-Spigot-annotation-mistakes.patch
@@ -349,8 +349,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
       */
 +    @Deprecated // Paper
      public boolean isInteractable() {
-         switch (this) {
-             // <editor-fold defaultstate="collapsed" desc="isInteractable">
+         BlockType type = asBlockType();
+         return type != null && type.isInteractable();
 diff --git a/src/main/java/org/bukkit/NamespacedKey.java b/src/main/java/org/bukkit/NamespacedKey.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/NamespacedKey.java
@@ -1415,9 +1415,9 @@ diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/o
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/inventory/ItemStack.java
 +++ b/src/main/java/org/bukkit/inventory/ItemStack.java
-@@ -0,0 +0,0 @@ import java.util.Map;
- import org.bukkit.Bukkit;
- import org.bukkit.Material;
+@@ -0,0 +0,0 @@ import org.bukkit.Material;
+ import org.bukkit.NamespacedKey;
+ import org.bukkit.Registry;
  import org.bukkit.Translatable;
 +import org.bukkit.UndefinedNullability;
  import org.bukkit.Utility;
diff --git a/patches/api/Fix-upstream-javadocs.patch b/patches/api/Fix-upstream-javadocs.patch
index ef356ba2c1..993026f897 100644
--- a/patches/api/Fix-upstream-javadocs.patch
+++ b/patches/api/Fix-upstream-javadocs.patch
@@ -626,6 +626,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
   */
  public class BlockExplodeEvent extends BlockEvent implements Cancellable {
      private static final HandlerList handlers = new HandlerList();
+@@ -0,0 +0,0 @@ public class BlockExplodeEvent extends BlockEvent implements Cancellable {
+         this.cancel = false;
+     }
+ 
++    @io.papermc.paper.annotation.DoNotUse // Paper
+     @Deprecated(forRemoval = true)
+     public BlockExplodeEvent(@NotNull final Block what, @NotNull final List<Block> blocks, final float yield) {
+         this(what, what.getState(), blocks, yield);
 diff --git a/src/main/java/org/bukkit/event/block/BlockPistonRetractEvent.java b/src/main/java/org/bukkit/event/block/BlockPistonRetractEvent.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/event/block/BlockPistonRetractEvent.java
@@ -697,6 +705,31 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
           */
          EXPLOSION,
          /**
+diff --git a/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java b/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java
++++ b/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java
+@@ -0,0 +0,0 @@ import org.jetbrains.annotations.Nullable;
+ 
+ /**
+  * Called when an entity is damaged by a block
++ * <p>
++ * For explosions, the Block returned by {@link #getDamager()} has
++ * already been cleared. See {@link #getDamagerBlockState()} for a snapshot
++ * of the block if it has already been changed.
+  */
+ public class EntityDamageByBlockEvent extends EntityDamageEvent {
+     private final Block damager;
+@@ -0,0 +0,0 @@ public class EntityDamageByBlockEvent extends EntityDamageEvent {
+ 
+     /**
+      * Returns the captured BlockState of the block that damaged the player.
++     * <p>
++     * This block state is not placed so {@link org.bukkit.block.BlockState#isPlaced}
++     * will be false.
+      *
+      * @return the block state
+      */
 diff --git a/src/main/java/org/bukkit/event/entity/EntityExplodeEvent.java b/src/main/java/org/bukkit/event/entity/EntityExplodeEvent.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/event/entity/EntityExplodeEvent.java
diff --git a/patches/api/Improve-Registry.patch b/patches/api/Improve-Registry.patch
index 5f32a3d8b9..f0f3c2d868 100644
--- a/patches/api/Improve-Registry.patch
+++ b/patches/api/Improve-Registry.patch
@@ -85,8 +85,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
       * Returns a new stream, which contains all registry items, which are registered to the registry.
       *
 @@ -0,0 +0,0 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
-         public Iterator<T> iterator() {
-             return map.values().iterator();
+         public Class<T> getType() {
+             return this.type;
          }
 +
 +        // Paper start - improve Registry
diff --git a/patches/api/Improve-death-events.patch b/patches/api/Improve-death-events.patch
index cc78ed422c..34e847f6f5 100644
--- a/patches/api/Improve-death-events.patch
+++ b/patches/api/Improve-death-events.patch
@@ -30,6 +30,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -public class EntityDeathEvent extends EntityEvent {
 +public class EntityDeathEvent extends EntityEvent implements org.bukkit.event.Cancellable {  // Paper - make cancellable
      private static final HandlerList handlers = new HandlerList();
+     private final DamageSource damageSource;
      private final List<ItemStack> drops;
      private int dropExp = 0;
 +    // Paper start - make cancellable
@@ -42,8 +43,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private float deathSoundPitch;
 +    // Paper end
  
-     public EntityDeathEvent(@NotNull final LivingEntity entity, @NotNull final List<ItemStack> drops) {
-         this(entity, drops, 0);
+     public EntityDeathEvent(@NotNull final LivingEntity entity, @NotNull DamageSource damageSource, @NotNull final List<ItemStack> drops) {
+         this(entity, damageSource, drops, 0);
 @@ -0,0 +0,0 @@ public class EntityDeathEvent extends EntityEvent {
      public static HandlerList getHandlerList() {
          return handlers;
diff --git a/patches/api/ItemStack-API-additions-for-quantity-flags-lore.patch b/patches/api/ItemStack-API-additions-for-quantity-flags-lore.patch
index 56a61718f2..758f8221e9 100644
--- a/patches/api/ItemStack-API-additions-for-quantity-flags-lore.patch
+++ b/patches/api/ItemStack-API-additions-for-quantity-flags-lore.patch
@@ -8,14 +8,6 @@ diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/o
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/inventory/ItemStack.java
 +++ b/src/main/java/org/bukkit/inventory/ItemStack.java
-@@ -0,0 +0,0 @@ package org.bukkit.inventory;
- import com.google.common.base.Preconditions;
- import com.google.common.collect.ImmutableMap;
- import java.util.LinkedHashMap;
-+import java.util.List; // Paper
- import java.util.Map;
- import org.bukkit.Bukkit;
- import org.bukkit.Material;
 @@ -0,0 +0,0 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
          // Requires access to NMS
          return ensureServerConversions().getMaxItemUseDuration();
@@ -90,7 +82,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @deprecated in favor of {@link #lore()}
 +     */
 +    @Deprecated
-+    public @Nullable List<String> getLore() {
++    public @Nullable java.util.List<String> getLore() {
 +        if (!hasItemMeta()) {
 +            return null;
 +        }
@@ -105,7 +97,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * If the item has lore, returns it, else it will return null
 +     * @return The lore, or null
 +     */
-+    public @Nullable List<net.kyori.adventure.text.Component> lore() {
++    public @Nullable java.util.List<net.kyori.adventure.text.Component> lore() {
 +        if (!this.hasItemMeta()) {
 +            return null;
 +        }
@@ -121,10 +113,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * Removes lore when given null.
 +     *
 +     * @param lore the lore that will be set
-+     * @deprecated in favour of {@link #lore(List)}
++     * @deprecated in favour of {@link #lore(java.util.List)}
 +     */
 +    @Deprecated
-+    public void setLore(@Nullable List<String> lore) {
++    public void setLore(@Nullable java.util.List<String> lore) {
 +        ItemMeta itemMeta = getItemMeta();
 +        if (itemMeta == null) {
 +            throw new IllegalStateException("Cannot set lore on " + getType());
@@ -139,7 +131,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param lore the lore that will be set
 +     */
-+    public void lore(@Nullable List<? extends net.kyori.adventure.text.Component> lore) {
++    public void lore(@Nullable java.util.List<? extends net.kyori.adventure.text.Component> lore) {
 +        ItemMeta itemMeta = getItemMeta();
 +        if (itemMeta == null) {
 +            throw new IllegalStateException("Cannot set lore on " + getType());
diff --git a/patches/api/ItemStack-Tooltip-API.patch b/patches/api/ItemStack-Tooltip-API.patch
index c00fd54c40..43649dade3 100644
--- a/patches/api/ItemStack-Tooltip-API.patch
+++ b/patches/api/ItemStack-Tooltip-API.patch
@@ -139,7 +139,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @return an immutable list of components (can be empty)
 +     */
 +    @SuppressWarnings("deprecation") // abusing unsafe as a bridge
-+    public @NotNull @org.jetbrains.annotations.Unmodifiable List<net.kyori.adventure.text.Component> computeTooltipLines(final @NotNull io.papermc.paper.inventory.tooltip.TooltipContext tooltipContext, final @Nullable org.bukkit.entity.Player player) {
++    public java.util.@NotNull @org.jetbrains.annotations.Unmodifiable List<net.kyori.adventure.text.Component> computeTooltipLines(final @NotNull io.papermc.paper.inventory.tooltip.TooltipContext tooltipContext, final @Nullable org.bukkit.entity.Player player) {
 +        return Bukkit.getUnsafe().computeTooltipLines(this, tooltipContext, player);
 +    }
 +    // Paper end - expose itemstack tooltip lines
diff --git a/patches/api/Paper-Plugins.patch b/patches/api/Paper-Plugins.patch
index 973e380fb9..939179798e 100644
--- a/patches/api/Paper-Plugins.patch
+++ b/patches/api/Paper-Plugins.patch
@@ -1351,9 +1351,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/UnsafeValues.java
 +++ b/src/main/java/org/bukkit/UnsafeValues.java
 @@ -0,0 +0,0 @@ public interface UnsafeValues {
+ 
      @ApiStatus.Internal
-     @NotNull
-     DamageSource.Builder createDamageSourceBuilder(@NotNull DamageType damageType);
+     <B extends Keyed> B get(Registry<B> registry, NamespacedKey key);
++
 +    // Paper start
 +    @Deprecated(forRemoval = true)
 +    boolean isSupportedApiVersion(String apiVersion);
diff --git a/patches/api/PlayerDeathEvent-getItemsToKeep.patch b/patches/api/PlayerDeathEvent-getItemsToKeep.patch
index 9b2d7d1f59..e8954efec3 100644
--- a/patches/api/PlayerDeathEvent-getItemsToKeep.patch
+++ b/patches/api/PlayerDeathEvent-getItemsToKeep.patch
@@ -11,14 +11,6 @@ diff --git a/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java b/src/m
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java
 +++ b/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java
-@@ -0,0 +0,0 @@ public class PlayerDeathEvent extends EntityDeathEvent {
-     }
-     // Paper end - adventure
- 
--    @Deprecated // Paper
-     public PlayerDeathEvent(@NotNull final Player player, @NotNull final List<ItemStack> drops, final int droppedExp, @Nullable final String deathMessage) {
-         this(player, drops, droppedExp, 0, deathMessage);
-     }
 @@ -0,0 +0,0 @@ public class PlayerDeathEvent extends EntityDeathEvent {
          this.deathMessage = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserializeOrNull(deathMessage); // Paper
      }
diff --git a/patches/api/PlayerDeathEvent-shouldDropExperience.patch b/patches/api/PlayerDeathEvent-shouldDropExperience.patch
index a695a178db..0bf4864d6c 100644
--- a/patches/api/PlayerDeathEvent-shouldDropExperience.patch
+++ b/patches/api/PlayerDeathEvent-shouldDropExperience.patch
@@ -15,18 +15,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private boolean doExpDrop; // Paper - shouldDropExperience API
      // Paper start - adventure
      @org.jetbrains.annotations.ApiStatus.Internal
-     public PlayerDeathEvent(final @NotNull Player player, final @NotNull List<ItemStack> drops, final int droppedExp, final @Nullable net.kyori.adventure.text.Component deathMessage) {
+     public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List<ItemStack> drops, final int droppedExp, final @Nullable net.kyori.adventure.text.Component deathMessage) {
 @@ -0,0 +0,0 @@ public class PlayerDeathEvent extends EntityDeathEvent {
  
      @org.jetbrains.annotations.ApiStatus.Internal
-     public PlayerDeathEvent(final @NotNull Player player, final @NotNull List<ItemStack> drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, final @Nullable net.kyori.adventure.text.Component deathMessage) {
+     public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List<ItemStack> drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, final @Nullable net.kyori.adventure.text.Component deathMessage) {
 +        // Paper start - shouldDropExperience API
-+        this(player, drops, droppedExp, newExp, newTotalExp, newLevel, deathMessage, true);
++        this(player, damageSource, drops, droppedExp, newExp, newTotalExp, newLevel, deathMessage, true);
 +    }
 +    @org.jetbrains.annotations.ApiStatus.Internal
-+    public PlayerDeathEvent(final @NotNull Player player, final @NotNull List<ItemStack> drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, final @Nullable net.kyori.adventure.text.Component deathMessage, final boolean doExpDrop) {
++    public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List<ItemStack> drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, final @Nullable net.kyori.adventure.text.Component deathMessage, final boolean doExpDrop) {
 +        // Paper end - shouldDropExperience API
-         super(player, drops, droppedExp);
+         super(player, damageSource, drops, droppedExp);
          this.newExp = newExp;
          this.newTotalExp = newTotalExp;
          this.newLevel = newLevel;
@@ -38,15 +38,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@ public class PlayerDeathEvent extends EntityDeathEvent {
  
      @Deprecated // Paper
-     public PlayerDeathEvent(@NotNull final Player player, @NotNull final List<ItemStack> drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, @Nullable final String deathMessage) {
+     public PlayerDeathEvent(@NotNull final Player player, @NotNull DamageSource damageSource, @NotNull final List<ItemStack> drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, @Nullable final String deathMessage) {
 +        // Paper start - shouldDropExperience API
-+        this(player, drops, droppedExp, newExp, newTotalExp, newLevel, deathMessage, true);
++        this(player, damageSource, drops, droppedExp, newExp, newTotalExp, newLevel, deathMessage, true);
 +    }
 +
 +    @Deprecated // Paper
-+    public PlayerDeathEvent(@NotNull final Player player, @NotNull final List<ItemStack> drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, @Nullable final String deathMessage, boolean doExpDrop) {
++    public PlayerDeathEvent(@NotNull final Player player, final @NotNull DamageSource damageSource, @NotNull final List<ItemStack> drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, @Nullable final String deathMessage, boolean doExpDrop) {
 +        // Paper end - shouldDropExperience API
-         super(player, drops, droppedExp);
+         super(player, damageSource, drops, droppedExp);
          this.newExp = newExp;
          this.newTotalExp = newTotalExp;
          this.newLevel = newLevel;
diff --git a/patches/server/Add-ArmorStand-Item-Meta.patch b/patches/server/Add-ArmorStand-Item-Meta.patch
index 3091f124f1..3de527c72c 100644
--- a/patches/server/Add-ArmorStand-Item-Meta.patch
+++ b/patches/server/Add-ArmorStand-Item-Meta.patch
@@ -12,6 +12,19 @@ starting point for future additions in this area.
 
 Fixes GH-559
 
+diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java
++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java
+@@ -0,0 +0,0 @@ public class CraftItemType<M extends ItemMeta> implements ItemType.Typed<M>, Han
+     private Class<M> getItemMetaClass(Item item) {
+         ItemMeta meta = new ItemStack(this.asMaterial()).getItemMeta();
+         if (meta != null) {
+-            if (CraftMetaEntityTag.class != meta.getClass() && CraftMetaArmorStand.class != meta.getClass()) {
++            if (CraftMetaEntityTag.class != meta.getClass()/* && CraftMetaArmorStand.class != meta.getClass()*/) { // Paper - CraftMetaArmorStand is implemented in the API via ArmorStandMeta.
+                 return (Class<M>) meta.getClass().getInterfaces()[0];
+             }
+         }
 diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java
diff --git a/patches/server/Add-NamespacedKey-biome-methods.patch b/patches/server/Add-NamespacedKey-biome-methods.patch
index 497917393c..eefb61dc8a 100644
--- a/patches/server/Add-NamespacedKey-biome-methods.patch
+++ b/patches/server/Add-NamespacedKey-biome-methods.patch
@@ -28,4 +28,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
      // Paper end
  
-     /**
+     @Override
diff --git a/patches/server/Add-Raw-Byte-ItemStack-Serialization.patch b/patches/server/Add-Raw-Byte-ItemStack-Serialization.patch
index 42dd267b50..2dc30c2136 100644
--- a/patches/server/Add-Raw-Byte-ItemStack-Serialization.patch
+++ b/patches/server/Add-Raw-Byte-ItemStack-Serialization.patch
@@ -62,4 +62,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
      // Paper end
  
-     /**
+     @Override
diff --git a/patches/server/Add-RegistryAccess-for-managing-Registries.patch b/patches/server/Add-RegistryAccess-for-managing-Registries.patch
index a0a71ec078..7ed5255136 100644
--- a/patches/server/Add-RegistryAccess-for-managing-Registries.patch
+++ b/patches/server/Add-RegistryAccess-for-managing-Registries.patch
@@ -31,20 +31,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.GameEvent;
 +import org.bukkit.Keyed;
 +import org.bukkit.MusicInstrument;
++import org.bukkit.block.BlockType;
 +import org.bukkit.craftbukkit.CraftGameEvent;
 +import org.bukkit.craftbukkit.CraftMusicInstrument;
++import org.bukkit.craftbukkit.block.CraftBlockType;
 +import org.bukkit.craftbukkit.damage.CraftDamageType;
 +import org.bukkit.craftbukkit.enchantments.CraftEnchantment;
 +import org.bukkit.craftbukkit.entity.CraftWolf;
 +import org.bukkit.craftbukkit.generator.structure.CraftStructure;
 +import org.bukkit.craftbukkit.generator.structure.CraftStructureType;
++import org.bukkit.craftbukkit.inventory.CraftItemType;
 +import org.bukkit.craftbukkit.inventory.trim.CraftTrimMaterial;
 +import org.bukkit.craftbukkit.inventory.trim.CraftTrimPattern;
++import org.bukkit.craftbukkit.legacy.FieldRename;
 +import org.bukkit.craftbukkit.potion.CraftPotionEffectType;
 +import org.bukkit.damage.DamageType;
 +import org.bukkit.entity.Wolf;
 +import org.bukkit.entity.memory.MemoryKey;
 +import org.bukkit.generator.structure.StructureType;
++import org.bukkit.inventory.ItemType;
 +import org.bukkit.inventory.meta.trim.TrimMaterial;
 +import org.bukkit.inventory.meta.trim.TrimPattern;
 +import org.bukkit.potion.PotionEffectType;
@@ -64,11 +69,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    static {
 +        REGISTRY_ENTRIES = List.of(
 +            // built-ins
-+            entry(Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT, Enchantment.class, CraftEnchantment::new),
++            entry(Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT, Enchantment.class, CraftEnchantment::new).withSerializationUpdater(FieldRename.ENCHANTMENT_RENAME),
 +            entry(Registries.GAME_EVENT, RegistryKey.GAME_EVENT, GameEvent.class, CraftGameEvent::new),
 +            entry(Registries.INSTRUMENT, RegistryKey.INSTRUMENT, MusicInstrument.class, CraftMusicInstrument::new),
 +            entry(Registries.MOB_EFFECT, RegistryKey.MOB_EFFECT, PotionEffectType.class, CraftPotionEffectType::new),
 +            entry(Registries.STRUCTURE_TYPE, RegistryKey.STRUCTURE_TYPE, StructureType.class, CraftStructureType::new),
++            entry(Registries.BLOCK, RegistryKey.BLOCK, BlockType.class, CraftBlockType::new),
++            entry(Registries.ITEM, RegistryKey.ITEM, ItemType.class, CraftItemType::new),
 +
 +            // data-drivens
 +            entry(Registries.STRUCTURE, RegistryKey.STRUCTURE, Structure.class, CraftStructure::new).delayed(),
@@ -382,14 +389,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.Keyed;
 +import org.bukkit.NamespacedKey;
 +import org.bukkit.craftbukkit.CraftRegistry;
++import org.bukkit.craftbukkit.util.ApiVersion;
 +import org.checkerframework.checker.nullness.qual.NonNull;
 +import org.checkerframework.framework.qual.DefaultQualifier;
 +
 +@DefaultQualifier(NonNull.class)
 +public class CraftRegistryEntry<M, B extends Keyed> extends BaseRegistryEntry<M, B, CraftRegistry<B, M>> { // TODO remove Keyed
 +
++    private static final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> EMPTY = (namespacedKey, apiVersion) -> namespacedKey;
++
 +    protected final Class<?> classToPreload;
 +    protected final BiFunction<NamespacedKey, M, B> minecraftToBukkit;
++    private BiFunction<NamespacedKey, ApiVersion, NamespacedKey> updater = EMPTY;
 +
 +    protected CraftRegistryEntry(
 +        final ResourceKey<? extends Registry<M>> mcKey,
@@ -403,12 +414,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
++    public RegistryEntry<M, B, CraftRegistry<B, M>> withSerializationUpdater(final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> updater) {
++        this.updater = updater;
++        return this;
++    }
++
++    @Override
 +    public RegistryHolder<B> createRegistryHolder(final Registry<M> nmsRegistry) {
 +        return new RegistryHolder.Memoized<>(() -> this.createApiRegistry(nmsRegistry));
 +    }
 +
 +    private CraftRegistry<B, M> createApiRegistry(final Registry<M> nmsRegistry) {
-+        return new CraftRegistry<>(this.classToPreload, nmsRegistry, this.minecraftToBukkit);
++        return new CraftRegistry<>(this.classToPreload, nmsRegistry, this.minecraftToBukkit, this.updater);
 +    }
 +}
 diff --git a/src/main/java/io/papermc/paper/registry/entry/RegistryEntry.java b/src/main/java/io/papermc/paper/registry/entry/RegistryEntry.java
@@ -429,6 +446,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.Keyed;
 +import org.bukkit.NamespacedKey;
 +import org.bukkit.craftbukkit.CraftRegistry;
++import org.bukkit.craftbukkit.util.ApiVersion;
 +import org.checkerframework.checker.nullness.qual.NonNull;
 +import org.checkerframework.framework.qual.DefaultQualifier;
 +
@@ -437,6 +455,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    RegistryHolder<B> createRegistryHolder(Registry<M> nmsRegistry);
 +
++    default RegistryEntry<M, B, R> withSerializationUpdater(final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> updater) {
++        return this;
++    }
++
 +    /**
 +     * This should only be used if the registry instance needs to exist early due to the need
 +     * to populate a field in {@link org.bukkit.Registry}. Data-driven registries shouldn't exist
@@ -687,54 +709,85 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -     * @param registryHolder the minecraft registry holder
 -     * @return the bukkit registry of the provided class
 -     */
--    public static <B extends Keyed> Registry<?> createRegistry(Class<B> bukkitClass, RegistryAccess registryHolder) {
+-    public static <B extends Keyed> Registry<?> createRegistry(Class<? super B> bukkitClass, RegistryAccess registryHolder) {
 -        if (bukkitClass == Enchantment.class) {
--            return new CraftRegistry<>(Enchantment.class, registryHolder.registryOrThrow(Registries.ENCHANTMENT), CraftEnchantment::new);
+-            return new CraftRegistry<>(Enchantment.class, registryHolder.registryOrThrow(Registries.ENCHANTMENT), CraftEnchantment::new, FieldRename.ENCHANTMENT_RENAME);
 -        }
 -        if (bukkitClass == GameEvent.class) {
--            return new CraftRegistry<>(GameEvent.class, registryHolder.registryOrThrow(Registries.GAME_EVENT), CraftGameEvent::new);
+-            return new CraftRegistry<>(GameEvent.class, registryHolder.registryOrThrow(Registries.GAME_EVENT), CraftGameEvent::new, CraftRegistry.NONE);
 -        }
 -        if (bukkitClass == MusicInstrument.class) {
--            return new CraftRegistry<>(MusicInstrument.class, registryHolder.registryOrThrow(Registries.INSTRUMENT), CraftMusicInstrument::new);
+-            return new CraftRegistry<>(MusicInstrument.class, registryHolder.registryOrThrow(Registries.INSTRUMENT), CraftMusicInstrument::new, CraftRegistry.NONE);
 -        }
 -        if (bukkitClass == PotionEffectType.class) {
--            return new CraftRegistry<>(PotionEffectType.class, registryHolder.registryOrThrow(Registries.MOB_EFFECT), CraftPotionEffectType::new);
+-            return new CraftRegistry<>(PotionEffectType.class, registryHolder.registryOrThrow(Registries.MOB_EFFECT), CraftPotionEffectType::new, CraftRegistry.NONE);
 -        }
 -        if (bukkitClass == Structure.class) {
--            return new CraftRegistry<>(Structure.class, registryHolder.registryOrThrow(Registries.STRUCTURE), CraftStructure::new);
+-            return new CraftRegistry<>(Structure.class, registryHolder.registryOrThrow(Registries.STRUCTURE), CraftStructure::new, CraftRegistry.NONE);
 -        }
 -        if (bukkitClass == StructureType.class) {
--            return new CraftRegistry<>(StructureType.class, BuiltInRegistries.STRUCTURE_TYPE, CraftStructureType::new);
+-            return new CraftRegistry<>(StructureType.class, BuiltInRegistries.STRUCTURE_TYPE, CraftStructureType::new, CraftRegistry.NONE);
 -        }
 -        if (bukkitClass == TrimMaterial.class) {
--            return new CraftRegistry<>(TrimMaterial.class, registryHolder.registryOrThrow(Registries.TRIM_MATERIAL), CraftTrimMaterial::new);
+-            return new CraftRegistry<>(TrimMaterial.class, registryHolder.registryOrThrow(Registries.TRIM_MATERIAL), CraftTrimMaterial::new, CraftRegistry.NONE);
 -        }
 -        if (bukkitClass == TrimPattern.class) {
--            return new CraftRegistry<>(TrimPattern.class, registryHolder.registryOrThrow(Registries.TRIM_PATTERN), CraftTrimPattern::new);
+-            return new CraftRegistry<>(TrimPattern.class, registryHolder.registryOrThrow(Registries.TRIM_PATTERN), CraftTrimPattern::new, CraftRegistry.NONE);
 -        }
 -        if (bukkitClass == DamageType.class) {
--            return new CraftRegistry<>(DamageType.class, registryHolder.registryOrThrow(Registries.DAMAGE_TYPE), CraftDamageType::new);
+-            return new CraftRegistry<>(DamageType.class, registryHolder.registryOrThrow(Registries.DAMAGE_TYPE), CraftDamageType::new, CraftRegistry.NONE);
 -        }
 -        if (bukkitClass == Wolf.Variant.class) {
--            return new CraftRegistry<>(Wolf.Variant.class, registryHolder.registryOrThrow(Registries.WOLF_VARIANT), CraftWolf.CraftVariant::new);
+-            return new CraftRegistry<>(Wolf.Variant.class, registryHolder.registryOrThrow(Registries.WOLF_VARIANT), CraftWolf.CraftVariant::new, CraftRegistry.NONE);
+-        }
+-        if (bukkitClass == BlockType.class) {
+-            return new CraftRegistry<>(BlockType.class, registryHolder.registryOrThrow(Registries.BLOCK), CraftBlockType::new, CraftRegistry.NONE);
+-        }
+-        if (bukkitClass == ItemType.class) {
+-            return new CraftRegistry<>(ItemType.class, registryHolder.registryOrThrow(Registries.ITEM), CraftItemType::new, CraftRegistry.NONE);
 -        }
 -
 -        return null;
 -    }
 +    // Paper - move to PaperRegistries
  
++    // Paper - NOTE: As long as all uses of the method below relate to *serialization* via ConfigurationSerializable, it's fine
+     public static <B extends Keyed> B get(Registry<B> bukkit, NamespacedKey namespacedKey, ApiVersion apiVersion) {
+         if (bukkit instanceof CraftRegistry<B, ?> craft) {
+-            return craft.get(namespacedKey, apiVersion);
++            return craft.get(craft.serializationUpdater.apply(namespacedKey, apiVersion)); // Paper
+         }
+ 
+         if (bukkit instanceof Registry.SimpleRegistry<?> simple) {
+@@ -0,0 +0,0 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
+         return bukkit.get(namespacedKey);
+     }
+ 
 -    private final Class<? super B> bukkitClass;
 +    private final Class<?> bukkitClass; // Paper - relax preload class
      private final Map<NamespacedKey, B> cache = new HashMap<>();
      private final net.minecraft.core.Registry<M> minecraftRegistry;
      private final BiFunction<NamespacedKey, M, B> minecraftToBukkit;
+-    private final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> updater;
++    private final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> serializationUpdater; // Paper - rename to make it *clear* what it is *only* for
      private boolean init;
  
--    public CraftRegistry(Class<? super B> bukkitClass, net.minecraft.core.Registry<M> minecraftRegistry, BiFunction<NamespacedKey, M, B> minecraftToBukkit) {
-+    public CraftRegistry(Class<?> bukkitClass, net.minecraft.core.Registry<M> minecraftRegistry, BiFunction<NamespacedKey, M, B> minecraftToBukkit) { // Paper - relax preload class
+-    public CraftRegistry(Class<? super B> bukkitClass, net.minecraft.core.Registry<M> minecraftRegistry, BiFunction<NamespacedKey, M, B> minecraftToBukkit, BiFunction<NamespacedKey, ApiVersion, NamespacedKey> updater) {
++    public CraftRegistry(Class<?> bukkitClass, net.minecraft.core.Registry<M> minecraftRegistry, BiFunction<NamespacedKey, M, B> minecraftToBukkit, BiFunction<NamespacedKey, ApiVersion, NamespacedKey> serializationUpdater) { // Paper - relax preload class
          this.bukkitClass = bukkitClass;
          this.minecraftRegistry = minecraftRegistry;
          this.minecraftToBukkit = minecraftToBukkit;
+-        this.updater = updater;
++        this.serializationUpdater = serializationUpdater;
+     }
+ 
+-    public B get(NamespacedKey namespacedKey, ApiVersion apiVersion) {
+-        return this.get(this.updater.apply(namespacedKey, apiVersion));
+-    }
++    // Paper - inline into CraftRegistry#get(Registry, NamespacedKey, ApiVersion) above
+ 
+     @Override
+     public B get(NamespacedKey namespacedKey) {
 diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -757,6 +810,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }
  
      @Deprecated
+diff --git a/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java b/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java
++++ b/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java
+@@ -0,0 +0,0 @@ public class FieldRename {
+         return Enum.valueOf(enumClass, FieldRename.rename(apiVersion, enumClass.getName().replace('.', '/'), name));
+     }
+ 
+-    public static <T extends Keyed> T get(Registry<T> registry, NamespacedKey namespacedKey) {
+-        // We don't have version-specific changes, so just use current, and don't inject a version
+-        return CraftRegistry.get(registry, namespacedKey, ApiVersion.CURRENT);
+-    }
++    // Paper start - absolutely not, having this as an expectation for plugin developers opens a huge
++    // can of worms in the future, especially if mojang comes back and reuses some old key
++    // public static <T extends Keyed> T get(Registry<T> registry, NamespacedKey namespacedKey) {
++    //     // We don't have version-specific changes, so just use current, and don't inject a version
++    //     return CraftRegistry.get(registry, namespacedKey, ApiVersion.CURRENT);
++    // }
++    // Paper end
+ 
+     // PatternType
+     private static final FieldRenameData PATTERN_TYPE_DATA = FieldRenameData.Builder.newBuilder()
 diff --git a/src/main/resources/META-INF/services/io.papermc.paper.registry.RegistryAccess b/src/main/resources/META-INF/services/io.papermc.paper.registry.RegistryAccess
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
@@ -872,21 +947,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Order(2)
      @RegistriesTest
 -    public void testMinecraftToBukkitPresent(Class<? extends Keyed> clazz, ResourceKey<net.minecraft.core.Registry<?>> registryKey,
-+    public void testMinecraftToBukkitPresent(io.papermc.paper.registry.RegistryKey<? extends Keyed> type, Class<? extends Keyed> clazz, ResourceKey<net.minecraft.core.Registry<?>> registryKey, // Paper
-                                              Class<? extends Keyed> craftClazz, Class<?> minecraftClazz) {
++    public void testMinecraftToBukkitPresent(io.papermc.paper.registry.RegistryKey<? extends Keyed> type, Class<? extends Keyed> clazz, ResourceKey<net.minecraft.core.Registry<?>> registryKey,
+                                              Class<? extends Keyed> craftClazz, Class<?> minecraftClazz, boolean newMethod) {
+         String methodName = (newMethod) ? RegistryConversionTest.MINECRAFT_TO_BUKKIT_NEW : RegistryConversionTest.MINECRAFT_TO_BUKKIT;
          Method method = null;
-         try {
 @@ -0,0 +0,0 @@ public class RegistryConversionTest extends AbstractTestingBase {
  
      @Order(2)
      @RegistriesTest
 -    public void testBukkitToMinecraftPresent(Class<? extends Keyed> clazz, ResourceKey<net.minecraft.core.Registry<?>> registryKey,
-+    public void testBukkitToMinecraftPresent(io.papermc.paper.registry.RegistryKey<? extends Keyed> type, Class<? extends Keyed> clazz, ResourceKey<net.minecraft.core.Registry<?>> registryKey, // Paper
-                                              Class<? extends Keyed> craftClazz, Class<?> minecraftClazz) {
++    public void testBukkitToMinecraftPresent(io.papermc.paper.registry.RegistryKey<? extends Keyed> type, Class<? extends Keyed> clazz, ResourceKey<net.minecraft.core.Registry<?>> registryKey,
+                                              Class<? extends Keyed> craftClazz, Class<?> minecraftClazz, boolean newMethod) {
+         String methodName = (newMethod) ? RegistryConversionTest.BUKKIT_TO_MINECRAFT_NEW : RegistryConversionTest.BUKKIT_TO_MINECRAFT;
          Method method = null;
-         try {
 @@ -0,0 +0,0 @@ public class RegistryConversionTest extends AbstractTestingBase {
-                 """, minecraftClazz.getName(), clazz.getSimpleName());
+                 """, minecraftClazz.getName(), methodName, clazz.getSimpleName());
      }
  
 -    @Order(2)
@@ -978,30 +1053,48 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  import java.util.stream.Stream;
  import net.minecraft.core.registries.Registries;
 @@ -0,0 +0,0 @@ public class RegistriesArgumentProvider implements ArgumentsProvider {
+     private static final List<Arguments> DATA = Lists.newArrayList();
  
      static {
-         // Order: Bukkit class, Minecraft Registry key, CraftBukkit class, Minecraft class
--        DATA.add(Arguments.of(Enchantment.class, Registries.ENCHANTMENT, CraftEnchantment.class, net.minecraft.world.item.enchantment.Enchantment.class));
--        DATA.add(Arguments.of(GameEvent.class, Registries.GAME_EVENT, CraftGameEvent.class, net.minecraft.world.level.gameevent.GameEvent.class));
--        DATA.add(Arguments.of(MusicInstrument.class, Registries.INSTRUMENT, CraftMusicInstrument.class, Instrument.class));
--        DATA.add(Arguments.of(PotionEffectType.class, Registries.MOB_EFFECT, CraftPotionEffectType.class, MobEffect.class));
--        DATA.add(Arguments.of(Structure.class, Registries.STRUCTURE, CraftStructure.class, net.minecraft.world.level.levelgen.structure.Structure.class));
--        DATA.add(Arguments.of(StructureType.class, Registries.STRUCTURE_TYPE, CraftStructureType.class, net.minecraft.world.level.levelgen.structure.StructureType.class));
--        DATA.add(Arguments.of(TrimMaterial.class, Registries.TRIM_MATERIAL, CraftTrimMaterial.class, net.minecraft.world.item.armortrim.TrimMaterial.class));
--        DATA.add(Arguments.of(TrimPattern.class, Registries.TRIM_PATTERN, CraftTrimPattern.class, net.minecraft.world.item.armortrim.TrimPattern.class));
--        DATA.add(Arguments.of(DamageType.class, Registries.DAMAGE_TYPE, CraftDamageType.class, net.minecraft.world.damagesource.DamageType.class));
--        DATA.add(Arguments.of(Wolf.Variant.class, Registries.WOLF_VARIANT, CraftWolf.CraftVariant.class, WolfVariant.class));
+-        // Order: Bukkit class, Minecraft Registry key, CraftBukkit class, Minecraft class
+-        register(Enchantment.class, Registries.ENCHANTMENT, CraftEnchantment.class, net.minecraft.world.item.enchantment.Enchantment.class);
+-        register(GameEvent.class, Registries.GAME_EVENT, CraftGameEvent.class, net.minecraft.world.level.gameevent.GameEvent.class);
+-        register(MusicInstrument.class, Registries.INSTRUMENT, CraftMusicInstrument.class, Instrument.class);
+-        register(PotionEffectType.class, Registries.MOB_EFFECT, CraftPotionEffectType.class, MobEffect.class);
+-        register(Structure.class, Registries.STRUCTURE, CraftStructure.class, net.minecraft.world.level.levelgen.structure.Structure.class);
+-        register(StructureType.class, Registries.STRUCTURE_TYPE, CraftStructureType.class, net.minecraft.world.level.levelgen.structure.StructureType.class);
+-        register(TrimMaterial.class, Registries.TRIM_MATERIAL, CraftTrimMaterial.class, net.minecraft.world.item.armortrim.TrimMaterial.class);
+-        register(TrimPattern.class, Registries.TRIM_PATTERN, CraftTrimPattern.class, net.minecraft.world.item.armortrim.TrimPattern.class);
+-        register(DamageType.class, Registries.DAMAGE_TYPE, CraftDamageType.class, net.minecraft.world.damagesource.DamageType.class);
+-        register(Wolf.Variant.class, Registries.WOLF_VARIANT, CraftWolf.CraftVariant.class, WolfVariant.class);
+-        register(ItemType.class, Registries.ITEM, CraftItemType.class, net.minecraft.world.item.Item.class, true);
+-        register(BlockType.class, Registries.BLOCK, CraftBlockType.class, net.minecraft.world.level.block.Block.class, true);
 +        // Order: RegistryKey, Bukkit class, Minecraft Registry key, CraftBukkit class, Minecraft class
-+        DATA.add(Arguments.of(RegistryKey.ENCHANTMENT, Enchantment.class, Registries.ENCHANTMENT, CraftEnchantment.class, net.minecraft.world.item.enchantment.Enchantment.class));
-+        DATA.add(Arguments.of(RegistryKey.GAME_EVENT, GameEvent.class, Registries.GAME_EVENT, CraftGameEvent.class, net.minecraft.world.level.gameevent.GameEvent.class));
-+        DATA.add(Arguments.of(RegistryKey.INSTRUMENT, MusicInstrument.class, Registries.INSTRUMENT, CraftMusicInstrument.class, Instrument.class));
-+        DATA.add(Arguments.of(RegistryKey.MOB_EFFECT, PotionEffectType.class, Registries.MOB_EFFECT, CraftPotionEffectType.class, MobEffect.class));
-+        DATA.add(Arguments.of(RegistryKey.STRUCTURE, Structure.class, Registries.STRUCTURE, CraftStructure.class, net.minecraft.world.level.levelgen.structure.Structure.class));
-+        DATA.add(Arguments.of(RegistryKey.STRUCTURE_TYPE, StructureType.class, Registries.STRUCTURE_TYPE, CraftStructureType.class, net.minecraft.world.level.levelgen.structure.StructureType.class));
-+        DATA.add(Arguments.of(RegistryKey.TRIM_MATERIAL, TrimMaterial.class, Registries.TRIM_MATERIAL, CraftTrimMaterial.class, net.minecraft.world.item.armortrim.TrimMaterial.class));
-+        DATA.add(Arguments.of(RegistryKey.TRIM_PATTERN, TrimPattern.class, Registries.TRIM_PATTERN, CraftTrimPattern.class, net.minecraft.world.item.armortrim.TrimPattern.class));
-+        DATA.add(Arguments.of(RegistryKey.DAMAGE_TYPE, DamageType.class, Registries.DAMAGE_TYPE, CraftDamageType.class, net.minecraft.world.damagesource.DamageType.class));
-+        DATA.add(Arguments.of(RegistryKey.WOLF_VARIANT, Wolf.Variant.class, Registries.WOLF_VARIANT, CraftWolf.CraftVariant.class, net.minecraft.world.entity.animal.WolfVariant.class));
++        register(RegistryKey.ENCHANTMENT, Enchantment.class, Registries.ENCHANTMENT, CraftEnchantment.class, net.minecraft.world.item.enchantment.Enchantment.class);
++        register(RegistryKey.GAME_EVENT, GameEvent.class, Registries.GAME_EVENT, CraftGameEvent.class, net.minecraft.world.level.gameevent.GameEvent.class);
++        register(RegistryKey.INSTRUMENT, MusicInstrument.class, Registries.INSTRUMENT, CraftMusicInstrument.class, Instrument.class);
++        register(RegistryKey.MOB_EFFECT, PotionEffectType.class, Registries.MOB_EFFECT, CraftPotionEffectType.class, MobEffect.class);
++        register(RegistryKey.STRUCTURE, Structure.class, Registries.STRUCTURE, CraftStructure.class, net.minecraft.world.level.levelgen.structure.Structure.class);
++        register(RegistryKey.STRUCTURE_TYPE, StructureType.class, Registries.STRUCTURE_TYPE, CraftStructureType.class, net.minecraft.world.level.levelgen.structure.StructureType.class);
++        register(RegistryKey.TRIM_MATERIAL, TrimMaterial.class, Registries.TRIM_MATERIAL, CraftTrimMaterial.class, net.minecraft.world.item.armortrim.TrimMaterial.class);
++        register(RegistryKey.TRIM_PATTERN, TrimPattern.class, Registries.TRIM_PATTERN, CraftTrimPattern.class, net.minecraft.world.item.armortrim.TrimPattern.class);
++        register(RegistryKey.DAMAGE_TYPE, DamageType.class, Registries.DAMAGE_TYPE, CraftDamageType.class, net.minecraft.world.damagesource.DamageType.class);
++        register(RegistryKey.WOLF_VARIANT, Wolf.Variant.class, Registries.WOLF_VARIANT, CraftWolf.CraftVariant.class, WolfVariant.class);
++        register(RegistryKey.ITEM, ItemType.class, Registries.ITEM, CraftItemType.class, net.minecraft.world.item.Item.class, true);
++        register(RegistryKey.BLOCK, BlockType.class, Registries.BLOCK, CraftBlockType.class, net.minecraft.world.level.block.Block.class, true);
+ 
+     }
+ 
+-    private static void register(Class bukkit, ResourceKey registry, Class craft, Class minecraft) {
+-        RegistriesArgumentProvider.register(bukkit, registry, craft, minecraft, false);
++    private static void register(RegistryKey registryKey, Class bukkit, ResourceKey registry, Class craft, Class minecraft) { // Paper
++        RegistriesArgumentProvider.register(registryKey, bukkit, registry, craft, minecraft, false);
+     }
+ 
+-    private static void register(Class bukkit, ResourceKey registry, Class craft, Class minecraft, boolean newClass) {
+-        RegistriesArgumentProvider.DATA.add(Arguments.of(bukkit, registry, craft, minecraft, newClass));
++    private static void register(RegistryKey registryKey, Class bukkit, ResourceKey registry, Class craft, Class minecraft, boolean newClass) { // Paper
++        RegistriesArgumentProvider.DATA.add(Arguments.of(registryKey, bukkit, registry, craft, minecraft, newClass));
      }
  
      @Override
diff --git a/patches/server/Add-api-for-spawn-egg-texture-colors.patch b/patches/server/Add-api-for-spawn-egg-texture-colors.patch
index 529c61964b..f2e2c9ebcf 100644
--- a/patches/server/Add-api-for-spawn-egg-texture-colors.patch
+++ b/patches/server/Add-api-for-spawn-egg-texture-colors.patch
@@ -9,8 +9,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
 +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
 @@ -0,0 +0,0 @@ public final class CraftMagicNumbers implements UnsafeValues {
+         return CraftRegistry.get(registry, namespacedKey, ApiVersion.CURRENT);
      }
-     // Paper end
  
 +    // Paper start - spawn egg color visibility
 +    @Override
diff --git a/patches/server/Add-critical-damage-API.patch b/patches/server/Add-critical-damage-API.patch
index 4740fc1208..b828c22b21 100644
--- a/patches/server/Add-critical-damage-API.patch
+++ b/patches/server/Add-critical-damage-API.patch
@@ -75,7 +75,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
 +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
 @@ -0,0 +0,0 @@ public class CraftEventFactory {
-                 return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
+                 return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
              }
              DamageCause damageCause = (damager.getBukkitEntity() instanceof org.bukkit.entity.TNTPrimed) ? DamageCause.BLOCK_EXPLOSION : DamageCause.ENTITY_EXPLOSION;
 -            return CraftEventFactory.callEntityDamageEvent(damager, entity, damageCause, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
@@ -90,7 +90,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -            return CraftEventFactory.callEntityDamageEvent(damager, entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
 +            return CraftEventFactory.callEntityDamageEvent(damager, entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.isCritical()); // Paper - add critical damage API
          } else if (source.is(DamageTypes.FELL_OUT_OF_WORLD)) {
-             return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, DamageCause.VOID, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
+             return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, DamageCause.VOID, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
          } else if (source.is(DamageTypes.LAVA)) {
 @@ -0,0 +0,0 @@ public class CraftEventFactory {
              cause = DamageCause.CUSTOM;
diff --git a/patches/server/Add-exploded-block-state-to-EntityDamageByBlockEvent.patch b/patches/server/Add-exploded-block-state-to-EntityDamageByBlockEvent.patch
deleted file mode 100644
index d0e1c929d7..0000000000
--- a/patches/server/Add-exploded-block-state-to-EntityDamageByBlockEvent.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jake Potrebic <jake.m.potrebic@gmail.com>
-Date: Fri, 22 Oct 2021 16:25:07 -0700
-Subject: [PATCH] Add exploded block state to EntityDamageByBlockEvent
-
-== AT ==
-public org.bukkit.craftbukkit.block.CraftBlockStates getBlockState(Lorg/bukkit/World;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/entity/BlockEntity;)Lorg/bukkit/craftbukkit/block/CraftBlockState;
-
-diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSources.java b/src/main/java/net/minecraft/world/damagesource/DamageSources.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/damagesource/DamageSources.java
-+++ b/src/main/java/net/minecraft/world/damagesource/DamageSources.java
-@@ -0,0 +0,0 @@ public class DamageSources {
-         return this.source(DamageTypes.SONIC_BOOM, attacker);
-     }
- 
-+    @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - add exploded state
-     public DamageSource badRespawnPointExplosion(Vec3 position) {
-         // CraftBukkit start
--        return this.badRespawnPointExplosion(position, null, null, null);
-+        return this.badRespawnPointExplosion(position, null, null, null, null); // Paper - pass possible BlockEntity
-     }
- 
--    public DamageSource badRespawnPointExplosion(Vec3 vec3d, net.minecraft.world.level.Level world, net.minecraft.world.level.block.state.BlockState blockData, net.minecraft.core.BlockPos position) {
-+    public DamageSource badRespawnPointExplosion(Vec3 vec3d, net.minecraft.world.level.Level world, net.minecraft.world.level.block.state.BlockState blockData, net.minecraft.core.BlockPos position, @Nullable net.minecraft.world.level.block.entity.BlockEntity blockEntity) { // Paper - pass possible BlockEntity
-         DamageSource damageSource = new DamageSource(this.damageTypes.getHolderOrThrow(DamageTypes.BAD_RESPAWN_POINT), vec3d);
-         if (world != null && blockData != null && position != null) {
--            damageSource.blockState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(world, position, blockData, null);
-+            damageSource.blockState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(null, position, blockData, blockEntity); // Paper - pass possible BlockEntity (null world for unplaced)
-         }
-         return damageSource;
-         // CraftBukkit end
-diff --git a/src/main/java/net/minecraft/world/level/block/BedBlock.java b/src/main/java/net/minecraft/world/level/block/BedBlock.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/level/block/BedBlock.java
-+++ b/src/main/java/net/minecraft/world/level/block/BedBlock.java
-@@ -0,0 +0,0 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock
-     private InteractionResult explodeBed(BlockState iblockdata, Level world, BlockPos blockposition) {
-         {
-             {
-+                final BlockEntity blockEntity = world.getBlockEntity(blockposition); // Paper - capture BlockEntity
-                 world.removeBlock(blockposition, false);
-                 BlockPos blockposition1 = blockposition.relative(((Direction) iblockdata.getValue(BedBlock.FACING)).getOpposite());
- 
-@@ -0,0 +0,0 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock
- 
-                 Vec3 vec3d = blockposition.getCenter();
- 
--                world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, world, iblockdata, blockposition), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state
-+                world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, world, iblockdata, blockposition, blockEntity), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state // Paper - add BlockEntity
-                 return InteractionResult.SUCCESS;
-             }
-         }
-diff --git a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
-+++ b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
-@@ -0,0 +0,0 @@ public class RespawnAnchorBlock extends Block {
-         };
-         Vec3 vec3d = explodedPos.getCenter();
- 
--        world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, world, state, explodedPos), explosiondamagecalculator, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state
-+        world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, world, state, explodedPos, null), explosiondamagecalculator, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state // Paper
-     }
- 
-     public static boolean canSetSpawn(Level world) {
-diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
-+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
-@@ -0,0 +0,0 @@ public class CraftEventFactory {
-         Entity damager = (bukkitDamageSource.isIndirect() && source.getDirectEntity() != null) ? source.getDirectEntity() : source.getCausingEntity();
-         if (source.is(DamageTypeTags.IS_EXPLOSION)) {
-             if (damager == null) {
--                return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
-+                return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.blockState); // Paper - Include BlockState for damage
-             }
-             DamageCause damageCause = (damager.getBukkitEntity() instanceof org.bukkit.entity.TNTPrimed) ? DamageCause.BLOCK_EXPLOSION : DamageCause.ENTITY_EXPLOSION;
-             return CraftEventFactory.callEntityDamageEvent(damager, entity, damageCause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.isCritical()); // Paper - add critical damage API
-@@ -0,0 +0,0 @@ public class CraftEventFactory {
-             } else {
-                 throw new IllegalStateException(String.format("Unhandled damage of %s by %s from %s", entity, source.getDirectBlock(), source.getMsgId()));
-             }
--            return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
-+            return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.blockState); // Paper - Include BlockState for damage
-         }
- 
-         DamageCause cause;
-@@ -0,0 +0,0 @@ public class CraftEventFactory {
-         return CraftEventFactory.callEntityDamageEvent(event, damagee, cancelled);
-     }
- 
--    private static EntityDamageEvent callEntityDamageEvent(Block damager, Entity damagee, DamageCause cause, org.bukkit.damage.DamageSource bukkitDamageSource, Map<DamageModifier, Double> modifiers, Map<DamageModifier, Function<? super Double, Double>> modifierFunctions, boolean cancelled) {
--        EntityDamageByBlockEvent event = new EntityDamageByBlockEvent(damager, damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions);
-+    // Paper start
-+    private static EntityDamageEvent callEntityDamageEvent(Block damager, Entity damagee, DamageCause cause, org.bukkit.damage.DamageSource bukkitDamageSource, Map<DamageModifier, Double> modifiers, Map<DamageModifier, Function<? super Double, Double>> modifierFunctions, boolean cancelled) { // Paper
-+        return callEntityDamageEvent(damager, damagee, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, null);
-+    }
-+    private static EntityDamageEvent callEntityDamageEvent(Block damager, Entity damagee, DamageCause cause, org.bukkit.damage.DamageSource bukkitDamageSource, Map<DamageModifier, Double> modifiers, Map<DamageModifier, Function<? super Double, Double>> modifierFunctions, boolean cancelled, @Nullable org.bukkit.block.BlockState explodedBlockState) {
-+        EntityDamageByBlockEvent event = new EntityDamageByBlockEvent(damager, damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions, explodedBlockState);
-+        // Paper end
-         return CraftEventFactory.callEntityDamageEvent(event, damagee, cancelled);
-     }
- 
diff --git a/patches/server/Add-isCollidable-methods-to-various-places.patch b/patches/server/Add-isCollidable-methods-to-various-places.patch
index c2c1063207..fcca7d6d87 100644
--- a/patches/server/Add-isCollidable-methods-to-various-places.patch
+++ b/patches/server/Add-isCollidable-methods-to-various-places.patch
@@ -54,4 +54,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
      // Paper end
  
-     /**
+     @Override
diff --git a/patches/server/Add-missing-team-sidebar-display-slots.patch b/patches/server/Add-missing-team-sidebar-display-slots.patch
index 471e5c67f7..97fd808c7b 100644
--- a/patches/server/Add-missing-team-sidebar-display-slots.patch
+++ b/patches/server/Add-missing-team-sidebar-display-slots.patch
@@ -21,8 +21,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              case "org/bukkit/enchantments/Enchantment" -> FieldRename.convertEnchantmentName(apiVersion, from);
              case "org/bukkit/block/Biome" -> FieldRename.convertBiomeName(apiVersion, from);
 @@ -0,0 +0,0 @@ public class FieldRename {
-         };
-     }
+     // }
+     // Paper end
  
 +    // Paper start - DisplaySlot
 +    @DoNotReroute
diff --git a/patches/server/Adventure.patch b/patches/server/Adventure.patch
index 6227c76395..1795324ea9 100644
--- a/patches/server/Adventure.patch
+++ b/patches/server/Adventure.patch
@@ -2721,8 +2721,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
          String deathmessage = defaultMessage.getString();
          this.keepLevel = keepInventory; // SPIGOT-2222: pre-set keepLevel
--        org.bukkit.event.entity.PlayerDeathEvent event = CraftEventFactory.callPlayerDeathEvent(this, loot, deathmessage, keepInventory);
-+        org.bukkit.event.entity.PlayerDeathEvent event = CraftEventFactory.callPlayerDeathEvent(this, loot, PaperAdventure.asAdventure(defaultMessage), keepInventory); // Paper - Adventure
+-        org.bukkit.event.entity.PlayerDeathEvent event = CraftEventFactory.callPlayerDeathEvent(this, damageSource, loot, deathmessage, keepInventory);
++        org.bukkit.event.entity.PlayerDeathEvent event = CraftEventFactory.callPlayerDeathEvent(this, damageSource, loot, PaperAdventure.asAdventure(defaultMessage), keepInventory); // Paper - Adventure
  
          // SPIGOT-943 - only call if they have an inventory open
          if (this.containerMenu != this.inventoryMenu) {
@@ -2939,19 +2939,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              AsyncPlayerChatEvent event = new AsyncPlayerChatEvent(async, player, s, new LazyPlayerSet(this.server));
              String originalFormat = event.getFormat(), originalMessage = event.getMessage();
 @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- 
-     public void sendPlayerChatMessage(PlayerChatMessage message, ChatType.Bound params) {
-         // CraftBukkit start - SPIGOT-7262: if hidden we have to send as disguised message. Query whether we should send at all (but changing this may not be expected).
--        if (!this.getCraftPlayer().canSee(message.link().sender())) {
-+        // Paper start - Do not query the world for players, if they're not in the player list, then they're not in the world - don't query world state
-+        // Also, mirror the logic for canSee in terms of "missing" players
-+        final ServerPlayer sender = this.server.getPlayerList().getPlayer(message.link().sender());
-+        if (sender == null || !this.getCraftPlayer().canSee(sender.getBukkitEntity())) {
-+        // Paper end
-             this.sendDisguisedChatMessage(message.decoratedContent(), params);
-             return;
-         }
-@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
      public void handleClientInformation(ServerboundClientInformationPacket packet) {
          PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
          this.player.updateOptions(packet.information());
@@ -4647,11 +4634,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          return event;
      }
  
--    public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, List<org.bukkit.inventory.ItemStack> drops, String deathMessage, boolean keepInventory) {
-+    public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, List<org.bukkit.inventory.ItemStack> drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure
+-    public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, DamageSource damageSource, List<org.bukkit.inventory.ItemStack> drops, String deathMessage, boolean keepInventory) {
++    public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, DamageSource damageSource, List<org.bukkit.inventory.ItemStack> drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure
          CraftPlayer entity = victim.getBukkitEntity();
-         PlayerDeathEvent event = new PlayerDeathEvent(entity, drops, victim.getExpReward(), 0, deathMessage);
-         event.setKeepInventory(keepInventory);
+         CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
+         PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(), 0, deathMessage);
 @@ -0,0 +0,0 @@ public class CraftEventFactory {
       * Server methods
       */
diff --git a/patches/server/CB-fixes.patch b/patches/server/CB-fixes.patch
index d020e8b434..c88465731c 100644
--- a/patches/server/CB-fixes.patch
+++ b/patches/server/CB-fixes.patch
@@ -110,19 +110,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          return this.mapId;
      }
  
-diff --git a/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java b/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java
-+++ b/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java
-@@ -0,0 +0,0 @@ public class FieldRename {
-             .change("DAMAGE_UNDEAD", "SMITE")
-             .change("DAMAGE_ARTHROPODS", "BANE_OF_ARTHROPODS")
-             .change("LOOT_BONUS_MOBS", "LOOTING")
--            .change("SWEEPING_EDGE", "SWEEPING")
-+            // .change("SWEEPING_EDGE", "SWEEPING") // Paper - this change is incorrect, sweeping edge is the correct name
-             .change("DIG_SPEED", "EFFICIENCY")
-             .change("DURABILITY", "UNBREAKING")
-             .change("LOOT_BONUS_BLOCKS", "FORTUNE")
 diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
diff --git a/patches/server/Cache-block-data-strings.patch b/patches/server/Cache-block-data-strings.patch
index 98442ce650..23dbb1f542 100644
--- a/patches/server/Cache-block-data-strings.patch
+++ b/patches/server/Cache-block-data-strings.patch
@@ -48,12 +48,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +    // Paper end - cache block data strings
 +
-     public static CraftBlockData newData(Material material, String data) {
-         Preconditions.checkArgument(material == null || material.isBlock(), "Cannot get data for not block %s", material);
- 
+     public static CraftBlockData newData(BlockType blockType, String data) {
++
 +        // Paper start - cache block data strings
-+        if (material != null) {
-+            Block block = CraftBlockType.bukkitToMinecraft(material);
++        if (blockType != null) {
++            Block block = CraftBlockType.bukkitToMinecraftNew(blockType);
 +            if (block != null) {
 +                net.minecraft.resources.ResourceLocation key = BuiltInRegistries.BLOCK.getKey(block);
 +                data = data == null ? key.toString() : key + data;
@@ -64,8 +63,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return (CraftBlockData) cached.clone();
 +    }
 +
-+    private static CraftBlockData createNewData(Material material, String data) {
++    private static CraftBlockData createNewData(BlockType blockType, String data) {
 +        // Paper end - cache block data strings
          net.minecraft.world.level.block.state.BlockState blockData;
-         Block block = CraftBlockType.bukkitToMinecraft(material);
+         Block block = blockType == null ? null : ((CraftBlockType<?>) blockType).getHandle();
          Map<Property<?>, Comparable<?>> parsed = null;
diff --git a/patches/server/Expand-world-key-API.patch b/patches/server/Expand-world-key-API.patch
index 7dd3948c63..7c5ca952cb 100644
--- a/patches/server/Expand-world-key-API.patch
+++ b/patches/server/Expand-world-key-API.patch
@@ -81,4 +81,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
      // Paper end
  
-     /**
+     @Override
diff --git a/patches/server/Expose-protocol-version.patch b/patches/server/Expose-protocol-version.patch
index 30902c3a65..219a69d9cd 100644
--- a/patches/server/Expose-protocol-version.patch
+++ b/patches/server/Expose-protocol-version.patch
@@ -19,4 +19,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
      // Paper end
  
-     /**
+     @Override
diff --git a/patches/server/Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch b/patches/server/Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch
index d30b1984a8..ccade23d20 100644
--- a/patches/server/Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch
+++ b/patches/server/Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch
@@ -35,4 +35,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
      // Paper end
  
-     /**
+     @Override
diff --git a/patches/server/Fire-entity-death-event-for-ender-dragon.patch b/patches/server/Fire-entity-death-event-for-ender-dragon.patch
index 852e793fd2..198dd78fda 100644
--- a/patches/server/Fire-entity-death-event-for-ender-dragon.patch
+++ b/patches/server/Fire-entity-death-event-for-ender-dragon.patch
@@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public void kill() {
 +        // Paper start - Fire entity death event
 +        this.silentDeath = true;
-+        org.bukkit.event.entity.EntityDeathEvent deathEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this);
++        org.bukkit.event.entity.EntityDeathEvent deathEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, this.damageSources().genericKill());
 +        if (deathEvent.isCancelled()) {
 +            this.silentDeath = false; // Reset to default if event was cancelled
 +            return;
diff --git a/patches/server/Fix-DamageSource-API.patch b/patches/server/Fix-DamageSource-API.patch
index a597b57fa6..ac16ccc25a 100644
--- a/patches/server/Fix-DamageSource-API.patch
+++ b/patches/server/Fix-DamageSource-API.patch
@@ -11,42 +11,62 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/net/minecraft/world/damagesource/DamageSource.java
 +++ b/src/main/java/net/minecraft/world/damagesource/DamageSource.java
 @@ -0,0 +0,0 @@ public class DamageSource {
-     private boolean withSweep = false;
+     private boolean sweep = false;
      private boolean melting = false;
      private boolean poison = false;
--    private Entity customCausingEntity = null; // This field is a helper for when causing entity damage is not set by vanilla
+-    private Entity customEntityDamager = null; // This field is a helper for when causing entity damage is not set by vanilla
 +    @Nullable
 +    private Entity customEventDamager = null; // This field is a helper for when causing entity damage is not set by vanilla // Paper - fix DamageSource API
  
      public DamageSource sweep() {
-         this.withSweep = true;
+         this.sweep = true;
 @@ -0,0 +0,0 @@ public class DamageSource {
          return this.poison;
      }
  
--    public Entity getCausingEntity() {
--        return (this.customCausingEntity != null) ? this.customCausingEntity : this.causingEntity;
+-    public Entity getDamager() {
+-        return (this.customEntityDamager != null) ? this.customEntityDamager : this.directEntity;
 +    // Paper start - fix DamageSource API
-+    public @Nullable Entity getCustomEventDamager() {
++    @Nullable
++    public Entity getCustomEventDamager() {
 +        return (this.customEventDamager != null) ? this.customEventDamager : this.directEntity;
      }
  
--    public DamageSource customCausingEntity(Entity entity) {
+-    public DamageSource customEntityDamager(Entity entity) {
 -        // This method is not intended for change the causing entity if is already set
 -        // also is only necessary if the entity passed is not the direct entity or different from the current causingEntity
--        if (this.customCausingEntity != null || this.directEntity == entity || this.causingEntity == entity) {
+-        if (this.customEntityDamager != null || this.directEntity == entity || this.causingEntity == entity) {
 -            return this;
 +    public DamageSource customEventDamager(Entity entity) {
 +        if (this.directEntity != null) {
 +            throw new IllegalStateException("Cannot set custom event damager when direct entity is already set (report a bug to Paper)");
          }
          DamageSource damageSource = this.cloneInstance();
--        damageSource.customCausingEntity = entity;
+-        damageSource.customEntityDamager = entity;
 +        damageSource.customEventDamager = entity;
 +        // Paper end - fix DamageSource API
          return damageSource;
      }
  
+diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSources.java b/src/main/java/net/minecraft/world/damagesource/DamageSources.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/world/damagesource/DamageSources.java
++++ b/src/main/java/net/minecraft/world/damagesource/DamageSources.java
+@@ -0,0 +0,0 @@ public class DamageSources {
+     }
+ 
+     public DamageSource explosion(@Nullable Entity source, @Nullable Entity attacker) {
+-        // CraftBukkit start
+-        return this.explosion(source, attacker, attacker != null && source != null ? DamageTypes.PLAYER_EXPLOSION : DamageTypes.EXPLOSION);
+-    }
+-
+-    public DamageSource explosion(@Nullable Entity entity, @Nullable Entity entity1, ResourceKey<DamageType> resourceKey) {
+-        return this.source(resourceKey, entity, entity1);
+-        // CraftBukkit end
++        return this.source(attacker != null && source != null ? DamageTypes.PLAYER_EXPLOSION : DamageTypes.EXPLOSION, source, attacker); // Paper - revert to vanilla
+     }
+ 
+     public DamageSource sonicBoom(Entity attacker) {
 diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/net/minecraft/world/entity/Entity.java
@@ -55,7 +75,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              return;
          }
  
--        if (!this.hurt(this.damageSources().lightningBolt().customCausingEntity(lightning), 5.0F)) {
+-        if (!this.hurt(this.damageSources().lightningBolt().customEntityDamager(lightning), 5.0F)) {
 +        if (!this.hurt(this.damageSources().lightningBolt().customEventDamager(lightning), 5.0F)) { // Paper - fix DamageSource API
              return;
          }
@@ -68,7 +88,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void thunderHit(ServerLevel world, LightningBolt lightning) {
--        this.hurt(this.damageSources().lightningBolt().customCausingEntity(lightning), Float.MAX_VALUE); // CraftBukkit
+-        this.hurt(this.damageSources().lightningBolt().customEntityDamager(lightning), Float.MAX_VALUE); // CraftBukkit
 +        this.hurt(this.damageSources().lightningBolt().customEventDamager(lightning), Float.MAX_VALUE); // CraftBukkit // Paper - fix DamageSource API
      }
  
@@ -94,8 +114,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              if (!event.isCancelled()) {
              // CraftBukkit end
              this.dead = true;
--            this.level().explode(this, net.minecraft.world.level.Explosion.getDefaultDamageSource(this.level(), this).customCausingEntity(this.entityIgniter), null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB); // CraftBukkit
-+            this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB); // CraftBukkit // Paper - fix DamageSource API
+-            this.level().explode(this, this.level().damageSources().explosion(this, this.entityIgniter, net.minecraft.world.damagesource.DamageTypes.EXPLOSION), null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB); // CraftBukkit
++            this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB); // CraftBukkit // Paper - fix DamageSource API (revert to vanilla, no, just no, don't change this)
              this.discard(EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause
              this.spawnLingeringCloud();
              // CraftBukkit start
@@ -107,7 +127,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
          if (target.isAlive() && !target.isInvulnerable() && target != entityliving1) {
              if (entityliving1 == null) {
--                target.hurt(this.damageSources().magic().customCausingEntity(this), 6.0F); // CraftBukkit
+-                target.hurt(this.damageSources().magic().customEntityDamager(this), 6.0F); // CraftBukkit
 +                target.hurt(this.damageSources().magic().customEventDamager(this), 6.0F); // CraftBukkit // Paper - fix DamageSource API
              } else {
                  if (entityliving1.isAlliedTo((Entity) target)) {
@@ -120,7 +140,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
                          entityplayer.connection.teleport(teleEvent.getTo());
                          entity.resetFallDistance();
--                        entity.hurt(this.damageSources().fall().customCausingEntity(this), 5.0F); // CraftBukkit
+-                        entity.hurt(this.damageSources().fall().customEntityDamager(this), 5.0F); // CraftBukkit
 +                        entity.hurt(this.damageSources().fall().customEventDamager(this), 5.0F); // CraftBukkit // Paper - fix DamageSource API
                      }
                      // CraftBukkit end
@@ -138,19 +158,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              }
  
              if (flag && entity instanceof LivingEntity) {
-diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/level/Explosion.java
-+++ b/src/main/java/net/minecraft/world/level/Explosion.java
-@@ -0,0 +0,0 @@ public class Explosion {
-         this.z = z;
-         this.fire = createFire;
-         this.blockInteraction = destructionType;
--        this.damageSource = damageSource == null ? world.damageSources().explosion(this).customCausingEntity(entity) : damageSource.customCausingEntity(entity); // CraftBukkit - handle source entity
-+        this.damageSource = damageSource == null ? world.damageSources().explosion(this) : damageSource; // CraftBukkit - handle source entity // Paper - revert to fix DamageSource API
-         this.damageCalculator = behavior == null ? this.makeDamageCalculator(entity) : behavior;
-         this.smallExplosionParticles = particle;
-         this.largeExplosionParticles = emitterParticle;
 diff --git a/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageSource.java b/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageSource.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageSource.java
@@ -158,9 +165,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@ public class CraftDamageSource implements DamageSource {
  
      @Override
-     public org.bukkit.entity.Entity getCausingEntity() {
--        net.minecraft.world.entity.Entity entity = this.getHandle().getCausingEntity();
-+        net.minecraft.world.entity.Entity entity = this.getHandle().getEntity(); // Paper - fix DamageSource API
+     public org.bukkit.entity.Entity getDirectEntity() {
+-        net.minecraft.world.entity.Entity entity = this.getHandle().getDamager();
++        net.minecraft.world.entity.Entity entity = this.getHandle().getDirectEntity(); // Paper - fix DamageSource API
          return (entity != null) ? entity.getBukkitEntity() : null;
      }
  
@@ -168,7 +175,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public boolean isIndirect() {
--        return this.getHandle().getCausingEntity() != this.getHandle().getDirectEntity();
+-        return this.getHandle().getEntity() != this.getHandle().getDamager();
 +        return this.getHandle().isIndirect(); // Paper - fix DamageSource API
      }
  
@@ -197,8 +204,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      private static EntityDamageEvent handleEntityDamageEvent(Entity entity, DamageSource source, Map<DamageModifier, Double> modifiers, Map<DamageModifier, Function<? super Double, Double>> modifierFunctions, boolean cancelled) {
          CraftDamageSource bukkitDamageSource = new CraftDamageSource(source);
--        Entity damager = (bukkitDamageSource.isIndirect() && source.getDirectEntity() != null) ? source.getDirectEntity() : source.getCausingEntity();
+-        Entity damager = (source.getDamager() != null) ? source.getDamager() : source.getEntity();
 +        final Entity damager = source.getCustomEventDamager(); // Paper - fix DamageSource API
          if (source.is(DamageTypeTags.IS_EXPLOSION)) {
              if (damager == null) {
-                 return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.blockState); // Paper - Include BlockState for damage
+                 return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
diff --git a/patches/server/Fix-custom-statistic-criteria-creation.patch b/patches/server/Fix-custom-statistic-criteria-creation.patch
index cce2fae123..50b78df47e 100644
--- a/patches/server/Fix-custom-statistic-criteria-creation.patch
+++ b/patches/server/Fix-custom-statistic-criteria-creation.patch
@@ -20,4 +20,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
      // Paper end
  
-     /**
+     @Override
diff --git a/patches/server/Fix-item-duplication-and-teleport-issues.patch b/patches/server/Fix-item-duplication-and-teleport-issues.patch
index f26a337da1..21e60d0ae2 100644
--- a/patches/server/Fix-item-duplication-and-teleport-issues.patch
+++ b/patches/server/Fix-item-duplication-and-teleport-issues.patch
@@ -101,9 +101,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              this.clearEquipmentSlots = prev; // Paper
          }
 -        // CraftBukkit start - Call death event
--        org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, this.drops); // Paper
+-        org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, source, this.drops); // Paper
 +        // CraftBukkit start - Call death event // Paper start - call advancement triggers with correct entity equipment
-+        org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, this.drops, () -> {
++        org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, source, this.drops, () -> {
 +            final LivingEntity entityliving = this.getKillCredit();
 +            if (this.deathScore >= 0 && entityliving != null) {
 +                entityliving.awardKillScore(this, this.deathScore, source);
@@ -141,15 +141,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@ public class CraftEventFactory {
      }
  
-     public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, List<org.bukkit.inventory.ItemStack> drops) {
+     public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List<org.bukkit.inventory.ItemStack> drops) {
 +        // Paper start
-+        return CraftEventFactory.callEntityDeathEvent(victim, drops, com.google.common.util.concurrent.Runnables.doNothing());
++        return CraftEventFactory.callEntityDeathEvent(victim, damageSource, drops, com.google.common.util.concurrent.Runnables.doNothing());
 +    }
-+    public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, List<org.bukkit.inventory.ItemStack> drops, Runnable lootCheck) {
++    public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List<org.bukkit.inventory.ItemStack> drops, Runnable lootCheck) {
 +        // Paper end
          CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
-         EntityDeathEvent event = new EntityDeathEvent(entity, drops, victim.getExpReward());
-         populateFields(victim, event); // Paper - make cancellable
+         CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
+         EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward());
 @@ -0,0 +0,0 @@ public class CraftEventFactory {
          playDeathSound(victim, event);
          // Paper end
diff --git a/patches/server/Fixup-NamespacedKey-handling.patch b/patches/server/Fixup-NamespacedKey-handling.patch
index 3a06cb401a..96f1681e9c 100644
--- a/patches/server/Fixup-NamespacedKey-handling.patch
+++ b/patches/server/Fixup-NamespacedKey-handling.patch
@@ -35,17 +35,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttribute.java
 +++ b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttribute.java
 @@ -0,0 +0,0 @@ public class CraftAttribute {
-     public static Attribute stringToBukkit(String bukkit) {
-         Preconditions.checkArgument(bukkit != null);
+         string = FieldRename.convertAttributeName(ApiVersion.CURRENT, string);
+         string = string.toLowerCase(Locale.ROOT);
+         NamespacedKey key = NamespacedKey.fromString(string);
++        if (key == null) return null; // Paper - Fixup NamespacedKey handling
  
--        return Registry.ATTRIBUTE.get(NamespacedKey.fromString(bukkit));
-+        // Paper start - Fixup NamespacedKey handling
-+        final NamespacedKey key = NamespacedKey.fromString(bukkit);
-+        return key != null ? Registry.ATTRIBUTE.get(key) : null;
-+        // Paper end - Fixup NamespacedKey handling
-     }
- 
-     public static net.minecraft.world.entity.ai.attributes.Attribute bukkitToMinecraft(Attribute bukkit) {
+         // Now also convert from when keys where saved
+         return CraftRegistry.get(Registry.ATTRIBUTE, key, ApiVersion.CURRENT);
 diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java
@@ -83,11 +79,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
          getOrEmpty(tag, CraftMetaMusicInstrument.GOAT_HORN_INSTRUMENT).ifPresent((instrument) -> {
 -            this.instrument = CraftMusicInstrument.minecraftHolderToBukkit(instrument);
-+            this.instrument = this.unwrapAndConvertHolder(Registry.INSTRUMENT, instrument); // Paper - fix upstream not handling custom instruments
++            this.instrument = this.unwrapAndConvertHolder(org.bukkit.Registry.INSTRUMENT, instrument); // Paper - fix upstream not handling custom instruments
          });
      }
 +    // Paper start - fixup upstream being dum
-+    private <T extends org.bukkit.Keyed, M> T unwrapAndConvertHolder(final Registry<T> registry, final net.minecraft.core.Holder<M> value) {
++    private <T extends org.bukkit.Keyed, M> T unwrapAndConvertHolder(final org.bukkit.Registry<T> registry, final net.minecraft.core.Holder<M> value) {
 +        return value.unwrap().map(key -> registry.get(org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(key.location())), v -> null);
 +    }
 +    // Paper end - fixup upstream being dum
@@ -99,17 +95,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionType.java
 +++ b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionType.java
 @@ -0,0 +0,0 @@ public class CraftPotionType implements PotionType.InternalPotionData {
-     public static PotionType stringToBukkit(String string) {
-         Preconditions.checkArgument(string != null);
+         string = FieldRename.convertPotionTypeName(ApiVersion.CURRENT, string);
+         string = string.toLowerCase(Locale.ROOT);
+         NamespacedKey key = NamespacedKey.fromString(string);
++        if (key == null) return null; // Paper - Fixup NamespacedKey handling
  
--        return Registry.POTION.get(NamespacedKey.fromString(string));
-+        // Paper start - Fixup NamespacedKey handling
-+        final NamespacedKey key = NamespacedKey.fromString(string);
-+        return key != null ? Registry.POTION.get(key) : null;
-+        // Paper end - Fixup NamespacedKey handling
-     }
- 
-     private final NamespacedKey key;
+         // Now also convert from when keys where saved
+         return CraftRegistry.get(Registry.POTION, key, ApiVersion.CURRENT);
 diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftNamespacedKey.java b/src/main/java/org/bukkit/craftbukkit/util/CraftNamespacedKey.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftNamespacedKey.java
diff --git a/patches/server/General-ItemMeta-fixes.patch b/patches/server/General-ItemMeta-fixes.patch
index 1eedd402a2..4ba99378a1 100644
--- a/patches/server/General-ItemMeta-fixes.patch
+++ b/patches/server/General-ItemMeta-fixes.patch
@@ -135,10 +135,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            // Paper end
  
              for (TypedDataComponent<?> component : this.blockEntityTag.collectComponents()) {
+-                tag.putIfAbsent(component);
 +                if (CraftMetaItem.DEFAULT_HANDLED_DCTS.contains(component.type())) continue; // Paper - if the component type was already handled by CraftMetaItem, don't add it again
-                 tag.builder.set(component);
++                tag.builder.set(component);
              }
          }
+     }
 @@ -0,0 +0,0 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta
          Preconditions.checkArgument(blockStateType == blockState.getClass() && blockState instanceof CraftBlockEntityState, "Invalid blockState for " + this.material);
  
@@ -270,7 +272,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -    static final class Applicator {
 +    static abstract class Applicator { // Paper - support updating profile after resolving it
  
-         final DataComponentPatch.Builder builder = DataComponentPatch.builder();
+-        private final DataComponentPatch.Builder builder = DataComponentPatch.builder();
++        final DataComponentPatch.Builder builder = DataComponentPatch.builder(); // Paper - private -> package-private
 +        void skullCallback(com.mojang.authlib.GameProfile gameProfile) {} // Paper - support updating profile after resolving it
  
          <T> Applicator put(ItemMetaKeyType<T> key, T value) {
@@ -360,6 +363,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          this.applyToItem(tag);
          DataComponentPatch patch = tag.build();
          Tag nbt = DataComponentPatch.CODEC.encodeStart(MinecraftServer.getDefaultRegistryAccess().createSerializationContext(NbtOps.INSTANCE), patch).getOrThrow();
+@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+ 
+     @Override
+     public String getAsComponentString() {
+-        CraftMetaItem.Applicator tag = new CraftMetaItem.Applicator();
++        CraftMetaItem.Applicator tag = new CraftMetaItem.Applicator() {}; // Paper
+         this.applyToItem(tag);
+         DataComponentPatch patch = tag.build();
+ 
 @@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
          if (first == null || second == null) {
              return false;
diff --git a/patches/server/Get-entity-default-attributes.patch b/patches/server/Get-entity-default-attributes.patch
index 0b081dfcf5..706a9e9f53 100644
--- a/patches/server/Get-entity-default-attributes.patch
+++ b/patches/server/Get-entity-default-attributes.patch
@@ -102,7 +102,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
      // Paper end
  
-     /**
+     @Override
 diff --git a/src/test/java/io/papermc/paper/attribute/EntityTypeAttributesTest.java b/src/test/java/io/papermc/paper/attribute/EntityTypeAttributesTest.java
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
diff --git a/patches/server/Handle-Item-Meta-Inconsistencies.patch b/patches/server/Handle-Item-Meta-Inconsistencies.patch
index ab4807bd8f..b36d6df45c 100644
--- a/patches/server/Handle-Item-Meta-Inconsistencies.patch
+++ b/patches/server/Handle-Item-Meta-Inconsistencies.patch
@@ -169,14 +169,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  import java.util.EnumSet;
  import java.util.HashMap;
  import java.util.Iterator;
-@@ -0,0 +0,0 @@ import java.util.Map;
- import java.util.Objects;
- import java.util.Optional;
- import java.util.Set;
-+import java.util.TreeMap; // Paper
- import java.util.logging.Level;
- import java.util.logging.Logger;
- import javax.annotation.Nonnull;
 @@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
      private List<Component> lore; // null and empty are two different states internally
      private Integer customModelData;
@@ -220,8 +212,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -        Map<Enchantment, Integer> enchantments = new LinkedHashMap<Enchantment, Integer>(ench.size());
 +        EnchantmentMap enchantments = new EnchantmentMap(); // Paper
          for (Map.Entry<?, ?> entry : ench.entrySet()) {
-             // Doctor older enchants
-             String enchantKey = entry.getKey().toString();
+             Enchantment enchantment = CraftEnchantment.stringToBukkit(entry.getKey().toString());
+             if ((enchantment != null) && (entry.getValue() instanceof Integer)) {
 @@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
  
      @Override
@@ -254,7 +246,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }
 +
 +    // Paper start
-+    private static class EnchantmentMap extends TreeMap<Enchantment, Integer> {
++    private static class EnchantmentMap extends java.util.TreeMap<org.bukkit.enchantments.Enchantment, Integer> {
 +        private EnchantmentMap(Map<Enchantment, Integer> enchantments) {
 +            this();
 +            putAll(enchantments);
diff --git a/patches/server/Implement-Paper-VersionChecker.patch b/patches/server/Implement-Paper-VersionChecker.patch
index c2650a5b2c..f56ab4c2b5 100644
--- a/patches/server/Implement-Paper-VersionChecker.patch
+++ b/patches/server/Implement-Paper-VersionChecker.patch
@@ -154,4 +154,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
      // Paper end
  
-     /**
+     @Override
diff --git a/patches/server/Improve-Registry.patch b/patches/server/Improve-Registry.patch
index 5fd373a658..b52e79bcfb 100644
--- a/patches/server/Improve-Registry.patch
+++ b/patches/server/Improve-Registry.patch
@@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private final Map<B, NamespacedKey> byValue = new java.util.IdentityHashMap<>(); // Paper - improve Registry
      private final net.minecraft.core.Registry<M> minecraftRegistry;
      private final BiFunction<NamespacedKey, M, B> minecraftToBukkit;
-     private boolean init;
+     private final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> serializationUpdater; // Paper - rename to make it *clear* what it is *only* for
 @@ -0,0 +0,0 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
          }
  
diff --git a/patches/server/Improve-death-events.patch b/patches/server/Improve-death-events.patch
index abe6c8f58d..6e1969f9d3 100644
--- a/patches/server/Improve-death-events.patch
+++ b/patches/server/Improve-death-events.patch
@@ -45,7 +45,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
          String deathmessage = defaultMessage.getString();
          this.keepLevel = keepInventory; // SPIGOT-2222: pre-set keepLevel
-         org.bukkit.event.entity.PlayerDeathEvent event = CraftEventFactory.callPlayerDeathEvent(this, loot, PaperAdventure.asAdventure(defaultMessage), keepInventory); // Paper - Adventure
+         org.bukkit.event.entity.PlayerDeathEvent event = CraftEventFactory.callPlayerDeathEvent(this, damageSource, loot, PaperAdventure.asAdventure(defaultMessage), keepInventory); // Paper - Adventure
 +        // Paper start - cancellable death event
 +        if (event.isCancelled()) {
 +            // make compatible with plugins that might have already set the health in an event listener
@@ -215,8 +215,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            this.clearEquipmentSlots = prev; // Paper
          }
          // CraftBukkit start - Call death event
--        CraftEventFactory.callEntityDeathEvent(this, this.drops);
-+        org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, this.drops); // Paper
+-        CraftEventFactory.callEntityDeathEvent(this, source, this.drops);
++        org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, source, this.drops); // Paper
 +        this.postDeathDropItems(deathEvent); // Paper
          this.drops = new ArrayList<>();
          // CraftBukkit end
@@ -347,10 +347,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  // CraftBukkit end
                  if (source.is(DamageTypeTags.IS_EXPLOSION)) {
 -                    this.brokenByAnything(source);
--                    this.kill();
+-                    this.kill(source); // CraftBukkit
 +                    // Paper start - avoid duplicate event call
 +                    org.bukkit.event.entity.EntityDeathEvent event = this.brokenByAnything(source);
-+                    if (!event.isCancelled()) this.kill(false);
++                    if (!event.isCancelled()) this.kill(source, false); // CraftBukkit
 +                    // Paper end
                      return false;
                  } else if (source.is(DamageTypeTags.IGNITES_ARMOR_STANDS)) {
@@ -363,7 +363,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                                org.bukkit.event.entity.EntityDeathEvent event = this.brokenByPlayer(source); // Paper
                                  this.showBreakingParticles();
 -                                this.discard(EntityRemoveEvent.Cause.DEATH); // CraftBukkit - SPIGOT-4890: remain as this.discard() since above damagesource method will call death event
-+                                if (!event.isCancelled()) this.kill(false); // Paper - we still need to kill to follow vanilla logic (emit the game event etc...)
++                                if (!event.isCancelled()) this.kill(source, false); // Paper - we still need to kill to follow vanilla logic (emit the game event etc...)
                              }
  
                              return true;
@@ -372,10 +372,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          f1 -= amount;
          if (f1 <= 0.5F) {
 -            this.brokenByAnything(damageSource);
--            this.kill();
+-            this.kill(damageSource); // CraftBukkit
 +            // Paper start - avoid duplicate event call
 +            org.bukkit.event.entity.EntityDeathEvent event = this.brokenByAnything(damageSource);
-+            if (!event.isCancelled()) this.kill(false);
++            if (!event.isCancelled()) this.kill(damageSource, false); // CraftBukkit
 +            // Paper end
          } else {
              this.setHealth(f1);
@@ -409,23 +409,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }
  
 @@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
- 
-     @Override
-     public void kill() {
--        org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, this.drops); // CraftBukkit - call event
-+        // Paper start
-+        kill(true);
-+    }
-+
-+    public void kill(boolean callEvent) {
-+        if (callEvent) {
-+        // Paper end
-+        org.bukkit.event.entity.EntityDeathEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, this.drops); // CraftBukkit - call event // Paper - make cancellable
-+        if (event.isCancelled()) return; // Paper - make cancellable
-+        } // Paper
-         this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause
-         this.gameEvent(GameEvent.ENTITY_DIE);
      }
+ 
+     public void kill(DamageSource damageSource) {
+-        org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, (damageSource == null ? this.damageSources().genericKill() : damageSource), this.drops); // CraftBukkit - call event
++        // Paper start - make cancellable
++        this.kill(damageSource, true);
++    }
++    public void kill(DamageSource damageSource, boolean callEvent) {
++        if (callEvent) {
++            org.bukkit.event.entity.EntityDeathEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, (damageSource == null ? this.damageSources().genericKill() : damageSource), this.drops); // CraftBukkit - call event
++            if (event.isCancelled()) return;
++        }
++        // Paper end
+         this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause
+         // CraftBukkit end
+         this.gameEvent(GameEvent.ENTITY_DIE);
 diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -451,9 +450,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
 +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
 @@ -0,0 +0,0 @@ public class CraftEventFactory {
-     public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, List<org.bukkit.inventory.ItemStack> drops) {
          CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
-         EntityDeathEvent event = new EntityDeathEvent(entity, drops, victim.getExpReward());
+         CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
+         EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward());
 +        populateFields(victim, event); // Paper - make cancellable
          CraftWorld world = (CraftWorld) entity.getWorld();
          Bukkit.getServer().getPluginManager().callEvent(event);
@@ -468,7 +467,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
          for (org.bukkit.inventory.ItemStack stack : event.getDrops()) {
 @@ -0,0 +0,0 @@ public class CraftEventFactory {
-         PlayerDeathEvent event = new PlayerDeathEvent(entity, drops, victim.getExpReward(), 0, deathMessage);
+         PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(), 0, deathMessage);
          event.setKeepInventory(keepInventory);
          event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel
 +        populateFields(victim, event); // Paper - make cancellable
diff --git a/patches/server/Improve-the-Saddle-API-for-Horses.patch b/patches/server/Improve-the-Saddle-API-for-Horses.patch
index b83781e0ac..3693eadd49 100644
--- a/patches/server/Improve-the-Saddle-API-for-Horses.patch
+++ b/patches/server/Improve-the-Saddle-API-for-Horses.patch
@@ -37,8 +37,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -public class CraftInventoryHorse extends CraftInventoryAbstractHorse implements HorseInventory {
 +public class CraftInventoryHorse extends CraftSaddledInventory implements HorseInventory {
  
-     public CraftInventoryHorse(Container inventory) {
-         super(inventory);
+     private final Container bodyArmorInventory;
+ 
 diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSaddledInventory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSaddledInventory.java
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
diff --git a/patches/server/ItemStack-Tooltip-API.patch b/patches/server/ItemStack-Tooltip-API.patch
index 594264b3e9..f7b32a0299 100644
--- a/patches/server/ItemStack-Tooltip-API.patch
+++ b/patches/server/ItemStack-Tooltip-API.patch
@@ -27,5 +27,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +    // Paper end - expose itemstack tooltip lines
  
-     // Paper start - spawn egg color visibility
      @Override
+     public String get(Class<?> aClass, String s) {
diff --git a/patches/server/ItemStack-repair-check-API.patch b/patches/server/ItemStack-repair-check-API.patch
index c0a9af534a..2873b560cb 100644
--- a/patches/server/ItemStack-repair-check-API.patch
+++ b/patches/server/ItemStack-repair-check-API.patch
@@ -22,7 +22,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
      // Paper end
  
-     /**
+     @Override
 diff --git a/src/test/java/io/papermc/paper/util/ItemStackRepairCheckTest.java b/src/test/java/io/papermc/paper/util/ItemStackRepairCheckTest.java
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
diff --git a/patches/server/Prevent-entity-loading-causing-async-lookups.patch b/patches/server/Prevent-entity-loading-causing-async-lookups.patch
index a8144302b8..0162c82269 100644
--- a/patches/server/Prevent-entity-loading-causing-async-lookups.patch
+++ b/patches/server/Prevent-entity-loading-causing-async-lookups.patch
@@ -30,14 +30,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -                    if (entity instanceof Mob) {
 -                        Mob entityinsentient = (Mob) entity;
 -
--                        this.setTarget(entityinsentient);
+-                        this.setTarget(entityinsentient, EntityTargetEvent.TargetReason.UNKNOWN, false); // CraftBukkit
 -                        this.setLastHurtByMob(entityinsentient);
 -                    }
 -
 -                    if (entity instanceof Player) {
 -                        Player entityhuman = (Player) entity;
 -
--                        this.setTarget(entityhuman);
+-                        this.setTarget(entityhuman, EntityTargetEvent.TargetReason.UNKNOWN, false); // CraftBukkit
 -                        this.setLastHurtByPlayer(entityhuman);
 -                    }
 -
@@ -67,12 +67,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +        if (entity != null) {
 +            if (entity instanceof Mob mob) {
-+                this.setTarget(mob, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY, true);
++                this.setTarget(mob, EntityTargetEvent.TargetReason.UNKNOWN, false); // CraftBukkit
 +                this.setLastHurtByMob(mob);
 +            }
 +
 +            if (entity instanceof Player player) {
-+                this.setTarget(player, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY, true);
++                this.setTarget(player, EntityTargetEvent.TargetReason.UNKNOWN, false); // CraftBukkit
 +                this.setLastHurtByPlayer(player);
 +            }
 +        }
diff --git a/patches/server/Restore-vanilla-entity-drops-behavior.patch b/patches/server/Restore-vanilla-entity-drops-behavior.patch
index baeb345791..643d8f5b20 100644
--- a/patches/server/Restore-vanilla-entity-drops-behavior.patch
+++ b/patches/server/Restore-vanilla-entity-drops-behavior.patch
@@ -171,28 +171,29 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@ public class CraftEventFactory {
      }
  
-     public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim) {
--        return CraftEventFactory.callEntityDeathEvent(victim, new ArrayList<org.bukkit.inventory.ItemStack>(0));
-+        return CraftEventFactory.callEntityDeathEvent(victim, new ArrayList<>(0)); // Paper - Restore vanilla drops behavior
+     public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource) {
+-        return CraftEventFactory.callEntityDeathEvent(victim, damageSource, new ArrayList<org.bukkit.inventory.ItemStack>(0));
++        return CraftEventFactory.callEntityDeathEvent(victim, damageSource, new ArrayList<>(0)); // Paper - Restore vanilla drops behavior
      }
  
--    public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, List<org.bukkit.inventory.ItemStack> drops) {
-+    public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, List<Entity.DefaultDrop> drops) { // Paper - Restore vanilla drops behavior
+-    public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List<org.bukkit.inventory.ItemStack> drops) {
++    public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List<Entity.DefaultDrop> drops) { // Paper - Restore vanilla drops behavior
          // Paper start
-         return CraftEventFactory.callEntityDeathEvent(victim, drops, com.google.common.util.concurrent.Runnables.doNothing());
+         return CraftEventFactory.callEntityDeathEvent(victim, damageSource, drops, com.google.common.util.concurrent.Runnables.doNothing());
      }
--    public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, List<org.bukkit.inventory.ItemStack> drops, Runnable lootCheck) {
+-    public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List<org.bukkit.inventory.ItemStack> drops, Runnable lootCheck) {
 +
 +    private static final java.util.function.Function<org.bukkit.inventory.ItemStack, Entity.DefaultDrop> FROM_FUNCTION = stack -> {
 +        if (stack == null) return null;
 +        return new Entity.DefaultDrop(CraftItemType.bukkitToMinecraft(stack.getType()), stack, null);
 +    };
 +
-+    public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, List<Entity.DefaultDrop> drops, Runnable lootCheck) { // Paper
++    public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List<Entity.DefaultDrop> drops, Runnable lootCheck) { // Paper
          // Paper end
          CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
--        EntityDeathEvent event = new EntityDeathEvent(entity, drops, victim.getExpReward());
-+        EntityDeathEvent event = new EntityDeathEvent(entity, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward()); // Paper - Restore vanilla drops behavior
+         CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
+-        EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward());
++        EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward()); // Paper - Restore vanilla drops behavior
          populateFields(victim, event); // Paper - make cancellable
          CraftWorld world = (CraftWorld) entity.getWorld();
          Bukkit.getServer().getPluginManager().callEvent(event);
@@ -216,11 +217,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          return event;
      }
  
--    public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, List<org.bukkit.inventory.ItemStack> drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure
-+    public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, List<Entity.DefaultDrop> drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure & Restore vanilla drops behavior
+-    public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, DamageSource damageSource, List<org.bukkit.inventory.ItemStack> drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure
++    public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, DamageSource damageSource, List<Entity.DefaultDrop> drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure & Restore vanilla drops behavior
          CraftPlayer entity = victim.getBukkitEntity();
--        PlayerDeathEvent event = new PlayerDeathEvent(entity, drops, victim.getExpReward(), 0, deathMessage);
-+        PlayerDeathEvent event = new PlayerDeathEvent(entity, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(), 0, deathMessage); // Paper - Restore vanilla drops behavior
+         CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
+-        PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(), 0, deathMessage);
++        PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(), 0, deathMessage); // Paper - Restore vanilla drops behavior
          event.setKeepInventory(keepInventory);
          event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel
          populateFields(victim, event); // Paper - make cancellable
diff --git a/patches/server/Timings-v2.patch b/patches/server/Timings-v2.patch
index f10441e8f6..483886fccf 100644
--- a/patches/server/Timings-v2.patch
+++ b/patches/server/Timings-v2.patch
@@ -2032,8 +2032,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +    // Paper end
  
-     /**
-      * This helper class represents the different NBT Tags.
+     @Override
+     public String get(Class<?> aClass, String s) {
 diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/spigotmc/ActivationRange.java
diff --git a/patches/server/cache-resource-keys.patch b/patches/server/cache-resource-keys.patch
index 7eed2e1c61..52efd99091 100644
--- a/patches/server/cache-resource-keys.patch
+++ b/patches/server/cache-resource-keys.patch
@@ -48,4 +48,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -                .getOptional(CraftNamespacedKey.toMinecraft(bukkit.getKey())).orElseThrow();
 +                .getOptional(KEY_CACHE.computeIfAbsent(bukkit, type -> net.minecraft.resources.ResourceKey.create(Registries.ENTITY_TYPE, CraftNamespacedKey.toMinecraft(type.getKey())))).orElseThrow();
      }
- }
+ 
+     public static String bukkitToString(EntityType bukkit) {
diff --git a/patches/server/handle-converting-old-serialized-names-to-new-names.patch b/patches/server/handle-converting-old-serialized-names-to-new-names.patch
deleted file mode 100644
index e803fb54dc..0000000000
--- a/patches/server/handle-converting-old-serialized-names-to-new-names.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jake Potrebic <jake.m.potrebic@gmail.com>
-Date: Fri, 26 Apr 2024 11:38:40 -0700
-Subject: [PATCH] handle converting old serialized names to new names
-
-
-diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
-+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
-@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
-             for (Object hideFlagObject : hideFlags) {
-                 String hideFlagString = (String) hideFlagObject;
-                 try {
--                    ItemFlag hideFlatEnum = ItemFlag.valueOf(hideFlagString);
-+                    ItemFlag hideFlatEnum = ItemFlag.valueOf(org.bukkit.craftbukkit.legacy.FieldRename.convertItemFlagName(org.bukkit.craftbukkit.util.ApiVersion.CURRENT, hideFlagString)); // Paper - handle old field names
-                     this.addItemFlags(hideFlatEnum);
-                 } catch (IllegalArgumentException ex) {
-                     // Ignore when we got a old String which does not map to a Enum value anymore
-@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
-                 enchantKey = "SWEEPING_EDGE";
-             }
- 
--            Enchantment enchantment = Enchantment.getByName(enchantKey);
-+            Enchantment enchantment = Enchantment.getByName(org.bukkit.craftbukkit.legacy.FieldRename.convertEnchantmentName(org.bukkit.craftbukkit.util.ApiVersion.CURRENT, enchantKey)); // Paper - convert enchantment names
-             if ((enchantment != null) && (entry.getValue() instanceof Integer)) {
-                 enchantments.put(enchantment, (Integer) entry.getValue());
-             }
-@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
-                     continue;
-                 }
-                 AttributeModifier modifier = (AttributeModifier) o;
--                Attribute attribute = EnumUtils.getEnum(Attribute.class, attributeName.toUpperCase(Locale.ROOT));
-+                Attribute attribute = EnumUtils.getEnum(Attribute.class, org.bukkit.craftbukkit.legacy.FieldRename.convertAttributeName(org.bukkit.craftbukkit.util.ApiVersion.CURRENT, attributeName.toUpperCase(Locale.ROOT))); // Paper - handle old field names
-                 if (attribute == null) {
-                     continue;
-                 }
diff --git a/patches/server/improve-checking-handled-tags-in-itemmeta.patch b/patches/server/improve-checking-handled-tags-in-itemmeta.patch
index 544cb01cb9..cc2b03867c 100644
--- a/patches/server/improve-checking-handled-tags-in-itemmeta.patch
+++ b/patches/server/improve-checking-handled-tags-in-itemmeta.patch
@@ -213,7 +213,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaAxolotlBucket.java
 +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaAxolotlBucket.java
 @@ -0,0 +0,0 @@ public class CraftMetaAxolotlBucket extends CraftMetaItem implements AxolotlBuck
-         this.entityTag = bucket.entityTag;
+         this.bucketEntityTag = bucket.bucketEntityTag;
      }
  
 -    CraftMetaAxolotlBucket(DataComponentPatch tag) {
@@ -485,7 +485,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -                        CraftMetaBlockState.BLOCK_ENTITY_TAG.TYPE,
 -                        CraftMetaKnowledgeBook.BOOK_RECIPES.TYPE,
 -                        CraftMetaTropicalFishBucket.ENTITY_TAG.TYPE,
+-                        CraftMetaTropicalFishBucket.BUCKET_ENTITY_TAG.TYPE,
 -                        CraftMetaAxolotlBucket.ENTITY_TAG.TYPE,
+-                        CraftMetaAxolotlBucket.BUCKET_ENTITY_TAG.TYPE,
 -                        CraftMetaCrossbow.CHARGED_PROJECTILES.TYPE,
 -                        CraftMetaSuspiciousStew.EFFECTS.TYPE,
 -                        CraftMetaCompass.LODESTONE_TARGET.TYPE,
@@ -493,6 +495,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -                        CraftMetaMusicInstrument.GOAT_HORN_INSTRUMENT.TYPE,
 -                        CraftMetaOminousBottle.OMINOUS_BOTTLE_AMPLIFIER.TYPE
 -                ));
+-            }
+-            return CraftMetaItem.HANDLED_TAGS;
 +    // 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<>();
@@ -525,7 +529,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                final Map<Class<? extends CraftMetaItem>, Set<DataComponentType<?>>> map = new HashMap<>();
 +                map.put(CraftMetaArmor.class, Set.of(CraftMetaArmor.TRIM.TYPE));
 +                map.put(CraftMetaArmorStand.class, Set.of(CraftMetaArmorStand.ENTITY_TAG.TYPE));
-+                map.put(CraftMetaAxolotlBucket.class, Set.of(CraftMetaAxolotlBucket.ENTITY_TAG.TYPE));
++                map.put(CraftMetaAxolotlBucket.class, Set.of(CraftMetaAxolotlBucket.ENTITY_TAG.TYPE, CraftMetaAxolotlBucket.BUCKET_ENTITY_TAG.TYPE));
 +                map.put(CraftMetaBanner.class, Set.of(/*CraftMetaBlockState.BLOCK_ENTITY_TAG.NBT, */CraftMetaBanner.PATTERNS.TYPE)); // banner uses same tag as block state
 +                map.put(CraftMetaBlockState.class, Set.of(CraftMetaBlockState.BLOCK_ENTITY_TAG.TYPE));
 +                map.put(CraftMetaBook.class, Set.of(CraftMetaBook.BOOK_CONTENT.TYPE));
@@ -547,7 +551,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                map.put(CraftMetaSkull.class, Set.of(CraftMetaSkull.SKULL_PROFILE.TYPE, CraftMetaSkull.NOTE_BLOCK_SOUND.TYPE));
 +                map.put(CraftMetaSpawnEgg.class, Set.of(CraftMetaSpawnEgg.ENTITY_TAG.TYPE));
 +                map.put(CraftMetaSuspiciousStew.class, Set.of(CraftMetaSuspiciousStew.EFFECTS.TYPE));
-+                map.put(CraftMetaTropicalFishBucket.class, Set.of(CraftMetaTropicalFishBucket.ENTITY_TAG.TYPE));
++                map.put(CraftMetaTropicalFishBucket.class, Set.of(CraftMetaTropicalFishBucket.ENTITY_TAG.TYPE, CraftMetaTropicalFishBucket.BUCKET_ENTITY_TAG.TYPE));
 +
 +                for (final Map.Entry<Class<? extends CraftMetaItem>, Set<DataComponentType<?>>> entry : map.entrySet()) {
 +                    final ArrayList<DataComponentType<?>> topLevelTags = new ArrayList<>(entry.getValue());
@@ -555,8 +559,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                    topLevelTags.addAll(DEFAULT_HANDLED_DCTS);
 +                    HANDLED_DCTS_PER_TYPE.put(entry.getKey(), Set.copyOf(topLevelTags));
 +                }
-             }
--            return CraftMetaItem.HANDLED_TAGS;
++            }
 +            return HANDLED_DCTS_PER_TYPE.getOrDefault(clazz, DEFAULT_HANDLED_DCTS);
          }
      }
@@ -623,7 +626,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        super(tag, extraHandledDcts); // Paper
  
          getOrEmpty(tag, CraftMetaMusicInstrument.GOAT_HORN_INSTRUMENT).ifPresent((instrument) -> {
-             this.instrument = this.unwrapAndConvertHolder(Registry.INSTRUMENT, instrument); // Paper - fix upstream not handling custom instruments
+             this.instrument = this.unwrapAndConvertHolder(org.bukkit.Registry.INSTRUMENT, instrument); // Paper - fix upstream not handling custom instruments
 diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java
@@ -704,7 +707,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaTropicalFishBucket.java
 +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaTropicalFishBucket.java
 @@ -0,0 +0,0 @@ class CraftMetaTropicalFishBucket extends CraftMetaItem implements TropicalFishB
-         this.entityTag = bucket.entityTag;
+         this.bucketEntityTag = bucket.bucketEntityTag;
      }
  
 -    CraftMetaTropicalFishBucket(DataComponentPatch tag) {
diff --git a/work/Bukkit b/work/Bukkit
index ac72b19b01..fa99e752ae 160000
--- a/work/Bukkit
+++ b/work/Bukkit
@@ -1 +1 @@
-Subproject commit ac72b19b01bcb3aef5710677b0b942e098479660
+Subproject commit fa99e752ae28e0a294b2def5955645ad74a8a2d3
diff --git a/work/CraftBukkit b/work/CraftBukkit
index 66fd94322c..4af0f22e8a 160000
--- a/work/CraftBukkit
+++ b/work/CraftBukkit
@@ -1 +1 @@
-Subproject commit 66fd94322c5b1b8eb474c7a95aed9d048f995803
+Subproject commit 4af0f22e8a2ce40afd554a3d60da4fe093c7debd