From 0254c46a8bc835cc9de11677d4e703ae616ca960 Mon Sep 17 00:00:00 2001
From: Nassim Jahnke <nassim@njahnke.dev>
Date: Sun, 2 Oct 2022 09:56:36 +0200
Subject: [PATCH] Updated Upstream (Bukkit/CraftBukkit) (#8430)

Upstream has released updates that appear to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

Bukkit Changes:
09943450 Update SnakeYAML version
5515734f SPIGOT-7162: Incorrect description for Entity#getVehicle javadoc
6f82b381 PR-788: Add getHand() to all relevant events

CraftBukkit Changes:
aaf484f6f SPIGOT-7163: CraftMerchantRecipe doesn't copy demand and specialPrice from BukkitMerchantRecipe
5329dd6fd PR-1107: Add getHand() to all relevant events
93061706e SPIGOT-7045: Ocelots never spawn with babies with spawn reason OCELOT_BABY
---
 ...Leash-variable-to-EntityUnleashEvent.patch |  10 +-
 patches/api/Add-hand-to-bucket-events.patch   | 130 ------------------
 patches/api/Adventure.patch                   |   4 +-
 patches/api/Build-system-changes.patch        |   4 +-
 patches/api/Convert-project-to-Gradle.patch   |   6 +-
 .../Custom-replacement-for-eaten-items.patch  |   4 +-
 ...-limit-in-YamlConfigOptions-and-incr.patch |  13 --
 .../Ability-to-apply-mending-to-XP-API.patch  |   2 +-
 ...Leash-variable-to-EntityUnleashEvent.patch |  16 +--
 .../server/Add-hand-to-bucket-events.patch    | 125 -----------------
 patches/server/Add-ignore-discounts-API.patch |   6 +-
 .../Custom-replacement-for-eaten-items.patch  |   7 +-
 work/Bukkit                                   |   2 +-
 work/CraftBukkit                              |   2 +-
 14 files changed, 32 insertions(+), 299 deletions(-)
 delete mode 100644 patches/api/Add-hand-to-bucket-events.patch
 delete mode 100644 patches/server/Add-hand-to-bucket-events.patch

diff --git a/patches/api/Add-dropLeash-variable-to-EntityUnleashEvent.patch b/patches/api/Add-dropLeash-variable-to-EntityUnleashEvent.patch
index fbd85673d8..67353e687c 100644
--- a/patches/api/Add-dropLeash-variable-to-EntityUnleashEvent.patch
+++ b/patches/api/Add-dropLeash-variable-to-EntityUnleashEvent.patch
@@ -61,18 +61,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +++ b/src/main/java/org/bukkit/event/player/PlayerUnleashEntityEvent.java
 @@ -0,0 +0,0 @@ public class PlayerUnleashEntityEvent extends EntityUnleashEvent implements Canc
      private final Player player;
-     private boolean cancelled = false;
+     private final EquipmentSlot hand;
  
 +    // Paper start - drop leash variable
 +    @Deprecated
-     public PlayerUnleashEntityEvent(@NotNull Entity entity, @NotNull Player player) {
+     public PlayerUnleashEntityEvent(@NotNull Entity entity, @NotNull Player player, @NotNull EquipmentSlot hand) {
 -        super(entity, UnleashReason.PLAYER_UNLEASH);
-+        this(entity, player, false);
++        this(entity, player, hand, false);
 +    }
 +
-+    public PlayerUnleashEntityEvent(@NotNull Entity entity, @NotNull Player player, boolean dropLeash) {
++    public PlayerUnleashEntityEvent(@NotNull Entity entity, @NotNull Player player, @NotNull EquipmentSlot hand, boolean dropLeash) {
 +        super(entity, UnleashReason.PLAYER_UNLEASH, dropLeash);
 +        // Paper end
          this.player = player;
+         this.hand = hand;
      }
- 
diff --git a/patches/api/Add-hand-to-bucket-events.patch b/patches/api/Add-hand-to-bucket-events.patch
deleted file mode 100644
index cb3670daf1..0000000000
--- a/patches/api/Add-hand-to-bucket-events.patch
+++ /dev/null
@@ -1,130 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: BillyGalbreath <Blake.Galbreath@GMail.com>
-Date: Thu, 2 Aug 2018 08:44:20 -0500
-Subject: [PATCH] Add hand to bucket events
-
-
-diff --git a/src/main/java/org/bukkit/event/player/PlayerBucketEmptyEvent.java b/src/main/java/org/bukkit/event/player/PlayerBucketEmptyEvent.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/event/player/PlayerBucketEmptyEvent.java
-+++ b/src/main/java/org/bukkit/event/player/PlayerBucketEmptyEvent.java
-@@ -0,0 +0,0 @@ import org.bukkit.block.Block;
- import org.bukkit.block.BlockFace;
- import org.bukkit.entity.Player;
- import org.bukkit.event.HandlerList;
-+import org.bukkit.inventory.EquipmentSlot;
- import org.bukkit.inventory.ItemStack;
- import org.jetbrains.annotations.NotNull;
- 
-@@ -0,0 +0,0 @@ public class PlayerBucketEmptyEvent extends PlayerBucketEvent {
-     public PlayerBucketEmptyEvent(@NotNull final Player who, @NotNull final Block block, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand) {
-         super(who, block, blockClicked, blockFace, bucket, itemInHand);
-     }
-+    // Paper start - add EquipmentSlot
-+    @Deprecated
-+    public PlayerBucketEmptyEvent(@NotNull final Player who, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand, @org.jetbrains.annotations.Nullable final EquipmentSlot hand) {
-+        super(who, blockClicked, blockFace, bucket, itemInHand, hand);
-+    }
-+
-+    public PlayerBucketEmptyEvent(@NotNull final Player who, @NotNull final Block block, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand, @org.jetbrains.annotations.Nullable final EquipmentSlot hand) {
-+        super(who, block, blockClicked, blockFace, bucket, itemInHand, hand);
-+    }
-+    // Paper end
- 
-     @NotNull
-     @Override
-diff --git a/src/main/java/org/bukkit/event/player/PlayerBucketEvent.java b/src/main/java/org/bukkit/event/player/PlayerBucketEvent.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/event/player/PlayerBucketEvent.java
-+++ b/src/main/java/org/bukkit/event/player/PlayerBucketEvent.java
-@@ -0,0 +0,0 @@ import org.bukkit.block.Block;
- import org.bukkit.block.BlockFace;
- import org.bukkit.entity.Player;
- import org.bukkit.event.Cancellable;
-+import org.bukkit.inventory.EquipmentSlot;
- import org.bukkit.inventory.ItemStack;
- import org.jetbrains.annotations.NotNull;
- import org.jetbrains.annotations.Nullable;
-@@ -0,0 +0,0 @@ public abstract class PlayerBucketEvent extends PlayerEvent implements Cancellab
-     private final Block blockClicked;
-     private final BlockFace blockFace;
-     private final Material bucket;
-+    private final EquipmentSlot hand; // Paper - add EquipmentSlot
- 
-     @Deprecated
-     public PlayerBucketEvent(@NotNull final Player who, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand) {
-@@ -0,0 +0,0 @@ public abstract class PlayerBucketEvent extends PlayerEvent implements Cancellab
-     }
- 
-     public PlayerBucketEvent(@NotNull final Player who, @NotNull final Block block, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand) {
-+        // Paper start - add EquipmentSlot
-+        this(who, block, blockClicked, blockFace, bucket, itemInHand, null);
-+    }
-+
-+    @Deprecated
-+    public PlayerBucketEvent(@NotNull final Player who,@NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand, @Nullable  final EquipmentSlot hand) {
-+        this(who, null, blockClicked, blockFace, bucket, itemInHand, hand);
-+    }
-+
-+    public PlayerBucketEvent(@NotNull final Player who, @NotNull final Block block, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand, @Nullable  final EquipmentSlot hand) {
-+        // Paper end
-         super(who);
-         this.block = block;
-         this.blockClicked = blockClicked;
-         this.blockFace = blockFace;
-         this.itemStack = itemInHand;
-         this.bucket = bucket;
-+        this.hand = hand == null ? player.getInventory().getItemInMainHand().equals(itemInHand) ? EquipmentSlot.HAND : EquipmentSlot.OFF_HAND : hand; // Paper - add EquipmentSlot
-     }
- 
-     /**
-@@ -0,0 +0,0 @@ public abstract class PlayerBucketEvent extends PlayerEvent implements Cancellab
-         return blockFace;
-     }
- 
-+    // Paper start
-+    /**
-+     * The hand used to perform this action.
-+     *
-+     * @return the hand used
-+     */
-+    @NotNull
-+    public EquipmentSlot getHand() {
-+        return hand;
-+    }
-+    // Paper end
-+
-     @Override
-     public boolean isCancelled() {
-         return cancelled;
-diff --git a/src/main/java/org/bukkit/event/player/PlayerBucketFillEvent.java b/src/main/java/org/bukkit/event/player/PlayerBucketFillEvent.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/event/player/PlayerBucketFillEvent.java
-+++ b/src/main/java/org/bukkit/event/player/PlayerBucketFillEvent.java
-@@ -0,0 +0,0 @@ import org.bukkit.block.Block;
- import org.bukkit.block.BlockFace;
- import org.bukkit.entity.Player;
- import org.bukkit.event.HandlerList;
-+import org.bukkit.inventory.EquipmentSlot;
- import org.bukkit.inventory.ItemStack;
- import org.jetbrains.annotations.NotNull;
- 
-@@ -0,0 +0,0 @@ public class PlayerBucketFillEvent extends PlayerBucketEvent {
-         super(who, block, blockClicked, blockFace, bucket, itemInHand);
-     }
- 
-+    // Paper start - add EquipmentSlot
-+    @Deprecated
-+    public PlayerBucketFillEvent(@NotNull final Player who, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand, @org.jetbrains.annotations.Nullable final EquipmentSlot hand) {
-+        super(who, blockClicked, blockFace, bucket, itemInHand, hand);
-+    }
-+
-+    // Paper start - add EquipmentSlot
-+    public PlayerBucketFillEvent(@NotNull final Player who, @NotNull Block block, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand, @org.jetbrains.annotations.Nullable final EquipmentSlot hand) {
-+        super(who, block, blockClicked, blockFace, bucket, itemInHand, hand);
-+    }
-+    // Paper end
-+
-     @NotNull
-     @Override
-     public HandlerList getHandlers() {
diff --git a/patches/api/Adventure.patch b/patches/api/Adventure.patch
index 160be97653..34cc439060 100644
--- a/patches/api/Adventure.patch
+++ b/patches/api/Adventure.patch
@@ -33,7 +33,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      api("com.google.code.gson:gson:2.8.9")
 -    api("net.md-5:bungeecord-chat:1.16-R0.4")
 +    api("net.md-5:bungeecord-chat:1.16-R0.4-deprecated+build.6") // Paper
-     api("org.yaml:snakeyaml:1.32")
+     api("org.yaml:snakeyaml:1.33")
      // Paper start
      api("com.googlecode.json-simple:json-simple:1.1.1") {
          isTransitive = false // includes junit
@@ -51,7 +51,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      compileOnly("org.apache.maven:maven-resolver-provider:3.8.5")
 @@ -0,0 +0,0 @@ tasks.withType<Javadoc> {
          "https://guava.dev/releases/31.0.1-jre/api/docs/",
-         "https://javadoc.io/doc/org.yaml/snakeyaml/1.30/",
+         "https://javadoc.io/doc/org.yaml/snakeyaml/1.33/",
          "https://javadoc.io/doc/org.jetbrains/annotations/23.0.0/", // Paper - we don't want Java 5 annotations
 -        "https://javadoc.io/doc/net.md-5/bungeecord-chat/1.16-R0.4/",
 +        // Paper start
diff --git a/patches/api/Build-system-changes.patch b/patches/api/Build-system-changes.patch
index 456ac74e7c..21bf2fd12c 100644
--- a/patches/api/Build-system-changes.patch
+++ b/patches/api/Build-system-changes.patch
@@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@ dependencies {
      api("com.google.code.gson:gson:2.8.9")
      api("net.md-5:bungeecord-chat:1.16-R0.4")
-     api("org.yaml:snakeyaml:1.32")
+     api("org.yaml:snakeyaml:1.33")
 +    // Paper start
 +    api("com.googlecode.json-simple:json-simple:1.1.1") {
 +        isTransitive = false // includes junit
@@ -40,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@ tasks.withType<Javadoc> {
      options.links(
          "https://guava.dev/releases/31.0.1-jre/api/docs/",
-         "https://javadoc.io/doc/org.yaml/snakeyaml/1.30/",
+         "https://javadoc.io/doc/org.yaml/snakeyaml/1.33/",
 -        "https://javadoc.io/doc/org.jetbrains/annotations-java5/23.0.0/",
 +        "https://javadoc.io/doc/org.jetbrains/annotations/23.0.0/", // Paper - we don't want Java 5 annotations
          "https://javadoc.io/doc/net.md-5/bungeecord-chat/1.16-R0.4/",
diff --git a/patches/api/Convert-project-to-Gradle.patch b/patches/api/Convert-project-to-Gradle.patch
index 1528448946..5a0daaaff6 100644
--- a/patches/api/Convert-project-to-Gradle.patch
+++ b/patches/api/Convert-project-to-Gradle.patch
@@ -46,7 +46,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    api("com.google.guava:guava:31.0.1-jre")
 +    api("com.google.code.gson:gson:2.8.9")
 +    api("net.md-5:bungeecord-chat:1.16-R0.4")
-+    api("org.yaml:snakeyaml:1.32")
++    api("org.yaml:snakeyaml:1.33")
 +
 +    compileOnly("org.apache.maven:maven-resolver-provider:3.8.5")
 +    compileOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.7.3")
@@ -96,7 +96,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    options.isDocFilesSubDirs = true
 +    options.links(
 +        "https://guava.dev/releases/31.0.1-jre/api/docs/",
-+        "https://javadoc.io/doc/org.yaml/snakeyaml/1.30/",
++        "https://javadoc.io/doc/org.yaml/snakeyaml/1.33/",
 +        "https://javadoc.io/doc/org.jetbrains/annotations-java5/23.0.0/",
 +        "https://javadoc.io/doc/net.md-5/bungeecord-chat/1.16-R0.4/",
 +    )
@@ -175,7 +175,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -        <dependency>
 -            <groupId>org.yaml</groupId>
 -            <artifactId>snakeyaml</artifactId>
--            <version>1.32</version>
+-            <version>1.33</version>
 -            <scope>compile</scope>
 -        </dependency>
 -        <!-- not part of the API proper -->
diff --git a/patches/api/Custom-replacement-for-eaten-items.patch b/patches/api/Custom-replacement-for-eaten-items.patch
index 5bd2b1657d..50e8e9add0 100644
--- a/patches/api/Custom-replacement-for-eaten-items.patch
+++ b/patches/api/Custom-replacement-for-eaten-items.patch
@@ -9,15 +9,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/event/player/PlayerItemConsumeEvent.java
 +++ b/src/main/java/org/bukkit/event/player/PlayerItemConsumeEvent.java
 @@ -0,0 +0,0 @@ public class PlayerItemConsumeEvent extends PlayerEvent implements Cancellable {
-     private static final HandlerList handlers = new HandlerList();
      private boolean isCancelled = false;
      private ItemStack item;
+     private final EquipmentSlot hand;
 +    @Nullable private ItemStack replacement; // Paper
  
      /**
       * @param player the player consuming
 @@ -0,0 +0,0 @@ public class PlayerItemConsumeEvent extends PlayerEvent implements Cancellable {
-         }
+         return hand;
      }
  
 +    // Paper start
diff --git a/patches/api/Expose-codepoint-limit-in-YamlConfigOptions-and-incr.patch b/patches/api/Expose-codepoint-limit-in-YamlConfigOptions-and-incr.patch
index bdf353e523..b37b835d4d 100644
--- a/patches/api/Expose-codepoint-limit-in-YamlConfigOptions-and-incr.patch
+++ b/patches/api/Expose-codepoint-limit-in-YamlConfigOptions-and-incr.patch
@@ -5,19 +5,6 @@ Subject: [PATCH] Expose codepoint limit in YamlConfigOptions, and increase
  default
 
 
-diff --git a/build.gradle.kts b/build.gradle.kts
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/build.gradle.kts
-+++ b/build.gradle.kts
-@@ -0,0 +0,0 @@ dependencies {
-     api("com.google.guava:guava:31.0.1-jre")
-     api("com.google.code.gson:gson:2.8.9")
-     api("net.md-5:bungeecord-chat:1.16-R0.4-deprecated+build.6") // Paper
--    api("org.yaml:snakeyaml:1.32")
-+    api("org.yaml:snakeyaml:1.33") // Paper
-     // Paper start
-     api("com.googlecode.json-simple:json-simple:1.1.1") {
-         isTransitive = false // includes junit
 diff --git a/src/main/java/org/bukkit/configuration/file/YamlConfiguration.java b/src/main/java/org/bukkit/configuration/file/YamlConfiguration.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/configuration/file/YamlConfiguration.java
diff --git a/patches/server/Ability-to-apply-mending-to-XP-API.patch b/patches/server/Ability-to-apply-mending-to-XP-API.patch
index 1f719680fd..34f9c123c4 100644
--- a/patches/server/Ability-to-apply-mending-to-XP-API.patch
+++ b/patches/server/Ability-to-apply-mending-to-XP-API.patch
@@ -32,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            orb.setPosRaw(handle.getX(), handle.getY(), handle.getZ());
 +
 +            int i = Math.min(orb.xpToDurability(amount), itemstack.getDamageValue());
-+            org.bukkit.event.player.PlayerItemMendEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemMendEvent(handle, orb, itemstack, i);
++            org.bukkit.event.player.PlayerItemMendEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemMendEvent(handle, orb, itemstack, stackEntry.getKey(), i);
 +            i = event.getRepairAmount();
 +            orb.discard();
 +            if (!event.isCancelled()) {
diff --git a/patches/server/Add-dropLeash-variable-to-EntityUnleashEvent.patch b/patches/server/Add-dropLeash-variable-to-EntityUnleashEvent.patch
index 0b3653bd69..7bbebb88cb 100644
--- a/patches/server/Add-dropLeash-variable-to-EntityUnleashEvent.patch
+++ b/patches/server/Add-dropLeash-variable-to-EntityUnleashEvent.patch
@@ -12,9 +12,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              return InteractionResult.PASS;
          } else if (this.getLeashHolder() == player) {
              // CraftBukkit start - fire PlayerUnleashEntityEvent
--            if (CraftEventFactory.callPlayerUnleashEntityEvent(this, player).isCancelled()) {
+-            if (CraftEventFactory.callPlayerUnleashEntityEvent(this, player, hand).isCancelled()) {
 +            // Paper start - drop leash variable
-+            org.bukkit.event.player.PlayerUnleashEntityEvent event = CraftEventFactory.callPlayerUnleashEntityEvent(this, player, !player.getAbilities().instabuild);
++            org.bukkit.event.player.PlayerUnleashEntityEvent event = CraftEventFactory.callPlayerUnleashEntityEvent(this, player, hand, !player.getAbilities().instabuild);
 +            if (event.isCancelled()) {
 +                // Paper end
                  ((ServerPlayer) player).connection.send(new ClientboundSetEntityLinkPacket(this, this.getLeashHolder()));
@@ -108,9 +108,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                          entityinsentient = (Mob) iterator.next();
                          if (entityinsentient.isLeashed() && entityinsentient.getLeashHolder() == this) {
                              // CraftBukkit start
--                            if (CraftEventFactory.callPlayerUnleashEntityEvent(entityinsentient, player).isCancelled()) {
+-                            if (CraftEventFactory.callPlayerUnleashEntityEvent(entityinsentient, player, hand).isCancelled()) {
 +                            // Paper start - drop leash variable
-+                            org.bukkit.event.player.PlayerUnleashEntityEvent event = CraftEventFactory.callPlayerUnleashEntityEvent(entityinsentient, player, !player.getAbilities().instabuild);
++                            org.bukkit.event.player.PlayerUnleashEntityEvent event = CraftEventFactory.callPlayerUnleashEntityEvent(entityinsentient, player, hand, !player.getAbilities().instabuild);
 +                            if (event.isCancelled()) {
 +                                // Paper end
                                  die = false;
@@ -129,11 +129,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          return itemInHand;
      }
  
--    public static PlayerUnleashEntityEvent callPlayerUnleashEntityEvent(Mob entity, net.minecraft.world.entity.player.Player player) {
--        PlayerUnleashEntityEvent event = new PlayerUnleashEntityEvent(entity.getBukkitEntity(), (Player) player.getBukkitEntity());
+-    public static PlayerUnleashEntityEvent callPlayerUnleashEntityEvent(Mob entity, net.minecraft.world.entity.player.Player player, InteractionHand enumhand) {
+-        PlayerUnleashEntityEvent event = new PlayerUnleashEntityEvent(entity.getBukkitEntity(), (Player) player.getBukkitEntity(), CraftEquipmentSlot.getHand(enumhand));
 +    // Paper start - drop leash variable
-+    public static PlayerUnleashEntityEvent callPlayerUnleashEntityEvent(Mob entity, net.minecraft.world.entity.player.Player player, boolean dropLeash) {
-+        PlayerUnleashEntityEvent event = new PlayerUnleashEntityEvent(entity.getBukkitEntity(), (Player) player.getBukkitEntity(), dropLeash);
++    public static PlayerUnleashEntityEvent callPlayerUnleashEntityEvent(Mob entity, net.minecraft.world.entity.player.Player player, InteractionHand enumhand, boolean dropLeash) {
++        PlayerUnleashEntityEvent event = new PlayerUnleashEntityEvent(entity.getBukkitEntity(), (Player) player.getBukkitEntity(), CraftEquipmentSlot.getHand(enumhand), dropLeash);
 +        // Paper end
          entity.level.getCraftServer().getPluginManager().callEvent(event);
          return event;
diff --git a/patches/server/Add-hand-to-bucket-events.patch b/patches/server/Add-hand-to-bucket-events.patch
deleted file mode 100644
index ce8b38ade9..0000000000
--- a/patches/server/Add-hand-to-bucket-events.patch
+++ /dev/null
@@ -1,125 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: BillyGalbreath <Blake.Galbreath@GMail.com>
-Date: Thu, 2 Aug 2018 08:44:35 -0500
-Subject: [PATCH] Add hand to bucket events
-
-
-diff --git a/src/main/java/net/minecraft/world/entity/animal/Cow.java b/src/main/java/net/minecraft/world/entity/animal/Cow.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/entity/animal/Cow.java
-+++ b/src/main/java/net/minecraft/world/entity/animal/Cow.java
-@@ -0,0 +0,0 @@ public class Cow extends Animal {
- 
-         if (itemstack.is(Items.BUCKET) && !this.isBaby()) {
-             // CraftBukkit start - Got milk?
--            org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET);
-+            org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand); // Paper - add enumHand
- 
-             if (event.isCancelled()) {
-                 return InteractionResult.PASS;
-diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
-+++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
-@@ -0,0 +0,0 @@ public class Goat extends Animal {
- 
-         if (itemstack.is(Items.BUCKET) && !this.isBaby()) {
-             // CraftBukkit start - Got milk?
--            org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET);
-+            org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand); // Paper - add enumHand
- 
-             if (event.isCancelled()) {
-                 return InteractionResult.PASS;
-diff --git a/src/main/java/net/minecraft/world/item/BucketItem.java b/src/main/java/net/minecraft/world/item/BucketItem.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/item/BucketItem.java
-+++ b/src/main/java/net/minecraft/world/item/BucketItem.java
-@@ -0,0 +0,0 @@ public class BucketItem extends Item implements DispensibleContainerItem {
-                         // CraftBukkit start
-                         ItemStack dummyFluid = ifluidsource.pickupBlock(DummyGeneratorAccess.INSTANCE, blockposition, iblockdata);
-                         if (dummyFluid.isEmpty()) return InteractionResultHolder.fail(itemstack); // Don't fire event if the bucket won't be filled.
--                        PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) world, user, blockposition, blockposition, movingobjectpositionblock.getDirection(), itemstack, dummyFluid.getItem());
-+                        PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) world, user, blockposition, blockposition, movingobjectpositionblock.getDirection(), itemstack, dummyFluid.getItem(), hand); // Paper - add enumhand
- 
-                         if (event.isCancelled()) {
-                             ((ServerPlayer) user).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-5163 (see PlayerInteractManager)
-@@ -0,0 +0,0 @@ public class BucketItem extends Item implements DispensibleContainerItem {
-                     iblockdata = world.getBlockState(blockposition);
-                     BlockPos blockposition2 = iblockdata.getBlock() instanceof LiquidBlockContainer && this.content == Fluids.WATER ? blockposition : blockposition1;
- 
--                    if (this.emptyContents(user, world, blockposition2, movingobjectpositionblock, movingobjectpositionblock.getDirection(), blockposition, itemstack)) { // CraftBukkit
-+                    if (this.emptyContents(user, world, blockposition2, movingobjectpositionblock, movingobjectpositionblock.getDirection(), blockposition, itemstack, hand)) { // CraftBukkit // Paper - add enumhand
-                         this.checkExtraContent(user, world, itemstack, blockposition2);
-                         if (user instanceof ServerPlayer) {
-                             CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer) user, blockposition2, itemstack);
-@@ -0,0 +0,0 @@ public class BucketItem extends Item implements DispensibleContainerItem {
- 
-     @Override
-     public boolean emptyContents(@Nullable Player player, Level world, BlockPos pos, @Nullable BlockHitResult hitResult) {
--        return this.emptyContents(player, world, pos, hitResult, null, null, null);
-+        // Paper start - add enumHand
-+        return emptyContents(player, world, pos, hitResult, null, null, null, null);
-     }
- 
--    public boolean emptyContents(Player entityhuman, Level world, BlockPos blockposition, @Nullable BlockHitResult movingobjectpositionblock, Direction enumdirection, BlockPos clicked, ItemStack itemstack) {
-+    public boolean emptyContents(Player entityhuman, Level world, BlockPos blockposition, @Nullable BlockHitResult movingobjectpositionblock, Direction enumdirection, BlockPos clicked, ItemStack itemstack, InteractionHand enumhand) {
-+        // Paper end
-         // CraftBukkit end
-         if (!(this.content instanceof FlowingFluid)) {
-             return false;
-@@ -0,0 +0,0 @@ public class BucketItem extends Item implements DispensibleContainerItem {
- 
-             // CraftBukkit start
-             if (flag1 && entityhuman != null) {
--                PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent((ServerLevel) world, entityhuman, blockposition, clicked, enumdirection, itemstack);
-+                PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent((ServerLevel) world, entityhuman, blockposition, clicked, enumdirection, itemstack, enumhand); // Paper - add enumhand
-                 if (event.isCancelled()) {
-                     ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-4238: needed when looking through entity
-                     ((ServerPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-4541
-@@ -0,0 +0,0 @@ public class BucketItem extends Item implements DispensibleContainerItem {
-             }
-             // CraftBukkit end
-             if (!flag1) {
--                return movingobjectpositionblock != null && this.emptyContents(entityhuman, world, movingobjectpositionblock.getBlockPos().relative(movingobjectpositionblock.getDirection()), (BlockHitResult) null, enumdirection, clicked, itemstack); // CraftBukkit
-+                return movingobjectpositionblock != null && this.emptyContents(entityhuman, world, movingobjectpositionblock.getBlockPos().relative(movingobjectpositionblock.getDirection()), (BlockHitResult) null, enumdirection, clicked, itemstack, enumhand); // CraftBukkit // Paper
-             } else if (world.dimensionType().ultraWarm() && this.content.is(FluidTags.WATER)) {
-                 int i = blockposition.getX();
-                 int j = blockposition.getY();
-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 {
-     }
- 
-     private static PlayerEvent getPlayerBucketEvent(boolean isFilling, ServerLevel world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemstack, net.minecraft.world.item.Item item) {
-+        // Paper start - add enumHand
-+        return getPlayerBucketEvent(isFilling, world, who, changed, clicked, clickedFace, itemstack, item, null);
-+    }
-+
-+    public static PlayerBucketEmptyEvent callPlayerBucketEmptyEvent(ServerLevel world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemstack, InteractionHand enumHand) {
-+        return (PlayerBucketEmptyEvent) getPlayerBucketEvent(false, world, who, changed, clicked, clickedFace, itemstack, Items.BUCKET, enumHand);
-+    }
-+
-+    public static PlayerBucketFillEvent callPlayerBucketFillEvent(ServerLevel world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemInHand, net.minecraft.world.item.Item bucket, InteractionHand enumHand) {
-+        return (PlayerBucketFillEvent) getPlayerBucketEvent(true, world, who, clicked, changed, clickedFace, itemInHand, bucket, enumHand);
-+    }
-+
-+    private static PlayerEvent getPlayerBucketEvent(boolean isFilling, ServerLevel world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemstack, net.minecraft.world.item.Item item, InteractionHand enumHand) {
-+        // Paper end
-         Player player = (Player) who.getBukkitEntity();
-         CraftItemStack itemInHand = CraftItemStack.asNewCraftStack(item);
-         Material bucket = CraftMagicNumbers.getMaterial(itemstack.getItem());
-@@ -0,0 +0,0 @@ public class CraftEventFactory {
- 
-         PlayerEvent event;
-         if (isFilling) {
--            event = new PlayerBucketFillEvent(player, block, blockClicked, blockFace, bucket, itemInHand);
-+            event = new PlayerBucketFillEvent(player, block, blockClicked, blockFace, bucket, itemInHand, enumHand == null ? null : enumHand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND); // Paper - add enumHand
-             ((PlayerBucketFillEvent) event).setCancelled(!CraftEventFactory.canBuild(world, player, changed.getX(), changed.getZ()));
-         } else {
--            event = new PlayerBucketEmptyEvent(player, block, blockClicked, blockFace, bucket, itemInHand);
-+            event = new PlayerBucketEmptyEvent(player, block, blockClicked, blockFace, bucket, itemInHand, enumHand == null ? null : enumHand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND); // Paper - add enumHand
-             ((PlayerBucketEmptyEvent) event).setCancelled(!CraftEventFactory.canBuild(world, player, changed.getX(), changed.getZ()));
-         }
- 
diff --git a/patches/server/Add-ignore-discounts-API.patch b/patches/server/Add-ignore-discounts-API.patch
index 9d6cd5ae0f..5ea55cd7fa 100644
--- a/patches/server/Add-ignore-discounts-API.patch
+++ b/patches/server/Add-ignore-discounts-API.patch
@@ -95,8 +95,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantRecipe.java
 +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantRecipe.java
 @@ -0,0 +0,0 @@ public class CraftMerchantRecipe extends MerchantRecipe {
-     }
  
+     @Deprecated
      public CraftMerchantRecipe(ItemStack result, int uses, int maxUses, boolean experienceReward, int experience, float priceMultiplier) {
 -        this(result, uses, maxUses, experienceReward, experience, priceMultiplier, 0, 0);
 +        // Paper start - add ignoreDiscounts param
@@ -147,8 +147,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          if (recipe instanceof CraftMerchantRecipe) {
              return (CraftMerchantRecipe) recipe;
          } else {
--            CraftMerchantRecipe craft = new CraftMerchantRecipe(recipe.getResult(), recipe.getUses(), recipe.getMaxUses(), recipe.hasExperienceReward(), recipe.getVillagerExperience(), recipe.getPriceMultiplier());
-+            CraftMerchantRecipe craft = new CraftMerchantRecipe(recipe.getResult(), recipe.getUses(), recipe.getMaxUses(), recipe.hasExperienceReward(), recipe.getVillagerExperience(), recipe.getPriceMultiplier(), recipe.shouldIgnoreDiscounts()); // Paper - shouldIgnoreDiscounts
+-            CraftMerchantRecipe craft = new CraftMerchantRecipe(recipe.getResult(), recipe.getUses(), recipe.getMaxUses(), recipe.hasExperienceReward(), recipe.getVillagerExperience(), recipe.getPriceMultiplier(), recipe.getDemand(), recipe.getSpecialPrice());
++            CraftMerchantRecipe craft = new CraftMerchantRecipe(recipe.getResult(), recipe.getUses(), recipe.getMaxUses(), recipe.hasExperienceReward(), recipe.getVillagerExperience(), recipe.getPriceMultiplier(), recipe.getDemand(), recipe.getSpecialPrice(), recipe.shouldIgnoreDiscounts()); // Paper - shouldIgnoreDiscounts
              craft.setIngredients(recipe.getIngredients());
  
              return craft;
diff --git a/patches/server/Custom-replacement-for-eaten-items.patch b/patches/server/Custom-replacement-for-eaten-items.patch
index 1b223f204b..3a655c7eca 100644
--- a/patches/server/Custom-replacement-for-eaten-items.patch
+++ b/patches/server/Custom-replacement-for-eaten-items.patch
@@ -12,11 +12,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                      this.triggerItemUseEffects(this.useItem, 16);
                      // CraftBukkit start - fire PlayerItemConsumeEvent
                      ItemStack itemstack;
-+                PlayerItemConsumeEvent event = null; // Paper
++                    PlayerItemConsumeEvent event = null; // Paper
                      if (this instanceof ServerPlayer) {
                          org.bukkit.inventory.ItemStack craftItem = CraftItemStack.asBukkitCopy(this.useItem);
--                        PlayerItemConsumeEvent event = new PlayerItemConsumeEvent((Player) this.getBukkitEntity(), craftItem);
-+                    event = new PlayerItemConsumeEvent((Player) this.getBukkitEntity(), craftItem); // Paper
+                         org.bukkit.inventory.EquipmentSlot hand = org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(enumhand);
+-                        PlayerItemConsumeEvent event = new PlayerItemConsumeEvent((Player) this.getBukkitEntity(), craftItem, hand);
++                        event = new PlayerItemConsumeEvent((Player) this.getBukkitEntity(), craftItem, hand); // Paper
                          level.getCraftServer().getPluginManager().callEvent(event);
  
                          if (event.isCancelled()) {
diff --git a/work/Bukkit b/work/Bukkit
index c7c1118861..0994345029 160000
--- a/work/Bukkit
+++ b/work/Bukkit
@@ -1 +1 @@
-Subproject commit c7c11188610b4b0a59d090b06cabdc239337dcb8
+Subproject commit 0994345029c4d127696616de3bab3e8044b03749
diff --git a/work/CraftBukkit b/work/CraftBukkit
index c2c39089eb..aaf484f6fd 160000
--- a/work/CraftBukkit
+++ b/work/CraftBukkit
@@ -1 +1 @@
-Subproject commit c2c39089eb639479327acb2c9f58bdfb69bc6b81
+Subproject commit aaf484f6fdb052306f7612bc0e721fa440d1b841