From 64e5ff904c9bb40faa26a07132f08c4484efea2a Mon Sep 17 00:00:00 2001
From: Nassim Jahnke <nassim@njahnke.dev>
Date: Fri, 19 Jan 2024 13:22:30 +0100
Subject: [PATCH] [ci skip] Add more identifying patch comments, merge related
 patches

---
 .../server/Add-BellRevealRaiderEvent.patch    |  6 +--
 patches/server/Add-BlockBreakBlockEvent.patch | 14 +++---
 .../Add-ElderGuardianAppearanceEvent.patch    | 10 ++--
 ....patch => Add-EntityDamageItemEvent.patch} | 18 ++++----
 .../server/Add-EntityInsideBlockEvent.patch   | 46 +++++++++----------
 ...nt.patch => Add-PlayerArmSwingEvent.patch} |  4 +-
 .../server/Add-PlayerKickEvent-causes.patch   |  8 ++--
 patches/server/Add-PlayerSetSpawnEvent.patch  | 44 +++++++++---------
 .../Add-Unix-domain-socket-support.patch      | 28 +++++------
 ...cause-to-Weather-ThunderChangeEvents.patch | 28 +++++------
 ...g-for-mobs-immune-to-default-effects.patch |  8 ++--
 ...ch => Add-missing-forceDrop-toggles.patch} | 34 +++++++-------
 .../Add-option-to-disable-block-updates.patch |  2 +-
 ...riting-of-comments-to-server.propert.patch |  4 +-
 ...target-without-changing-other-things.patch | 14 +++---
 .../Clear-bucket-NBT-after-dispense.patch     |  2 +-
 ...g-option-for-Piglins-guarding-chests.patch |  2 +-
 ....patch => Expand-EntityUnleashEvent.patch} |  6 +--
 .../server/Expand-PlayerItemDamageEvent.patch |  6 +--
 ...yerBucketEmptyEvent-result-itemstack.patch |  8 ++--
 ...PlayerDropItemEvent-using-wrong-item.patch |  2 +-
 .../server/Fix-a-bunch-of-vanilla-bugs.patch  |  2 +-
 ...x-and-optimise-world-force-upgrading.patch |  4 +-
 ...from-signs-not-firing-command-events.patch | 12 ++---
 .../Fix-invulnerable-end-crystals.patch       |  4 +-
 ...-event-leave-message-not-being-sent.patch} | 22 ++++-----
 ...lock-data-for-EntityChangeBlockEvent.patch |  2 +-
 .../server/Fix-potions-splash-events.patch    | 28 +++++------
 .../Improve-boat-collision-performance.patch  | 16 +++----
 .../Limit-item-frame-cursors-on-maps.patch    |  6 +--
 patches/server/Line-Of-Sight-Changes.patch    |  2 +-
 .../Make-EntityUnleashEvent-cancellable.patch | 41 -----------------
 ...ers-respect-inventory-max-stack-size.patch |  8 ++--
 patches/server/More-Enchantment-API.patch     |  2 +-
 patches/server/More-Projectile-API.patch      |  4 +-
 ...ove-range-check-for-block-placing-up.patch |  2 +-
 ...e-Biome-Mob-Lookups-for-Mob-Spawning.patch |  4 +-
 patches/server/Optimize-Hoppers.patch         |  2 +-
 ...ptimize-indirect-passenger-iteration.patch | 12 ++---
 ...prevent-NBT-copy-in-smithing-recipes.patch | 38 +++++++--------
 ...-AFK-kick-while-watching-end-credits.patch |  4 +-
 ...e-experience-dropping-on-block-break.patch |  2 +-
 ...nd-timings-for-sensors-and-behaviors.patch |  8 ++--
 .../Use-correct-seed-on-api-world-load.patch  |  2 +-
 ...etChunkIfLoadedImmediately-in-places.patch |  8 ++--
 .../server/add-per-world-spawn-limits.patch   |  3 +-
 46 files changed, 242 insertions(+), 290 deletions(-)
 rename patches/server/{Added-EntityDamageItemEvent.patch => Add-EntityDamageItemEvent.patch} (86%)
 rename patches/server/{Adds-PlayerArmSwingEvent.patch => Add-PlayerArmSwingEvent.patch} (92%)
 rename patches/server/{Add-a-bunch-of-missing-forceDrop-toggles.patch => Add-missing-forceDrop-toggles.patch} (78%)
 rename patches/server/{Add-dropLeash-variable-to-EntityUnleashEvent.patch => Expand-EntityUnleashEvent.patch} (97%)
 rename patches/server/{Fixes-kick-event-leave-message-not-being-sent.patch => Fix-kick-event-leave-message-not-being-sent.patch} (90%)
 delete mode 100644 patches/server/Make-EntityUnleashEvent-cancellable.patch

diff --git a/patches/server/Add-BellRevealRaiderEvent.patch b/patches/server/Add-BellRevealRaiderEvent.patch
index efd4d8b45f..34ce82469a 100644
--- a/patches/server/Add-BellRevealRaiderEvent.patch
+++ b/patches/server/Add-BellRevealRaiderEvent.patch
@@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          }).map((entity) -> (org.bukkit.entity.LivingEntity) entity.getBukkitEntity()).collect(java.util.stream.Collectors.toCollection(java.util.ArrayList::new)); // CraftBukkit
  
 -        org.bukkit.craftbukkit.event.CraftEventFactory.handleBellResonateEvent(world, pos, entities).forEach(BellBlockEntity::glow);
-+        org.bukkit.craftbukkit.event.CraftEventFactory.handleBellResonateEvent(world, pos, entities).forEach(entity -> glow(entity, pos)); // Paper - pass BlockPos
++        org.bukkit.craftbukkit.event.CraftEventFactory.handleBellResonateEvent(world, pos, entities).forEach(entity -> glow(entity, pos)); // Paper - Add BellRevealRaiderEvent
          // CraftBukkit end
      }
  
@@ -22,11 +22,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }
  
 -    private static void glow(LivingEntity entity) {
-+    // Paper start
++    // Paper start - Add BellRevealRaiderEvent
 +    private static void glow(LivingEntity entity) { glow(entity, null); }
 +    private static void glow(LivingEntity entity, @javax.annotation.Nullable BlockPos pos) {
 +        if (pos != null && !new io.papermc.paper.event.block.BellRevealRaiderEvent(entity.level().getWorld().getBlockAt(io.papermc.paper.util.MCUtil.toLocation(entity.level(), pos)), entity.getBukkitEntity()).callEvent()) return;
-+        // Paper end
++        // Paper end - Add BellRevealRaiderEvent
          entity.addEffect(new MobEffectInstance(MobEffects.GLOWING, 60));
      }
  
diff --git a/patches/server/Add-BlockBreakBlockEvent.patch b/patches/server/Add-BlockBreakBlockEvent.patch
index 431fd922f8..6488a966c4 100644
--- a/patches/server/Add-BlockBreakBlockEvent.patch
+++ b/patches/server/Add-BlockBreakBlockEvent.patch
@@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          }
  
      }
-+    // Paper start
++    // Paper start - Add BlockBreakBlockEvent
 +    public static boolean dropResources(BlockState state, LevelAccessor world, BlockPos pos, @Nullable BlockEntity blockEntity, BlockPos source) {
 +        if (world instanceof ServerLevel) {
 +            List<org.bukkit.inventory.ItemStack> items = com.google.common.collect.Lists.newArrayList();
@@ -28,7 +28,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        }
 +        return true;
 +    }
-+    // Paper end
++    // Paper end - Add BlockBreakBlockEvent
  
      public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) {
          if (world instanceof ServerLevel) {
@@ -41,7 +41,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  BlockEntity tileentity = iblockdata1.hasBlockEntity() ? world.getBlockEntity(blockposition3) : null;
  
 -                dropResources(iblockdata1, world, blockposition3, tileentity);
-+                dropResources(iblockdata1, world, blockposition3, tileentity, pos); // Paper
++                dropResources(iblockdata1, world, blockposition3, tileentity, pos); // Paper - Add BlockBreakBlockEvent
                  world.setBlock(blockposition3, Blocks.AIR.defaultBlockState(), 18);
                  world.gameEvent(GameEvent.BLOCK_DESTROY, blockposition3, GameEvent.Context.of(iblockdata1));
                  if (!iblockdata1.is(BlockTags.FIRE)) {
@@ -54,7 +54,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          } else {
              if (!state.isAir()) {
 -                this.beforeDestroyingBlock(world, pos, state);
-+                this.beforeDestroyingBlock(world, pos, state, pos.relative(direction.getOpposite())); // Paper
++                this.beforeDestroyingBlock(world, pos, state, pos.relative(direction.getOpposite())); // Paper - Add BlockBreakBlockEvent
              }
  
              world.setBlock(pos, fluidState.createLegacyBlock(), 3);
@@ -62,7 +62,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      }
  
-+    protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) { beforeDestroyingBlock(world, pos, state); } // Paper - add source parameter
++    protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) { beforeDestroyingBlock(world, pos, state); } // Paper - Add BlockBreakBlockEvent
      protected abstract void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state);
  
      private static short getCacheKey(BlockPos from, BlockPos to) {
@@ -74,13 +74,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          return world.getGameRules().getBoolean(GameRules.RULE_WATER_SOURCE_CONVERSION);
      }
  
-+    // Paper start
++    // Paper start - Add BlockBreakBlockEvent
 +    @Override
 +    protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state,  BlockPos source) {
 +        BlockEntity tileentity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null;
 +        Block.dropResources(state, world, pos, tileentity, source);
 +    }
