From c300745c8bce24f1f7628eb439a6964cdb1b52a8 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Thu, 25 Jun 2020 16:38:24 -0700
Subject: [PATCH] even even even even more work

---
 SHIT_TO_CHECK.md                              |   2 +
 ...ptions-from-dispenser-entity-spawns.patch} |   0
 ...66-Fix-World-isChunkGenerated-calls.patch} |  71 ++-
 ...te-location-if-we-failed-to-read-it.patch} |   2 +-
 ...aletteBlock-instead-of-ReentrantLoc.patch} |  18 +-
 .../0369-incremental-chunk-saving.patch       |  69 ++-
 ...4-Anti-Xray.patch => 0370-Anti-Xray.patch} | 138 ++---
 ...l-Spawned-mobs-towards-natural-spaw.patch} |  28 +-
 ...urable-projectile-relative-velocity.patch} |  33 +-
 ...being-ticked-when-notifying-navigat.patch} |   6 +-
 ...h => 0374-offset-item-frame-ticking.patch} |   2 +-
 ...pper-searches-if-there-are-no-items.patch} |  14 +-
 ...6-Asynchronous-chunk-IO-and-loading.patch} | 480 ++++++++----------
 ...tChunkIfLoadedImmediately-in-places.patch} |  51 +-
 ...ads.patch => 0378-Reduce-sync-loads.patch} |  26 +-
 ...ement-alternative-item-despawn-rate.patch} |  14 +-
 ...if-we-have-a-custom-Bukkit-generator.patch |  40 ++
 ...-158900.patch => 0381-Fix-MC-158900.patch} |   4 +-
 ...ment-optional-per-player-mob-spawns.patch} | 336 ++++++------
 ...event-consuming-the-wrong-itemstack.patch} |  16 +-
 ...ssanger-entities-once-from-spawners.patch} |   2 +-
 ... => 0385-Fix-nether-portal-creation.patch} |   0
 .../0386-Generator-Settings.patch             |  89 ++++
 ...-161754.patch => 0387-Fix-MC-161754.patch} |   2 +-
 ...e-improvement-for-Chunk.getEntities.patch} |   4 +-
 ...anging-entities-that-are-not-ItemFr.patch} |   4 +-
 ...90-Expose-the-internal-current-tick.patch} |   4 +-
 ...sneak-when-changing-worlds-MC-10657.patch} |   8 +-
 ...-option-to-disable-pillager-patrols.patch} |  10 +-
 ...r-when-player-hand-set-to-empty-typ.patch} |  28 +-
 ...if-we-have-a-custom-Bukkit-generator.patch |  46 --
 ...=> 0394-PlayerLaunchProjectileEvent.patch} |  80 ++-
 ...tMagicNumbers.isSupportedApiVersion.patch} |   2 +-
 ...nk-loads-when-villagers-try-to-find-.patch |  20 +
 ...656-Fix-Follow-Range-Initial-Target.patch} |   8 +-
 ...pers.patch => 0398-Optimize-Hoppers.patch} |  58 +--
 ...ayerDeathEvent-shouldDropExperience.patch} |   8 +-
 .../0400-Generator-Settings.patch             |  53 --
 ...ading-chunks-checking-hive-position.patch} |   4 +-
 ...hunks-from-Hoppers-and-other-things.patch} |  11 +-
 ...ializing-mismatching-chunk-coordina.patch} |  16 +-
 ...imise-IEntityAccess-getPlayerByUUID.patch} |  16 +-
 ...404-Fix-items-not-falling-correctly.patch} |   4 +-
 ...patch => 0405-Lag-compensate-eating.patch} |  50 +-
 ...ize-call-to-getFluid-for-explosions.patch} |   8 +-
 ...-in-stack-not-having-effects-when-d.patch} |  12 +-
 ...=> 0408-Entity-Activation-Range-2.0.patch} | 153 +++---
 ...Add-effect-to-block-break-naturally.patch} |   8 +-
 ...=> 0410-Tracking-Range-Improvements.patch} |   4 +-
 ...-items-vanishing-through-end-portal.patch} |  12 +-
 ...nk-loads-when-villagers-try-to-find-.patch |  20 -
 ...et-gravity-in-void.-Fixes-MC-167279.patch} |  10 +-
 ...-getChunkAt-calls-for-loaded-chunks.patch} |  10 +-
 ...w-overriding-the-java-version-check.patch} |   2 +-
 ...tch => 0415-Add-ThrownEggHatchEvent.patch} |   4 +-
 ... 0416-Optimise-random-block-ticking.patch} | 213 ++------
 ...p-API.patch => 0417-Entity-Jump-API.patch} |  20 +-
 ...-to-nerf-pigmen-from-nether-portals.patch} |  20 +-
 ... => 0419-Make-the-GUI-graph-fancier.patch} |  20 +-
 ...20-add-hand-to-BlockMultiPlaceEvent.patch} |   4 +-
 ...1-Prevent-teleporting-dead-entities.patch} |   4 +-
 ...ipwire-hook-placement-before-update.patch} |   2 +-
 ...o-allow-iron-golems-to-spawn-in-air.patch} |   8 +-
 ...chance-of-villager-zombie-infection.patch} |  19 +-
 ...tch => 0425-Optimise-Chunk-getFluid.patch} |  10 +-
 ...mise-TickListServer-by-rewriting-it.patch} | 118 ++---
 ...ator-behavior-for-EntityPhanton-goal.patch |  19 -
 ...pawn-settings-and-per-player-option.patch} |  17 +-
 ...e-Entity-is-never-double-registered.patch} |  24 +-
 ...ring-entities-from-unloading-chunks.patch} |   4 +-
 ...nections-shouldn-t-hold-up-shutdown.patch} |   4 +-
 ...ow-bees-to-load-chunks-for-beehives.patch} |  12 +-
 ...-more-tolerant-of-invalid-attributes.patch |  29 --
 ...PlayerChunkMap-adds-crashing-server.patch} |  14 +-
 .../0439-Backport-fix-for-MC-167561.patch     |  41 --
 ...Status-cache-when-saving-protochunks.patch |   0
 ...-Fix-spawn-radius-being-treated-as-0.patch |   2 +
 .../0429-Seed-based-feature-search.patch      |   0
 scripts/importmcdev.sh                        |   2 +-
 79 files changed, 1260 insertions(+), 1466 deletions(-)
 rename Spigot-Server-Patches/{0366-Catch-exceptions-from-dispenser-entity-spawns.patch => 0365-Catch-exceptions-from-dispenser-entity-spawns.patch} (100%)
 rename Spigot-Server-Patches/{0380-Fix-World-isChunkGenerated-calls.patch => 0366-Fix-World-isChunkGenerated-calls.patch} (88%)
 rename Spigot-Server-Patches/{0381-Show-blockstate-location-if-we-failed-to-read-it.patch => 0367-Show-blockstate-location-if-we-failed-to-read-it.patch} (94%)
 rename Spigot-Server-Patches/{0382-Synchronize-DataPaletteBlock-instead-of-ReentrantLoc.patch => 0368-Synchronize-DataPaletteBlock-instead-of-ReentrantLoc.patch} (86%)
 rename removed/1.16/0378-incremental-chunk-saving.patch => Spigot-Server-Patches/0369-incremental-chunk-saving.patch (85%)
 rename Spigot-Server-Patches/{0384-Anti-Xray.patch => 0370-Anti-Xray.patch} (92%)
 rename Spigot-Server-Patches/{0385-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch => 0371-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch} (62%)
 rename Spigot-Server-Patches/{0386-Configurable-projectile-relative-velocity.patch => 0372-Configurable-projectile-relative-velocity.patch} (57%)
 rename Spigot-Server-Patches/{0387-Mark-entities-as-being-ticked-when-notifying-navigat.patch => 0373-Mark-entities-as-being-ticked-when-notifying-navigat.patch} (76%)
 rename Spigot-Server-Patches/{0388-offset-item-frame-ticking.patch => 0374-offset-item-frame-ticking.patch} (89%)
 rename Spigot-Server-Patches/{0389-Avoid-hopper-searches-if-there-are-no-items.patch => 0375-Avoid-hopper-searches-if-there-are-no-items.patch} (91%)
 rename Spigot-Server-Patches/{0390-Asynchronous-chunk-IO-and-loading.patch => 0376-Asynchronous-chunk-IO-and-loading.patch} (92%)
 rename Spigot-Server-Patches/{0391-Use-getChunkIfLoadedImmediately-in-places.patch => 0377-Use-getChunkIfLoadedImmediately-in-places.patch} (65%)
 rename Spigot-Server-Patches/{0392-Reduce-sync-loads.patch => 0378-Reduce-sync-loads.patch} (91%)
 rename Spigot-Server-Patches/{0393-Implement-alternative-item-despawn-rate.patch => 0379-Implement-alternative-item-despawn-rate.patch} (91%)
 create mode 100644 Spigot-Server-Patches/0380-Do-less-work-if-we-have-a-custom-Bukkit-generator.patch
 rename Spigot-Server-Patches/{0395-Fix-MC-158900.patch => 0381-Fix-MC-158900.patch} (90%)
 rename Spigot-Server-Patches/{0396-implement-optional-per-player-mob-spawns.patch => 0382-implement-optional-per-player-mob-spawns.patch} (68%)
 rename Spigot-Server-Patches/{0397-Prevent-consuming-the-wrong-itemstack.patch => 0383-Prevent-consuming-the-wrong-itemstack.patch} (80%)
 rename Spigot-Server-Patches/{0398-only-add-passanger-entities-once-from-spawners.patch => 0384-only-add-passanger-entities-once-from-spawners.patch} (90%)
 rename Spigot-Server-Patches/{0399-Fix-nether-portal-creation.patch => 0385-Fix-nether-portal-creation.patch} (100%)
 create mode 100644 Spigot-Server-Patches/0386-Generator-Settings.patch
 rename Spigot-Server-Patches/{0402-Fix-MC-161754.patch => 0387-Fix-MC-161754.patch} (91%)
 rename Spigot-Server-Patches/{0403-Performance-improvement-for-Chunk.getEntities.patch => 0388-Performance-improvement-for-Chunk.getEntities.patch} (90%)
 rename Spigot-Server-Patches/{0404-Fix-spawning-of-hanging-entities-that-are-not-ItemFr.patch => 0389-Fix-spawning-of-hanging-entities-that-are-not-ItemFr.patch} (90%)
 rename Spigot-Server-Patches/{0405-Expose-the-internal-current-tick.patch => 0390-Expose-the-internal-current-tick.patch} (81%)
 rename Spigot-Server-Patches/{0406-Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch => 0391-Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch} (80%)
 rename Spigot-Server-Patches/{0407-Add-option-to-disable-pillager-patrols.patch => 0392-Add-option-to-disable-pillager-patrols.patch} (80%)
 rename Spigot-Server-Patches/{0408-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch => 0393-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch} (55%)
 delete mode 100644 Spigot-Server-Patches/0394-Do-less-work-if-we-have-a-custom-Bukkit-generator.patch
 rename Spigot-Server-Patches/{0409-PlayerLaunchProjectileEvent.patch => 0394-PlayerLaunchProjectileEvent.patch} (82%)
 rename Spigot-Server-Patches/{0410-Add-CraftMagicNumbers.isSupportedApiVersion.patch => 0395-Add-CraftMagicNumbers.isSupportedApiVersion.patch} (90%)
 create mode 100644 Spigot-Server-Patches/0396-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch
 rename Spigot-Server-Patches/{0413-MC-145656-Fix-Follow-Range-Initial-Target.patch => 0397-MC-145656-Fix-Follow-Range-Initial-Target.patch} (89%)
 rename Spigot-Server-Patches/{0414-Optimize-Hoppers.patch => 0398-Optimize-Hoppers.patch} (92%)
 rename Spigot-Server-Patches/{0415-PlayerDeathEvent-shouldDropExperience.patch => 0399-PlayerDeathEvent-shouldDropExperience.patch} (81%)
 delete mode 100644 Spigot-Server-Patches/0400-Generator-Settings.patch
 rename Spigot-Server-Patches/{0416-Prevent-bees-loading-chunks-checking-hive-position.patch => 0400-Prevent-bees-loading-chunks-checking-hive-position.patch} (82%)
 rename Spigot-Server-Patches/{0417-Don-t-load-Chunks-from-Hoppers-and-other-things.patch => 0401-Don-t-load-Chunks-from-Hoppers-and-other-things.patch} (82%)
 rename Spigot-Server-Patches/{0418-Guard-against-serializing-mismatching-chunk-coordina.patch => 0402-Guard-against-serializing-mismatching-chunk-coordina.patch} (85%)
 rename Spigot-Server-Patches/{0419-Optimise-IEntityAccess-getPlayerByUUID.patch => 0403-Optimise-IEntityAccess-getPlayerByUUID.patch} (57%)
 rename Spigot-Server-Patches/{0420-Fix-items-not-falling-correctly.patch => 0404-Fix-items-not-falling-correctly.patch} (89%)
 rename Spigot-Server-Patches/{0421-Lag-compensate-eating.patch => 0405-Lag-compensate-eating.patch} (65%)
 rename Spigot-Server-Patches/{0422-Optimize-call-to-getFluid-for-explosions.patch => 0406-Optimize-call-to-getFluid-for-explosions.patch} (72%)
 rename Spigot-Server-Patches/{0423-Fix-last-firework-in-stack-not-having-effects-when-d.patch => 0407-Fix-last-firework-in-stack-not-having-effects-when-d.patch} (56%)
 rename Spigot-Server-Patches/{0424-Entity-Activation-Range-2.0.patch => 0408-Entity-Activation-Range-2.0.patch} (89%)
 rename Spigot-Server-Patches/{0425-Add-effect-to-block-break-naturally.patch => 0409-Add-effect-to-block-break-naturally.patch} (78%)
 rename Spigot-Server-Patches/{0426-Tracking-Range-Improvements.patch => 0410-Tracking-Range-Improvements.patch} (95%)
 rename Spigot-Server-Patches/{0428-Fix-items-vanishing-through-end-portal.patch => 0411-Fix-items-vanishing-through-end-portal.patch} (63%)
 delete mode 100644 Spigot-Server-Patches/0411-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch
 rename Spigot-Server-Patches/{0430-Bees-get-gravity-in-void.-Fixes-MC-167279.patch => 0412-Bees-get-gravity-in-void.-Fixes-MC-167279.patch} (84%)
 rename Spigot-Server-Patches/{0431-Optimise-getChunkAt-calls-for-loaded-chunks.patch => 0413-Optimise-getChunkAt-calls-for-loaded-chunks.patch} (89%)
 rename Spigot-Server-Patches/{0433-Allow-overriding-the-java-version-check.patch => 0414-Allow-overriding-the-java-version-check.patch} (90%)
 rename Spigot-Server-Patches/{0434-Add-ThrownEggHatchEvent.patch => 0415-Add-ThrownEggHatchEvent.patch} (89%)
 rename Spigot-Server-Patches/{0435-Optimise-random-block-ticking.patch => 0416-Optimise-random-block-ticking.patch} (67%)
 rename Spigot-Server-Patches/{0436-Entity-Jump-API.patch => 0417-Entity-Jump-API.patch} (76%)
 rename Spigot-Server-Patches/{0437-Add-option-to-nerf-pigmen-from-nether-portals.patch => 0418-Add-option-to-nerf-pigmen-from-nether-portals.patch} (75%)
 rename Spigot-Server-Patches/{0438-Make-the-GUI-graph-fancier.patch => 0419-Make-the-GUI-graph-fancier.patch} (95%)
 rename Spigot-Server-Patches/{0440-add-hand-to-BlockMultiPlaceEvent.patch => 0420-add-hand-to-BlockMultiPlaceEvent.patch} (89%)
 rename Spigot-Server-Patches/{0441-Prevent-teleporting-dead-entities.patch => 0421-Prevent-teleporting-dead-entities.patch} (84%)
 rename Spigot-Server-Patches/{0442-Validate-tripwire-hook-placement-before-update.patch => 0422-Validate-tripwire-hook-placement-before-update.patch} (90%)
 rename Spigot-Server-Patches/{0443-Add-option-to-allow-iron-golems-to-spawn-in-air.patch => 0423-Add-option-to-allow-iron-golems-to-spawn-in-air.patch} (82%)
 rename Spigot-Server-Patches/{0444-Configurable-chance-of-villager-zombie-infection.patch => 0424-Configurable-chance-of-villager-zombie-infection.patch} (84%)
 rename Spigot-Server-Patches/{0445-Optimise-Chunk-getFluid.patch => 0425-Optimise-Chunk-getFluid.patch} (87%)
 rename Spigot-Server-Patches/{0446-Optimise-TickListServer-by-rewriting-it.patch => 0426-Optimise-TickListServer-by-rewriting-it.patch} (91%)
 delete mode 100644 Spigot-Server-Patches/0427-Fix-comparator-behavior-for-EntityPhanton-goal.patch
 rename Spigot-Server-Patches/{0447-Pillager-patrol-spawn-settings-and-per-player-option.patch => 0427-Pillager-patrol-spawn-settings-and-per-player-option.patch} (92%)
 rename Spigot-Server-Patches/{0448-Ensure-Entity-is-never-double-registered.patch => 0428-Ensure-Entity-is-never-double-registered.patch} (77%)
 rename Spigot-Server-Patches/{0449-Fix-unregistering-entities-from-unloading-chunks.patch => 0429-Fix-unregistering-entities-from-unloading-chunks.patch} (88%)
 rename Spigot-Server-Patches/{0450-Remote-Connections-shouldn-t-hold-up-shutdown.patch => 0430-Remote-Connections-shouldn-t-hold-up-shutdown.patch} (86%)
 rename Spigot-Server-Patches/{0451-Do-not-allow-bees-to-load-chunks-for-beehives.patch => 0431-Do-not-allow-bees-to-load-chunks-for-beehives.patch} (73%)
 delete mode 100644 Spigot-Server-Patches/0432-Be-more-tolerant-of-invalid-attributes.patch
 rename Spigot-Server-Patches/{0452-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch => 0432-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch} (81%)
 delete mode 100644 Spigot-Server-Patches/0439-Backport-fix-for-MC-167561.patch
 rename {Spigot-Server-Patches => removed/1.16}/0383-Use-ChunkStatus-cache-when-saving-protochunks.patch (100%)
 rename {Spigot-Server-Patches => removed/1.16}/0412-Fix-spawn-radius-being-treated-as-0.patch (98%)
 rename {Spigot-Server-Patches => removed/1.16}/0429-Seed-based-feature-search.patch (100%)

diff --git a/SHIT_TO_CHECK.md b/SHIT_TO_CHECK.md
index 6077d66cd2..024d8cc9af 100644
--- a/SHIT_TO_CHECK.md
+++ b/SHIT_TO_CHECK.md
@@ -4,3 +4,5 @@
 * Mini: "Optimize World Server Map": Figure out how to fill PaperWorldMap, it needs a dim key which doesnt exist anymore?
 * Mini: "MC-50319": fix if still works
 * Mini: I definetly dropped a patch I didnt want to drop, we need to go thru in the end and see if all patches are still in, lol
+* Make sure the flat bedrock setting doesn't do anything stupid
+* Check DataBits foreach
\ No newline at end of file
diff --git a/Spigot-Server-Patches/0366-Catch-exceptions-from-dispenser-entity-spawns.patch b/Spigot-Server-Patches/0365-Catch-exceptions-from-dispenser-entity-spawns.patch
similarity index 100%
rename from Spigot-Server-Patches/0366-Catch-exceptions-from-dispenser-entity-spawns.patch
rename to Spigot-Server-Patches/0365-Catch-exceptions-from-dispenser-entity-spawns.patch
diff --git a/Spigot-Server-Patches/0380-Fix-World-isChunkGenerated-calls.patch b/Spigot-Server-Patches/0366-Fix-World-isChunkGenerated-calls.patch
similarity index 88%
rename from Spigot-Server-Patches/0380-Fix-World-isChunkGenerated-calls.patch
rename to Spigot-Server-Patches/0366-Fix-World-isChunkGenerated-calls.patch
index 66b5a976d6..a50ee287d7 100644
--- a/Spigot-Server-Patches/0380-Fix-World-isChunkGenerated-calls.patch
+++ b/Spigot-Server-Patches/0366-Fix-World-isChunkGenerated-calls.patch
@@ -8,10 +8,10 @@ This patch also adds a chunk status cache on region files (note that
 its only purpose is to cache the status on DISK)
 
 diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
-index 7b855ec2914a8a31ce0ade0f7ad085dd04f71478..d8647f272bdb29518b1a7faafa6fbcb53ffe1163 100644
+index 9f4c79629c981d496b96cf8a7a4c8e058f102b8b..726926f19c6725c1d935beec2f0f766d7466835e 100644
 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
 +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
-@@ -28,7 +28,7 @@ public class ChunkProviderServer extends IChunkProvider {
+@@ -29,7 +29,7 @@ public class ChunkProviderServer extends IChunkProvider {
      private final WorldServer world;
      public final Thread serverThread; // Paper - private -> public
      private final LightEngineThreaded lightEngine;
@@ -20,7 +20,7 @@ index 7b855ec2914a8a31ce0ade0f7ad085dd04f71478..d8647f272bdb29518b1a7faafa6fbcb5
      public final PlayerChunkMap playerChunkMap;
      private final WorldPersistentData worldPersistentData;
      private long lastTickTime;
-@@ -294,6 +294,21 @@ public class ChunkProviderServer extends IChunkProvider {
+@@ -295,6 +295,21 @@ public class ChunkProviderServer extends IChunkProvider {
  
          return ret;
      }
@@ -43,10 +43,10 @@ index 7b855ec2914a8a31ce0ade0f7ad085dd04f71478..d8647f272bdb29518b1a7faafa6fbcb5
  
      @Nullable
 diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
-index f54572773c25b6716a68166efa8d3fc8b22b6258..8e4b3e52cbc95e24b1d72aed9ec8c32b94a91561 100644
+index 17b8c4445af2bd2ed907d05ed3c396d4290dc63d..208a8ef3aaa4b33bfe2db2569a3588a332ab5686 100644
 --- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
 +++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
-@@ -403,6 +403,17 @@ public class ChunkRegionLoader {
+@@ -407,6 +407,17 @@ public class ChunkRegionLoader {
      }
      // Paper end
  
@@ -65,10 +65,10 @@ index f54572773c25b6716a68166efa8d3fc8b22b6258..8e4b3e52cbc95e24b1d72aed9ec8c32b
          if (nbttagcompound != null) {
              ChunkStatus chunkstatus = ChunkStatus.a(nbttagcompound.getCompound("Level").getString("Status"));
 diff --git a/src/main/java/net/minecraft/server/ChunkStatus.java b/src/main/java/net/minecraft/server/ChunkStatus.java
-index efdf611e66ffd782291de749d8a48f3bf08f2129..134a4f0b7d254b5dd8ca26a9c5874532826978c4 100644
+index fb3ddcc5d5a1154a7e0583135ecd541e8f67ff0b..3ef584605d408c268806e74b95e9223ca4ffe0d9 100644
 --- a/src/main/java/net/minecraft/server/ChunkStatus.java
 +++ b/src/main/java/net/minecraft/server/ChunkStatus.java
-@@ -176,6 +176,7 @@ public class ChunkStatus {
+@@ -182,6 +182,7 @@ public class ChunkStatus {
          return this.s;
      }
  
@@ -76,7 +76,7 @@ index efdf611e66ffd782291de749d8a48f3bf08f2129..134a4f0b7d254b5dd8ca26a9c5874532
      public ChunkStatus e() {
          return this.u;
      }
-@@ -196,6 +197,17 @@ public class ChunkStatus {
+@@ -202,6 +203,17 @@ public class ChunkStatus {
          return this.y;
      }
  
@@ -95,7 +95,7 @@ index efdf611e66ffd782291de749d8a48f3bf08f2129..134a4f0b7d254b5dd8ca26a9c5874532
          return (ChunkStatus) IRegistry.CHUNK_STATUS.get(MinecraftKey.a(s));
      }
 diff --git a/src/main/java/net/minecraft/server/IChunkLoader.java b/src/main/java/net/minecraft/server/IChunkLoader.java
-index f0a052eec2fb72b11dc70bf62a5e57f599bbc190..2f95174fcc467908808ed3f2dc956bdcafdc3558 100644
+index 2fde0b6ca8f38a998ac73b68be61fbfea9088cee..fa03834dacacf7ae6a326c88007256a261153c27 100644
 --- a/src/main/java/net/minecraft/server/IChunkLoader.java
 +++ b/src/main/java/net/minecraft/server/IChunkLoader.java
 @@ -8,7 +8,7 @@ import javax.annotation.Nullable;
@@ -108,10 +108,10 @@ index f0a052eec2fb72b11dc70bf62a5e57f599bbc190..2f95174fcc467908808ed3f2dc956bdc
      @Nullable
      private PersistentStructureLegacy c;
 diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
-index ed9ada49c7cc1131691bd6e005b2380274ef23e3..52ea4f05a0c7f29f62f31bb032a5ceb905107e60 100644
+index d806b6acbcfbf141f4c1436bd5a163fbf11bf4e6..3b0d13d319fe1d274ab657c7c87e5a2db5c02c4f 100644
 --- a/src/main/java/net/minecraft/server/PlayerChunk.java
 +++ b/src/main/java/net/minecraft/server/PlayerChunk.java
-@@ -115,6 +115,19 @@ public class PlayerChunk {
+@@ -111,6 +111,19 @@ public class PlayerChunk {
          Either<IChunkAccess, PlayerChunk.Failure> either = (Either<IChunkAccess, PlayerChunk.Failure>) statusFuture.getNow(null);
          return either == null ? null : (Chunk) either.left().orElse(null);
      }
@@ -132,24 +132,22 @@ index ed9ada49c7cc1131691bd6e005b2380274ef23e3..52ea4f05a0c7f29f62f31bb032a5ceb9
  
      public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> getStatusFutureUnchecked(ChunkStatus chunkstatus) {
 diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
-index 4f5b516144829a7ae11f21a56789ac7a1f256250..1d517fd1aea90edf470388fd857a41f2be149327 100644
+index 684d84e3c5caf1a0c816895c4930d056b2ba8be5..6dda11ffc022aa9bc7481506811a710a184f5e78 100644
 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
 +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
-@@ -969,12 +969,62 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -938,12 +938,61 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
      }
  
      @Nullable
 -    private NBTTagCompound readChunkData(ChunkCoordIntPair chunkcoordintpair) throws IOException {
 +    public NBTTagCompound readChunkData(ChunkCoordIntPair chunkcoordintpair) throws IOException { // Paper - private -> public
          NBTTagCompound nbttagcompound = this.read(chunkcoordintpair);
- 
--        return nbttagcompound == null ? null : this.getChunkData(this.world.getWorldProvider().getDimensionManager(), this.l, nbttagcompound, chunkcoordintpair, world); // CraftBukkit
 +        // Paper start - Cache chunk status on disk
 +        if (nbttagcompound == null) {
 +            return null;
 +        }
 +
-+        nbttagcompound = this.getChunkData(this.world.getWorldProvider().getDimensionManager(), this.l, nbttagcompound, chunkcoordintpair, world); // CraftBukkit
++        nbttagcompound = this.getChunkData(this.world.getTypeKey(), this.l, nbttagcompound, chunkcoordintpair, world); // CraftBukkit
 +        if (nbttagcompound == null) {
 +            return null;
 +        }
@@ -165,12 +163,12 @@ index 4f5b516144829a7ae11f21a56789ac7a1f256250..1d517fd1aea90edf470388fd857a41f2
 +        RegionFile regionFile = this.getIOWorker().getRegionFileCache().getRegionFileIfLoaded(chunkPos);
 +
 +        return regionFile == null ? null : regionFile.getStatusIfCached(chunkPos.x, chunkPos.z);
-     }
- 
-+    public ChunkStatus getChunkStatusOnDisk(ChunkCoordIntPair chunkPos) throws IOException {
-+        RegionFile regionFile = this.getIOWorker().getRegionFileCache().getFile(chunkPos, false);
++    }
 +
-+        if (!regionFile.chunkExists(chunkPos)) {
++    public ChunkStatus getChunkStatusOnDisk(ChunkCoordIntPair chunkPos) throws IOException {
++        RegionFile regionFile = this.getIOWorker().getRegionFileCache().getFile(chunkPos, true);
++
++        if (regionFile == null || !regionFile.chunkExists(chunkPos)) {
 +            return null;
 +        }
 +
@@ -181,10 +179,11 @@ index 4f5b516144829a7ae11f21a56789ac7a1f256250..1d517fd1aea90edf470388fd857a41f2
 +        }
 +
 +        this.readChunkData(chunkPos);
-+
+ 
+-        return nbttagcompound == null ? null : this.getChunkData(this.world.getTypeKey(), this.l, nbttagcompound, chunkcoordintpair, world); // CraftBukkit
 +        return regionFile.getStatusIfCached(chunkPos.x, chunkPos.z);
-+    }
-+
+     }
+ 
 +    public void updateChunkStatusOnDisk(ChunkCoordIntPair chunkPos, @Nullable NBTTagCompound compound) throws IOException {
 +        RegionFile regionFile = this.getIOWorker().getRegionFileCache().getFile(chunkPos, false);
 +
@@ -201,7 +200,7 @@ index 4f5b516144829a7ae11f21a56789ac7a1f256250..1d517fd1aea90edf470388fd857a41f2
          // Spigot start
          return isOutsideOfRange(chunkcoordintpair, false);
 diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java
-index 6b543f89d4e32fb79bfe9aa7b815e4117dbea602..d37abf2cf304f81405e570588c8accbc44a629f4 100644
+index f781bb12a1c37d8b3088d0f638eae80d5b80aca4..e1730709fff5dfee68621d0aaed70a00bab97948 100644
 --- a/src/main/java/net/minecraft/server/RegionFile.java
 +++ b/src/main/java/net/minecraft/server/RegionFile.java
 @@ -36,6 +36,30 @@ public class RegionFile implements AutoCloseable {
@@ -232,10 +231,10 @@ index 6b543f89d4e32fb79bfe9aa7b815e4117dbea602..d37abf2cf304f81405e570588c8accbc
 +    }
 +    // Paper end
 +
-     public RegionFile(File file, File file1) throws IOException {
-         this(file.toPath(), file1.toPath(), RegionFileCompression.b);
+     public RegionFile(File file, File file1, boolean flag) throws IOException {
+         this(file.toPath(), file1.toPath(), RegionFileCompression.b, flag);
      }
-@@ -350,11 +374,13 @@ public class RegionFile implements AutoCloseable {
+@@ -359,11 +383,13 @@ public class RegionFile implements AutoCloseable {
          return this.getOffset(chunkcoordintpair) != 0;
      }
  
@@ -247,14 +246,14 @@ index 6b543f89d4e32fb79bfe9aa7b815e4117dbea602..d37abf2cf304f81405e570588c8accbc
      public void close() throws IOException {
 +        this.closed = true; // Paper
          try {
-             this.c();
+             this.d();
          } finally {
 diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java
-index 942b7d323936a872d83c536c1901b4b436aa7e7c..2f8af42e2aadeb1b11db94fdb54ec0ba9e30f095 100644
+index 02bd568af727633a6e834d5328683a9ff67b9dd7..341689ac996164b7b53e095495b92b6e85ab991a 100644
 --- a/src/main/java/net/minecraft/server/RegionFileCache.java
 +++ b/src/main/java/net/minecraft/server/RegionFileCache.java
-@@ -18,7 +18,14 @@ public final class RegionFileCache implements AutoCloseable {
-         this.b = file;
+@@ -20,7 +20,14 @@ public final class RegionFileCache implements AutoCloseable {
+         this.c = flag;
      }
  
 -    private RegionFile getFile(ChunkCoordIntPair chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit
@@ -269,7 +268,7 @@ index 942b7d323936a872d83c536c1901b4b436aa7e7c..2f8af42e2aadeb1b11db94fdb54ec0ba
          long i = ChunkCoordIntPair.pair(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ());
          RegionFile regionfile = (RegionFile) this.cache.getAndMoveToFirst(i);
  
-@@ -165,7 +172,8 @@ public final class RegionFileCache implements AutoCloseable {
+@@ -167,7 +174,8 @@ public final class RegionFileCache implements AutoCloseable {
  
          try {
              NBTCompressedStreamTools.a(nbttagcompound, (DataOutput) dataoutputstream);
@@ -280,7 +279,7 @@ index 942b7d323936a872d83c536c1901b4b436aa7e7c..2f8af42e2aadeb1b11db94fdb54ec0ba
              throwable = throwable1;
              throw throwable1;
 diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index b257ef7583f7bc3b6d31f0be89990603640c5ff7..cf059aa091e9c732f99b89fc347074a9c1b879a8 100644
+index 0286bfc117efd9424de332f20398a26d613b98b7..1f1839f40a406f6a2bf2d3af68c2d208d6503b2d 100644
 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
 +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
 @@ -19,6 +19,7 @@ import java.util.Objects;
@@ -291,7 +290,7 @@ index b257ef7583f7bc3b6d31f0be89990603640c5ff7..cf059aa091e9c732f99b89fc347074a9
  import java.util.function.Predicate;
  import java.util.stream.Collectors;
  import net.minecraft.server.ArraySetSorted;
-@@ -410,8 +411,22 @@ public class CraftWorld implements World {
+@@ -411,8 +412,22 @@ public class CraftWorld implements World {
  
      @Override
      public boolean isChunkGenerated(int x, int z) {
@@ -315,7 +314,7 @@ index b257ef7583f7bc3b6d31f0be89990603640c5ff7..cf059aa091e9c732f99b89fc347074a9
          } catch (IOException ex) {
              throw new RuntimeException(ex);
          }
-@@ -522,20 +537,49 @@ public class CraftWorld implements World {
+@@ -523,20 +538,49 @@ public class CraftWorld implements World {
      @Override
      public boolean loadChunk(int x, int z, boolean generate) {
          org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
diff --git a/Spigot-Server-Patches/0381-Show-blockstate-location-if-we-failed-to-read-it.patch b/Spigot-Server-Patches/0367-Show-blockstate-location-if-we-failed-to-read-it.patch
similarity index 94%
rename from Spigot-Server-Patches/0381-Show-blockstate-location-if-we-failed-to-read-it.patch
rename to Spigot-Server-Patches/0367-Show-blockstate-location-if-we-failed-to-read-it.patch
index 76414879fa..bdabcc0cc8 100644
--- a/Spigot-Server-Patches/0381-Show-blockstate-location-if-we-failed-to-read-it.patch
+++ b/Spigot-Server-Patches/0367-Show-blockstate-location-if-we-failed-to-read-it.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Show blockstate location if we failed to read it
 
 
 diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
-index f6401e2cde9d56547cee7f8d9e4b2a58764ee895..3e22d558ea09a6554e1bc71f8ca10277ec480705 100644
+index feeae1a9eb309ae4101783b191bb2bffe9aeb7d3..6e9eff2c29528b857cf758e9e45606c8a1c1cc8d 100644
 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
 +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
 @@ -19,6 +19,8 @@ public class CraftBlockEntityState<T extends TileEntity> extends CraftBlockState
diff --git a/Spigot-Server-Patches/0382-Synchronize-DataPaletteBlock-instead-of-ReentrantLoc.patch b/Spigot-Server-Patches/0368-Synchronize-DataPaletteBlock-instead-of-ReentrantLoc.patch
similarity index 86%
rename from Spigot-Server-Patches/0382-Synchronize-DataPaletteBlock-instead-of-ReentrantLoc.patch
rename to Spigot-Server-Patches/0368-Synchronize-DataPaletteBlock-instead-of-ReentrantLoc.patch
index fab2aaf139..f0a0d68f9e 100644
--- a/Spigot-Server-Patches/0382-Synchronize-DataPaletteBlock-instead-of-ReentrantLoc.patch
+++ b/Spigot-Server-Patches/0368-Synchronize-DataPaletteBlock-instead-of-ReentrantLoc.patch
@@ -13,10 +13,10 @@ contention situations.
 And this is extremely a low contention situation.
 
 diff --git a/src/main/java/net/minecraft/server/DataPaletteBlock.java b/src/main/java/net/minecraft/server/DataPaletteBlock.java
-index 3586fe065f21fbf1e71b602c372a690ef603f377..44310efd63b0a460e9dcdc1c8ad0abec78052061 100644
+index bcf249aab7d8223f6d9b597fcb20c1aa523ab862..4d397dc5a5127d5e9eb1ba5675239b022a1544c0 100644
 --- a/src/main/java/net/minecraft/server/DataPaletteBlock.java
 +++ b/src/main/java/net/minecraft/server/DataPaletteBlock.java
-@@ -24,7 +24,7 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
+@@ -23,7 +23,7 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
      private int i; private int getBitsPerObject() { return this.i; } // Paper - OBFHELPER
      private final ReentrantLock j = new ReentrantLock();
  
@@ -25,7 +25,7 @@ index 3586fe065f21fbf1e71b602c372a690ef603f377..44310efd63b0a460e9dcdc1c8ad0abec
          if (this.j.isLocked() && !this.j.isHeldByCurrentThread()) {
              String s = (String) Thread.getAllStackTraces().keySet().stream().filter(Objects::nonNull).map((thread) -> {
                  return thread.getName() + ": \n\tat " + (String) Arrays.stream(thread.getStackTrace()).map(Object::toString).collect(Collectors.joining("\n\tat "));
-@@ -36,11 +36,11 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
+@@ -35,11 +35,11 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
              throw new ReportedException(crashreport);
          } else {
              this.j.lock();
@@ -39,7 +39,7 @@ index 3586fe065f21fbf1e71b602c372a690ef603f377..44310efd63b0a460e9dcdc1c8ad0abec
      }
  
      public DataPaletteBlock(DataPalette<T> datapalette, RegistryBlockID<T> registryblockid, Function<NBTTagCompound, T> function, Function<T, NBTTagCompound> function1, T t0) {
-@@ -76,7 +76,7 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
+@@ -75,7 +75,7 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
      }
  
      @Override
@@ -48,7 +48,7 @@ index 3586fe065f21fbf1e71b602c372a690ef603f377..44310efd63b0a460e9dcdc1c8ad0abec
          this.a();
          DataBits databits = this.a;
          DataPalette<T> datapalette = this.h;
-@@ -99,18 +99,18 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
+@@ -98,18 +98,18 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
      }
  
      public T setBlock(int i, int j, int k, T t0) {
@@ -72,7 +72,7 @@ index 3586fe065f21fbf1e71b602c372a690ef603f377..44310efd63b0a460e9dcdc1c8ad0abec
          int j = this.h.a(t0);
          int k = this.a.a(i, j);
          T t1 = this.h.a(k);
-@@ -135,7 +135,7 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
+@@ -134,7 +134,7 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
      }
  
      public void writeDataPaletteBlock(PacketDataSerializer packetDataSerializer) { this.b(packetDataSerializer); } // Paper - OBFHELPER
@@ -81,16 +81,16 @@ index 3586fe065f21fbf1e71b602c372a690ef603f377..44310efd63b0a460e9dcdc1c8ad0abec
          this.a();
          packetdataserializer.writeByte(this.i);
          this.h.b(packetdataserializer);
-@@ -143,7 +143,7 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
+@@ -142,7 +142,7 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
          this.b();
      }
  
 -    public void a(NBTTagList nbttaglist, long[] along) {
 +    public synchronized void a(NBTTagList nbttaglist, long[] along) { // Paper - synchronize
          this.a();
-         int i = Math.max(4, MathHelper.d(nbttaglist.size()));
+         int i = Math.max(4, MathHelper.e(nbttaglist.size()));
  
-@@ -176,7 +176,7 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
+@@ -175,7 +175,7 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
          this.b();
      }
  
diff --git a/removed/1.16/0378-incremental-chunk-saving.patch b/Spigot-Server-Patches/0369-incremental-chunk-saving.patch
similarity index 85%
rename from removed/1.16/0378-incremental-chunk-saving.patch
rename to Spigot-Server-Patches/0369-incremental-chunk-saving.patch
index 6afaaf3e9d..761a36ea6b 100644
--- a/removed/1.16/0378-incremental-chunk-saving.patch
+++ b/Spigot-Server-Patches/0369-incremental-chunk-saving.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] incremental chunk saving
 
 
 diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-index 071e5e7f729d6c3ffb70506e7ef32eebee1e9118..48676152152faf7a7b9524ac37d8b4a8c32c4e2c 100644
+index 91c9a027dd7aef8253f3d707c95e4ed917d32580..b947b31fc3b135f116af97907d5301619cc33070 100644
 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-@@ -487,4 +487,19 @@ public class PaperWorldConfig {
+@@ -455,4 +455,19 @@ public class PaperWorldConfig {
          keepLoadedRange = (short) (getInt("keep-spawn-loaded-range", Math.min(spigotConfig.viewDistance, 10)) * 16);
          log( "Keep Spawn Loaded Range: " + (keepLoadedRange/16));
      }
@@ -29,10 +29,10 @@ index 071e5e7f729d6c3ffb70506e7ef32eebee1e9118..48676152152faf7a7b9524ac37d8b4a8
 +    }
  }
 diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
-index 962f425bbb7165740e77664dc543f976ef3d9c4a..dd3857bb6a002d8432ecbc6c6b52a39e5d55e6a6 100644
+index 141f2e8975b01fc2a5e7743955894f100c3062a2..8a316f732644886c476921c69838e9cb8b93a5b5 100644
 --- a/src/main/java/net/minecraft/server/Chunk.java
 +++ b/src/main/java/net/minecraft/server/Chunk.java
-@@ -42,7 +42,7 @@ public class Chunk implements IChunkAccess {
+@@ -43,7 +43,7 @@ public class Chunk implements IChunkAccess {
      private TickList<Block> o;
      private TickList<FluidType> p;
      private boolean q;
@@ -42,10 +42,10 @@ index 962f425bbb7165740e77664dc543f976ef3d9c4a..dd3857bb6a002d8432ecbc6c6b52a39e
      private long inhabitedTime;
      @Nullable
 diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
-index 8a8fb6acaabc5fc179a23ce3e23ddb54e1ee23a4..7b855ec2914a8a31ce0ade0f7ad085dd04f71478 100644
+index 726926f19c6725c1d935beec2f0f766d7466835e..f2ff1aa915c218bb1fc72467ccbd73ccf135c494 100644
 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
 +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
-@@ -525,6 +525,15 @@ public class ChunkProviderServer extends IChunkProvider {
+@@ -535,6 +535,15 @@ public class ChunkProviderServer extends IChunkProvider {
          } // Paper - Timings
      }
  
@@ -62,10 +62,10 @@ index 8a8fb6acaabc5fc179a23ce3e23ddb54e1ee23a4..7b855ec2914a8a31ce0ade0f7ad085dd
      public void close() throws IOException {
          // CraftBukkit start
 diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 257adcf4d5387fc18d5c48e0fa221f68539ad8f9..7920d24ab089fb8360ef74946cf7dc35cb7625eb 100644
+index 531031221346d2ed46bd25793c6c2b81029860d4..03ae25736b02ac02c01e76b5d2fbfd803585ebde 100644
 --- a/src/main/java/net/minecraft/server/MinecraftServer.java
 +++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -168,6 +168,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
+@@ -152,6 +152,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
      public static int currentTick = 0; // Paper - Further improve tick loop
      public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
      public int autosavePeriod;
@@ -73,7 +73,7 @@ index 257adcf4d5387fc18d5c48e0fa221f68539ad8f9..7920d24ab089fb8360ef74946cf7dc35
      public File bukkitDataPackFolder;
      public CommandDispatcher vanillaCommandDispatcher;
      private boolean forceTicks;
-@@ -1116,14 +1117,28 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
+@@ -1144,14 +1145,28 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
              this.serverPing.b().a(agameprofile);
          }
  
@@ -108,10 +108,10 @@ index 257adcf4d5387fc18d5c48e0fa221f68539ad8f9..7920d24ab089fb8360ef74946cf7dc35
          this.methodProfiler.enter("snooper");
          if (((DedicatedServer) this).getDedicatedServerProperties().snooperEnabled && !this.snooper.d() && this.ticks > 100) { // Spigot
 diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
-index 47e3e618c9e683e6975fb64e1094dc7078574dae..ed9ada49c7cc1131691bd6e005b2380274ef23e3 100644
+index 3b0d13d319fe1d274ab657c7c87e5a2db5c02c4f..3e1c1253ad5e2fa68fd8a0bac100c2e7536ea080 100644
 --- a/src/main/java/net/minecraft/server/PlayerChunk.java
 +++ b/src/main/java/net/minecraft/server/PlayerChunk.java
-@@ -41,6 +41,9 @@ public class PlayerChunk {
+@@ -40,6 +40,9 @@ public class PlayerChunk {
  
      private final PlayerChunkMap chunkMap; // Paper
  
@@ -175,10 +175,10 @@ index 47e3e618c9e683e6975fb64e1094dc7078574dae..ed9ada49c7cc1131691bd6e005b23802
      public void a(ProtoChunkExtension protochunkextension) {
          for (int i = 0; i < this.statusFutures.length(); ++i) {
 diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
-index 34f470779fa5d1cf9638431253024481236c073b..4f5b516144829a7ae11f21a56789ac7a1f256250 100644
+index 6dda11ffc022aa9bc7481506811a710a184f5e78..39d89d6209123ae2146ae292009cad44c25f490a 100644
 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
 +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
-@@ -332,6 +332,64 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -333,6 +333,64 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
  
      }
  
@@ -195,7 +195,7 @@ index 34f470779fa5d1cf9638431253024481236c073b..4f5b516144829a7ae11f21a56789ac7a
 +    protected void saveIncrementally() {
 +        int savedThisTick = 0;
 +        // optimized since we search far less chunks to hit ones that need to be saved
-+        List<PlayerChunk> reschedule = new ArrayList<>(this.world.paperConfig.maxAutoSaveChunksPerTick);
++        List<PlayerChunk> reschedule = new java.util.ArrayList<>(this.world.paperConfig.maxAutoSaveChunksPerTick);
 +        long currentTick = this.world.getTime();
 +        long maxSaveTime = currentTick - this.world.paperConfig.autoSavePeriod;
 +
@@ -243,7 +243,7 @@ index 34f470779fa5d1cf9638431253024481236c073b..4f5b516144829a7ae11f21a56789ac7a
      protected void save(boolean flag) {
          if (flag) {
              List<PlayerChunk> list = (List) this.visibleChunks.values().stream().filter(PlayerChunk::hasBeenLoaded).peek(PlayerChunk::m).collect(Collectors.toList());
-@@ -442,6 +500,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -443,6 +501,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
  
                          this.world.unloadChunk(chunk);
                      }
@@ -251,7 +251,7 @@ index 34f470779fa5d1cf9638431253024481236c073b..4f5b516144829a7ae11f21a56789ac7a
  
                      this.lightEngine.a(ichunkaccess.getPos());
                      this.lightEngine.queueUpdate();
-@@ -623,6 +682,8 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -635,6 +694,8 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
                      playerchunk.a(new ProtoChunkExtension(chunk));
                  }
  
@@ -261,15 +261,15 @@ index 34f470779fa5d1cf9638431253024481236c073b..4f5b516144829a7ae11f21a56789ac7a
                      return PlayerChunk.getChunkState(playerchunk.getTicketLevel());
                  });
 diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
-index ca0a23be27ee8174204867d463eb89a10931ff84..a0484d8062ecfb817cfd5b996915dc8f9a4eb2bd 100644
+index 58c6f9194dbd767650117594eee3ae0ba3a00dce..c2fffa60b3d020e4c70a2cabcf61ec36fb9edc65 100644
 --- a/src/main/java/net/minecraft/server/WorldServer.java
 +++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -817,11 +817,44 @@ public class WorldServer extends World {
-         return this.worldProvider.c();
+@@ -769,11 +769,43 @@ public class WorldServer extends World implements GeneratorAccessSeed {
+         return !this.server.a(this, blockposition, entityhuman) && this.getWorldBorder().a(blockposition);
      }
  
 +    // Paper start - derived from below
-+    public void saveIncrementally(boolean doFull) throws ExceptionWorldConflict {
++    public void saveIncrementally(boolean doFull) {
 +        ChunkProviderServer chunkproviderserver = this.getChunkProvider();
 +
 +        if (doFull) {
@@ -286,35 +286,34 @@ index ca0a23be27ee8174204867d463eb89a10931ff84..a0484d8062ecfb817cfd5b996915dc8f
 +            timings.worldSaveChunks.stopTiming(); // Paper
 +
 +
++            // Copied from save()
 +            // CraftBukkit start - moved from MinecraftServer.saveChunks
-+            // PAIL - rename
-+            if (doFull) {
++            if (doFull) { // Paper
 +                WorldServer worldserver1 = this;
-+                WorldData worlddata = worldserver1.getWorldData();
 +
-+                worldserver1.getWorldBorder().save(worlddata);
-+                worlddata.setCustomBossEvents(this.server.getBossBattleCustomData().save());
-+                worldserver1.getDataManager().saveWorldData(worlddata, this.server.getPlayerList().save());
-+                // CraftBukkit end
++                worldDataServer.a(worldserver1.getWorldBorder().t());
++                worldDataServer.setCustomBossEvents(this.server.getBossBattleCustomData().save());
++                convertable.a(this.server.f, this.worldDataServer, this.server.getPlayerList().save());
 +            }
++            // CraftBukkit end
 +        }
 +    }
 +    // Paper end
 +
-     public void save(@Nullable IProgressUpdate iprogressupdate, boolean flag, boolean flag1) throws ExceptionWorldConflict {
+     public void save(@Nullable IProgressUpdate iprogressupdate, boolean flag, boolean flag1) {
          ChunkProviderServer chunkproviderserver = this.getChunkProvider();
  
          if (!flag1) {
 -            org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit
-+            if (flag) org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit
++            if (flag) org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit // Paper
              try (co.aikar.timings.Timing ignored = timings.worldSave.startTiming()) { // Paper
              if (iprogressupdate != null) {
-                 iprogressupdate.a(new ChatMessage("menu.savingLevel", new Object[0]));
-@@ -848,6 +881,7 @@ public class WorldServer extends World {
+                 iprogressupdate.a(new ChatMessage("menu.savingLevel"));
+@@ -799,6 +831,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
          // CraftBukkit end
      }
  
-+    protected void saveData() throws ExceptionWorldConflict { this.m_(); } // Paper - OBFHELPER
-     protected void m_() throws ExceptionWorldConflict {
-         this.checkSession();
-         this.worldProvider.i();
++    private void saveData() { this.ag(); } // Paper - OBFHELPER
+     private void ag() {
+         if (this.dragonBattle != null) {
+             this.server.getSaveData().a(this.dragonBattle.a());
diff --git a/Spigot-Server-Patches/0384-Anti-Xray.patch b/Spigot-Server-Patches/0370-Anti-Xray.patch
similarity index 92%
rename from Spigot-Server-Patches/0384-Anti-Xray.patch
rename to Spigot-Server-Patches/0370-Anti-Xray.patch
index 47bca2c297..fc10c0f704 100644
--- a/Spigot-Server-Patches/0384-Anti-Xray.patch
+++ b/Spigot-Server-Patches/0370-Anti-Xray.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Anti-Xray
 
 
 diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-index 48676152152faf7a7b9524ac37d8b4a8c32c4e2c..f7c7c2871726e3a1673a693b9bd93910a28189b2 100644
+index b947b31fc3b135f116af97907d5301619cc33070..43925ed1e5c210399ba9fedb7bf890a6bd617e4a 100644
 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 @@ -1,7 +1,9 @@
@@ -18,7 +18,7 @@ index 48676152152faf7a7b9524ac37d8b4a8c32c4e2c..f7c7c2871726e3a1673a693b9bd93910
  import org.bukkit.Bukkit;
  import org.bukkit.configuration.file.YamlConfiguration;
  import org.spigotmc.SpigotWorldConfig;
-@@ -502,4 +504,31 @@ public class PaperWorldConfig {
+@@ -470,4 +472,31 @@ public class PaperWorldConfig {
      private void maxAutoSaveChunksPerTick() {
          maxAutoSaveChunksPerTick = getInt("max-auto-save-chunks-per-tick", 24);
      }
@@ -998,10 +998,10 @@ index 0000000000000000000000000000000000000000..2eff19f6aaa31245f80910c6fbb541e3
 +    }
 +}
 diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
-index dd3857bb6a002d8432ecbc6c6b52a39e5d55e6a6..08b3cbabc482d71862d90fcd9acd32d28f44a6e2 100644
+index 8a316f732644886c476921c69838e9cb8b93a5b5..8fa440b313b414a79118089b7481dee9f7ba69a8 100644
 --- a/src/main/java/net/minecraft/server/Chunk.java
 +++ b/src/main/java/net/minecraft/server/Chunk.java
-@@ -422,7 +422,7 @@ public class Chunk implements IChunkAccess {
+@@ -423,7 +423,7 @@ public class Chunk implements IChunkAccess {
                  return null;
              }
  
@@ -1011,10 +1011,10 @@ index dd3857bb6a002d8432ecbc6c6b52a39e5d55e6a6..08b3cbabc482d71862d90fcd9acd32d2
          }
  
 diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
-index 8e4b3e52cbc95e24b1d72aed9ec8c32b94a91561..d287ea55c550dbebbbc1d5f815296ae7ba6315e9 100644
+index 208a8ef3aaa4b33bfe2db2569a3588a332ab5686..be3c7a8697c540d03a143b9306311a184474857f 100644
 --- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
 +++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
-@@ -57,7 +57,7 @@ public class ChunkRegionLoader {
+@@ -58,7 +58,7 @@ public class ChunkRegionLoader {
              byte b0 = nbttagcompound2.getByte("Y");
  
              if (nbttagcompound2.hasKeyOfType("Palette", 9) && nbttagcompound2.hasKeyOfType("BlockStates", 12)) {
@@ -1023,7 +1023,7 @@ index 8e4b3e52cbc95e24b1d72aed9ec8c32b94a91561..d287ea55c550dbebbbc1d5f815296ae7
  
                  chunksection.getBlocks().a(nbttagcompound2.getList("Palette", 10), nbttagcompound2.getLongArray("BlockStates"));
                  chunksection.recalcBlockCounts();
-@@ -115,7 +115,7 @@ public class ChunkRegionLoader {
+@@ -116,7 +116,7 @@ public class ChunkRegionLoader {
                  loadEntities(nbttagcompound1, chunk);
              });
          } else {
@@ -1033,17 +1033,18 @@ index 8e4b3e52cbc95e24b1d72aed9ec8c32b94a91561..d287ea55c550dbebbbc1d5f815296ae7
              protochunk.a(biomestorage);
              object = protochunk;
 diff --git a/src/main/java/net/minecraft/server/ChunkSection.java b/src/main/java/net/minecraft/server/ChunkSection.java
-index e72d1386feb59e4a4c27466da96ffd29222bea18..c180d44bed91c86838d3be8c19be954b4412534e 100644
+index bd2290a4d4ec314b7afdb1f63d711f80803153cd..b168ad8021a5387e05023cd03ec1a69c8a86a233 100644
 --- a/src/main/java/net/minecraft/server/ChunkSection.java
 +++ b/src/main/java/net/minecraft/server/ChunkSection.java
-@@ -1,5 +1,6 @@
+@@ -1,6 +1,7 @@
  package net.minecraft.server;
  
+ import java.util.function.Predicate;
 +import com.destroystokyo.paper.antixray.ChunkPacketInfo; // Paper - Anti-Xray - Add chunk packet info
  import javax.annotation.Nullable;
  
  public class ChunkSection {
-@@ -11,16 +12,22 @@ public class ChunkSection {
+@@ -12,16 +13,22 @@ public class ChunkSection {
      private short e;
      final DataPaletteBlock<IBlockData> blockIds;
  
@@ -1065,12 +1066,12 @@ index e72d1386feb59e4a4c27466da96ffd29222bea18..c180d44bed91c86838d3be8c19be954b
          this.nonEmptyBlockCount = short0;
          this.tickingBlockCount = short1;
          this.e = short2;
--        this.blockIds = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, Block.REGISTRY_ID, GameProfileSerializer::d, GameProfileSerializer::a, Blocks.AIR.getBlockData());
-+        this.blockIds = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, Block.REGISTRY_ID, GameProfileSerializer::d, GameProfileSerializer::a, Blocks.AIR.getBlockData(), world == null ? null : world.chunkPacketBlockController.getPredefinedBlockData(world, chunk, this, initializeBlocks), initializeBlocks); // Paper - Anti-Xray - Add predefined block data
+-        this.blockIds = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, Block.REGISTRY_ID, GameProfileSerializer::c, GameProfileSerializer::a, Blocks.AIR.getBlockData());
++        this.blockIds = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, Block.REGISTRY_ID, GameProfileSerializer::c, GameProfileSerializer::a, Blocks.AIR.getBlockData(), world == null ? null : world.chunkPacketBlockController.getPredefinedBlockData(world, chunk, this, initializeBlocks), initializeBlocks); // Paper - Anti-Xray - Add predefined block data
      }
  
      public final IBlockData getType(int i, int j, int k) { // Paper
-@@ -132,10 +139,14 @@ public class ChunkSection {
+@@ -133,10 +140,14 @@ public class ChunkSection {
          return this.blockIds;
      }
  
@@ -1089,18 +1090,18 @@ index e72d1386feb59e4a4c27466da96ffd29222bea18..c180d44bed91c86838d3be8c19be954b
  
      public int j() {
 diff --git a/src/main/java/net/minecraft/server/DataPaletteBlock.java b/src/main/java/net/minecraft/server/DataPaletteBlock.java
-index 44310efd63b0a460e9dcdc1c8ad0abec78052061..a5ea0e34ec181ad9f98f9ee2f644c3ec1eb1cd3c 100644
+index 4d397dc5a5127d5e9eb1ba5675239b022a1544c0..900b551f6f76862443b09c1e76ad596eda5655f4 100644
 --- a/src/main/java/net/minecraft/server/DataPaletteBlock.java
 +++ b/src/main/java/net/minecraft/server/DataPaletteBlock.java
-@@ -3,6 +3,7 @@ package net.minecraft.server;
- import it.unimi.dsi.fastutil.ints.Int2IntMap;
+@@ -1,6 +1,7 @@
+ package net.minecraft.server;
+ 
  import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
- import it.unimi.dsi.fastutil.ints.Int2IntMap.Entry;
 +import com.destroystokyo.paper.antixray.ChunkPacketInfo; // Paper - Anti-Xray - Add chunk packet info
  import java.util.Arrays;
  import java.util.Objects;
  import java.util.concurrent.locks.ReentrantLock;
-@@ -19,6 +20,7 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
+@@ -18,6 +19,7 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
      private final Function<NBTTagCompound, T> e;
      private final Function<T, NBTTagCompound> f;
      private final T g;
@@ -1108,7 +1109,7 @@ index 44310efd63b0a460e9dcdc1c8ad0abec78052061..a5ea0e34ec181ad9f98f9ee2f644c3ec
      protected DataBits a; protected DataBits getDataBits() { return this.a; } // Paper - OBFHELPER
      private DataPalette<T> h; private DataPalette<T> getDataPalette() { return this.h; } // Paper - OBFHELPER
      private int i; private int getBitsPerObject() { return this.i; } // Paper - OBFHELPER
-@@ -43,14 +45,47 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
+@@ -42,14 +44,47 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
          //this.j.unlock(); // Paper - disable this
      }
  
@@ -1158,7 +1159,7 @@ index 44310efd63b0a460e9dcdc1c8ad0abec78052061..a5ea0e34ec181ad9f98f9ee2f644c3ec
  
      private static int b(int i, int j, int k) {
          return j << 8 | k << 4 | i;
-@@ -85,6 +120,7 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
+@@ -84,6 +119,7 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
  
          int j;
  
@@ -1166,7 +1167,7 @@ index 44310efd63b0a460e9dcdc1c8ad0abec78052061..a5ea0e34ec181ad9f98f9ee2f644c3ec
          for (j = 0; j < databits.b(); ++j) {
              T t1 = datapalette.a(databits.a(j));
  
-@@ -134,24 +170,38 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
+@@ -133,24 +169,38 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
          return t0 == null ? this.g : t0;
      }
  
@@ -1195,9 +1196,9 @@ index 44310efd63b0a460e9dcdc1c8ad0abec78052061..a5ea0e34ec181ad9f98f9ee2f644c3ec
  
      public synchronized void a(NBTTagList nbttaglist, long[] along) { // Paper - synchronize
          this.a();
--        int i = Math.max(4, MathHelper.d(nbttaglist.size()));
+-        int i = Math.max(4, MathHelper.e(nbttaglist.size()));
 +        // Paper - Anti-Xray - TODO: Should this.predefinedObjects.length just be added here (faster) or should the contents be compared to calculate the size (less RAM)?
-+        int i = Math.max(4, MathHelper.d(nbttaglist.size() + (this.predefinedObjects == null ? 0 : this.predefinedObjects.length))); // Paper - Anti-Xray - Calculate the size with predefined objects
++        int i = Math.max(4, MathHelper.e(nbttaglist.size() + (this.predefinedObjects == null ? 0 : this.predefinedObjects.length))); // Paper - Anti-Xray - Calculate the size with predefined objects
  
 -        if (i != this.i) {
 +        if (true || i != this.i) { // Paper - Anti-Xray - Not initialized yet
@@ -1210,7 +1211,7 @@ index 44310efd63b0a460e9dcdc1c8ad0abec78052061..a5ea0e34ec181ad9f98f9ee2f644c3ec
  
          if (this.h == this.b) {
 diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
-index 23223f3f45210cf23f44f9012f292db80df781a0..9b608d73869bd2907f705562c8378bc2f205767b 100644
+index 900f16efde29ace3f073b1cbc01df8bafc360a9a..8335d003369d94cbad17ec6fce76d6f9d016455a 100644
 --- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
 +++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
 @@ -1,5 +1,6 @@
@@ -1220,14 +1221,13 @@ index 23223f3f45210cf23f44f9012f292db80df781a0..9b608d73869bd2907f705562c8378bc2
  import com.google.common.collect.Lists;
  import io.netty.buffer.ByteBuf;
  import io.netty.buffer.Unpooled;
-@@ -20,8 +21,13 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
-     private byte[] f; private byte[] getData() { return this.f; } // Paper - OBFHELPER
-     private List<NBTTagCompound> g;
+@@ -22,7 +23,12 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
      private boolean h;
-+    private volatile boolean ready; // Paper - Async-Anti-Xray - Ready flag for the network manager
+     private boolean i;
  
 -    public PacketPlayOutMapChunk() {}
 +    // Paper start - Async-Anti-Xray - Set the ready flag to true
++    private volatile boolean ready; // Paper - Async-Anti-Xray - Ready flag for the network manager
 +    public PacketPlayOutMapChunk() {
 +        this.ready = true;
 +    }
@@ -1235,29 +1235,29 @@ index 23223f3f45210cf23f44f9012f292db80df781a0..9b608d73869bd2907f705562c8378bc2
  
      // Paper start
      private final java.util.List<Packet> extraPackets = new java.util.ArrayList<>();
-@@ -33,6 +39,7 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
+@@ -34,6 +40,7 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
      }
      // Paper end
-     public PacketPlayOutMapChunk(Chunk chunk, int i) {
+     public PacketPlayOutMapChunk(Chunk chunk, int i, boolean flag) {
 +        ChunkPacketInfo<IBlockData> chunkPacketInfo = chunk.world.chunkPacketBlockController.getChunkPacketInfo(this, chunk, i); // Paper - Anti-Xray - Add chunk packet info
          ChunkCoordIntPair chunkcoordintpair = chunk.getPos();
  
          this.a = chunkcoordintpair.x;
-@@ -55,7 +62,12 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
+@@ -57,7 +64,12 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
          }
  
          this.f = new byte[this.a(chunk, i)];
--        this.c = this.a(new PacketDataSerializer(this.j()), chunk, i);
+-        this.c = this.a(new PacketDataSerializer(this.k()), chunk, i);
 +        // Paper start - Anti-Xray - Add chunk packet info
 +        if (chunkPacketInfo != null) {
 +            chunkPacketInfo.setData(this.getData());
 +        }
-+        this.c = this.writeChunk(new PacketDataSerializer(this.j()), chunk, i, chunkPacketInfo);
++        this.c = this.writeChunk(new PacketDataSerializer(this.k()), chunk, i, chunkPacketInfo);
 +        // Paper end
          this.g = Lists.newArrayList();
          iterator = chunk.getTileEntities().entrySet().iterator();
          int totalTileEntities = 0; // Paper
-@@ -82,8 +94,19 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
+@@ -84,8 +96,19 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
                  this.g.add(nbttagcompound);
              }
          }
@@ -1277,7 +1277,7 @@ index 23223f3f45210cf23f44f9012f292db80df781a0..9b608d73869bd2907f705562c8378bc2
  
      @Override
      public void a(PacketDataSerializer packetdataserializer) throws IOException {
-@@ -149,8 +172,12 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
+@@ -153,8 +176,12 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
          return bytebuf;
      }
  
@@ -1292,7 +1292,7 @@ index 23223f3f45210cf23f44f9012f292db80df781a0..9b608d73869bd2907f705562c8378bc2
          int j = 0;
          ChunkSection[] achunksection = chunk.getSections();
          int k = 0;
-@@ -160,7 +187,7 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
+@@ -164,7 +191,7 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
  
              if (chunksection != Chunk.a && (!this.f() || !chunksection.c()) && (i & 1 << k) != 0) {
                  j |= 1 << k;
@@ -1302,23 +1302,23 @@ index 23223f3f45210cf23f44f9012f292db80df781a0..9b608d73869bd2907f705562c8378bc2
          }
  
 diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
-index 9171785ad54a26e95dea8b30509c1e49a5d9b22d..94b0c54d9d4d77b724087be55ffe6ce464a0bbe7 100644
+index 39d89d6209123ae2146ae292009cad44c25f490a..24f3e8a6866bb416f04aca342514fa5dd3d314c8 100644
 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
 +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
-@@ -604,7 +604,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
-                 PlayerChunkMap.LOGGER.error("Couldn't load chunk {}", chunkcoordintpair, exception);
+@@ -608,7 +608,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
              }
  
+             this.g(chunkcoordintpair);
 -            return Either.left(new ProtoChunk(chunkcoordintpair, ChunkConverter.a));
 +            return Either.left(new ProtoChunk(chunkcoordintpair, ChunkConverter.a, this.world)); // Paper - Anti-Xray - Add parameter
          }, this.executor);
      }
  
 diff --git a/src/main/java/net/minecraft/server/PlayerInteractManager.java b/src/main/java/net/minecraft/server/PlayerInteractManager.java
-index ed3f3362b640746649455f8dd2255ac2da03df7c..f11ef84df85c1e7ada9c62247b7882f19ae32089 100644
+index a32490f0eb754b065ee34c41465176db78b1625d..734855c1db3215d90b2743988f64af68aacb388e 100644
 --- a/src/main/java/net/minecraft/server/PlayerInteractManager.java
 +++ b/src/main/java/net/minecraft/server/PlayerInteractManager.java
-@@ -272,6 +272,8 @@ public class PlayerInteractManager {
+@@ -275,6 +275,8 @@ public class PlayerInteractManager {
              }
  
          }
@@ -1328,10 +1328,10 @@ index ed3f3362b640746649455f8dd2255ac2da03df7c..f11ef84df85c1e7ada9c62247b7882f1
  
      public void a(BlockPosition blockposition, PacketPlayInBlockDig.EnumPlayerDigType packetplayinblockdig_enumplayerdigtype, String s) {
 diff --git a/src/main/java/net/minecraft/server/ProtoChunk.java b/src/main/java/net/minecraft/server/ProtoChunk.java
-index 51a5b9cb36c4325df8d1434dcf28d27abefdfede..a78b240621e0407fff67b018224c39fc4f97f4e5 100644
+index 5114ce15ad1be23ca83b3a3fcaba10a34fcb1a6f..a60b414cdf70096e667e776ab4fd36e411f8ff12 100644
 --- a/src/main/java/net/minecraft/server/ProtoChunk.java
 +++ b/src/main/java/net/minecraft/server/ProtoChunk.java
-@@ -45,16 +45,24 @@ public class ProtoChunk implements IChunkAccess {
+@@ -46,16 +46,24 @@ public class ProtoChunk implements IChunkAccess {
      private long s;
      private final Map<WorldGenStage.Features, BitSet> t;
      private volatile boolean u;
@@ -1359,7 +1359,7 @@ index 51a5b9cb36c4325df8d1434dcf28d27abefdfede..a78b240621e0407fff67b018224c39fc
          this.f = Maps.newEnumMap(HeightMap.Type.class);
          this.g = ChunkStatus.EMPTY;
          this.h = Maps.newHashMap();
-@@ -209,7 +217,7 @@ public class ProtoChunk implements IChunkAccess {
+@@ -210,7 +218,7 @@ public class ProtoChunk implements IChunkAccess {
  
      public ChunkSection a(int i) {
          if (this.j[i] == Chunk.a) {
@@ -1369,7 +1369,7 @@ index 51a5b9cb36c4325df8d1434dcf28d27abefdfede..a78b240621e0407fff67b018224c39fc
  
          return this.j[i];
 diff --git a/src/main/java/net/minecraft/server/ProtoChunkExtension.java b/src/main/java/net/minecraft/server/ProtoChunkExtension.java
-index b740e82622e282bdf543a84a559af69dd5b8568c..6db6e74886943559e3582c350ffae54857ad8b84 100644
+index ee8df274d43be753887fb77e4203e2ee30ea02b3..9f91c02b444874e690eacb0cfa0c810168c8bb46 100644
 --- a/src/main/java/net/minecraft/server/ProtoChunkExtension.java
 +++ b/src/main/java/net/minecraft/server/ProtoChunkExtension.java
 @@ -11,7 +11,7 @@ public class ProtoChunkExtension extends ProtoChunk {
@@ -1382,7 +1382,7 @@ index b740e82622e282bdf543a84a559af69dd5b8568c..6db6e74886943559e3582c350ffae548
      }
  
 diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
-index 69db339c29c8f06026f05b0b5bb8019099af3fdf..479b87eaae67909768db1ba23854f05d2e61110c 100644
+index 8773b521db869f26525af7b4342955ade835b8ef..1434a6e2830aa455bb6ccfd2ce8c034b8d300414 100644
 --- a/src/main/java/net/minecraft/server/World.java
 +++ b/src/main/java/net/minecraft/server/World.java
 @@ -2,6 +2,8 @@ package net.minecraft.server;
@@ -1394,7 +1394,7 @@ index 69db339c29c8f06026f05b0b5bb8019099af3fdf..479b87eaae67909768db1ba23854f05d
  import com.destroystokyo.paper.event.server.ServerExceptionEvent;
  import com.destroystokyo.paper.exception.ServerInternalException;
  import com.google.common.base.MoreObjects;
-@@ -78,6 +80,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
+@@ -83,6 +85,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
      public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot
  
      public final com.destroystokyo.paper.PaperWorldConfig paperConfig; // Paper
@@ -1402,19 +1402,19 @@ index 69db339c29c8f06026f05b0b5bb8019099af3fdf..479b87eaae67909768db1ba23854f05d
  
      public final co.aikar.timings.WorldTimingsHandler timings; // Paper
      public static BlockPosition lastPhysicsProblem; // Spigot
-@@ -116,9 +119,10 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
-         return ((ChunkProviderServer) this.chunkProvider).getChunkAt(x, z, false);
+@@ -100,9 +103,10 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
+         return (CraftServer) Bukkit.getServer();
      }
  
--    protected World(WorldData worlddata, DimensionManager dimensionmanager, BiFunction<World, WorldProvider, IChunkProvider> bifunction, GameProfilerFiller gameprofilerfiller, boolean flag, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env) {
-+    protected World(WorldData worlddata, DimensionManager dimensionmanager, java.util.concurrent.Executor executor, BiFunction<World, WorldProvider, IChunkProvider> bifunction, GameProfilerFiller gameprofilerfiller, boolean flag, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env) { // Paper - executor
-         this.spigotConfig = new org.spigotmc.SpigotWorldConfig( worlddata.getName() ); // Spigot
-         this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig(worlddata.getName(), this.spigotConfig); // Paper
+-    protected World(WorldDataMutable worlddatamutable, ResourceKey<World> resourcekey, ResourceKey<DimensionManager> resourcekey1, DimensionManager dimensionmanager, Supplier<GameProfilerFiller> supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env) {
++    protected World(WorldDataMutable worlddatamutable, ResourceKey<World> resourcekey, ResourceKey<DimensionManager> resourcekey1, DimensionManager dimensionmanager, Supplier<GameProfilerFiller> supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env, java.util.concurrent.Executor executor) {
+         this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((WorldDataServer) worlddatamutable).getName()); // Spigot
+         this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig((((WorldDataServer)worlddatamutable).getName()), this.spigotConfig); // Paper
 +        this.chunkPacketBlockController = this.paperConfig.antiXray ? new ChunkPacketBlockControllerAntiXray(this.paperConfig, executor) : ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray
          this.generator = gen;
-         if (dimensionmanager.world == null) dimensionmanager.world = (WorldServer) this; // Paper
          this.world = new CraftWorld((WorldServer) this, gen, env);
-@@ -343,6 +347,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
+         this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit
+@@ -402,6 +406,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
              // CraftBukkit end
  
              IBlockData iblockdata1 = chunk.setType(blockposition, iblockdata, (i & 64) != 0, (i & 1024) == 0); // CraftBukkit custom NO_PLACE flag
@@ -1423,23 +1423,23 @@ index 69db339c29c8f06026f05b0b5bb8019099af3fdf..479b87eaae67909768db1ba23854f05d
              if (iblockdata1 == null) {
                  // CraftBukkit start - remove blockstate if failed (or the same)
 diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
-index a0484d8062ecfb817cfd5b996915dc8f9a4eb2bd..c019f0287711f8301b47a3c8f3740ff2aecb998b 100644
+index c2fffa60b3d020e4c70a2cabcf61ec36fb9edc65..789fd7d3d7679408d11a20cca6db96ecb86a067d 100644
 --- a/src/main/java/net/minecraft/server/WorldServer.java
 +++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -84,7 +84,7 @@ public class WorldServer extends World {
- 
-     // Add env and gen to constructor
-     public WorldServer(MinecraftServer minecraftserver, Executor executor, WorldNBTStorage worldnbtstorage, WorldData worlddata, DimensionManager dimensionmanager, GameProfilerFiller gameprofilerfiller, WorldLoadListener worldloadlistener, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
--        super(worlddata, dimensionmanager, (world, worldprovider) -> {
-+        super(worlddata, dimensionmanager, executor, (world, worldprovider) -> { // Paper - pass executor down
-             // CraftBukkit start
-             ChunkGenerator<?> chunkGenerator;
+@@ -96,7 +96,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
  
+     // Add env and gen to constructor, WorldData -> WorldDataServer
+     public WorldServer(MinecraftServer minecraftserver, Executor executor, Convertable.ConversionSession convertable_conversionsession, IWorldDataServer iworlddataserver, ResourceKey<World> resourcekey, ResourceKey<DimensionManager> resourcekey1, DimensionManager dimensionmanager, WorldLoadListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List<MobSpawner> list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
+-        super(iworlddataserver, resourcekey, resourcekey1, dimensionmanager, minecraftserver::getMethodProfiler, false, flag, i, gen, env);
++        super(iworlddataserver, resourcekey, resourcekey1, dimensionmanager, minecraftserver::getMethodProfiler, false, flag, i, gen, env, executor); // Paper pass executor
+         this.pvpMode = minecraftserver.getPVP();
+         convertable = convertable_conversionsession;
+         uuid = WorldUUID.getUUID(convertable_conversionsession.folder.toFile());
 diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
-index a53bb7295c5d510f2976ff3787d68857548e11cc..47f1b970b9ba39f9050ac34a5ac15593c25f8a70 100644
+index 2bd7d7959ce2845dbc09e198122e3574593dca58..cccb8f7b1c13811db7203282a5caad3da5b69a09 100644
 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
 +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
-@@ -38,7 +38,7 @@ public class CraftChunk implements Chunk {
+@@ -40,7 +40,7 @@ public class CraftChunk implements Chunk {
      private final WorldServer worldServer;
      private final int x;
      private final int z;
@@ -1448,12 +1448,12 @@ index a53bb7295c5d510f2976ff3787d68857548e11cc..47f1b970b9ba39f9050ac34a5ac15593
      private static final byte[] emptyLight = new byte[2048];
  
      public CraftChunk(net.minecraft.server.Chunk chunk) {
-@@ -260,7 +260,7 @@ public class CraftChunk implements Chunk {
+@@ -262,7 +262,7 @@ public class CraftChunk implements Chunk {
                  NBTTagCompound data = new NBTTagCompound();
                  cs[i].getBlocks().a(data, "Palette", "BlockStates");
  
--                DataPaletteBlock blockids = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, net.minecraft.server.Block.REGISTRY_ID, GameProfileSerializer::d, GameProfileSerializer::a, Blocks.AIR.getBlockData()); // TODO: snapshot whole ChunkSection
-+                DataPaletteBlock blockids = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, net.minecraft.server.Block.REGISTRY_ID, GameProfileSerializer::d, GameProfileSerializer::a, Blocks.AIR.getBlockData(), null, false); // TODO: snapshot whole ChunkSection // Paper - Anti-Xray - Add no predefined block data and don't initialize because it's done in the line below internally
+-                DataPaletteBlock blockids = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, net.minecraft.server.Block.REGISTRY_ID, GameProfileSerializer::c, GameProfileSerializer::a, Blocks.AIR.getBlockData()); // TODO: snapshot whole ChunkSection
++                DataPaletteBlock blockids = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, net.minecraft.server.Block.REGISTRY_ID, GameProfileSerializer::c, GameProfileSerializer::a, Blocks.AIR.getBlockData(), null, false); // TODO: snapshot whole ChunkSection // Paper - Anti-Xray - Add no predefined block data and don't initialize because it's done in the line below internally
                  blockids.a(data.getList("Palette", CraftMagicNumbers.NBT.TAG_COMPOUND), data.getLongArray("BlockStates"));
  
                  sectionBlockIDs[i] = blockids;
diff --git a/Spigot-Server-Patches/0385-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch b/Spigot-Server-Patches/0371-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch
similarity index 62%
rename from Spigot-Server-Patches/0385-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch
rename to Spigot-Server-Patches/0371-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch
index 29b06fd92f..134323c6db 100644
--- a/Spigot-Server-Patches/0385-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch
+++ b/Spigot-Server-Patches/0371-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch
@@ -17,10 +17,10 @@ This should fully solve all of the issues around it so that only natural
 influences natural spawns.
 
 diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-index f7c7c2871726e3a1673a693b9bd93910a28189b2..e8e61ce505cafccb3c8338bc5bbdf941f903bb27 100644
+index 43925ed1e5c210399ba9fedb7bf890a6bd617e4a..16727e92f591725c8f8cefb250b7ab8c64a19472 100644
 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-@@ -505,6 +505,16 @@ public class PaperWorldConfig {
+@@ -473,6 +473,16 @@ public class PaperWorldConfig {
          maxAutoSaveChunksPerTick = getInt("max-auto-save-chunks-per-tick", 24);
      }
  
@@ -37,21 +37,21 @@ index f7c7c2871726e3a1673a693b9bd93910a28189b2..e8e61ce505cafccb3c8338bc5bbdf941
      public boolean antiXray;
      public EngineMode engineMode;
      public int maxChunkSectionIndex;
-diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
-index c019f0287711f8301b47a3c8f3740ff2aecb998b..702dcc0387f85ebae8f1cfe9a8e79affef24281b 100644
---- a/src/main/java/net/minecraft/server/WorldServer.java
-+++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -960,6 +960,13 @@ public class WorldServer extends World {
+diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
+index 32d45b54fc4e67555a7f016ac72787a8ad4818f3..86e906361ed998ba94ff6e1cbe21860a88626c3b 100644
+--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
++++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
+@@ -48,6 +48,13 @@ public final class SpawnerCreature {
              EnumCreatureType enumcreaturetype = entity.getEntityType().e();
  
-             if (enumcreaturetype != EnumCreatureType.MISC && this.getChunkProvider().b(entity)) {
+             if (enumcreaturetype != EnumCreatureType.MISC) {
 +                // Paper start - Only count natural spawns
-+                if (!this.paperConfig.countAllMobsForSpawning &&
-+                    !(entity.spawnReason == CreatureSpawnEvent.SpawnReason.NATURAL ||
-+                        entity.spawnReason == CreatureSpawnEvent.SpawnReason.CHUNK_GEN)) {
++                if (!entity.world.paperConfig.countAllMobsForSpawning &&
++                    !(entity.spawnReason == org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL ||
++                        entity.spawnReason == org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CHUNK_GEN)) {
 +                    continue;
 +                }
 +                // Paper end
-                 object2intmap.mergeInt(enumcreaturetype, 1, Integer::sum);
-             }
-         }
+                 BlockPosition blockposition = entity.getChunkCoordinates();
+                 long j = ChunkCoordIntPair.pair(blockposition.getX() >> 4, blockposition.getZ() >> 4);
+ 
diff --git a/Spigot-Server-Patches/0386-Configurable-projectile-relative-velocity.patch b/Spigot-Server-Patches/0372-Configurable-projectile-relative-velocity.patch
similarity index 57%
rename from Spigot-Server-Patches/0386-Configurable-projectile-relative-velocity.patch
rename to Spigot-Server-Patches/0372-Configurable-projectile-relative-velocity.patch
index 73ac6c25e5..5f2519a433 100644
--- a/Spigot-Server-Patches/0386-Configurable-projectile-relative-velocity.patch
+++ b/Spigot-Server-Patches/0372-Configurable-projectile-relative-velocity.patch
@@ -25,10 +25,10 @@ P3) Solutions for 1) and especially 2) might not be future-proof, while this
 server-internal fix makes this change future-proof.
 
 diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-index e8e61ce505cafccb3c8338bc5bbdf941f903bb27..7101ef0912221bdb1c32d2cafbac5d9d53e7037d 100644
+index 16727e92f591725c8f8cefb250b7ab8c64a19472..a6e68b2ab8890d9d2a842ca0a6b565a1831fed6b 100644
 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-@@ -541,4 +541,9 @@ public class PaperWorldConfig {
+@@ -509,4 +509,9 @@ public class PaperWorldConfig {
          }
          log("Anti-Xray: " + (antiXray ? "enabled" : "disabled") + " / Engine Mode: " + engineMode.getDescription() + " / Up to " + ((maxChunkSectionIndex + 1) * 16) + " blocks / Update Radius: " + updateRadius);
      }
@@ -38,29 +38,16 @@ index e8e61ce505cafccb3c8338bc5bbdf941f903bb27..7101ef0912221bdb1c32d2cafbac5d9d
 +        disableRelativeProjectileVelocity = getBoolean("game-mechanics.disable-relative-projectile-velocity", false);
 +    }
  }
-diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java/net/minecraft/server/EntityArrow.java
-index 634e2bd3049d65bbef4ef12e2264049a6980fd71..9c97edf9c9e9a8cdf029264f6b563090142c686b 100644
---- a/src/main/java/net/minecraft/server/EntityArrow.java
-+++ b/src/main/java/net/minecraft/server/EntityArrow.java
-@@ -85,7 +85,7 @@ public abstract class EntityArrow extends Entity implements IProjectile {
-         float f7 = MathHelper.cos(f1 * 0.017453292F) * MathHelper.cos(f * 0.017453292F);
- 
-         this.shoot((double) f5, (double) f6, (double) f7, f3, f4);
--        this.setMot(this.getMot().add(entity.getMot().x, entity.onGround ? 0.0D : entity.getMot().y, entity.getMot().z));
-+        if (!entity.world.paperConfig.disableRelativeProjectileVelocity) this.setMot(this.getMot().add(entity.getMot().x, entity.onGround ? 0.0D : entity.getMot().y, entity.getMot().z)); // Paper - allow disabling relative velocity
-     }
- 
-     @Override
-diff --git a/src/main/java/net/minecraft/server/EntityProjectile.java b/src/main/java/net/minecraft/server/EntityProjectile.java
-index 6c091b68087d60b0b916871eb0ce06c6a2776bf8..f5c8074dcf1c6275bc13eb8f2b67c04ca547877b 100644
---- a/src/main/java/net/minecraft/server/EntityProjectile.java
-+++ b/src/main/java/net/minecraft/server/EntityProjectile.java
-@@ -43,7 +43,7 @@ public abstract class EntityProjectile extends Entity implements IProjectile {
+diff --git a/src/main/java/net/minecraft/server/IProjectile.java b/src/main/java/net/minecraft/server/IProjectile.java
+index ceecb0520a63d2eff5f4cadf45fa49f56eaea8dd..ecdc717b3013749ed2384a143d6b6eef07f6f642 100644
+--- a/src/main/java/net/minecraft/server/IProjectile.java
++++ b/src/main/java/net/minecraft/server/IProjectile.java
+@@ -114,7 +114,7 @@ public abstract class IProjectile extends Entity {
          this.shoot((double) f5, (double) f6, (double) f7, f3, f4);
          Vec3D vec3d = entity.getMot();
  
--        this.setMot(this.getMot().add(vec3d.x, entity.onGround ? 0.0D : vec3d.y, vec3d.z));
-+        if (!entity.world.paperConfig.disableRelativeProjectileVelocity) this.setMot(this.getMot().add(vec3d.x, entity.onGround ? 0.0D : vec3d.y, vec3d.z)); // Paper - allow disabling relative velocity
+-        this.setMot(this.getMot().add(vec3d.x, entity.isOnGround() ? 0.0D : vec3d.y, vec3d.z));
++        if (!entity.world.paperConfig.disableRelativeProjectileVelocity) this.setMot(this.getMot().add(vec3d.x, entity.isOnGround() ? 0.0D : vec3d.y, vec3d.z)); // Paper - allow disabling relative velocity
      }
  
-     @Override
+     protected void a(MovingObjectPosition movingobjectposition) {
diff --git a/Spigot-Server-Patches/0387-Mark-entities-as-being-ticked-when-notifying-navigat.patch b/Spigot-Server-Patches/0373-Mark-entities-as-being-ticked-when-notifying-navigat.patch
similarity index 76%
rename from Spigot-Server-Patches/0387-Mark-entities-as-being-ticked-when-notifying-navigat.patch
rename to Spigot-Server-Patches/0373-Mark-entities-as-being-ticked-when-notifying-navigat.patch
index 372f4a9a83..cee98a020d 100644
--- a/Spigot-Server-Patches/0387-Mark-entities-as-being-ticked-when-notifying-navigat.patch
+++ b/Spigot-Server-Patches/0373-Mark-entities-as-being-ticked-when-notifying-navigat.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Mark entities as being ticked when notifying navigation
 
 
 diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
-index 702dcc0387f85ebae8f1cfe9a8e79affef24281b..83585f3ba7ef9e72f3702079a82f62c8b17e4077 100644
+index 789fd7d3d7679408d11a20cca6db96ecb86a067d..2738d61709a956e83ab7b4e05063a99bcbb7e01b 100644
 --- a/src/main/java/net/minecraft/server/WorldServer.java
 +++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -1401,6 +1401,7 @@ public class WorldServer extends World {
+@@ -1320,6 +1320,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
          VoxelShape voxelshape1 = iblockdata1.getCollisionShape(this, blockposition);
  
          if (VoxelShapes.c(voxelshape, voxelshape1, OperatorBoolean.NOT_SAME)) {
@@ -16,7 +16,7 @@ index 702dcc0387f85ebae8f1cfe9a8e79affef24281b..83585f3ba7ef9e72f3702079a82f62c8
              Iterator iterator = this.navigators.iterator();
  
              while (iterator.hasNext()) {
-@@ -1411,6 +1412,7 @@ public class WorldServer extends World {
+@@ -1330,6 +1331,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
                  }
              }
  
diff --git a/Spigot-Server-Patches/0388-offset-item-frame-ticking.patch b/Spigot-Server-Patches/0374-offset-item-frame-ticking.patch
similarity index 89%
rename from Spigot-Server-Patches/0388-offset-item-frame-ticking.patch
rename to Spigot-Server-Patches/0374-offset-item-frame-ticking.patch
index 7e53a08ee4..f3cc8ac572 100644
--- a/Spigot-Server-Patches/0388-offset-item-frame-ticking.patch
+++ b/Spigot-Server-Patches/0374-offset-item-frame-ticking.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] offset item frame ticking
 
 
 diff --git a/src/main/java/net/minecraft/server/EntityHanging.java b/src/main/java/net/minecraft/server/EntityHanging.java
-index 21dbc9b2ab7c6edf2691f5c4f9e466ba33ba7580..ef9c4717c31c9fae4d9ac2e357ce22dab8fa3cce 100644
+index 3dc1f234a389b1badf0b189ba27708c787ce37af..06cf11af972f7762de43dc1df18a431a62787111 100644
 --- a/src/main/java/net/minecraft/server/EntityHanging.java
 +++ b/src/main/java/net/minecraft/server/EntityHanging.java
 @@ -15,7 +15,7 @@ public abstract class EntityHanging extends Entity {
diff --git a/Spigot-Server-Patches/0389-Avoid-hopper-searches-if-there-are-no-items.patch b/Spigot-Server-Patches/0375-Avoid-hopper-searches-if-there-are-no-items.patch
similarity index 91%
rename from Spigot-Server-Patches/0389-Avoid-hopper-searches-if-there-are-no-items.patch
rename to Spigot-Server-Patches/0375-Avoid-hopper-searches-if-there-are-no-items.patch
index 9e05dd85f9..c514cf39dc 100644
--- a/Spigot-Server-Patches/0389-Avoid-hopper-searches-if-there-are-no-items.patch
+++ b/Spigot-Server-Patches/0375-Avoid-hopper-searches-if-there-are-no-items.patch
@@ -14,10 +14,10 @@ And since minecart hoppers are used _very_ rarely near we can avoid alot of sear
 Combined, this adds up a lot.
 
 diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
-index 08b3cbabc482d71862d90fcd9acd32d28f44a6e2..af9a195f6d0f966133577d00d30e8b4ad812aaeb 100644
+index 8fa440b313b414a79118089b7481dee9f7ba69a8..b2713942d8cf5bedd91ac63df18a336743c72da5 100644
 --- a/src/main/java/net/minecraft/server/Chunk.java
 +++ b/src/main/java/net/minecraft/server/Chunk.java
-@@ -84,6 +84,10 @@ public class Chunk implements IChunkAccess {
+@@ -85,6 +85,10 @@ public class Chunk implements IChunkAccess {
              return removed;
          }
      }
@@ -28,7 +28,7 @@ index 08b3cbabc482d71862d90fcd9acd32d28f44a6e2..af9a195f6d0f966133577d00d30e8b4a
      // Paper end
  
      public Chunk(World world, ChunkCoordIntPair chunkcoordintpair, BiomeStorage biomestorage, ChunkConverter chunkconverter, TickList<Block> ticklist, TickList<FluidType> ticklist1, long i, @Nullable ChunkSection[] achunksection, @Nullable Consumer<Chunk> consumer) {
-@@ -538,6 +542,13 @@ public class Chunk implements IChunkAccess {
+@@ -539,6 +543,13 @@ public class Chunk implements IChunkAccess {
          entity.chunkZ = this.loc.z;
          this.entities.add(entity); // Paper - per chunk entity list
          this.entitySlices[k].add(entity);
@@ -42,7 +42,7 @@ index 08b3cbabc482d71862d90fcd9acd32d28f44a6e2..af9a195f6d0f966133577d00d30e8b4a
          entity.entitySlice = this.entitySlices[k]; // Paper
          this.markDirty(); // Paper
      }
-@@ -570,6 +581,11 @@ public class Chunk implements IChunkAccess {
+@@ -571,6 +582,11 @@ public class Chunk implements IChunkAccess {
          if (!this.entitySlices[i].remove(entity)) {
              return;
          }
@@ -54,7 +54,7 @@ index 08b3cbabc482d71862d90fcd9acd32d28f44a6e2..af9a195f6d0f966133577d00d30e8b4a
          entityCounts.decrement(entity.getMinecraftKeyString());
          this.markDirty(); // Paper
          // Paper end
-@@ -853,6 +869,14 @@ public class Chunk implements IChunkAccess {
+@@ -854,6 +870,14 @@ public class Chunk implements IChunkAccess {
          for (int k = i; k <= j; ++k) {
              Iterator iterator = this.entitySlices[k].iterator(); // Spigot
  
@@ -69,7 +69,7 @@ index 08b3cbabc482d71862d90fcd9acd32d28f44a6e2..af9a195f6d0f966133577d00d30e8b4a
              while (iterator.hasNext()) {
                  T entity = (T) iterator.next(); // CraftBukkit - decompile error
                  if (entity.shouldBeRemoved) continue; // Paper
-@@ -872,9 +896,29 @@ public class Chunk implements IChunkAccess {
+@@ -873,9 +897,29 @@ public class Chunk implements IChunkAccess {
          i = MathHelper.clamp(i, 0, this.entitySlices.length - 1);
          j = MathHelper.clamp(j, 0, this.entitySlices.length - 1);
  
@@ -100,7 +100,7 @@ index 08b3cbabc482d71862d90fcd9acd32d28f44a6e2..af9a195f6d0f966133577d00d30e8b4a
                  T t0 = (T) iterator.next(); // CraftBukkit - decompile error
                  if (t0.shouldBeRemoved) continue; // Paper
 diff --git a/src/main/java/net/minecraft/server/IEntitySelector.java b/src/main/java/net/minecraft/server/IEntitySelector.java
-index 498f381099b2cf9460104688e12afc5f586e057a..a2d1ef3602a1c63d106d10140e18dfdb1d490805 100644
+index 28f10ab2e427872c04bc97ebc392cf6d58854cf9..57bc56cffff87d9b1774cec455af8d1651fb882c 100644
 --- a/src/main/java/net/minecraft/server/IEntitySelector.java
 +++ b/src/main/java/net/minecraft/server/IEntitySelector.java
 @@ -11,6 +11,7 @@ public final class IEntitySelector {
diff --git a/Spigot-Server-Patches/0390-Asynchronous-chunk-IO-and-loading.patch b/Spigot-Server-Patches/0376-Asynchronous-chunk-IO-and-loading.patch
similarity index 92%
rename from Spigot-Server-Patches/0390-Asynchronous-chunk-IO-and-loading.patch
rename to Spigot-Server-Patches/0376-Asynchronous-chunk-IO-and-loading.patch
index 1f4ccdf6f6..4b451a71d4 100644
--- a/Spigot-Server-Patches/0390-Asynchronous-chunk-IO-and-loading.patch
+++ b/Spigot-Server-Patches/0376-Asynchronous-chunk-IO-and-loading.patch
@@ -199,7 +199,7 @@ index af810987846efcd2bffbd23c31481b2d31c168dd..331493a172f58e71b464d635efdba461
                  doChunkInfo(sender, args);
                  break;
 diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
-index dbd14399707cdd43f98af40191be8ff3e76edf43..74295466e53db06d0d019a13768f3575ac61d699 100644
+index 1aa7d0cfaf5697daeeb98e237387f27e76bca16f..8c2202fbc1c38e6cd19005d010e365ae14233f51 100644
 --- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
 +++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
 @@ -1,5 +1,6 @@
@@ -209,7 +209,7 @@ index dbd14399707cdd43f98af40191be8ff3e76edf43..74295466e53db06d0d019a13768f3575
  import com.google.common.base.Strings;
  import com.google.common.base.Throwables;
  
-@@ -367,4 +368,54 @@ public class PaperConfig {
+@@ -346,4 +347,54 @@ public class PaperConfig {
          maxBookPageSize = getInt("settings.book-size.page-max", maxBookPageSize);
          maxBookTotalSizeMultiplier = getDouble("settings.book-size.total-multiplier", maxBookTotalSizeMultiplier);
      }
@@ -2309,10 +2309,10 @@ index 0000000000000000000000000000000000000000..b5c2e1f4a2b5fdcaa6bb01f4b3b6847c
 +
 +}
 diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
-index d8647f272bdb29518b1a7faafa6fbcb53ffe1163..981cf581c7504c38120d48c06b6351952fab43c0 100644
+index f2ff1aa915c218bb1fc72467ccbd73ccf135c494..edd901bb53385fa3d189a0057d57f98bf8b7115c 100644
 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
 +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
-@@ -309,11 +309,138 @@ public class ChunkProviderServer extends IChunkProvider {
+@@ -310,11 +310,138 @@ public class ChunkProviderServer extends IChunkProvider {
          return playerChunk.getAvailableChunkNow();
  
      }
@@ -2451,7 +2451,7 @@ index d8647f272bdb29518b1a7faafa6fbcb53ffe1163..981cf581c7504c38120d48c06b635195
          if (Thread.currentThread() != this.serverThread) {
              return (IChunkAccess) CompletableFuture.supplyAsync(() -> {
                  return this.getChunkAt(i, j, chunkstatus, flag);
-@@ -336,11 +463,16 @@ public class ChunkProviderServer extends IChunkProvider {
+@@ -337,11 +464,16 @@ public class ChunkProviderServer extends IChunkProvider {
              }
  
              gameprofilerfiller.c("getChunkCacheMiss");
@@ -2469,7 +2469,7 @@ index d8647f272bdb29518b1a7faafa6fbcb53ffe1163..981cf581c7504c38120d48c06b635195
                  this.world.timings.syncChunkLoad.stopTiming(); // Paper
              } // Paper
              ichunkaccess = (IChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> {
-@@ -406,6 +538,11 @@ public class ChunkProviderServer extends IChunkProvider {
+@@ -407,6 +539,11 @@ public class ChunkProviderServer extends IChunkProvider {
      }
  
      private CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> getChunkFutureMainThread(int i, int j, ChunkStatus chunkstatus, boolean flag) {
@@ -2481,7 +2481,7 @@ index d8647f272bdb29518b1a7faafa6fbcb53ffe1163..981cf581c7504c38120d48c06b635195
          ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j);
          long k = chunkcoordintpair.pair();
          int l = 33 + ChunkStatus.a(chunkstatus);
-@@ -845,11 +982,12 @@ public class ChunkProviderServer extends IChunkProvider {
+@@ -806,11 +943,12 @@ public class ChunkProviderServer extends IChunkProvider {
          protected boolean executeNext() {
          // CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task
          try {
@@ -2496,7 +2496,7 @@ index d8647f272bdb29518b1a7faafa6fbcb53ffe1163..981cf581c7504c38120d48c06b635195
          } finally {
              playerChunkMap.callbackExecutor.run();
 diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
-index d287ea55c550dbebbbc1d5f815296ae7ba6315e9..34cd09a503bfe617bd50808927bae0ccf43e53fc 100644
+index be3c7a8697c540d03a143b9306311a184474857f..4d6e8f987233ca6c5f53d004031c022bb2d43e1e 100644
 --- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
 +++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
 @@ -6,6 +6,7 @@ import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
@@ -2507,7 +2507,7 @@ index d287ea55c550dbebbbc1d5f815296ae7ba6315e9..34cd09a503bfe617bd50808927bae0cc
  import java.util.Arrays;
  import java.util.BitSet;
  import java.util.EnumSet;
-@@ -22,7 +23,29 @@ public class ChunkRegionLoader {
+@@ -23,7 +24,29 @@ public class ChunkRegionLoader {
  
      private static final Logger LOGGER = LogManager.getLogger();
  
@@ -2534,10 +2534,10 @@ index d287ea55c550dbebbbc1d5f815296ae7ba6315e9..34cd09a503bfe617bd50808927bae0cc
 +    public static InProgressChunkHolder loadChunk(WorldServer worldserver, DefinedStructureManager definedstructuremanager, VillagePlace villageplace, ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound, boolean distinguish) {
 +        ArrayDeque<Runnable> tasksToExecuteOnMain = new ArrayDeque<>();
 +        // Paper end
-         ChunkGenerator<?> chunkgenerator = worldserver.getChunkProvider().getChunkGenerator();
+         ChunkGenerator chunkgenerator = worldserver.getChunkProvider().getChunkGenerator();
          WorldChunkManager worldchunkmanager = chunkgenerator.getWorldChunkManager();
          NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Level");
-@@ -49,7 +72,9 @@ public class ChunkRegionLoader {
+@@ -50,7 +73,9 @@ public class ChunkRegionLoader {
          LightEngine lightengine = chunkproviderserver.getLightEngine();
  
          if (flag) {
@@ -2548,7 +2548,7 @@ index d287ea55c550dbebbbc1d5f815296ae7ba6315e9..34cd09a503bfe617bd50808927bae0cc
          }
  
          for (int i = 0; i < nbttaglist.size(); ++i) {
-@@ -65,16 +90,30 @@ public class ChunkRegionLoader {
+@@ -66,16 +91,28 @@ public class ChunkRegionLoader {
                      achunksection[b0] = chunksection;
                  }
  
@@ -2560,29 +2560,27 @@ index d287ea55c550dbebbbc1d5f815296ae7ba6315e9..34cd09a503bfe617bd50808927bae0cc
  
              if (flag) {
                  if (nbttagcompound2.hasKeyOfType("BlockLight", 7)) {
--                    lightengine.a(EnumSkyBlock.BLOCK, SectionPosition.a(chunkcoordintpair, b0), new NibbleArray(nbttagcompound2.getByteArray("BlockLight")));
+-                    lightengine.a(EnumSkyBlock.BLOCK, SectionPosition.a(chunkcoordintpair, b0), new NibbleArray(nbttagcompound2.getByteArray("BlockLight")), true);
 +                    // Paper start - delay this task since we're executing off-main
 +                    NibbleArray blockLight = new NibbleArray(nbttagcompound2.getByteArray("BlockLight"));
-+                    // Note: We move the block light nibble array creation here for perf & in case the compound is modified
 +                    tasksToExecuteOnMain.add(() -> {
-+                        lightengine.a(EnumSkyBlock.BLOCK, SectionPosition.a(chunkcoordintpair, b0), blockLight);
++                        lightengine.a(EnumSkyBlock.BLOCK, SectionPosition.a(chunkcoordintpair, b0), blockLight, true);
 +                    });
-+                    // Paper end
++                    // Paper end - delay this task since we're executing off-main
                  }
  
                  if (flag2 && nbttagcompound2.hasKeyOfType("SkyLight", 7)) {
--                    lightengine.a(EnumSkyBlock.SKY, SectionPosition.a(chunkcoordintpair, b0), new NibbleArray(nbttagcompound2.getByteArray("SkyLight")));
+-                    lightengine.a(EnumSkyBlock.SKY, SectionPosition.a(chunkcoordintpair, b0), new NibbleArray(nbttagcompound2.getByteArray("SkyLight")), true);
 +                    // Paper start - delay this task since we're executing off-main
 +                    NibbleArray skyLight = new NibbleArray(nbttagcompound2.getByteArray("SkyLight"));
-+                    // Note: We move the block light nibble array creation here for perf & in case the compound is modified
 +                    tasksToExecuteOnMain.add(() -> {
-+                        lightengine.a(EnumSkyBlock.SKY, SectionPosition.a(chunkcoordintpair, b0), skyLight);
++                        lightengine.a(EnumSkyBlock.SKY, SectionPosition.a(chunkcoordintpair, b0), skyLight, true);
 +                    });
-+                    // Paper end
++                    // Paper end - delay this task since we're executing off-main
                  }
              }
          }
-@@ -177,7 +216,7 @@ public class ChunkRegionLoader {
+@@ -178,7 +215,7 @@ public class ChunkRegionLoader {
          }
  
          if (chunkstatus_type == ChunkStatus.Type.LEVELCHUNK) {
@@ -2591,15 +2589,15 @@ index d287ea55c550dbebbbc1d5f815296ae7ba6315e9..34cd09a503bfe617bd50808927bae0cc
          } else {
              ProtoChunk protochunk1 = (ProtoChunk) object;
  
-@@ -216,11 +255,83 @@ public class ChunkRegionLoader {
+@@ -217,11 +254,83 @@ public class ChunkRegionLoader {
                  protochunk1.a(worldgenstage_features, BitSet.valueOf(nbttagcompound5.getByteArray(s1)));
              }
  
 -            return protochunk1;
 +            return new InProgressChunkHolder(protochunk1, tasksToExecuteOnMain); // Paper - Async chunk loading
-         }
-     }
- 
++        }
++    }
++
 +    // Paper start - async chunk save for unload
 +    public static final class AsyncSaveData {
 +        public final NibbleArray[] blockLight; // null or size of 17 (for indices -1 through 15)
@@ -2617,9 +2615,9 @@ index d287ea55c550dbebbbc1d5f815296ae7ba6315e9..34cd09a503bfe617bd50808927bae0cc
 +            this.blockTickList = blockTickList;
 +            this.fluidTickList = fluidTickList;
 +            this.worldTime = worldTime;
-+        }
-+    }
-+
+         }
+     }
+ 
 +    // must be called sync
 +    public static AsyncSaveData getAsyncSaveData(WorldServer world, IChunkAccess chunk) {
 +        org.spigotmc.AsyncCatcher.catchOp("preparation of chunk data for async save");
@@ -2676,7 +2674,7 @@ index d287ea55c550dbebbbc1d5f815296ae7ba6315e9..34cd09a503bfe617bd50808927bae0cc
          ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos();
          NBTTagCompound nbttagcompound = new NBTTagCompound();
          NBTTagCompound nbttagcompound1 = new NBTTagCompound();
-@@ -229,7 +340,7 @@ public class ChunkRegionLoader {
+@@ -230,7 +339,7 @@ public class ChunkRegionLoader {
          nbttagcompound.set("Level", nbttagcompound1);
          nbttagcompound1.setInt("xPos", chunkcoordintpair.x);
          nbttagcompound1.setInt("zPos", chunkcoordintpair.z);
@@ -2685,7 +2683,7 @@ index d287ea55c550dbebbbc1d5f815296ae7ba6315e9..34cd09a503bfe617bd50808927bae0cc
          nbttagcompound1.setLong("InhabitedTime", ichunkaccess.getInhabitedTime());
          nbttagcompound1.setString("Status", ichunkaccess.getChunkStatus().d());
          ChunkConverter chunkconverter = ichunkaccess.p();
-@@ -245,14 +356,22 @@ public class ChunkRegionLoader {
+@@ -246,14 +355,22 @@ public class ChunkRegionLoader {
  
          NBTTagCompound nbttagcompound2;
  
@@ -2712,7 +2710,7 @@ index d287ea55c550dbebbbc1d5f815296ae7ba6315e9..34cd09a503bfe617bd50808927bae0cc
              if (chunksection != Chunk.a || nibblearray != null || nibblearray1 != null) {
                  nbttagcompound2 = new NBTTagCompound();
                  nbttagcompound2.setByte("Y", (byte) (i & 255));
-@@ -313,7 +432,7 @@ public class ChunkRegionLoader {
+@@ -314,7 +431,7 @@ public class ChunkRegionLoader {
                      Entity entity = (Entity) iterator1.next();
                      NBTTagCompound nbttagcompound4 = new NBTTagCompound();
                      // Paper start
@@ -2721,7 +2719,7 @@ index d287ea55c550dbebbbc1d5f815296ae7ba6315e9..34cd09a503bfe617bd50808927bae0cc
                          toUpdate.add(entity);
                          continue;
                      }
-@@ -353,24 +472,32 @@ public class ChunkRegionLoader {
+@@ -357,24 +474,32 @@ public class ChunkRegionLoader {
          }
  
          nbttagcompound1.set("Entities", nbttaglist2);
@@ -2731,8 +2729,7 @@ index d287ea55c550dbebbbc1d5f815296ae7ba6315e9..34cd09a503bfe617bd50808927bae0cc
          if (ticklist instanceof ProtoChunkTickList) {
              nbttagcompound1.set("ToBeTicked", ((ProtoChunkTickList) ticklist).b());
          } else if (ticklist instanceof TickListChunk) {
--            nbttagcompound1.set("TileTicks", ((TickListChunk) ticklist).a(worldserver.getTime()));
-+            nbttagcompound1.set("TileTicks", ((TickListChunk) ticklist).a(asyncsavedata != null ? asyncsavedata.worldTime : worldserver.getTime())); // Paper - async chunk unloading
+             nbttagcompound1.set("TileTicks", ((TickListChunk) ticklist).b());
 +            // Paper start - async chunk save for unload
 +        } else if (asyncsavedata != null) {
 +            nbttagcompound1.set("TileTicks", asyncsavedata.blockTickList);
@@ -2748,23 +2745,22 @@ index d287ea55c550dbebbbc1d5f815296ae7ba6315e9..34cd09a503bfe617bd50808927bae0cc
          if (ticklist1 instanceof ProtoChunkTickList) {
              nbttagcompound1.set("LiquidsToBeTicked", ((ProtoChunkTickList) ticklist1).b());
          } else if (ticklist1 instanceof TickListChunk) {
--            nbttagcompound1.set("LiquidTicks", ((TickListChunk) ticklist1).a(worldserver.getTime()));
-+            nbttagcompound1.set("LiquidTicks", ((TickListChunk) ticklist1).a(asyncsavedata != null ? asyncsavedata.worldTime : worldserver.getTime())); // Paper - async chunk unloading
+             nbttagcompound1.set("LiquidTicks", ((TickListChunk) ticklist1).b());
 +            // Paper start - async chunk save for unload
 +        } else if (asyncsavedata != null) {
 +            nbttagcompound1.set("LiquidTicks", asyncsavedata.fluidTickList);
 +            // Paper end
          } else {
 -            nbttagcompound1.set("LiquidTicks", worldserver.getFluidTickList().a(chunkcoordintpair));
-+            nbttagcompound1.set("LiquidTicks", worldserver.getFluidTickList().a(chunkcoordintpair));  // Paper - diff on method change (see getAsyncSaveData)
++            nbttagcompound1.set("LiquidTicks", worldserver.getFluidTickList().a(chunkcoordintpair)); // Paper - diff on method change (see getAsyncSaveData)
          }
  
          nbttagcompound1.set("PostProcessing", a(ichunkaccess.l()));
 diff --git a/src/main/java/net/minecraft/server/ChunkStatus.java b/src/main/java/net/minecraft/server/ChunkStatus.java
-index 134a4f0b7d254b5dd8ca26a9c5874532826978c4..40ce30cdc2a07b7a9c2d1f33070e87259f27cd27 100644
+index 3ef584605d408c268806e74b95e9223ca4ffe0d9..92d55591a994ab618c9641d77850e644ea093734 100644
 --- a/src/main/java/net/minecraft/server/ChunkStatus.java
 +++ b/src/main/java/net/minecraft/server/ChunkStatus.java
-@@ -153,6 +153,7 @@ public class ChunkStatus {
+@@ -159,6 +159,7 @@ public class ChunkStatus {
          return ChunkStatus.q.size();
      }
  
@@ -2772,7 +2768,7 @@ index 134a4f0b7d254b5dd8ca26a9c5874532826978c4..40ce30cdc2a07b7a9c2d1f33070e8725
      public static int a(ChunkStatus chunkstatus) {
          return ChunkStatus.r.getInt(chunkstatus.c());
      }
-@@ -168,6 +169,7 @@ public class ChunkStatus {
+@@ -174,6 +175,7 @@ public class ChunkStatus {
          this.t = chunkstatus == null ? 0 : chunkstatus.c() + 1;
      }
  
@@ -2780,7 +2776,7 @@ index 134a4f0b7d254b5dd8ca26a9c5874532826978c4..40ce30cdc2a07b7a9c2d1f33070e8725
      public int c() {
          return this.t;
      }
-@@ -189,6 +191,7 @@ public class ChunkStatus {
+@@ -195,6 +197,7 @@ public class ChunkStatus {
          return this.w.doWork(this, worldserver, definedstructuremanager, lightenginethreaded, function, ichunkaccess);
      }
  
@@ -2788,7 +2784,7 @@ index 134a4f0b7d254b5dd8ca26a9c5874532826978c4..40ce30cdc2a07b7a9c2d1f33070e8725
      public int f() {
          return this.x;
      }
-@@ -216,6 +219,7 @@ public class ChunkStatus {
+@@ -222,6 +225,7 @@ public class ChunkStatus {
          return this.z;
      }
  
@@ -2797,7 +2793,7 @@ index 134a4f0b7d254b5dd8ca26a9c5874532826978c4..40ce30cdc2a07b7a9c2d1f33070e8725
          return this.c() >= chunkstatus.c();
      }
 diff --git a/src/main/java/net/minecraft/server/IAsyncTaskHandler.java b/src/main/java/net/minecraft/server/IAsyncTaskHandler.java
-index 7e5ece9d50af7151ad4cc084e3680dae41ac92be..cfe43e882e524b6ab3d9702e81269c97e6b75eba 100644
+index 1ba26ee10f338edbec0f580bb55d083a3d6d2284..63fdae15ccbef0c39718b320dbd096794bcfa3b4 100644
 --- a/src/main/java/net/minecraft/server/IAsyncTaskHandler.java
 +++ b/src/main/java/net/minecraft/server/IAsyncTaskHandler.java
 @@ -91,7 +91,7 @@ public abstract class IAsyncTaskHandler<R extends Runnable> implements Mailbox<R
@@ -2810,10 +2806,10 @@ index 7e5ece9d50af7151ad4cc084e3680dae41ac92be..cfe43e882e524b6ab3d9702e81269c97
              ;
          }
 diff --git a/src/main/java/net/minecraft/server/IChunkLoader.java b/src/main/java/net/minecraft/server/IChunkLoader.java
-index 2f95174fcc467908808ed3f2dc956bdcafdc3558..134c76065bf382912e6c28d15449db3f9827f848 100644
+index fa03834dacacf7ae6a326c88007256a261153c27..c0d2df8ef3b4d0224ede2b7a4ef4e3f930590209 100644
 --- a/src/main/java/net/minecraft/server/IChunkLoader.java
 +++ b/src/main/java/net/minecraft/server/IChunkLoader.java
-@@ -3,37 +3,49 @@ package net.minecraft.server;
+@@ -3,37 +3,50 @@ package net.minecraft.server;
  import com.mojang.datafixers.DataFixer;
  import java.io.File;
  import java.io.IOException;
@@ -2824,23 +2820,23 @@ index 2f95174fcc467908808ed3f2dc956bdcafdc3558..134c76065bf382912e6c28d15449db3f
  import java.util.function.Supplier;
  import javax.annotation.Nullable;
  
--public class IChunkLoader implements AutoCloseable {
-+public class IChunkLoader extends RegionFileCache implements AutoCloseable {
+ public class IChunkLoader implements AutoCloseable {
  
 -    private final IOWorker a; public IOWorker getIOWorker() { return a; } // Paper - OBFHELPER
-+//    private final IOWorker a; public IOWorker getIOWorker() { return a; } // Paper - OBFHELPER - nuke IOWorker
++    // Paper - OBFHELPER - nuke IOWorker
      protected final DataFixer b;
      @Nullable
 -    private PersistentStructureLegacy c;
 +    private volatile PersistentStructureLegacy c; // Paper - async chunk loading
 +
 +    private final Object persistentDataLock = new Object(); // Paper
++    protected final RegionFileCache regionFileCache;
  
-     public IChunkLoader(File file, DataFixer datafixer) {
-+        super(file);
+     public IChunkLoader(File file, DataFixer datafixer, boolean flag) {
++        this.regionFileCache = new RegionFileCache(file, flag); // Paper - nuke IOWorker
          this.b = datafixer;
--        this.a = new IOWorker(new RegionFileCache(file), "chunk");
-+//        this.a = new IOWorker(new RegionFileCache(file), "chunk"); // Paper - nuke IOWorker
+-        this.a = new IOWorker(file, flag, "chunk");
++        // Paper - nuke IOWorker
      }
  
      // CraftBukkit start
@@ -2875,13 +2871,13 @@ index 2f95174fcc467908808ed3f2dc956bdcafdc3558..134c76065bf382912e6c28d15449db3f
  
              ChunkStatus status = ChunkStatus.a(level.getString("Status"));
              if (status != null && status.b(ChunkStatus.FEATURES)) {
-@@ -64,11 +76,13 @@ public class IChunkLoader implements AutoCloseable {
+@@ -64,11 +77,13 @@ public class IChunkLoader implements AutoCloseable {
          if (i < 1493) {
              nbttagcompound = GameProfileSerializer.a(this.b, DataFixTypes.CHUNK, nbttagcompound, i, 1493);
              if (nbttagcompound.getCompound("Level").getBoolean("hasLegacyStructureData")) {
 +                synchronized (this.persistentDataLock) { // Paper - Async chunk loading
                  if (this.c == null) {
-                     this.c = PersistentStructureLegacy.a(dimensionmanager.getType(), (WorldPersistentData) supplier.get()); // CraftBukkit - getType
+                     this.c = PersistentStructureLegacy.a(resourcekey, (WorldPersistentData) supplier.get());
                  }
  
                  nbttagcompound = this.c.a(nbttagcompound);
@@ -2889,56 +2885,41 @@ index 2f95174fcc467908808ed3f2dc956bdcafdc3558..134c76065bf382912e6c28d15449db3f
              }
          }
  
-@@ -84,24 +98,28 @@ public class IChunkLoader implements AutoCloseable {
-         return nbttagcompound.hasKeyOfType("DataVersion", 99) ? nbttagcompound.getInt("DataVersion") : -1;
+@@ -86,22 +101,20 @@ public class IChunkLoader implements AutoCloseable {
+ 
+     @Nullable
+     public NBTTagCompound read(ChunkCoordIntPair chunkcoordintpair) throws IOException {
+-        return this.a.a(chunkcoordintpair);
++        return this.regionFileCache.read(chunkcoordintpair);
      }
  
--    @Nullable
--    public NBTTagCompound read(ChunkCoordIntPair chunkcoordintpair) throws IOException {
--        return this.a.a(chunkcoordintpair);
--    }
--
 -    public void a(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) {
 -        this.a.a(chunkcoordintpair, nbttagcompound);
-+//    Paper start - nuke IOWorker
-+//    @Nullable
-+//    public NBTTagCompound read(ChunkCoordIntPair chunkcoordintpair) throws IOException {
-+//        return this.a.a(chunkcoordintpair);
-+//    }
-+//
 +    public void a(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException { write(chunkcoordintpair, nbttagcompound); } // Paper OBFHELPER
 +    public void write(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException { // Paper - OBFHELPER - (Switched around for safety)
-+        super.write(chunkcoordintpair, nbttagcompound);
++        this.regionFileCache.write(chunkcoordintpair, nbttagcompound);
          if (this.c != null) {
--            this.c.a(chunkcoordintpair.pair());
 +            synchronized (this.persistentDataLock) { // Paper - Async chunk loading
-+            this.c.a(chunkcoordintpair.pair()); } // Paper - Async chunk loading}
+             this.c.a(chunkcoordintpair.pair());
++            } // Paper - Async chunk loading}
          }
- 
-     }
+-
+-    }
 -
 -    public void i() {
 -        this.a.a().join();
--    }
--
--    public void close() throws IOException {
+     }
+ 
+     public void close() throws IOException {
 -        this.a.close();
--    }
-+//
-+//    public void i() {
-+//        this.a.a().join();
-+//    }
-+//
-+//    public void close() throws IOException {
-+//        this.a.close();
-+//    }
-+//    Paper end
++        this.regionFileCache.close();
+     }
  }
 diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
-index ece411feee81f96ae0462cf7643ec450cafad7a7..ea087800eb838371d5da70538091e1148816296e 100644
+index 5658b2a3c4601d07545b08b0a7179c8f3b051bd4..b2e8ddc9ff1bf5f519d971455d48a2faad3638f2 100644
 --- a/src/main/java/net/minecraft/server/MCUtil.java
 +++ b/src/main/java/net/minecraft/server/MCUtil.java
-@@ -708,4 +708,9 @@ public final class MCUtil {
+@@ -696,4 +696,9 @@ public final class MCUtil {
              out.print(fileData);
          }
      }
@@ -2948,26 +2929,31 @@ index ece411feee81f96ae0462cf7643ec450cafad7a7..ea087800eb838371d5da70538091e114
 +        return 33 + ChunkStatus.getTicketLevelOffset(status);
 +    }
  }
+diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
+index ca45b10b5dd7003314ff4c3294f13d2c53d9e678..32a4d1d036ed01e556348361407b7ea276efa64e 100644
+--- a/src/main/java/net/minecraft/server/Main.java
++++ b/src/main/java/net/minecraft/server/Main.java
+@@ -149,6 +149,7 @@ public class Main {
+ 
+             convertable_conversionsession.a((IRegistryCustom) iregistrycustom_dimension, (SaveData) object);
+             */
++            Class.forName("net.minecraft.server.VillagerTrades");// Paper - load this sync so it won't fail later async
+             final DedicatedServer dedicatedserver = (DedicatedServer) MinecraftServer.a((thread) -> {
+                 DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, datapackconfiguration1, thread, iregistrycustom_dimension, convertable_conversionsession, resourcepackrepository, datapackresources, null, dedicatedserversettings, DataConverterRegistry.a(), minecraftsessionservice, gameprofilerepository, usercache, WorldLoadListenerLogger::new);
+ 
 diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 7920d24ab089fb8360ef74946cf7dc35cb7625eb..9450e27e5ce9295d87b95be2797fc27984ca2b0b 100644
+index 03ae25736b02ac02c01e76b5d2fbfd803585ebde..7e832d2610f9c0d805c7f289de5098d9b5f09402 100644
 --- a/src/main/java/net/minecraft/server/MinecraftServer.java
 +++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -780,6 +780,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
+@@ -808,7 +808,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
              this.getUserCache().c(false); // Paper
          }
          // Spigot end
+-
 +        com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.close(true, true); // Paper
      }
  
      public String getServerIp() {
-@@ -1401,6 +1402,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
-                 dedicatedserver.setEraseCache(true);
-             }
- 
-+            Class.forName("net.minecraft.server.VillagerTrades");// Paper - load this sync so it won't fail later async
-             dedicatedserver.serverThread.setPriority(Thread.NORM_PRIORITY+2); // Paper - boost priority
-             dedicatedserver.serverThread.start();
-             // CraftBukkit end
 diff --git a/src/main/java/net/minecraft/server/NextTickListEntry.java b/src/main/java/net/minecraft/server/NextTickListEntry.java
 index e9c405fb5376c5733b9b0191cd5309173f4021e8..33cfeabdee03195a294f303f28044a313cb1c4ed 100644
 --- a/src/main/java/net/minecraft/server/NextTickListEntry.java
@@ -3016,10 +3002,10 @@ index 4c52c57c02571353f71772e3650932f314da62ca..71daa0cb08d69c16bded510d1a490534
  
      @Override
 diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
-index 52ea4f05a0c7f29f62f31bb032a5ceb905107e60..0f1576effe10795bcb8ed3b519f4dbafdf9ea6ed 100644
+index 3e1c1253ad5e2fa68fd8a0bac100c2e7536ea080..b6868b6b23a09e8e0dfe7a5e378dca22b8d80bad 100644
 --- a/src/main/java/net/minecraft/server/PlayerChunk.java
 +++ b/src/main/java/net/minecraft/server/PlayerChunk.java
-@@ -128,6 +128,18 @@ public class PlayerChunk {
+@@ -127,6 +127,18 @@ public class PlayerChunk {
          }
          return null;
      }
@@ -3038,7 +3024,7 @@ index 52ea4f05a0c7f29f62f31bb032a5ceb905107e60..0f1576effe10795bcb8ed3b519f4dbaf
      // Paper end
  
      public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> getStatusFutureUnchecked(ChunkStatus chunkstatus) {
-@@ -353,7 +365,7 @@ public class PlayerChunk {
+@@ -340,7 +352,7 @@ public class PlayerChunk {
          ChunkStatus chunkstatus = getChunkStatus(this.oldTicketLevel);
          ChunkStatus chunkstatus1 = getChunkStatus(this.ticketLevel);
          boolean flag = this.oldTicketLevel <= PlayerChunkMap.GOLDEN_TICKET;
@@ -3047,7 +3033,7 @@ index 52ea4f05a0c7f29f62f31bb032a5ceb905107e60..0f1576effe10795bcb8ed3b519f4dbaf
          PlayerChunk.State playerchunk_state = getChunkState(this.oldTicketLevel);
          PlayerChunk.State playerchunk_state1 = getChunkState(this.ticketLevel);
          // CraftBukkit start
-@@ -389,6 +401,12 @@ public class PlayerChunk {
+@@ -376,6 +388,12 @@ public class PlayerChunk {
                  }
              });
  
@@ -3061,19 +3047,19 @@ index 52ea4f05a0c7f29f62f31bb032a5ceb905107e60..0f1576effe10795bcb8ed3b519f4dbaf
                  completablefuture = (CompletableFuture) this.statusFutures.get(i);
                  if (completablefuture != null) {
 diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
-index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3e381cb5a 100644
+index 24f3e8a6866bb416f04aca342514fa5dd3d314c8..cdb72b225226083ca45ade798f54989422e5281c 100644
 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
 +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
-@@ -63,7 +63,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -64,7 +64,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
      private final LightEngineThreaded lightEngine;
      private final IAsyncTaskHandler<Runnable> executor;
-     public final ChunkGenerator<?> chunkGenerator;
+     public final ChunkGenerator chunkGenerator;
 -    private final Supplier<WorldPersistentData> l;
 +    private final Supplier<WorldPersistentData> l; public final Supplier<WorldPersistentData> getWorldPersistentDataSupplier() { return this.l; } // Paper - OBFHELPER
      private final VillagePlace m;
      public final LongSet unloadQueue;
      private boolean updatingChunksModified;
-@@ -73,7 +73,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -74,7 +74,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
      public final WorldLoadListener worldLoadListener;
      public final PlayerChunkMap.a chunkDistanceManager; public final PlayerChunkMap.a getChunkMapDistanceManager() { return this.chunkDistanceManager; } // Paper - OBFHELPER
      private final AtomicInteger u;
@@ -3082,16 +3068,16 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
      private final File w;
      private final PlayerMap playerMap;
      public final Int2ObjectMap<PlayerChunkMap.EntityTracker> trackedEntities;
-@@ -156,7 +156,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
-         this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getWorldProvider().f(), threadedmailbox1, this.p.a(threadedmailbox1, false));
+@@ -157,7 +157,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+         this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getDimensionManager().hasSkyLight(), threadedmailbox1, this.p.a(threadedmailbox1, false));
          this.chunkDistanceManager = new PlayerChunkMap.a(executor, iasynctaskhandler);
          this.l = supplier;
--        this.m = new VillagePlace(new File(this.w, "poi"), datafixer);
-+        this.m = new VillagePlace(new File(this.w, "poi"), datafixer, this.world); // Paper
+-        this.m = new VillagePlace(new File(this.w, "poi"), datafixer, flag);
++        this.m = new VillagePlace(new File(this.w, "poi"), datafixer, flag, this.world); // Paper
          this.setViewDistance(i);
      }
  
-@@ -203,7 +203,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -204,7 +204,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
      }
  
      @Nullable
@@ -3100,7 +3086,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
          return (PlayerChunk) this.visibleChunks.get(i);
      }
  
-@@ -325,6 +325,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -326,6 +326,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
      public void close() throws IOException {
          try {
              this.p.close();
@@ -3108,7 +3094,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
              this.m.close();
          } finally {
              super.close();
-@@ -416,7 +417,8 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -417,7 +418,8 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
              this.b(() -> {
                  return true;
              });
@@ -3118,7 +3104,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
              PlayerChunkMap.LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", this.w.getName());
          } else {
              this.visibleChunks.values().stream().filter(PlayerChunk::hasBeenLoaded).forEach((playerchunk) -> {
-@@ -432,16 +434,20 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -433,16 +435,20 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
  
      }
  
@@ -3140,7 +3126,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
          }
  
          gameprofilerfiller.exit();
-@@ -462,12 +468,13 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -463,12 +469,13 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
              if (playerchunk != null) {
                  this.pendingUnload.put(j, playerchunk);
                  this.updatingChunksModified = true;
@@ -3155,7 +3141,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
              }
          }
          activityAccountant.endActivity(); // Spigot
-@@ -481,6 +488,60 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -482,6 +489,60 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
  
      }
  
@@ -3216,7 +3202,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
      private void a(long i, PlayerChunk playerchunk) {
          CompletableFuture<IChunkAccess> completablefuture = playerchunk.getChunkSave();
          Consumer<IChunkAccess> consumer = (ichunkaccess) -> { // CraftBukkit - decompile error
-@@ -494,7 +555,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -495,7 +556,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
                          ((Chunk) ichunkaccess).setLoaded(false);
                      }
  
@@ -3225,7 +3211,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
                      if (this.loadedChunks.remove(i) && ichunkaccess instanceof Chunk) {
                          Chunk chunk = (Chunk) ichunkaccess;
  
-@@ -502,6 +563,13 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -503,6 +564,13 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
                      }
                      this.autoSaveQueue.remove(playerchunk); // Paper
  
@@ -3239,16 +3225,9 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
                      this.lightEngine.a(ichunkaccess.getPos());
                      this.lightEngine.queueUpdate();
                      this.worldLoadListener.a(ichunkaccess.getPos(), (ChunkStatus) null);
-@@ -571,27 +639,32 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
-         }
+@@ -573,19 +641,20 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
      }
  
-+    // Paper start - Async chunk io
-+    public NBTTagCompound completeChunkData(NBTTagCompound compound, ChunkCoordIntPair chunkcoordintpair) throws IOException {
-+        return compound == null ? null : this.getChunkData(this.world.getWorldProvider().getDimensionManager(), this.getWorldPersistentDataSupplier(), compound, chunkcoordintpair, this.world);
-+    }
-+    // Paper end
-+
      private CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> f(ChunkCoordIntPair chunkcoordintpair) {
 -        return CompletableFuture.supplyAsync(() -> {
 +        // Paper start - Async chunk io
@@ -3259,38 +3238,26 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
 -                try (Timing ignored2 = this.world.timings.chunkIO.startTimingIfSync()) { // Paper start - timings
 -                    nbttagcompound = this.readChunkData(chunkcoordintpair);
 -                } // Paper end
--
++                // Paper start
++                if (ioThrowable != null) {
++                    com.destroystokyo.paper.util.SneakyThrow.sneaky(ioThrowable);
++                }
++                // Paper end
+ 
 -                if (nbttagcompound != null) {try (Timing ignored2 = this.world.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings
 -                    boolean flag = nbttagcompound.hasKeyOfType("Level", 10) && nbttagcompound.getCompound("Level").hasKeyOfType("Status", 8);
-+                if (ioThrowable != null) {
-+                    com.destroystokyo.paper.io.IOUtil.rethrow(ioThrowable);
-+                }
++                if (chunkHolder.protoChunk != null) {try (Timing ignored2 = this.world.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings // Paper - chunk is created async
  
 -                    if (flag) {
 -                        ProtoChunk protochunk = ChunkRegionLoader.loadChunk(this.world, this.definedStructureManager, this.m, chunkcoordintpair, nbttagcompound);
-+                this.getVillagePlace().loadInData(chunkcoordintpair, chunkHolder.poiData);
-+                chunkHolder.tasks.forEach(Runnable::run);
-+                // Paper - async load completes this
-+                // Paper end
++                    if (true) {
++                        ProtoChunk protochunk = chunkHolder.protoChunk;
  
--                        protochunk.setLastSaved(this.world.getTime());
--                        return Either.left(protochunk);
--                    }
--
--                    PlayerChunkMap.LOGGER.error("Chunk file at {} is missing level data, skipping", chunkcoordintpair);
--                }} // Paper
-+                // Paper start - This is done async
-+                if (chunkHolder.protoChunk != null) {
-+                    chunkHolder.protoChunk.setLastSaved(this.world.getTime());
-+                    return Either.left(chunkHolder.protoChunk);
-+                }
-+                // Paper end
-             } catch (ReportedException reportedexception) {
-                 Throwable throwable = reportedexception.getCause();
- 
-@@ -605,7 +678,32 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
-             }
+                         protochunk.setLastSaved(this.world.getTime());
+                         this.a(chunkcoordintpair, protochunk.getChunkStatus().getType());
+@@ -609,7 +678,32 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
  
+             this.g(chunkcoordintpair);
              return Either.left(new ProtoChunk(chunkcoordintpair, ChunkConverter.a, this.world)); // Paper - Anti-Xray - Add parameter
 -        }, this.executor);
 +            // Paper start - Async chunk io
@@ -3321,8 +3288,8 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
 +        // Paper end
      }
  
-     private CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> b(PlayerChunk playerchunk, ChunkStatus chunkstatus) {
-@@ -824,17 +922,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+     private void g(ChunkCoordIntPair chunkcoordintpair) {
+@@ -836,6 +930,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
      }
  
      public boolean saveChunk(IChunkAccess ichunkaccess) {
@@ -3330,52 +3297,46 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
          this.m.a(ichunkaccess.getPos());
          if (!ichunkaccess.isNeedsSaving()) {
              return false;
-         } else {
--            try {
--                this.world.checkSession();
--            } catch (ExceptionWorldConflict exceptionworldconflict) {
--                PlayerChunkMap.LOGGER.error("Couldn't save chunk; already in use by another instance of Minecraft?", exceptionworldconflict);
--                com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exceptionworldconflict); // Paper
--                return false;
--            }
-+            // Paper - The save session check is performed on the IO thread
- 
-             ichunkaccess.setLastSaved(this.world.getTime());
-             ichunkaccess.setNeedsSaving(false);
-@@ -845,6 +938,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
-                 NBTTagCompound nbttagcompound;
+@@ -848,6 +943,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+                 ChunkStatus chunkstatus = ichunkaccess.getChunkStatus();
  
                  if (chunkstatus.getType() != ChunkStatus.Type.LEVELCHUNK) {
 +                    try (co.aikar.timings.Timing ignored1 = this.world.timings.chunkSaveOverwriteCheck.startTiming()) { // Paper
-                     // Paper start - Optimize save by using status cache
-                     ChunkStatus statusOnDisk = this.getChunkStatusOnDisk(chunkcoordintpair);
-                     if (statusOnDisk != null && statusOnDisk.getType() == ChunkStatus.Type.LEVELCHUNK) {
-@@ -857,9 +951,15 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+                     if (this.h(chunkcoordintpair)) {
+                         return false;
                      }
+@@ -855,12 +951,20 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+                     if (chunkstatus == ChunkStatus.EMPTY && ichunkaccess.h().values().stream().noneMatch(StructureStart::e)) {
+                         return false;
+                     }
++                    } // Paper
                  }
  
-+                } // Paper
                  this.world.getMethodProfiler().c("chunkSave");
+-                NBTTagCompound nbttagcompound = ChunkRegionLoader.saveChunk(this.world, ichunkaccess);
++                NBTTagCompound nbttagcompound;
 +                try (co.aikar.timings.Timing ignored1 = this.world.timings.chunkSaveDataSerialization.startTiming()) { // Paper
-                 nbttagcompound = ChunkRegionLoader.saveChunk(this.world, ichunkaccess);
--                this.a(chunkcoordintpair, nbttagcompound);
++                    nbttagcompound = ChunkRegionLoader.saveChunk(this.world, ichunkaccess);
 +                } // Paper
++
+ 
+-                this.a(chunkcoordintpair, nbttagcompound);
 +                // Paper start - async chunk io
 +                com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.world, chunkcoordintpair.x, chunkcoordintpair.z,
 +                    null, nbttagcompound, com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY);
 +                // Paper end - async chunk io
+                 this.a(chunkcoordintpair, chunkstatus.getType());
                  return true;
              } catch (Exception exception) {
-                 PlayerChunkMap.LOGGER.error("Failed to save chunk {},{}", chunkcoordintpair.x, chunkcoordintpair.z, exception);
-@@ -867,6 +967,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -869,6 +973,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
                  return false;
              }
          }
 +        } // Paper
      }
  
-     protected void setViewDistance(int i) {
-@@ -970,6 +1071,35 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+     private boolean h(ChunkCoordIntPair chunkcoordintpair) {
+@@ -998,6 +1103,35 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
          }
      }
  
@@ -3411,20 +3372,20 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
      @Nullable
      public NBTTagCompound readChunkData(ChunkCoordIntPair chunkcoordintpair) throws IOException { // Paper - private -> public
          NBTTagCompound nbttagcompound = this.read(chunkcoordintpair);
-@@ -992,33 +1122,55 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -1019,33 +1153,55 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
  
      // Paper start - chunk status cache "api"
      public ChunkStatus getChunkStatusOnDiskIfCached(ChunkCoordIntPair chunkPos) {
 -        RegionFile regionFile = this.getIOWorker().getRegionFileCache().getRegionFileIfLoaded(chunkPos);
 +        synchronized (this) { // Paper
-+        RegionFile regionFile = this.getRegionFileIfLoaded(chunkPos);
++        RegionFile regionFile = this.regionFileCache.getRegionFileIfLoaded(chunkPos);
  
          return regionFile == null ? null : regionFile.getStatusIfCached(chunkPos.x, chunkPos.z);
 +        } // Paper
      }
  
      public ChunkStatus getChunkStatusOnDisk(ChunkCoordIntPair chunkPos) throws IOException {
--        RegionFile regionFile = this.getIOWorker().getRegionFileCache().getFile(chunkPos, false);
+-        RegionFile regionFile = this.getIOWorker().getRegionFileCache().getFile(chunkPos, true);
 +        // Paper start - async chunk save for unload
 +        IChunkAccess unloadingChunk = this.world.asyncChunkTaskManager.getChunkInSaveProgress(chunkPos.x, chunkPos.z);
 +        if (unloadingChunk != null) {
@@ -3435,20 +3396,20 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
 +        NBTTagCompound inProgressWrite = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE
 +                                             .getPendingWrite(this.world, chunkPos.x, chunkPos.z, false);
  
--        if (!regionFile.chunkExists(chunkPos)) {
+-        if (regionFile == null || !regionFile.chunkExists(chunkPos)) {
 -            return null;
 +        if (inProgressWrite != null) {
 +            return ChunkRegionLoader.getStatus(inProgressWrite);
          }
 +        // Paper end
 +        synchronized (this) { // Paper - async io
-+            RegionFile regionFile = this.getFile(chunkPos, false);
-+
-+            if (!regionFile.chunkExists(chunkPos)) {
-+                return null;
-+            }
++            RegionFile regionFile = this.regionFileCache.getFile(chunkPos, true);
  
 -        ChunkStatus status = regionFile.getStatusIfCached(chunkPos.x, chunkPos.z);
++            if (regionFile == null || !regionFile.chunkExists(chunkPos)) {
++                return null;
++            }
++
 +            ChunkStatus status = regionFile.getStatusIfCached(chunkPos.x, chunkPos.z);
  
 -        if (status != null) {
@@ -3470,7 +3431,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
      public void updateChunkStatusOnDisk(ChunkCoordIntPair chunkPos, @Nullable NBTTagCompound compound) throws IOException {
 -        RegionFile regionFile = this.getIOWorker().getRegionFileCache().getFile(chunkPos, false);
 +        synchronized (this) {
-+            RegionFile regionFile = this.getFile(chunkPos, false);
++            RegionFile regionFile = this.regionFileCache.getFile(chunkPos, false);
  
 -        regionFile.setStatus(chunkPos.x, chunkPos.z, ChunkRegionLoader.getStatus(compound));
 +            regionFile.setStatus(chunkPos.x, chunkPos.z, ChunkRegionLoader.getStatus(compound));
@@ -3478,7 +3439,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
      }
  
      public IChunkAccess getUnloadingChunk(int chunkX, int chunkZ) {
-@@ -1027,6 +1179,39 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -1054,6 +1210,39 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
      }
      // Paper end
  
@@ -3506,7 +3467,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
 +        synchronized (world.getChunkProvider().playerChunkMap) {
 +            net.minecraft.server.RegionFile file;
 +            try {
-+                file = world.getChunkProvider().playerChunkMap.getFile(chunkPos, false);
++                file = world.getChunkProvider().playerChunkMap.regionFileCache.getFile(chunkPos, false);
 +            } catch (IOException ex) {
 +                throw new RuntimeException(ex);
 +            }
@@ -3518,7 +3479,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
      boolean isOutsideOfRange(ChunkCoordIntPair chunkcoordintpair) {
          // Spigot start
          return isOutsideOfRange(chunkcoordintpair, false);
-@@ -1374,6 +1559,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -1399,6 +1588,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
  
      }
  
@@ -3527,10 +3488,10 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
          return this.m;
      }
 diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
-index a5700a955b6d7927228a14128860b49e79e61f03..6a7bdf8c5f38ca4eb578e1104375e5773269330c 100644
+index 35536527a01e72841e358c643631b2739dd0bf26..795b24c8d102417ae7e730254ecddefc06dbe0df 100644
 --- a/src/main/java/net/minecraft/server/PlayerConnection.java
 +++ b/src/main/java/net/minecraft/server/PlayerConnection.java
-@@ -541,6 +541,13 @@ public class PlayerConnection implements PacketListenerPlayIn {
+@@ -544,6 +544,13 @@ public class PlayerConnection implements PacketListenerPlayIn {
              minecraftServer.scheduleOnMain(() -> this.disconnect(new ChatMessage("disconnect.spam", new Object[0]))); // Paper
              return;
          }
@@ -3545,7 +3506,7 @@ index a5700a955b6d7927228a14128860b49e79e61f03..6a7bdf8c5f38ca4eb578e1104375e577
          StringReader stringreader = new StringReader(packetplayintabcomplete.c());
  
 diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java
-index d37abf2cf304f81405e570588c8accbc44a629f4..df728e2c0a2bf660a91e0bd6342c4b4b1471dcb7 100644
+index e1730709fff5dfee68621d0aaed70a00bab97948..93797395c3a710d228bd790771ac18b4baa3b1e2 100644
 --- a/src/main/java/net/minecraft/server/RegionFile.java
 +++ b/src/main/java/net/minecraft/server/RegionFile.java
 @@ -36,6 +36,8 @@ public class RegionFile implements AutoCloseable {
@@ -3557,7 +3518,7 @@ index d37abf2cf304f81405e570588c8accbc44a629f4..df728e2c0a2bf660a91e0bd6342c4b4b
      // Paper start - Cache chunk status
      private final ChunkStatus[] statuses = new ChunkStatus[32 * 32];
  
-@@ -224,7 +226,7 @@ public class RegionFile implements AutoCloseable {
+@@ -229,7 +231,7 @@ public class RegionFile implements AutoCloseable {
          return (i + 4096 - 1) / 4096;
      }
  
@@ -3566,7 +3527,7 @@ index d37abf2cf304f81405e570588c8accbc44a629f4..df728e2c0a2bf660a91e0bd6342c4b4b
          int i = this.getOffset(chunkcoordintpair);
  
          if (i == 0) {
-@@ -380,6 +382,11 @@ public class RegionFile implements AutoCloseable {
+@@ -389,6 +391,11 @@ public class RegionFile implements AutoCloseable {
      }
  
      public void close() throws IOException {
@@ -3577,9 +3538,9 @@ index d37abf2cf304f81405e570588c8accbc44a629f4..df728e2c0a2bf660a91e0bd6342c4b4b
 +        // Paper end
          this.closed = true; // Paper
          try {
-             this.c();
-@@ -394,6 +401,10 @@ public class RegionFile implements AutoCloseable {
-                 }
+             this.d();
+@@ -399,6 +406,10 @@ public class RegionFile implements AutoCloseable {
+                 this.dataFile.close();
              }
          }
 +        } finally { // Paper start - Prevent regionfiles from being closed during use
@@ -3590,7 +3551,7 @@ index d37abf2cf304f81405e570588c8accbc44a629f4..df728e2c0a2bf660a91e0bd6342c4b4b
      }
  
 diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java
-index 2f8af42e2aadeb1b11db94fdb54ec0ba9e30f095..72118a7dcfabde0f069b8c8b86f41c026a2c99d9 100644
+index 341689ac996164b7b53e095495b92b6e85ab991a..867dc074bc57b27486de6ce742971d5db945b0fc 100644
 --- a/src/main/java/net/minecraft/server/RegionFileCache.java
 +++ b/src/main/java/net/minecraft/server/RegionFileCache.java
 @@ -9,7 +9,7 @@ import java.io.File;
@@ -3602,7 +3563,7 @@ index 2f8af42e2aadeb1b11db94fdb54ec0ba9e30f095..72118a7dcfabde0f069b8c8b86f41c02
  
      public final Long2ObjectLinkedOpenHashMap<RegionFile> cache = new Long2ObjectLinkedOpenHashMap();
      private final File b;
-@@ -20,16 +20,27 @@ public final class RegionFileCache implements AutoCloseable {
+@@ -22,16 +22,27 @@ public final class RegionFileCache implements AutoCloseable {
  
  
      // Paper start
@@ -3632,8 +3593,8 @@ index 2f8af42e2aadeb1b11db94fdb54ec0ba9e30f095..72118a7dcfabde0f069b8c8b86f41c02
              return regionfile;
          } else {
              if (this.cache.size() >= com.destroystokyo.paper.PaperConfig.regionFileCacheSize) { // Paper - configurable
-@@ -45,6 +56,12 @@ public final class RegionFileCache implements AutoCloseable {
-             RegionFile regionfile1 = new RegionFile(file, this.b);
+@@ -47,6 +58,12 @@ public final class RegionFileCache implements AutoCloseable {
+             RegionFile regionfile1 = new RegionFile(file, this.b, this.c);
  
              this.cache.putAndMoveToFirst(i, regionfile1);
 +            // Paper start
@@ -3645,7 +3606,7 @@ index 2f8af42e2aadeb1b11db94fdb54ec0ba9e30f095..72118a7dcfabde0f069b8c8b86f41c02
              return regionfile1;
          }
      }
-@@ -120,11 +137,12 @@ public final class RegionFileCache implements AutoCloseable {
+@@ -122,11 +139,12 @@ public final class RegionFileCache implements AutoCloseable {
      @Nullable
      public NBTTagCompound read(ChunkCoordIntPair chunkcoordintpair) throws IOException {
          // CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing
@@ -3659,7 +3620,7 @@ index 2f8af42e2aadeb1b11db94fdb54ec0ba9e30f095..72118a7dcfabde0f069b8c8b86f41c02
          DataInputStream datainputstream = regionfile.a(chunkcoordintpair);
          // Paper start
          if (regionfile.isOversized(chunkcoordintpair.x, chunkcoordintpair.z)) {
-@@ -162,10 +180,14 @@ public final class RegionFileCache implements AutoCloseable {
+@@ -164,10 +182,14 @@ public final class RegionFileCache implements AutoCloseable {
          }
  
          return nbttagcompound;
@@ -3675,7 +3636,7 @@ index 2f8af42e2aadeb1b11db94fdb54ec0ba9e30f095..72118a7dcfabde0f069b8c8b86f41c02
          int attempts = 0; Exception laste = null; while (attempts++ < 5) { try { // Paper
          DataOutputStream dataoutputstream = regionfile.c(chunkcoordintpair);
          Throwable throwable = null;
-@@ -204,9 +226,12 @@ public final class RegionFileCache implements AutoCloseable {
+@@ -206,9 +228,12 @@ public final class RegionFileCache implements AutoCloseable {
              MinecraftServer.LOGGER.error("Failed to save chunk", laste);
          }
          // Paper end
@@ -3686,10 +3647,10 @@ index 2f8af42e2aadeb1b11db94fdb54ec0ba9e30f095..72118a7dcfabde0f069b8c8b86f41c02
  
 -    public void close() throws IOException {
 +    public synchronized void close() throws IOException { // Paper -> synchronized
+         ExceptionSuppressor<IOException> exceptionsuppressor = new ExceptionSuppressor<>();
          ObjectIterator objectiterator = this.cache.values().iterator();
  
-         while (objectiterator.hasNext()) {
-@@ -216,4 +241,12 @@ public final class RegionFileCache implements AutoCloseable {
+@@ -235,4 +260,12 @@ public final class RegionFileCache implements AutoCloseable {
          }
  
      }
@@ -3703,46 +3664,45 @@ index 2f8af42e2aadeb1b11db94fdb54ec0ba9e30f095..72118a7dcfabde0f069b8c8b86f41c02
 +    // CraftBukkit end
  }
 diff --git a/src/main/java/net/minecraft/server/RegionFileSection.java b/src/main/java/net/minecraft/server/RegionFileSection.java
-index db9f0196bda4c987de6cf63eea437b7154d47b57..a6d8ef5eb44f3f851a3a1be4032ca21ab1d7f2b2 100644
+index a39075c68bb04e7183941c5eb80eb7cdde235045..bd0ff1e43a07a3332f9ade49fec2f76275a25c7f 100644
 --- a/src/main/java/net/minecraft/server/RegionFileSection.java
 +++ b/src/main/java/net/minecraft/server/RegionFileSection.java
-@@ -20,28 +20,29 @@ import javax.annotation.Nullable;
+@@ -21,28 +21,29 @@ import javax.annotation.Nullable;
  import org.apache.logging.log4j.LogManager;
  import org.apache.logging.log4j.Logger;
  
--public class RegionFileSection<R extends MinecraftSerializable> implements AutoCloseable {
-+public class RegionFileSection<R extends MinecraftSerializable> extends RegionFileCache implements AutoCloseable { // Paper - nuke IOWorker
+-public class RegionFileSection<R> implements AutoCloseable {
++public class RegionFileSection<R> extends RegionFileCache implements AutoCloseable { // Paper - nuke IOWorker
  
      private static final Logger LOGGER = LogManager.getLogger();
 -    private final IOWorker b;
-+//    private final IOWorker b;
++    // Paper - nuke IOWorker
      private final Long2ObjectMap<Optional<R>> c = new Long2ObjectOpenHashMap();
 -    private final LongLinkedOpenHashSet d = new LongLinkedOpenHashSet();
 +    protected final LongLinkedOpenHashSet d = new LongLinkedOpenHashSet(); // Paper - private -> protected
-     private final BiFunction<Runnable, Dynamic<?>, R> e;
+     private final Function<Runnable, Codec<R>> e;
      private final Function<Runnable, R> f;
      private final DataFixer g;
      private final DataFixTypes h;
  
-     public RegionFileSection(File file, BiFunction<Runnable, Dynamic<?>, R> bifunction, Function<Runnable, R> function, DataFixer datafixer, DataFixTypes datafixtypes) {
-+        super(file); // Paper - nuke IOWorker
-         this.e = bifunction;
-         this.f = function;
+     public RegionFileSection(File file, Function<Runnable, Codec<R>> function, Function<Runnable, R> function1, DataFixer datafixer, DataFixTypes datafixtypes, boolean flag) {
++        super(file, flag); // Paper - nuke IOWorker
+         this.e = function;
+         this.f = function1;
          this.g = datafixer;
          this.h = datafixtypes;
--        this.b = new IOWorker(new RegionFileCache(file), file.getName());
-+//        this.b = new IOWorker(new RegionFileCache(file), file.getName()); // Paper - nuke IOWorker
+-        this.b = new IOWorker(file, flag, file.getName());
++        //this.b = new IOWorker(file, flag, file.getName()); // Paper - nuke IOWorker
      }
  
      protected void a(BooleanSupplier booleansupplier) {
--        while (!this.d.isEmpty() && booleansupplier.getAsBoolean()) {
--            ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(this.d.firstLong()).u();
-+        while (!this.d.isEmpty() && booleansupplier.getAsBoolean()) { // Paper - conflict here to avoid obfhelpers
-+            ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(this.d.firstLong()).u(); // Paper - conflict here to avoid obfhelpers
+         while (!this.d.isEmpty() && booleansupplier.getAsBoolean()) {
+-            ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(this.d.firstLong()).r();
++            ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(this.d.firstLong()).r(); // Paper - conflict here to avoid obfhelpers
  
              this.d(chunkcoordintpair);
          }
-@@ -95,13 +96,18 @@ public class RegionFileSection<R extends MinecraftSerializable> implements AutoC
+@@ -96,13 +97,18 @@ public class RegionFileSection<R> implements AutoCloseable {
      }
  
      private void b(ChunkCoordIntPair chunkcoordintpair) {
@@ -3763,7 +3723,7 @@ index db9f0196bda4c987de6cf63eea437b7154d47b57..a6d8ef5eb44f3f851a3a1be4032ca21a
          } catch (IOException ioexception) {
              RegionFileSection.LOGGER.error("Error reading chunk {} data from disk", chunkcoordintpair, ioexception);
              return null;
-@@ -143,17 +149,31 @@ public class RegionFileSection<R extends MinecraftSerializable> implements AutoC
+@@ -148,17 +154,31 @@ public class RegionFileSection<R> implements AutoCloseable {
      }
  
      private void d(ChunkCoordIntPair chunkcoordintpair) {
@@ -3797,19 +3757,19 @@ index db9f0196bda4c987de6cf63eea437b7154d47b57..a6d8ef5eb44f3f851a3a1be4032ca21a
      private <T> Dynamic<T> a(ChunkCoordIntPair chunkcoordintpair, DynamicOps<T> dynamicops) {
          Map<T, T> map = Maps.newHashMap();
  
-@@ -190,9 +210,9 @@ public class RegionFileSection<R extends MinecraftSerializable> implements AutoC
+@@ -204,9 +224,9 @@ public class RegionFileSection<R> implements AutoCloseable {
      public void a(ChunkCoordIntPair chunkcoordintpair) {
          if (!this.d.isEmpty()) {
              for (int i = 0; i < 16; ++i) {
--                long j = SectionPosition.a(chunkcoordintpair, i).v();
-+                long j = SectionPosition.a(chunkcoordintpair, i).v(); // Paper - conflict here to avoid obfhelpers
+-                long j = SectionPosition.a(chunkcoordintpair, i).s();
++                long j = SectionPosition.a(chunkcoordintpair, i).s();  // Paper - conflict here to avoid obfhelpers
  
 -                if (this.d.contains(j)) {
 +                if (this.d.contains(j)) { // Paper - conflict here to avoid obfhelpers
                      this.d(chunkcoordintpair);
                      return;
                  }
-@@ -201,7 +221,26 @@ public class RegionFileSection<R extends MinecraftSerializable> implements AutoC
+@@ -215,7 +235,26 @@ public class RegionFileSection<R> implements AutoCloseable {
  
      }
  
@@ -3827,7 +3787,7 @@ index db9f0196bda4c987de6cf63eea437b7154d47b57..a6d8ef5eb44f3f851a3a1be4032ca21a
 +        // This is checking if the data exists, then it builds it later in getDataInternal(ChunkCoordIntPair)
 +        if (!this.d.isEmpty()) {
 +            for (int i = 0; i < 16; ++i) {
-+                long j = SectionPosition.a(chunkcoordintpair, i).v();
++                long j = SectionPosition.a(chunkcoordintpair, i).s();
 +
 +                if (this.d.contains(j)) {
 +                    return this.getDataInternal(chunkcoordintpair);
@@ -3851,27 +3811,27 @@ index 75ab9f185b3231113dfa387c956a707b403bb2db..8055f5998213ab1c6c10d03d88d2b14d
      public static <T> TicketType<T> a(String s, Comparator<T> comparator) {
          return new TicketType<>(s, comparator, 0L);
 diff --git a/src/main/java/net/minecraft/server/VillagePlace.java b/src/main/java/net/minecraft/server/VillagePlace.java
-index c999f8c9bf8a59e19b3d6d1b7ad8b5fb6e48b928..1a5ec6152c15a6ece227d4bac00c3b02bd9c5c95 100644
+index b8c15047771bd4527b86e514a3b950b2ffc6eef0..303f6b0953ff3c29bd31ec5e02386a92b11d114a 100644
 --- a/src/main/java/net/minecraft/server/VillagePlace.java
 +++ b/src/main/java/net/minecraft/server/VillagePlace.java
-@@ -24,8 +24,16 @@ public class VillagePlace extends RegionFileSection<VillagePlaceSection> {
+@@ -25,8 +25,16 @@ public class VillagePlace extends RegionFileSection<VillagePlaceSection> {
      private final VillagePlace.a a = new VillagePlace.a();
      private final LongSet b = new LongOpenHashSet();
  
 +    private final WorldServer world; // Paper
 +
-     public VillagePlace(File file, DataFixer datafixer) {
-+        // Paper start
-+        this(file, datafixer, null);
+     public VillagePlace(File file, DataFixer datafixer, boolean flag) {
++        // Paper start - add world parameter
++        this(file, datafixer, flag, null);
 +    }
-+    public VillagePlace(File file, DataFixer datafixer, WorldServer world) {
-+        // Paper end
-         super(file, VillagePlaceSection::new, VillagePlaceSection::new, datafixer, DataFixTypes.POI_CHUNK);
-+        this.world = world; // Paper
++    public VillagePlace(File file, DataFixer datafixer, boolean flag, WorldServer world) {
+         super(file, VillagePlaceSection::a, VillagePlaceSection::new, datafixer, DataFixTypes.POI_CHUNK, flag);
++        this.world = world;
++        // Paper end - add world parameter
      }
  
      public void a(BlockPosition blockposition, VillagePlaceType villageplacetype) {
-@@ -129,7 +137,23 @@ public class VillagePlace extends RegionFileSection<VillagePlaceSection> {
+@@ -134,7 +142,23 @@ public class VillagePlace extends RegionFileSection<VillagePlaceSection> {
  
      @Override
      public void a(BooleanSupplier booleansupplier) {
@@ -3882,7 +3842,7 @@ index c999f8c9bf8a59e19b3d6d1b7ad8b5fb6e48b928..1a5ec6152c15a6ece227d4bac00c3b02
 +        } else {
 +            //super.a(booleansupplier); // re-implement below
 +            while (!((RegionFileSection)this).d.isEmpty() && booleansupplier.getAsBoolean()) {
-+                ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(((RegionFileSection)this).d.firstLong()).u();
++                ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(((RegionFileSection)this).d.firstLong()).r();
 +
 +                NBTTagCompound data;
 +                try (co.aikar.timings.Timing ignored1 = this.world.timings.poiSaveDataSerialization.startTiming()) {
@@ -3896,7 +3856,7 @@ index c999f8c9bf8a59e19b3d6d1b7ad8b5fb6e48b928..1a5ec6152c15a6ece227d4bac00c3b02
          this.a.a();
      }
  
-@@ -229,6 +253,35 @@ public class VillagePlace extends RegionFileSection<VillagePlaceSection> {
+@@ -234,6 +258,35 @@ public class VillagePlace extends RegionFileSection<VillagePlaceSection> {
          }
      }
  
@@ -3933,11 +3893,11 @@ index c999f8c9bf8a59e19b3d6d1b7ad8b5fb6e48b928..1a5ec6152c15a6ece227d4bac00c3b02
  
          HAS_SPACE(VillagePlaceRecord::d), IS_OCCUPIED(VillagePlaceRecord::e), ANY((villageplacerecord) -> {
 diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
-index 83585f3ba7ef9e72f3702079a82f62c8b17e4077..83e6c872028107a17de1c08a5f6e8a02d62277ea 100644
+index 2738d61709a956e83ab7b4e05063a99bcbb7e01b..88a7217101070222c3c9a07ce6a6d7d75573144d 100644
 --- a/src/main/java/net/minecraft/server/WorldServer.java
 +++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -82,6 +82,79 @@ public class WorldServer extends World {
-         return new Throwable(entity + " Added to world at " + new java.util.Date());
+@@ -94,6 +94,79 @@ public class WorldServer extends World implements GeneratorAccessSeed {
+         return this.chunkProvider.getChunkAt(x, z, false);
      }
  
 +    // Paper start - Asynchronous IO
@@ -3993,7 +3953,7 @@ index 83585f3ba7ef9e72f3702079a82f62c8b17e4077..83e6c872028107a17de1c08a5f6e8a02
 +                RegionFile file;
 +
 +                try {
-+                    file = WorldServer.this.getChunkProvider().playerChunkMap.getFile(new ChunkCoordIntPair(chunkX, chunkZ), false);
++                    file = WorldServer.this.getChunkProvider().playerChunkMap.regionFileCache.getFile(new ChunkCoordIntPair(chunkX, chunkZ), false);
 +                } catch (java.io.IOException ex) {
 +                    throw new RuntimeException(ex);
 +                }
@@ -4005,7 +3965,7 @@ index 83585f3ba7ef9e72f3702079a82f62c8b17e4077..83e6c872028107a17de1c08a5f6e8a02
 +        @Override
 +        public <T> T computeForRegionFileIfLoaded(int chunkX, int chunkZ, java.util.function.Function<RegionFile, T> function) {
 +            synchronized (WorldServer.this.getChunkProvider().playerChunkMap) {
-+                RegionFile file = WorldServer.this.getChunkProvider().playerChunkMap.getRegionFileIfLoaded(new ChunkCoordIntPair(chunkX, chunkZ));
++                RegionFile file = WorldServer.this.getChunkProvider().playerChunkMap.regionFileCache.getRegionFileIfLoaded(new ChunkCoordIntPair(chunkX, chunkZ));
 +                return function.apply(file);
 +            }
 +        }
@@ -4013,19 +3973,19 @@ index 83585f3ba7ef9e72f3702079a82f62c8b17e4077..83e6c872028107a17de1c08a5f6e8a02
 +    public final com.destroystokyo.paper.io.chunk.ChunkTaskManager asyncChunkTaskManager;
 +    // Paper end
 +
-     // Add env and gen to constructor
-     public WorldServer(MinecraftServer minecraftserver, Executor executor, WorldNBTStorage worldnbtstorage, WorldData worlddata, DimensionManager dimensionmanager, GameProfilerFiller gameprofilerfiller, WorldLoadListener worldloadlistener, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
-         super(worlddata, dimensionmanager, executor, (world, worldprovider) -> { // Paper - pass executor down
-@@ -125,6 +198,8 @@ public class WorldServer extends World {
- 
-         this.mobSpawnerTrader = this.worldProvider.getDimensionManager().getType() == DimensionManager.OVERWORLD ? new MobSpawnerTrader(this) : null; // CraftBukkit - getType()
+     // Add env and gen to constructor, WorldData -> WorldDataServer
+     public WorldServer(MinecraftServer minecraftserver, Executor executor, Convertable.ConversionSession convertable_conversionsession, IWorldDataServer iworlddataserver, ResourceKey<World> resourcekey, ResourceKey<DimensionManager> resourcekey1, DimensionManager dimensionmanager, WorldLoadListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List<MobSpawner> list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
+         super(iworlddataserver, resourcekey, resourcekey1, dimensionmanager, minecraftserver::getMethodProfiler, false, flag, i, gen, env, executor); // Paper pass executor
+@@ -141,6 +214,8 @@ public class WorldServer extends World implements GeneratorAccessSeed {
+             this.dragonBattle = null;
+         }
          this.getServer().addWorld(this.getWorld()); // CraftBukkit
 +
 +        this.asyncChunkTaskManager = new com.destroystokyo.paper.io.chunk.ChunkTaskManager(this); // Paper
      }
  
      // CraftBukkit start
-@@ -1664,7 +1739,10 @@ public class WorldServer extends World {
+@@ -1570,7 +1645,10 @@ public class WorldServer extends World implements GeneratorAccessSeed {
          }
  
          MCUtil.getSpiralOutChunks(spawn, radiusInBlocks >> 4).forEach(pair -> {
@@ -4038,10 +3998,10 @@ index 83585f3ba7ef9e72f3702079a82f62c8b17e4077..83e6c872028107a17de1c08a5f6e8a02
      }
      public void removeTicketsForSpawn(int radiusInBlocks, BlockPosition spawn) {
 diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index cf059aa091e9c732f99b89fc347074a9c1b879a8..5aea49404717061fce4bf24e91f36217db5cee83 100644
+index 1f1839f40a406f6a2bf2d3af68c2d208d6503b2d..abf285be2b71a93681f06879177f03c0f5fdff1a 100644
 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
 +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -75,6 +75,7 @@ import net.minecraft.server.GroupDataEntity;
+@@ -74,6 +74,7 @@ import net.minecraft.server.GroupDataEntity;
  import net.minecraft.server.IBlockData;
  import net.minecraft.server.IChunkAccess;
  import net.minecraft.server.MinecraftKey;
@@ -4049,7 +4009,7 @@ index cf059aa091e9c732f99b89fc347074a9c1b879a8..5aea49404717061fce4bf24e91f36217
  import net.minecraft.server.MovingObjectPosition;
  import net.minecraft.server.PacketPlayOutCustomSoundEffect;
  import net.minecraft.server.PacketPlayOutUpdateTime;
-@@ -555,22 +556,23 @@ public class CraftWorld implements World {
+@@ -556,22 +557,23 @@ public class CraftWorld implements World {
                  return true;
              }
  
@@ -4081,9 +4041,9 @@ index cf059aa091e9c732f99b89fc347074a9c1b879a8..5aea49404717061fce4bf24e91f36217
  
              // fall through to load
              // we do this so we do not re-read the chunk data on disk
-@@ -2442,6 +2444,34 @@ public class CraftWorld implements World {
- 
-         return new CraftDragonBattle(worldProvider.o()); // PAIL rename getDragonBattle
+@@ -2445,6 +2447,34 @@ public class CraftWorld implements World {
+     public DragonBattle getEnderDragonBattle() {
+         return (getHandle().getDragonBattle() == null) ? null : new CraftDragonBattle(getHandle().getDragonBattle());
      }
 +    // Paper start
 +    @Override
diff --git a/Spigot-Server-Patches/0391-Use-getChunkIfLoadedImmediately-in-places.patch b/Spigot-Server-Patches/0377-Use-getChunkIfLoadedImmediately-in-places.patch
similarity index 65%
rename from Spigot-Server-Patches/0391-Use-getChunkIfLoadedImmediately-in-places.patch
rename to Spigot-Server-Patches/0377-Use-getChunkIfLoadedImmediately-in-places.patch
index eab049a619..684a858e98 100644
--- a/Spigot-Server-Patches/0391-Use-getChunkIfLoadedImmediately-in-places.patch
+++ b/Spigot-Server-Patches/0377-Use-getChunkIfLoadedImmediately-in-places.patch
@@ -8,10 +8,10 @@ ticket level 33 (yes getChunkIfLoaded will actually perform a chunk
 load in that case).
 
 diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
-index 6a7bdf8c5f38ca4eb578e1104375e5773269330c..ee186ed5a076ede4d89702aeb5a2128d6e7ac8cf 100644
+index 795b24c8d102417ae7e730254ecddefc06dbe0df..e382315c91540ac24821e432ee31a8244f4f7efa 100644
 --- a/src/main/java/net/minecraft/server/PlayerConnection.java
 +++ b/src/main/java/net/minecraft/server/PlayerConnection.java
-@@ -996,7 +996,7 @@ public class PlayerConnection implements PacketListenerPlayIn {
+@@ -1015,7 +1015,7 @@ public class PlayerConnection implements PacketListenerPlayIn {
                                  speed = player.abilities.walkSpeed * 10f;
                              }
                              // Paper start - Prevent moving into unloaded chunks
@@ -21,45 +21,41 @@ index 6a7bdf8c5f38ca4eb578e1104375e5773269330c..ee186ed5a076ede4d89702aeb5a2128d
                                  return;
                              }
 diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
-index 479b87eaae67909768db1ba23854f05d2e61110c..8e5c54af26d2c7abf2daae081af97caee7fd9f7a 100644
+index 1434a6e2830aa455bb6ccfd2ce8c034b8d300414..4564c6ebb3aaed1ca63ff26524bba2edda551f85 100644
 --- a/src/main/java/net/minecraft/server/World.java
 +++ b/src/main/java/net/minecraft/server/World.java
-@@ -116,8 +116,16 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
+@@ -103,6 +103,13 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
+         return (CraftServer) Bukkit.getServer();
      }
  
-     public Chunk getChunkIfLoaded(int x, int z) {
--        return ((ChunkProviderServer) this.chunkProvider).getChunkAt(x, z, false);
-+        return ((ChunkProviderServer) this.chunkProvider).getChunkAtIfLoadedImmediately(x, z); // Paper
-     }
 +    // Paper start
 +    @Override
 +    public boolean isChunkLoaded(int x, int z) {
-+        return getChunkIfLoaded(x, z) != null;
++        return ((WorldServer)this).getChunkIfLoaded(x, z) != null;
 +    }
-+
-+
 +    // Paper end
- 
-     protected World(WorldData worlddata, DimensionManager dimensionmanager, java.util.concurrent.Executor executor, BiFunction<World, WorldProvider, IChunkProvider> bifunction, GameProfilerFiller gameprofilerfiller, boolean flag, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env) { // Paper - executor
-         this.spigotConfig = new org.spigotmc.SpigotWorldConfig( worlddata.getName() ); // Spigot
-@@ -1110,14 +1118,14 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
++
+     protected World(WorldDataMutable worlddatamutable, ResourceKey<World> resourcekey, ResourceKey<DimensionManager> resourcekey1, DimensionManager dimensionmanager, Supplier<GameProfilerFiller> supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env, java.util.concurrent.Executor executor) {
+         this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((WorldDataServer) worlddatamutable).getName()); // Spigot
+         this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig((((WorldDataServer)worlddatamutable).getName()), this.spigotConfig); // Paper
+@@ -1033,14 +1040,14 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
      }
  
-     public boolean n(BlockPosition blockposition) {
--        return isOutsideWorld(blockposition) ? false : this.chunkProvider.b(blockposition.getX() >> 4, blockposition.getZ() >> 4);
+     public boolean p(BlockPosition blockposition) {
+-        return isOutsideWorld(blockposition) ? false : this.getChunkProvider().b(blockposition.getX() >> 4, blockposition.getZ() >> 4);
 +        return isOutsideWorld(blockposition) ? false : isChunkLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4); // Paper
      }
  
-     public boolean a(BlockPosition blockposition, Entity entity) {
+     public boolean a(BlockPosition blockposition, Entity entity, EnumDirection enumdirection) {
          if (isOutsideWorld(blockposition)) {
              return false;
          } else {
 -            IChunkAccess ichunkaccess = this.getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4, ChunkStatus.FULL, false);
 +            IChunkAccess ichunkaccess = this.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); // Paper
  
-             return ichunkaccess == null ? false : ichunkaccess.getType(blockposition).a((IBlockAccess) this, blockposition, entity);
+             return ichunkaccess == null ? false : ichunkaccess.getType(blockposition).a((IBlockAccess) this, blockposition, entity, enumdirection);
          }
-@@ -1233,7 +1241,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
+@@ -1161,7 +1168,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
  
          for (int i1 = i; i1 < j; ++i1) {
              for (int j1 = k; j1 < l; ++j1) {
@@ -68,8 +64,21 @@ index 479b87eaae67909768db1ba23854f05d2e61110c..8e5c54af26d2c7abf2daae081af97cae
  
                  if (chunk != null) {
                      chunk.a(oclass, axisalignedbb, list, predicate);
+diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
+index 88a7217101070222c3c9a07ce6a6d7d75573144d..3e42d52d2256c85b7dcbbd0e363fa1e1c789b1bf 100644
+--- a/src/main/java/net/minecraft/server/WorldServer.java
++++ b/src/main/java/net/minecraft/server/WorldServer.java
+@@ -91,7 +91,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
+     }
+ 
+     public Chunk getChunkIfLoaded(int x, int z) {
+-        return this.chunkProvider.getChunkAt(x, z, false);
++        return this.chunkProvider.getChunkAtIfLoadedImmediately(x, z); // Paper
+     }
+ 
+     // Paper start - Asynchronous IO
 diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java
-index f86404f83ae605159307a3ad2cca6c6c314a01af..92601c581cffac471872226abeb93ef9aa24f079 100644
+index 78f0fb5d97b077673ec542cd70bbc3ffa13f916c..b73af0a5fb2d08c2f3a52c699ef0d8ed34c83f77 100644
 --- a/src/main/java/org/spigotmc/ActivationRange.java
 +++ b/src/main/java/org/spigotmc/ActivationRange.java
 @@ -143,9 +143,10 @@ public class ActivationRange
diff --git a/Spigot-Server-Patches/0392-Reduce-sync-loads.patch b/Spigot-Server-Patches/0378-Reduce-sync-loads.patch
similarity index 91%
rename from Spigot-Server-Patches/0392-Reduce-sync-loads.patch
rename to Spigot-Server-Patches/0378-Reduce-sync-loads.patch
index cd2b995d79..7d7d74706d 100644
--- a/Spigot-Server-Patches/0392-Reduce-sync-loads.patch
+++ b/Spigot-Server-Patches/0378-Reduce-sync-loads.patch
@@ -109,7 +109,7 @@ index 331493a172f58e71b464d635efdba461082bd27d..182b440ba4802d199b8e44f7779b3401
          if (args.length < 2 || args[1].equals("*")) {
 diff --git a/src/main/java/com/destroystokyo/paper/io/SyncLoadFinder.java b/src/main/java/com/destroystokyo/paper/io/SyncLoadFinder.java
 new file mode 100644
-index 0000000000000000000000000000000000000000..59aec103295f747793fdc0a52eb45f4121aba921
+index 0000000000000000000000000000000000000000..1a68a8012f83bab9e814159c76b8c3710c7b1112
 --- /dev/null
 +++ b/src/main/java/com/destroystokyo/paper/io/SyncLoadFinder.java
 @@ -0,0 +1,172 @@
@@ -267,7 +267,7 @@ index 0000000000000000000000000000000000000000..59aec103295f747793fdc0a52eb45f41
 +            final ThrowableWithEquals other = (ThrowableWithEquals)obj;
 +            final StackTraceElement[] otherStackTrace = other.stacktrace;
 +
-+            if (this.stacktrace.length != otherStackTrace.length) {
++            if (this.stacktrace.length != otherStackTrace.length || this.hash != other.hash) {
 +                return false;
 +            }
 +
@@ -286,10 +286,10 @@ index 0000000000000000000000000000000000000000..59aec103295f747793fdc0a52eb45f41
 +    }
 +}
 diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
-index 981cf581c7504c38120d48c06b6351952fab43c0..54cf319e9db1aad793ab7f55249f9857b450eda2 100644
+index edd901bb53385fa3d189a0057d57f98bf8b7115c..707db4febac59a4d09d6420ea2add469cf54c2ec 100644
 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
 +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
-@@ -470,6 +470,7 @@ public class ChunkProviderServer extends IChunkProvider {
+@@ -471,6 +471,7 @@ public class ChunkProviderServer extends IChunkProvider {
                  this.world.asyncChunkTaskManager.raisePriority(x, z, com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGHEST_PRIORITY);
                  com.destroystokyo.paper.io.chunk.ChunkTaskManager.pushChunkWait(this.world, x, z);
                  // Paper end
@@ -298,19 +298,19 @@ index 981cf581c7504c38120d48c06b6351952fab43c0..54cf319e9db1aad793ab7f55249f9857
              this.serverThreadQueue.awaitTasks(completablefuture::isDone);
                  com.destroystokyo.paper.io.chunk.ChunkTaskManager.popChunkWait(); // Paper - async chunk debug
 diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
-index 8e5c54af26d2c7abf2daae081af97caee7fd9f7a..045e449c7e411dec7ef415c76c808cda426db652 100644
+index 4564c6ebb3aaed1ca63ff26524bba2edda551f85..ddd66c2519d67585df06d68612a0c8a8830669ac 100644
 --- a/src/main/java/net/minecraft/server/World.java
 +++ b/src/main/java/net/minecraft/server/World.java
-@@ -1174,7 +1174,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
+@@ -1101,7 +1101,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
  
          for (int i1 = i; i1 <= j; ++i1) {
              for (int j1 = k; j1 <= l; ++j1) {
--                Chunk chunk = this.getChunkProvider().getChunkAt(i1, j1, false);
+-                Chunk chunk = ichunkprovider.getChunkAt(i1, j1, false);
 +                Chunk chunk = (Chunk)this.getChunkIfLoadedImmediately(i1, j1); // Paper
  
                  if (chunk != null) {
                      chunk.a(entity, axisalignedbb, list, predicate);
-@@ -1195,7 +1195,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
+@@ -1122,7 +1122,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
  
          for (int i1 = i; i1 < j; ++i1) {
              for (int j1 = k; j1 < l; ++j1) {
@@ -319,7 +319,7 @@ index 8e5c54af26d2c7abf2daae081af97caee7fd9f7a..045e449c7e411dec7ef415c76c808cda
  
                  if (chunk != null) {
                      chunk.a(entitytypes, axisalignedbb, list, predicate);
-@@ -1218,7 +1218,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
+@@ -1145,7 +1145,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
  
          for (int i1 = i; i1 < j; ++i1) {
              for (int j1 = k; j1 < l; ++j1) {
@@ -329,10 +329,10 @@ index 8e5c54af26d2c7abf2daae081af97caee7fd9f7a..045e449c7e411dec7ef415c76c808cda
                  if (chunk != null) {
                      chunk.a(oclass, axisalignedbb, list, predicate);
 diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
-index 83e6c872028107a17de1c08a5f6e8a02d62277ea..da38293cf02d84f3e24a883136ffe5118a510b5a 100644
+index 3e42d52d2256c85b7dcbbd0e363fa1e1c789b1bf..0dd249f94905c30b5320109a3f0b17cac70def8d 100644
 --- a/src/main/java/net/minecraft/server/WorldServer.java
 +++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -154,6 +154,12 @@ public class WorldServer extends World {
+@@ -166,6 +166,12 @@ public class WorldServer extends World implements GeneratorAccessSeed {
      };
      public final com.destroystokyo.paper.io.chunk.ChunkTaskManager asyncChunkTaskManager;
      // Paper end
@@ -343,5 +343,5 @@ index 83e6c872028107a17de1c08a5f6e8a02d62277ea..da38293cf02d84f3e24a883136ffe511
 +    }
 +    // Paper end
  
-     // Add env and gen to constructor
-     public WorldServer(MinecraftServer minecraftserver, Executor executor, WorldNBTStorage worldnbtstorage, WorldData worlddata, DimensionManager dimensionmanager, GameProfilerFiller gameprofilerfiller, WorldLoadListener worldloadlistener, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
+     // Add env and gen to constructor, WorldData -> WorldDataServer
+     public WorldServer(MinecraftServer minecraftserver, Executor executor, Convertable.ConversionSession convertable_conversionsession, IWorldDataServer iworlddataserver, ResourceKey<World> resourcekey, ResourceKey<DimensionManager> resourcekey1, DimensionManager dimensionmanager, WorldLoadListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List<MobSpawner> list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
diff --git a/Spigot-Server-Patches/0393-Implement-alternative-item-despawn-rate.patch b/Spigot-Server-Patches/0379-Implement-alternative-item-despawn-rate.patch
similarity index 91%
rename from Spigot-Server-Patches/0393-Implement-alternative-item-despawn-rate.patch
rename to Spigot-Server-Patches/0379-Implement-alternative-item-despawn-rate.patch
index 1479d50390..47adb6a101 100644
--- a/Spigot-Server-Patches/0393-Implement-alternative-item-despawn-rate.patch
+++ b/Spigot-Server-Patches/0379-Implement-alternative-item-despawn-rate.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Implement alternative item-despawn-rate
 
 
 diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-index 7101ef0912221bdb1c32d2cafbac5d9d53e7037d..9b43b4172ae5df253479a412ec0d83fed08d70f1 100644
+index a6e68b2ab8890d9d2a842ca0a6b565a1831fed6b..cf9d980e61be199a34cff98f805e511f9410dd51 100644
 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 @@ -1,10 +1,15 @@
@@ -24,7 +24,7 @@ index 7101ef0912221bdb1c32d2cafbac5d9d53e7037d..9b43b4172ae5df253479a412ec0d83fe
  import org.bukkit.configuration.file.YamlConfiguration;
  import org.spigotmc.SpigotWorldConfig;
  
-@@ -546,4 +551,52 @@ public class PaperWorldConfig {
+@@ -514,4 +519,52 @@ public class PaperWorldConfig {
      private void disableRelativeProjectileVelocity() {
          disableRelativeProjectileVelocity = getBoolean("game-mechanics.disable-relative-projectile-velocity", false);
      }
@@ -78,7 +78,7 @@ index 7101ef0912221bdb1c32d2cafbac5d9d53e7037d..9b43b4172ae5df253479a412ec0d83fe
 +    }
  }
 diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java
-index ef2cf6565b5935b1f1a80f12670609017aebb2c8..507627a29f67c380314d2fa8ee56807ced8ee56a 100644
+index 465550656356394074ebf4cc8d6188455daded88..f2626358d16e8f3d60633283322009e5afacd145 100644
 --- a/src/main/java/net/minecraft/server/EntityItem.java
 +++ b/src/main/java/net/minecraft/server/EntityItem.java
 @@ -6,6 +6,7 @@ import java.util.Objects;
@@ -89,7 +89,7 @@ index ef2cf6565b5935b1f1a80f12670609017aebb2c8..507627a29f67c380314d2fa8ee56807c
  import org.bukkit.event.entity.EntityPickupItemEvent;
  import org.bukkit.event.player.PlayerPickupItemEvent;
  // CraftBukkit end
-@@ -128,7 +129,7 @@ public class EntityItem extends Entity {
+@@ -129,7 +130,7 @@ public class EntityItem extends Entity {
                  }
              }
  
@@ -98,7 +98,7 @@ index ef2cf6565b5935b1f1a80f12670609017aebb2c8..507627a29f67c380314d2fa8ee56807c
                  // CraftBukkit start - fire ItemDespawnEvent
                  if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) {
                      this.age = 0;
-@@ -152,7 +153,7 @@ public class EntityItem extends Entity {
+@@ -153,7 +154,7 @@ public class EntityItem extends Entity {
          this.lastTick = MinecraftServer.currentTick;
          // CraftBukkit end
  
@@ -107,7 +107,7 @@ index ef2cf6565b5935b1f1a80f12670609017aebb2c8..507627a29f67c380314d2fa8ee56807c
              // CraftBukkit start - fire ItemDespawnEvent
              if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) {
                  this.age = 0;
-@@ -478,9 +479,16 @@ public class EntityItem extends Entity {
+@@ -497,9 +498,16 @@ public class EntityItem extends Entity {
  
      public void s() {
          this.o();
@@ -123,5 +123,5 @@ index ef2cf6565b5935b1f1a80f12670609017aebb2c8..507627a29f67c380314d2fa8ee56807c
 +    // Paper end
 +
      @Override
-     public Packet<?> L() {
+     public Packet<?> O() {
          return new PacketPlayOutSpawnEntity(this);
diff --git a/Spigot-Server-Patches/0380-Do-less-work-if-we-have-a-custom-Bukkit-generator.patch b/Spigot-Server-Patches/0380-Do-less-work-if-we-have-a-custom-Bukkit-generator.patch
new file mode 100644
index 0000000000..3f88179170
--- /dev/null
+++ b/Spigot-Server-Patches/0380-Do-less-work-if-we-have-a-custom-Bukkit-generator.patch
@@ -0,0 +1,40 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Paul Sauve <paul@burngames.net>
+Date: Sun, 14 Jul 2019 21:05:03 -0500
+Subject: [PATCH] Do less work if we have a custom Bukkit generator
+
+If the Bukkit generator already has a spawn, use it immediately instead
+of spending time generating one that we won't use
+
+diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
+index 7e832d2610f9c0d805c7f289de5098d9b5f09402..824c3763a56171ceb5f7163783cd46154b7e181e 100644
+--- a/src/main/java/net/minecraft/server/MinecraftServer.java
++++ b/src/main/java/net/minecraft/server/MinecraftServer.java
+@@ -513,11 +513,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
+         } else if (flag1) {
+             iworlddataserver.setSpawn(BlockPosition.ZERO.up());
+         } else {
+-            WorldChunkManager worldchunkmanager = chunkgenerator.getWorldChunkManager();
+-            List<BiomeBase> list = worldchunkmanager.b();
+-            Random random = new Random(worldserver.getSeed());
+-            BlockPosition blockposition = worldchunkmanager.a(0, worldserver.getSeaLevel(), 0, 256, list, random);
+-            ChunkCoordIntPair chunkcoordintpair = blockposition == null ? new ChunkCoordIntPair(0, 0) : new ChunkCoordIntPair(blockposition);
++            // Paper start - moved down
+             // CraftBukkit start
+             if (worldserver.generator != null) {
+                 Random rand = new Random(worldserver.getSeed());
+@@ -533,6 +529,14 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
+                 }
+             }
+             // CraftBukkit end
++            // Paper start - if the generator created a spawn for us, then there is no need for us to also create a spawn -
++            // only do it if the generator did not
++            WorldChunkManager worldchunkmanager = chunkgenerator.getWorldChunkManager();
++            List<BiomeBase> list = worldchunkmanager.b();
++            Random random = new Random(worldserver.getSeed());
++            BlockPosition blockposition = worldchunkmanager.a(0, worldserver.getSeaLevel(), 0, 256, list, random);
++            ChunkCoordIntPair chunkcoordintpair = blockposition == null ? new ChunkCoordIntPair(0, 0) : new ChunkCoordIntPair(blockposition);
++            // Paper end
+ 
+             if (blockposition == null) {
+                 MinecraftServer.LOGGER.warn("Unable to find spawn biome");
diff --git a/Spigot-Server-Patches/0395-Fix-MC-158900.patch b/Spigot-Server-Patches/0381-Fix-MC-158900.patch
similarity index 90%
rename from Spigot-Server-Patches/0395-Fix-MC-158900.patch
rename to Spigot-Server-Patches/0381-Fix-MC-158900.patch
index b7d14ec681..f08fb6bd61 100644
--- a/Spigot-Server-Patches/0395-Fix-MC-158900.patch
+++ b/Spigot-Server-Patches/0381-Fix-MC-158900.patch
@@ -7,10 +7,10 @@ The problem was we were checking isExpired() on the entry, but if it
 was expired at that point, then it would be null.
 
 diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
-index 559a411627ed7b018f00b90e8dfc1b470af4a531..3cc9c70882bfb9a933c726b7a194aa3b142034fa 100644
+index 8d067082ad52397d11822277438f00a43d7f3e09..93d30964fee7117beca92653df62f474730d866e 100644
 --- a/src/main/java/net/minecraft/server/PlayerList.java
 +++ b/src/main/java/net/minecraft/server/PlayerList.java
-@@ -502,8 +502,10 @@ public abstract class PlayerList {
+@@ -532,8 +532,10 @@ public abstract class PlayerList {
          Player player = entity.getBukkitEntity();
          PlayerLoginEvent event = new PlayerLoginEvent(player, hostname, ((java.net.InetSocketAddress) socketaddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.networkManager.getRawAddress()).getAddress());
  
diff --git a/Spigot-Server-Patches/0396-implement-optional-per-player-mob-spawns.patch b/Spigot-Server-Patches/0382-implement-optional-per-player-mob-spawns.patch
similarity index 68%
rename from Spigot-Server-Patches/0396-implement-optional-per-player-mob-spawns.patch
rename to Spigot-Server-Patches/0382-implement-optional-per-player-mob-spawns.patch
index cf5dc5764c..c0e8da7d7d 100644
--- a/Spigot-Server-Patches/0396-implement-optional-per-player-mob-spawns.patch
+++ b/Spigot-Server-Patches/0382-implement-optional-per-player-mob-spawns.patch
@@ -25,10 +25,10 @@ index 98acbfa44dd9042b26fdf719d7748f92d201c928..a94ebf7c76f167d3b66f7d243910c13d
          poiUnload = Timings.ofSafe(name + "Chunk unload - POI");
          chunkUnload = Timings.ofSafe(name + "Chunk unload - Chunk");
 diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-index 9b43b4172ae5df253479a412ec0d83fed08d70f1..c148a57a9c3d44f2a0a2edfed4f96211745cc3e7 100644
+index cf9d980e61be199a34cff98f805e511f9410dd51..3d9a48e56194225cf39e31d13d26ec17afedadaf 100644
 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-@@ -599,4 +599,9 @@ public class PaperWorldConfig {
+@@ -567,4 +567,9 @@ public class PaperWorldConfig {
              }
          }
      }
@@ -545,16 +545,16 @@ index 0000000000000000000000000000000000000000..4f13d3ff8391793a99f067189f854078
 +    }
 +}
 diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
-index 54cf319e9db1aad793ab7f55249f9857b450eda2..633f12098973857eca04acd2839bb4d453860f1e 100644
+index 707db4febac59a4d09d6420ea2add469cf54c2ec..1597b7a882769109f467d81ecbadc45ff6779b7e 100644
 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
 +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
-@@ -757,7 +757,22 @@ public class ChunkProviderServer extends IChunkProvider {
+@@ -744,7 +744,22 @@ public class ChunkProviderServer extends IChunkProvider {
+             this.world.getMethodProfiler().enter("naturalSpawnCount");
              this.world.timings.countNaturalMobs.startTiming(); // Paper - timings
              int l = this.chunkMapDistance.b();
-             EnumCreatureType[] aenumcreaturetype = EnumCreatureType.values();
--            Object2IntMap<EnumCreatureType> object2intmap = this.world.l();
+-            SpawnerCreature.d spawnercreature_d = SpawnerCreature.a(l, this.world.z(), this::a);
 +            // Paper start - per player mob spawning
-+            int[] worldMobCount;
++            SpawnerCreature.d spawnercreature_d; // moved down
 +            if (this.playerChunkMap.playerMobDistanceMap != null) {
 +                // update distance map
 +                this.world.timings.playerMobDistanceMapUpdate.startTiming();
@@ -564,45 +564,19 @@ index 54cf319e9db1aad793ab7f55249f9857b450eda2..633f12098973857eca04acd2839bb4d4
 +                for (EntityPlayer player : this.world.players) {
 +                    Arrays.fill(player.mobCounts, 0);
 +                }
-+                worldMobCount = this.world.countMobs(true);
++                spawnercreature_d = SpawnerCreature.countMobs(l, this.world.z(), this::a, true);
 +            } else {
-+                worldMobCount = this.world.countMobs(false);
++                spawnercreature_d = SpawnerCreature.countMobs(l, this.world.z(), this::a, false);
 +            }
 +            // Paper end
- 
              this.world.timings.countNaturalMobs.stopTiming(); // Paper - timings
-             this.world.getMethodProfiler().exit();
-@@ -825,8 +840,23 @@ public class ChunkProviderServer extends IChunkProvider {
-                                 if (enumcreaturetype != EnumCreatureType.MISC && (!enumcreaturetype.c() || this.allowAnimals) && (enumcreaturetype.c() || this.allowMonsters) && (!enumcreaturetype.d() || flag2)) {
-                                     int k1 = limit * l / ChunkProviderServer.b; // CraftBukkit - use per-world limits
  
--                                    if (object2intmap.getInt(enumcreaturetype) <= k1) {
--                                        SpawnerCreature.a(enumcreaturetype, this.world, chunk, blockposition);
-+                                    // Paper start - only allow spawns upto the limit per chunk and update count afterwards
-+                                    int currEntityCount = worldMobCount[enumcreaturetype.ordinal()];
-+                                    int difference = k1 - currEntityCount;
-+
-+                                    if (this.world.paperConfig.perPlayerMobSpawns) {
-+                                        int minDiff = Integer.MAX_VALUE;
-+                                        for (EntityPlayer entityplayer : this.playerChunkMap.playerMobDistanceMap.getPlayersInRange(chunk.getPos())) {
-+                                            minDiff = Math.min(limit - this.playerChunkMap.getMobCountNear(entityplayer, enumcreaturetype), minDiff);
-+                                        }
-+                                        difference = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff;
-+                                    }
-+
-+                                    if (difference > 0) {
-+                                        int spawnCount = SpawnerCreature.spawnMobs(enumcreaturetype, this.world, chunk, blockposition, difference,
-+                                            this.world.paperConfig.perPlayerMobSpawns ? this.playerChunkMap::updatePlayerMobTypeMap : null);
-+                                        worldMobCount[enumcreaturetype.ordinal()] += spawnCount;
-+                                        // Paper end
-                                     }
-                                 }
-                             }
+             this.p = spawnercreature_d;
 diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
-index 57b393c22448910c3ecc34353c3aa8480c58c074..3db173fb5559e62150192a28dbdccdff16787401 100644
+index df8db93a7b2783c738281adb0b696ff41a5105d0..f967f08049d792b1f2542828ed28de9e94949bab 100644
 --- a/src/main/java/net/minecraft/server/EntityPlayer.java
 +++ b/src/main/java/net/minecraft/server/EntityPlayer.java
-@@ -81,6 +81,11 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
+@@ -85,6 +85,11 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
      public boolean queueHealthUpdatePacket = false;
      public net.minecraft.server.PacketPlayOutUpdateHealth queuedHealthUpdatePacket;
      // Paper end
@@ -614,7 +588,7 @@ index 57b393c22448910c3ecc34353c3aa8480c58c074..3db173fb5559e62150192a28dbdccdff
  
      // CraftBukkit start
      public String displayName;
-@@ -116,6 +121,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
+@@ -120,6 +125,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
          this.displayName = this.getName();
          this.canPickUpLoot = true;
          this.maxHealthCache = this.getMaxHealth();
@@ -622,43 +596,43 @@ index 57b393c22448910c3ecc34353c3aa8480c58c074..3db173fb5559e62150192a28dbdccdff
      }
  
      // Yes, this doesn't match Vanilla, but it's the best we can do for now.
-@@ -1791,6 +1797,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
+@@ -1929,6 +1935,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
  
      }
  
-+    public SectionPosition getPlayerMapSection() { return this.K(); } // Paper - OBFHELPER
-     public SectionPosition K() {
-         return this.cs;
++    public final SectionPosition getPlayerMapSection() { return this.N(); } // Paper - OBFHELPER
+     public SectionPosition N() {
+         return this.cq;
      }
 diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java
-index 8427ee2ee8b90d5deb686412bb2eefb9a574b75a..0f04bcc8b7cd5bd0536dd3fccab0f4dae6b0130b 100644
+index b9fe08301409bc1f0d61a7566c26e720ff720d80..18a806ebbf092b904983691529ce5edf2da4e6db 100644
 --- a/src/main/java/net/minecraft/server/EntityTypes.java
 +++ b/src/main/java/net/minecraft/server/EntityTypes.java
-@@ -254,6 +254,7 @@ public class EntityTypes<T extends Entity> {
-         return this.bf;
+@@ -265,6 +265,7 @@ public class EntityTypes<T extends Entity> {
+         return this.bk;
      }
  
-+    public EnumCreatureType getEnumCreatureType() { return this.e(); } // Paper - OBFHELPER
++    public final EnumCreatureType getEnumCreatureType() { return this.e(); } // Paper - OBFHELPER
      public EnumCreatureType e() {
-         return this.bb;
+         return this.bf;
      }
 diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
-index 6552bbf06637b08626cbf0fb352123c3e381cb5a..c20acd86beb8f28345d1359d0a2b68b7d8e0e410 100644
+index cdb72b225226083ca45ade798f54989422e5281c..f7e57fd1ce5881c056c104d5a6a9a74e34e3ffc3 100644
 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
 +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
-@@ -78,7 +78,8 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
-     private final PlayerMap playerMap;
+@@ -80,7 +80,8 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
      public final Int2ObjectMap<PlayerChunkMap.EntityTracker> trackedEntities;
-     private final Queue<Runnable> z;
+     private final Long2ByteMap z;
+     private final Queue<Runnable> A; private final Queue<Runnable> getUnloadQueueTasks() { return this.A; } // Paper - OBFHELPER
 -    private int viewDistance;
 +    int viewDistance; // Paper - private -> package private
 +    public final com.destroystokyo.paper.util.PlayerMobDistanceMap playerMobDistanceMap; // Paper
  
      // CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback()
      public final CallbackExecutor callbackExecutor = new CallbackExecutor();
-@@ -158,6 +159,24 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -159,6 +160,24 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
          this.l = supplier;
-         this.m = new VillagePlace(new File(this.w, "poi"), datafixer, this.world); // Paper
+         this.m = new VillagePlace(new File(this.w, "poi"), datafixer, flag, this.world); // Paper
          this.setViewDistance(i);
 +        this.playerMobDistanceMap = this.world.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper
 +    }
@@ -682,120 +656,170 @@ index 6552bbf06637b08626cbf0fb352123c3e381cb5a..c20acd86beb8f28345d1359d0a2b68b7
  
      private static double a(ChunkCoordIntPair chunkcoordintpair, Entity entity) {
 diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
-index fdac5bb3a2d4a73035e1d914979b87fc224b6b20..58bbf2f9d2ec91715051d40e108e16067bb36561 100644
+index 86e906361ed998ba94ff6e1cbe21860a88626c3b..011e017a8121799cd00d3371bb6bb8f237b5b2bf 100644
 --- a/src/main/java/net/minecraft/server/SpawnerCreature.java
 +++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
-@@ -3,6 +3,7 @@ package net.minecraft.server;
- import java.util.List;
- import java.util.Objects;
- import java.util.Random;
-+import java.util.function.Consumer; // Paper
- import javax.annotation.Nullable;
- import org.apache.logging.log4j.LogManager;
- import org.apache.logging.log4j.Logger;
-@@ -16,9 +17,14 @@ public final class SpawnerCreature {
+@@ -29,6 +29,11 @@ public final class SpawnerCreature {
+     });
  
-     private static final Logger LOGGER = LogManager.getLogger();
- 
-+    // Paper start - add maxSpawns parameter and return spawned mobs
-     public static void a(EnumCreatureType enumcreaturetype, WorldServer worldserver, Chunk chunk, BlockPosition blockposition) {
-+        spawnMobs(enumcreaturetype, worldserver, chunk, blockposition, Integer.MAX_VALUE, null);
+     public static SpawnerCreature.d a(int i, Iterable<Entity> iterable, SpawnerCreature.b spawnercreature_b) {
++        // Paper start - add countMobs parameter
++        return countMobs(i, iterable, spawnercreature_b, false);
 +    }
-+    public static int spawnMobs(EnumCreatureType enumcreaturetype, WorldServer worldserver, Chunk chunk, BlockPosition blockposition, int maxSpawns, Consumer<Entity> trackEntity) {
-+        // Paper end
-         ChunkGenerator<?> chunkgenerator = worldserver.getChunkProvider().getChunkGenerator();
--        int i = 0;
-+        int i = 0; // Paper - force diff on name change
-         BlockPosition blockposition1 = getRandomPosition(worldserver, chunk);
-         int j = blockposition1.getX();
-         int k = blockposition1.getY();
-@@ -88,7 +94,7 @@ public final class SpawnerCreature {
-                                                         );
-                                                         if (!event.callEvent()) {
-                                                             if (event.shouldAbortSpawn()) {
--                                                                return;
-+                                                                return i; // Paper
-                                                             }
-                                                             ++i2;
-                                                             continue;
-@@ -107,7 +113,7 @@ public final class SpawnerCreature {
-                                                         } catch (Exception exception) {
-                                                             SpawnerCreature.LOGGER.warn("Failed to create mob", exception);
-                                                             ServerInternalException.reportInternalException(exception); // Paper
--                                                            return;
-+                                                            return i; // Paper
-                                                         }
- 
-                                                         entityinsentient.setPositionRotation((double) f, (double) k, (double) f1, worldserver.random.nextFloat() * 360.0F, 0.0F);
-@@ -115,12 +121,16 @@ public final class SpawnerCreature {
-                                                             groupdataentity = entityinsentient.prepare(worldserver, worldserver.getDamageScaler(new BlockPosition(entityinsentient)), EnumMobSpawn.NATURAL, groupdataentity, (NBTTagCompound) null);
-                                                             // CraftBukkit start
-                                                             if (worldserver.addEntity(entityinsentient, SpawnReason.NATURAL)) {
--                                                                ++i;
-+                                                                ++i; // Paper - force diff on name change
-                                                                 ++i2;
-+                                                                if (trackEntity != null) {
-+                                                                    trackEntity.accept(entityinsentient); // Paper
-+                                                                }
-                                                             }
-+                                                            if (i >= maxSpawns) { return i; } // Paper
-                                                             // CraftBukkit end
-                                                             if (i >= entityinsentient.getMaxSpawnGroup()) {
--                                                                return;
-+                                                                return i; // Paper
-                                                             }
- 
-                                                             if (entityinsentient.c(i2)) {
-@@ -146,6 +156,7 @@ public final class SpawnerCreature {
++    public static SpawnerCreature.d countMobs(int i, Iterable<Entity> iterable, SpawnerCreature.b spawnercreature_b, boolean countMobs) {
++        // Paper end - add countMobs parameter
+         SpawnerCreatureProbabilities spawnercreatureprobabilities = new SpawnerCreatureProbabilities();
+         Object2IntOpenHashMap<EnumCreatureType> object2intopenhashmap = new Object2IntOpenHashMap();
+         Iterator iterator = iterable.iterator();
+@@ -67,6 +72,11 @@ public final class SpawnerCreature {
+                     }
  
+                     object2intopenhashmap.addTo(enumcreaturetype, 1);
++                    // Paper start
++                    if (countMobs) {
++                        ((WorldServer)chunk.world).getChunkProvider().playerChunkMap.updatePlayerMobTypeMap(entity);
++                    }
++                    // Paper end
+                 });
              }
          }
-+        return i; // Paper
-     }
+@@ -120,13 +130,33 @@ public final class SpawnerCreature {
+                 continue;
+             }
  
-     @Nullable
-diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
-index 135d1211525f499198122e500626ce463c263088..80e2a15bebe93939dc7b43b17b8116965438c062 100644
---- a/src/main/java/net/minecraft/server/WorldServer.java
-+++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -1031,7 +1031,20 @@ public class WorldServer extends World {
-     }
- 
-     public Object2IntMap<EnumCreatureType> l() {
--        Object2IntMap<EnumCreatureType> object2intmap = new Object2IntOpenHashMap();
-+        // Paper start
-+        int[] values = this.countMobs(false);
-+        EnumCreatureType[] byId = EnumCreatureType.values();
-+        Object2IntMap<EnumCreatureType> ret = new Object2IntOpenHashMap<>();
++            // Paper start - only allow spawns upto the limit per chunk and update count afterwards
++            int currEntityCount = spawnercreature_d.getEntityCountsByType().getInt(enumcreaturetype);
++            int k1 = limit * spawnercreature_d.getSpawnerChunks() / SpawnerCreature.b;
++            int difference = k1 - currEntityCount;
 +
-+        for (int i = 0, len = values.length; i < len; ++i) {
-+            ret.put(byId[i], values[i]);
-+        }
-+
-+        return ret;
-+    }
-+    public int[] countMobs(boolean updatePlayerCounts) {
-+        int[] ret = new int[EntityPlayer.ENUMCREATURETYPE_TOTAL_ENUMS];
-+        // Paper end
-         ObjectIterator objectiterator = this.entitiesById.values().iterator();
- 
-         while (objectiterator.hasNext()) {
-@@ -1056,11 +1069,16 @@ public class WorldServer extends World {
-                     continue;
-                 }
-                 // Paper end
--                object2intmap.mergeInt(enumcreaturetype, 1, Integer::sum);
-+                // Paper start - rework mob spawning
-+                if (updatePlayerCounts) {
-+                    this.getChunkProvider().playerChunkMap.updatePlayerMobTypeMap(entity);
++            if (worldserver.paperConfig.perPlayerMobSpawns) {
++                int minDiff = Integer.MAX_VALUE;
++                for (EntityPlayer entityplayer : worldserver.getChunkProvider().playerChunkMap.playerMobDistanceMap.getPlayersInRange(chunk.getPos())) {
++                    minDiff = Math.min(limit - worldserver.getChunkProvider().playerChunkMap.getMobCountNear(entityplayer, enumcreaturetype), minDiff);
 +                }
-+                ++ret[enumcreaturetype.ordinal()];
-+                // Paper end
++                difference = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff;
++            }
++            // Paper end
++
++            if (difference > 0) { // Paper
+             if ((flag || !enumcreaturetype.d()) && (flag1 || enumcreaturetype.d()) && (flag2 || !enumcreaturetype.e()) && spawnercreature_d.a(enumcreaturetype, limit)) {
+                 // CraftBukkit end
+-                a(enumcreaturetype, worldserver, chunk, (entitytypes, blockposition, ichunkaccess) -> {
++                int spawnCount = spawnMobs(enumcreaturetype, worldserver, chunk, (entitytypes, blockposition, ichunkaccess) -> {
+                     return spawnercreature_d.a(entitytypes, blockposition, ichunkaccess);
+                 }, (entityinsentient, ichunkaccess) -> {
+                     spawnercreature_d.a(entityinsentient, ichunkaccess);
++                },
++                limit, worldserver.paperConfig.perPlayerMobSpawns ? worldserver.getChunkProvider().playerChunkMap::updatePlayerMobTypeMap : null);
++                spawnercreature_d.getEntityCountsByType().mergeInt(enumcreaturetype, 0, (keyInMap, valueInMap) -> {
++                    return Integer.valueOf(spawnCount + valueInMap.intValue());
+                 });
++                } // Paper
              }
          }
  
--        return object2intmap;
-+        return ret;
+@@ -135,22 +165,34 @@ public final class SpawnerCreature {
      }
  
-     @Override
+     public static void a(EnumCreatureType enumcreaturetype, WorldServer worldserver, Chunk chunk, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a) {
++        // Paper start - add parameters and int ret type
++        spawnMobs(enumcreaturetype, worldserver, chunk, spawnercreature_c, spawnercreature_a, Integer.MAX_VALUE, null);
++    }
++    public static int spawnMobs(EnumCreatureType enumcreaturetype, WorldServer worldserver, Chunk chunk, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a, int maxSpawns, Consumer<Entity> trackEntity) {
++        // Paper end - add parameters and int ret type
+         BlockPosition blockposition = getRandomPosition(worldserver, chunk);
+ 
+         if (blockposition.getY() >= 1) {
+-            a(enumcreaturetype, worldserver, (IChunkAccess) chunk, blockposition, spawnercreature_c, spawnercreature_a);
++            return spawnMobsInternal(enumcreaturetype, worldserver, (IChunkAccess) chunk, blockposition, spawnercreature_c, spawnercreature_a, maxSpawns, trackEntity);
+         }
++        return 0; // Paper
+     }
+ 
+     public static void a(EnumCreatureType enumcreaturetype, WorldServer worldserver, IChunkAccess ichunkaccess, BlockPosition blockposition, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a) {
++        // Paper start - add maxSpawns parameter and return spawned mobs
++        spawnMobsInternal(enumcreaturetype, worldserver, ichunkaccess, blockposition, spawnercreature_c, spawnercreature_a, Integer.MAX_VALUE, null);
++    }
++    public static int spawnMobsInternal(EnumCreatureType enumcreaturetype, WorldServer worldserver, IChunkAccess ichunkaccess, BlockPosition blockposition, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a, int maxSpawns, Consumer<Entity> trackEntity) {
++        // Paper end - add maxSpawns parameter and return spawned mobs
+         StructureManager structuremanager = worldserver.getStructureManager();
+         ChunkGenerator chunkgenerator = worldserver.getChunkProvider().getChunkGenerator();
+         int i = blockposition.getY();
+         IBlockData iblockdata = worldserver.getTypeIfLoadedAndInBounds(blockposition); // Paper - don't load chunks for mob spawn
++        int j = 0; // Paper - moved up
+ 
+         if (iblockdata != null && !iblockdata.isOccluding(ichunkaccess, blockposition)) { // Paper - don't load chunks for mob spawn
+             BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
+-            int j = 0;
++            // Paper - moved up
+             int k = 0;
+ 
+             while (k < 3) {
+@@ -190,13 +232,13 @@ public final class SpawnerCreature {
+                                     // Paper start
+                                     Boolean doSpawning = a(worldserver, enumcreaturetype, structuremanager, chunkgenerator, biomebase_biomemeta, blockposition_mutableblockposition, d2);
+                                     if (doSpawning == null) {
+-                                        return;
++                                        return j; // Paper
+                                     }
+                                     if (doSpawning.booleanValue() && spawnercreature_c.test(biomebase_biomemeta.c, blockposition_mutableblockposition, ichunkaccess)) { // Paper end
+                                         EntityInsentient entityinsentient = a(worldserver, biomebase_biomemeta.c);
+ 
+                                         if (entityinsentient == null) {
+-                                            return;
++                                            return j; // Paper
+                                         }
+ 
+                                         entityinsentient.setPositionRotation(d0, (double) i, d1, worldserver.random.nextFloat() * 360.0F, 0.0F);
+@@ -204,13 +246,18 @@ public final class SpawnerCreature {
+                                             groupdataentity = entityinsentient.prepare(worldserver, worldserver.getDamageScaler(entityinsentient.getChunkCoordinates()), EnumMobSpawn.NATURAL, groupdataentity, (NBTTagCompound) null);
+                                             // CraftBukkit start
+                                             if (worldserver.addEntity(entityinsentient, SpawnReason.NATURAL)) {
+-                                                ++j;
++                                                ++j; // Paper - force diff on name change - we expect this to be the total amount spawned
+                                                 ++k1;
+                                                 spawnercreature_a.run(entityinsentient, ichunkaccess);
++                                                // Paper start
++                                                if (trackEntity != null) {
++                                                    trackEntity.accept(entityinsentient);
++                                                }
++                                                // Paper end
+                                             }
+                                             // CraftBukkit end
+-                                            if (j >= entityinsentient.getMaxSpawnGroup()) {
+-                                                return;
++                                            if (j >= entityinsentient.getMaxSpawnGroup() || j >= maxSpawns) { // Paper
++                                                return j; // Paper
+                                             }
+ 
+                                             if (entityinsentient.c(k1)) {
+@@ -232,6 +279,7 @@ public final class SpawnerCreature {
+             }
+ 
+         }
++        return j; // Paper
+     }
+ 
+     private static boolean a(WorldServer worldserver, IChunkAccess ichunkaccess, BlockPosition.MutableBlockPosition blockposition_mutableblockposition, double d0) {
+@@ -471,10 +519,10 @@ public final class SpawnerCreature {
+ 
+     public static class d {
+ 
+-        private final int a;
++        private final int a; final int getSpawnerChunks() { return this.a; } // Paper - OBFHELPER
+         private final Object2IntOpenHashMap<EnumCreatureType> b;
+         private final SpawnerCreatureProbabilities c;
+-        private final Object2IntMap<EnumCreatureType> d;
++        private final Object2IntMap<EnumCreatureType> d; final Object2IntMap<EnumCreatureType> getEntityCountsByType() { return this.d; } // Paper - OBFHELPER
+         @Nullable
+         private BlockPosition e;
+         @Nullable
+@@ -535,7 +583,7 @@ public final class SpawnerCreature {
+ 
+         // CraftBukkit start
+         private boolean a(EnumCreatureType enumcreaturetype, int limit) {
+-            int i = limit * this.a / SpawnerCreature.b;
++            int i = limit * this.a / SpawnerCreature.b; // Paper - diff on change, needed in the spawn method
+             // CraftBukkit end
+ 
+             return this.b.getInt(enumcreaturetype) < i;
diff --git a/Spigot-Server-Patches/0397-Prevent-consuming-the-wrong-itemstack.patch b/Spigot-Server-Patches/0383-Prevent-consuming-the-wrong-itemstack.patch
similarity index 80%
rename from Spigot-Server-Patches/0397-Prevent-consuming-the-wrong-itemstack.patch
rename to Spigot-Server-Patches/0383-Prevent-consuming-the-wrong-itemstack.patch
index c7c6b44c5b..4fc97cb716 100644
--- a/Spigot-Server-Patches/0397-Prevent-consuming-the-wrong-itemstack.patch
+++ b/Spigot-Server-Patches/0383-Prevent-consuming-the-wrong-itemstack.patch
@@ -5,11 +5,11 @@ Subject: [PATCH] Prevent consuming the wrong itemstack
 
 
 diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
-index 0a31f2e931bba74ecda40c3792718a530acec3af..576c9c6ae4339951d4ec9fffa69c7f860d82b33f 100644
+index 79cf31d6fcd0e82ee146c489448a93a6e55e4190..d44d594b52cd63adcede55fbe6548b758b482c90 100644
 --- a/src/main/java/net/minecraft/server/EntityLiving.java
 +++ b/src/main/java/net/minecraft/server/EntityLiving.java
-@@ -2897,10 +2897,13 @@ public abstract class EntityLiving extends Entity {
-         this.datawatcher.set(EntityLiving.ao, (byte) j);
+@@ -3062,10 +3062,13 @@ public abstract class EntityLiving extends Entity {
+         this.datawatcher.set(EntityLiving.an, (byte) j);
      }
  
 -    public void c(EnumHand enumhand) {
@@ -22,20 +22,20 @@ index 0a31f2e931bba74ecda40c3792718a530acec3af..576c9c6ae4339951d4ec9fffa69c7f86
 -        if (!itemstack.isEmpty() && !this.isHandRaised()) {
 +        if (!itemstack.isEmpty() && !this.isHandRaised() || forceUpdate) { // Paper use override flag
              this.activeItem = itemstack;
-             this.bl = itemstack.k();
+             this.bk = itemstack.k();
              if (!this.world.isClientSide) {
-@@ -2976,6 +2979,7 @@ public abstract class EntityLiving extends Entity {
-             this.clearActiveItem();
+@@ -3141,6 +3144,7 @@ public abstract class EntityLiving extends Entity {
+             this.releaseActiveItem();
          } else {
              if (!this.activeItem.isEmpty() && this.isHandRaised()) {
 +                this.updateActiveItem(this.getRaisedHand(), true); // Paper
                  this.b(this.activeItem, 16);
                  // CraftBukkit start - fire PlayerItemConsumeEvent
                  ItemStack itemstack;
-@@ -3006,8 +3010,8 @@ public abstract class EntityLiving extends Entity {
+@@ -3171,8 +3175,8 @@ public abstract class EntityLiving extends Entity {
                  this.a(this.getRaisedHand(), itemstack);
                  // CraftBukkit end
-                 this.dH();
+                 this.clearActiveItem();
 -                // Paper start - if the replacement is anything but the default, update the client inventory
 -                if (this instanceof EntityPlayer && !com.google.common.base.Objects.equal(defaultReplacement, itemstack)) {
 +                // Paper start
diff --git a/Spigot-Server-Patches/0398-only-add-passanger-entities-once-from-spawners.patch b/Spigot-Server-Patches/0384-only-add-passanger-entities-once-from-spawners.patch
similarity index 90%
rename from Spigot-Server-Patches/0398-only-add-passanger-entities-once-from-spawners.patch
rename to Spigot-Server-Patches/0384-only-add-passanger-entities-once-from-spawners.patch
index 63a8d16c97..64f30c9f2e 100644
--- a/Spigot-Server-Patches/0398-only-add-passanger-entities-once-from-spawners.patch
+++ b/Spigot-Server-Patches/0384-only-add-passanger-entities-once-from-spawners.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] only add passanger entities once from spawners
 
 
 diff --git a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
-index 41001b02a654194c4a8e25ad5f7af8fdd91090b2..df494d37be687860878c2709ae7996510118a559 100644
+index 921abae4914c7b3f28d387f7a682d991293c4798..2f1d168bd6daad1bbd41977b18263d1fe67a3da0 100644
 --- a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
 +++ b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
 @@ -196,7 +196,7 @@ public abstract class MobSpawnerAbstract {
diff --git a/Spigot-Server-Patches/0399-Fix-nether-portal-creation.patch b/Spigot-Server-Patches/0385-Fix-nether-portal-creation.patch
similarity index 100%
rename from Spigot-Server-Patches/0399-Fix-nether-portal-creation.patch
rename to Spigot-Server-Patches/0385-Fix-nether-portal-creation.patch
diff --git a/Spigot-Server-Patches/0386-Generator-Settings.patch b/Spigot-Server-Patches/0386-Generator-Settings.patch
new file mode 100644
index 0000000000..04d445d5d6
--- /dev/null
+++ b/Spigot-Server-Patches/0386-Generator-Settings.patch
@@ -0,0 +1,89 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Byteflux <byte@byteflux.net>
+Date: Wed, 2 Mar 2016 02:17:54 -0600
+Subject: [PATCH] Generator Settings
+
+
+diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+index 3d9a48e56194225cf39e31d13d26ec17afedadaf..a9d7e81ef123a7da7785a4b8dc868a0e256a61d0 100644
+--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
++++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+@@ -572,4 +572,9 @@ public class PaperWorldConfig {
+     private void perPlayerMobSpawns() {
+         perPlayerMobSpawns = getBoolean("per-player-mob-spawns", false);
+     }
++
++    public boolean generateFlatBedrock;
++    private void generatorSettings() {
++        generateFlatBedrock = getBoolean("generator-settings.flat-bedrock", false);
++    }
+ }
+diff --git a/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java b/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java
+index bbd955160802fdb231cd8090d95f4e49f10d8495..733c6244e08f6b7277006c1ed801f2cfc8fc36e5 100644
+--- a/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java
++++ b/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java
+@@ -370,8 +370,8 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator {
+         BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
+         int i = ichunkaccess.getPos().d();
+         int j = ichunkaccess.getPos().e();
+-        int k = this.h.f();
+-        int l = this.x - 1 - this.h.e();
++        int k = this.h.f(); final int floorHeight = k; // Paper
++        int l = this.x - 1 - this.h.e(); final int roofHeight = l; // Paper
+         boolean flag = true;
+         boolean flag1 = l + 4 >= 0 && l < this.x;
+         boolean flag2 = k + 4 >= 0 && k < this.x;
+@@ -385,7 +385,7 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator {
+ 
+                 if (flag1) {
+                     for (i1 = 0; i1 < 5; ++i1) {
+-                        if (i1 <= random.nextInt(5)) {
++                        if (i1 <= (ichunkaccess.generateFlatBedrock() ? roofHeight : random.nextInt(5))) { // Paper - Configurable flat bedrock roof
+                             ichunkaccess.setType(blockposition_mutableblockposition.d(blockposition.getX(), l - i1, blockposition.getZ()), Blocks.BEDROCK.getBlockData(), false);
+                         }
+                     }
+@@ -393,7 +393,7 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator {
+ 
+                 if (flag2) {
+                     for (i1 = 4; i1 >= 0; --i1) {
+-                        if (i1 <= random.nextInt(5)) {
++                        if (i1 <= (ichunkaccess.generateFlatBedrock() ? floorHeight : random.nextInt(5))) { // Paper - Configurable flat bedrock floor
+                             ichunkaccess.setType(blockposition_mutableblockposition.d(blockposition.getX(), k + i1, blockposition.getZ()), Blocks.BEDROCK.getBlockData(), false);
+                         }
+                     }
+diff --git a/src/main/java/net/minecraft/server/IChunkAccess.java b/src/main/java/net/minecraft/server/IChunkAccess.java
+index 3adb35b6abd0df9617e27e10fa3e0d365958ba42..930cd8106412b362650c77a69ea5f945043c92c7 100644
+--- a/src/main/java/net/minecraft/server/IChunkAccess.java
++++ b/src/main/java/net/minecraft/server/IChunkAccess.java
+@@ -12,6 +12,18 @@ import org.apache.logging.log4j.LogManager;
+ 
+ public interface IChunkAccess extends IBlockAccess, IStructureAccess {
+ 
++    // Paper start
++    default boolean generateFlatBedrock() {
++        if (this instanceof ProtoChunk) {
++            return ((ProtoChunk)this).world.paperConfig.generateFlatBedrock;
++        } else if (this instanceof Chunk) {
++            return ((Chunk)this).world.paperConfig.generateFlatBedrock;
++        } else {
++            return false;
++        }
++    }
++    // Paper end
++
+     IBlockData getType(final int x, final int y, final int z); // Paper
+     @Nullable
+     IBlockData setType(BlockPosition blockposition, IBlockData iblockdata, boolean flag);
+diff --git a/src/main/java/net/minecraft/server/ProtoChunk.java b/src/main/java/net/minecraft/server/ProtoChunk.java
+index a60b414cdf70096e667e776ab4fd36e411f8ff12..3b03c28ee5de1481e1f8088c0e4d388778155fad 100644
+--- a/src/main/java/net/minecraft/server/ProtoChunk.java
++++ b/src/main/java/net/minecraft/server/ProtoChunk.java
+@@ -46,7 +46,7 @@ public class ProtoChunk implements IChunkAccess {
+     private long s;
+     private final Map<WorldGenStage.Features, BitSet> t;
+     private volatile boolean u;
+-    private final World world; // Paper - Anti-Xray - Add world
++    final World world; // Paper - Anti-Xray - Add world // Paper - private -> default
+ 
+     // Paper start - Anti-Xray - Add world
+     @Deprecated public ProtoChunk(ChunkCoordIntPair chunkcoordintpair, ChunkConverter chunkconverter) { this(chunkcoordintpair, chunkconverter, null); } // Notice for updates: Please make sure this constructor isn't used anywhere
diff --git a/Spigot-Server-Patches/0402-Fix-MC-161754.patch b/Spigot-Server-Patches/0387-Fix-MC-161754.patch
similarity index 91%
rename from Spigot-Server-Patches/0402-Fix-MC-161754.patch
rename to Spigot-Server-Patches/0387-Fix-MC-161754.patch
index 9ba10c6d76..bab48dada7 100644
--- a/Spigot-Server-Patches/0402-Fix-MC-161754.patch
+++ b/Spigot-Server-Patches/0387-Fix-MC-161754.patch
@@ -9,7 +9,7 @@ We can use an entity valid check since this method is invoked for
 each inventory iteraction (thanks to CB) and on player tick (vanilla).
 
 diff --git a/src/main/java/net/minecraft/server/ContainerHorse.java b/src/main/java/net/minecraft/server/ContainerHorse.java
-index c95ce0124d948626732e796c386b7544e34b36c4..18e1ae7f0a4b06ec7d7400e791ac79e5192eb8d8 100644
+index 82109f50778a3ac4bea43ef83b5442105a45664a..ebaf45be997d121e1974dc1f920dccbf11744cb3 100644
 --- a/src/main/java/net/minecraft/server/ContainerHorse.java
 +++ b/src/main/java/net/minecraft/server/ContainerHorse.java
 @@ -76,7 +76,7 @@ public class ContainerHorse extends Container {
diff --git a/Spigot-Server-Patches/0403-Performance-improvement-for-Chunk.getEntities.patch b/Spigot-Server-Patches/0388-Performance-improvement-for-Chunk.getEntities.patch
similarity index 90%
rename from Spigot-Server-Patches/0403-Performance-improvement-for-Chunk.getEntities.patch
rename to Spigot-Server-Patches/0388-Performance-improvement-for-Chunk.getEntities.patch
index e58b04f559..d166242db6 100644
--- a/Spigot-Server-Patches/0403-Performance-improvement-for-Chunk.getEntities.patch
+++ b/Spigot-Server-Patches/0388-Performance-improvement-for-Chunk.getEntities.patch
@@ -10,10 +10,10 @@ operation. This patch will reduce the load of plugins which for example
 implement custom moblimits and depend on Chunk.getEntities().
 
 diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
-index 47f1b970b9ba39f9050ac34a5ac15593c25f8a70..39ef95cbbb1d1d049354ae1e8991309e918d0462 100644
+index cccb8f7b1c13811db7203282a5caad3da5b69a09..01bf7320b5cbc38e278ca907aa324ee3e945805e 100644
 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
 +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
-@@ -111,14 +111,14 @@ public class CraftChunk implements Chunk {
+@@ -113,14 +113,14 @@ public class CraftChunk implements Chunk {
          Entity[] entities = new Entity[count];
  
          for (int i = 0; i < 16; i++) {
diff --git a/Spigot-Server-Patches/0404-Fix-spawning-of-hanging-entities-that-are-not-ItemFr.patch b/Spigot-Server-Patches/0389-Fix-spawning-of-hanging-entities-that-are-not-ItemFr.patch
similarity index 90%
rename from Spigot-Server-Patches/0404-Fix-spawning-of-hanging-entities-that-are-not-ItemFr.patch
rename to Spigot-Server-Patches/0389-Fix-spawning-of-hanging-entities-that-are-not-ItemFr.patch
index f136189c97..85944b591c 100644
--- a/Spigot-Server-Patches/0404-Fix-spawning-of-hanging-entities-that-are-not-ItemFr.patch
+++ b/Spigot-Server-Patches/0389-Fix-spawning-of-hanging-entities-that-are-not-ItemFr.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Fix spawning of hanging entities that are not ItemFrames and
 
 
 diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 5aea49404717061fce4bf24e91f36217db5cee83..c030ff7b34fdd4c4632714a800935a6a5f8082cb 100644
+index abf285be2b71a93681f06879177f03c0f5fdff1a..84c6dfcd87d9d893e846c08c9d14e01fbfb15fb2 100644
 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
 +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -1850,7 +1850,12 @@ public class CraftWorld implements World {
+@@ -1860,7 +1860,12 @@ public class CraftWorld implements World {
                  height = 9;
              }
  
diff --git a/Spigot-Server-Patches/0405-Expose-the-internal-current-tick.patch b/Spigot-Server-Patches/0390-Expose-the-internal-current-tick.patch
similarity index 81%
rename from Spigot-Server-Patches/0405-Expose-the-internal-current-tick.patch
rename to Spigot-Server-Patches/0390-Expose-the-internal-current-tick.patch
index cb23c2a1b5..f300ee3976 100644
--- a/Spigot-Server-Patches/0405-Expose-the-internal-current-tick.patch
+++ b/Spigot-Server-Patches/0390-Expose-the-internal-current-tick.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Expose the internal current tick
 
 
 diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 14cc12d772fe8c879a282275e3ee76cd66047c6b..e8d3528d515754affb14c947109ccdf1739d9745 100644
+index 57eb049e97e184426bf2a4a80232bf1c105196e2..181616c93656e45ec83659e59ac77cedce8af682 100644
 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
 +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-@@ -2203,5 +2203,10 @@ public final class CraftServer implements Server {
+@@ -2258,5 +2258,10 @@ public final class CraftServer implements Server {
          }
          return new com.destroystokyo.paper.profile.CraftPlayerProfile(uuid, name);
      }
diff --git a/Spigot-Server-Patches/0406-Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch b/Spigot-Server-Patches/0391-Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch
similarity index 80%
rename from Spigot-Server-Patches/0406-Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch
rename to Spigot-Server-Patches/0391-Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch
index 3ab0a3b4d5..49377c8ba3 100644
--- a/Spigot-Server-Patches/0406-Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch
+++ b/Spigot-Server-Patches/0391-Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Fix stuck in sneak when changing worlds (MC-10657)
 
 
 diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
-index 3db173fb5559e62150192a28dbdccdff16787401..81f00141776a1767b907d14ef04f60b576110128 100644
+index f967f08049d792b1f2542828ed28de9e94949bab..639bca91eec78f772b64677e37d8173e24b57391 100644
 --- a/src/main/java/net/minecraft/server/EntityPlayer.java
 +++ b/src/main/java/net/minecraft/server/EntityPlayer.java
-@@ -984,6 +984,8 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
+@@ -1017,6 +1017,8 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
              this.lastHealthSent = -1.0F;
              this.lastFoodSent = -1;
  
@@ -18,10 +18,10 @@ index 3db173fb5559e62150192a28dbdccdff16787401..81f00141776a1767b907d14ef04f60b5
              PlayerChangedWorldEvent changeEvent = new PlayerChangedWorldEvent(this.getBukkitEntity(), worldserver.getWorld());
              this.world.getServer().getPluginManager().callEvent(changeEvent);
 diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
-index 3cc9c70882bfb9a933c726b7a194aa3b142034fa..088c82c5379b39f8cebd60465e054b97c96eb983 100644
+index 93d30964fee7117beca92653df62f474730d866e..0b6bb4b2a679c6a3589ce30becbf2af498804aff 100644
 --- a/src/main/java/net/minecraft/server/PlayerList.java
 +++ b/src/main/java/net/minecraft/server/PlayerList.java
-@@ -718,6 +718,8 @@ public abstract class PlayerList {
+@@ -760,6 +760,8 @@ public abstract class PlayerList {
              entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityEffect(entityplayer.getId(), mobEffect));
          }
  
diff --git a/Spigot-Server-Patches/0407-Add-option-to-disable-pillager-patrols.patch b/Spigot-Server-Patches/0392-Add-option-to-disable-pillager-patrols.patch
similarity index 80%
rename from Spigot-Server-Patches/0407-Add-option-to-disable-pillager-patrols.patch
rename to Spigot-Server-Patches/0392-Add-option-to-disable-pillager-patrols.patch
index 2e175f1978..d11e1de6e9 100644
--- a/Spigot-Server-Patches/0407-Add-option-to-disable-pillager-patrols.patch
+++ b/Spigot-Server-Patches/0392-Add-option-to-disable-pillager-patrols.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Add option to disable pillager patrols
 
 
 diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-index f6f5f9dea6284582e9a175c0875273ee1db76076..19f355d00ebe7065ae2d2df8156ea4b6459a6598 100644
+index a9d7e81ef123a7da7785a4b8dc868a0e256a61d0..f8a617a62e62d088077712bfb66656c28b82a3c5 100644
 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-@@ -614,4 +614,9 @@ public class PaperWorldConfig {
+@@ -577,4 +577,9 @@ public class PaperWorldConfig {
      private void generatorSettings() {
          generateFlatBedrock = getBoolean("generator-settings.flat-bedrock", false);
      }
@@ -19,12 +19,12 @@ index f6f5f9dea6284582e9a175c0875273ee1db76076..19f355d00ebe7065ae2d2df8156ea4b6
 +    }
  }
 diff --git a/src/main/java/net/minecraft/server/MobSpawnerPatrol.java b/src/main/java/net/minecraft/server/MobSpawnerPatrol.java
-index 33488b37e4d0dd295e0f48b59c43d30208eb531a..a0f582807605b9cc5bbf31d84907e56fba393e2e 100644
+index e108f14b36b5459503e02146f8c11e5223d6bd61..b1fea06d29a0c98136496d6eff81e6959cb73672 100644
 --- a/src/main/java/net/minecraft/server/MobSpawnerPatrol.java
 +++ b/src/main/java/net/minecraft/server/MobSpawnerPatrol.java
-@@ -9,6 +9,7 @@ public class MobSpawnerPatrol {
-     public MobSpawnerPatrol() {}
+@@ -10,6 +10,7 @@ public class MobSpawnerPatrol implements MobSpawner {
  
+     @Override
      public int a(WorldServer worldserver, boolean flag, boolean flag1) {
 +        if (worldserver.paperConfig.disablePillagerPatrols) return 0; // Paper
          if (!flag) {
diff --git a/Spigot-Server-Patches/0408-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch b/Spigot-Server-Patches/0393-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch
similarity index 55%
rename from Spigot-Server-Patches/0408-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch
rename to Spigot-Server-Patches/0393-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch
index 019af38f15..e55c366dd5 100644
--- a/Spigot-Server-Patches/0408-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch
+++ b/Spigot-Server-Patches/0393-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch
@@ -7,29 +7,29 @@ Fixes an AssertionError when setting the player's item in hand to null or a new
 Fixes GH-2718
 
 diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
-index 576c9c6ae4339951d4ec9fffa69c7f860d82b33f..4f9255c0bc2ff46f34072846d2b0dc2e97f05db4 100644
+index d44d594b52cd63adcede55fbe6548b758b482c90..17491b9f9b4c8fb931a249580810681cb618ee45 100644
 --- a/src/main/java/net/minecraft/server/EntityLiving.java
 +++ b/src/main/java/net/minecraft/server/EntityLiving.java
-@@ -1891,6 +1891,7 @@ public abstract class EntityLiving extends Entity {
-         return this.getEquipment(EnumItemSlot.OFFHAND);
+@@ -2035,6 +2035,7 @@ public abstract class EntityLiving extends Entity {
+         return predicate.test(this.getItemInMainHand().getItem()) || predicate.test(this.getItemInOffHand().getItem());
      }
  
-+    public ItemStack getItemInHand(EnumHand enumhand) { return this.b(enumhand); } // Paper - OBFHELPER
++    public final ItemStack getItemInHand(EnumHand enumhand) { return this.b(enumhand); } // Paper - OBFHELPER
      public ItemStack b(EnumHand enumhand) {
          if (enumhand == EnumHand.MAIN_HAND) {
              return this.getEquipment(EnumItemSlot.MAINHAND);
 diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
-index ee186ed5a076ede4d89702aeb5a2128d6e7ac8cf..9ba5f9325fe0a7adc3ecf745d52cafe6496bc73f 100644
+index e382315c91540ac24821e432ee31a8244f4f7efa..204eae3abdb006c3006537e6cf8f4c7a0bae2a47 100644
 --- a/src/main/java/net/minecraft/server/PlayerConnection.java
 +++ b/src/main/java/net/minecraft/server/PlayerConnection.java
-@@ -1438,6 +1438,10 @@ public class PlayerConnection implements PacketListenerPlayIn {
-             if (cancelled) {
+@@ -1477,6 +1477,10 @@ public class PlayerConnection implements PacketListenerPlayIn {
                  this.player.getBukkitEntity().updateInventory(); // SPIGOT-2524
-             } else {
-+                // Paper start
-+                itemstack = this.player.getItemInHand(enumhand);
-+                if (itemstack.isEmpty()) return;
-+                // Paper end
-                 this.player.playerInteractManager.a(this.player, worldserver, itemstack, enumhand);
+                 return;
              }
-             // CraftBukkit end
++            // Paper start
++            itemstack = this.player.getItemInHand(enumhand);
++            if (itemstack.isEmpty()) return;
++            // Paper end
+             EnumInteractionResult enuminteractionresult = this.player.playerInteractManager.a(this.player, worldserver, itemstack, enumhand);
+ 
+             if (enuminteractionresult.b()) {
diff --git a/Spigot-Server-Patches/0394-Do-less-work-if-we-have-a-custom-Bukkit-generator.patch b/Spigot-Server-Patches/0394-Do-less-work-if-we-have-a-custom-Bukkit-generator.patch
deleted file mode 100644
index 45b933c4b9..0000000000
--- a/Spigot-Server-Patches/0394-Do-less-work-if-we-have-a-custom-Bukkit-generator.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Paul Sauve <paul@burngames.net>
-Date: Sun, 14 Jul 2019 21:05:03 -0500
-Subject: [PATCH] Do less work if we have a custom Bukkit generator
-
-If the Bukkit generator already has a spawn, use it immediately instead
-of spending time generating one that we won't use
-
-diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
-index da38293cf02d84f3e24a883136ffe5118a510b5a..135d1211525f499198122e500626ce463c263088 100644
---- a/src/main/java/net/minecraft/server/WorldServer.java
-+++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -814,12 +814,13 @@ public class WorldServer extends World {
-         } else if (this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) {
-             this.worldData.setSpawn(BlockPosition.ZERO.up());
-         } else {
--            WorldChunkManager worldchunkmanager = this.getChunkProvider().getChunkGenerator().getWorldChunkManager();
--            List<BiomeBase> list = worldchunkmanager.a();
--            Random random = new Random(this.getSeed());
--            BlockPosition blockposition = worldchunkmanager.a(0, this.getSeaLevel(), 0, 256, list, random);
--            ChunkCoordIntPair chunkcoordintpair = blockposition == null ? new ChunkCoordIntPair(0, 0) : new ChunkCoordIntPair(blockposition);
--
-+//            Paper start - moved down
-+//            WorldChunkManager worldchunkmanager = this.getChunkProvider().getChunkGenerator().getWorldChunkManager();
-+//            List<BiomeBase> list = worldchunkmanager.a();
-+//            Random random = new Random(this.getSeed());
-+//            BlockPosition blockposition = worldchunkmanager.a(0, this.getSeaLevel(), 0, 256, list, random);
-+//            ChunkCoordIntPair chunkcoordintpair = blockposition == null ? new ChunkCoordIntPair(0, 0) : new ChunkCoordIntPair(blockposition);
-+//            Paper end
-             // CraftBukkit start
-             if (this.generator != null) {
-                 Random rand = new Random(this.getSeed());
-@@ -836,6 +837,13 @@ public class WorldServer extends World {
-             }
-             // CraftBukkit end
- 
-+            // Paper start - this is useless if craftbukkit returns early
-+            WorldChunkManager worldchunkmanager = this.getChunkProvider().getChunkGenerator().getWorldChunkManager();
-+            List<BiomeBase> list = worldchunkmanager.a();
-+            Random random = new Random(this.getSeed());
-+            BlockPosition blockposition = worldchunkmanager.a(0, this.getSeaLevel(), 0, 256, list, random);
-+            ChunkCoordIntPair chunkcoordintpair = blockposition == null ? new ChunkCoordIntPair(0, 0) : new ChunkCoordIntPair(blockposition);
-+            // Paper end
-             if (blockposition == null) {
-                 WorldServer.LOGGER.warn("Unable to find spawn biome");
-             }
diff --git a/Spigot-Server-Patches/0409-PlayerLaunchProjectileEvent.patch b/Spigot-Server-Patches/0394-PlayerLaunchProjectileEvent.patch
similarity index 82%
rename from Spigot-Server-Patches/0409-PlayerLaunchProjectileEvent.patch
rename to Spigot-Server-Patches/0394-PlayerLaunchProjectileEvent.patch
index d5773b74c1..cf650d9db4 100644
--- a/Spigot-Server-Patches/0409-PlayerLaunchProjectileEvent.patch
+++ b/Spigot-Server-Patches/0394-PlayerLaunchProjectileEvent.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] PlayerLaunchProjectileEvent
 
 
 diff --git a/src/main/java/net/minecraft/server/InteractionResultWrapper.java b/src/main/java/net/minecraft/server/InteractionResultWrapper.java
-index 5cab47a2821adf869693132f8ce1193b1543f896..886babdcda0b559fc6a760b48074bec44e0f9da1 100644
+index d59a0b739c0b8787029969a14002042e5c288ae8..8b2fc1c0e608c911b2cdc95ef134f84e3760c05d 100644
 --- a/src/main/java/net/minecraft/server/InteractionResultWrapper.java
 +++ b/src/main/java/net/minecraft/server/InteractionResultWrapper.java
 @@ -10,6 +10,7 @@ public class InteractionResultWrapper<T> {
@@ -17,7 +17,7 @@ index 5cab47a2821adf869693132f8ce1193b1543f896..886babdcda0b559fc6a760b48074bec4
          return this.a;
      }
 diff --git a/src/main/java/net/minecraft/server/ItemEgg.java b/src/main/java/net/minecraft/server/ItemEgg.java
-index 6fccd70a034b5d70729f57e0f2ee56e59e6f9cbc..16f1b734e01ee7cf917d2f9a4a4dc1e98e4f2af9 100644
+index f028cb04d692f848a4682aa2eeac2174eb0f6769..6ddb0237c013e5c40d6c28a300f33443f6f703a5 100644
 --- a/src/main/java/net/minecraft/server/ItemEgg.java
 +++ b/src/main/java/net/minecraft/server/ItemEgg.java
 @@ -16,21 +16,35 @@ public class ItemEgg extends Item {
@@ -49,7 +49,7 @@ index 6fccd70a034b5d70729f57e0f2ee56e59e6f9cbc..16f1b734e01ee7cf917d2f9a4a4dc1e9
 +
 +
          }
-         world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_EGG_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (ItemEgg.i.nextFloat() * 0.4F + 0.8F)); // CraftBukkit - from above
+         world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_EGG_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (ItemEgg.RANDOM.nextFloat() * 0.4F + 0.8F)); // CraftBukkit - from above
  
 +        /* // Paper start - moved up
          entityhuman.b(StatisticList.ITEM_USED.b(this));
@@ -58,10 +58,10 @@ index 6fccd70a034b5d70729f57e0f2ee56e59e6f9cbc..16f1b734e01ee7cf917d2f9a4a4dc1e9
          }
 +        */ // Paper end
  
-         return InteractionResultWrapper.success(itemstack);
+         return InteractionResultWrapper.a(itemstack, world.s_());
      }
 diff --git a/src/main/java/net/minecraft/server/ItemEnderPearl.java b/src/main/java/net/minecraft/server/ItemEnderPearl.java
-index cab869e8e9b6a505e23c109c4434178a8824ba45..b57e9f7e72b892165129c3857d5d03a088bee3ee 100644
+index aa7356e6a18c0bf72314e92809a4eab320d3695f..0e154ee2976694dacf8d41fcd831f21fbbda13af 100644
 --- a/src/main/java/net/minecraft/server/ItemEnderPearl.java
 +++ b/src/main/java/net/minecraft/server/ItemEnderPearl.java
 @@ -16,22 +16,37 @@ public class ItemEnderPearl extends Item {
@@ -91,7 +91,7 @@ index cab869e8e9b6a505e23c109c4434178a8824ba45..b57e9f7e72b892165129c3857d5d03a0
              }
          }
  
--        world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_ENDER_PEARL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemEnderPearl.i.nextFloat() * 0.4F + 0.8F));
+-        world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_ENDER_PEARL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemEnderPearl.RANDOM.nextFloat() * 0.4F + 0.8F));
 -        entityhuman.getCooldownTracker().setCooldown(this, 20);
 -        // CraftBukkit end
 -
@@ -100,7 +100,7 @@ index cab869e8e9b6a505e23c109c4434178a8824ba45..b57e9f7e72b892165129c3857d5d03a0
 -            itemstack.subtract(1);
 -        }
 +        // Paper start - moved up
-+//        world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_ENDER_PEARL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemEnderPearl.i.nextFloat() * 0.4F + 0.8F));
++//        world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_ENDER_PEARL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemEnderPearl.RANDOM.nextFloat() * 0.4F + 0.8F));
 +//        entityhuman.getCooldownTracker().setCooldown(this, 20);
 +//        // CraftBukkit end
 +//
@@ -108,20 +108,20 @@ index cab869e8e9b6a505e23c109c4434178a8824ba45..b57e9f7e72b892165129c3857d5d03a0
 +//        if (!entityhuman.abilities.canInstantlyBuild) {
 +//            itemstack.subtract(1);
 +//        }
-+        // Paper end
++        // Paper end - moved up
  
-         return InteractionResultWrapper.success(itemstack);
+         return InteractionResultWrapper.a(itemstack, world.s_());
      }
 diff --git a/src/main/java/net/minecraft/server/ItemExpBottle.java b/src/main/java/net/minecraft/server/ItemExpBottle.java
-index 071688b3ab45a527a642c3d16c8d8b1f3682e63c..1d575af5269762f6f2616884a7733470cca06be5 100644
+index 07e12714d064a2ccc7a3a50fbb88517f9a3b8b78..10abf20e907f1ea25797ff33d181de7eaed9a9da 100644
 --- a/src/main/java/net/minecraft/server/ItemExpBottle.java
 +++ b/src/main/java/net/minecraft/server/ItemExpBottle.java
 @@ -15,19 +15,38 @@ public class ItemExpBottle extends Item {
      public InteractionResultWrapper<ItemStack> a(World world, EntityHuman entityhuman, EnumHand enumhand) {
          ItemStack itemstack = entityhuman.b(enumhand);
  
--        world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_EXPERIENCE_BOTTLE_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemExpBottle.i.nextFloat() * 0.4F + 0.8F));
-+//        world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_EXPERIENCE_BOTTLE_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemExpBottle.i.nextFloat() * 0.4F + 0.8F)); // Paper - moved down
+-        world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_EXPERIENCE_BOTTLE_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemExpBottle.RANDOM.nextFloat() * 0.4F + 0.8F));
++        //world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_EXPERIENCE_BOTTLE_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemExpBottle.RANDOM.nextFloat() * 0.4F + 0.8F));  // Paper - moved down
          if (!world.isClientSide) {
              EntityThrownExpBottle entitythrownexpbottle = new EntityThrownExpBottle(world, entityhuman);
  
@@ -155,28 +155,29 @@ index 071688b3ab45a527a642c3d16c8d8b1f3682e63c..1d575af5269762f6f2616884a7733470
          }
 +        */ // Paper end
  
-         return InteractionResultWrapper.success(itemstack);
+         return InteractionResultWrapper.a(itemstack, world.s_());
      }
 diff --git a/src/main/java/net/minecraft/server/ItemLingeringPotion.java b/src/main/java/net/minecraft/server/ItemLingeringPotion.java
-index c19b678cfb2bc3c27858488031e119d482905f8b..7672e31fc0c915c49c8752ba864c2706f1292e86 100644
+index 685d958994bc35ad5eceba629e6743b41e2cc04b..58f7191a6980265e8fab17cf39769bbbca0ee105 100644
 --- a/src/main/java/net/minecraft/server/ItemLingeringPotion.java
 +++ b/src/main/java/net/minecraft/server/ItemLingeringPotion.java
-@@ -8,7 +8,11 @@ public class ItemLingeringPotion extends ItemPotionThrowable {
+@@ -8,7 +8,12 @@ public class ItemLingeringPotion extends ItemPotionThrowable {
  
      @Override
      public InteractionResultWrapper<ItemStack> a(World world, EntityHuman entityhuman, EnumHand enumhand) {
--        world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_LINGERING_POTION_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemLingeringPotion.i.nextFloat() * 0.4F + 0.8F));
+-        world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_LINGERING_POTION_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemLingeringPotion.RANDOM.nextFloat() * 0.4F + 0.8F));
 -        return super.a(world, entityhuman, enumhand);
 +        // Paper start
 +        InteractionResultWrapper<ItemStack> wrapper = super.a(world, entityhuman, enumhand);
-+        if (wrapper.getResult() != EnumInteractionResult.FAIL)
-+            world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_LINGERING_POTION_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemLingeringPotion.i.nextFloat() * 0.4F + 0.8F));
++        if (wrapper.getResult() != EnumInteractionResult.FAIL) {
++            world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_LINGERING_POTION_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemLingeringPotion.RANDOM.nextFloat() * 0.4F + 0.8F));
++        }
 +        return wrapper;
 +        // Paper end
      }
  }
 diff --git a/src/main/java/net/minecraft/server/ItemPotionThrowable.java b/src/main/java/net/minecraft/server/ItemPotionThrowable.java
-index 5d1f118c5139540a809dbaeee0982fbc7e9c3996..d1beab1ab72dffd3ee671982991d414b9244973d 100644
+index dee3d4042b0cd1ace86fe1d80d894d0cc48cf941..9c84de77df7e32915a633b92c842cfb69e30e0d0 100644
 --- a/src/main/java/net/minecraft/server/ItemPotionThrowable.java
 +++ b/src/main/java/net/minecraft/server/ItemPotionThrowable.java
 @@ -15,13 +15,31 @@ public class ItemPotionThrowable extends ItemPotion {
@@ -210,13 +211,13 @@ index 5d1f118c5139540a809dbaeee0982fbc7e9c3996..d1beab1ab72dffd3ee671982991d414b
          }
 +        */ // Paper end
  
-         return InteractionResultWrapper.success(itemstack);
+         return InteractionResultWrapper.a(itemstack, world.s_());
      }
 diff --git a/src/main/java/net/minecraft/server/ItemSnowball.java b/src/main/java/net/minecraft/server/ItemSnowball.java
-index 56ec5089596de4209780a823a2a3f37676ec515b..e6044e654b78ab8ef9d73ef7bd6ad82a079745a8 100644
+index 19ac8cc57d6400e7574dd475dd21f2f48a954324..4242b5c4ed1e7d546fee7e2b3892b7b25e1259ff 100644
 --- a/src/main/java/net/minecraft/server/ItemSnowball.java
 +++ b/src/main/java/net/minecraft/server/ItemSnowball.java
-@@ -17,19 +17,27 @@ public class ItemSnowball extends Item {
+@@ -17,14 +17,20 @@ public class ItemSnowball extends Item {
  
              entitysnowball.setItem(itemstack);
              entitysnowball.a(entityhuman, entityhuman.pitch, entityhuman.yaw, 0.0F, 1.5F, 1.0F);
@@ -226,44 +227,35 @@ index 56ec5089596de4209780a823a2a3f37676ec515b..e6044e654b78ab8ef9d73ef7bd6ad82a
 +            com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entitysnowball.getBukkitEntity());
 +            if (event.callEvent() && world.addEntity(entitysnowball)) {
 +                if (event.shouldConsume() && !entityhuman.abilities.canInstantlyBuild) {
++                    // Paper end
                      itemstack.subtract(1);
-+                } else if (entityhuman instanceof EntityPlayer) {
-+                    ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory();
++                } else if (entityhuman instanceof EntityPlayer) {  // Paper
++                    ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory();  // Paper
                  }
  
--                world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_SNOWBALL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemSnowball.i.nextFloat() * 0.4F + 0.8F));
+                 world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_SNOWBALL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemSnowball.RANDOM.nextFloat() * 0.4F + 0.8F));
 -            } else if (entityhuman instanceof EntityPlayer) {
 -                ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory();
-+                world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_SNOWBALL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F));
-+                entityhuman.b(StatisticList.ITEM_USED.b(this));
-+            } else {
-+                if (entityhuman instanceof EntityPlayer) {
-+                    ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory();
-+                }
-+                return new InteractionResultWrapper<ItemStack>(EnumInteractionResult.FAIL, itemstack);
++            } else { // Paper
++                if (entityhuman instanceof EntityPlayer) ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); // Paper
++                return new InteractionResultWrapper<ItemStack>(EnumInteractionResult.FAIL, itemstack); // Paper
              }
          }
          // CraftBukkit end
- 
--        entityhuman.b(StatisticList.ITEM_USED.b(this));
-+//        entityhuman.b(StatisticList.ITEM_USED.b(this)); // Paper - moved up
-         // CraftBukkit start - moved up
-         /*
-         if (!entityhuman.abilities.canInstantlyBuild) {
 diff --git a/src/main/java/net/minecraft/server/ItemSplashPotion.java b/src/main/java/net/minecraft/server/ItemSplashPotion.java
-index 18bd846ceecf638fa1184a6cceb5c909ec49372c..e71e933fffb04aa4a00d02cfbc284da8ad3ee925 100644
+index 3574cf875c6284687c10637159ec96a823ade2dc..c919a402e80a5c6b17fdbd99e110be1abefda747 100644
 --- a/src/main/java/net/minecraft/server/ItemSplashPotion.java
 +++ b/src/main/java/net/minecraft/server/ItemSplashPotion.java
-@@ -8,7 +8,11 @@ public class ItemSplashPotion extends ItemPotionThrowable {
+@@ -8,7 +8,12 @@ public class ItemSplashPotion extends ItemPotionThrowable {
  
      @Override
      public InteractionResultWrapper<ItemStack> a(World world, EntityHuman entityhuman, EnumHand enumhand) {
--        world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_SPLASH_POTION_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (ItemSplashPotion.i.nextFloat() * 0.4F + 0.8F));
--        return super.a(world, entityhuman, enumhand);
 +        // Paper start
 +        InteractionResultWrapper<ItemStack> wrapper = super.a(world, entityhuman, enumhand);
-+        if (wrapper.getResult() != EnumInteractionResult.FAIL)
-+            world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_SPLASH_POTION_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (ItemSplashPotion.i.nextFloat() * 0.4F + 0.8F));
++        if (wrapper.getResult() != EnumInteractionResult.FAIL) {
+         world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_SPLASH_POTION_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (ItemSplashPotion.RANDOM.nextFloat() * 0.4F + 0.8F));
+-        return super.a(world, entityhuman, enumhand);
++        }
 +        return wrapper;
 +        // Paper end
      }
diff --git a/Spigot-Server-Patches/0410-Add-CraftMagicNumbers.isSupportedApiVersion.patch b/Spigot-Server-Patches/0395-Add-CraftMagicNumbers.isSupportedApiVersion.patch
similarity index 90%
rename from Spigot-Server-Patches/0410-Add-CraftMagicNumbers.isSupportedApiVersion.patch
rename to Spigot-Server-Patches/0395-Add-CraftMagicNumbers.isSupportedApiVersion.patch
index e84521520d..2418e3bb12 100644
--- a/Spigot-Server-Patches/0410-Add-CraftMagicNumbers.isSupportedApiVersion.patch
+++ b/Spigot-Server-Patches/0395-Add-CraftMagicNumbers.isSupportedApiVersion.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Add CraftMagicNumbers.isSupportedApiVersion()
 
 
 diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
-index 79ddf03c7f3afc868cb73ee4c000fc879ede90d8..6363074c38312387b62e6cf5df2592aefb078f29 100644
+index 9f2903c8623976ae71802ab56ff2e0e3ee9089b7..6e6da966a8c5b40494213f914db5b9449aea4f43 100644
 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
 +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
 @@ -314,6 +314,11 @@ public final class CraftMagicNumbers implements UnsafeValues {
diff --git a/Spigot-Server-Patches/0396-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch b/Spigot-Server-Patches/0396-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch
new file mode 100644
index 0000000000..74c0749370
--- /dev/null
+++ b/Spigot-Server-Patches/0396-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch
@@ -0,0 +1,20 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Callahan <mr.callahhh@gmail.com>
+Date: Mon, 13 Jan 2020 23:47:28 -0600
+Subject: [PATCH] Prevent sync chunk loads when villagers try to find beds
+
+
+diff --git a/src/main/java/net/minecraft/server/BehaviorSleep.java b/src/main/java/net/minecraft/server/BehaviorSleep.java
+index 77bbe246b225aab41fa193cf63286739118c05f4..615a06497588e07fa2b71194a5836ef6360bf0ca 100644
+--- a/src/main/java/net/minecraft/server/BehaviorSleep.java
++++ b/src/main/java/net/minecraft/server/BehaviorSleep.java
+@@ -34,7 +34,8 @@ public class BehaviorSleep extends Behavior<EntityLiving> {
+                     }
+                 }
+ 
+-                IBlockData iblockdata = worldserver.getType(globalpos.getBlockPosition());
++                IBlockData iblockdata = worldserver.getTypeIfLoaded(globalpos.getBlockPosition()); // Paper
++                if (iblockdata == null) { return false; } // Paper
+ 
+                 return globalpos.getBlockPosition().a((IPosition) entityliving.getPositionVector(), 2.0D) && iblockdata.getBlock().a((Tag) TagsBlock.BEDS) && !(Boolean) iblockdata.get(BlockBed.OCCUPIED);
+             }
diff --git a/Spigot-Server-Patches/0413-MC-145656-Fix-Follow-Range-Initial-Target.patch b/Spigot-Server-Patches/0397-MC-145656-Fix-Follow-Range-Initial-Target.patch
similarity index 89%
rename from Spigot-Server-Patches/0413-MC-145656-Fix-Follow-Range-Initial-Target.patch
rename to Spigot-Server-Patches/0397-MC-145656-Fix-Follow-Range-Initial-Target.patch
index 3494a96801..e8540c0cd8 100644
--- a/Spigot-Server-Patches/0413-MC-145656-Fix-Follow-Range-Initial-Target.patch
+++ b/Spigot-Server-Patches/0397-MC-145656-Fix-Follow-Range-Initial-Target.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] MC-145656 Fix Follow Range Initial Target
 
 
 diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-index 19f355d00ebe7065ae2d2df8156ea4b6459a6598..a26848df994ffb0dc02d6a6051971439613dd0ba 100644
+index f8a617a62e62d088077712bfb66656c28b82a3c5..5c5a79d0ea00c9c4c2e93d524291f48f92e77857 100644
 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-@@ -619,4 +619,9 @@ public class PaperWorldConfig {
+@@ -582,4 +582,9 @@ public class PaperWorldConfig {
      private void pillagerSettings() {
          disablePillagerPatrols = getBoolean("game-mechanics.disable-pillager-patrols", disablePillagerPatrols);
      }
@@ -19,7 +19,7 @@ index 19f355d00ebe7065ae2d2df8156ea4b6459a6598..a26848df994ffb0dc02d6a6051971439
 +    }
  }
 diff --git a/src/main/java/net/minecraft/server/PathfinderGoalNearestAttackableTarget.java b/src/main/java/net/minecraft/server/PathfinderGoalNearestAttackableTarget.java
-index cd17bf2be53a92bcbe9c54794981753153bbef07..b85e67a85d16934c2158621b58701df403a42ff3 100644
+index 25a67f91e487d80d3996cc8b2544fece55059590..c0721c7fe479c8f753b8f48197a70dcd1ecfef5f 100644
 --- a/src/main/java/net/minecraft/server/PathfinderGoalNearestAttackableTarget.java
 +++ b/src/main/java/net/minecraft/server/PathfinderGoalNearestAttackableTarget.java
 @@ -25,6 +25,7 @@ public class PathfinderGoalNearestAttackableTarget<T extends EntityLiving> exten
@@ -31,7 +31,7 @@ index cd17bf2be53a92bcbe9c54794981753153bbef07..b85e67a85d16934c2158621b58701df4
  
      @Override
 diff --git a/src/main/java/net/minecraft/server/PathfinderTargetCondition.java b/src/main/java/net/minecraft/server/PathfinderTargetCondition.java
-index c76a43837b443d09c0648d520b045765530d9af9..e35ec2db078cc888333cfdd44e1cd3fda71246da 100644
+index 42859f323ad5a300e0026e86371f5753ab3feab5..3f0b3eab438be921440be91f8a51439ac887c154 100644
 --- a/src/main/java/net/minecraft/server/PathfinderTargetCondition.java
 +++ b/src/main/java/net/minecraft/server/PathfinderTargetCondition.java
 @@ -80,7 +80,7 @@ public class PathfinderTargetCondition {
diff --git a/Spigot-Server-Patches/0414-Optimize-Hoppers.patch b/Spigot-Server-Patches/0398-Optimize-Hoppers.patch
similarity index 92%
rename from Spigot-Server-Patches/0414-Optimize-Hoppers.patch
rename to Spigot-Server-Patches/0398-Optimize-Hoppers.patch
index ad789cfbc6..801b3c9e09 100644
--- a/Spigot-Server-Patches/0414-Optimize-Hoppers.patch
+++ b/Spigot-Server-Patches/0398-Optimize-Hoppers.patch
@@ -13,10 +13,10 @@ Subject: [PATCH] Optimize Hoppers
 * Remove Streams from Item Suck In and restore restore 1.12 AABB checks which is simpler and no voxel allocations (was doing TWO Item Suck ins)
 
 diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-index a26848df994ffb0dc02d6a6051971439613dd0ba..cab503bd5c34d12b38a2f5deed6d3feb9287b370 100644
+index 5c5a79d0ea00c9c4c2e93d524291f48f92e77857..4bfe2fb948ee204f8c5a8c316141904a8a6a8b16 100644
 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-@@ -624,4 +624,13 @@ public class PaperWorldConfig {
+@@ -587,4 +587,13 @@ public class PaperWorldConfig {
      private void entitiesTargetWithFollowRange() {
          entitiesTargetWithFollowRange = getBoolean("entities-target-with-follow-range", entitiesTargetWithFollowRange);
      }
@@ -31,7 +31,7 @@ index a26848df994ffb0dc02d6a6051971439613dd0ba..cab503bd5c34d12b38a2f5deed6d3feb
 +    }
  }
 diff --git a/src/main/java/net/minecraft/server/IHopper.java b/src/main/java/net/minecraft/server/IHopper.java
-index e1aa272e526950e6405221e566cf4299c869a6b2..4da26365ec59ed33e10b55789e535a1c0e7b92a1 100644
+index d891be4115f35c7b9685faa34ce90380e989fb18..54552d181912133577cd2c16c0d54e47d90f59d3 100644
 --- a/src/main/java/net/minecraft/server/IHopper.java
 +++ b/src/main/java/net/minecraft/server/IHopper.java
 @@ -12,12 +12,13 @@ public interface IHopper extends IInventory {
@@ -43,20 +43,20 @@ index e1aa272e526950e6405221e566cf4299c869a6b2..4da26365ec59ed33e10b55789e535a1c
      World getWorld();
 +    default BlockPosition getBlockPosition() { return new BlockPosition(getX(), getY(), getZ()); } // Paper
  
+-    double x();
++    double x(); default double getX() { return this.x(); } // Paper - OBFHELPER
+ 
 -    double z();
-+    double z();default double getX() { return z(); } // Paper - OBFHELPER
++    double z(); default double getY() { return this.z(); } // Paper - OBFHELPER
  
 -    double A();
-+    double A();default double getY() { return A(); } // Paper - OBFHELPER
- 
--    double B();
-+    double B();default double getZ() { return B(); } // Paper - OBFHELPER
++    double A(); default double getZ() { return this.A(); } // Paper - OBFHELPER
  }
 diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java
-index d953cdef14a9b62833a35a4fe94a22b5e9b19c2d..d6e43313bf0c678cf78fe77de2f8f4b6f819e3f4 100644
+index a075a41d954836864a5186b383e967a9ac262df8..64150130fa0081786190eada4cd2d1312a51572d 100644
 --- a/src/main/java/net/minecraft/server/ItemStack.java
 +++ b/src/main/java/net/minecraft/server/ItemStack.java
-@@ -482,11 +482,12 @@ public final class ItemStack {
+@@ -486,11 +486,12 @@ public final class ItemStack {
          return this.getItem().a(this, entityhuman, entityliving, enumhand);
      }
  
@@ -65,27 +65,27 @@ index d953cdef14a9b62833a35a4fe94a22b5e9b19c2d..d6e43313bf0c678cf78fe77de2f8f4b6
 +    public ItemStack cloneItemStack() { return cloneItemStack(false); } // Paper
 +    public ItemStack cloneItemStack(boolean origItem) { // Paper
 +        if (!origItem && this.isEmpty()) { // Paper
-             return ItemStack.a;
+             return ItemStack.b;
          } else {
 -            ItemStack itemstack = new ItemStack(this.getItem(), this.count);
 +            ItemStack itemstack = new ItemStack(origItem ? this.item : this.getItem(), this.count); // Paper
  
-             itemstack.d(this.C());
+             itemstack.d(this.D());
              if (this.tag != null) {
 diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 9450e27e5ce9295d87b95be2797fc27984ca2b0b..8c08a542a97edd76c07ef7d64834bdbd70345876 100644
+index 824c3763a56171ceb5f7163783cd46154b7e181e..9edf1ead68e64cdd3ee3b1256d0f92374f20e9e7 100644
 --- a/src/main/java/net/minecraft/server/MinecraftServer.java
 +++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -1222,6 +1222,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
+@@ -1252,6 +1252,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
+         while (iterator.hasNext()) {
              WorldServer worldserver = (WorldServer) iterator.next();
- 
              worldserver.hasPhysicsEvent =  org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
 +            TileEntityHopper.skipHopperEvents = worldserver.paperConfig.disableHopperMoveEvents || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper
-             if (true || worldserver.worldProvider.getDimensionManager() == DimensionManager.OVERWORLD || this.getAllowNether()) { // CraftBukkit
-                 this.methodProfiler.a(() -> {
-                     return worldserver.getWorldData().getName() + " " + IRegistry.DIMENSION_TYPE.getKey(worldserver.worldProvider.getDimensionManager());
+ 
+             this.methodProfiler.a(() -> {
+                 return worldserver + " " + worldserver.getDimensionKey().a();
 diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java
-index 958279249fdadfe5c2808d2a046636f06c3bd500..a8e64dfdab1e73894144a65c10c15d22f9198d3d 100644
+index 54285237ed5a096b2e46cabd78f7dcd5128133a8..543bbd1610fb2e6df4e8ad7fbf9f2cf9b4c6cbe6 100644
 --- a/src/main/java/net/minecraft/server/TileEntity.java
 +++ b/src/main/java/net/minecraft/server/TileEntity.java
 @@ -62,6 +62,7 @@ public abstract class TileEntity implements KeyedObject { // Paper
@@ -105,7 +105,7 @@ index 958279249fdadfe5c2808d2a046636f06c3bd500..a8e64dfdab1e73894144a65c10c15d22
              this.world.b(this.position, this);
              if (!this.c.isAir()) {
 diff --git a/src/main/java/net/minecraft/server/TileEntityHopper.java b/src/main/java/net/minecraft/server/TileEntityHopper.java
-index 907d088c8691eec5d72836ccda420a7a0703ad22..c755faed4f63884cb6a66bf951104a27dbaf887f 100644
+index a0a3adac3e2bc939b1809c5587929f674f4318a5..728c829c18db4bb25ad4581b485bb8a44300d1b1 100644
 --- a/src/main/java/net/minecraft/server/TileEntityHopper.java
 +++ b/src/main/java/net/minecraft/server/TileEntityHopper.java
 @@ -168,6 +168,160 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
@@ -266,8 +266,8 @@ index 907d088c8691eec5d72836ccda420a7a0703ad22..c755faed4f63884cb6a66bf951104a27
 +    }
 +    // Paper end
 +
-     private boolean j() {
-         IInventory iinventory = this.k();
+     private boolean k() {
+         IInventory iinventory = this.l();
  
 @@ -179,6 +333,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
              if (this.b(iinventory, enumdirection)) {
@@ -412,15 +412,15 @@ index 907d088c8691eec5d72836ccda420a7a0703ad22..c755faed4f63884cb6a66bf951104a27
 +                IGNORE_TILE_UPDATES = true; // Paper
                  iinventory1.setItem(i, itemstack);
 +                IGNORE_TILE_UPDATES = false; // Paper
-                 itemstack = ItemStack.a;
+                 itemstack = ItemStack.b;
                  flag = true;
              } else if (a(itemstack1, itemstack)) {
 @@ -419,18 +622,24 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
      }
  
      public static List<EntityItem> c(IHopper ihopper) {
--        return (List) ihopper.P_().d().stream().flatMap((axisalignedbb) -> {
--            return ihopper.getWorld().a(EntityItem.class, axisalignedbb.d(ihopper.z() - 0.5D, ihopper.A() - 0.5D, ihopper.B() - 0.5D), IEntitySelector.a).stream();
+-        return (List) ihopper.ac_().d().stream().flatMap((axisalignedbb) -> {
+-            return ihopper.getWorld().a(EntityItem.class, axisalignedbb.d(ihopper.x() - 0.5D, ihopper.z() - 0.5D, ihopper.A() - 0.5D), IEntitySelector.a).stream();
 -        }).collect(Collectors.toList());
 +        // Paper start - Optimize item suck in. remove streams, restore 1.12 checks. Seriously checking the bowl?!
 +        World world = ihopper.getWorld();
@@ -455,10 +455,10 @@ index 907d088c8691eec5d72836ccda420a7a0703ad22..c755faed4f63884cb6a66bf951104a27
  
              if (!list.isEmpty()) {
 diff --git a/src/main/java/net/minecraft/server/TileEntityLootable.java b/src/main/java/net/minecraft/server/TileEntityLootable.java
-index d4cbce3243fe1f4973c9c0ae0dbdab10e3390897..3b394c2726e0fbe595641a022e59c8967d525f82 100644
+index 5ebba482a65cfe6079484a99f016f968c59df8ee..d017904561d093bf8f0061f646a75aa53975be88 100644
 --- a/src/main/java/net/minecraft/server/TileEntityLootable.java
 +++ b/src/main/java/net/minecraft/server/TileEntityLootable.java
-@@ -72,12 +72,19 @@ public abstract class TileEntityLootable extends TileEntityContainer {
+@@ -77,12 +77,19 @@ public abstract class TileEntityLootable extends TileEntityContainer {
      @Override
      public boolean isEmpty() {
          this.d((EntityHuman) null);
@@ -481,10 +481,10 @@ index d4cbce3243fe1f4973c9c0ae0dbdab10e3390897..3b394c2726e0fbe595641a022e59c896
      }
  
 diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
-index 045e449c7e411dec7ef415c76c808cda426db652..2beb1374b105381d4467de4989c207339cb5dca1 100644
+index ddd66c2519d67585df06d68612a0c8a8830669ac..9b751727d137316290f363e39993f75293fd0887 100644
 --- a/src/main/java/net/minecraft/server/World.java
 +++ b/src/main/java/net/minecraft/server/World.java
-@@ -1206,8 +1206,8 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
+@@ -1133,8 +1133,8 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
          return list;
      }
  
diff --git a/Spigot-Server-Patches/0415-PlayerDeathEvent-shouldDropExperience.patch b/Spigot-Server-Patches/0399-PlayerDeathEvent-shouldDropExperience.patch
similarity index 81%
rename from Spigot-Server-Patches/0415-PlayerDeathEvent-shouldDropExperience.patch
rename to Spigot-Server-Patches/0399-PlayerDeathEvent-shouldDropExperience.patch
index ed6a98ac25..73006a4639 100644
--- a/Spigot-Server-Patches/0415-PlayerDeathEvent-shouldDropExperience.patch
+++ b/Spigot-Server-Patches/0399-PlayerDeathEvent-shouldDropExperience.patch
@@ -5,12 +5,12 @@ Subject: [PATCH] PlayerDeathEvent#shouldDropExperience
 
 
 diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
-index 86bbbbaefca9ace5327d8bc2456939eb9ae8966a..8434f10d4c674fbbed40dba86e54f7cad93df642 100644
+index 639bca91eec78f772b64677e37d8173e24b57391..458306bd5585e1b78dec6cbfafba1751c76513a2 100644
 --- a/src/main/java/net/minecraft/server/EntityPlayer.java
 +++ b/src/main/java/net/minecraft/server/EntityPlayer.java
-@@ -645,7 +645,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
- 
-         this.releaseShoulderEntities();
+@@ -691,7 +691,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
+             this.eW();
+         }
          // SPIGOT-5478 must be called manually now
 -        this.dropExperience();
 +        if (event.shouldDropExperience()) this.dropExperience(); // Paper - tie to event
diff --git a/Spigot-Server-Patches/0400-Generator-Settings.patch b/Spigot-Server-Patches/0400-Generator-Settings.patch
deleted file mode 100644
index 2cbf2fe4f7..0000000000
--- a/Spigot-Server-Patches/0400-Generator-Settings.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Byteflux <byte@byteflux.net>
-Date: Wed, 2 Mar 2016 02:17:54 -0600
-Subject: [PATCH] Generator Settings
-
-
-diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-index c148a57a9c3d44f2a0a2edfed4f96211745cc3e7..62fe175dc4f00cc9cab6cbd828b57e25740b3793 100644
---- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-@@ -604,4 +604,9 @@ public class PaperWorldConfig {
-     private void perPlayerMobSpawns() {
-         perPlayerMobSpawns = getBoolean("per-player-mob-spawns", false);
-     }
-+
-+    public boolean generateFlatBedrock;
-+    private void generatorSettings() {
-+        generateFlatBedrock = getBoolean("generator-settings.flat-bedrock", false);
-+    }
- }
-diff --git a/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java b/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java
-index af81a841428a656bc4c4a23c9dcafb25e4c96ee2..2268fbdd8716233ce8f5a8a68d17a8a460a6685f 100644
---- a/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java
-+++ b/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java
-@@ -211,8 +211,8 @@ public abstract class ChunkGeneratorAbstract<T extends GeneratorSettingsDefault>
-         int i = ichunkaccess.getPos().d();
-         int j = ichunkaccess.getPos().e();
-         T t0 = this.getSettings();
--        int k = t0.u();
--        int l = t0.t();
-+        int k = t0.u(); final int floorHeight = k; // Paper
-+        int l = t0.t(); final int roofHeight = l; // Paper
-         Iterator iterator = BlockPosition.b(i, 0, j, i + 15, 0, j + 15).iterator();
- 
-         while (iterator.hasNext()) {
-@@ -221,7 +221,7 @@ public abstract class ChunkGeneratorAbstract<T extends GeneratorSettingsDefault>
- 
-             if (l > 0) {
-                 for (i1 = l; i1 >= l - 4; --i1) {
--                    if (i1 >= l - random.nextInt(5)) {
-+                    if (i1 >= (getWorld().paperConfig.generateFlatBedrock ? roofHeight : l - random.nextInt(5))) { // Paper - Configurable flat bedrock roof
-                         ichunkaccess.setType(blockposition_mutableblockposition.d(blockposition.getX(), i1, blockposition.getZ()), Blocks.BEDROCK.getBlockData(), false);
-                     }
-                 }
-@@ -229,7 +229,7 @@ public abstract class ChunkGeneratorAbstract<T extends GeneratorSettingsDefault>
- 
-             if (k < 256) {
-                 for (i1 = k + 4; i1 >= k; --i1) {
--                    if (i1 <= k + random.nextInt(5)) {
-+                    if (i1 <= (getWorld().paperConfig.generateFlatBedrock ? floorHeight : k + random.nextInt(5))) { // Paper - Configurable flat bedrock floor
-                         ichunkaccess.setType(blockposition_mutableblockposition.d(blockposition.getX(), i1, blockposition.getZ()), Blocks.BEDROCK.getBlockData(), false);
-                     }
-                 }
diff --git a/Spigot-Server-Patches/0416-Prevent-bees-loading-chunks-checking-hive-position.patch b/Spigot-Server-Patches/0400-Prevent-bees-loading-chunks-checking-hive-position.patch
similarity index 82%
rename from Spigot-Server-Patches/0416-Prevent-bees-loading-chunks-checking-hive-position.patch
rename to Spigot-Server-Patches/0400-Prevent-bees-loading-chunks-checking-hive-position.patch
index 5aa65f1fea..8ff6e16636 100644
--- a/Spigot-Server-Patches/0416-Prevent-bees-loading-chunks-checking-hive-position.patch
+++ b/Spigot-Server-Patches/0400-Prevent-bees-loading-chunks-checking-hive-position.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Prevent bees loading chunks checking hive position
 
 
 diff --git a/src/main/java/net/minecraft/server/EntityBee.java b/src/main/java/net/minecraft/server/EntityBee.java
-index b39599654e3e0a1120a37d254c80749ba70b3c15..73e016257847e5654e37ec6dbf8c689c36593216 100644
+index 5cc0a9284ef635aa6cb6f4803c0776cdbbf515a8..dcfd2ea5024be6d4a001fa7437092a7831b36fa7 100644
 --- a/src/main/java/net/minecraft/server/EntityBee.java
 +++ b/src/main/java/net/minecraft/server/EntityBee.java
-@@ -386,6 +386,7 @@ public class EntityBee extends EntityAnimal implements EntityBird {
+@@ -368,6 +368,7 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
          if (!this.hasHivePos()) {
              return false;
          } else {
diff --git a/Spigot-Server-Patches/0417-Don-t-load-Chunks-from-Hoppers-and-other-things.patch b/Spigot-Server-Patches/0401-Don-t-load-Chunks-from-Hoppers-and-other-things.patch
similarity index 82%
rename from Spigot-Server-Patches/0417-Don-t-load-Chunks-from-Hoppers-and-other-things.patch
rename to Spigot-Server-Patches/0401-Don-t-load-Chunks-from-Hoppers-and-other-things.patch
index ed2db84aa9..83a4f9a58f 100644
--- a/Spigot-Server-Patches/0417-Don-t-load-Chunks-from-Hoppers-and-other-things.patch
+++ b/Spigot-Server-Patches/0401-Don-t-load-Chunks-from-Hoppers-and-other-things.patch
@@ -13,21 +13,20 @@ This of course is undesirable, so just return the loaded side as "primary"
 and treat it as a single chest if the other sides are unloaded
 
 diff --git a/src/main/java/net/minecraft/server/DoubleBlockFinder.java b/src/main/java/net/minecraft/server/DoubleBlockFinder.java
-index 3cb6e60895637405f163c1fac731926ee2cf0d2c..7a16a3e0e209b254db0ec15212d51fab71c17f60 100644
+index ac46a68f7b0f13b9d936ae872306a229ec4f1a61..89b2b11bf00b656bb23be855b25697e6ac93a0a2 100644
 --- a/src/main/java/net/minecraft/server/DoubleBlockFinder.java
 +++ b/src/main/java/net/minecraft/server/DoubleBlockFinder.java
-@@ -21,8 +21,12 @@ public class DoubleBlockFinder {
+@@ -21,7 +21,12 @@ public class DoubleBlockFinder {
                  return new DoubleBlockFinder.Result.Single<>(s0);
              } else {
                  BlockPosition blockposition1 = blockposition.shift((EnumDirection) function1.apply(iblockdata));
 -                IBlockData iblockdata1 = generatoraccess.getType(blockposition1);
--
-+                // Paper start - don't load chunks if the other side of the chest is in unloaded chunk
++                // Paper start
 +                IBlockData iblockdata1 = generatoraccess.getTypeIfLoaded(blockposition1);
 +                if (iblockdata1 == null) {
 +                    return new DoubleBlockFinder.Result.Single<>(s0);
 +                }
 +                // Paper end
-                 if (iblockdata1.getBlock() == iblockdata.getBlock()) {
-                     DoubleBlockFinder.BlockType doubleblockfinder_blocktype1 = (DoubleBlockFinder.BlockType) function.apply(iblockdata1);
  
+                 if (iblockdata1.a(iblockdata.getBlock())) {
+                     DoubleBlockFinder.BlockType doubleblockfinder_blocktype1 = (DoubleBlockFinder.BlockType) function.apply(iblockdata1);
diff --git a/Spigot-Server-Patches/0418-Guard-against-serializing-mismatching-chunk-coordina.patch b/Spigot-Server-Patches/0402-Guard-against-serializing-mismatching-chunk-coordina.patch
similarity index 85%
rename from Spigot-Server-Patches/0418-Guard-against-serializing-mismatching-chunk-coordina.patch
rename to Spigot-Server-Patches/0402-Guard-against-serializing-mismatching-chunk-coordina.patch
index c654bb838c..bcb1842884 100644
--- a/Spigot-Server-Patches/0418-Guard-against-serializing-mismatching-chunk-coordina.patch
+++ b/Spigot-Server-Patches/0402-Guard-against-serializing-mismatching-chunk-coordina.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Guard against serializing mismatching chunk coordinate
 Should help if something dumb happens
 
 diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
-index 34cd09a503bfe617bd50808927bae0ccf43e53fc..fa893b14bcef9bab6891dea2c4375b09d74ac038 100644
+index 4d6e8f987233ca6c5f53d004031c022bb2d43e1e..5b196201c0e35895a04e2a542ef7c753d0c469e1 100644
 --- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
 +++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
-@@ -23,6 +23,13 @@ public class ChunkRegionLoader {
+@@ -24,6 +24,13 @@ public class ChunkRegionLoader {
  
      private static final Logger LOGGER = LogManager.getLogger();
  
@@ -23,9 +23,9 @@ index 34cd09a503bfe617bd50808927bae0ccf43e53fc..fa893b14bcef9bab6891dea2c4375b09
      // Paper start
      public static final class InProgressChunkHolder {
  
-@@ -48,8 +55,8 @@ public class ChunkRegionLoader {
+@@ -49,8 +56,8 @@ public class ChunkRegionLoader {
          // Paper end
-         ChunkGenerator<?> chunkgenerator = worldserver.getChunkProvider().getChunkGenerator();
+         ChunkGenerator chunkgenerator = worldserver.getChunkProvider().getChunkGenerator();
          WorldChunkManager worldchunkmanager = chunkgenerator.getWorldChunkManager();
 -        NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Level");
 -        ChunkCoordIntPair chunkcoordintpair1 = new ChunkCoordIntPair(nbttagcompound1.getInt("xPos"), nbttagcompound1.getInt("zPos"));
@@ -35,11 +35,11 @@ index 34cd09a503bfe617bd50808927bae0ccf43e53fc..fa893b14bcef9bab6891dea2c4375b09
          if (!Objects.equals(chunkcoordintpair, chunkcoordintpair1)) {
              ChunkRegionLoader.LOGGER.error("Chunk file at {} is in the wrong location; relocating. (Expected {}, got {})", chunkcoordintpair, chunkcoordintpair, chunkcoordintpair1);
 diff --git a/src/main/java/net/minecraft/server/IChunkLoader.java b/src/main/java/net/minecraft/server/IChunkLoader.java
-index 134c76065bf382912e6c28d15449db3f9827f848..25c8b131fec6d9076120bd8ef516b14956a668ec 100644
+index c0d2df8ef3b4d0224ede2b7a4ef4e3f930590209..582a5695bac7d078e3022b8ee70c512c0680d992 100644
 --- a/src/main/java/net/minecraft/server/IChunkLoader.java
 +++ b/src/main/java/net/minecraft/server/IChunkLoader.java
-@@ -106,6 +106,13 @@ public class IChunkLoader extends RegionFileCache implements AutoCloseable {
- //
+@@ -106,6 +106,13 @@ public class IChunkLoader implements AutoCloseable {
+ 
      public void a(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException { write(chunkcoordintpair, nbttagcompound); } // Paper OBFHELPER
      public void write(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException { // Paper - OBFHELPER - (Switched around for safety)
 +        // Paper start
@@ -49,6 +49,6 @@ index 134c76065bf382912e6c28d15449db3f9827f848..25c8b131fec6d9076120bd8ef516b149
 +                + " but compound says coordinate is " + ChunkRegionLoader.getChunkCoordinate(nbttagcompound).toString() + (world == null ? " for an unknown world" : (" for world: " + world)));
 +        }
 +        // Paper end
-         super.write(chunkcoordintpair, nbttagcompound);
+         this.regionFileCache.write(chunkcoordintpair, nbttagcompound);
          if (this.c != null) {
              synchronized (this.persistentDataLock) { // Paper - Async chunk loading
diff --git a/Spigot-Server-Patches/0419-Optimise-IEntityAccess-getPlayerByUUID.patch b/Spigot-Server-Patches/0403-Optimise-IEntityAccess-getPlayerByUUID.patch
similarity index 57%
rename from Spigot-Server-Patches/0419-Optimise-IEntityAccess-getPlayerByUUID.patch
rename to Spigot-Server-Patches/0403-Optimise-IEntityAccess-getPlayerByUUID.patch
index f9ea7f61b5..8087a97ce9 100644
--- a/Spigot-Server-Patches/0419-Optimise-IEntityAccess-getPlayerByUUID.patch
+++ b/Spigot-Server-Patches/0403-Optimise-IEntityAccess-getPlayerByUUID.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Optimise IEntityAccess#getPlayerByUUID
 Use the world entity map instead of iterating over all players
 
 diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java
-index d5c284cdd10d33f5f1b7f456d6a384a44eafb139..4157e50e4d99c029759bffcb48a8d645487554c8 100644
+index 48e8b005bd9589135eff03a110ecce8776ab208a..74d4c28246e7db850e6d993e07a84b2a6ca24ce2 100644
 --- a/src/main/java/net/minecraft/server/IEntityAccess.java
 +++ b/src/main/java/net/minecraft/server/IEntityAccess.java
-@@ -219,6 +219,12 @@ public interface IEntityAccess {
+@@ -235,6 +235,12 @@ public interface IEntityAccess {
  
      @Nullable
      default EntityHuman b(UUID uuid) {
@@ -23,12 +23,12 @@ index d5c284cdd10d33f5f1b7f456d6a384a44eafb139..4157e50e4d99c029759bffcb48a8d645
              EntityHuman entityhuman = (EntityHuman) this.getPlayers().get(i);
  
 diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
-index 3ecc73d021c09fbcad74dd62aced460771f86038..f32e313a6287c8f5d487d4ad7148cac176773228 100644
+index 0dd249f94905c30b5320109a3f0b17cac70def8d..1d4e34b2ece861e7e4f2fe0f15f6fbf8ab47f86c 100644
 --- a/src/main/java/net/minecraft/server/WorldServer.java
 +++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -82,6 +82,15 @@ public class WorldServer extends World {
-         return new Throwable(entity + " Added to world at " + new java.util.Date());
+@@ -173,6 +173,15 @@ public class WorldServer extends World implements GeneratorAccessSeed {
      }
+     // Paper end
  
 +    // Paper start - optimise getPlayerByUUID
 +    @Nullable
@@ -39,6 +39,6 @@ index 3ecc73d021c09fbcad74dd62aced460771f86038..f32e313a6287c8f5d487d4ad7148cac1
 +    }
 +    // Paper end
 +
-     // Paper start - Asynchronous IO
-     public final com.destroystokyo.paper.io.PaperFileIOThread.ChunkDataController poiDataController = new com.destroystokyo.paper.io.PaperFileIOThread.ChunkDataController() {
-         @Override
+     // Add env and gen to constructor, WorldData -> WorldDataServer
+     public WorldServer(MinecraftServer minecraftserver, Executor executor, Convertable.ConversionSession convertable_conversionsession, IWorldDataServer iworlddataserver, ResourceKey<World> resourcekey, ResourceKey<DimensionManager> resourcekey1, DimensionManager dimensionmanager, WorldLoadListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List<MobSpawner> list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
+         super(iworlddataserver, resourcekey, resourcekey1, dimensionmanager, minecraftserver::getMethodProfiler, false, flag, i, gen, env, executor); // Paper pass executor
diff --git a/Spigot-Server-Patches/0420-Fix-items-not-falling-correctly.patch b/Spigot-Server-Patches/0404-Fix-items-not-falling-correctly.patch
similarity index 89%
rename from Spigot-Server-Patches/0420-Fix-items-not-falling-correctly.patch
rename to Spigot-Server-Patches/0404-Fix-items-not-falling-correctly.patch
index ac6d68d294..e8f474c064 100644
--- a/Spigot-Server-Patches/0420-Fix-items-not-falling-correctly.patch
+++ b/Spigot-Server-Patches/0404-Fix-items-not-falling-correctly.patch
@@ -15,10 +15,10 @@ This patch resolves the conflict by offsetting checking an item's
 move method from Spigot's entity activation range check.
 
 diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java
-index 507627a29f67c380314d2fa8ee56807ced8ee56a..2926fbb95705f4389ca599c3bf0421267b83d401 100644
+index f2626358d16e8f3d60633283322009e5afacd145..a7860cb4ded3e9f949e6e1a7a2afacd738da756e 100644
 --- a/src/main/java/net/minecraft/server/EntityItem.java
 +++ b/src/main/java/net/minecraft/server/EntityItem.java
-@@ -86,7 +86,7 @@ public class EntityItem extends Entity {
+@@ -88,7 +88,7 @@ public class EntityItem extends Entity {
                  }
              }
  
diff --git a/Spigot-Server-Patches/0421-Lag-compensate-eating.patch b/Spigot-Server-Patches/0405-Lag-compensate-eating.patch
similarity index 65%
rename from Spigot-Server-Patches/0421-Lag-compensate-eating.patch
rename to Spigot-Server-Patches/0405-Lag-compensate-eating.patch
index 606469d9d6..97c8f1a7b7 100644
--- a/Spigot-Server-Patches/0421-Lag-compensate-eating.patch
+++ b/Spigot-Server-Patches/0405-Lag-compensate-eating.patch
@@ -7,76 +7,76 @@ When the server is lagging, players will wait longer when eating.
 Change to also use a time check instead if it passes.
 
 diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
-index 4f9255c0bc2ff46f34072846d2b0dc2e97f05db4..0ec0ddb7d0e3f25820fe064d75916407cb579eae 100644
+index 17491b9f9b4c8fb931a249580810681cb618ee45..3d30dcfdf124ff634afff3db17375bad06a19ad8 100644
 --- a/src/main/java/net/minecraft/server/EntityLiving.java
 +++ b/src/main/java/net/minecraft/server/EntityLiving.java
-@@ -113,7 +113,7 @@ public abstract class EntityLiving extends Entity {
+@@ -119,7 +119,7 @@ public abstract class EntityLiving extends Entity {
      private int jumpTicks;
      private float bD;
      public ItemStack activeItem; // Paper - public
--    protected int bl;
-+    protected int bl; protected final int getEatTimeTicks() { return this.bl; } protected final void setEatTimeTicks(int value) { this.bl = value; } // Paper - OBFHELPER
-     protected int bm;
+-    protected int bk;
++    protected int bk; protected final int getEatTimeTicks() { return this.bk; } protected final void setEatTimeTicks(int value) { this.bk = value; } // Paper - OBFHELPER
+     protected int bl;
      private BlockPosition bE;
-     private DamageSource bF;
-@@ -2848,6 +2848,10 @@ public abstract class EntityLiving extends Entity {
-         return ((Byte) this.datawatcher.get(EntityLiving.ao) & 2) > 0 ? EnumHand.OFF_HAND : EnumHand.MAIN_HAND;
+     private Optional<BlockPosition> bF;
+@@ -3012,6 +3012,11 @@ public abstract class EntityLiving extends Entity {
+         return ((Byte) this.datawatcher.get(EntityLiving.an) & 2) > 0 ? EnumHand.OFF_HAND : EnumHand.MAIN_HAND;
      }
  
 +    // Paper start - lag compensate eating
 +    protected long eatStartTime;
 +    protected int totalEatTimeTicks;
 +    // Paper end
-     private void o() {
++
+     private void u() {
          if (this.isHandRaised()) {
              if (ItemStack.d(this.b(this.getRaisedHand()), this.activeItem)) {
-@@ -2856,7 +2860,14 @@ public abstract class EntityLiving extends Entity {
+@@ -3021,7 +3026,13 @@ public abstract class EntityLiving extends Entity {
                      this.b(this.activeItem, 5);
                  }
  
--                if (--this.bl == 0 && !this.world.isClientSide && !this.activeItem.m()) {
-+
+-                if (--this.bk == 0 && !this.world.isClientSide && !this.activeItem.m()) {
 +                // Paper start - lag compensate eating
 +                // we add 1 to the expected time to avoid lag compensating when we should not
 +                boolean shouldLagCompensate
 +                    = this.activeItem.getItem().isFood() && this.eatStartTime != -1 && (System.nanoTime() - this.eatStartTime) > ((1 + this.totalEatTimeTicks) * 50 * (1000 * 1000));
-+                if ((--this.bl == 0 || shouldLagCompensate) && !this.world.isClientSide && !this.activeItem.m()) {
++                if ((--this.bk == 0 || shouldLagCompensate) && !this.world.isClientSide && !this.activeItem.m()) {
 +                    this.setEatTimeTicks(0);
 +                    // Paper end
-                     this.q();
+                     this.s();
                  }
              } else {
-@@ -2906,7 +2917,10 @@ public abstract class EntityLiving extends Entity {
+@@ -3071,7 +3082,10 @@ public abstract class EntityLiving extends Entity {
  
          if (!itemstack.isEmpty() && !this.isHandRaised() || forceUpdate) { // Paper use override flag
              this.activeItem = itemstack;
--            this.bl = itemstack.k();
+-            this.bk = itemstack.k();
 +            // Paper start - lag compensate eating
-+            this.bl = this.totalEatTimeTicks = itemstack.k();
++            this.bk = this.totalEatTimeTicks = itemstack.k();
 +            this.eatStartTime = System.nanoTime();
 +            // Paper end
              if (!this.world.isClientSide) {
                  this.c(1, true);
                  this.c(2, enumhand == EnumHand.OFF_HAND);
-@@ -2930,7 +2944,10 @@ public abstract class EntityLiving extends Entity {
+@@ -3095,7 +3109,10 @@ public abstract class EntityLiving extends Entity {
                  }
              } else if (!this.isHandRaised() && !this.activeItem.isEmpty()) {
-                 this.activeItem = ItemStack.a;
--                this.bl = 0;
+                 this.activeItem = ItemStack.b;
+-                this.bk = 0;
 +                // Paper start - lag compensate eating
-+                this.bl = this.totalEatTimeTicks = 0;
++                this.bk = this.totalEatTimeTicks = 0;
 +                this.eatStartTime = -1L;
 +                // Paper end
              }
          }
  
-@@ -3052,7 +3069,10 @@ public abstract class EntityLiving extends Entity {
+@@ -3217,7 +3234,10 @@ public abstract class EntityLiving extends Entity {
          }
  
-         this.activeItem = ItemStack.a;
--        this.bl = 0;
+         this.activeItem = ItemStack.b;
+-        this.bk = 0;
 +        // Paper start - lag compensate eating
-+        this.bl = this.totalEatTimeTicks = 0;
++        this.bk = this.totalEatTimeTicks = 0;
 +        this.eatStartTime = -1L;
 +        // Paper end
      }
diff --git a/Spigot-Server-Patches/0422-Optimize-call-to-getFluid-for-explosions.patch b/Spigot-Server-Patches/0406-Optimize-call-to-getFluid-for-explosions.patch
similarity index 72%
rename from Spigot-Server-Patches/0422-Optimize-call-to-getFluid-for-explosions.patch
rename to Spigot-Server-Patches/0406-Optimize-call-to-getFluid-for-explosions.patch
index 1657736d45..46956819e7 100644
--- a/Spigot-Server-Patches/0422-Optimize-call-to-getFluid-for-explosions.patch
+++ b/Spigot-Server-Patches/0406-Optimize-call-to-getFluid-for-explosions.patch
@@ -5,15 +5,15 @@ Subject: [PATCH] Optimize call to getFluid for explosions
 
 
 diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java
-index d99d2defe9916e191ba7a2bfbd94bd72a2f5872a..a353f3d5fa5a5f54335f73584589de3f5cb20d3e 100644
+index 1b738260fb06446713ceab159eb7fa3df70fb611..22a19e761fdec68cc9405988b977021a8b6398eb 100644
 --- a/src/main/java/net/minecraft/server/Explosion.java
 +++ b/src/main/java/net/minecraft/server/Explosion.java
-@@ -117,7 +117,7 @@ public class Explosion {
+@@ -124,7 +124,7 @@ public class Explosion {
                          for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) {
                              BlockPosition blockposition = new BlockPosition(d4, d5, d6);
                              IBlockData iblockdata = this.world.getType(blockposition);
 -                            Fluid fluid = this.world.getFluid(blockposition);
 +                            Fluid fluid = iblockdata.getFluid(); // Paper
+                             Optional<Float> optional = this.k.a(this, this.world, blockposition, iblockdata, fluid);
  
-                             if (!iblockdata.isAir() || !fluid.isEmpty()) {
-                                 float f2 = Math.max(iblockdata.getBlock().getDurability(), fluid.k());
+                             if (optional.isPresent()) {
diff --git a/Spigot-Server-Patches/0423-Fix-last-firework-in-stack-not-having-effects-when-d.patch b/Spigot-Server-Patches/0407-Fix-last-firework-in-stack-not-having-effects-when-d.patch
similarity index 56%
rename from Spigot-Server-Patches/0423-Fix-last-firework-in-stack-not-having-effects-when-d.patch
rename to Spigot-Server-Patches/0407-Fix-last-firework-in-stack-not-having-effects-when-d.patch
index a1c44ea4f9..9c065ec6c5 100644
--- a/Spigot-Server-Patches/0423-Fix-last-firework-in-stack-not-having-effects-when-d.patch
+++ b/Spigot-Server-Patches/0407-Fix-last-firework-in-stack-not-having-effects-when-d.patch
@@ -9,15 +9,15 @@ dispensed. The resulting item would have size == 0 and therefore
 be convertered to air, hence why the effects disappeared.
 
 diff --git a/src/main/java/net/minecraft/server/IDispenseBehavior.java b/src/main/java/net/minecraft/server/IDispenseBehavior.java
-index b6b7e3c6c973886e35bde0bf10787b62c7f015ca..3af686c7f1e483afd4dbf5e2b27c484e2ef321d0 100644
+index 5432c24919bb5c32ca1eec4c9861ad127f72a60a..660f44975a003ea68ddad59899618485fdaf5487 100644
 --- a/src/main/java/net/minecraft/server/IDispenseBehavior.java
 +++ b/src/main/java/net/minecraft/server/IDispenseBehavior.java
-@@ -265,7 +265,7 @@ public interface IDispenseBehavior {
+@@ -352,7 +352,7 @@ public interface IDispenseBehavior {
                  }
  
                  itemstack1 = CraftItemStack.asNMSCopy(event.getItem());
--                EntityFireworks entityfireworks = new EntityFireworks(isourceblock.getWorld(), itemstack, d3, d4, d5, true);
-+                EntityFireworks entityfireworks = new EntityFireworks(isourceblock.getWorld(), itemstack1, d3, d4, d5, true); // Paper - GH-2871 - fix last firework in stack having no effects when dispensed
+-                EntityFireworks entityfireworks = new EntityFireworks(isourceblock.getWorld(), itemstack, isourceblock.getX(), isourceblock.getY(), isourceblock.getX(), true);
++                EntityFireworks entityfireworks = new EntityFireworks(isourceblock.getWorld(), itemstack1, isourceblock.getX(), isourceblock.getY(), isourceblock.getX(), true); // Paper - GH-2871 - fix last firework in stack having no effects when dispensed
  
-                 entityfireworks.shoot(d0, d1, d2, 0.5F, 1.0F);
-                 isourceblock.getWorld().addEntity(entityfireworks);
+                 IDispenseBehavior.a(isourceblock, entityfireworks, enumdirection);
+                 entityfireworks.shoot((double) enumdirection.getAdjacentX(), (double) enumdirection.getAdjacentY(), (double) enumdirection.getAdjacentZ(), 0.5F, 1.0F);
diff --git a/Spigot-Server-Patches/0424-Entity-Activation-Range-2.0.patch b/Spigot-Server-Patches/0408-Entity-Activation-Range-2.0.patch
similarity index 89%
rename from Spigot-Server-Patches/0424-Entity-Activation-Range-2.0.patch
rename to Spigot-Server-Patches/0408-Entity-Activation-Range-2.0.patch
index 574d3c7907..36be6d5baa 100644
--- a/Spigot-Server-Patches/0424-Entity-Activation-Range-2.0.patch
+++ b/Spigot-Server-Patches/0408-Entity-Activation-Range-2.0.patch
@@ -14,22 +14,22 @@ Adds flying monsters to control ghast and phantoms
 Adds villagers as separate config
 
 diff --git a/src/main/java/net/minecraft/server/BehaviorController.java b/src/main/java/net/minecraft/server/BehaviorController.java
-index a1883eba63e0da420a3cf57b8da6ebdb2afbad80..7c6e687707cdf32638eee41e549818a494cd45ab 100644
+index ae2905b403a63396d9cdc61444586ea5548f2974..5ba4f96eec81dc6552aa195eaf544fe400441458 100644
 --- a/src/main/java/net/minecraft/server/BehaviorController.java
 +++ b/src/main/java/net/minecraft/server/BehaviorController.java
-@@ -161,6 +161,7 @@ public class BehaviorController<E extends EntityLiving> implements MinecraftSeri
-         });
+@@ -379,6 +379,7 @@ public class BehaviorController<E extends EntityLiving> {
+ 
      }
  
 +    public boolean hasActivity(Activity activity) { return c(activity); } // Paper - OBFHELPER
      public boolean c(Activity activity) {
-         return this.g.contains(activity);
+         return this.j.contains(activity);
      }
 diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
-index fbec89c6d827463ea28036617acaa573c8e11d02..a1245c1f551cbce84b0f3dd3a7349e8585631a82 100644
+index 397ca1f0667ec002829e0d0435bedc6465538e8a..bc162a4f18d1123a2e844f4429ea2c26b632dfe5 100644
 --- a/src/main/java/net/minecraft/server/Entity.java
 +++ b/src/main/java/net/minecraft/server/Entity.java
-@@ -192,6 +192,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
+@@ -193,6 +193,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
      public final org.spigotmc.ActivationRange.ActivationType activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this);
      public final boolean defaultActivationState;
      public long activatedTick = Integer.MIN_VALUE;
@@ -37,7 +37,7 @@ index fbec89c6d827463ea28036617acaa573c8e11d02..a1245c1f551cbce84b0f3dd3a7349e85
      public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one
      protected int numCollisions = 0; // Paper
      public void inactiveTick() { }
-@@ -553,6 +554,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
+@@ -576,6 +577,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
              this.recalcPosition();
          } else {
              if (enummovetype == EnumMoveType.PISTON) {
@@ -45,8 +45,8 @@ index fbec89c6d827463ea28036617acaa573c8e11d02..a1245c1f551cbce84b0f3dd3a7349e85
                  vec3d = this.a(vec3d);
                  if (vec3d.equals(Vec3D.a)) {
                      return;
-@@ -565,6 +567,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
-                 this.y = Vec3D.a;
+@@ -588,6 +590,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
+                 this.x = Vec3D.a;
                  this.setMot(Vec3D.a);
              }
 +            // Paper start - ignore movement changes while inactive.
@@ -58,17 +58,17 @@ index fbec89c6d827463ea28036617acaa573c8e11d02..a1245c1f551cbce84b0f3dd3a7349e85
 +            // Paper end
  
              vec3d = this.a(vec3d, enummovetype);
-             Vec3D vec3d1 = this.e(vec3d);
-@@ -2769,6 +2778,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
-         return this.am;
+             Vec3D vec3d1 = this.f(vec3d);
+@@ -2695,6 +2704,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
+         return this.al;
      }
  
-+    public boolean isPushedByWater() { return this.bM(); } // Paper - OBFHELPER - the below is not an obfhelper, don't use it!
-     public boolean bM() {
++    public boolean isPushedByWater() { return this.bU(); } // Paper - OBFHELPER - the below is not an obfhelper, don't use it!
+     public boolean bU() {
          // Paper start
          return this.pushedByWater();
 diff --git a/src/main/java/net/minecraft/server/EntityCreature.java b/src/main/java/net/minecraft/server/EntityCreature.java
-index b40c8d2f83a80bcb8925632a1e7d6bb4cc0caebf..4eda130750ff4903c3dc7d2afae09b8b77ff62b9 100644
+index c94197a50269622e8995685119bac984c45e6833..11d384729326af693a9a679195acbd594227466a 100644
 --- a/src/main/java/net/minecraft/server/EntityCreature.java
 +++ b/src/main/java/net/minecraft/server/EntityCreature.java
 @@ -7,6 +7,7 @@ import org.bukkit.event.entity.EntityUnleashEvent;
@@ -80,19 +80,19 @@ index b40c8d2f83a80bcb8925632a1e7d6bb4cc0caebf..4eda130750ff4903c3dc7d2afae09b8b
      protected EntityCreature(EntityTypes<? extends EntityCreature> entitytypes, World world) {
          super(entitytypes, world);
 diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java
-index 6d53254f8381f3a957673930c7fdf42d4b9d2f36..5aca7a9131787415fb2edba1ebec9601e8a56d3a 100644
+index 081baca9a101d188e4810d04f69811d52de7a107..9f6f2caf25825bb135037c6205cb578dd375b9f8 100644
 --- a/src/main/java/net/minecraft/server/EntityInsentient.java
 +++ b/src/main/java/net/minecraft/server/EntityInsentient.java
-@@ -46,7 +46,7 @@ public abstract class EntityInsentient extends EntityLiving {
+@@ -47,7 +47,7 @@ public abstract class EntityInsentient extends EntityLiving {
      public MinecraftKey lootTableKey;
      public long lootTableSeed;
      @Nullable
 -    private Entity leashHolder;
-+    public Entity leashHolder; // Paper
-     private int bF;
++    public Entity leashHolder; // Paper - private -> public
+     private int bE;
      @Nullable
-     private NBTTagCompound bG;
-@@ -114,6 +114,17 @@ public abstract class EntityInsentient extends EntityLiving {
+     private NBTTagCompound bF;
+@@ -128,6 +128,17 @@ public abstract class EntityInsentient extends EntityLiving {
          return this.lookController;
      }
  
@@ -111,35 +111,35 @@ index 6d53254f8381f3a957673930c7fdf42d4b9d2f36..5aca7a9131787415fb2edba1ebec9601
          if (this.isPassenger() && this.getVehicle() instanceof EntityInsentient) {
              EntityInsentient entityinsentient = (EntityInsentient) this.getVehicle();
 diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
-index 0ec0ddb7d0e3f25820fe064d75916407cb579eae..bbe72ac65b7a9cfdfd577a0fbc316fbcc84fac59 100644
+index 3d30dcfdf124ff634afff3db17375bad06a19ad8..27b92664cee1c685b5b6b9b385150bb5fdb9fa7a 100644
 --- a/src/main/java/net/minecraft/server/EntityLiving.java
 +++ b/src/main/java/net/minecraft/server/EntityLiving.java
-@@ -91,7 +91,7 @@ public abstract class EntityLiving extends Entity {
-     protected float aV;
-     protected int aW; protected int getKillCount() { return this.aW; } // Paper - OBFHELPER
+@@ -97,7 +97,7 @@ public abstract class EntityLiving extends Entity {
+     protected float aU;
+     protected int aV; protected int getKillCount() { return this.aV; } // Paper - OBFHELPER
      public float lastDamage;
 -    protected boolean jumping;
-+    public boolean jumping; // Paper
++    public boolean jumping; // Paper protected -> public
+     public float aY;
      public float aZ;
      public float ba;
-     public float bb;
 diff --git a/src/main/java/net/minecraft/server/EntityLlama.java b/src/main/java/net/minecraft/server/EntityLlama.java
-index 6d4d41c88c206ad63f3733b5c8b3f23eb40dde52..193dbfc5f684bfe46f69cb2ab2c52dbb44707792 100644
+index 7ce3421696fbfc5a445f879dfd55a3055502a933..4fe769c761949c40bbb923cde5dfe1709843921f 100644
 --- a/src/main/java/net/minecraft/server/EntityLlama.java
 +++ b/src/main/java/net/minecraft/server/EntityLlama.java
-@@ -382,6 +382,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn
-         return this.bK != null;
-     }
- 
-+    public boolean inCaravan() { return this.fd(); } // Paper - OBFHELPER
-     public boolean fd() {
+@@ -404,6 +404,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn
          return this.bJ != null;
      }
+ 
++    public final boolean inCaravan() { return this.fD(); } // Paper - OBFHELPER
+     public boolean fD() {
+         return this.bI != null;
+     }
 diff --git a/src/main/java/net/minecraft/server/EntityVillager.java b/src/main/java/net/minecraft/server/EntityVillager.java
-index 6e0020ae0b4d2f2597843129b83fff0d194de337..b3462576469f67dca618c54bb35fd53454afcd1f 100644
+index a23c8d54a30a1ed1a3ed4d158da08229f59ca4c5..8d3811ead268635c4b728f5c9b8dd6c9b8ec6124 100644
 --- a/src/main/java/net/minecraft/server/EntityVillager.java
 +++ b/src/main/java/net/minecraft/server/EntityVillager.java
-@@ -135,17 +135,30 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
+@@ -144,18 +144,29 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
      @Override
      public void inactiveTick() {
          // SPIGOT-3874, SPIGOT-3894, SPIGOT-3846, SPIGOT-5286 :(
@@ -148,14 +148,14 @@ index 6e0020ae0b4d2f2597843129b83fff0d194de337..b3462576469f67dca618c54bb35fd534
 +        // Paper start
 +        if (this.getUnhappy() > 0) {
 +            this.setUnhappy(this.getUnhappy() - 1);
-+        }
+         }
 +        if (this.doAITick()) {
 +            if (world.spigotConfig.tickInactiveVillagers) {
 +                this.mobTick();
 +            } else {
 +                this.mobTick(true);
 +            }
-         }
++        }
 +        doReputationTick();
 +        // Paper end
 +
@@ -163,62 +163,61 @@ index 6e0020ae0b4d2f2597843129b83fff0d194de337..b3462576469f67dca618c54bb35fd534
      }
      // Spigot End
  
--    @Override
+     @Override
 -    protected void mobTick() {
-+    @Override // Paper start - tick trades while inactive
 +    protected void mobTick() { mobTick(false); }
 +    protected void mobTick(boolean inactive) {
-+        // Paper end
-         this.world.getMethodProfiler().enter("brain");
+         this.world.getMethodProfiler().enter("villagerBrain");
 -        this.getBehaviorController().a((WorldServer) this.world, this); // CraftBukkit - decompile error
+-        this.world.getMethodProfiler().exit();
 +        if (!inactive) this.getBehaviorController().a((WorldServer) this.world, this); // CraftBukkit - decompile error // Paper
-         this.world.getMethodProfiler().exit();
-         if (!this.et() && this.bB > 0) {
-             --this.bB;
-@@ -165,7 +178,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
-             this.bD = null;
+         if (this.bM) {
+             this.bM = false;
+         }
+@@ -178,7 +189,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
+             this.bC = null;
          }
  
 -        if (!this.isNoAI() && this.random.nextInt(100) == 0) {
 +        if (!inactive && !this.isNoAI() && this.random.nextInt(100) == 0) { // Paper
-             Raid raid = ((WorldServer) this.world).c_(new BlockPosition(this));
+             Raid raid = ((WorldServer) this.world).c_(this.getChunkCoordinates());
  
              if (raid != null && raid.v() && !raid.a()) {
-@@ -176,6 +189,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
-         if (this.getVillagerData().getProfession() == VillagerProfession.NONE && this.et()) {
-             this.ey();
+@@ -189,6 +200,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
+         if (this.getVillagerData().getProfession() == VillagerProfession.NONE && this.eO()) {
+             this.eT();
          }
 +        if (inactive) return; // Paper
  
          super.mobTick();
      }
-@@ -819,6 +833,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
+@@ -820,6 +832,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
          }
      }
  
-+    private void doReputationTick() { fa(); } // Paper - OBFHELPER
-     private void fa() {
++    private void doReputationTick() { fv(); } // Paper - OBFHELPER
+     private void fv() {
          long i = this.world.getTime();
  
 diff --git a/src/main/java/net/minecraft/server/EntityVillagerAbstract.java b/src/main/java/net/minecraft/server/EntityVillagerAbstract.java
-index 9b75c67c72bc2837cf12bf7ef8172031831deb6e..463528532026e9757431a90cc2540af0f7903faf 100644
+index b2ea467f26f78d3239062c6c3b9741b87489713e..81823b5d5ef17479583fda0121c95091175fdf1e 100644
 --- a/src/main/java/net/minecraft/server/EntityVillagerAbstract.java
 +++ b/src/main/java/net/minecraft/server/EntityVillagerAbstract.java
-@@ -43,10 +43,12 @@ public abstract class EntityVillagerAbstract extends EntityAgeable implements NP
+@@ -45,10 +45,12 @@ public abstract class EntityVillagerAbstract extends EntityAgeable implements NP
          return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, (GroupDataEntity) groupdataentity, nbttagcompound);
      }
  
-+    public final int getUnhappy() { return eq(); } // Paper - OBFHELPER
-     public int eq() {
-         return (Integer) this.datawatcher.get(EntityVillagerAbstract.bx);
++    public final int getUnhappy() { return eL(); } // Paper - OBFHELPER
+     public int eL() {
+         return (Integer) this.datawatcher.get(EntityVillagerAbstract.bw);
      }
  
 +    public final void setUnhappy(int i) { s(i); } // Paper - OBFHELPER
      public void s(int i) {
-         this.datawatcher.set(EntityVillagerAbstract.bx, i);
+         this.datawatcher.set(EntityVillagerAbstract.bw, i);
      }
 diff --git a/src/main/java/net/minecraft/server/PathfinderGoal.java b/src/main/java/net/minecraft/server/PathfinderGoal.java
-index f22f12eeb0b10d038fcd74cc4b19e888b134c3c7..bdb90a346639db37d3c72359c28b72d021d1b389 100644
+index d9454448119a3c1590b7f9ef141dccf10d4742cc..384300894d19ff70556c23b130c01b2e49aa3f20 100644
 --- a/src/main/java/net/minecraft/server/PathfinderGoal.java
 +++ b/src/main/java/net/minecraft/server/PathfinderGoal.java
 @@ -20,7 +20,10 @@ public abstract class PathfinderGoal {
@@ -234,7 +233,7 @@ index f22f12eeb0b10d038fcd74cc4b19e888b134c3c7..bdb90a346639db37d3c72359c28b72d0
      public void e() {}
  
 diff --git a/src/main/java/net/minecraft/server/PathfinderGoalGotoTarget.java b/src/main/java/net/minecraft/server/PathfinderGoalGotoTarget.java
-index 41fb166ce0ab29148ebd40e147fef98d1a2e9609..e93129f0b281e242383e36c99d19f6b0577a0b6b 100644
+index b0e17a5764ae4668ef45c4b5e8fe7280b3f5bfdf..3e26c32d0c886c6bd70aa4823d8738cdde7a6b24 100644
 --- a/src/main/java/net/minecraft/server/PathfinderGoalGotoTarget.java
 +++ b/src/main/java/net/minecraft/server/PathfinderGoalGotoTarget.java
 @@ -4,12 +4,12 @@ import java.util.EnumSet;
@@ -267,7 +266,7 @@ index 41fb166ce0ab29148ebd40e147fef98d1a2e9609..e93129f0b281e242383e36c99d19f6b0
      public PathfinderGoalGotoTarget(EntityCreature entitycreature, double d0, int i, int j) {
          this.e = BlockPosition.ZERO;
 @@ -100,6 +107,7 @@ public abstract class PathfinderGoalGotoTarget extends PathfinderGoal {
-                         blockposition_mutableblockposition.g(blockposition).e(i1, k - 1, j1);
+                         blockposition_mutableblockposition.a((BaseBlockPosition) blockposition, i1, k - 1, j1);
                          if (this.a.a((BlockPosition) blockposition_mutableblockposition) && this.a(this.a.world, blockposition_mutableblockposition)) {
                              this.e = blockposition_mutableblockposition;
 +                            setTarget(blockposition_mutableblockposition.immutableCopy()); // Paper
@@ -275,24 +274,24 @@ index 41fb166ce0ab29148ebd40e147fef98d1a2e9609..e93129f0b281e242383e36c99d19f6b0
                          }
                      }
 diff --git a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java b/src/main/java/net/minecraft/server/PathfinderGoalSelector.java
-index 44bb18c5945b69f09b3a6e6272f2c3a5477780c7..935136771e776fe498f608a159a41393340adc4e 100644
+index 482ce2cd8123252110508e8e03aa65afdd533e0a..b18e53220d8dbd50723c4201231091cbe4f4119a 100644
 --- a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java
 +++ b/src/main/java/net/minecraft/server/PathfinderGoalSelector.java
-@@ -24,10 +24,11 @@ public class PathfinderGoalSelector {
+@@ -25,10 +25,11 @@ public class PathfinderGoalSelector {
          }
      };
      private final Map<PathfinderGoal.Type, PathfinderGoalWrapped> c = new EnumMap(PathfinderGoal.Type.class);
 -    private final Set<PathfinderGoalWrapped> d = Sets.newLinkedHashSet();
-+    private final Set<PathfinderGoalWrapped> d = Sets.newLinkedHashSet();private Set<PathfinderGoalWrapped> getTasks() { return d; }// Paper - OBFHELPER
-     private final GameProfilerFiller e;
++    private final Set<PathfinderGoalWrapped> d = Sets.newLinkedHashSet(); private Set<PathfinderGoalWrapped> getTasks() { return d; }// Paper - OBFHELPER
+     private final Supplier<GameProfilerFiller> e;
      private final EnumSet<PathfinderGoal.Type> f = EnumSet.noneOf(PathfinderGoal.Type.class);
 -    private int g = 3;
 +    private int g = 3;private int getTickRate() { return g; } // Paper - OBFHELPER
 +    private int curRate;private int getCurRate() { return curRate; } private void incRate() { this.curRate++; } // Paper TODO
  
-     public PathfinderGoalSelector(GameProfilerFiller gameprofilerfiller) {
-         this.e = gameprofilerfiller;
-@@ -37,6 +38,25 @@ public class PathfinderGoalSelector {
+     public PathfinderGoalSelector(Supplier<GameProfilerFiller> supplier) {
+         this.e = supplier;
+@@ -38,6 +39,25 @@ public class PathfinderGoalSelector {
          this.d.add(new PathfinderGoalWrapped(i, pathfindergoal));
      }
  
@@ -319,7 +318,7 @@ index 44bb18c5945b69f09b3a6e6272f2c3a5477780c7..935136771e776fe498f608a159a41393
          this.d.stream().filter((pathfindergoalwrapped) -> {
              return pathfindergoalwrapped.j() == pathfindergoal;
 diff --git a/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java b/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java
-index 5a8c60ad909394413427851db8068ba79c058b63..29657fed75184aee0c89e56f5e642a5d68eda444 100644
+index 50487dbf0ac162d7608b67b4fb50fa7f8bfba69d..04b28555b1bb68536e40bb652613678775337b31 100644
 --- a/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java
 +++ b/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java
 @@ -64,6 +64,7 @@ public class PathfinderGoalWrapped extends PathfinderGoal {
@@ -331,10 +330,10 @@ index 5a8c60ad909394413427851db8068ba79c058b63..29657fed75184aee0c89e56f5e642a5d
          return this.c;
      }
 diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
-index 2beb1374b105381d4467de4989c207339cb5dca1..0fa2b335db297c6270090d3dd24ced92eab12825 100644
+index 9b751727d137316290f363e39993f75293fd0887..7d13f7a8b7272ad2ac86e706c1b8c7649cccb01c 100644
 --- a/src/main/java/net/minecraft/server/World.java
 +++ b/src/main/java/net/minecraft/server/World.java
-@@ -76,6 +76,12 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
+@@ -81,6 +81,12 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
      public long ticksPerMonsterSpawns;
      public long ticksPerWaterSpawns;
      public long ticksPerAmbientSpawns;
@@ -348,7 +347,7 @@ index 2beb1374b105381d4467de4989c207339cb5dca1..0fa2b335db297c6270090d3dd24ced92
      public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot
  
 diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java
-index 92601c581cffac471872226abeb93ef9aa24f079..d873b8cf3aec01b791565c33b252889f99f181f9 100644
+index b73af0a5fb2d08c2f3a52c699ef0d8ed34c83f77..97af8f8e3c48694c390036bb1455e6d22fcd1c49 100644
 --- a/src/main/java/org/spigotmc/ActivationRange.java
 +++ b/src/main/java/org/spigotmc/ActivationRange.java
 @@ -2,24 +2,34 @@ package org.spigotmc;
@@ -593,8 +592,8 @@ index 92601c581cffac471872226abeb93ef9aa24f079..d873b8cf3aec01b791565c33b252889f
          }
          if ( !( entity instanceof EntityArrow ) )
          {
--            if ( !entity.onGround || !entity.passengers.isEmpty() || entity.isPassenger() )
-+            if ( (!entity.onGround && !(entity instanceof EntityFlying)) || !entity.passengers.isEmpty() || entity.isPassenger() ) // Paper
+-            if ( !entity.isOnGround() || !entity.passengers.isEmpty() || entity.isPassenger() )
++            if ( (!entity.isOnGround() && !(entity instanceof EntityFlying)) || !entity.passengers.isEmpty() || entity.isPassenger() )
              {
 -                return true;
 +                return 10; // Paper
@@ -735,7 +734,7 @@ index 92601c581cffac471872226abeb93ef9aa24f079..d873b8cf3aec01b791565c33b252889f
              isActive = false;
          }
 diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
-index 37ef07338e0e7ebb778b4446c8e7a630f597c7be..69454bc3c51c0d7c6f1b6d1fbcba93322205bab6 100644
+index f0ad5fa235adfd165b8e56be7352568a3b3ae54a..9859e0c964e4d1e7dc7689cb97f40643a8e5cdd7 100644
 --- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
 +++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
 @@ -180,13 +180,59 @@ public class SpigotWorldConfig
diff --git a/Spigot-Server-Patches/0425-Add-effect-to-block-break-naturally.patch b/Spigot-Server-Patches/0409-Add-effect-to-block-break-naturally.patch
similarity index 78%
rename from Spigot-Server-Patches/0425-Add-effect-to-block-break-naturally.patch
rename to Spigot-Server-Patches/0409-Add-effect-to-block-break-naturally.patch
index f43e886f86..22dffbdf60 100644
--- a/Spigot-Server-Patches/0425-Add-effect-to-block-break-naturally.patch
+++ b/Spigot-Server-Patches/0409-Add-effect-to-block-break-naturally.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Add effect to block break naturally
 
 
 diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
-index 16349e8e796c5e7e4e43fb355d4d641df7f41dc9..382b50d37aced746266b618f3f277846728565bd 100644
+index 2e24b75d2b56dc40d05200ddded817d6ae06803c..c50277fb107c562c00f9d803967b4121e427f40e 100644
 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
 +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
-@@ -606,6 +606,13 @@ public class CraftBlock implements Block {
+@@ -619,6 +619,13 @@ public class CraftBlock implements Block {
  
      @Override
      public boolean breakNaturally(ItemStack item) {
@@ -22,9 +22,9 @@ index 16349e8e796c5e7e4e43fb355d4d641df7f41dc9..382b50d37aced746266b618f3f277846
          // Order matters here, need to drop before setting to air so skulls can get their data
          net.minecraft.server.IBlockData iblockdata = this.getNMS();
          net.minecraft.server.Block block = iblockdata.getBlock();
-@@ -615,6 +622,7 @@ public class CraftBlock implements Block {
+@@ -628,6 +635,7 @@ public class CraftBlock implements Block {
          // Modelled off EntityHuman#hasBlock
-         if (block != Blocks.AIR && (item == null || iblockdata.getMaterial().isAlwaysDestroyable() || nmsItem.canDestroySpecialBlock(iblockdata))) {
+         if (block != Blocks.AIR && (item == null || !iblockdata.isAlwaysDestroyable() || nmsItem.canDestroySpecialBlock(iblockdata))) {
              net.minecraft.server.Block.dropItems(iblockdata, world.getMinecraftWorld(), position, world.getTileEntity(position), null, nmsItem);
 +            if (triggerEffect) world.triggerEffect(org.bukkit.Effect.STEP_SOUND.getId(), position, net.minecraft.server.Block.getCombinedId(block.getBlockData())); // Paper
              result = true;
diff --git a/Spigot-Server-Patches/0426-Tracking-Range-Improvements.patch b/Spigot-Server-Patches/0410-Tracking-Range-Improvements.patch
similarity index 95%
rename from Spigot-Server-Patches/0426-Tracking-Range-Improvements.patch
rename to Spigot-Server-Patches/0410-Tracking-Range-Improvements.patch
index 01f06e48be..f5237e2f23 100644
--- a/Spigot-Server-Patches/0426-Tracking-Range-Improvements.patch
+++ b/Spigot-Server-Patches/0410-Tracking-Range-Improvements.patch
@@ -8,10 +8,10 @@ Sets tracking range of watermobs to animals instead of misc and simplifies code
 Also ignores Enderdragon, defaulting it to Mojang's setting
 
 diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
-index c20acd86beb8f28345d1359d0a2b68b7d8e0e410..4ba661c5a89bebe29c8802387bc93c10094b7606 100644
+index f7e57fd1ce5881c056c104d5a6a9a74e34e3ffc3..fe3aab87de4e1eb60b19352499790fd9b571e169 100644
 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
 +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
-@@ -1702,6 +1702,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -1735,6 +1735,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
              while (iterator.hasNext()) {
                  Entity entity = (Entity) iterator.next();
                  int j = entity.getEntityType().getChunkRange() * 16;
diff --git a/Spigot-Server-Patches/0428-Fix-items-vanishing-through-end-portal.patch b/Spigot-Server-Patches/0411-Fix-items-vanishing-through-end-portal.patch
similarity index 63%
rename from Spigot-Server-Patches/0428-Fix-items-vanishing-through-end-portal.patch
rename to Spigot-Server-Patches/0411-Fix-items-vanishing-through-end-portal.patch
index 467cd1e040..01ffc4d1e4 100644
--- a/Spigot-Server-Patches/0428-Fix-items-vanishing-through-end-portal.patch
+++ b/Spigot-Server-Patches/0411-Fix-items-vanishing-through-end-portal.patch
@@ -13,18 +13,16 @@ Quickly loading the exact world spawn chunk before searching the
 heightmap resolves the issue without having to load all spawn chunks.
 
 diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
-index a1245c1f551cbce84b0f3dd3a7349e8585631a82..83e0af493c0f4037ff3e625ee93b9422863f335f 100644
+index bc162a4f18d1123a2e844f4429ea2c26b632dfe5..6cfbece5cbb6effb843f54e9917a755e2a9df4c5 100644
 --- a/src/main/java/net/minecraft/server/Entity.java
 +++ b/src/main/java/net/minecraft/server/Entity.java
-@@ -2613,6 +2613,11 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
+@@ -2532,6 +2532,9 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
  
          if (blockposition == null) { // CraftBukkit
-             if (dimensionmanager1.getType() == DimensionManager.THE_END && dimensionmanager == DimensionManager.OVERWORLD) { // CraftBukkit
+             if (this.world.getDimensionKey() == World.THE_END && worldserver.getDimensionKey() == World.OVERWORLD) {
 +                // Paper start - Ensure spawn chunk is always loaded before calculating Y coordinate
-+                if (!worldserver1.isLoaded(worldserver1.getSpawn())) {
-+                    worldserver1.getChunkAtWorldCoords(worldserver1.getSpawn());
-+                }
++                this.world.getChunkAtWorldCoords(this.world.getSpawn());
 +                // Paper end
                  // CraftBukkit start
-                 EntityPortalEvent event = CraftEventFactory.callEntityPortalEvent(this, worldserver1, worldserver1.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, worldserver1.getSpawn()), 0);
+                 EntityPortalEvent event = CraftEventFactory.callEntityPortalEvent(this, worldserver, worldserver.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, worldserver.getSpawn()), 0);
                  if (event == null) {
diff --git a/Spigot-Server-Patches/0411-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch b/Spigot-Server-Patches/0411-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch
deleted file mode 100644
index 7535c03fa5..0000000000
--- a/Spigot-Server-Patches/0411-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Callahan <mr.callahhh@gmail.com>
-Date: Mon, 13 Jan 2020 23:47:28 -0600
-Subject: [PATCH] Prevent sync chunk loads when villagers try to find beds
-
-
-diff --git a/src/main/java/net/minecraft/server/BehaviorSleep.java b/src/main/java/net/minecraft/server/BehaviorSleep.java
-index fa575dde1924d840b966791aab8553108a877be4..dfe0f66500ab2ea733fd5ef84d7d80f32e2dfaab 100644
---- a/src/main/java/net/minecraft/server/BehaviorSleep.java
-+++ b/src/main/java/net/minecraft/server/BehaviorSleep.java
-@@ -31,7 +31,8 @@ public class BehaviorSleep extends Behavior<EntityLiving> {
-                 if (optional.isPresent() && worldserver.getTime() - ((MinecraftSerializableLong) optional.get()).a() < 100L) {
-                     return false;
-                 } else {
--                    IBlockData iblockdata = worldserver.getType(globalpos.getBlockPosition());
-+                    IBlockData iblockdata = worldserver.getTypeIfLoaded(globalpos.getBlockPosition()); // Paper
-+                    if(iblockdata == null) return false; // Paper
- 
-                     return globalpos.getBlockPosition().a((IPosition) entityliving.getPositionVector(), 2.0D) && iblockdata.getBlock().a(TagsBlock.BEDS) && !(Boolean) iblockdata.get(BlockBed.OCCUPIED);
-                 }
diff --git a/Spigot-Server-Patches/0430-Bees-get-gravity-in-void.-Fixes-MC-167279.patch b/Spigot-Server-Patches/0412-Bees-get-gravity-in-void.-Fixes-MC-167279.patch
similarity index 84%
rename from Spigot-Server-Patches/0430-Bees-get-gravity-in-void.-Fixes-MC-167279.patch
rename to Spigot-Server-Patches/0412-Bees-get-gravity-in-void.-Fixes-MC-167279.patch
index f20d611888..80436106a1 100644
--- a/Spigot-Server-Patches/0430-Bees-get-gravity-in-void.-Fixes-MC-167279.patch
+++ b/Spigot-Server-Patches/0412-Bees-get-gravity-in-void.-Fixes-MC-167279.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Bees get gravity in void. Fixes MC-167279
 
 
 diff --git a/src/main/java/net/minecraft/server/ControllerMove.java b/src/main/java/net/minecraft/server/ControllerMove.java
-index 7e3671dae6194a9caad68054fb61c9e441b2d538..a5c4cbb67f030760e64e75e618285bd98083c5b5 100644
+index f2d2d04fe16bc091a971c8c90db56e6cd2799555..ac6f9d9e5252b819f91703ad6aeaae3d580eeca0 100644
 --- a/src/main/java/net/minecraft/server/ControllerMove.java
 +++ b/src/main/java/net/minecraft/server/ControllerMove.java
 @@ -2,7 +2,7 @@ package net.minecraft.server;
@@ -18,7 +18,7 @@ index 7e3671dae6194a9caad68054fb61c9e441b2d538..a5c4cbb67f030760e64e75e618285bd9
      protected double c;
      protected double d;
 diff --git a/src/main/java/net/minecraft/server/ControllerMoveFlying.java b/src/main/java/net/minecraft/server/ControllerMoveFlying.java
-index 2b6ac2eeb0fdf35e75c35144941d7fb82cb8adc1..0496c0c5dbbcf89461c947881129673fa4f33e42 100644
+index d3507b3852f02bf35bda35a13db66d5375325000..bafcb780f520db562e4a834400b789f60b563597 100644
 --- a/src/main/java/net/minecraft/server/ControllerMoveFlying.java
 +++ b/src/main/java/net/minecraft/server/ControllerMoveFlying.java
 @@ -12,7 +12,7 @@ public class ControllerMoveFlying extends ControllerMove {
@@ -31,10 +31,10 @@ index 2b6ac2eeb0fdf35e75c35144941d7fb82cb8adc1..0496c0c5dbbcf89461c947881129673f
              this.h = ControllerMove.Operation.WAIT;
              this.a.setNoGravity(true);
 diff --git a/src/main/java/net/minecraft/server/EntityBee.java b/src/main/java/net/minecraft/server/EntityBee.java
-index 73e016257847e5654e37ec6dbf8c689c36593216..c7d79efdf6ee3b1ac910ff48bfd4b0ef084b4d43 100644
+index dcfd2ea5024be6d4a001fa7437092a7831b36fa7..b9e01e4d9e64fdec4c4f04f1808eb8832bd00c8e 100644
 --- a/src/main/java/net/minecraft/server/EntityBee.java
 +++ b/src/main/java/net/minecraft/server/EntityBee.java
-@@ -36,7 +36,17 @@ public class EntityBee extends EntityAnimal implements EntityBird {
+@@ -37,7 +37,17 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
  
      public EntityBee(EntityTypes<? extends EntityBee> entitytypes, World world) {
          super(entitytypes, world);
@@ -51,5 +51,5 @@ index 73e016257847e5654e37ec6dbf8c689c36593216..c7d79efdf6ee3b1ac910ff48bfd4b0ef
 +        };
 +        // Paper end
          this.lookController = new EntityBee.j(this);
+         this.a(PathType.DANGER_FIRE, -1.0F);
          this.a(PathType.WATER, -1.0F);
-         this.a(PathType.COCOA, -1.0F);
diff --git a/Spigot-Server-Patches/0431-Optimise-getChunkAt-calls-for-loaded-chunks.patch b/Spigot-Server-Patches/0413-Optimise-getChunkAt-calls-for-loaded-chunks.patch
similarity index 89%
rename from Spigot-Server-Patches/0431-Optimise-getChunkAt-calls-for-loaded-chunks.patch
rename to Spigot-Server-Patches/0413-Optimise-getChunkAt-calls-for-loaded-chunks.patch
index 9ac993e609..0ca1c3c83b 100644
--- a/Spigot-Server-Patches/0431-Optimise-getChunkAt-calls-for-loaded-chunks.patch
+++ b/Spigot-Server-Patches/0413-Optimise-getChunkAt-calls-for-loaded-chunks.patch
@@ -7,10 +7,10 @@ bypass the need to get a player chunk, then get the either,
 then unwrap it...
 
 diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
-index 633f12098973857eca04acd2839bb4d453860f1e..e467cd8123dafc46a8c894f1ffa9440de0d45340 100644
+index 1597b7a882769109f467d81ecbadc45ff6779b7e..67d6facd37462beef49dac311019b1977150d73f 100644
 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
 +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
-@@ -446,6 +446,12 @@ public class ChunkProviderServer extends IChunkProvider {
+@@ -447,6 +447,12 @@ public class ChunkProviderServer extends IChunkProvider {
                  return this.getChunkAt(i, j, chunkstatus, flag);
              }, this.serverThreadQueue).join();
          } else {
@@ -23,7 +23,7 @@ index 633f12098973857eca04acd2839bb4d453860f1e..e467cd8123dafc46a8c894f1ffa9440d
              GameProfilerFiller gameprofilerfiller = this.world.getMethodProfiler();
  
              gameprofilerfiller.c("getChunk");
-@@ -496,39 +502,7 @@ public class ChunkProviderServer extends IChunkProvider {
+@@ -497,39 +503,7 @@ public class ChunkProviderServer extends IChunkProvider {
          if (Thread.currentThread() != this.serverThread) {
              return null;
          } else {
@@ -65,10 +65,10 @@ index 633f12098973857eca04acd2839bb4d453860f1e..e467cd8123dafc46a8c894f1ffa9440d
      }
  
 diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
-index d7ac4c86d170a8d7d816f86ac691c3b5129a20ba..adacff593ee20804b5ddb2df55b66bc6c162dc70 100644
+index 7d13f7a8b7272ad2ac86e706c1b8c7649cccb01c..50848896588e16bf2a498ba28ab30919a081afd5 100644
 --- a/src/main/java/net/minecraft/server/World.java
 +++ b/src/main/java/net/minecraft/server/World.java
-@@ -266,6 +266,14 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
+@@ -319,6 +319,14 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
  
      @Override
      public Chunk getChunkAt(int i, int j) {
diff --git a/Spigot-Server-Patches/0433-Allow-overriding-the-java-version-check.patch b/Spigot-Server-Patches/0414-Allow-overriding-the-java-version-check.patch
similarity index 90%
rename from Spigot-Server-Patches/0433-Allow-overriding-the-java-version-check.patch
rename to Spigot-Server-Patches/0414-Allow-overriding-the-java-version-check.patch
index f1bc40efc3..d326950c38 100644
--- a/Spigot-Server-Patches/0433-Allow-overriding-the-java-version-check.patch
+++ b/Spigot-Server-Patches/0414-Allow-overriding-the-java-version-check.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] Allow overriding the java version check
 -DPaper.IgnoreJavaVersion=true
 
 diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
-index 9b4f01120d473a4fea993a5df952e265b33cde0b..d3463abe89f6e730373cef5e3ac8c0911d0b0963 100644
+index 05b647fbb360910b2961c9276c2928fe71dad90c..5ec16547a20271074d034f7fbcb43e86cb1597e6 100644
 --- a/src/main/java/org/bukkit/craftbukkit/Main.java
 +++ b/src/main/java/org/bukkit/craftbukkit/Main.java
 @@ -175,7 +175,7 @@ public class Main {
diff --git a/Spigot-Server-Patches/0434-Add-ThrownEggHatchEvent.patch b/Spigot-Server-Patches/0415-Add-ThrownEggHatchEvent.patch
similarity index 89%
rename from Spigot-Server-Patches/0434-Add-ThrownEggHatchEvent.patch
rename to Spigot-Server-Patches/0415-Add-ThrownEggHatchEvent.patch
index 42e3a2e270..5edd2e992d 100644
--- a/Spigot-Server-Patches/0434-Add-ThrownEggHatchEvent.patch
+++ b/Spigot-Server-Patches/0415-Add-ThrownEggHatchEvent.patch
@@ -7,10 +7,10 @@ Adds a new event similar to PlayerEggThrowEvent, but without the Player requirem
 (dispensers can throw eggs to hatch them, too).
 
 diff --git a/src/main/java/net/minecraft/server/EntityEgg.java b/src/main/java/net/minecraft/server/EntityEgg.java
-index 970f9109d9bdea5556dc2ac7752860378623ecfa..bdd82d052a2b04744435e5695b4578c7872d8d52 100644
+index 0d5e91a4204c394efcc510d34011f32f2e313ab1..edce89169b3ca2894852087b83a6bf035ba43c3f 100644
 --- a/src/main/java/net/minecraft/server/EntityEgg.java
 +++ b/src/main/java/net/minecraft/server/EntityEgg.java
-@@ -52,6 +52,16 @@ public class EntityEgg extends EntityProjectileThrowable {
+@@ -55,6 +55,16 @@ public class EntityEgg extends EntityProjectileThrowable {
                      hatchingType = event.getHatchingType();
                  }
  
diff --git a/Spigot-Server-Patches/0435-Optimise-random-block-ticking.patch b/Spigot-Server-Patches/0416-Optimise-random-block-ticking.patch
similarity index 67%
rename from Spigot-Server-Patches/0435-Optimise-random-block-ticking.patch
rename to Spigot-Server-Patches/0416-Optimise-random-block-ticking.patch
index 4b05375b2e..be5febc5c1 100644
--- a/Spigot-Server-Patches/0435-Optimise-random-block-ticking.patch
+++ b/Spigot-Server-Patches/0416-Optimise-random-block-ticking.patch
@@ -70,39 +70,11 @@ index 0000000000000000000000000000000000000000..3edc8e52e06a62ce9f8cc734fd7458b3
 +        return fastRandomBounded(this.next(32) & 0xFFFFFFFFL, bound);
 +    }
 +}
-diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java
-index e29ec958b3519d92cda215a50e97e6852d71c684..e40375b67a4a321048c87002a07fde5c5d2395db 100644
---- a/src/main/java/net/minecraft/server/Block.java
-+++ b/src/main/java/net/minecraft/server/Block.java
-@@ -109,8 +109,8 @@ public class Block implements IMaterial {
-         return iblockdata.d(iblockaccess, blockposition, EnumDirection.UP) && this.n < 14;
-     }
- 
--    @Deprecated
--    public boolean d(IBlockData iblockdata) {
-+    public final boolean isAir(IBlockData iblockdata) { return this.d(iblockdata); } // Paper - OBFHELPER
-+    @Deprecated public boolean d(IBlockData iblockdata) { // Paper - OBFHELPER
-         return false;
-     }
- 
-diff --git a/src/main/java/net/minecraft/server/BlockFluids.java b/src/main/java/net/minecraft/server/BlockFluids.java
-index 6d351f0979ecfa8e500edf8dd03b4a455fd5d180..a44f65f40d2080b63069602a454266ee6fe6cff7 100644
---- a/src/main/java/net/minecraft/server/BlockFluids.java
-+++ b/src/main/java/net/minecraft/server/BlockFluids.java
-@@ -27,7 +27,7 @@ public class BlockFluids extends Block implements IFluidSource {
- 
-     @Override
-     public void b(IBlockData iblockdata, WorldServer worldserver, BlockPosition blockposition, Random random) {
--        worldserver.getFluid(blockposition).b(worldserver, blockposition, random);
-+        iblockdata.getFluid().b(worldserver, blockposition, random); // Paper - avoid getType call
-     }
- 
-     @Override
 diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java
-index a3a376e35eaf17b128048bd26a22eef713e7d535..3fcfe416d26808fa1c9bfdc5b413b149764c544a 100644
+index 37570a3bbb9a36133d012350eca1685cca68c73b..9fb776318c10f393eb6d94e5112c454a7cd246b9 100644
 --- a/src/main/java/net/minecraft/server/BlockPosition.java
 +++ b/src/main/java/net/minecraft/server/BlockPosition.java
-@@ -452,6 +452,7 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali
+@@ -402,6 +402,7 @@ public class BlockPosition extends BaseBlockPosition {
              return this.d(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2));
          }
  
@@ -111,25 +83,25 @@ index a3a376e35eaf17b128048bd26a22eef713e7d535..3fcfe416d26808fa1c9bfdc5b413b149
              return this.d(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ());
          }
 diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
-index af9a195f6d0f966133577d00d30e8b4ad812aaeb..cfdf6ea55dedeaf6b96566b72ca0015350c13e92 100644
+index b2713942d8cf5bedd91ac63df18a336743c72da5..a76b1d2fd81aaedb37190bcb8510020d5df2513e 100644
 --- a/src/main/java/net/minecraft/server/Chunk.java
 +++ b/src/main/java/net/minecraft/server/Chunk.java
-@@ -592,8 +592,8 @@ public class Chunk implements IChunkAccess {
+@@ -593,8 +593,8 @@ public class Chunk implements IChunkAccess {
          this.entities.remove(entity); // Paper
      }
  
 -    @Override
--    public int a(HeightMap.Type heightmap_type, int i, int j) {
-+    public int getHighestBlockY(HeightMap.Type heightmap_type, int i, int j) { return this.a(heightmap_type, i, j) + 1; } // Paper - sort of an obfhelper, but without -1
-+    @Override public int a(HeightMap.Type heightmap_type, int i, int j) { // Paper
+-    public int getHighestBlock(HeightMap.Type heightmap_type, int i, int j) {
++    public final int getHighestBlockY(HeightMap.Type heightmap_type, int i, int j) { return this.getHighestBlock(heightmap_type, i, j) + 1; } // Paper - sort of an obfhelper, but without -1
++    @Override public int getHighestBlock(HeightMap.Type heightmap_type, int i, int j) { // Paper
          return ((HeightMap) this.heightMap.get(heightmap_type)).a(i & 15, j & 15) - 1;
      }
  
 diff --git a/src/main/java/net/minecraft/server/ChunkSection.java b/src/main/java/net/minecraft/server/ChunkSection.java
-index c180d44bed91c86838d3be8c19be954b4412534e..4eb7c1a9b5afced4be79a263e6a918f39c4b51be 100644
+index b168ad8021a5387e05023cd03ec1a69c8a86a233..cf444fa1cc96e881a1f9ed0c78d45935fe1c90ab 100644
 --- a/src/main/java/net/minecraft/server/ChunkSection.java
 +++ b/src/main/java/net/minecraft/server/ChunkSection.java
-@@ -6,12 +6,14 @@ import javax.annotation.Nullable;
+@@ -7,12 +7,14 @@ import javax.annotation.Nullable;
  public class ChunkSection {
  
      public static final DataPalette<IBlockData> GLOBAL_PALETTE = new DataPaletteGlobal<>(Block.REGISTRY_ID, Blocks.AIR.getBlockData());
@@ -146,9 +118,9 @@ index c180d44bed91c86838d3be8c19be954b4412534e..4eb7c1a9b5afced4be79a263e6a918f3
      // Paper start - Anti-Xray - Add parameters
      @Deprecated public ChunkSection(int i) { this(i, null, null, true); } // Notice for updates: Please make sure this constructor isn't used anywhere
      public ChunkSection(int i, IChunkAccess chunk, World world, boolean initializeBlocks) {
-@@ -66,6 +68,9 @@ public class ChunkSection {
+@@ -67,6 +69,9 @@ public class ChunkSection {
              --this.nonEmptyBlockCount;
-             if (iblockdata1.q()) {
+             if (iblockdata1.isTicking()) {
                  --this.tickingBlockCount;
 +                // Paper start
 +                this.tickingList.remove(i, j, k);
@@ -156,9 +128,9 @@ index c180d44bed91c86838d3be8c19be954b4412534e..4eb7c1a9b5afced4be79a263e6a918f3
              }
          }
  
-@@ -77,6 +82,9 @@ public class ChunkSection {
+@@ -78,6 +83,9 @@ public class ChunkSection {
              ++this.nonEmptyBlockCount;
-             if (iblockdata.q()) {
+             if (iblockdata.isTicking()) {
                  ++this.tickingBlockCount;
 +                // Paper start
 +                this.tickingList.add(i, j, k, iblockdata);
@@ -166,7 +138,7 @@ index c180d44bed91c86838d3be8c19be954b4412534e..4eb7c1a9b5afced4be79a263e6a918f3
              }
          }
  
-@@ -112,23 +120,29 @@ public class ChunkSection {
+@@ -113,23 +121,29 @@ public class ChunkSection {
      }
  
      public void recalcBlockCounts() {
@@ -182,10 +154,10 @@ index c180d44bed91c86838d3be8c19be954b4412534e..4eb7c1a9b5afced4be79a263e6a918f3
  
              if (!iblockdata.isAir()) {
 -                this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + i);
-+                this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1); // Paper
-                 if (iblockdata.q()) {
++                this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1);
+                 if (iblockdata.isTicking()) {
 -                    this.tickingBlockCount = (short) (this.tickingBlockCount + i);
-+                    this.tickingBlockCount = (short) (this.tickingBlockCount + 1); // Paper
++                    this.tickingBlockCount = (short) (this.tickingBlockCount + 1);
 +                    // Paper start
 +                    this.tickingList.add(location, iblockdata);
 +                    // Paper end
@@ -194,53 +166,39 @@ index c180d44bed91c86838d3be8c19be954b4412534e..4eb7c1a9b5afced4be79a263e6a918f3
  
              if (!fluid.isEmpty()) {
 -                this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + i);
-+                this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1); // Paper
-                 if (fluid.h()) {
++                this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1);
+                 if (fluid.f()) {
 -                    this.e = (short) (this.e + i);
-+                    this.e = (short) (this.e + 1); // Paper
++                    this.e = (short) (this.e + 1);
                  }
              }
  
 diff --git a/src/main/java/net/minecraft/server/DataBits.java b/src/main/java/net/minecraft/server/DataBits.java
-index f9680b6830c77f31e1eb8b6845dd6d58d04f624a..a61cffa3f494be5fea785a573b0faf05b149a30d 100644
+index 48cca2b9a1dbb071615625842123c0c47e281b29..235c9ec37c00ce8838b3e7c02284e402f9d30e38 100644
 --- a/src/main/java/net/minecraft/server/DataBits.java
 +++ b/src/main/java/net/minecraft/server/DataBits.java
-@@ -127,4 +127,46 @@ public class DataBits {
- 
+@@ -111,4 +111,32 @@ public class DataBits {
          }
+ 
      }
 +
 +    // Paper start
 +    public final void forEach(DataBitConsumer consumer) {
-+        // Note: copied from above
-+        int i = this.a.length;
++        int i = 0;
++        long[] along = this.b;
++        int j = along.length;
 +
-+        if (i != 0) {
-+            int j = 0;
-+            long k = this.a[0];
-+            long l = i > 1 ? this.a[1] : 0L;
++        for (int k = 0; k < j; ++k) {
++            long l = along[k];
 +
-+            for (int i1 = 0; i1 < this.d; ++i1) {
-+                int j1 = i1 * this.b;
-+                int k1 = j1 >> 6;
-+                int l1 = (i1 + 1) * this.b - 1 >> 6;
-+                int i2 = j1 ^ k1 << 6;
-+
-+                if (k1 != j) {
-+                    k = l;
-+                    l = k1 + 1 < i ? this.a[k1 + 1] : 0L;
-+                    j = k1;
-+                }
-+
-+                if (k1 == l1) {
-+                    consumer.accept(i1, (int) (k >>> i2 & this.c));
-+                } else {
-+                    int j2 = 64 - i2;
-+
-+                    consumer.accept(i1, (int) ((k >>> i2 | l << j2) & this.c));
++            for (int i1 = 0; i1 < this.f; ++i1) {
++                consumer.accept(i, (int) (l & this.d));
++                l >>= this.c;
++                ++i;
++                if (i >= this.e) {
++                    return;
 +                }
 +            }
-+
 +        }
 +    }
 +
@@ -253,10 +211,10 @@ index f9680b6830c77f31e1eb8b6845dd6d58d04f624a..a61cffa3f494be5fea785a573b0faf05
 +    // Paper end
  }
 diff --git a/src/main/java/net/minecraft/server/DataPaletteBlock.java b/src/main/java/net/minecraft/server/DataPaletteBlock.java
-index a5ea0e34ec181ad9f98f9ee2f644c3ec1eb1cd3c..81362de5430f9cd045ee7cbefa4a28e4c6bc0457 100644
+index 900b551f6f76862443b09c1e76ad596eda5655f4..1cb45f97b644347d16b66b46113b1e4455004fd3 100644
 --- a/src/main/java/net/minecraft/server/DataPaletteBlock.java
 +++ b/src/main/java/net/minecraft/server/DataPaletteBlock.java
-@@ -278,6 +278,14 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
+@@ -277,6 +277,14 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
          });
      }
  
@@ -272,77 +230,24 @@ index a5ea0e34ec181ad9f98f9ee2f644c3ec1eb1cd3c..81362de5430f9cd045ee7cbefa4a28e4
      public interface a<T> {
  
 diff --git a/src/main/java/net/minecraft/server/EntityTurtle.java b/src/main/java/net/minecraft/server/EntityTurtle.java
-index dd02cb3485021c3afd23c2985a71e93c6b0ab07d..b24a5100b452f69f771b724ca96d34613c7fa170 100644
+index 5862e2026b685df80de45c529f1367382a2a60b0..a5cd127c0f133b0ef136f4efad9d71eab2edf8e4 100644
 --- a/src/main/java/net/minecraft/server/EntityTurtle.java
 +++ b/src/main/java/net/minecraft/server/EntityTurtle.java
 @@ -29,7 +29,7 @@ public class EntityTurtle extends EntityAnimal {
  
-     public final void setHome(BlockPosition pos) { g(pos); } // Paper - OBFHELPER
-     public void g(BlockPosition blockposition) {
--        this.datawatcher.set(EntityTurtle.bx, blockposition);
-+        this.datawatcher.set(EntityTurtle.bx, blockposition.immutableCopy()); // Paper - make sure home position can't change
+     public final void setHome(BlockPosition pos) { setHomePos(pos); } // Paper - OBFHELPER
+     public void setHomePos(BlockPosition blockposition) {
+-        this.datawatcher.set(EntityTurtle.bw, blockposition);
++        this.datawatcher.set(EntityTurtle.bw, blockposition.immutableCopy()); // Paper - called with mutablepos...
      }
- 
-     public final BlockPosition getHome() { return this.es(); } // Paper - OBFHELPER
-diff --git a/src/main/java/net/minecraft/server/IBlockData.java b/src/main/java/net/minecraft/server/IBlockData.java
-index 321eae23c575528788b1b575f17593580d6ba737..b19bbbbc81376177751396a2de9452ce1f84c06b 100644
---- a/src/main/java/net/minecraft/server/IBlockData.java
-+++ b/src/main/java/net/minecraft/server/IBlockData.java
-@@ -22,11 +22,15 @@ public class IBlockData extends BlockDataAbstract<Block, IBlockData> implements
-     private IBlockData.a c;
-     private final int d;
-     private final boolean e;
-+    private final boolean isAir; // Paper
-+    private final boolean isTicking; // Paper
- 
-     public IBlockData(Block block, ImmutableMap<IBlockState<?>, Comparable<?>> immutablemap) {
-         super(block, immutablemap);
-         this.d = block.a(this);
-         this.e = block.o(this);
-+        this.isAir = this.getBlock().isAir(this); // Paper
-+        this.isTicking = this.getBlock().isTicking(this); // Paper
-     }
- 
-     public void c() {
-@@ -82,8 +86,8 @@ public class IBlockData extends BlockDataAbstract<Block, IBlockData> implements
-         return this.d;
-     }
- 
--    public boolean isAir() {
--        return this.getBlock().d(this);
-+    public final boolean isAir() { // Paper - compile fail if the impl changes
-+        return this.isAir; // Paper - improve inlining of isAir
-     }
- 
-     public MaterialMapColor c(IBlockAccess iblockaccess, BlockPosition blockposition) {
-@@ -268,12 +272,19 @@ public class IBlockData extends BlockDataAbstract<Block, IBlockData> implements
-         return this.getBlock().a(tag);
-     }
- 
-+    private Fluid fluidData; // Paper - cache result
-     public Fluid getFluid() {
--        return this.getBlock().a_(this);
-+        // Paper start
-+        // This can't be done during the constructor, order issues
-+        if (this.fluidData != null) {
-+            return this.fluidData;
-+        }
-+        return this.fluidData = this.getBlock().a_(this);
-+        // Paper end
-     }
- 
-     public boolean q() {
--        return this.getBlock().isTicking(this);
-+        return this.isTicking; // Paper
-     }
- 
-     public final SoundEffectType getStepSound() { return this.r(); } // Paper - OBFHELPER
+     // TODO Paper: Obf helpers here can prolly be removed? check that no newer patches use them
+     public final BlockPosition getHome() { return this.getHomePos(); } // Paper - OBFHELPER
 diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
-index adacff593ee20804b5ddb2df55b66bc6c162dc70..a52d8a27cee6721c32444d9d2bd81135b7d4b859 100644
+index 50848896588e16bf2a498ba28ab30919a081afd5..d2b3e06dda10fc321768301c35f319767796d7d5 100644
 --- a/src/main/java/net/minecraft/server/World.java
 +++ b/src/main/java/net/minecraft/server/World.java
-@@ -1564,10 +1564,19 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
-     public abstract TagRegistry t();
+@@ -1460,10 +1460,18 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
+     public abstract TagRegistry p();
  
      public BlockPosition a(int i, int j, int k, int l) {
 +        // Paper start - allow use of mutable pos
@@ -350,11 +255,10 @@ index adacff593ee20804b5ddb2df55b66bc6c162dc70..a52d8a27cee6721c32444d9d2bd81135
 +        this.getRandomBlockPosition(i, j, k, l, ret);
 +        return ret.immutableCopy();
 +    }
-+
 +    public final BlockPosition.MutableBlockPosition getRandomBlockPosition(int i, int j, int k, int l, BlockPosition.MutableBlockPosition out) {
 +        // Paper end
-         this.i = this.i * 3 + 1013904223;
-         int i1 = this.i >> 2;
+         this.n = this.n * 3 + 1013904223;
+         int i1 = this.n >> 2;
  
 -        return new BlockPosition(i + (i1 & 15), j + (i1 >> 16 & l), k + (i1 >> 8 & 15));
 +        out.setValues(i + (i1 & 15), j + (i1 >> 16 & l), k + (i1 >> 8 & 15)); // Paper - change to setValues call
@@ -363,10 +267,10 @@ index adacff593ee20804b5ddb2df55b66bc6c162dc70..a52d8a27cee6721c32444d9d2bd81135
  
      public boolean isSavingDisabled() {
 diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
-index f32e313a6287c8f5d487d4ad7148cac176773228..7fded15f14a3f5c04a676e9e25413718b9922c13 100644
+index 1d4e34b2ece861e7e4f2fe0f15f6fbf8ab47f86c..3266ecf2ad975613942a9cd127440dd898b12ff5 100644
 --- a/src/main/java/net/minecraft/server/WorldServer.java
 +++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -531,7 +531,12 @@ public class WorldServer extends World {
+@@ -558,7 +558,12 @@ public class WorldServer extends World implements GeneratorAccessSeed {
          });
      }
  
@@ -380,21 +284,20 @@ index f32e313a6287c8f5d487d4ad7148cac176773228..7fded15f14a3f5c04a676e9e25413718
          ChunkCoordIntPair chunkcoordintpair = chunk.getPos();
          boolean flag = this.isRaining();
          int j = chunkcoordintpair.d();
-@@ -539,10 +544,10 @@ public class WorldServer extends World {
+@@ -566,10 +571,10 @@ public class WorldServer extends World implements GeneratorAccessSeed {
          GameProfilerFiller gameprofilerfiller = this.getMethodProfiler();
  
          gameprofilerfiller.enter("thunder");
 -        BlockPosition blockposition;
 +        final BlockPosition.MutableBlockPosition blockposition = this.chunkTickMutablePosition; // Paper - use mutable to reduce allocation rate, final to force compile fail on change
  
--        if (!this.paperConfig.disableThunder && flag && this.U() && this.random.nextInt(100000) == 0) { // Paper - Disable thunder
+         if (!this.paperConfig.disableThunder && flag && this.T() && this.random.nextInt(100000) == 0) { // Paper - Disable thunder
 -            blockposition = this.a(this.a(j, 0, k, 15));
-+        if (!this.paperConfig.disableThunder && flag && this.U() && this.randomTickRandom.nextInt(100000) == 0) { // Paper - Disable thunder // Paper - optimise random ticking
-+            blockposition.setValues(this.a(this.getRandomBlockPosition(j, 0, k, 15, blockposition))); // Paper
++            blockposition.setValues(this.a(this.a(j, 0, k, 15))); // Paper
              if (this.isRainingAt(blockposition)) {
                  DifficultyDamageScaler difficultydamagescaler = this.getDamageScaler(blockposition);
                  boolean flag1 = this.getGameRules().getBoolean(GameRules.DO_MOB_SPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.b() * paperConfig.skeleHorseSpawnChance; // Paper
-@@ -561,61 +566,79 @@ public class WorldServer extends World {
+@@ -592,59 +597,77 @@ public class WorldServer extends World implements GeneratorAccessSeed {
          }
  
          gameprofilerfiller.exitEnter("iceandsnow");
@@ -469,10 +372,8 @@ index f32e313a6287c8f5d487d4ad7148cac176773228..7fded15f14a3f5c04a676e9e25413718
 +                        continue;
 +                    }
  
--                        if (iblockdata.q()) {
--                            iblockdata.getBlock().randomTick = true; // Paper - fix MC-113809
+-                        if (iblockdata.isTicking()) {
 -                            iblockdata.b(this, blockposition2, this.random);
--                            iblockdata.getBlock().randomTick = false; // Paper - fix MC-113809
 -                        }
 +                    long raw = section.tickingList.getRaw(index);
 +                    int location = com.destroystokyo.paper.util.maplist.IBlockDataList.getLocationFromRaw(raw);
@@ -484,12 +385,10 @@ index f32e313a6287c8f5d487d4ad7148cac176773228..7fded15f14a3f5c04a676e9e25413718
 +                    BlockPosition blockposition2 = blockposition.setValues(j + randomX, randomY, k + randomZ);
 +                    IBlockData iblockdata = com.destroystokyo.paper.util.maplist.IBlockDataList.getBlockDataFromRaw(raw);
  
--                        if (fluid.h()) {
+-                        if (fluid.f()) {
 -                            fluid.b(this, blockposition2, this.random);
 -                        }
-+                    iblockdata.getBlock().randomTick = true; // Paper - fix MC-113809
 +                    iblockdata.b(this, blockposition2, this.randomTickRandom);
-+                    iblockdata.getBlock().randomTick = false; // Paper - fix MC-113809
  
 -                        gameprofilerfiller.exit();
 -                    }
diff --git a/Spigot-Server-Patches/0436-Entity-Jump-API.patch b/Spigot-Server-Patches/0417-Entity-Jump-API.patch
similarity index 76%
rename from Spigot-Server-Patches/0436-Entity-Jump-API.patch
rename to Spigot-Server-Patches/0417-Entity-Jump-API.patch
index c2af5a8fed..63f5a0bfae 100644
--- a/Spigot-Server-Patches/0436-Entity-Jump-API.patch
+++ b/Spigot-Server-Patches/0417-Entity-Jump-API.patch
@@ -5,13 +5,13 @@ Subject: [PATCH] Entity Jump API
 
 
 diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
-index bbe72ac65b7a9cfdfd577a0fbc316fbcc84fac59..4cac47c280a757b09e0b1e3f98c815bb8cd1b3c0 100644
+index 27b92664cee1c685b5b6b9b385150bb5fdb9fa7a..e4c7f4c100e1b8d4470da954a3b72f9e0ec5b494 100644
 --- a/src/main/java/net/minecraft/server/EntityLiving.java
 +++ b/src/main/java/net/minecraft/server/EntityLiving.java
-@@ -2608,8 +2608,10 @@ public abstract class EntityLiving extends Entity {
-             } else if (this.aH()) {
-                 this.c(TagsFluid.LAVA);
-             } else if ((this.onGround || this.N > 0.0D && this.N <= 0.4D) && this.jumpTicks == 0) {
+@@ -2748,8 +2748,10 @@ public abstract class EntityLiving extends Entity {
+             } else if (this.aN() && (!this.onGround || d7 > d8)) {
+                 this.c((Tag) TagsFluid.LAVA);
+             } else if ((this.onGround || flag && d7 <= d8) && this.jumpTicks == 0) {
 +                if (new com.destroystokyo.paper.event.entity.EntityJumpEvent(getBukkitLivingEntity()).callEvent()) { // Paper
                  this.jump();
                  this.jumpTicks = 10;
@@ -20,13 +20,13 @@ index bbe72ac65b7a9cfdfd577a0fbc316fbcc84fac59..4cac47c280a757b09e0b1e3f98c815bb
          } else {
              this.jumpTicks = 0;
 diff --git a/src/main/java/net/minecraft/server/EntityPanda.java b/src/main/java/net/minecraft/server/EntityPanda.java
-index cd41c80f19105633305be933ac20fc5548b1c5f7..f50ed19080257b9199bf1b8b846877a2ba1cafbb 100644
+index 50fe69143a6b91f957414ff556a0e60d220ab04f..42df0d74ee24ef9ac15ee19cfd298c5721df0d7d 100644
 --- a/src/main/java/net/minecraft/server/EntityPanda.java
 +++ b/src/main/java/net/minecraft/server/EntityPanda.java
-@@ -438,7 +438,9 @@ public class EntityPanda extends EntityAnimal {
+@@ -435,7 +435,9 @@ public class EntityPanda extends EntityAnimal {
              EntityPanda entitypanda = (EntityPanda) iterator.next();
  
-             if (!entitypanda.isBaby() && entitypanda.onGround && !entitypanda.isInWater() && entitypanda.eL()) {
+             if (!entitypanda.isBaby() && entitypanda.onGround && !entitypanda.isInWater() && entitypanda.fi()) {
 +                if (new com.destroystokyo.paper.event.entity.EntityJumpEvent(getBukkitLivingEntity()).callEvent()) { // Paper
                  entitypanda.jump();
 +                } else { this.setJumping(false); } // Paper - setJumping(false) stops a potential loop
@@ -34,10 +34,10 @@ index cd41c80f19105633305be933ac20fc5548b1c5f7..f50ed19080257b9199bf1b8b846877a2
          }
  
 diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
-index 7d101d9630848b68b15acc5efdc16ae51dc1f132..245bd116d143af120127a9d25dcb7a0c43ad47a0 100644
+index 39b8ab223bc708e5ee3dc967e489fdc76d944416..b3ec32b20751fbea2f6df14fc5e9f84682493bfd 100644
 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
 +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
-@@ -723,5 +723,20 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
+@@ -736,5 +736,20 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
      public boolean isHandRaised() {
          return getHandle().isHandRaised();
      }
diff --git a/Spigot-Server-Patches/0437-Add-option-to-nerf-pigmen-from-nether-portals.patch b/Spigot-Server-Patches/0418-Add-option-to-nerf-pigmen-from-nether-portals.patch
similarity index 75%
rename from Spigot-Server-Patches/0437-Add-option-to-nerf-pigmen-from-nether-portals.patch
rename to Spigot-Server-Patches/0418-Add-option-to-nerf-pigmen-from-nether-portals.patch
index 9803eec324..026a8e3c6f 100644
--- a/Spigot-Server-Patches/0437-Add-option-to-nerf-pigmen-from-nether-portals.patch
+++ b/Spigot-Server-Patches/0418-Add-option-to-nerf-pigmen-from-nether-portals.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Add option to nerf pigmen from nether portals
 
 
 diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-index 2ab810f71beaa608af2194165696817a2cde4b92..578d81337394e5279c99937890c3ce35bf58404c 100644
+index 4bfe2fb948ee204f8c5a8c316141904a8a6a8b16..3496f615aa9857aa704767f460b1b166295ccf39 100644
 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-@@ -639,4 +639,9 @@ public class PaperWorldConfig {
+@@ -596,4 +596,9 @@ public class PaperWorldConfig {
          disableHopperMoveEvents = getBoolean("hopper.disable-move-event", disableHopperMoveEvents);
          log("Hopper Move Item Events: " + (disableHopperMoveEvents ? "disabled" : "enabled"));
      }
@@ -19,23 +19,23 @@ index 2ab810f71beaa608af2194165696817a2cde4b92..578d81337394e5279c99937890c3ce35
 +    }
  }
 diff --git a/src/main/java/net/minecraft/server/BlockPortal.java b/src/main/java/net/minecraft/server/BlockPortal.java
-index 2dc3ab4cfa3fb9335d271e91c89f0b22f21eeb39..09c7c131833ded951e49a7a1a2eb2e1f6f8cb989 100644
+index e5b8d45ed9f62c28b0429859593d881546ccead2..77f8d5e6662fa75e622f07b3e6efae04c38735fe 100644
 --- a/src/main/java/net/minecraft/server/BlockPortal.java
 +++ b/src/main/java/net/minecraft/server/BlockPortal.java
-@@ -45,6 +45,8 @@ public class BlockPortal extends Block {
-                 Entity entity = EntityTypes.ZOMBIE_PIGMAN.spawnCreature(worldserver, (NBTTagCompound) null, (IChatBaseComponent) null, (EntityHuman) null, blockposition.up(), EnumMobSpawn.STRUCTURE, false, false, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NETHER_PORTAL);
+@@ -46,6 +46,8 @@ public class BlockPortal extends Block {
  
                  if (entity != null) {
+                     entity.portalCooldown = entity.getDefaultPortalCooldown();
 +                    entity.fromNetherPortal = true; // Paper
 +                    if (worldserver.paperConfig.nerfNetherPortalPigmen) ((EntityInsentient) entity).aware = false; // Paper
-                     entity.portalCooldown = entity.ba();
                  }
              }
+         }
 diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
-index 83e0af493c0f4037ff3e625ee93b9422863f335f..7bdd3f19b2bc51c4f995d42fcd47e0e315310bff 100644
+index 6cfbece5cbb6effb843f54e9917a755e2a9df4c5..278b379ba761b76fd94d3cb7aef9d3240271a973 100644
 --- a/src/main/java/net/minecraft/server/Entity.java
 +++ b/src/main/java/net/minecraft/server/Entity.java
-@@ -194,6 +194,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
+@@ -195,6 +195,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
      public long activatedTick = Integer.MIN_VALUE;
      public boolean isTemporarilyActive = false; // Paper
      public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one
@@ -43,7 +43,7 @@ index 83e0af493c0f4037ff3e625ee93b9422863f335f..7bdd3f19b2bc51c4f995d42fcd47e0e3
      protected int numCollisions = 0; // Paper
      public void inactiveTick() { }
      // Spigot end
-@@ -1646,6 +1647,9 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
+@@ -1607,6 +1608,9 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
              if (spawnedViaMobSpawner) {
                  nbttagcompound.setBoolean("Paper.FromMobSpawner", true);
              }
@@ -53,7 +53,7 @@ index 83e0af493c0f4037ff3e625ee93b9422863f335f..7bdd3f19b2bc51c4f995d42fcd47e0e3
              // Paper end
              return nbttagcompound;
          } catch (Throwable throwable) {
-@@ -1768,6 +1772,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
+@@ -1731,6 +1735,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
              }
  
              spawnedViaMobSpawner = nbttagcompound.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status
diff --git a/Spigot-Server-Patches/0438-Make-the-GUI-graph-fancier.patch b/Spigot-Server-Patches/0419-Make-the-GUI-graph-fancier.patch
similarity index 95%
rename from Spigot-Server-Patches/0438-Make-the-GUI-graph-fancier.patch
rename to Spigot-Server-Patches/0419-Make-the-GUI-graph-fancier.patch
index 6f0b10d334..5390ceee55 100644
--- a/Spigot-Server-Patches/0438-Make-the-GUI-graph-fancier.patch
+++ b/Spigot-Server-Patches/0419-Make-the-GUI-graph-fancier.patch
@@ -385,10 +385,10 @@ index 0000000000000000000000000000000000000000..c3e54da4ab6440811aab2f9dd1e21880
 +    }
 +}
 diff --git a/src/main/java/net/minecraft/server/GuiStatsComponent.java b/src/main/java/net/minecraft/server/GuiStatsComponent.java
-index c21db8e6b798cd5106801d666f14d1d73d5e84ed..7b6e9352578aecf37c5827ba2b2596d07851bf9a 100644
+index d4d5bc19e167a5271f8eb8d010f8a52b23b942df..859e31c63f94bdc7729c6d475990750b76e24b9c 100644
 --- a/src/main/java/net/minecraft/server/GuiStatsComponent.java
 +++ b/src/main/java/net/minecraft/server/GuiStatsComponent.java
-@@ -12,7 +12,7 @@ import javax.swing.Timer;
+@@ -11,7 +11,7 @@ import javax.swing.Timer;
  
  public class GuiStatsComponent extends JComponent {
  
@@ -398,23 +398,23 @@ index c21db8e6b798cd5106801d666f14d1d73d5e84ed..7b6e9352578aecf37c5827ba2b2596d0
      });
      private final int[] b = new int[256];
 diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 8c08a542a97edd76c07ef7d64834bdbd70345876..234c6f1854d4a491f6233fbd4677719a0503d3a1 100644
+index 9edf1ead68e64cdd3ee3b1256d0f92374f20e9e7..281b8d508e569c7a5e2112e72a45fa088e7cacce 100644
 --- a/src/main/java/net/minecraft/server/MinecraftServer.java
 +++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -105,7 +105,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
+@@ -106,7 +106,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
      private String motd;
+     private int F;
      private int G;
-     private int H;
--    public final long[] f = new long[100];
-+    public final long[] f = new long[100]; public long[] getTickTimes() { return f; } // Paper - OBFHELPER
+-    public final long[] h;
++    public final long[] h; public long[] getTickTimes() { return h; } // Paper - OBFHELPER
      @Nullable
-     private KeyPair I;
+     private KeyPair H;
      @Nullable
 diff --git a/src/main/java/net/minecraft/server/ServerGUI.java b/src/main/java/net/minecraft/server/ServerGUI.java
-index 95561d9db4bb2e2775dde620af5898afde15a351..470009fe4c46fdf3e31374ab576be823f6423193 100644
+index ab818eb198d4b29461731b81811a14ecc2f59511..e51434f2323bcb9385d11e99d0438d66434e3e63 100644
 --- a/src/main/java/net/minecraft/server/ServerGUI.java
 +++ b/src/main/java/net/minecraft/server/ServerGUI.java
-@@ -90,7 +90,7 @@ public class ServerGUI extends JComponent {
+@@ -89,7 +89,7 @@ public class ServerGUI extends JComponent {
  
      private JComponent c() {
          JPanel jpanel = new JPanel(new BorderLayout());
diff --git a/Spigot-Server-Patches/0440-add-hand-to-BlockMultiPlaceEvent.patch b/Spigot-Server-Patches/0420-add-hand-to-BlockMultiPlaceEvent.patch
similarity index 89%
rename from Spigot-Server-Patches/0440-add-hand-to-BlockMultiPlaceEvent.patch
rename to Spigot-Server-Patches/0420-add-hand-to-BlockMultiPlaceEvent.patch
index 9f9fb5a7fb..7c3d5a6e33 100644
--- a/Spigot-Server-Patches/0440-add-hand-to-BlockMultiPlaceEvent.patch
+++ b/Spigot-Server-Patches/0420-add-hand-to-BlockMultiPlaceEvent.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] add hand to BlockMultiPlaceEvent
 
 
 diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
-index 6ea8650d23b9fa8826142f0de3556db14c301f61..5d88a48b4c54c4b2c79804557bd36d1a6c686c89 100644
+index 3ba376b077bde759ac62ca1641962598637edd59..d82b57f4078802acd6b4a45e1f46f7ac9c8ba1d6 100644
 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
 +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
-@@ -304,13 +304,18 @@ public class CraftEventFactory {
+@@ -302,13 +302,18 @@ public class CraftEventFactory {
          }
  
          org.bukkit.inventory.ItemStack item;
diff --git a/Spigot-Server-Patches/0441-Prevent-teleporting-dead-entities.patch b/Spigot-Server-Patches/0421-Prevent-teleporting-dead-entities.patch
similarity index 84%
rename from Spigot-Server-Patches/0441-Prevent-teleporting-dead-entities.patch
rename to Spigot-Server-Patches/0421-Prevent-teleporting-dead-entities.patch
index 1133666cd0..a748121407 100644
--- a/Spigot-Server-Patches/0441-Prevent-teleporting-dead-entities.patch
+++ b/Spigot-Server-Patches/0421-Prevent-teleporting-dead-entities.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Prevent teleporting dead entities
 
 
 diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
-index 9ba5f9325fe0a7adc3ecf745d52cafe6496bc73f..4be93d12dbe12511628fd97af52d5cf78da17eaa 100644
+index 204eae3abdb006c3006537e6cf8f4c7a0bae2a47..651ecb50c2b06ca81cb9a2286d77fd41a17b5140 100644
 --- a/src/main/java/net/minecraft/server/PlayerConnection.java
 +++ b/src/main/java/net/minecraft/server/PlayerConnection.java
-@@ -1217,6 +1217,10 @@ public class PlayerConnection implements PacketListenerPlayIn {
+@@ -1239,6 +1239,10 @@ public class PlayerConnection implements PacketListenerPlayIn {
      }
  
      private void internalTeleport(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set) {
diff --git a/Spigot-Server-Patches/0442-Validate-tripwire-hook-placement-before-update.patch b/Spigot-Server-Patches/0422-Validate-tripwire-hook-placement-before-update.patch
similarity index 90%
rename from Spigot-Server-Patches/0442-Validate-tripwire-hook-placement-before-update.patch
rename to Spigot-Server-Patches/0422-Validate-tripwire-hook-placement-before-update.patch
index eb09d84299..6ea67bd8e8 100644
--- a/Spigot-Server-Patches/0442-Validate-tripwire-hook-placement-before-update.patch
+++ b/Spigot-Server-Patches/0422-Validate-tripwire-hook-placement-before-update.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Validate tripwire hook placement before update
 
 
 diff --git a/src/main/java/net/minecraft/server/BlockTripwireHook.java b/src/main/java/net/minecraft/server/BlockTripwireHook.java
-index 1b9d889af6bdefed0d6a3ebc832c39effb8af0b9..a5e6e94fe0d7702594a842bcfec2fcaae9f19d7f 100644
+index 26d801c231c6e9e31d0bdfea59e6027c77f488e4..dd30810569325096d35a367c4348e09f1463b2a9 100644
 --- a/src/main/java/net/minecraft/server/BlockTripwireHook.java
 +++ b/src/main/java/net/minecraft/server/BlockTripwireHook.java
 @@ -149,6 +149,7 @@ public class BlockTripwireHook extends Block {
diff --git a/Spigot-Server-Patches/0443-Add-option-to-allow-iron-golems-to-spawn-in-air.patch b/Spigot-Server-Patches/0423-Add-option-to-allow-iron-golems-to-spawn-in-air.patch
similarity index 82%
rename from Spigot-Server-Patches/0443-Add-option-to-allow-iron-golems-to-spawn-in-air.patch
rename to Spigot-Server-Patches/0423-Add-option-to-allow-iron-golems-to-spawn-in-air.patch
index 364a1c75bf..533e3f7386 100644
--- a/Spigot-Server-Patches/0443-Add-option-to-allow-iron-golems-to-spawn-in-air.patch
+++ b/Spigot-Server-Patches/0423-Add-option-to-allow-iron-golems-to-spawn-in-air.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Add option to allow iron golems to spawn in air
 
 
 diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-index 578d81337394e5279c99937890c3ce35bf58404c..7d39028c930cbd66c867649d5148be2fb96bc579 100644
+index 3496f615aa9857aa704767f460b1b166295ccf39..101a473ff8979b37098fde7ac6ac66c6ed1b0282 100644
 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-@@ -413,6 +413,11 @@ public class PaperWorldConfig {
+@@ -385,6 +385,11 @@ public class PaperWorldConfig {
          scanForLegacyEnderDragon = getBoolean("game-mechanics.scan-for-legacy-ender-dragon", true);
      }
  
@@ -21,10 +21,10 @@ index 578d81337394e5279c99937890c3ce35bf58404c..7d39028c930cbd66c867649d5148be2f
      private void bedSearchRadius() {
          bedSearchRadius = getInt("bed-search-radius", 1);
 diff --git a/src/main/java/net/minecraft/server/EntityIronGolem.java b/src/main/java/net/minecraft/server/EntityIronGolem.java
-index 2f764776b2fd7b9fd7c2489f1ab914dc6d2f121a..7f6a56776000643ecc42b0b917f6673b7b038d79 100644
+index 86de45327653c09dcb6764754b10b8ad1b3450fd..e38a675be7e6a4cbb1f2f7606bf84ac570bb5985 100644
 --- a/src/main/java/net/minecraft/server/EntityIronGolem.java
 +++ b/src/main/java/net/minecraft/server/EntityIronGolem.java
-@@ -221,7 +221,7 @@ public class EntityIronGolem extends EntityGolem {
+@@ -251,7 +251,7 @@ public class EntityIronGolem extends EntityGolem implements IEntityAngerable {
          BlockPosition blockposition1 = blockposition.down();
          IBlockData iblockdata = iworldreader.getType(blockposition1);
  
diff --git a/Spigot-Server-Patches/0444-Configurable-chance-of-villager-zombie-infection.patch b/Spigot-Server-Patches/0424-Configurable-chance-of-villager-zombie-infection.patch
similarity index 84%
rename from Spigot-Server-Patches/0444-Configurable-chance-of-villager-zombie-infection.patch
rename to Spigot-Server-Patches/0424-Configurable-chance-of-villager-zombie-infection.patch
index aa7b0311ae..69cc38bd06 100644
--- a/Spigot-Server-Patches/0444-Configurable-chance-of-villager-zombie-infection.patch
+++ b/Spigot-Server-Patches/0424-Configurable-chance-of-villager-zombie-infection.patch
@@ -8,10 +8,10 @@ This allows you to solve an issue in vanilla behavior where:
 * On normal difficulty they will have a 50% of getting infected or dying.
 
 diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-index 7d39028c930cbd66c867649d5148be2fb96bc579..0ff4475625e93d6f7a41345149e7c1fed0220bbb 100644
+index 101a473ff8979b37098fde7ac6ac66c6ed1b0282..9e8485679bd36481c2bd2f0c7cfa49892f0e4baf 100644
 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-@@ -649,4 +649,9 @@ public class PaperWorldConfig {
+@@ -606,4 +606,9 @@ public class PaperWorldConfig {
      private void nerfNetherPortalPigmen() {
          nerfNetherPortalPigmen = getBoolean("game-mechanics.nerf-pigmen-from-nether-portals", nerfNetherPortalPigmen);
      }
@@ -22,23 +22,22 @@ index 7d39028c930cbd66c867649d5148be2fb96bc579..0ff4475625e93d6f7a41345149e7c1fe
 +    }
  }
 diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/java/net/minecraft/server/EntityZombie.java
-index e8b9a21baf74645cc07cd9daf741bf9f65deff08..6989c0469641150b93d4264b0b6ae7080879faa7 100644
+index 9bb54d13a318199bbce3d5b32db3710f822daa40..ad8b1f0e419e6341eb46def2dc58423588a65882 100644
 --- a/src/main/java/net/minecraft/server/EntityZombie.java
 +++ b/src/main/java/net/minecraft/server/EntityZombie.java
-@@ -455,10 +455,14 @@ public class EntityZombie extends EntityMonster {
+@@ -390,10 +390,14 @@ public class EntityZombie extends EntityMonster {
      @Override
-     public void b(EntityLiving entityliving) {
-         super.b(entityliving);
+     public void a_(EntityLiving entityliving) {
+         super.a_(entityliving);
 -        if ((this.world.getDifficulty() == EnumDifficulty.NORMAL || this.world.getDifficulty() == EnumDifficulty.HARD) && entityliving instanceof EntityVillager) {
 -            if (this.world.getDifficulty() != EnumDifficulty.HARD && this.random.nextBoolean()) {
 +        // Paper start
 +        if (world.paperConfig.zombieVillagerInfectionChance != 0.0 && (world.paperConfig.zombieVillagerInfectionChance != -1.0 || this.world.getDifficulty() == EnumDifficulty.NORMAL || this.world.getDifficulty() == EnumDifficulty.HARD) && entityliving instanceof EntityVillager) {
 +            if (world.paperConfig.zombieVillagerInfectionChance == -1.0 && this.world.getDifficulty() != EnumDifficulty.HARD && this.random.nextBoolean()) {
-+                 return;
-+             }
-+            if (world.paperConfig.zombieVillagerInfectionChance != -1.0 && (this.random.nextDouble() * 100.0) > world.paperConfig.zombieVillagerInfectionChance) {
                  return;
--            }
+             }
++            if (world.paperConfig.zombieVillagerInfectionChance != -1.0 && (this.random.nextDouble() * 100.0) > world.paperConfig.zombieVillagerInfectionChance) {
++                return;
 +            } // Paper end
  
              EntityVillager entityvillager = (EntityVillager) entityliving;
diff --git a/Spigot-Server-Patches/0445-Optimise-Chunk-getFluid.patch b/Spigot-Server-Patches/0425-Optimise-Chunk-getFluid.patch
similarity index 87%
rename from Spigot-Server-Patches/0445-Optimise-Chunk-getFluid.patch
rename to Spigot-Server-Patches/0425-Optimise-Chunk-getFluid.patch
index d0174a7e1e..ed9f3cdb2c 100644
--- a/Spigot-Server-Patches/0445-Optimise-Chunk-getFluid.patch
+++ b/Spigot-Server-Patches/0425-Optimise-Chunk-getFluid.patch
@@ -8,10 +8,10 @@ faster on its own, however removing the try catch makes it
 easier to inline due to code size
 
 diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
-index cfdf6ea55dedeaf6b96566b72ca0015350c13e92..74d110874d0a9c1603d6b2d77753179ba49811ea 100644
+index a76b1d2fd81aaedb37190bcb8510020d5df2513e..cb24f27bc443880b18ffc36236f6ec7174c9d493 100644
 --- a/src/main/java/net/minecraft/server/Chunk.java
 +++ b/src/main/java/net/minecraft/server/Chunk.java
-@@ -385,17 +385,20 @@ public class Chunk implements IChunkAccess {
+@@ -386,17 +386,20 @@ public class Chunk implements IChunkAccess {
      }
  
      public Fluid a(int i, int j, int k) {
@@ -39,7 +39,7 @@ index cfdf6ea55dedeaf6b96566b72ca0015350c13e92..74d110874d0a9c1603d6b2d77753179b
              CrashReport crashreport = CrashReport.a(throwable, "Getting fluid state");
              CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Block being got");
  
-@@ -404,6 +407,7 @@ public class Chunk implements IChunkAccess {
+@@ -405,6 +408,7 @@ public class Chunk implements IChunkAccess {
              });
              throw new ReportedException(crashreport);
          }
@@ -48,10 +48,10 @@ index cfdf6ea55dedeaf6b96566b72ca0015350c13e92..74d110874d0a9c1603d6b2d77753179b
  
      // CraftBukkit start
 diff --git a/src/main/java/net/minecraft/server/ChunkSection.java b/src/main/java/net/minecraft/server/ChunkSection.java
-index 4eb7c1a9b5afced4be79a263e6a918f39c4b51be..f6df85c6bf27bfa7a16967259a6016c9473201a5 100644
+index cf444fa1cc96e881a1f9ed0c78d45935fe1c90ab..860dc98ab4f84c470b27726314943936d23fcb79 100644
 --- a/src/main/java/net/minecraft/server/ChunkSection.java
 +++ b/src/main/java/net/minecraft/server/ChunkSection.java
-@@ -37,7 +37,7 @@ public class ChunkSection {
+@@ -38,7 +38,7 @@ public class ChunkSection {
      }
  
      public Fluid b(int i, int j, int k) {
diff --git a/Spigot-Server-Patches/0446-Optimise-TickListServer-by-rewriting-it.patch b/Spigot-Server-Patches/0426-Optimise-TickListServer-by-rewriting-it.patch
similarity index 91%
rename from Spigot-Server-Patches/0446-Optimise-TickListServer-by-rewriting-it.patch
rename to Spigot-Server-Patches/0426-Optimise-TickListServer-by-rewriting-it.patch
index 852cf1d22c..d7a6348ff4 100644
--- a/Spigot-Server-Patches/0446-Optimise-TickListServer-by-rewriting-it.patch
+++ b/Spigot-Server-Patches/0426-Optimise-TickListServer-by-rewriting-it.patch
@@ -42,10 +42,10 @@ sets the excessive tick delay to the specified ticks (defaults to
 60 * 20 ticks, aka 60 seconds)
 
 diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
-index 74295466e53db06d0d019a13768f3575ac61d699..f1b41e16c8ce8323a896339c5d822f8ff7d8f7e6 100644
+index 8c2202fbc1c38e6cd19005d010e365ae14233f51..c03ff5f856f669ed535379f6c9d41812b7472743 100644
 --- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
 +++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
-@@ -369,6 +369,13 @@ public class PaperConfig {
+@@ -348,6 +348,13 @@ public class PaperConfig {
          maxBookTotalSizeMultiplier = getDouble("settings.book-size.total-multiplier", maxBookTotalSizeMultiplier);
      }
  
@@ -61,10 +61,10 @@ index 74295466e53db06d0d019a13768f3575ac61d699..f1b41e16c8ce8323a896339c5d822f8f
          ConfigurationSection section;
 diff --git a/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java b/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java
 new file mode 100644
-index 0000000000000000000000000000000000000000..ce653f6b4be3ab6c6d35cb3e9222e7f8c8759e25
+index 0000000000000000000000000000000000000000..0692fe33bb7c4a7bb666920b10f5dd3a0e7a7689
 --- /dev/null
 +++ b/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java
-@@ -0,0 +1,622 @@
+@@ -0,0 +1,617 @@
 +package com.destroystokyo.paper.server.ticklist;
 +
 +import net.minecraft.server.MCUtil;
@@ -113,7 +113,7 @@ index 0000000000000000000000000000000000000000..ce653f6b4be3ab6c6d35cb3e9222e7f8
 +    private final WorldServer world;
 +    private final Predicate<T> excludeFromScheduling;
 +    private final Function<T, MinecraftKey> getMinecraftKeyFrom;
-+    private final Function<MinecraftKey, T> getObjectFronMinecraftKey;
++    //private final Function<MinecraftKey, T> getObjectFronMinecraftKey;
 +    private final Consumer<NextTickListEntry<T>> tickFunction;
 +
 +    private final co.aikar.timings.Timing timingCleanup; // Paper
@@ -156,12 +156,11 @@ index 0000000000000000000000000000000000000000..ce653f6b4be3ab6c6d35cb3e9222e7f8
 +    }
 +
 +    public PaperTickList(final WorldServer world, final Predicate<T> excludeFromScheduling, final Function<T, MinecraftKey> getMinecraftKeyFrom,
-+                         final Function<MinecraftKey, T> getObjectFronMinecraftKey, final Consumer<NextTickListEntry<T>> tickFunction, final String timingsType) {
-+        super(world, excludeFromScheduling, getMinecraftKeyFrom, getObjectFronMinecraftKey, tickFunction, timingsType);
++                         final Consumer<NextTickListEntry<T>> tickFunction, final String timingsType) {
++        super(world, excludeFromScheduling, getMinecraftKeyFrom, tickFunction, timingsType);
 +        this.world = world;
 +        this.excludeFromScheduling = excludeFromScheduling;
 +        this.getMinecraftKeyFrom = getMinecraftKeyFrom;
-+        this.getObjectFronMinecraftKey = getObjectFronMinecraftKey;
 +        this.tickFunction = tickFunction;
 +        this.timingCleanup = co.aikar.timings.WorldTimingsHandler.getTickList(world, timingsType + " - Cleanup"); // Paper
 +        this.timingTicking = co.aikar.timings.WorldTimingsHandler.getTickList(world, timingsType + " - Ticking"); // Paper
@@ -521,10 +520,6 @@ index 0000000000000000000000000000000000000000..ce653f6b4be3ab6c6d35cb3e9222e7f8
 +        this.addToSchedule(entry);
 +    }
 +
-+    @Override
-+    public void scheduleAll(final Stream<NextTickListEntry<T>> stream) {
-+        this.scheduleAll(stream.iterator());
-+    }
 +    public void scheduleAll(final Iterator<NextTickListEntry<T>> iterator) {
 +        while (iterator.hasNext()) {
 +            this.schedule(iterator.next());
@@ -883,10 +878,10 @@ index 0000000000000000000000000000000000000000..118988c39e58f28e8a2851792b9c014f
 +    }
 +}
 diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java
-index 3fcfe416d26808fa1c9bfdc5b413b149764c544a..3bf17ccdaef21322b787db538d569e0bc614ef22 100644
+index 9fb776318c10f393eb6d94e5112c454a7cd246b9..adfeeefbbc307a77738c2cc8d82856cd02c2285e 100644
 --- a/src/main/java/net/minecraft/server/BlockPosition.java
 +++ b/src/main/java/net/minecraft/server/BlockPosition.java
-@@ -126,6 +126,7 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali
+@@ -104,6 +104,7 @@ public class BlockPosition extends BaseBlockPosition {
          return i == 0 && j == 0 && k == 0 ? this : new BlockPosition(this.getX() + i, this.getY() + j, this.getZ() + k);
      }
  
@@ -895,10 +890,10 @@ index 3fcfe416d26808fa1c9bfdc5b413b149764c544a..3bf17ccdaef21322b787db538d569e0b
          return this.b(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ());
      }
 diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
-index e467cd8123dafc46a8c894f1ffa9440de0d45340..9e3471be219b5e061486c8a3e4b638a45e6f28f5 100644
+index 67d6facd37462beef49dac311019b1977150d73f..ba9f75bd8f6fe1990d485548f4481bd1762d93af 100644
 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
 +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
-@@ -200,6 +200,13 @@ public class ChunkProviderServer extends IChunkProvider {
+@@ -202,6 +202,13 @@ public class ChunkProviderServer extends IChunkProvider {
      }
      // Paper end
  
@@ -909,9 +904,9 @@ index e467cd8123dafc46a8c894f1ffa9440de0d45340..9e3471be219b5e061486c8a3e4b638a4
 +    }
 +    // Paper end - rewrite ticklistserver
 +
- 
-     public ChunkProviderServer(WorldServer worldserver, File file, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, ChunkGenerator<?> chunkgenerator, int i, WorldLoadListener worldloadlistener, Supplier<WorldPersistentData> supplier) {
+     public ChunkProviderServer(WorldServer worldserver, Convertable.ConversionSession convertable_conversionsession, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, ChunkGenerator chunkgenerator, int i, boolean flag, WorldLoadListener worldloadlistener, Supplier<WorldPersistentData> supplier) {
          this.world = worldserver;
+         this.serverThreadQueue = new ChunkProviderServer.a(worldserver);
 diff --git a/src/main/java/net/minecraft/server/NextTickListEntry.java b/src/main/java/net/minecraft/server/NextTickListEntry.java
 index 33cfeabdee03195a294f303f28044a313cb1c4ed..2287e47d1b891135a5f2579ec324c70589141192 100644
 --- a/src/main/java/net/minecraft/server/NextTickListEntry.java
@@ -984,10 +979,10 @@ index 33cfeabdee03195a294f303f28044a313cb1c4ed..2287e47d1b891135a5f2579ec324c705
      public String toString() {
          return this.e + ": " + this.a + ", " + this.b + ", " + this.c + ", " + this.f;
 diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
-index 0f1576effe10795bcb8ed3b519f4dbafdf9ea6ed..afc92dd031cdaf725b85c0b301d5a5a21da54720 100644
+index b6868b6b23a09e8e0dfe7a5e378dca22b8d80bad..9cb2ff09da0b8832e58eed4d70741853a25c9011 100644
 --- a/src/main/java/net/minecraft/server/PlayerChunk.java
 +++ b/src/main/java/net/minecraft/server/PlayerChunk.java
-@@ -473,7 +473,9 @@ public class PlayerChunk {
+@@ -460,7 +460,9 @@ public class PlayerChunk {
                      PlayerChunk.this.isTickingReady = true;
  
  
@@ -999,7 +994,7 @@ index 0f1576effe10795bcb8ed3b519f4dbafdf9ea6ed..afc92dd031cdaf725b85c0b301d5a5a2
                  }
              });
 diff --git a/src/main/java/net/minecraft/server/StructureBoundingBox.java b/src/main/java/net/minecraft/server/StructureBoundingBox.java
-index dbb565e74d211ef35d5d40b3d024e2f07cef9031..185658e230688a9939c89dae9167217cbee03571 100644
+index 7873db26b336c97f909e5391e58ee53feaf59b9a..447eb2ba84789edf9bac2e2ffb2dec7cb4596cbf 100644
 --- a/src/main/java/net/minecraft/server/StructureBoundingBox.java
 +++ b/src/main/java/net/minecraft/server/StructureBoundingBox.java
 @@ -4,12 +4,12 @@ import com.google.common.base.MoreObjects;
@@ -1021,7 +1016,7 @@ index dbb565e74d211ef35d5d40b3d024e2f07cef9031..185658e230688a9939c89dae9167217c
  
      public StructureBoundingBox() {}
  
-@@ -84,6 +84,7 @@ public class StructureBoundingBox {
+@@ -88,6 +88,7 @@ public class StructureBoundingBox {
          this.e = 512;
      }
  
@@ -1029,8 +1024,8 @@ index dbb565e74d211ef35d5d40b3d024e2f07cef9031..185658e230688a9939c89dae9167217c
      public boolean b(StructureBoundingBox structureboundingbox) {
          return this.d >= structureboundingbox.a && this.a <= structureboundingbox.d && this.f >= structureboundingbox.c && this.c <= structureboundingbox.f && this.e >= structureboundingbox.b && this.b <= structureboundingbox.e;
      }
-@@ -114,6 +115,7 @@ public class StructureBoundingBox {
-         return new StructureBoundingBox(this.a + i, this.b + j, this.c + k, this.d + i, this.e + j, this.f + k);
+@@ -122,6 +123,7 @@ public class StructureBoundingBox {
+         this.a(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ());
      }
  
 +    public final boolean hasPoint(BaseBlockPosition baseblockposition) { return this.b(baseblockposition); } // Paper - OBFHELPER
@@ -1038,10 +1033,10 @@ index dbb565e74d211ef35d5d40b3d024e2f07cef9031..185658e230688a9939c89dae9167217c
          return baseblockposition.getX() >= this.a && baseblockposition.getX() <= this.d && baseblockposition.getZ() >= this.c && baseblockposition.getZ() <= this.f && baseblockposition.getY() >= this.b && baseblockposition.getY() <= this.e;
      }
 diff --git a/src/main/java/net/minecraft/server/TickListServer.java b/src/main/java/net/minecraft/server/TickListServer.java
-index f533860bbed19ff2915c90186c259b466f41ce90..3f1aa5ced697490b5481ba992cf5af5dc98b8166 100644
+index 3b8f56c0f0507ebdd9ac20be70688b4c0cfe4cf8..149d2b4f929c11b8baf17163bbd6ff8220a95e86 100644
 --- a/src/main/java/net/minecraft/server/TickListServer.java
 +++ b/src/main/java/net/minecraft/server/TickListServer.java
-@@ -42,6 +42,11 @@ public class TickListServer<T> implements TickList<T> {
+@@ -39,6 +39,11 @@ public class TickListServer<T> implements TickList<T> {
      // Paper end
  
      public void b() {
@@ -1053,7 +1048,7 @@ index f533860bbed19ff2915c90186c259b466f41ce90..3f1aa5ced697490b5481ba992cf5af5d
          int i = this.nextTickList.size();
  
          if (false) { // CraftBukkit
-@@ -109,15 +114,30 @@ public class TickListServer<T> implements TickList<T> {
+@@ -106,10 +111,20 @@ public class TickListServer<T> implements TickList<T> {
  
      @Override
      public boolean b(BlockPosition blockposition, T t0) {
@@ -1062,17 +1057,7 @@ index f533860bbed19ff2915c90186c259b466f41ce90..3f1aa5ced697490b5481ba992cf5af5d
 +    }
 +    public boolean isPendingTickThisTick(BlockPosition blockposition, T t0) {
 +        // Paper end
-         return this.g.contains(new NextTickListEntry<>(blockposition, t0));
-     }
- 
-     @Override
-     public void a(Stream<NextTickListEntry<T>> stream) {
-+        // Paper start - allow overriding
-+        this.scheduleAll(stream);
-+    }
-+    public void scheduleAll(Stream<NextTickListEntry<T>> stream) {
-+        // Paper end
-         stream.forEach(this::a);
+         return this.f.contains(new NextTickListEntry<>(blockposition, t0));
      }
  
      public List<NextTickListEntry<T>> a(ChunkCoordIntPair chunkcoordintpair, boolean flag, boolean flag1) {
@@ -1084,7 +1069,7 @@ index f533860bbed19ff2915c90186c259b466f41ce90..3f1aa5ced697490b5481ba992cf5af5d
          int i = (chunkcoordintpair.x << 4) - 2;
          int j = i + 16 + 2;
          int k = (chunkcoordintpair.z << 4) - 2;
-@@ -127,6 +147,11 @@ public class TickListServer<T> implements TickList<T> {
+@@ -119,6 +134,11 @@ public class TickListServer<T> implements TickList<T> {
      }
  
      public List<NextTickListEntry<T>> a(StructureBoundingBox structureboundingbox, boolean flag, boolean flag1) {
@@ -1096,7 +1081,7 @@ index f533860bbed19ff2915c90186c259b466f41ce90..3f1aa5ced697490b5481ba992cf5af5d
          List<NextTickListEntry<T>> list = this.a((List) null, this.nextTickList, structureboundingbox, flag);
  
          if (flag && list != null) {
-@@ -166,6 +191,11 @@ public class TickListServer<T> implements TickList<T> {
+@@ -158,6 +178,11 @@ public class TickListServer<T> implements TickList<T> {
      }
  
      public void a(StructureBoundingBox structureboundingbox, BlockPosition blockposition) {
@@ -1108,7 +1093,7 @@ index f533860bbed19ff2915c90186c259b466f41ce90..3f1aa5ced697490b5481ba992cf5af5d
          List<NextTickListEntry<T>> list = this.a(structureboundingbox, false, false);
          Iterator iterator = list.iterator();
  
-@@ -183,11 +213,17 @@ public class TickListServer<T> implements TickList<T> {
+@@ -175,11 +200,17 @@ public class TickListServer<T> implements TickList<T> {
      }
  
      public NBTTagList a(ChunkCoordIntPair chunkcoordintpair) {
@@ -1119,14 +1104,14 @@ index f533860bbed19ff2915c90186c259b466f41ce90..3f1aa5ced697490b5481ba992cf5af5d
 +        // Paper end
          List<NextTickListEntry<T>> list = this.a(chunkcoordintpair, false, true);
  
-         return a(this.b, list, this.f.getTime());
+         return a(this.b, list, this.e.getTime());
      }
  
 +    public static <T> NBTTagList serialize(Function<T, MinecraftKey> function, Iterable<NextTickListEntry<T>> iterable, long i) { return TickListServer.a(function, iterable, i); } // Paper - OBFHELPER
-     public static <T> NBTTagList a(Function<T, MinecraftKey> function, Iterable<NextTickListEntry<T>> iterable, long i) {
+     private static <T> NBTTagList a(Function<T, MinecraftKey> function, Iterable<NextTickListEntry<T>> iterable, long i) {
          NBTTagList nbttaglist = new NBTTagList();
          Iterator iterator = iterable.iterator();
-@@ -210,11 +246,21 @@ public class TickListServer<T> implements TickList<T> {
+@@ -202,11 +233,21 @@ public class TickListServer<T> implements TickList<T> {
  
      @Override
      public boolean a(BlockPosition blockposition, T t0) {
@@ -1146,9 +1131,9 @@ index f533860bbed19ff2915c90186c259b466f41ce90..3f1aa5ced697490b5481ba992cf5af5d
 +    public void schedule(BlockPosition blockposition, T t0, int i, TickListPriority ticklistpriority) {
 +        // Paper end
          if (!this.a.test(t0)) {
-             this.a(new NextTickListEntry<>(blockposition, t0, (long) i + this.f.getTime(), ticklistpriority));
+             this.a(new NextTickListEntry<>(blockposition, t0, (long) i + this.e.getTime(), ticklistpriority));
          }
-@@ -230,6 +276,11 @@ public class TickListServer<T> implements TickList<T> {
+@@ -222,6 +263,11 @@ public class TickListServer<T> implements TickList<T> {
      }
  
      public int a() {
@@ -1161,10 +1146,10 @@ index f533860bbed19ff2915c90186c259b466f41ce90..3f1aa5ced697490b5481ba992cf5af5d
      }
  }
 diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
-index 7fded15f14a3f5c04a676e9e25413718b9922c13..642b5b485df28149f255ae9b5e43083821b20a0a 100644
+index 3266ecf2ad975613942a9cd127440dd898b12ff5..b8e635e351773663f62bd07193c6b0aceef0a3f3 100644
 --- a/src/main/java/net/minecraft/server/WorldServer.java
 +++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -170,6 +170,15 @@ public class WorldServer extends World {
+@@ -182,6 +182,15 @@ public class WorldServer extends World implements GeneratorAccessSeed {
      }
      // Paper end
  
@@ -1177,35 +1162,34 @@ index 7fded15f14a3f5c04a676e9e25413718b9922c13..642b5b485df28149f255ae9b5e430838
 +    }
 +    // Paper end - rewrite ticklistserver
 +
-     // Add env and gen to constructor
-     public WorldServer(MinecraftServer minecraftserver, Executor executor, WorldNBTStorage worldnbtstorage, WorldData worlddata, DimensionManager dimensionmanager, GameProfilerFiller gameprofilerfiller, WorldLoadListener worldloadlistener, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
-         super(worlddata, dimensionmanager, executor, (world, worldprovider) -> { // Paper - pass executor down
-@@ -190,12 +199,22 @@ public class WorldServer extends World {
-         this.pvpMode = minecraftserver.getPVP();
-         worlddata.world = this;
+     // Add env and gen to constructor, WorldData -> WorldDataServer
+     public WorldServer(MinecraftServer minecraftserver, Executor executor, Convertable.ConversionSession convertable_conversionsession, IWorldDataServer iworlddataserver, ResourceKey<World> resourcekey, ResourceKey<DimensionManager> resourcekey1, DimensionManager dimensionmanager, WorldLoadListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List<MobSpawner> list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
+         super(iworlddataserver, resourcekey, resourcekey1, dimensionmanager, minecraftserver::getMethodProfiler, false, flag, i, gen, env, executor); // Paper pass executor
+@@ -189,12 +198,21 @@ public class WorldServer extends World implements GeneratorAccessSeed {
+         convertable = convertable_conversionsession;
+         uuid = WorldUUID.getUUID(convertable_conversionsession.folder.toFile());
          // CraftBukkit end
 -        this.nextTickListBlock = new TickListServer<>(this, (block) -> {
 -            return block == null || block.getBlockData().isAir();
--        }, IRegistry.BLOCK::getKey, IRegistry.BLOCK::get, this::b, "Blocks"); // Paper - Timings
+-        }, IRegistry.BLOCK::getKey, this::b, "Blocks"); // Paper - Timings
 -        this.nextTickListFluid = new TickListServer<>(this, (fluidtype) -> {
 -            return fluidtype == null || fluidtype == FluidTypes.EMPTY;
--        }, IRegistry.FLUID::getKey, IRegistry.FLUID::get, this::a, "Fluids"); // Paper - Timings
+-        }, IRegistry.FLUID::getKey, this::a, "Fluids"); // Paper - Timings
 +        if (com.destroystokyo.paper.PaperConfig.useOptimizedTickList) {
-+            this.nextTickListBlock = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (block) -> { // Paper - optimise TickListServer
++            this.nextTickListBlock = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (block) -> {
 +                return block == null || block.getBlockData().isAir();
-+            }, IRegistry.BLOCK::getKey, IRegistry.BLOCK::get, this::b, "Blocks"); // Paper - Timings
-+            this.nextTickListFluid = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (fluidtype) -> { // Paper - optimise TickListServer
++            }, IRegistry.BLOCK::getKey, this::b, "Blocks"); // Paper - Timings
++            this.nextTickListFluid = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (fluidtype) -> {
 +                return fluidtype == null || fluidtype == FluidTypes.EMPTY;
-+            }, IRegistry.FLUID::getKey, IRegistry.FLUID::get, this::a, "Fluids"); // Paper - Timings
++            }, IRegistry.FLUID::getKey, this::a, "Fluids"); // Paper - Timings
 +        } else {
-+            this.nextTickListBlock = new TickListServer<>(this, (block) -> { // Paper - optimise TickListServer
++            this.nextTickListBlock = new TickListServer<>(this, (block) -> {
 +                return block == null || block.getBlockData().isAir();
-+            }, IRegistry.BLOCK::getKey, IRegistry.BLOCK::get, this::b, "Blocks"); // Paper - Timings
-+            this.nextTickListFluid = new TickListServer<>(this, (fluidtype) -> { // Paper - optimise TickListServer
++            }, IRegistry.BLOCK::getKey, this::b, "Blocks"); // Paper - Timings
++            this.nextTickListFluid = new TickListServer<>(this, (fluidtype) -> {
 +                return fluidtype == null || fluidtype == FluidTypes.EMPTY;
-+            }, IRegistry.FLUID::getKey, IRegistry.FLUID::get, this::a, "Fluids"); // Paper - Timings
++            }, IRegistry.FLUID::getKey, this::a, "Fluids"); // Paper - Timings
 +        }
-+
          this.navigators = Sets.newHashSet();
-         this.I = new ObjectLinkedOpenHashSet();
-         this.dataManager = worldnbtstorage;
+         this.L = new ObjectLinkedOpenHashSet();
+         this.Q = flag1;
diff --git a/Spigot-Server-Patches/0427-Fix-comparator-behavior-for-EntityPhanton-goal.patch b/Spigot-Server-Patches/0427-Fix-comparator-behavior-for-EntityPhanton-goal.patch
deleted file mode 100644
index 3e04bb18fc..0000000000
--- a/Spigot-Server-Patches/0427-Fix-comparator-behavior-for-EntityPhanton-goal.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Shane Freeder <theboyetronic@gmail.com>
-Date: Wed, 22 Jan 2020 21:00:21 +0000
-Subject: [PATCH] Fix comparator behavior for EntityPhanton goal
-
-
-diff --git a/src/main/java/net/minecraft/server/EntityPhantom.java b/src/main/java/net/minecraft/server/EntityPhantom.java
-index 82323bf4acc140d279c399cc64fa393a0db90136..90eeddb1af59126ea7ca19c2cc909da72578fb6c 100644
---- a/src/main/java/net/minecraft/server/EntityPhantom.java
-+++ b/src/main/java/net/minecraft/server/EntityPhantom.java
-@@ -224,7 +224,7 @@ public class EntityPhantom extends EntityFlying implements IMonster {
- 
-                 if (!list.isEmpty()) {
-                     list.sort((entityhuman, entityhuman1) -> {
--                        return entityhuman.locY() > entityhuman1.locY() ? -1 : 1;
-+                        return Double.compare(entityhuman1.locY(), entityhuman.locY()); // Paper
-                     });
-                     Iterator iterator = list.iterator();
- 
diff --git a/Spigot-Server-Patches/0447-Pillager-patrol-spawn-settings-and-per-player-option.patch b/Spigot-Server-Patches/0427-Pillager-patrol-spawn-settings-and-per-player-option.patch
similarity index 92%
rename from Spigot-Server-Patches/0447-Pillager-patrol-spawn-settings-and-per-player-option.patch
rename to Spigot-Server-Patches/0427-Pillager-patrol-spawn-settings-and-per-player-option.patch
index 3ceb2620fa..4bc611f700 100644
--- a/Spigot-Server-Patches/0447-Pillager-patrol-spawn-settings-and-per-player-option.patch
+++ b/Spigot-Server-Patches/0427-Pillager-patrol-spawn-settings-and-per-player-option.patch
@@ -10,10 +10,10 @@ When not per player it will use the Vanilla mechanic of one delay per
 world and the world age for the start day.
 
 diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-index 0ff4475625e93d6f7a41345149e7c1fed0220bbb..598f27bc1b95132ded224dd5c7a0e2639ab2bd12 100644
+index 9e8485679bd36481c2bd2f0c7cfa49892f0e4baf..2688b3018eaab4e7ba95754164f83065a98e53fc 100644
 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-@@ -627,10 +627,21 @@ public class PaperWorldConfig {
+@@ -584,10 +584,21 @@ public class PaperWorldConfig {
      }
  
      public boolean disablePillagerPatrols = false;
@@ -36,10 +36,10 @@ index 0ff4475625e93d6f7a41345149e7c1fed0220bbb..598f27bc1b95132ded224dd5c7a0e263
      private void entitiesTargetWithFollowRange() {
          entitiesTargetWithFollowRange = getBoolean("entities-target-with-follow-range", entitiesTargetWithFollowRange);
 diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
-index 8434f10d4c674fbbed40dba86e54f7cad93df642..52544730a2cce4db4f912ad1109945ac4e53a9b6 100644
+index 458306bd5585e1b78dec6cbfafba1751c76513a2..9d7096c61fed5f5b8b45273e146862688df22c59 100644
 --- a/src/main/java/net/minecraft/server/EntityPlayer.java
 +++ b/src/main/java/net/minecraft/server/EntityPlayer.java
-@@ -77,6 +77,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
+@@ -81,6 +81,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
      public boolean viewingCredits;
      private int containerUpdateDelay; // Paper
      public long loginTime; // Paper
@@ -48,12 +48,12 @@ index 8434f10d4c674fbbed40dba86e54f7cad93df642..52544730a2cce4db4f912ad1109945ac
      public boolean queueHealthUpdatePacket = false;
      public net.minecraft.server.PacketPlayOutUpdateHealth queuedHealthUpdatePacket;
 diff --git a/src/main/java/net/minecraft/server/MobSpawnerPatrol.java b/src/main/java/net/minecraft/server/MobSpawnerPatrol.java
-index a0f582807605b9cc5bbf31d84907e56fba393e2e..edca6d3abdc31701068cad4af493759f353d4407 100644
+index b1fea06d29a0c98136496d6eff81e6959cb73672..78029e10e6670936fb7dbedc7f34c5f8045fc291 100644
 --- a/src/main/java/net/minecraft/server/MobSpawnerPatrol.java
 +++ b/src/main/java/net/minecraft/server/MobSpawnerPatrol.java
-@@ -4,12 +4,14 @@ import java.util.Random;
+@@ -4,13 +4,15 @@ import java.util.Random;
  
- public class MobSpawnerPatrol {
+ public class MobSpawnerPatrol implements MobSpawner {
  
 +    private int getSpawnDelay() { return a; } // Paper - OBFHELPER
 +    private void setSpawnDelay(int spawnDelay) { this.a = spawnDelay; } // Paper - OBFHELPER
@@ -61,13 +61,14 @@ index a0f582807605b9cc5bbf31d84907e56fba393e2e..edca6d3abdc31701068cad4af493759f
  
      public MobSpawnerPatrol() {}
  
+     @Override
      public int a(WorldServer worldserver, boolean flag, boolean flag1) {
 -        if (worldserver.paperConfig.disablePillagerPatrols) return 0; // Paper
 +        if (worldserver.paperConfig.disablePillagerPatrols || worldserver.paperConfig.patrolSpawnChance == 0) return 0; // Paper
          if (!flag) {
              return 0;
          } else if (!worldserver.getGameRules().getBoolean(GameRules.DO_PATROL_SPAWNING)) {
-@@ -17,23 +19,51 @@ public class MobSpawnerPatrol {
+@@ -18,23 +20,51 @@ public class MobSpawnerPatrol implements MobSpawner {
          } else {
              Random random = worldserver.random;
  
diff --git a/Spigot-Server-Patches/0448-Ensure-Entity-is-never-double-registered.patch b/Spigot-Server-Patches/0428-Ensure-Entity-is-never-double-registered.patch
similarity index 77%
rename from Spigot-Server-Patches/0448-Ensure-Entity-is-never-double-registered.patch
rename to Spigot-Server-Patches/0428-Ensure-Entity-is-never-double-registered.patch
index 13035d203c..21f54aa5ef 100644
--- a/Spigot-Server-Patches/0448-Ensure-Entity-is-never-double-registered.patch
+++ b/Spigot-Server-Patches/0428-Ensure-Entity-is-never-double-registered.patch
@@ -11,10 +11,10 @@ Vs behavior of non ticking of just overwriting state.
 We will now simply log a warning when this happens instead of crashing the server.
 
 diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
-index 7bdd3f19b2bc51c4f995d42fcd47e0e315310bff..7434f859f7f9acff0f881ff594c8dffdfa249c76 100644
+index 278b379ba761b76fd94d3cb7aef9d3240271a973..59d72dfc903bb7a9c50baf59fface280b44a6d5b 100644
 --- a/src/main/java/net/minecraft/server/Entity.java
 +++ b/src/main/java/net/minecraft/server/Entity.java
-@@ -59,6 +59,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
+@@ -60,6 +60,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
      }
  
      // Paper start
@@ -23,18 +23,18 @@ index 7bdd3f19b2bc51c4f995d42fcd47e0e315310bff..7434f859f7f9acff0f881ff594c8dffd
          private boolean locked = false;
          @Override
 diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
-index 642b5b485df28149f255ae9b5e43083821b20a0a..46b28be6a808a33e4330a051ac6d8139953ed299 100644
+index b8e635e351773663f62bd07193c6b0aceef0a3f3..17f9e9119723561a4b01efbb91d651fbc9c8726e 100644
 --- a/src/main/java/net/minecraft/server/WorldServer.java
 +++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -532,6 +532,7 @@ public class WorldServer extends World {
+@@ -532,6 +532,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
+             Entity entity2;
  
-             try (co.aikar.timings.Timing ignored = this.timings.newEntities.startTiming()) { // Paper - timings
-             while ((entity = (Entity) this.entitiesToAdd.poll()) != null) {
-+                if (!entity.isQueuedForRegister) continue; // Paper - ignore cancelled registers
-                 this.registerEntity(entity);
+             while ((entity2 = (Entity) this.entitiesToAdd.poll()) != null) {
++                if (!entity2.isQueuedForRegister) continue; // Paper - ignore cancelled registers
+                 this.registerEntity(entity2);
              }
-             } // Paper - timings
-@@ -1338,6 +1339,19 @@ public class WorldServer extends World {
+ 
+@@ -1228,6 +1229,19 @@ public class WorldServer extends World implements GeneratorAccessSeed {
  
      public void unregisterEntity(Entity entity) {
          org.spigotmc.AsyncCatcher.catchOp("entity unregister"); // Spigot
@@ -54,7 +54,7 @@ index 642b5b485df28149f255ae9b5e43083821b20a0a..46b28be6a808a33e4330a051ac6d8139
          // Spigot start
          if ( entity instanceof EntityHuman )
          {
-@@ -1404,9 +1418,21 @@ public class WorldServer extends World {
+@@ -1294,9 +1308,21 @@ public class WorldServer extends World implements GeneratorAccessSeed {
  
      private void registerEntity(Entity entity) {
          org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot
@@ -76,4 +76,4 @@ index 642b5b485df28149f255ae9b5e43083821b20a0a..46b28be6a808a33e4330a051ac6d8139
 +            entity.isQueuedForRegister = false; // Paper
              this.entitiesById.put(entity.getId(), entity);
              if (entity instanceof EntityEnderDragon) {
-                 EntityComplexPart[] aentitycomplexpart = ((EntityEnderDragon) entity).eo();
+                 EntityComplexPart[] aentitycomplexpart = ((EntityEnderDragon) entity).eK();
diff --git a/Spigot-Server-Patches/0449-Fix-unregistering-entities-from-unloading-chunks.patch b/Spigot-Server-Patches/0429-Fix-unregistering-entities-from-unloading-chunks.patch
similarity index 88%
rename from Spigot-Server-Patches/0449-Fix-unregistering-entities-from-unloading-chunks.patch
rename to Spigot-Server-Patches/0429-Fix-unregistering-entities-from-unloading-chunks.patch
index 8baa9ea66b..8baef3ad57 100644
--- a/Spigot-Server-Patches/0449-Fix-unregistering-entities-from-unloading-chunks.patch
+++ b/Spigot-Server-Patches/0429-Fix-unregistering-entities-from-unloading-chunks.patch
@@ -15,10 +15,10 @@ Combine that with a buggy detail of the previous implementation of
 the Dupe UUID patch, then this was the likely source of the "Ghost entities"
 
 diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
-index 46b28be6a808a33e4330a051ac6d8139953ed299..68c7c243a6d12d5c2f1045dfc5dd36f455dfbffa 100644
+index 17f9e9119723561a4b01efbb91d651fbc9c8726e..f792ff541793855d9ed0b60f5990b6fdfa303995 100644
 --- a/src/main/java/net/minecraft/server/WorldServer.java
 +++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -1497,9 +1497,9 @@ public class WorldServer extends World {
+@@ -1387,9 +1387,9 @@ public class WorldServer extends World implements GeneratorAccessSeed {
      }
  
      private void removeEntityFromChunk(Entity entity) {
diff --git a/Spigot-Server-Patches/0450-Remote-Connections-shouldn-t-hold-up-shutdown.patch b/Spigot-Server-Patches/0430-Remote-Connections-shouldn-t-hold-up-shutdown.patch
similarity index 86%
rename from Spigot-Server-Patches/0450-Remote-Connections-shouldn-t-hold-up-shutdown.patch
rename to Spigot-Server-Patches/0430-Remote-Connections-shouldn-t-hold-up-shutdown.patch
index e74f8cac97..cf920fbc7c 100644
--- a/Spigot-Server-Patches/0450-Remote-Connections-shouldn-t-hold-up-shutdown.patch
+++ b/Spigot-Server-Patches/0430-Remote-Connections-shouldn-t-hold-up-shutdown.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Remote Connections shouldn't hold up shutdown
 Bugs in the connection logic appears to leave stale connections even, preventing shutdown
 
 diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java
-index 349a0ea213f7f45e927d439985e121e8fa66c041..1ef7890da599d13e784861035e7891efcc4cd504 100644
+index 715063432bb3a18421f7ac00723f6695f8a56a8c..4fa8d40d84884f17b4bbcc357a6bb902f8f668cd 100644
 --- a/src/main/java/net/minecraft/server/DedicatedServer.java
 +++ b/src/main/java/net/minecraft/server/DedicatedServer.java
-@@ -415,11 +415,11 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
+@@ -361,11 +361,11 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
          }
  
          if (this.remoteControlListener != null) {
diff --git a/Spigot-Server-Patches/0451-Do-not-allow-bees-to-load-chunks-for-beehives.patch b/Spigot-Server-Patches/0431-Do-not-allow-bees-to-load-chunks-for-beehives.patch
similarity index 73%
rename from Spigot-Server-Patches/0451-Do-not-allow-bees-to-load-chunks-for-beehives.patch
rename to Spigot-Server-Patches/0431-Do-not-allow-bees-to-load-chunks-for-beehives.patch
index f639d95a41..f39f9165ee 100644
--- a/Spigot-Server-Patches/0451-Do-not-allow-bees-to-load-chunks-for-beehives.patch
+++ b/Spigot-Server-Patches/0431-Do-not-allow-bees-to-load-chunks-for-beehives.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Do not allow bees to load chunks for beehives
 
 
 diff --git a/src/main/java/net/minecraft/server/EntityBee.java b/src/main/java/net/minecraft/server/EntityBee.java
-index c7d79efdf6ee3b1ac910ff48bfd4b0ef084b4d43..dd1d246aeb5bd7c7d284175f936936ececb0f932 100644
+index b9e01e4d9e64fdec4c4f04f1808eb8832bd00c8e..e6868e2b65e3c2bde7696272b242a47e7394e27f 100644
 --- a/src/main/java/net/minecraft/server/EntityBee.java
 +++ b/src/main/java/net/minecraft/server/EntityBee.java
-@@ -315,6 +315,7 @@ public class EntityBee extends EntityAnimal implements EntityBird {
+@@ -284,6 +284,7 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
          if (this.hivePos == null) {
              return false;
          } else {
@@ -16,7 +16,7 @@ index c7d79efdf6ee3b1ac910ff48bfd4b0ef084b4d43..dd1d246aeb5bd7c7d284175f936936ec
              TileEntity tileentity = this.world.getTileEntity(this.hivePos);
  
              return tileentity instanceof TileEntityBeehive && ((TileEntityBeehive) tileentity).d();
-@@ -334,6 +335,7 @@ public class EntityBee extends EntityAnimal implements EntityBird {
+@@ -316,6 +317,7 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
      }
  
      private boolean i(BlockPosition blockposition) {
@@ -24,15 +24,15 @@ index c7d79efdf6ee3b1ac910ff48bfd4b0ef084b4d43..dd1d246aeb5bd7c7d284175f936936ec
          TileEntity tileentity = this.world.getTileEntity(blockposition);
  
          return tileentity instanceof TileEntityBeehive ? !((TileEntityBeehive) tileentity).isFull() : false;
-@@ -593,6 +595,7 @@ public class EntityBee extends EntityAnimal implements EntityBird {
+@@ -558,6 +560,7 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
          @Override
          public boolean g() {
-             if (EntityBee.this.hasHivePos() && EntityBee.this.eI() && EntityBee.this.hivePos.a((IPosition) EntityBee.this.getPositionVector(), 2.0D)) {
+             if (EntityBee.this.hasHivePos() && EntityBee.this.fe() && EntityBee.this.hivePos.a((IPosition) EntityBee.this.getPositionVector(), 2.0D)) {
 +                if (!EntityBee.this.world.isLoadedAndInBounds(EntityBee.this.hivePos)) return false; // Paper
                  TileEntity tileentity = EntityBee.this.world.getTileEntity(EntityBee.this.hivePos);
  
                  if (tileentity instanceof TileEntityBeehive) {
-@@ -616,6 +619,7 @@ public class EntityBee extends EntityAnimal implements EntityBird {
+@@ -581,6 +584,7 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
  
          @Override
          public void c() {
diff --git a/Spigot-Server-Patches/0432-Be-more-tolerant-of-invalid-attributes.patch b/Spigot-Server-Patches/0432-Be-more-tolerant-of-invalid-attributes.patch
deleted file mode 100644
index 9f40d486f6..0000000000
--- a/Spigot-Server-Patches/0432-Be-more-tolerant-of-invalid-attributes.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Zach Brown <zach@zachbr.io>
-Date: Thu, 6 Feb 2020 19:20:27 -0600
-Subject: [PATCH] Be more tolerant of invalid attributes
-
-Prior to this commit, the player would be disconnected if they ever encountered an attribute with a name that did
-not match Bukkit's expected vanilla scheme. It appears that datapacks can set whatever attribute name they want,
-ignoring vanilla's typical scheme.
-
-In a more perfect world the API would expose some way to interact with these attributes, however Bukkit is not
-particularly flexible in this area. Perhaps this is an area for future expansion at a later time.
-
-diff --git a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java
-index 77e584b129ab21959b7c33ac45e5841935e86ac8..007d28b16ce16295c7d398c09557b8c0777657c6 100644
---- a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java
-+++ b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java
-@@ -47,6 +47,12 @@ public class CraftAttributeMap implements Attributable {
-     public static Attribute fromMinecraft(String nms) {
-         String[] split = nms.split("\\.", 2);
- 
-+        // Paper start - Datapacks can set their own attributes that may not match our expectations, ignore them
-+        if (split.length != 2) {
-+            return null;
-+        }
-+        // Paper end
-+
-         String generic = split[0];
-         String descriptor = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, split[1]); // movementSpeed -> MOVEMENT_SPEED
-         String fin = generic + "_" + descriptor;
diff --git a/Spigot-Server-Patches/0452-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch b/Spigot-Server-Patches/0432-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch
similarity index 81%
rename from Spigot-Server-Patches/0452-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch
rename to Spigot-Server-Patches/0432-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch
index 8c7cd4a030..ff50f90ba8 100644
--- a/Spigot-Server-Patches/0452-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch
+++ b/Spigot-Server-Patches/0432-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch
@@ -7,10 +7,10 @@ Suspected case would be around the technique used in .stopRiding
 Stack will identify any causer of this and warn instead of crashing.
 
 diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
-index 4ba661c5a89bebe29c8802387bc93c10094b7606..6a2cf0c6f649e7a74b58fc292f57a08c0663b0a4 100644
+index fe3aab87de4e1eb60b19352499790fd9b571e169..c9be4ae99458863bf91687c3667d67bc6b37b0f0 100644
 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
 +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
-@@ -1411,6 +1411,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -1442,6 +1442,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
  
      protected void addEntity(Entity entity) {
          org.spigotmc.AsyncCatcher.catchOp("entity track"); // Spigot
@@ -23,13 +23,13 @@ index 4ba661c5a89bebe29c8802387bc93c10094b7606..6a2cf0c6f649e7a74b58fc292f57a08c
 +        }
 +        // Paper end
          if (!(entity instanceof EntityComplexPart)) {
-             if (!(entity instanceof EntityLightning)) {
-                 EntityTypes<?> entitytypes = entity.getEntityType();
+             EntityTypes<?> entitytypes = entity.getEntityType();
+             int i = entitytypes.getChunkRange() * 16;
 diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
-index 68c7c243a6d12d5c2f1045dfc5dd36f455dfbffa..dfc9f4d5738b01e3f80af8f3d25aec51b6e9d8d9 100644
+index f792ff541793855d9ed0b60f5990b6fdfa303995..2609ae63556053adccdce19677d2e52aaab4ebf6 100644
 --- a/src/main/java/net/minecraft/server/WorldServer.java
 +++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -1463,7 +1463,7 @@ public class WorldServer extends World {
+@@ -1353,7 +1353,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
                  }
              }
  
@@ -38,7 +38,7 @@ index 68c7c243a6d12d5c2f1045dfc5dd36f455dfbffa..dfc9f4d5738b01e3f80af8f3d25aec51
              // CraftBukkit start - SPIGOT-5278
              if (entity instanceof EntityDrowned) {
                  this.navigators.add(((EntityDrowned) entity).navigationWater);
-@@ -1474,6 +1474,7 @@ public class WorldServer extends World {
+@@ -1364,6 +1364,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
                  this.navigators.add(((EntityInsentient) entity).getNavigation());
              }
              entity.valid = true; // CraftBukkit
diff --git a/Spigot-Server-Patches/0439-Backport-fix-for-MC-167561.patch b/Spigot-Server-Patches/0439-Backport-fix-for-MC-167561.patch
deleted file mode 100644
index 3a93a0a388..0000000000
--- a/Spigot-Server-Patches/0439-Backport-fix-for-MC-167561.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Shane Freeder <theboyetronic@gmail.com>
-Date: Fri, 21 Feb 2020 18:44:28 +0000
-Subject: [PATCH] Backport fix for MC-167561
-
-
-diff --git a/src/main/java/net/minecraft/server/EntityWolf.java b/src/main/java/net/minecraft/server/EntityWolf.java
-index db15d5e0a23c414742ac73785d29aeadd432d3d7..eec1e26b6eba07c31d251ecf69dc36199688110e 100644
---- a/src/main/java/net/minecraft/server/EntityWolf.java
-+++ b/src/main/java/net/minecraft/server/EntityWolf.java
-@@ -296,7 +296,14 @@ public class EntityWolf extends EntityTameableAnimal {
-                     boolean flag = super.a(entityhuman, enumhand);
- 
-                     if (!flag || this.isBaby()) {
--                        this.goalSit.setSitting(!this.isSitting());
-+                        //this.goalSit.setSitting(!this.isSitting()); // Paper start - copied from below
-+                        if (this.i((EntityLiving) entityhuman) && !this.i(itemstack)) {
-+                            this.goalSit.setSitting(!this.isSitting());
-+                            this.jumping = false;
-+                            this.navigation.o();
-+                            this.setGoalTarget((EntityLiving) null, TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason
-+                        }
-+                        // Paper end - copied from below
-                     }
- 
-                     return flag;
-@@ -313,12 +320,14 @@ public class EntityWolf extends EntityTameableAnimal {
-                     return true;
-                 }
- 
-+                /* Paper start - Move into above
-                 if (this.i((EntityLiving) entityhuman) && !this.i(itemstack)) {
-                     this.goalSit.setSitting(!this.isSitting());
-                     this.jumping = false;
-                     this.navigation.o();
-                     this.setGoalTarget((EntityLiving) null, TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason
-                 }
-+                 */ // Paper end
-             } else if (item == Items.BONE && !this.isAngry()) {
-                 if (!entityhuman.abilities.canInstantlyBuild) {
-                     itemstack.subtract(1);
diff --git a/Spigot-Server-Patches/0383-Use-ChunkStatus-cache-when-saving-protochunks.patch b/removed/1.16/0383-Use-ChunkStatus-cache-when-saving-protochunks.patch
similarity index 100%
rename from Spigot-Server-Patches/0383-Use-ChunkStatus-cache-when-saving-protochunks.patch
rename to removed/1.16/0383-Use-ChunkStatus-cache-when-saving-protochunks.patch
diff --git a/Spigot-Server-Patches/0412-Fix-spawn-radius-being-treated-as-0.patch b/removed/1.16/0412-Fix-spawn-radius-being-treated-as-0.patch
similarity index 98%
rename from Spigot-Server-Patches/0412-Fix-spawn-radius-being-treated-as-0.patch
rename to removed/1.16/0412-Fix-spawn-radius-being-treated-as-0.patch
index d5fd1f08cb..7f6c706c69 100644
--- a/Spigot-Server-Patches/0412-Fix-spawn-radius-being-treated-as-0.patch
+++ b/removed/1.16/0412-Fix-spawn-radius-being-treated-as-0.patch
@@ -4,6 +4,8 @@ Date: Sun, 15 Dec 2019 19:41:28 +0000
 Subject: [PATCH] Fix spawn radius being treated as 0
 
 
+Not needed anymore?
+
 diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
 index 81f00141776a1767b907d14ef04f60b576110128..86bbbbaefca9ace5327d8bc2456939eb9ae8966a 100644
 --- a/src/main/java/net/minecraft/server/EntityPlayer.java
diff --git a/Spigot-Server-Patches/0429-Seed-based-feature-search.patch b/removed/1.16/0429-Seed-based-feature-search.patch
similarity index 100%
rename from Spigot-Server-Patches/0429-Seed-based-feature-search.patch
rename to removed/1.16/0429-Seed-based-feature-search.patch
diff --git a/scripts/importmcdev.sh b/scripts/importmcdev.sh
index 6fd55da94e..06ad7ab9b9 100755
--- a/scripts/importmcdev.sh
+++ b/scripts/importmcdev.sh
@@ -94,7 +94,7 @@ done
 
 # import FileName
 
-
+import VoxelShapeSpliterator
 
 ########################################################
 ########################################################