-+    // Paper end
++    // Paper end - Add BlockBreakBlockEvent
      @Override
      protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state) {
          BlockEntity blockEntity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null;
diff --git a/patches/server/Add-ElderGuardianAppearanceEvent.patch b/patches/server/Add-ElderGuardianAppearanceEvent.patch
index 03fc95e743..db52fad94a 100644
--- a/patches/server/Add-ElderGuardianAppearanceEvent.patch
+++ b/patches/server/Add-ElderGuardianAppearanceEvent.patch
@@ -12,24 +12,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }
  
      public static List<ServerPlayer> addEffectToPlayersAround(ServerLevel worldserver, @Nullable Entity entity, Vec3 vec3d, double d0, MobEffectInstance mobeffect, int i, org.bukkit.event.entity.EntityPotionEffectEvent.Cause cause) {
-+        // Paper start
++        // Paper start - Add ElderGuardianAppearanceEvent
 +        return addEffectToPlayersAround(worldserver, entity, vec3d, d0, mobeffect, i, cause, null);
 +    }
 +
 +    public static List<ServerPlayer> addEffectToPlayersAround(ServerLevel worldserver, @Nullable Entity entity, Vec3 vec3d, double d0, MobEffectInstance mobeffect, int i, org.bukkit.event.entity.EntityPotionEffectEvent.Cause cause, @Nullable java.util.function.Predicate<ServerPlayer> playerPredicate) {
-+        // Paper end
++        // Paper end - Add ElderGuardianAppearanceEvent
          // CraftBukkit end
          MobEffect mobeffectlist = mobeffect.getEffect();
          List<ServerPlayer> list = worldserver.getPlayers((entityplayer) -> {
 -            return entityplayer.gameMode.isSurvival() && (entity == null || !entity.isAlliedTo((Entity) entityplayer)) && vec3d.closerThan(entityplayer.position(), d0) && (!entityplayer.hasEffect(mobeffectlist) || entityplayer.getEffect(mobeffectlist).getAmplifier() < mobeffect.getAmplifier() || entityplayer.getEffect(mobeffectlist).endsWithin(i - 1));
-+            // Paper start
++            // Paper start - Add ElderGuardianAppearanceEvent
 +            boolean condition = entityplayer.gameMode.isSurvival() && (entity == null || !entity.isAlliedTo((Entity) entityplayer)) && vec3d.closerThan(entityplayer.position(), d0) && (!entityplayer.hasEffect(mobeffectlist) || entityplayer.getEffect(mobeffectlist).getAmplifier() < mobeffect.getAmplifier() || entityplayer.getEffect(mobeffectlist).endsWithin(i - 1));
 +            if (condition) {
 +                return playerPredicate == null || playerPredicate.test(entityplayer); // Only test the player AFTER it is true
 +            } else {
 +                return false;
 +            }
-+            // Paper ned
++            // Paper ned - Add ElderGuardianAppearanceEvent
          });
  
          list.forEach((entityplayer) -> {
@@ -42,7 +42,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          if ((this.tickCount + this.getId()) % 1200 == 0) {
              MobEffectInstance mobeffect = new MobEffectInstance(MobEffects.DIG_SLOWDOWN, 6000, 2);
 -            List<ServerPlayer> list = MobEffectUtil.addEffectToPlayersAround((ServerLevel) this.level(), this, this.position(), 50.0D, mobeffect, 1200, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit
-+            List<ServerPlayer> list = MobEffectUtil.addEffectToPlayersAround((ServerLevel) this.level(), this, this.position(), 50.0D, mobeffect, 1200, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK, (player) -> new io.papermc.paper.event.entity.ElderGuardianAppearanceEvent(getBukkitEntity(), player.getBukkitEntity()).callEvent()); // CraftBukkit // Paper
++            List<ServerPlayer> list = MobEffectUtil.addEffectToPlayersAround((ServerLevel) this.level(), this, this.position(), 50.0D, mobeffect, 1200, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK, (player) -> new io.papermc.paper.event.entity.ElderGuardianAppearanceEvent(getBukkitEntity(), player.getBukkitEntity()).callEvent()); // CraftBukkit // Paper - Add ElderGuardianAppearanceEvent
  
              list.forEach((entityplayer) -> {
                  entityplayer.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.GUARDIAN_ELDER_EFFECT, this.isSilent() ? 0.0F : 1.0F));
diff --git a/patches/server/Added-EntityDamageItemEvent.patch b/patches/server/Add-EntityDamageItemEvent.patch
similarity index 86%
rename from patches/server/Added-EntityDamageItemEvent.patch
rename to patches/server/Add-EntityDamageItemEvent.patch
index f3865d51bd..d54330a001 100644
--- a/patches/server/Added-EntityDamageItemEvent.patch
+++ b/patches/server/Add-EntityDamageItemEvent.patch
@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Jake Potrebic <jake.m.potrebic@gmail.com>
 Date: Tue, 22 Dec 2020 13:52:48 -0800
-Subject: [PATCH] Added EntityDamageItemEvent
+Subject: [PATCH] Add EntityDamageItemEvent
 
 
 diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
@@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }
  
 -    public boolean hurt(int amount, RandomSource random, @Nullable ServerPlayer player) {
-+    public boolean hurt(int amount, RandomSource random, @Nullable LivingEntity player) { // Paper - allow any living entity instead of only ServerPlayers
++    public boolean hurt(int amount, RandomSource random, @Nullable LivingEntity player) { // Paper - Add EntityDamageItemEvent
          if (!this.isDamageableItem()) {
              return false;
          } else {
@@ -23,8 +23,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  // CraftBukkit start
 -                if (player != null) {
 -                    PlayerItemDamageEvent event = new PlayerItemDamageEvent(player.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount);
-+                if (player instanceof ServerPlayer serverPlayer) { // Paper
-+                    PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount); // Paper
++                if (player instanceof ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent
++                    PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount); // Paper - Add EntityDamageItemEvent
                      event.getPlayer().getServer().getPluginManager().callEvent(event);
  
                      if (amount != event.getDamage() || event.isCancelled()) {
@@ -32,14 +32,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                      }
  
                      amount = event.getDamage();
-+                    // Paper start - EntityDamageItemEvent
++                    // Paper start - Add EntityDamageItemEvent
 +                } else if (player != null) {
 +                    io.papermc.paper.event.entity.EntityDamageItemEvent event = new io.papermc.paper.event.entity.EntityDamageItemEvent(player.getBukkitLivingEntity(), CraftItemStack.asCraftMirror(this), amount);
 +                    if (!event.callEvent()) {
 +                        return false;
 +                    }
 +                    amount = event.getDamage();
-+                    // Paper end
++                    // Paper end - Add EntityDamageItemEvent
                  }
                  // CraftBukkit end
                  if (amount <= 0) {
@@ -49,8 +49,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
 -            if (player != null && amount != 0) {
 -                CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(player, this, this.getDamageValue() + amount);
-+            if (player instanceof ServerPlayer serverPlayer && amount != 0) { // Paper
-+                CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(serverPlayer, this, this.getDamageValue() + amount); // Paper
++            if (player instanceof ServerPlayer serverPlayer && amount != 0) { // Paper - Add EntityDamageItemEvent
++                CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(serverPlayer, this, this.getDamageValue() + amount); // Paper - Add EntityDamageItemEvent
              }
  
              j = this.getDamageValue() + amount;
@@ -59,7 +59,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          if (!entity.level().isClientSide && (!(entity instanceof net.minecraft.world.entity.player.Player) || !((net.minecraft.world.entity.player.Player) entity).getAbilities().instabuild)) {
              if (this.isDamageableItem()) {
 -                if (this.hurt(amount, entity.getRandom(), entity instanceof ServerPlayer ? (ServerPlayer) entity : null)) {
-+                if (this.hurt(amount, entity.getRandom(), entity /*instanceof ServerPlayer ? (ServerPlayer) entity : null*/)) { // Paper - pass LivingEntity for EntityItemDamageEvent
++                if (this.hurt(amount, entity.getRandom(), entity /*instanceof ServerPlayer ? (ServerPlayer) entity : null*/)) { // Paper - Add EntityDamageItemEvent
                      breakCallback.accept(entity);
                      Item item = this.getItem();
                      // CraftBukkit start - Check for item breaking
diff --git a/patches/server/Add-EntityInsideBlockEvent.patch b/patches/server/Add-EntityInsideBlockEvent.patch
index a16cebf738..6f3585f7f2 100644
--- a/patches/server/Add-EntityInsideBlockEvent.patch
+++ b/patches/server/Add-EntityInsideBlockEvent.patch
@@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (!entity.fireImmune()) {
              entity.setRemainingFireTicks(entity.getRemainingFireTicks() + 1);
              if (entity.getRemainingFireTicks() == 0) {
@@ -24,7 +24,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (!world.isClientSide) {
              int i = this.getSignalForState(state);
  
@@ -36,7 +36,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (!world.isClientSide) {
              if (state.getValue(BigDripleafBlock.TILT) == Tilt.NONE && BigDripleafBlock.canEntityTilt(pos, entity) && !world.hasNeighborSignal(pos)) {
                  // CraftBukkit start - tilt dripleaf
@@ -48,7 +48,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          BlockState blockState = world.getBlockState(pos.above());
          if (blockState.isAir()) {
              entity.onAboveBubbleCol(state.getValue(DRAG_DOWN));
@@ -60,7 +60,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (!world.isClientSide && this.type.canButtonBeActivatedByArrows() && !(Boolean) state.getValue(ButtonBlock.POWERED)) {
              this.checkPressed(state, world, pos);
          }
@@ -72,7 +72,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          CraftEventFactory.blockDamage = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); // CraftBukkit
          entity.hurt(world.damageSources().cactus(), 1.0F);
          CraftEventFactory.blockDamage = null; // CraftBukkit
@@ -84,7 +84,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if ((Boolean) state.getValue(CampfireBlock.LIT) && entity instanceof LivingEntity && !EnchantmentHelper.hasFrostWalker((LivingEntity) entity)) {
              org.bukkit.craftbukkit.event.CraftEventFactory.blockDamage = CraftBlock.at(world, pos); // CraftBukkit
              entity.hurt(world.damageSources().inFire(), (float) this.fireDamage);
@@ -96,7 +96,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (entity instanceof Ravager && CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit
              world.destroyBlock(pos, true, entity);
          }
@@ -108,7 +108,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (!world.isClientSide) {
              if (!(Boolean) state.getValue(DetectorRailBlock.POWERED)) {
                  this.checkPressed(world, pos, state);
@@ -120,7 +120,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (world instanceof ServerLevel && entity.canChangeDimensions() && Shapes.joinIsNotEmpty(Shapes.create(entity.getBoundingBox().move((double) (-pos.getX()), (double) (-pos.getY()), (double) (-pos.getZ()))), state.getShape(world, pos), BooleanOp.AND)) {
              ResourceKey<Level> resourcekey = world.getTypeKey() == LevelStem.END ? Level.OVERWORLD : Level.END; // CraftBukkit - SPIGOT-6152: send back to main overworld in custom ends
              ServerLevel worldserver = ((ServerLevel) world).getServer().getLevel(resourcekey);
@@ -132,7 +132,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (entity.getType().equals(EntityType.FALLING_BLOCK)) {
              this.destroyBlock(world, pos);
          }
@@ -144,7 +144,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (this.isSlidingDown(pos, entity)) {
              this.maybeDoSlideAchievement(entity, pos);
              this.doSlideMovement(entity);
@@ -156,7 +156,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          BlockEntity blockEntity = world.getBlockEntity(pos);
          if (blockEntity instanceof HopperBlockEntity) {
              HopperBlockEntity.entityInside(world, pos, state, entity, (HopperBlockEntity)blockEntity);
@@ -168,7 +168,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (this.isEntityInsideContent(state, pos, entity)) {
              entity.lavaHurt();
          }
@@ -180,7 +180,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (!world.isClientSide && entity.isOnFire() && this.isEntityInsideContent(state, pos, entity)) {
              // CraftBukkit start
              if (entity.mayInteract(world, pos)) {
@@ -192,7 +192,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (entity.canChangeDimensions()) {
              // CraftBukkit start - Entity in portal
              EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()));
@@ -204,7 +204,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (entity instanceof Ravager && world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
              world.destroyBlock(pos, true, entity);
          }
@@ -216,7 +216,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (!(entity instanceof LivingEntity) || entity.getFeetBlockState().is((Block) this)) {
              entity.makeStuckInBlock(state, new Vec3(0.8999999761581421D, 1.5D, 0.8999999761581421D));
              if (world.isClientSide) {
@@ -228,7 +228,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (entity instanceof LivingEntity && entity.getType() != EntityType.FOX && entity.getType() != EntityType.BEE) {
              entity.makeStuckInBlock(state, new Vec3(0.800000011920929D, 0.75D, 0.800000011920929D));
              if (!world.isClientSide && (Integer) state.getValue(SweetBerryBushBlock.AGE) > 0 && (entity.xOld != entity.getX() || entity.zOld != entity.getZ())) {
@@ -240,7 +240,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (!world.isClientSide) {
              if (!(Boolean) state.getValue(TripWireBlock.POWERED)) {
                  this.checkPressed(world, pos);
@@ -252,7 +252,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
          super.entityInside(state, world, pos, entity);
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (world instanceof ServerLevel && entity instanceof Boat) {
              // CraftBukkit start
              if (!CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState())) {
@@ -264,7 +264,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          entity.makeStuckInBlock(state, new Vec3(0.25D, (double)0.05F, 0.25D));
      }
  }
@@ -276,7 +276,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
++        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (!world.isClientSide && world.getDifficulty() != Difficulty.PEACEFUL) {
              if (entity instanceof LivingEntity) {
                  LivingEntity entityliving = (LivingEntity) entity;
diff --git a/patches/server/Adds-PlayerArmSwingEvent.patch b/patches/server/Add-PlayerArmSwingEvent.patch
similarity index 92%
rename from patches/server/Adds-PlayerArmSwingEvent.patch
rename to patches/server/Add-PlayerArmSwingEvent.patch
index 899e2bd6e0..0d3b0fd870 100644
--- a/patches/server/Adds-PlayerArmSwingEvent.patch
+++ b/patches/server/Add-PlayerArmSwingEvent.patch
@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Jake Potrebic <jake.m.potrebic@gmail.com>
 Date: Fri, 12 Mar 2021 19:22:21 -0800
-Subject: [PATCH] Adds PlayerArmSwingEvent
+Subject: [PATCH] Add PlayerArmSwingEvent
 
 
 diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
          // Arm swing animation
 -        PlayerAnimationEvent event = new PlayerAnimationEvent(this.getCraftPlayer(), (packet.getHand() == InteractionHand.MAIN_HAND) ? PlayerAnimationType.ARM_SWING : PlayerAnimationType.OFF_ARM_SWING);
-+        io.papermc.paper.event.player.PlayerArmSwingEvent event = new io.papermc.paper.event.player.PlayerArmSwingEvent(this.getCraftPlayer(), packet.getHand() == InteractionHand.MAIN_HAND ? org.bukkit.inventory.EquipmentSlot.HAND : org.bukkit.inventory.EquipmentSlot.OFF_HAND); // Paper
++        io.papermc.paper.event.player.PlayerArmSwingEvent event = new io.papermc.paper.event.player.PlayerArmSwingEvent(this.getCraftPlayer(), packet.getHand() == InteractionHand.MAIN_HAND ? org.bukkit.inventory.EquipmentSlot.HAND : org.bukkit.inventory.EquipmentSlot.OFF_HAND); // Paper - Add PlayerArmSwingEvent
          this.cserver.getPluginManager().callEvent(event);
  
          if (event.isCancelled()) return;
diff --git a/patches/server/Add-PlayerKickEvent-causes.patch b/patches/server/Add-PlayerKickEvent-causes.patch
index ac8bad1a25..229fb35aeb 100644
--- a/patches/server/Add-PlayerKickEvent-causes.patch
+++ b/patches/server/Add-PlayerKickEvent-causes.patch
@@ -33,17 +33,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      public static class DecodeException extends ThrowingComponent {
          private final boolean shouldDisconnect;
-+        public final org.bukkit.event.player.PlayerKickEvent.Cause kickCause; // Paper
++        public final org.bukkit.event.player.PlayerKickEvent.Cause kickCause; // Paper - kick event causes
  
          public DecodeException(Component message, boolean shouldDisconnect) {
-+            // Paper start
++            // Paper start - kick event causes
 +            this(message, shouldDisconnect, org.bukkit.event.player.PlayerKickEvent.Cause.UNKNOWN);
 +        }
 +        public DecodeException(Component message, boolean shouldDisconnect, org.bukkit.event.player.PlayerKickEvent.Cause kickCause) {
-+            // Paper end
++            // Paper end - kick event causes
              super(message);
              this.shouldDisconnect = shouldDisconnect;
-+            this.kickCause = kickCause; // Paper
++            this.kickCause = kickCause; // Paper - kick event causes
          }
  
          public boolean shouldDisconnect() {
diff --git a/patches/server/Add-PlayerSetSpawnEvent.patch b/patches/server/Add-PlayerSetSpawnEvent.patch
index 9a27ae571f..f9763c8cd5 100644
--- a/patches/server/Add-PlayerSetSpawnEvent.patch
+++ b/patches/server/Add-PlayerSetSpawnEvent.patch
@@ -12,40 +12,40 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          ResourceKey<Level> resourcekey = source.getLevel().dimension();
          Iterator iterator = targets.iterator();
  
-+        final Collection<ServerPlayer> actualTargets = new java.util.ArrayList<>(); // Paper
++        final Collection<ServerPlayer> actualTargets = new java.util.ArrayList<>(); // Paper - Add PlayerSetSpawnEvent
          while (iterator.hasNext()) {
              ServerPlayer entityplayer = (ServerPlayer) iterator.next();
  
 -            entityplayer.setRespawnPosition(resourcekey, pos, angle, true, false, org.bukkit.event.player.PlayerSpawnChangeEvent.Cause.COMMAND); // CraftBukkit
-+            // Paper start - PlayerSetSpawnEvent
++            // Paper start - Add PlayerSetSpawnEvent
 +            if (entityplayer.setRespawnPosition(resourcekey, pos, angle, true, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.COMMAND)) {
 +                actualTargets.add(entityplayer);
 +            }
-+            // Paper end
++            // Paper end - Add PlayerSetSpawnEvent
          }
-+        // Paper start
++        // Paper start - Add PlayerSetSpawnEvent
 +        if (actualTargets.isEmpty()) {
 +            return 0;
 +        }
-+        // Paper end
++        // Paper end - Add PlayerSetSpawnEvent
  
          String s = resourcekey.location().toString();
  
 -        if (targets.size() == 1) {
-+        if (actualTargets.size() == 1) { // Paper
++        if (actualTargets.size() == 1) { // Paper - Add PlayerSetSpawnEvent
              source.sendSuccess(() -> {
 -                return Component.translatable("commands.spawnpoint.success.single", pos.getX(), pos.getY(), pos.getZ(), angle, s, ((ServerPlayer) targets.iterator().next()).getDisplayName());
-+                return Component.translatable("commands.spawnpoint.success.single", pos.getX(), pos.getY(), pos.getZ(), angle, s, ((ServerPlayer) actualTargets.iterator().next()).getDisplayName()); // Paper
++                return Component.translatable("commands.spawnpoint.success.single", pos.getX(), pos.getY(), pos.getZ(), angle, s, ((ServerPlayer) actualTargets.iterator().next()).getDisplayName()); // Paper - Add PlayerSetSpawnEvent
              }, true);
          } else {
              source.sendSuccess(() -> {
 -                return Component.translatable("commands.spawnpoint.success.multiple", pos.getX(), pos.getY(), pos.getZ(), angle, s, targets.size());
-+                return Component.translatable("commands.spawnpoint.success.multiple", pos.getX(), pos.getY(), pos.getZ(), angle, s, actualTargets.size()); // Paper
++                return Component.translatable("commands.spawnpoint.success.multiple", pos.getX(), pos.getY(), pos.getZ(), angle, s, actualTargets.size()); // Paper - Add PlayerSetSpawnEvent
              }, true);
          }
  
 -        return targets.size();
-+        return actualTargets.size(); // Paper
++        return actualTargets.size(); // Paper - Add PlayerSetSpawnEvent
      }
  }
 diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -57,7 +57,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  return Either.left(Player.BedSleepingProblem.OBSTRUCTED);
              } else {
 -                this.setRespawnPosition(this.level().dimension(), blockposition, this.getYRot(), false, true, PlayerSpawnChangeEvent.Cause.BED); // CraftBukkit
-+                this.setRespawnPosition(this.level().dimension(), blockposition, this.getYRot(), false, true, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.BED); // Paper - PlayerSetSpawnEvent
++                this.setRespawnPosition(this.level().dimension(), blockposition, this.getYRot(), false, true, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.BED); // Paper - Add PlayerSetSpawnEvent
                  if (this.level().isDay()) {
                      return Either.left(Player.BedSleepingProblem.NOT_POSSIBLE_NOW);
                  } else {
@@ -65,7 +65,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          return this.respawnForced;
      }
  
-+    @Deprecated // Paper
++    @Deprecated // Paper - Add PlayerSetSpawnEvent
      public void setRespawnPosition(ResourceKey<Level> dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage) {
 -        // CraftBukkit start
 -        this.setRespawnPosition(dimension, pos, angle, forced, sendMessage, PlayerSpawnChangeEvent.Cause.UNKNOWN);
@@ -91,7 +91,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -            resourcekey = Level.OVERWORLD;
 -            blockposition = null;
 -            f = 0.0F;
-+        // Paper start
++        // Paper start - Add PlayerSetSpawnEvent
 +        this.setRespawnPosition(dimension, pos, angle, forced, sendMessage, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.UNKNOWN);
 +    }
 +    @Deprecated
@@ -126,12 +126,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            pos = io.papermc.paper.util.MCUtil.toBlockPosition(event.getLocation());
 +            angle = event.getLocation().getYaw();
 +            forced = event.isForced();
-+            // Paper end
++            // Paper end - Add PlayerSetSpawnEvent
  
 -            if (flag1 && !flag2) {
 -                this.sendSystemMessage(Component.translatable("block.minecraft.set_spawn"));
-+            if (event.willNotifyPlayer() && event.getNotification() != null) { // Paper
-+                this.sendSystemMessage(PaperAdventure.asVanilla(event.getNotification())); // Paper
++            if (event.willNotifyPlayer() && event.getNotification() != null) { // Paper - Add PlayerSetSpawnEvent
++                this.sendSystemMessage(PaperAdventure.asVanilla(event.getNotification())); // Paper - Add PlayerSetSpawnEvent
              }
  
 -            this.respawnPosition = blockposition;
@@ -149,7 +149,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              this.respawnForced = false;
          }
  
-+        return true; // Paper
++        return true; // Paper - Add PlayerSetSpawnEvent
      }
  
      public SectionPos getLastSectionPos() {
@@ -162,7 +162,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  } else if (blockposition != null) {
                      entityplayer1.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0F));
 -                    entityplayer1.setRespawnPosition(null, null, 0f, false, false, PlayerSpawnChangeEvent.Cause.RESET); // CraftBukkit - SPIGOT-5988: Clear respawn location when obstructed
-+                    entityplayer1.setRespawnPosition(null, null, 0f, false, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLAYER_RESPAWN); // CraftBukkit - SPIGOT-5988: Clear respawn location when obstructed // Paper - PlayerSetSpawnEvent
++                    entityplayer1.setRespawnPosition(null, null, 0f, false, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLAYER_RESPAWN); // CraftBukkit - SPIGOT-5988: Clear respawn location when obstructed // Paper - Add PlayerSetSpawnEvent
                  }
              }
  
@@ -175,14 +175,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
                  if (entityplayer.getRespawnDimension() != world.dimension() || !pos.equals(entityplayer.getRespawnPosition())) {
 -                    entityplayer.setRespawnPosition(world.dimension(), pos, 0.0F, false, true, org.bukkit.event.player.PlayerSpawnChangeEvent.Cause.RESPAWN_ANCHOR); // CraftBukkit
-+                    if (entityplayer.setRespawnPosition(world.dimension(), pos, 0.0F, false, true, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.RESPAWN_ANCHOR)) { // Paper - PlayerSetSpawnEvent
++                    if (entityplayer.setRespawnPosition(world.dimension(), pos, 0.0F, false, true, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.RESPAWN_ANCHOR)) { // Paper - Add PlayerSetSpawnEvent
                      world.playSound((Player) null, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, SoundEvents.RESPAWN_ANCHOR_SET_SPAWN, SoundSource.BLOCKS, 1.0F, 1.0F);
                      return InteractionResult.SUCCESS;
-+                    // Paper start - handle failed set spawn
++                    // Paper start - Add PlayerSetSpawnEvent
 +                    } else {
 +                        return InteractionResult.FAIL;
 +                    }
-+                    // Paper end
++                    // Paper end - Add PlayerSetSpawnEvent
                  }
              }
  
@@ -195,10 +195,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public void setBedSpawnLocation(Location location, boolean override) {
          if (location == null) {
 -            this.getHandle().setRespawnPosition(null, null, 0.0F, override, false, PlayerSpawnChangeEvent.Cause.PLUGIN);
-+            this.getHandle().setRespawnPosition(null, null, 0.0F, override, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLUGIN); // Paper - PlayerSetSpawnEvent
++            this.getHandle().setRespawnPosition(null, null, 0.0F, override, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLUGIN); // Paper - Add PlayerSetSpawnEvent
          } else {
 -            this.getHandle().setRespawnPosition(((CraftWorld) location.getWorld()).getHandle().dimension(), CraftLocation.toBlockPosition(location), location.getYaw(), override, false, PlayerSpawnChangeEvent.Cause.PLUGIN);
-+            this.getHandle().setRespawnPosition(((CraftWorld) location.getWorld()).getHandle().dimension(), CraftLocation.toBlockPosition(location), location.getYaw(), override, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLUGIN); // Paper - PlayerSetSpawnEvent
++            this.getHandle().setRespawnPosition(((CraftWorld) location.getWorld()).getHandle().dimension(), CraftLocation.toBlockPosition(location), location.getYaw(), override, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLUGIN); // Paper - Add PlayerSetSpawnEvent
          }
      }
  
diff --git a/patches/server/Add-Unix-domain-socket-support.patch b/patches/server/Add-Unix-domain-socket-support.patch
index 4fd13c5c0b..e42635de18 100644
--- a/patches/server/Add-Unix-domain-socket-support.patch
+++ b/patches/server/Add-Unix-domain-socket-support.patch
@@ -3,12 +3,6 @@ From: Andrew Steinborn <git@steinborn.me>
 Date: Tue, 11 May 2021 17:39:22 -0400
 Subject: [PATCH] Add Unix domain socket support
 
-For Windows and ARM support, JEP-380 is required:
-https://inside.java/2021/02/03/jep380-unix-domain-sockets-channels/
-This will be possible as of the Minecraft 1.17 Java version bump.
-
-Tested-by: Mariell Hoversholm <proximyst@proximyst.com>
-Reviewed-by: Mariell Hoversholm <proximyst@proximyst.com>
 
 diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
@@ -41,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          }
 +        bindAddress = new java.net.InetSocketAddress(inetaddress, this.getPort());
 +        }
-+        // Paper end
++        // Paper end - Unix domain socket support
  
          this.initializeKeyPair();
          DedicatedServer.LOGGER.info("Starting Minecraft server on {}:{}", this.getLocalIp().isEmpty() ? "*" : this.getLocalIp(), this.getPort());
@@ -60,12 +54,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          this.running = true;
      }
  
-+    // Paper start
++    // Paper start - Unix domain socket support
      public void startTcpServerListener(@Nullable InetAddress address, int port) throws IOException {
 +        bind(new java.net.InetSocketAddress(address, port));
 +    }
 +    public void bind(java.net.SocketAddress address) throws IOException {
-+    // Paper end
++    // Paper end - Unix domain socket support
          List list = this.channels;
  
          synchronized (this.channels) {
@@ -73,13 +67,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              EventLoopGroup eventloopgroup;
  
              if (Epoll.isAvailable() && this.server.isEpollEnabled()) {
-+                // Paper start
++                // Paper start - Unix domain socket support
 +                if (address instanceof io.netty.channel.unix.DomainSocketAddress) {
 +                    oclass = io.netty.channel.epoll.EpollServerDomainSocketChannel.class;
 +                } else {
                  oclass = EpollServerSocketChannel.class;
 +                }
-+                // Paper end
++                // Paper end - Unix domain socket support
                  eventloopgroup = (EventLoopGroup) ServerConnectionListener.SERVER_EPOLL_EVENT_GROUP.get();
                  ServerConnectionListener.LOGGER.info("Using epoll channel type");
              } else {
@@ -88,7 +82,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                      io.papermc.paper.network.ChannelInitializeListenerHolder.callListeners(channel); // Paper
                  }
 -            }).group(eventloopgroup).localAddress(address, port)).option(ChannelOption.AUTO_READ, false).bind().syncUninterruptibly()); // CraftBukkit
-+            }).group(eventloopgroup).localAddress(address)).option(ChannelOption.AUTO_READ, false).bind().syncUninterruptibly()); // CraftBukkit // Paper
++            }).group(eventloopgroup).localAddress(address)).option(ChannelOption.AUTO_READ, false).bind().syncUninterruptibly()); // CraftBukkit // Paper - Unix domain socket support
          }
      }
  
@@ -100,11 +94,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      // Spigot Start
      public SocketAddress getRawAddress()
      {
-+        // Paper start - this can be nullable in the case of a Unix domain socket, so if it is, fake something
++        // Paper start - Unix domain socket support; this can be nullable in the case of a Unix domain socket, so if it is, fake something
 +        if (connection.channel.remoteAddress() == null) {
 +            return new java.net.InetSocketAddress(java.net.InetAddress.getLoopbackAddress(), 0);
 +        }
-+        // Paper end
++        // Paper end - Unix domain socket support
          return this.connection.channel.remoteAddress();
      }
      // Spigot End
@@ -116,7 +110,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  this.connection.setClientboundProtocolAfterHandshake(ClientIntent.LOGIN);
                  // CraftBukkit start - Connection throttle
                  try {
-+                    if (!(this.connection.channel.localAddress() instanceof io.netty.channel.unix.DomainSocketAddress)) { // Paper - the connection throttle is useless when you have a Unix domain socket
++                    if (!(this.connection.channel.localAddress() instanceof io.netty.channel.unix.DomainSocketAddress)) { // Paper - Unix domain socket support; the connection throttle is useless when you have a Unix domain socket
                      long currentTime = System.currentTimeMillis();
                      long connectionThrottle = this.server.server.getConnectionThrottle();
                      InetAddress address = ((java.net.InetSocketAddress) this.connection.getRemoteAddress()).getAddress();
@@ -124,7 +118,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                              }
                          }
                      }
-+                    } // Paper - add closing bracket for if check above
++                    } // Paper - Unix domain socket support
                  } catch (Throwable t) {
                      org.apache.logging.log4j.LogManager.getLogger().debug("Failed to check connection throttle", t);
                  }
@@ -137,7 +131,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                              this.connection.hostname = split[0];
 -                            this.connection.address = new java.net.InetSocketAddress(split[1], ((java.net.InetSocketAddress) this.connection.getRemoteAddress()).getPort());
 +                            this.connection.address = new java.net.InetSocketAddress(split[1], socketAddress instanceof java.net.InetSocketAddress ? ((java.net.InetSocketAddress) socketAddress).getPort() : 0);
-+                            // Paper end
++                            // Paper end - Unix domain socket support
                              this.connection.spoofedUUID = com.mojang.util.UndashedUuid.fromStringLenient( split[2] );
                          } else
                          {
diff --git a/patches/server/Add-cause-to-Weather-ThunderChangeEvents.patch b/patches/server/Add-cause-to-Weather-ThunderChangeEvents.patch
index 6287e76b51..bb44a3c296 100644
--- a/patches/server/Add-cause-to-Weather-ThunderChangeEvents.patch
+++ b/patches/server/Add-cause-to-Weather-ThunderChangeEvents.patch
@@ -14,8 +14,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          this.serverLevelData.setThunderTime(rainDuration);
 -        this.serverLevelData.setRaining(raining);
 -        this.serverLevelData.setThundering(thundering);
-+        this.serverLevelData.setRaining(raining, org.bukkit.event.weather.WeatherChangeEvent.Cause.COMMAND); // Paper
-+        this.serverLevelData.setThundering(thundering, org.bukkit.event.weather.ThunderChangeEvent.Cause.COMMAND); // Paper
++        this.serverLevelData.setRaining(raining, org.bukkit.event.weather.WeatherChangeEvent.Cause.COMMAND); // Paper - Add cause to Weather/ThunderChangeEvents
++        this.serverLevelData.setThundering(thundering, org.bukkit.event.weather.ThunderChangeEvent.Cause.COMMAND); // Paper - Add cause to Weather/ThunderChangeEvents
      }
  
      @Override
@@ -25,8 +25,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  this.serverLevelData.setClearWeatherTime(i);
 -                this.serverLevelData.setThundering(flag1);
 -                this.serverLevelData.setRaining(flag2);
-+                this.serverLevelData.setThundering(flag1, org.bukkit.event.weather.ThunderChangeEvent.Cause.NATURAL); // Paper
-+                this.serverLevelData.setRaining(flag2, org.bukkit.event.weather.WeatherChangeEvent.Cause.NATURAL); // Paper
++                this.serverLevelData.setThundering(flag1, org.bukkit.event.weather.ThunderChangeEvent.Cause.NATURAL); // Paper - Add cause to Weather/ThunderChangeEvents
++                this.serverLevelData.setRaining(flag2, org.bukkit.event.weather.WeatherChangeEvent.Cause.NATURAL); // Paper - Add cause to Weather/ThunderChangeEvents
              }
  
              this.oThunderLevel = this.thunderLevel;
@@ -35,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public void resetWeatherCycle() {
          // CraftBukkit start
 -        this.serverLevelData.setRaining(false);
-+        this.serverLevelData.setRaining(false, org.bukkit.event.weather.WeatherChangeEvent.Cause.SLEEP); // Paper - when passing the night
++        this.serverLevelData.setRaining(false, org.bukkit.event.weather.WeatherChangeEvent.Cause.SLEEP); // Paper - Add cause to Weather/ThunderChangeEvents
          // If we stop due to everyone sleeping we should reset the weather duration to some other random value.
          // Not that everyone ever manages to get the whole server to sleep at the same time....
          if (!this.serverLevelData.isRaining()) {
@@ -43,7 +43,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          }
          // CraftBukkit end
 -        this.serverLevelData.setThundering(false);
-+        this.serverLevelData.setThundering(false, org.bukkit.event.weather.ThunderChangeEvent.Cause.SLEEP); // Paper - when passing the night
++        this.serverLevelData.setThundering(false, org.bukkit.event.weather.ThunderChangeEvent.Cause.SLEEP); // Paper - Add cause to Weather/ThunderChangeEvents
          // CraftBukkit start
          // If we stop due to everyone sleeping we should reset the weather duration to some other random value.
          // Not that everyone ever manages to get the whole server to sleep at the same time....
@@ -55,11 +55,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void setThundering(boolean thundering) {
-+        // Paper start
++        // Paper start - Add cause to Weather/ThunderChangeEvents
 +        this.setThundering(thundering, org.bukkit.event.weather.ThunderChangeEvent.Cause.UNKNOWN);
 +    }
 +    public void setThundering(boolean thundering, org.bukkit.event.weather.ThunderChangeEvent.Cause cause) {
-+        // Paper end
++        // Paper end - Add cause to Weather/ThunderChangeEvents
          // CraftBukkit start
          if (this.thundering == thundering) {
              return;
@@ -68,7 +68,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          org.bukkit.World world = Bukkit.getWorld(this.getLevelName());
          if (world != null) {
 -            ThunderChangeEvent thunder = new ThunderChangeEvent(world, thundering);
-+            ThunderChangeEvent thunder = new ThunderChangeEvent(world, thundering, cause); // Paper
++            ThunderChangeEvent thunder = new ThunderChangeEvent(world, thundering, cause); // Paper - Add cause to Weather/ThunderChangeEvents
              Bukkit.getServer().getPluginManager().callEvent(thunder);
              if (thunder.isCancelled()) {
                  return;
@@ -76,12 +76,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void setRaining(boolean raining) {
-+        // Paper start
++        // Paper start - Add cause to Weather/ThunderChangeEvents
 +        this.setRaining(raining, org.bukkit.event.weather.WeatherChangeEvent.Cause.UNKNOWN);
 +    }
 +
 +    public void setRaining(boolean raining, org.bukkit.event.weather.WeatherChangeEvent.Cause cause) {
-+        // Paper end
++        // Paper end - Add cause to Weather/ThunderChangeEvents
          // CraftBukkit start
          if (this.raining == raining) {
              return;
@@ -90,7 +90,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          org.bukkit.World world = Bukkit.getWorld(this.getLevelName());
          if (world != null) {
 -            WeatherChangeEvent weather = new WeatherChangeEvent(world, raining);
-+            WeatherChangeEvent weather = new WeatherChangeEvent(world, raining, cause); // Paper
++            WeatherChangeEvent weather = new WeatherChangeEvent(world, raining, cause); // Paper - Add cause to Weather/ThunderChangeEvents
              Bukkit.getServer().getPluginManager().callEvent(weather);
              if (weather.isCancelled()) {
                  return;
@@ -103,7 +103,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
      public void setStorm(boolean hasStorm) {
 -        this.world.levelData.setRaining(hasStorm);
-+        this.world.serverLevelData.setRaining(hasStorm, org.bukkit.event.weather.WeatherChangeEvent.Cause.PLUGIN); // Paper
++        this.world.serverLevelData.setRaining(hasStorm, org.bukkit.event.weather.WeatherChangeEvent.Cause.PLUGIN); // Paper - Add cause to Weather/ThunderChangeEvents
          this.setWeatherDuration(0); // Reset weather duration (legacy behaviour)
          this.setClearWeatherDuration(0); // Reset clear weather duration (reset "/weather clear" commands)
      }
@@ -112,7 +112,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
      public void setThundering(boolean thundering) {
 -        this.world.serverLevelData.setThundering(thundering);
-+        this.world.serverLevelData.setThundering(thundering, org.bukkit.event.weather.ThunderChangeEvent.Cause.PLUGIN); // Paper
++        this.world.serverLevelData.setThundering(thundering, org.bukkit.event.weather.ThunderChangeEvent.Cause.PLUGIN); // Paper - Add cause to Weather/ThunderChangeEvents
          this.setThunderDuration(0); // Reset weather duration (legacy behaviour)
          this.setClearWeatherDuration(0); // Reset clear weather duration (reset "/weather clear" commands)
      }
diff --git a/patches/server/Add-config-for-mobs-immune-to-default-effects.patch b/patches/server/Add-config-for-mobs-immune-to-default-effects.patch
index e599b46d43..62dd122fe6 100644
--- a/patches/server/Add-config-for-mobs-immune-to-default-effects.patch
+++ b/patches/server/Add-config-for-mobs-immune-to-default-effects.patch
@@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              MobEffect mobeffectlist = effect.getEffect();
  
 -            if (mobeffectlist == MobEffects.REGENERATION || mobeffectlist == MobEffects.POISON) {
-+            if ((mobeffectlist == MobEffects.REGENERATION || mobeffectlist == MobEffects.POISON) && this.level().paperConfig().entities.mobEffects.undeadImmuneToCertainEffects) { // Paper
++            if ((mobeffectlist == MobEffects.REGENERATION || mobeffectlist == MobEffects.POISON) && this.level().paperConfig().entities.mobEffects.undeadImmuneToCertainEffects) { // Paper - Add config for mobs immune to default effects
                  return false;
              }
          }
@@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
      public boolean canBeAffected(MobEffectInstance effect) {
 -        return effect.getEffect() == MobEffects.WITHER ? false : super.canBeAffected(effect);
-+        return effect.getEffect() == MobEffects.WITHER && this.level().paperConfig().entities.mobEffects.immuneToWitherEffect.wither ? false : super.canBeAffected(effect); // Paper
++        return effect.getEffect() == MobEffects.WITHER && this.level().paperConfig().entities.mobEffects.immuneToWitherEffect.wither ? false : super.canBeAffected(effect); // Paper - Add config for mobs immune to default effects
      }
  
      private class WitherDoNothingGoal extends Goal {
@@ -39,7 +39,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
      public boolean canBeAffected(MobEffectInstance effect) {
 -        return effect.getEffect() == MobEffects.POISON ? false : super.canBeAffected(effect);
-+        return effect.getEffect() == MobEffects.POISON && this.level().paperConfig().entities.mobEffects.spidersImmuneToPoisonEffect ? false : super.canBeAffected(effect); // Paper
++        return effect.getEffect() == MobEffects.POISON && this.level().paperConfig().entities.mobEffects.spidersImmuneToPoisonEffect ? false : super.canBeAffected(effect); // Paper - Add config for mobs immune to default effects
      }
  
      public boolean isClimbing() {
@@ -52,6 +52,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
      public boolean canBeAffected(MobEffectInstance effect) {
 -        return effect.getEffect() == MobEffects.WITHER ? false : super.canBeAffected(effect);
-+        return effect.getEffect() == MobEffects.WITHER && this.level().paperConfig().entities.mobEffects.immuneToWitherEffect.witherSkeleton ? false : super.canBeAffected(effect); // Paper
++        return effect.getEffect() == MobEffects.WITHER && this.level().paperConfig().entities.mobEffects.immuneToWitherEffect.witherSkeleton ? false : super.canBeAffected(effect); // Paper - Add config for mobs immune to default effects
      }
  }
diff --git a/patches/server/Add-a-bunch-of-missing-forceDrop-toggles.patch b/patches/server/Add-missing-forceDrop-toggles.patch
similarity index 78%
rename from patches/server/Add-a-bunch-of-missing-forceDrop-toggles.patch
rename to patches/server/Add-missing-forceDrop-toggles.patch
index c5f58814d7..ee9e4b820f 100644
--- a/patches/server/Add-a-bunch-of-missing-forceDrop-toggles.patch
+++ b/patches/server/Add-missing-forceDrop-toggles.patch
@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Jake Potrebic <jake.m.potrebic@gmail.com>
 Date: Tue, 20 Jul 2021 21:25:35 -0700
-Subject: [PATCH] Add a bunch of missing forceDrop toggles
+Subject: [PATCH] Add missing forceDrop toggles
 
 
 diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java b/src/main/java/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java
@@ -12,9 +12,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  simpleContainer.removeItemType(Items.WHEAT, m);
                  ItemStack itemStack = simpleContainer.addItem(new ItemStack(Items.BREAD, l));
                  if (!itemStack.isEmpty()) {
-+                    entity.forceDrops = true; // Paper
++                    entity.forceDrops = true; // Paper - Add missing forceDrop toggles
                      entity.spawnAtLocation(itemStack, 0.5F);
-+                    entity.forceDrops = false; // Paper
++                    entity.forceDrops = false; // Paper - Add missing forceDrop toggles
                  }
  
              }
@@ -26,9 +26,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          }
  
          if (!this.level().isClientSide() && this.random.nextInt(700) == 0 && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
-+            this.forceDrops = true; // Paper
++            this.forceDrops = true; // Paper - Add missing forceDrop toggles
              this.spawnAtLocation((ItemLike) Items.SLIME_BALL);
-+            this.forceDrops = false; // Paper
++            this.forceDrops = false; // Paper - Add missing forceDrop toggles
          }
  
      }
@@ -36,9 +36,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  ItemStack itemstack1 = this.getItemBySlot(EquipmentSlot.MAINHAND);
  
                  if (!itemstack1.isEmpty() && !player.getAbilities().instabuild) {
-+                    this.forceDrops = true; // Paper
++                    this.forceDrops = true; // Paper - Add missing forceDrop toggles
                      this.spawnAtLocation(itemstack1);
-+                    this.forceDrops = false; // Paper
++                    this.forceDrops = false; // Paper - Add missing forceDrop toggles
                  }
  
                  this.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(itemstack.getItem(), 1));
@@ -46,9 +46,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              ItemStack itemstack = Panda.this.getItemBySlot(EquipmentSlot.MAINHAND);
  
              if (!itemstack.isEmpty()) {
-+                Panda.this.forceDrops = true; // Paper
++                Panda.this.forceDrops = true; // Paper - Add missing forceDrop toggles
                  Panda.this.spawnAtLocation(itemstack);
-+                Panda.this.forceDrops = false; // Paper
++                Panda.this.forceDrops = false; // Paper - Add missing forceDrop toggles
                  Panda.this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
                  int i = Panda.this.isLazy() ? Panda.this.random.nextInt(50) + 10 : Panda.this.random.nextInt(150) + 10;
  
@@ -60,9 +60,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
      protected void finishConversion(ServerLevel world) {
          PiglinAi.cancelAdmiring(this);
-+        this.forceDrops = true; // Paper
++        this.forceDrops = true; // Paper - Add missing forceDrop toggles
          this.inventory.removeAllItems().forEach(this::spawnAtLocation);
-+        this.forceDrops = false; // Paper
++        this.forceDrops = false; // Paper - Add missing forceDrop toggles
          super.finishConversion(world);
      }
  
@@ -74,9 +74,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      private static void holdInOffhand(Piglin piglin, ItemStack stack) {
          if (PiglinAi.isHoldingItemInOffHand(piglin)) {
-+            piglin.forceDrops = true; // Paper
++            piglin.forceDrops = true; // Paper - Add missing forceDrop toggles
              piglin.spawnAtLocation(piglin.getItemInHand(InteractionHand.OFF_HAND));
-+            piglin.forceDrops = false; // Paper
++            piglin.forceDrops = false; // Paper - Add missing forceDrop toggles
          }
  
          piglin.holdInOffHand(stack);
@@ -84,9 +84,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      protected static void cancelAdmiring(Piglin piglin) {
          if (PiglinAi.isAdmiringItem(piglin) && !piglin.getOffhandItem().isEmpty()) {
-+            piglin.forceDrops = true; // Paper
++            piglin.forceDrops = true; // Paper - Add missing forceDrop toggles
              piglin.spawnAtLocation(piglin.getOffhandItem());
-+            piglin.forceDrops = false; // Paper
++            piglin.forceDrops = false; // Paper - Add missing forceDrop toggles
              piglin.setItemInHand(InteractionHand.OFF_HAND, ItemStack.EMPTY);
          }
  
@@ -98,9 +98,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              double d0 = (double) this.getEquipmentDropChance(enumitemslot);
  
              if (!itemstack1.isEmpty() && (double) Math.max(this.random.nextFloat() - 0.1F, 0.0F) < d0) {
-+                this.forceDrops = true; // Paper
++                this.forceDrops = true; // Paper - Add missing forceDrop toggles
                  this.spawnAtLocation(itemstack1);
-+                this.forceDrops = false; // Paper
++                this.forceDrops = false; // Paper - Add missing forceDrop toggles
              }
  
              this.onItemPickup(item);
diff --git a/patches/server/Add-option-to-disable-block-updates.patch b/patches/server/Add-option-to-disable-block-updates.patch
index 673248e3a4..ea355dd571 100644
--- a/patches/server/Add-option-to-disable-block-updates.patch
+++ b/patches/server/Add-option-to-disable-block-updates.patch
@@ -162,7 +162,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
      public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
 +        if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent tripwires from detecting collision
-         if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
+         if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (!world.isClientSide) {
              if (!(Boolean) state.getValue(TripWireBlock.POWERED)) {
 @@ -0,0 +0,0 @@ public class TripWireBlock extends Block {
diff --git a/patches/server/Allow-skipping-writing-of-comments-to-server.propert.patch b/patches/server/Allow-skipping-writing-of-comments-to-server.propert.patch
index e4ce42e876..95818029fe 100644
--- a/patches/server/Allow-skipping-writing-of-comments-to-server.propert.patch
+++ b/patches/server/Allow-skipping-writing-of-comments-to-server.propert.patch
@@ -24,7 +24,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              }
              // CraftBukkit end
 -            BufferedWriter bufferedwriter = Files.newBufferedWriter(path, StandardCharsets.UTF_8);
-+            // Paper start - disable writing comments to properties file
++            // Paper start - allow skipping server.properties comments
 +            java.io.OutputStream outputstream = Files.newOutputStream(path);
 +            java.io.BufferedOutputStream bufferedOutputStream =  !skipComments ? new java.io.BufferedOutputStream(outputstream) : new java.io.BufferedOutputStream(outputstream) {
 +                private boolean isRightAfterNewline = true; // If last written char was newline
@@ -63,7 +63,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                }
 +            };
 +            BufferedWriter bufferedwriter = new BufferedWriter(new java.io.OutputStreamWriter(bufferedOutputStream, java.nio.charset.StandardCharsets.UTF_8.newEncoder()));
-+            // Paper end
++            // Paper end - allow skipping server.properties comments
  
              try {
                  this.properties.store(bufferedwriter, "Minecraft server properties");
diff --git a/patches/server/Change-EnderEye-target-without-changing-other-things.patch b/patches/server/Change-EnderEye-target-without-changing-other-things.patch
index 7f32a5cfa7..5954112deb 100644
--- a/patches/server/Change-EnderEye-target-without-changing-other-things.patch
+++ b/patches/server/Change-EnderEye-target-without-changing-other-things.patch
@@ -12,11 +12,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }
  
      public void signalTo(BlockPos pos) {
-+        // Paper start
++        // Paper start - Change EnderEye target without changing other things
 +        this.signalTo(pos, true);
 +    }
 +    public void signalTo(BlockPos pos, boolean update) {
-+        // Paper end
++        // Paper end - Change EnderEye target without changing other things
          double d0 = (double) pos.getX();
          int i = pos.getY();
          double d1 = (double) pos.getZ();
@@ -24,10 +24,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              this.tz = d1;
          }
  
-+        if (update) { // Paper
++        if (update) { // Paper - Change EnderEye target without changing other things
          this.life = 0;
          this.surviveAfterDeath = this.random.nextInt(5) > 0;
-+        } // Paper
++        } // Paper - Change EnderEye target without changing other things
      }
  
      @Override
@@ -39,16 +39,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void setTargetLocation(Location location) {
-+        // Paper start
++        // Paper start - Change EnderEye target without changing other things
 +        this.setTargetLocation(location, true);
 +    }
 +
 +    @Override
 +    public void setTargetLocation(Location location, boolean update) {
-+        // Paper end
++        // Paper end - Change EnderEye target without changing other things
          Preconditions.checkArgument(this.getWorld().equals(location.getWorld()), "Cannot target EnderSignal across worlds");
 -        this.getHandle().signalTo(CraftLocation.toBlockPosition(location));
-+        this.getHandle().signalTo(CraftLocation.toBlockPosition(location), update); // Paper
++        this.getHandle().signalTo(CraftLocation.toBlockPosition(location), update); // Paper - Change EnderEye target without changing other things
      }
  
      @Override
diff --git a/patches/server/Clear-bucket-NBT-after-dispense.patch b/patches/server/Clear-bucket-NBT-after-dispense.patch
index 46112cd13e..7671481a18 100644
--- a/patches/server/Clear-bucket-NBT-after-dispense.patch
+++ b/patches/server/Clear-bucket-NBT-after-dispense.patch
@@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                      if (stack.isEmpty()) {
 -                        stack.setItem(Items.BUCKET);
 -                        stack.setCount(1);
-+                        stack = new ItemStack(item); // Paper - clear tag
++                        stack = new ItemStack(item); // Paper - Clear bucket NBT after dispense
                      } else if (pointer.blockEntity().addItem(new ItemStack(item)) < 0) {
                          this.defaultDispenseItemBehavior.dispense(pointer, new ItemStack(item));
                      }
diff --git a/patches/server/Config-option-for-Piglins-guarding-chests.patch b/patches/server/Config-option-for-Piglins-guarding-chests.patch
index f1b6896efe..981eab76f0 100644
--- a/patches/server/Config-option-for-Piglins-guarding-chests.patch
+++ b/patches/server/Config-option-for-Piglins-guarding-chests.patch
@@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }
  
      public static void angerNearbyPiglins(Player player, boolean blockOpen) {
-+        if (!player.level().paperConfig().entities.behavior.piglinsGuardChests) return; // Paper
++        if (!player.level().paperConfig().entities.behavior.piglinsGuardChests) return; // Paper - Config option for Piglins guarding chests
          List<Piglin> list = player.level().getEntitiesOfClass(Piglin.class, player.getBoundingBox().inflate(16.0D));
  
          list.stream().filter(PiglinAi::isIdle).filter((entitypiglin) -> {
diff --git a/patches/server/Add-dropLeash-variable-to-EntityUnleashEvent.patch b/patches/server/Expand-EntityUnleashEvent.patch
similarity index 97%
rename from patches/server/Add-dropLeash-variable-to-EntityUnleashEvent.patch
rename to patches/server/Expand-EntityUnleashEvent.patch
index 2db0656be0..fc08441ed8 100644
--- a/patches/server/Add-dropLeash-variable-to-EntityUnleashEvent.patch
+++ b/patches/server/Expand-EntityUnleashEvent.patch
@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Nassim Jahnke <nassim@njahnke.dev>
 Date: Fri, 29 Jan 2021 15:13:11 +0100
-Subject: [PATCH] Add dropLeash variable to EntityUnleashEvent
+Subject: [PATCH] Expand EntityUnleashEvent
 
 
 diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -48,7 +48,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -            this.dropLeash(true, true);
 +            // Paper start - drop leash variable
 +            EntityUnleashEvent event = new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.UNKNOWN, true);
-+            this.level().getCraftServer().getPluginManager().callEvent(event); // CraftBukkit
++            if (!event.callEvent()) { return flag1; }
 +            this.dropLeash(true, event.isDropLeash());
 +            // Paper end
          }
@@ -62,7 +62,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -        this.dropLeash(true, false);
 +        // Paper start - drop leash variable
 +        EntityUnleashEvent event = new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.UNKNOWN, false);
-+        this.level().getCraftServer().getPluginManager().callEvent(event); // CraftBukkit
++        if (!event.callEvent()) { return; }
 +        this.dropLeash(true, event.isDropLeash());
 +        // Paper end
          this.getAllSlots().forEach((itemstack) -> {
diff --git a/patches/server/Expand-PlayerItemDamageEvent.patch b/patches/server/Expand-PlayerItemDamageEvent.patch
index 218ea8ea0c..bf5ee55406 100644
--- a/patches/server/Expand-PlayerItemDamageEvent.patch
+++ b/patches/server/Expand-PlayerItemDamageEvent.patch
@@ -15,9 +15,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                int originalDamage = amount; // Paper - Expand PlayerItemDamageEvent
                  amount -= k;
                  // CraftBukkit start
-                 if (player instanceof ServerPlayer serverPlayer) { // Paper
--                    PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount); // Paper
-+                    PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount, originalDamage); // Paper - Expand PlayerItemDamageEvent
+                 if (player instanceof ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent
+-                    PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount); // Paper - Add EntityDamageItemEvent
++                    PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount, originalDamage); // Paper - Add EntityDamageItemEvent & Expand PlayerItemDamageEvent
                      event.getPlayer().getServer().getPluginManager().callEvent(event);
  
                      if (amount != event.getDamage() || event.isCancelled()) {
diff --git a/patches/server/Fix-PlayerBucketEmptyEvent-result-itemstack.patch b/patches/server/Fix-PlayerBucketEmptyEvent-result-itemstack.patch
index b7efae81b5..6e0b08b574 100644
--- a/patches/server/Fix-PlayerBucketEmptyEvent-result-itemstack.patch
+++ b/patches/server/Fix-PlayerBucketEmptyEvent-result-itemstack.patch
@@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
  public class BucketItem extends Item implements DispensibleContainerItem {
  
-+    private static @Nullable ItemStack itemLeftInHandAfterPlayerBucketEmptyEvent = null; // Paper
++    private static @Nullable ItemStack itemLeftInHandAfterPlayerBucketEmptyEvent = null; // Paper - Fix PlayerBucketEmptyEvent result itemstack
 +
      public final Fluid content;
  
@@ -22,13 +22,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }
  
      public static ItemStack getEmptySuccessItem(ItemStack stack, Player player) {
-+        // Paper start
++        // Paper start - Fix PlayerBucketEmptyEvent result itemstack
 +        if (itemLeftInHandAfterPlayerBucketEmptyEvent != null) {
 +            ItemStack itemInHand = itemLeftInHandAfterPlayerBucketEmptyEvent;
 +            itemLeftInHandAfterPlayerBucketEmptyEvent = null;
 +            return itemInHand;
 +        }
-+        // Paper end
++        // Paper end - Fix PlayerBucketEmptyEvent result itemstack
          return !player.getAbilities().instabuild ? new ItemStack(Items.BUCKET) : stack;
      }
  
@@ -36,7 +36,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                      ((ServerPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-4541
                      return false;
                  }
-+                itemLeftInHandAfterPlayerBucketEmptyEvent = event.getItemStack() != null ? event.getItemStack().equals(CraftItemStack.asNewCraftStack(net.minecraft.world.item.Items.BUCKET)) ? null : CraftItemStack.asNMSCopy(event.getItemStack()) : ItemStack.EMPTY; // Paper - fix empty event result itemstack
++                itemLeftInHandAfterPlayerBucketEmptyEvent = event.getItemStack() != null ? event.getItemStack().equals(CraftItemStack.asNewCraftStack(net.minecraft.world.item.Items.BUCKET)) ? null : CraftItemStack.asNMSCopy(event.getItemStack()) : ItemStack.EMPTY; // Paper - Fix PlayerBucketEmptyEvent result itemstack
              }
              // CraftBukkit end
              if (!flag2) {
diff --git a/patches/server/Fix-PlayerDropItemEvent-using-wrong-item.patch b/patches/server/Fix-PlayerDropItemEvent-using-wrong-item.patch
index d33328b571..f4de35c03e 100644
--- a/patches/server/Fix-PlayerDropItemEvent-using-wrong-item.patch
+++ b/patches/server/Fix-PlayerDropItemEvent-using-wrong-item.patch
@@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              if (retainOwnership) {
                  if (!itemstack1.isEmpty()) {
 -                    this.awardStat(Stats.ITEM_DROPPED.get(itemstack1.getItem()), stack.getCount());
-+                    this.awardStat(Stats.ITEM_DROPPED.get(itemstack1.getItem()), itemstack1.getCount()); // Paper
++                    this.awardStat(Stats.ITEM_DROPPED.get(itemstack1.getItem()), itemstack1.getCount()); // Paper - Fix PlayerDropItemEvent using wrong item
                  }
  
                  this.awardStat(Stats.DROP);
diff --git a/patches/server/Fix-a-bunch-of-vanilla-bugs.patch b/patches/server/Fix-a-bunch-of-vanilla-bugs.patch
index ee4b94ba39..b6a7bcabfc 100644
--- a/patches/server/Fix-a-bunch-of-vanilla-bugs.patch
+++ b/patches/server/Fix-a-bunch-of-vanilla-bugs.patch
@@ -446,7 +446,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
 +++ b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
 @@ -0,0 +0,0 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock {
-         if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
+         if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (!world.isClientSide && entity.isOnFire() && this.isEntityInsideContent(state, pos, entity)) {
              // CraftBukkit start
 -            if (entity.mayInteract(world, pos)) {
diff --git a/patches/server/Fix-and-optimise-world-force-upgrading.patch b/patches/server/Fix-and-optimise-world-force-upgrading.patch
index 43e0b02128..af9d1eb5b7 100644
--- a/patches/server/Fix-and-optimise-world-force-upgrading.patch
+++ b/patches/server/Fix-and-optimise-world-force-upgrading.patch
@@ -279,7 +279,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -                    return true;
 -                }, dimensions);
 -            }
-+            // Paper - move down
++            // Paper - fix and optimise world upgrading; move down
  
              PrimaryLevelData iworlddataserver = worlddata;
              boolean flag = worlddata.isDebugWorld();
@@ -362,7 +362,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -        if (this.console.options.has("forceUpgrade")) {
 -            net.minecraft.server.Main.forceUpgrade(worldSession, DataFixers.getDataFixer(), this.console.options.has("eraseCache"), () -> true, iregistry);
 -        }
-+        // Paper - move down
++        // Paper - fix and optimise world upgrading; move down
  
          long j = BiomeManager.obfuscateSeed(creator.seed());
          List<CustomSpawner> list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(worlddata));
diff --git a/patches/server/Fix-commands-from-signs-not-firing-command-events.patch b/patches/server/Fix-commands-from-signs-not-firing-command-events.patch
index f0698bd77b..393732d565 100644
--- a/patches/server/Fix-commands-from-signs-not-firing-command-events.patch
+++ b/patches/server/Fix-commands-from-signs-not-firing-command-events.patch
@@ -66,7 +66,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
              if (chatclickable != null && chatclickable.getAction() == ClickEvent.Action.RUN_COMMAND) {
 -                player.getServer().getCommands().performPrefixedCommand(this.createCommandSourceStack(player, world, pos), chatclickable.getValue());
-+                // Paper start
++                // Paper start - Fix commands from signs not firing command events
 +                String command = chatclickable.getValue().startsWith("/") ? chatclickable.getValue() : "/" + chatclickable.getValue();
 +                if (org.spigotmc.SpigotConfig.logCommands)  {
 +                    LOGGER.info("{} issued server command: {}", player.getScoreboardName(), command);
@@ -76,7 +76,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                    return false;
 +                }
 +                player.getServer().getCommands().performPrefixedCommand(this.createCommandSourceStack(((org.bukkit.craftbukkit.entity.CraftPlayer) event.getPlayer()).getHandle(), world, pos), event.getMessage());
-+                // Paper end
++                // Paper end - Fix commands from signs not firing command events
                  flag1 = true;
              }
          }
@@ -84,7 +84,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          String s = player == null ? "Sign" : player.getName().getString();
          Object object = player == null ? Component.literal("Sign") : player.getDisplayName();
  
-+        // Paper start - send messages back to the player
++        // Paper start - Fix commands from signs not firing command events
 +        CommandSource commandSource = this.level.paperConfig().misc.showSignClickCommandFailureMsgsToPlayer ? new io.papermc.paper.commands.DelegatingCommandSource(this) {
 +            @Override
 +            public void sendSystemMessage(Component message) {
@@ -98,10 +98,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                return true;
 +            }
 +        } : this;
-+        // Paper end
++        // Paper end - Fix commands from signs not firing command events
          // CraftBukkit - this
 -        return new CommandSourceStack(this, Vec3.atCenterOf(pos), Vec2.ZERO, (ServerLevel) world, 2, s, (Component) object, world.getServer(), player);
-+        return new CommandSourceStack(commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, (ServerLevel) world, 2, s, (Component) object, world.getServer(), player); // Paper
++        return new CommandSourceStack(commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, (ServerLevel) world, 2, s, (Component) object, world.getServer(), player); // Paper - Fix commands from signs not firing command events
      }
  
      @Override
@@ -114,7 +114,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
          try {
 -            return this.server.dispatchCommand(sender, context.getInput()) ? 1 : 0;
-+            return this.server.dispatchCommand(sender, context.getRange().get(context.getInput())) ? 1 : 0; // Paper - actually use the StringRange from context
++            return this.server.dispatchCommand(sender, context.getRange().get(context.getInput())) ? 1 : 0; // Paper - Fix commands from signs not firing command events; actually use the StringRange from context
          } catch (CommandException ex) {
              sender.sendMessage(org.bukkit.ChatColor.RED + "An internal error occurred while attempting to perform this command");
              this.server.getLogger().log(Level.SEVERE, null, ex);
diff --git a/patches/server/Fix-invulnerable-end-crystals.patch b/patches/server/Fix-invulnerable-end-crystals.patch
index 4475e67e56..58a31f92e6 100644
--- a/patches/server/Fix-invulnerable-end-crystals.patch
+++ b/patches/server/Fix-invulnerable-end-crystals.patch
@@ -31,7 +31,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                    this.setBeamTarget(null);
 +                }
 +            }
-+            // Paper end
++            // Paper end - Fix invulnerable end crystals
          }
  
      }
@@ -59,7 +59,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              endCrystal.setBeamTarget(config.getCrystalBeamTarget());
              endCrystal.setInvulnerable(config.isCrystalInvulnerable());
              endCrystal.moveTo((double)spike.getCenterX() + 0.5D, (double)(spike.getHeight() + 1), (double)spike.getCenterZ() + 0.5D, random.nextFloat() * 360.0F, 0.0F);
-+        endCrystal.generatedByDragonFight = true; // Paper
++            endCrystal.generatedByDragonFight = true; // Paper - Fix invulnerable end crystals
              world.addFreshEntity(endCrystal);
              BlockPos blockPos2 = endCrystal.blockPosition();
              this.setBlock(world, blockPos2.below(), Blocks.BEDROCK.defaultBlockState());
diff --git a/patches/server/Fixes-kick-event-leave-message-not-being-sent.patch b/patches/server/Fix-kick-event-leave-message-not-being-sent.patch
similarity index 90%
rename from patches/server/Fixes-kick-event-leave-message-not-being-sent.patch
rename to patches/server/Fix-kick-event-leave-message-not-being-sent.patch
index 41354d9e4c..29782d0b58 100644
--- a/patches/server/Fixes-kick-event-leave-message-not-being-sent.patch
+++ b/patches/server/Fix-kick-event-leave-message-not-being-sent.patch
@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Jake Potrebic <jake.m.potrebic@gmail.com>
 Date: Wed, 7 Jul 2021 16:19:41 -0700
-Subject: [PATCH] Fixes kick event leave message not being sent
+Subject: [PATCH] Fix kick event leave message not being sent
 
 
 diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -24,11 +24,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void onDisconnect(Component reason) {
-+        // Paper start
++        // Paper start - Fix kick event leave message not being sent
 +        this.onDisconnect(reason, null);
 +    }
 +    public void onDisconnect(Component reason, @Nullable net.kyori.adventure.text.Component quitMessage) {
-+        // Paper end
++        // Paper end - Fix kick event leave message not being sent
          if (this.isSingleplayerOwner()) {
              ServerCommonPacketListenerImpl.LOGGER.info("Stopping singleplayer server as player logged out");
              this.server.halt(false);
@@ -57,12 +57,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void onDisconnect(Component reason) {
-+        // Paper start
++        // Paper start - Fix kick event leave message not being sent
 +        this.onDisconnect(reason, null);
 +    }
 +    @Override
 +    public void onDisconnect(Component reason, @Nullable net.kyori.adventure.text.Component quitMessage) {
-+        // Paper end
++        // Paper end - Fix kick event leave message not being sent
          // CraftBukkit start - Rarely it would send a disconnect line twice
          if (this.processedDisconnect) {
              return;
@@ -72,17 +72,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          ServerGamePacketListenerImpl.LOGGER.info("{} lost connection: {}", this.player.getName().getString(), reason.getString());
 -        this.removePlayerFromWorld();
 -        super.onDisconnect(reason);
-+        this.removePlayerFromWorld(quitMessage); // Paper
-+        super.onDisconnect(reason, quitMessage); // Paper
++        this.removePlayerFromWorld(quitMessage); // Paper - Fix kick event leave message not being sent
++        super.onDisconnect(reason, quitMessage); // Paper - Fix kick event leave message not being sent
      }
  
-+    // Paper start
++    // Paper start - Fix kick event leave message not being sent
      private void removePlayerFromWorld() {
 +        this.removePlayerFromWorld(null);
 +    }
 +
 +    private void removePlayerFromWorld(@Nullable net.kyori.adventure.text.Component quitMessage) {
-+        // Paper end
++        // Paper end - Fix kick event leave message not being sent
          this.chatMessageChain.close();
          // CraftBukkit start - Replace vanilla quit message handling with our own.
          /*
@@ -103,11 +103,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }
  
      public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer) { // CraftBukkit - return string // Paper - return Component
-+        // Paper start
++        // Paper start - Fix kick event leave message not being sent
 +        return this.remove(entityplayer, net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? entityplayer.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(entityplayer.getDisplayName())));
 +    }
 +    public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer, net.kyori.adventure.text.Component leaveMessage) {
-+        // Paper end
++        // Paper end - Fix kick event leave message not being sent
          ServerLevel worldserver = entityplayer.serverLevel();
  
          entityplayer.awardStat(Stats.LEAVE_GAME);
diff --git a/patches/server/Fix-new-block-data-for-EntityChangeBlockEvent.patch b/patches/server/Fix-new-block-data-for-EntityChangeBlockEvent.patch
index 5c35c95e3b..baa982df10 100644
--- a/patches/server/Fix-new-block-data-for-EntityChangeBlockEvent.patch
+++ b/patches/server/Fix-new-block-data-for-EntityChangeBlockEvent.patch
@@ -187,7 +187,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java
 +++ b/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java
 @@ -0,0 +0,0 @@ public class WaterlilyBlock extends BushBlock {
-         if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
+         if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
          if (world instanceof ServerLevel && entity instanceof Boat) {
              // CraftBukkit start
 -            if (!CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState())) {
diff --git a/patches/server/Fix-potions-splash-events.patch b/patches/server/Fix-potions-splash-events.patch
index 99b3791c37..309c933e65 100644
--- a/patches/server/Fix-potions-splash-events.patch
+++ b/patches/server/Fix-potions-splash-events.patch
@@ -15,11 +15,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              Potion potionregistry = PotionUtils.getPotion(itemstack);
              List<MobEffectInstance> list = PotionUtils.getMobEffects(itemstack);
              boolean flag = potionregistry == Potions.WATER && list.isEmpty();
-+            boolean showParticles = true; // Paper
++            boolean showParticles = true; // Paper - Fix potions splash events
  
              if (flag) {
 -                this.applyWater();
-+                showParticles = this.applyWater(); // Paper
++                showParticles = this.applyWater(); // Paper - Fix potions splash events
              } else if (true || !list.isEmpty()) { // CraftBukkit - Call event even if no effects to apply
                  if (this.isLingering()) {
 -                    this.makeAreaOfEffectCloud(itemstack, potionregistry, hitResult); // CraftBukkit - Pass MovingObjectPosition
@@ -30,21 +30,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  }
              }
  
-+            if (showParticles) { // Paper
++            if (showParticles) { // Paper - Fix potions splash events
              int i = potionregistry.hasInstantEffects() ? 2007 : 2002;
  
              this.level().levelEvent(i, this.blockPosition(), PotionUtils.getColor(itemstack));
-+            } // Paper
++            } // Paper - Fix potions splash events
              this.discard();
          }
      }
  
 -    private void applyWater() {
-+    private static final Predicate<net.minecraft.world.entity.LivingEntity> APPLY_WATER_GET_ENTITIES_PREDICATE = ThrownPotion.WATER_SENSITIVE_OR_ON_FIRE.or(Axolotl.class::isInstance); // Paper
-+    private boolean applyWater() { // Paper
++    private static final Predicate<net.minecraft.world.entity.LivingEntity> APPLY_WATER_GET_ENTITIES_PREDICATE = ThrownPotion.WATER_SENSITIVE_OR_ON_FIRE.or(Axolotl.class::isInstance); // Paper - Fix potions splash events
++    private boolean applyWater() { // Paper - Fix potions splash events
          AABB axisalignedbb = this.getBoundingBox().inflate(4.0D, 2.0D, 4.0D);
 -        List<net.minecraft.world.entity.LivingEntity> list = this.level().getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb, ThrownPotion.WATER_SENSITIVE_OR_ON_FIRE);
-+        // Paper start
++        // Paper start - Fix potions splash events
 +        List<net.minecraft.world.entity.LivingEntity> list = this.level().getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb, ThrownPotion.APPLY_WATER_GET_ENTITIES_PREDICATE);
 +        Map<LivingEntity, Double> affected = new HashMap<>();
 +        java.util.Set<LivingEntity> rehydrate = new java.util.HashSet<>();
@@ -93,14 +93,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                    axolotl.rehydrate();
 +                }
 +            }
-+            // Paper end
++            // Paper end - Fix potions splash events
          }
-+        return !event.isCancelled(); // Paper
++        return !event.isCancelled(); // Paper - Fix potions splash events
  
      }
  
 -    private void applySplash(List<MobEffectInstance> list, @Nullable Entity entity, HitResult position) { // CraftBukkit - Pass MovingObjectPosition
-+    private boolean applySplash(List<MobEffectInstance> list, @Nullable Entity entity, HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - return boolean
++    private boolean applySplash(List<MobEffectInstance> list, @Nullable Entity entity, HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events
          AABB axisalignedbb = this.getBoundingBox().inflate(4.0D, 2.0D, 4.0D);
          List<net.minecraft.world.entity.LivingEntity> list1 = this.level().getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb);
          Map<LivingEntity, Double> affected = new HashMap<LivingEntity, Double>(); // CraftBukkit
@@ -116,7 +116,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  }
              }
          }
-+        return !event.isCancelled(); // Paper
++        return !event.isCancelled(); // Paper - Fix potions splash events
  
      }
  
@@ -129,12 +129,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          entityareaeffectcloud.setPotion(potionregistry);
          Iterator iterator = PotionUtils.getCustomEffects(itemstack).iterator();
  
-+        boolean noEffects = potionregistry.getEffects().isEmpty(); // Paper
++        boolean noEffects = potionregistry.getEffects().isEmpty(); // Paper - Fix potions splash events
          while (iterator.hasNext()) {
              MobEffectInstance mobeffect = (MobEffectInstance) iterator.next();
  
              entityareaeffectcloud.addEffect(new MobEffectInstance(mobeffect));
-+            noEffects = false; // Paper
++            noEffects = false; // Paper - Fix potions splash events
          }
  
          CompoundTag nbttagcompound = itemstack.getTag();
@@ -149,7 +149,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              entityareaeffectcloud.discard();
          }
          // CraftBukkit end
-+        return !event.isCancelled(); // Paper
++        return !event.isCancelled(); // Paper - Fix potions splash events
      }
  
      public boolean isLingering() {
diff --git a/patches/server/Improve-boat-collision-performance.patch b/patches/server/Improve-boat-collision-performance.patch
index 025b175d01..84630f026f 100644
--- a/patches/server/Improve-boat-collision-performance.patch
+++ b/patches/server/Improve-boat-collision-performance.patch
@@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }).findFirst().orElseThrow(() -> {
          return new IllegalStateException("No jar file system provider found");
      });
-+    public static final double COLLISION_EPSILON = 1.0E-7; // Paper
++    public static final double COLLISION_EPSILON = 1.0E-7; // Paper - Improve boat collision performance
      private static Consumer<String> thePauser = (message) -> {
      };
  
@@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                      Entity entity = source.getDirectEntity();
  
 -                    if (entity instanceof LivingEntity) {
-+                    if (entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper
++                    if (entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper - Improve boat collision performance
                          LivingEntity entityliving = (LivingEntity) entity;
  
                          this.blockUsingShield(entityliving);
@@ -34,13 +34,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
                  if (entity1 != null && !source.is(DamageTypeTags.NO_KNOCKBACK)) {
 -                    double d0 = entity1.getX() - this.getX();
-+                    final boolean far = entity1.distanceToSqr(this) > (200.0 * 200.0); // Paper
-+                    double d0 = far ? (Math.random() - Math.random()) : entity1.getX() - this.getX(); // Paper
++                    final boolean far = entity1.distanceToSqr(this) > (200.0 * 200.0); // Paper - Improve boat collision performance
++                    double d0 = far ? (Math.random() - Math.random()) : entity1.getX() - this.getX(); // Paper - Improve boat collision performance
  
                      double d1;
  
 -                    for (d1 = entity1.getZ() - this.getZ(); d0 * d0 + d1 * d1 < 1.0E-4D; d1 = (Math.random() - Math.random()) * 0.01D) {
-+                    for (d1 = far ? Math.random() - Math.random() : entity1.getZ() - this.getZ(); d0 * d0 + d1 * d1 < 1.0E-4D; d1 = (Math.random() - Math.random()) * 0.01D) { // Paper
++                    for (d1 = far ? Math.random() - Math.random() : entity1.getZ() - this.getZ(); d0 * d0 + d1 * d1 < 1.0E-4D; d1 = (Math.random() - Math.random()) * 0.01D) { // Paper - Improve boat collision performance
                          d0 = (Math.random() - Math.random()) * 0.01D;
                      }
  
@@ -49,7 +49,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  Entity entity = damagesource.getDirectEntity();
  
 -                if (entity instanceof LivingEntity) {
-+                if (entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper
++                if (entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper - Improve boat collision performance
                      this.blockUsingShield((LivingEntity) entity);
                  }
              }
@@ -63,8 +63,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              this.waterLevel = this.getY(1.0D);
 -            this.setPos(this.getX(), (double) (this.getWaterLevelAbove() - this.getBbHeight()) + 0.101D, this.getZ());
 -            this.setDeltaMovement(this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D));
-+            this.move(MoverType.SELF, new Vec3(0.0, ((double) (this.getWaterLevelAbove() - this.getBbHeight()) + 0.101D) - this.getY(), 0.0)); // Paper
-+            this.setDeltaMovement(this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D)); // Paper
++            this.move(MoverType.SELF, new Vec3(0.0, ((double) (this.getWaterLevelAbove() - this.getBbHeight()) + 0.101D) - this.getY(), 0.0)); // Paper - Improve boat collision performance
++            this.setDeltaMovement(this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D)); // Paper - Improve boat collision performance
              this.lastYd = 0.0D;
              this.status = Boat.Status.IN_WATER;
          } else {
diff --git a/patches/server/Limit-item-frame-cursors-on-maps.patch b/patches/server/Limit-item-frame-cursors-on-maps.patch
index 5f8cf287d7..d9454802b9 100644
--- a/patches/server/Limit-item-frame-cursors-on-maps.patch
+++ b/patches/server/Limit-item-frame-cursors-on-maps.patch
@@ -12,10 +12,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
              MapFrame worldmapframe1 = new MapFrame(blockposition, entityitemframe.getDirection().get2DDataValue() * 90, entityitemframe.getId());
  
-+            if (this.decorations.size() < player.level().paperConfig().maps.itemFrameCursorLimit) { // Paper
++            if (this.decorations.size() < player.level().paperConfig().maps.itemFrameCursorLimit) { // Paper - Limit item frame cursors on maps
              this.addDecoration(MapDecoration.Type.FRAME, player.level(), "frame-" + entityitemframe.getId(), (double) blockposition.getX(), (double) blockposition.getZ(), (double) (entityitemframe.getDirection().get2DDataValue() * 90), (Component) null);
              this.frameMarkers.put(worldmapframe1.getId(), worldmapframe1);
-+            } // Paper
++            } // Paper - Limit item frame cursors on maps
          }
  
          CompoundTag nbttagcompound = stack.getTag();
@@ -24,7 +24,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              }
  
 -            if (!this.isTrackedCountOverLimit(256)) {
-+            if (!this.isTrackedCountOverLimit(((Level) world).paperConfig().maps.itemFrameCursorLimit)) { // Paper
++            if (!this.isTrackedCountOverLimit(((Level) world).paperConfig().maps.itemFrameCursorLimit)) { // Paper - Limit item frame cursors on maps
                  this.bannerMarkers.put(mapiconbanner.getId(), mapiconbanner);
                  this.addDecoration(mapiconbanner.getDecoration(), world, mapiconbanner.getId(), d0, d1, 180.0D, mapiconbanner.getName());
                  return true;
diff --git a/patches/server/Line-Of-Sight-Changes.patch b/patches/server/Line-Of-Sight-Changes.patch
index a8a70b3e11..f9ed855c77 100644
--- a/patches/server/Line-Of-Sight-Changes.patch
+++ b/patches/server/Line-Of-Sight-Changes.patch
@@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
 -            return vec3d1.distanceTo(vec3d) > 128.0D ? false : this.level().clipDirect(vec3d, vec3d1, net.minecraft.world.phys.shapes.CollisionContext.of(this)) == HitResult.Type.MISS; // Paper
 +            // Paper - diff on change - used in CraftLivingEntity#hasLineOfSight(Location) and CraftWorld#lineOfSightExists
-+            return vec3d1.distanceToSqr(vec3d) > 128.0D * 128.0D ? false : this.level().clipDirect(vec3d, vec3d1, net.minecraft.world.phys.shapes.CollisionContext.of(this)) == HitResult.Type.MISS; // Paper
++            return vec3d1.distanceToSqr(vec3d) > 128.0D * 128.0D ? false : this.level().clipDirect(vec3d, vec3d1, net.minecraft.world.phys.shapes.CollisionContext.of(this)) == HitResult.Type.MISS; // Paper - Perf: Use distance squared
          }
      }
  
diff --git a/patches/server/Make-EntityUnleashEvent-cancellable.patch b/patches/server/Make-EntityUnleashEvent-cancellable.patch
deleted file mode 100644
index 1a6a597185..0000000000
--- a/patches/server/Make-EntityUnleashEvent-cancellable.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jake Potrebic <jake.m.potrebic@gmail.com>
-Date: Sun, 3 Jan 2021 21:25:31 -0800
-Subject: [PATCH] Make EntityUnleashEvent cancellable
-
-
-diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/entity/Mob.java
-+++ b/src/main/java/net/minecraft/world/entity/Mob.java
-@@ -0,0 +0,0 @@ public abstract class Mob extends LivingEntity implements Targeting {
-         if (flag1 && this.isLeashed()) {
-             // Paper start - drop leash variable
-             EntityUnleashEvent event = new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.UNKNOWN, true);
--            this.level().getCraftServer().getPluginManager().callEvent(event); // CraftBukkit
-+            if (!event.callEvent()) { return flag1; }
-             this.dropLeash(true, event.isDropLeash());
-             // Paper end
-         }
-diff --git a/src/main/java/net/minecraft/world/entity/PathfinderMob.java b/src/main/java/net/minecraft/world/entity/PathfinderMob.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/entity/PathfinderMob.java
-+++ b/src/main/java/net/minecraft/world/entity/PathfinderMob.java
-@@ -0,0 +0,0 @@ public abstract class PathfinderMob extends Mob {
-                 if (f > entity.level().paperConfig().misc.maxLeashDistance) { // Paper
-                     // Paper start - drop leash variable
-                     EntityUnleashEvent event = new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE, true);
--                    this.level().getCraftServer().getPluginManager().callEvent(event); // CraftBukkit
-+                    if (!event.callEvent()) { return; }
-                     this.dropLeash(true, event.isDropLeash());
-                     // Paper end
-                 }
-@@ -0,0 +0,0 @@ public abstract class PathfinderMob extends Mob {
-             if (f > entity.level().paperConfig().misc.maxLeashDistance) { // Paper
-                 // Paper start - drop leash variable
-                 EntityUnleashEvent event = new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE, true);
--                this.level().getCraftServer().getPluginManager().callEvent(event); // CraftBukkit
-+                if (!event.callEvent()) { return; }
-                 this.dropLeash(true, event.isDropLeash());
-                 // Paper end
-                 this.goalSelector.disableControlFlag(Goal.Flag.MOVE);
diff --git a/patches/server/Make-hoppers-respect-inventory-max-stack-size.patch b/patches/server/Make-hoppers-respect-inventory-max-stack-size.patch
index 5c870950b9..ff00bfa3d8 100644
--- a/patches/server/Make-hoppers-respect-inventory-max-stack-size.patch
+++ b/patches/server/Make-hoppers-respect-inventory-max-stack-size.patch
@@ -12,19 +12,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
              if (itemstack1.isEmpty()) {
                  // Spigot start - SPIGOT-6693, InventorySubcontainer#setItem
-+                ItemStack leftover = ItemStack.EMPTY; // Paper
++                ItemStack leftover = ItemStack.EMPTY; // Paper - Make hoppers respect inventory max stack size
                  if (!stack.isEmpty() && stack.getCount() > to.getMaxStackSize()) {
-+                    leftover = stack; // Paper
++                    leftover = stack; // Paper - Make hoppers respect inventory max stack size
                      stack = stack.split(to.getMaxStackSize());
                  }
                  // Spigot end
                  to.setItem(slot, stack);
 -                stack = ItemStack.EMPTY;
-+                stack = leftover; // Paper
++                stack = leftover; // Paper - Make hoppers respect inventory max stack size
                  flag = true;
              } else if (HopperBlockEntity.canMergeItems(itemstack1, stack)) {
 -                int j = stack.getMaxStackSize() - itemstack1.getCount();
-+                int j = Math.min(stack.getMaxStackSize(), to.getMaxStackSize()) - itemstack1.getCount(); // Paper
++                int j = Math.min(stack.getMaxStackSize(), to.getMaxStackSize()) - itemstack1.getCount(); // Paper - Make hoppers respect inventory max stack size
                  int k = Math.min(stack.getCount(), j);
  
                  stack.shrink(k);
diff --git a/patches/server/More-Enchantment-API.patch b/patches/server/More-Enchantment-API.patch
index 0e8cc97e32..b3da8e8ef4 100644
--- a/patches/server/More-Enchantment-API.patch
+++ b/patches/server/More-Enchantment-API.patch
@@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
      public boolean isCursed() {
 -        return this.handle instanceof BindingCurseEnchantment || this.handle instanceof VanishingCurseEnchantment;
-+        return this.handle.isCurse(); // Paper
++        return this.handle.isCurse(); // Paper - More Enchantment API
      }
  
      @Override
diff --git a/patches/server/More-Projectile-API.patch b/patches/server/More-Projectile-API.patch
index a81d59463f..7e1c7f8fa2 100644
--- a/patches/server/More-Projectile-API.patch
+++ b/patches/server/More-Projectile-API.patch
@@ -48,8 +48,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      }
  
--    private boolean applySplash(List<MobEffectInstance> list, @Nullable Entity entity, HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - return boolean
-+    private boolean applySplash(List<MobEffectInstance> list, @Nullable Entity entity, @Nullable HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - return boolean & More projectile API
+-    private boolean applySplash(List<MobEffectInstance> list, @Nullable Entity entity, HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events
++    private boolean applySplash(List<MobEffectInstance> list, @Nullable Entity entity, @Nullable HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events & More projectile API
          AABB axisalignedbb = this.getBoundingBox().inflate(4.0D, 2.0D, 4.0D);
          List<net.minecraft.world.entity.LivingEntity> list1 = this.level().getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb);
          Map<LivingEntity, Double> affected = new HashMap<LivingEntity, Double>(); // CraftBukkit
diff --git a/patches/server/Move-range-check-for-block-placing-up.patch b/patches/server/Move-range-check-for-block-placing-up.patch
index d622eb2e30..438aeb4c5d 100644
--- a/patches/server/Move-range-check-for-block-placing-up.patch
+++ b/patches/server/Move-range-check-for-block-placing-up.patch
@@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            if (!Double.isFinite(vec3d.x) || !Double.isFinite(vec3d.y) || !Double.isFinite(vec3d.z)) {
 +                return;
 +            }
-+            // Paper end
++            // Paper end - improve distance check
              BlockPos blockposition = movingobjectpositionblock.getBlockPos();
              Vec3 vec3d1 = Vec3.atCenterOf(blockposition);
  
diff --git a/patches/server/Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch b/patches/server/Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch
index d62ea59491..15b2ddda76 100644
--- a/patches/server/Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch
+++ b/patches/server/Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch
@@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      public static class Builder {
 -        private final Map<MobCategory, List<MobSpawnSettings.SpawnerData>> spawners = Stream.of(MobCategory.values()).collect(ImmutableMap.toImmutableMap((mobCategory) -> {
-+        // Paper start - keep track of data in a pair set to give O(1) contains calls - we have to hook removals incase plugins mess with it
++        // Paper start - Perf: keep track of data in a pair set to give O(1) contains calls - we have to hook removals incase plugins mess with it
 +        public static class MobList extends java.util.ArrayList<MobSpawnSettings.SpawnerData> {
 +            java.util.Set<MobSpawnSettings.SpawnerData> biomes = new java.util.HashSet<>();
 +
@@ -51,7 +51,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -            return Lists.newArrayList();
 +            return new MobList(); // Use MobList instead of ArrayList
          }));
-+        // Paper end
++        // Paper end - Perf: keep track of data in a pair set to give O(1) contains calls
          private final Map<EntityType<?>, MobSpawnSettings.MobSpawnCost> mobSpawnCosts = Maps.newLinkedHashMap();
          private float creatureGenerationProbability = 0.1F;
  
diff --git a/patches/server/Optimize-Hoppers.patch b/patches/server/Optimize-Hoppers.patch
index 8aa716b517..0b616b1caf 100644
--- a/patches/server/Optimize-Hoppers.patch
+++ b/patches/server/Optimize-Hoppers.patch
@@ -647,7 +647,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                ignoreTileUpdates = true; // Paper - Perf: Optimize Hoppers
                  to.setItem(slot, stack);
 +                ignoreTileUpdates = false; // Paper - Perf: Optimize Hoppers
-                 stack = leftover; // Paper
+                 stack = leftover; // Paper - Make hoppers respect inventory max stack size
                  flag = true;
              } else if (HopperBlockEntity.canMergeItems(itemstack1, stack)) {
 @@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
diff --git a/patches/server/Optimize-indirect-passenger-iteration.patch b/patches/server/Optimize-indirect-passenger-iteration.patch
index 580d176547..ed969dd1af 100644
--- a/patches/server/Optimize-indirect-passenger-iteration.patch
+++ b/patches/server/Optimize-indirect-passenger-iteration.patch
@@ -12,24 +12,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }
  
      private Stream<Entity> getIndirectPassengersStream() {
-+        if (this.passengers.isEmpty()) { return Stream.of(); } // Paper
++        if (this.passengers.isEmpty()) { return Stream.of(); } // Paper - Optimize indirect passenger iteration
          return this.passengers.stream().flatMap(Entity::getSelfAndPassengers);
      }
  
      @Override
      public Stream<Entity> getSelfAndPassengers() {
-+        if (this.passengers.isEmpty()) { return Stream.of(this); } // Paper
++        if (this.passengers.isEmpty()) { return Stream.of(this); } // Paper - Optimize indirect passenger iteration
          return Stream.concat(Stream.of(this), this.getIndirectPassengersStream());
      }
  
      @Override
      public Stream<Entity> getPassengersAndSelf() {
-+        if (this.passengers.isEmpty()) { return Stream.of(this); } // Paper
++        if (this.passengers.isEmpty()) { return Stream.of(this); } // Paper - Optimize indirect passenger iteration
          return Stream.concat(this.passengers.stream().flatMap(Entity::getPassengersAndSelf), Stream.of(this));
      }
  
      public Iterable<Entity> getIndirectPassengers() {
-+        // Paper start - rewrite this method
++        // Paper start - Optimize indirect passenger iteration
 +        if (this.passengers.isEmpty()) { return ImmutableList.of(); }
 +        ImmutableList.Builder<Entity> indirectPassengers = ImmutableList.builder();
 +        for (Entity passenger : this.passengers) {
@@ -39,7 +39,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return indirectPassengers.build();
 +    }
 +    private Iterable<Entity> getIndirectPassengers_old() {
-+        // Paper end
++        // Paper end - Optimize indirect passenger iteration
          return () -> {
              return this.getIndirectPassengersStream().iterator();
          };
@@ -47,7 +47,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      // Paper end - rewrite chunk system
  
      public boolean hasExactlyOnePlayerPassenger() {
-+        if (this.passengers.isEmpty()) { return false; } // Paper
++        if (this.passengers.isEmpty()) { return false; } // Paper - Optimize indirect passenger iteration
          return this.countPlayerPassengers() == 1;
      }
  
diff --git a/patches/server/Option-to-prevent-NBT-copy-in-smithing-recipes.patch b/patches/server/Option-to-prevent-NBT-copy-in-smithing-recipes.patch
index 6989e14c70..b79b0db3fd 100644
--- a/patches/server/Option-to-prevent-NBT-copy-in-smithing-recipes.patch
+++ b/patches/server/Option-to-prevent-NBT-copy-in-smithing-recipes.patch
@@ -12,15 +12,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      final Ingredient base;
      final Ingredient addition;
      final ItemStack result;
-+    final boolean copyNBT; // Paper
++    final boolean copyNBT; // Paper - Option to prevent NBT copy
  
      public SmithingTransformRecipe(Ingredient template, Ingredient base, Ingredient addition, ItemStack result) {
-+        // Paper start
++        // Paper start - Option to prevent NBT copy
 +        this(template, base, addition, result, true);
 +    }
 +    public SmithingTransformRecipe(Ingredient template, Ingredient base, Ingredient addition, ItemStack result, boolean copyNBT) {
 +        this.copyNBT = copyNBT;
-+        // Paper end
++        // Paper end - Option to prevent NBT copy
          this.template = template;
          this.base = base;
          this.addition = addition;
@@ -28,13 +28,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
      public ItemStack assemble(Container inventory, RegistryAccess registryManager) {
          ItemStack itemstack = this.result.copy();
-+        if (this.copyNBT) { // Paper - copy nbt conditionally
++        if (this.copyNBT) { // Paper - Option to prevent NBT copy
          CompoundTag nbttagcompound = inventory.getItem(1).getTag();
  
          if (nbttagcompound != null) {
              itemstack.setTag(nbttagcompound.copy());
          }
-+        } // Paper
++        } // Paper - Option to prevent NBT copy
  
          return itemstack;
      }
@@ -43,7 +43,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          CraftItemStack result = CraftItemStack.asCraftMirror(this.result);
  
 -        CraftSmithingTransformRecipe recipe = new CraftSmithingTransformRecipe(id, result, CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition));
-+        CraftSmithingTransformRecipe recipe = new CraftSmithingTransformRecipe(id, result, CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition), this.copyNBT); // Paper
++        CraftSmithingTransformRecipe recipe = new CraftSmithingTransformRecipe(id, result, CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition), this.copyNBT); // Paper - Option to prevent NBT copy
  
          return recipe;
      }
@@ -55,15 +55,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      final Ingredient template;
      final Ingredient base;
      final Ingredient addition;
-+    final boolean copyNbt; // Paper
++    final boolean copyNbt; // Paper - Option to prevent NBT copy
  
      public SmithingTrimRecipe(Ingredient template, Ingredient base, Ingredient addition) {
-+        // Paper start
++        // Paper start - Option to prevent NBT copy
 +        this(template, base, addition, true);
 +    }
 +    public SmithingTrimRecipe(Ingredient template, Ingredient base, Ingredient addition, boolean copyNbt) {
 +        this.copyNbt = copyNbt;
-+        // Paper end
++        // Paper end - Option to prevent NBT copy
          this.template = template;
          this.base = base;
          this.addition = addition;
@@ -72,7 +72,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  }
  
 -                ItemStack itemstack1 = itemstack.copy();
-+                ItemStack itemstack1 = this.copyNbt ? itemstack.copy() : new ItemStack(itemstack.getItem(), itemstack.getCount()); // Paper
++                ItemStack itemstack1 = this.copyNbt ? itemstack.copy() : new ItemStack(itemstack.getItem(), itemstack.getCount()); // Paper - Option to prevent NBT copy
  
                  itemstack1.setCount(1);
                  ArmorTrim armortrim = new ArmorTrim((Holder) optional.get(), (Holder) optional1.get());
@@ -81,7 +81,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
      public Recipe toBukkitRecipe(NamespacedKey id) {
 -        return new CraftSmithingTrimRecipe(id, CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition));
-+        return new CraftSmithingTrimRecipe(id, CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition), this.copyNbt); // Paper
++        return new CraftSmithingTrimRecipe(id, CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition), this.copyNbt); // Paper - Option to prevent NBT copy
      }
      // CraftBukkit end
  
@@ -93,18 +93,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public CraftSmithingTransformRecipe(NamespacedKey key, ItemStack result, RecipeChoice template, RecipeChoice base, RecipeChoice addition) {
          super(key, result, template, base, addition);
      }
-+    // Paper start
++    // Paper start - Option to prevent NBT copy
 +    public CraftSmithingTransformRecipe(NamespacedKey key, ItemStack result, RecipeChoice template, RecipeChoice base, RecipeChoice addition, boolean copyNbt) {
 +        super(key, result, template, base, addition, copyNbt);
 +    }
-+    // Paper end
++    // Paper endv
  
      public static CraftSmithingTransformRecipe fromBukkitRecipe(SmithingTransformRecipe recipe) {
          if (recipe instanceof CraftSmithingTransformRecipe) {
              return (CraftSmithingTransformRecipe) recipe;
          }
 -        CraftSmithingTransformRecipe ret = new CraftSmithingTransformRecipe(recipe.getKey(), recipe.getResult(), recipe.getTemplate(), recipe.getBase(), recipe.getAddition());
-+        CraftSmithingTransformRecipe ret = new CraftSmithingTransformRecipe(recipe.getKey(), recipe.getResult(), recipe.getTemplate(), recipe.getBase(), recipe.getAddition(), recipe.willCopyNbt()); // Paper
++        CraftSmithingTransformRecipe ret = new CraftSmithingTransformRecipe(recipe.getKey(), recipe.getResult(), recipe.getTemplate(), recipe.getBase(), recipe.getAddition(), recipe.willCopyNbt()); // Paper - Option to prevent NBT copy
          return ret;
      }
  
@@ -113,7 +113,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          ItemStack result = this.getResult();
  
 -        MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTransformRecipe(this.toNMS(this.getTemplate(), true), this.toNMS(this.getBase(), true), this.toNMS(this.getAddition(), true), CraftItemStack.asNMSCopy(result))));
-+        MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTransformRecipe(this.toNMS(this.getTemplate(), true), this.toNMS(this.getBase(), true), this.toNMS(this.getAddition(), true), CraftItemStack.asNMSCopy(result), this.willCopyNbt()))); // Paper
++        MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTransformRecipe(this.toNMS(this.getTemplate(), true), this.toNMS(this.getBase(), true), this.toNMS(this.getAddition(), true), CraftItemStack.asNMSCopy(result), this.willCopyNbt()))); // Paper - Option to prevent NBT copy
      }
  }
 diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java
@@ -124,24 +124,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public CraftSmithingTrimRecipe(NamespacedKey key, RecipeChoice template, RecipeChoice base, RecipeChoice addition) {
          super(key, template, base, addition);
      }
-+    // Paper start
++    // Paper start - Option to prevent NBT copy
 +    public CraftSmithingTrimRecipe(NamespacedKey key, RecipeChoice template, RecipeChoice base, RecipeChoice addition, boolean copyNbt) {
 +        super(key, template, base, addition, copyNbt);
 +    }
-+    // Paper end
++    // Paper end - Option to prevent NBT copy
  
      public static CraftSmithingTrimRecipe fromBukkitRecipe(SmithingTrimRecipe recipe) {
          if (recipe instanceof CraftSmithingTrimRecipe) {
              return (CraftSmithingTrimRecipe) recipe;
          }
 -        CraftSmithingTrimRecipe ret = new CraftSmithingTrimRecipe(recipe.getKey(), recipe.getTemplate(), recipe.getBase(), recipe.getAddition());
-+        CraftSmithingTrimRecipe ret = new CraftSmithingTrimRecipe(recipe.getKey(), recipe.getTemplate(), recipe.getBase(), recipe.getAddition(), recipe.willCopyNbt()); // Paper
++        CraftSmithingTrimRecipe ret = new CraftSmithingTrimRecipe(recipe.getKey(), recipe.getTemplate(), recipe.getBase(), recipe.getAddition(), recipe.willCopyNbt()); // Paper - Option to prevent NBT copy
          return ret;
      }
  
      @Override
      public void addToCraftingManager() {
 -        MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTrimRecipe(this.toNMS(this.getTemplate(), true), this.toNMS(this.getBase(), true), this.toNMS(this.getAddition(), true))));
-+        MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTrimRecipe(this.toNMS(this.getTemplate(), true), this.toNMS(this.getBase(), true), this.toNMS(this.getAddition(), true), this.willCopyNbt()))); // Paper
++        MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTrimRecipe(this.toNMS(this.getTemplate(), true), this.toNMS(this.getBase(), true), this.toNMS(this.getAddition(), true), this.willCopyNbt()))); // Paper - Option to prevent NBT copy
      }
  }
diff --git a/patches/server/Prevent-AFK-kick-while-watching-end-credits.patch b/patches/server/Prevent-AFK-kick-while-watching-end-credits.patch
index da6e8bf395..fc86f078ae 100644
--- a/patches/server/Prevent-AFK-kick-while-watching-end-credits.patch
+++ b/patches/server/Prevent-AFK-kick-while-watching-end-credits.patch
@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Noah van der Aa <ndvdaa@gmail.com>
 Date: Sat, 24 Jul 2021 16:54:11 +0200
-Subject: [PATCH] Prevent AFK kick while watching end credits.
+Subject: [PATCH] Prevent AFK kick while watching end credits
 
 
 diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          }
  
 -        if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L) {
-+        if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L && !this.player.wonGame) { // Paper - Prevent AFK kick while watching end credits.
++        if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L && !this.player.wonGame) { // Paper - Prevent AFK kick while watching end credits
              this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854
              this.disconnect(Component.translatable("multiplayer.disconnect.idling"), org.bukkit.event.player.PlayerKickEvent.Cause.IDLING); // Paper - kick event cause
          }
diff --git a/patches/server/Properly-handle-experience-dropping-on-block-break.patch b/patches/server/Properly-handle-experience-dropping-on-block-break.patch
index 9f5b3f83b0..9539517d7c 100644
--- a/patches/server/Properly-handle-experience-dropping-on-block-break.patch
+++ b/patches/server/Properly-handle-experience-dropping-on-block-break.patch
@@ -41,7 +41,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          }
          return true;
      }
-     // Paper end
+     // Paper end - Add BlockBreakBlockEvent
  
      public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) {
 +    // Paper start - Properly handle xp dropping
diff --git a/patches/server/Rate-options-and-timings-for-sensors-and-behaviors.patch b/patches/server/Rate-options-and-timings-for-sensors-and-behaviors.patch
index aa94c146a3..6d602b1034 100644
--- a/patches/server/Rate-options-and-timings-for-sensors-and-behaviors.patch
+++ b/patches/server/Rate-options-and-timings-for-sensors-and-behaviors.patch
@@ -38,7 +38,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    // Paper start - configurable behavior tick rate and timings
 +    private final String configKey;
 +    private final co.aikar.timings.Timing timing;
-+    // Paper end
++    // Paper end - configurable behavior tick rate and timings
  
      public Behavior(Map<MemoryModuleType<?>, MemoryStatus> requiredMemoryState) {
          this(requiredMemoryState, 60);
@@ -54,7 +54,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        }
 +        this.configKey = key.toLowerCase(java.util.Locale.ROOT);
 +        this.timing = co.aikar.timings.MinecraftTimings.getBehaviorTimings(configKey);
-+        // Paper end
++        // Paper end - configurable behavior tick rate and timings
      }
  
      @Override
@@ -62,12 +62,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public final boolean tryStart(ServerLevel world, E entity, long time) {
-+        // Paper start - behavior tick rate
++        // Paper start - configurable behavior tick rate and timings
 +        int tickRate = java.util.Objects.requireNonNullElse(world.paperConfig().tickRates.behavior.get(entity.getType(), this.configKey), -1);
 +        if (tickRate > -1 && time < this.endTimestamp + tickRate) {
 +            return false;
 +        }
-+        // Paper end
++        // Paper end - configurable behavior tick rate and timings
          if (this.hasRequiredMemories(entity) && this.checkExtraStartConditions(world, entity)) {
              this.status = Behavior.Status.RUNNING;
              int i = this.minDuration + world.getRandom().nextInt(this.maxDuration + 1 - this.minDuration);
diff --git a/patches/server/Use-correct-seed-on-api-world-load.patch b/patches/server/Use-correct-seed-on-api-world-load.patch
index fb0ea89b84..48b2384c9f 100644
--- a/patches/server/Use-correct-seed-on-api-world-load.patch
+++ b/patches/server/Use-correct-seed-on-api-world-load.patch
@@ -10,7 +10,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
 @@ -0,0 +0,0 @@ public final class CraftServer implements Server {
  
-         // Paper - move down
+         // Paper - fix and optimise world upgrading; move down
  
 -        long j = BiomeManager.obfuscateSeed(creator.seed());
 +        long j = BiomeManager.obfuscateSeed(worlddata.worldGenOptions().seed()); // Paper - use world seed
diff --git a/patches/server/Use-getChunkIfLoadedImmediately-in-places.patch b/patches/server/Use-getChunkIfLoadedImmediately-in-places.patch
index 4f695f21fd..60456ce5ba 100644
--- a/patches/server/Use-getChunkIfLoadedImmediately-in-places.patch
+++ b/patches/server/Use-getChunkIfLoadedImmediately-in-places.patch
@@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override public LevelChunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI
 -        return this.chunkSource.getChunk(x, z, false);
-+        return this.chunkSource.getChunkAtIfLoadedImmediately(x, z); // Paper
++        return this.chunkSource.getChunkAtIfLoadedImmediately(x, z); // Paper - Use getChunkIfLoadedImmediately
      }
  
      @Override
@@ -28,12 +28,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          return (CraftServer) Bukkit.getServer();
      }
  
-+    // Paper start
++    // Paper start - Use getChunkIfLoadedImmediately
 +    @Override
 +    public boolean hasChunk(int chunkX, int chunkZ) {
 +        return this.getChunkIfLoaded(chunkX, chunkZ) != null;
 +    }
-+    // Paper end
++    // Paper end - Use getChunkIfLoadedImmediately
 +
      public abstract ResourceKey<LevelStem> getTypeKey();
  
@@ -47,7 +47,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          for (int l1 = j; l1 <= i1; ++l1) {
              for (int i2 = l; i2 <= k1; ++i2) {
 -                LevelChunk chunk = this.level.getChunkSource().getChunkNow(l1, i2);
-+                LevelChunk chunk = (LevelChunk) this.level.getChunkIfLoadedImmediately(l1, i2); // Paper
++                LevelChunk chunk = (LevelChunk) this.level.getChunkIfLoadedImmediately(l1, i2); // Paper - Use getChunkIfLoadedImmediately
  
                  if (chunk != null) {
                      for (int j2 = k; j2 <= j1; ++j2) {
diff --git a/patches/server/add-per-world-spawn-limits.patch b/patches/server/add-per-world-spawn-limits.patch
index 47d5f17754..fc8dcfb504 100644
--- a/patches/server/add-per-world-spawn-limits.patch
+++ b/patches/server/add-per-world-spawn-limits.patch
@@ -3,7 +3,6 @@ From: chase <chasewhip20@gmail.com>
 Date: Wed, 2 Dec 2020 22:43:39 -0800
 Subject: [PATCH] add per world spawn limits
 
-Taken from #2982. Credit to Chasewhip8
 
 diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
@@ -19,7 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                setSpawnLimit(spawnCategory, this.world.paperConfig().entities.spawning.spawnLimits.getInt(CraftSpawnCategory.toNMS(spawnCategory)));
 +            }
 +        }
-+        // Paper end
++        // Paper end - per world spawn limits
      }
  
      @Override