diff --git a/patches/api/Add-setMaxPlayers-API.patch b/patches/api/Add-setMaxPlayers-API.patch
deleted file mode 100644
index 4fe279ad35..0000000000
--- a/patches/api/Add-setMaxPlayers-API.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Mariell Hoversholm <proximyst@proximyst.com>
-Date: Sat, 22 Aug 2020 23:59:25 +0200
-Subject: [PATCH] Add #setMaxPlayers API
-
-
-diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/Bukkit.java
-+++ b/src/main/java/org/bukkit/Bukkit.java
-@@ -0,0 +0,0 @@ public final class Bukkit {
-         return server.getMaxPlayers();
-     }
- 
-+    // Paper start
-+    /**
-+     * Set the maximum amount of players which can login to this server.
-+     *
-+     * @param maxPlayers the amount of players this server allows
-+     */
-+    public static void setMaxPlayers(int maxPlayers) {
-+        server.setMaxPlayers(maxPlayers);
-+    }
-+    // Paper end
-+
-     /**
-      * Get the game port that the server runs on.
-      *
-diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/Server.java
-+++ b/src/main/java/org/bukkit/Server.java
-@@ -0,0 +0,0 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
-      */
-     public int getMaxPlayers();
- 
-+    // Paper start
-+    /**
-+     * Set the maximum amount of players which can login to this server.
-+     *
-+     * @param maxPlayers the amount of players this server allows
-+     */
-+    public void setMaxPlayers(int maxPlayers);
-+    // Paper end
-+
-     /**
-      * Get the game port that the server runs on.
-      *
diff --git a/patches/api/Adventure.patch b/patches/api/Adventure.patch
index 5dbaa509dd..d695b2afc1 100644
--- a/patches/api/Adventure.patch
+++ b/patches/api/Adventure.patch
@@ -928,6 +928,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @NotNull public static net.kyori.adventure.text.Component motd() {
 +        return server.motd();
 +    }
++
++    /**
++     * Set the message that is displayed on the server list.
++     *
++     * @param motd The message to be displayed
++     */
++    public static void motd(final net.kyori.adventure.text.@NotNull Component motd) {
++        server.motd(motd);
++    }
++
++    /**
++     * Gets the default message that is displayed when the server is stopped.
++     *
++     * @return the shutdown message
++     */
++    public static net.kyori.adventure.text.@Nullable Component shutdownMessage() {
++        return server.shutdownMessage();
++    }
 +    // Paper end
 +
      /**
@@ -941,18 +959,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public static String getMotd() {
          return server.getMotd();
      }
- 
-+    // Paper start
-+    /**
-+     * Gets the default message that is displayed when the server is stopped.
-+     *
-+     * @return the shutdown message
-+     */
-+    public static net.kyori.adventure.text.@Nullable Component shutdownMessage() {
-+        return server.shutdownMessage();
-+    }
-+    // Paper end
-     /**
+@@ -0,0 +0,0 @@ public final class Bukkit {
+      * Set the message that is displayed on the server list.
+      *
+      * @param motd The message to be displayed
++     * @deprecated in favour of {@link #motd(net.kyori.adventure.text.Component)}
+      */
++    @Deprecated // Paper
+     public static void setMotd(@NotNull String motd) {
+         server.setMotd(motd);
+     }
+@@ -0,0 +0,0 @@ public final class Bukkit {
       * Gets the default message that is displayed when the server is stopped.
       *
       * @return the shutdown message
@@ -1209,16 +1226,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      Inventory createInventory(@Nullable InventoryHolder owner, @NotNull InventoryType type);
  
 +    // Paper start
-     /**
-      * Creates an empty inventory with the specified type and title. If the type
-      * is {@link InventoryType#CHEST}, the new inventory has a size of 27;
-@@ -0,0 +0,0 @@ public interface Server extends PluginMessageRecipient {
-      * @see InventoryType#isCreatable()
-      */
-     @NotNull
-+    Inventory createInventory(@Nullable InventoryHolder owner, @NotNull InventoryType type, net.kyori.adventure.text.@NotNull Component title);
-+    // Paper end
-+
 +    /**
 +     * Creates an empty inventory with the specified type and title. If the type
 +     * is {@link InventoryType#CHEST}, the new inventory has a size of 27;
@@ -1240,15 +1247,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @return The new inventory.
 +     * @throws IllegalArgumentException if the {@link InventoryType} cannot be
 +     * viewed.
-+     * @deprecated in favour of {@link #createInventory(InventoryHolder, InventoryType, net.kyori.adventure.text.Component)}
 +     *
 +     * @see InventoryType#isCreatable()
 +     */
-+    @Deprecated // Paper
 +    @NotNull
++    Inventory createInventory(@Nullable InventoryHolder owner, @NotNull InventoryType type, net.kyori.adventure.text.@NotNull Component title);
++    // Paper end
++
+     /**
+      * Creates an empty inventory with the specified type and title. If the type
+      * is {@link InventoryType#CHEST}, the new inventory has a size of 27;
+@@ -0,0 +0,0 @@ public interface Server extends PluginMessageRecipient {
+      * @return The new inventory.
+      * @throws IllegalArgumentException if the {@link InventoryType} cannot be
+      * viewed.
++     * @deprecated in favour of {@link #createInventory(InventoryHolder, InventoryType, net.kyori.adventure.text.Component)}
+      *
+      * @see InventoryType#isCreatable()
+      */
++    @Deprecated // Paper
+     @NotNull
      Inventory createInventory(@Nullable InventoryHolder owner, @NotNull InventoryType type, @NotNull String title);
  
-     /**
 @@ -0,0 +0,0 @@ public interface Server extends PluginMessageRecipient {
      @NotNull
      Inventory createInventory(@Nullable InventoryHolder owner, int size) throws IllegalArgumentException;
@@ -1282,15 +1302,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @NotNull
      Inventory createInventory(@Nullable InventoryHolder owner, int size, @NotNull String title) throws IllegalArgumentException;
  
-+    // Paper start
-     /**
-      * Creates an empty merchant.
-      *
-@@ -0,0 +0,0 @@ public interface Server extends PluginMessageRecipient {
-      * when the merchant inventory is viewed
-      * @return a new merchant
-      */
-+    @NotNull Merchant createMerchant(net.kyori.adventure.text.@Nullable Component title);
 +    // Paper start
 +    /**
 +     * Creates an empty merchant.
@@ -1298,8 +1309,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param title the title of the corresponding merchant inventory, displayed
 +     * when the merchant inventory is viewed
 +     * @return a new merchant
-+     * @deprecated in favour of {@link #createMerchant(net.kyori.adventure.text.Component)}
 +     */
++    @NotNull Merchant createMerchant(net.kyori.adventure.text.@Nullable Component title);
++    // Paper start
+     /**
+      * Creates an empty merchant.
+      *
+      * @param title the title of the corresponding merchant inventory, displayed
+      * when the merchant inventory is viewed
+      * @return a new merchant
++     * @deprecated in favour of {@link #createMerchant(net.kyori.adventure.text.Component)}
+      */
      @NotNull
 +    @Deprecated // Paper
      Merchant createMerchant(@Nullable String title);
@@ -1316,6 +1336,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @return the server's MOTD
 +     */
 +    net.kyori.adventure.text.@NotNull Component motd();
++
++    /**
++     * Set the message that is displayed on the server list.
++     *
++     * @param motd The message to be displayed
++     */
++    void motd(final net.kyori.adventure.text.@NotNull Component motd);
++
++    /**
++     * Gets the default message that is displayed when the server is stopped.
++     *
++     * @return the shutdown message
++     */
++    net.kyori.adventure.text.@Nullable Component shutdownMessage();
 +    // Paper end
 +
      /**
@@ -1328,14 +1362,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      String getMotd();
  
-+    // Paper start
-+    /**
-+     * Gets the default message that is displayed when the server is stopped.
-+     *
-+     * @return the shutdown message
-+     */
-+    net.kyori.adventure.text.@Nullable Component shutdownMessage();
-+    // Paper end
+     /**
+      * Set the message that is displayed on the server list.
+      *
+      * @param motd The message to be displayed
++     * @deprecated in favour of {@link #motd(net.kyori.adventure.text.Component)}
+      */
++    @Deprecated // Paper
+     void setMotd(@NotNull String motd);
+ 
      /**
       * Gets the default message that is displayed when the server is stopped.
       *
diff --git a/patches/api/Mob-Spawner-API-Enhancements.patch b/patches/api/Mob-Spawner-API-Enhancements.patch
index 5aa9cb0654..94a30adb9f 100644
--- a/patches/api/Mob-Spawner-API-Enhancements.patch
+++ b/patches/api/Mob-Spawner-API-Enhancements.patch
@@ -36,6 +36,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param itemStack The item to spawn. Must not {@link org.bukkit.Material#isAir be air}.
 +     * @see #setSpawnedType(EntityType)
 +     */
-+    void setSpawnedItem(@NotNull org.bukkit.inventory.ItemStack itemStack);
++    void setSpawnedItem(org.bukkit.inventory.@org.jetbrains.annotations.NotNull ItemStack itemStack);
 +    // Paper end
  }
diff --git a/patches/server/Add-a-consumer-parameter-to-ProjectileSource-launchP.patch b/patches/server/Add-a-consumer-parameter-to-ProjectileSource-launchP.patch
index c1ab1466ec..36e4a3cc13 100644
--- a/patches/server/Add-a-consumer-parameter-to-ProjectileSource-launchP.patch
+++ b/patches/server/Add-a-consumer-parameter-to-ProjectileSource-launchP.patch
@@ -52,7 +52,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Override
 +    public <T extends Projectile> T launchProjectile(Class<? extends T> projectile, Vector velocity, org.bukkit.util.Consumer<T> function) {
 +        // Paper end - launchProjectile consumer
-         Validate.isTrue(this.getBlock().getType() == Material.DISPENSER, "Block is no longer dispenser");
+         Preconditions.checkArgument(this.getBlock().getType() == Material.DISPENSER, "Block is no longer dispenser");
          // Copied from BlockDispenser.dispense()
          BlockSourceImpl isourceblock = new BlockSourceImpl((ServerLevel) this.dispenserBlock.getLevel(), this.dispenserBlock.getBlockPos());
 @@ -0,0 +0,0 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
diff --git a/patches/server/Add-exception-reporting-event.patch b/patches/server/Add-exception-reporting-event.patch
index 07fc343b0f..b23a9b799c 100644
--- a/patches/server/Add-exception-reporting-event.patch
+++ b/patches/server/Add-exception-reporting-event.patch
@@ -195,22 +195,12 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
 +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
-@@ -0,0 +0,0 @@ import java.util.concurrent.atomic.AtomicReference;
- import java.util.function.Consumer;
- import java.util.function.IntUnaryOperator;
- import java.util.logging.Level;
-+import com.destroystokyo.paper.ServerSchedulerReportingWrapper;
-+import com.destroystokyo.paper.event.server.ServerExceptionEvent;
-+import com.destroystokyo.paper.exception.ServerSchedulerException;
- import org.apache.commons.lang.Validate;
- import org.bukkit.plugin.IllegalPluginAccessException;
- import org.bukkit.plugin.Plugin;
 @@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
                              msg,
                              throwable);
                      }
 +                    org.bukkit.Bukkit.getServer().getPluginManager().callEvent(
-+                        new ServerExceptionEvent(new ServerSchedulerException(msg, throwable, task)));
++                        new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerSchedulerException(msg, throwable, task)));
                      // Paper end
                  } finally {
                      this.currentTask = null;
@@ -219,7 +209,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              } else {
                  this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass()));
 -                this.executor.execute(task);
-+                this.executor.execute(new ServerSchedulerReportingWrapper(task)); // Paper
++                this.executor.execute(new com.destroystokyo.paper.ServerSchedulerReportingWrapper(task)); // Paper
                  // We don't need to parse pending
                  // (async tasks must live with race-conditions if they attempt to cancel between these few lines of code)
              }
diff --git a/patches/server/Add-getMainThreadExecutor-to-BukkitScheduler.patch b/patches/server/Add-getMainThreadExecutor-to-BukkitScheduler.patch
index 0515cea2e3..e430f9c838 100644
--- a/patches/server/Add-getMainThreadExecutor-to-BukkitScheduler.patch
+++ b/patches/server/Add-getMainThreadExecutor-to-BukkitScheduler.patch
@@ -16,9 +16,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    // Paper start - add getMainThreadExecutor
 +    @Override
 +    public Executor getMainThreadExecutor(Plugin plugin) {
-+        Validate.notNull(plugin, "Plugin cannot be null");
++        Preconditions.checkArgument(plugin != null, "Plugin cannot be null");
 +        return command -> {
-+            Validate.notNull(command, "Command cannot be null");
++            Preconditions.checkArgument(command != null, "Command cannot be null");
 +            this.runTask(plugin, command);
 +        };
 +    }
diff --git a/patches/server/Add-getOfflinePlayerIfCached-String.patch b/patches/server/Add-getOfflinePlayerIfCached-String.patch
index 3783e2967d..184d1f5a98 100644
--- a/patches/server/Add-getOfflinePlayerIfCached-String.patch
+++ b/patches/server/Add-getOfflinePlayerIfCached-String.patch
@@ -16,8 +16,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Override
 +    @Nullable
 +    public OfflinePlayer getOfflinePlayerIfCached(String name) {
-+        Validate.notNull(name, "Name cannot be null");
-+        Validate.notEmpty(name, "Name cannot be empty");
++        Preconditions.checkArgument(name != null, "Name cannot be null");
++        Preconditions.checkArgument(!name.isEmpty(), "Name cannot be empty");
 +
 +        OfflinePlayer result = getPlayerExact(name);
 +        if (result == null) {
@@ -36,4 +36,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
      @Override
      public OfflinePlayer getOfflinePlayer(UUID id) {
-         Validate.notNull(id, "UUID cannot be null");
+         Preconditions.checkArgument(id != null, "UUID id cannot be null");
diff --git a/patches/server/Add-isCollidable-methods-to-various-places.patch b/patches/server/Add-isCollidable-methods-to-various-places.patch
index f90963e6f3..3d614c84fe 100644
--- a/patches/server/Add-isCollidable-methods-to-various-places.patch
+++ b/patches/server/Add-isCollidable-methods-to-various-places.patch
@@ -27,8 +27,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
 +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
 @@ -0,0 +0,0 @@ public class CraftBlockState implements BlockState {
-             throw new IllegalStateException("The blockState must be placed to call this method");
-         }
+     protected void requirePlaced() {
+         Preconditions.checkState(this.isPlaced(), "The blockState must be placed to call this method");
      }
 +
 +    // Paper start
diff --git a/patches/server/Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch b/patches/server/Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch
index 9e2ad69182..b2bb16996a 100644
--- a/patches/server/Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch
+++ b/patches/server/Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch
@@ -13,8 +13,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
      public int getSpawnLimit(SpawnCategory spawnCategory) {
          // Paper start
-+        Validate.notNull(spawnCategory, "SpawnCategory cannot be null");
-+        Validate.isTrue(CraftSpawnCategory.isValidForLimits(spawnCategory), "SpawnCategory." + spawnCategory + " does not have a spawn limit.");
++        Preconditions.checkArgument(spawnCategory != null, "SpawnCategory cannot be null");
++        Preconditions.checkArgument(CraftSpawnCategory.isValidForLimits(spawnCategory), "SpawnCategory." + spawnCategory + " does not have a spawn limit.");
          return this.getSpawnLimitUnsafe(spawnCategory);
      }
      public int getSpawnLimitUnsafe(final SpawnCategory spawnCategory) {
diff --git a/patches/server/Add-new-overload-to-PersistentDataContainer-has.patch b/patches/server/Add-new-overload-to-PersistentDataContainer-has.patch
index 454cacd912..7721b27e0e 100644
--- a/patches/server/Add-new-overload-to-PersistentDataContainer-has.patch
+++ b/patches/server/Add-new-overload-to-PersistentDataContainer-has.patch
@@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    @Override
 +    public boolean has(NamespacedKey key) {
-+        Validate.notNull(key, "The provided key for the custom value was null");
++        Preconditions.checkArgument(key != null, "The provided key for the custom value was null");
 +
 +        return this.customDataTags.containsKey(key.toString());
 +    }
diff --git a/patches/server/Add-paper-mobcaps-and-paper-playermobcaps.patch b/patches/server/Add-paper-mobcaps-and-paper-playermobcaps.patch
index 6a84a75e15..d3446f38ad 100644
--- a/patches/server/Add-paper-mobcaps-and-paper-playermobcaps.patch
+++ b/patches/server/Add-paper-mobcaps-and-paper-playermobcaps.patch
@@ -298,8 +298,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
 +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
 @@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
-         Validate.notNull(spawnCategory, "SpawnCategory cannot be null");
-         Validate.isTrue(CraftSpawnCategory.isValidForLimits(spawnCategory), "SpawnCategory." + spawnCategory + " are not supported.");
+         Preconditions.checkArgument(spawnCategory != null, "SpawnCategory cannot be null");
+         Preconditions.checkArgument(CraftSpawnCategory.isValidForLimits(spawnCategory), "SpawnCategory.%s are not supported", spawnCategory);
  
 +        // Paper start
 +        return this.getSpawnLimitUnsafe(spawnCategory);
diff --git a/patches/server/Add-setMaxPlayers-API.patch b/patches/server/Add-setMaxPlayers-API.patch
deleted file mode 100644
index eeb70e2464..0000000000
--- a/patches/server/Add-setMaxPlayers-API.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Mariell Hoversholm <proximyst@proximyst.com>
-Date: Sat, 22 Aug 2020 23:59:30 +0200
-Subject: [PATCH] Add #setMaxPlayers API
-
-
-diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/players/PlayerList.java
-+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -0,0 +0,0 @@ public abstract class PlayerList {
-     private boolean doWhiteList;
-     private final LayeredRegistryAccess<RegistryLayer> registries;
-     private final RegistryAccess.Frozen synchronizedRegistries;
--    protected final int maxPlayers;
-+    protected int maxPlayers; public final void setMaxPlayers(int maxPlayers) { this.maxPlayers = maxPlayers; } // Paper - remove final and add setter
-     private int viewDistance;
-     private int simulationDistance;
-     private boolean allowCheatsForAllPlayers;
-diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
-         return this.playerList.getMaxPlayers();
-     }
- 
-+    // Paper start
-+    @Override
-+    public void setMaxPlayers(int maxPlayers) {
-+        this.playerList.setMaxPlayers(maxPlayers);
-+    }
-+    // Paper end
-+
-     // NOTE: These are dependent on the corresponding call in MinecraftServer
-     // so if that changes this will need to as well
-     @Override
diff --git a/patches/server/Add-tick-times-API-and-mspt-command.patch b/patches/server/Add-tick-times-API-and-mspt-command.patch
index 0ccb68b609..d76a0be26a 100644
--- a/patches/server/Add-tick-times-API-and-mspt-command.patch
+++ b/patches/server/Add-tick-times-API-and-mspt-command.patch
@@ -129,7 +129,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/net/minecraft/server/MinecraftServer.java
 +++ b/src/main/java/net/minecraft/server/MinecraftServer.java
 @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
-     @Nullable private net.kyori.adventure.text.Component cachedMotd; // Paper
+     private net.kyori.adventure.text.Component motd; // Paper - Adventure
      private int playerIdleTimeout;
      public final long[] tickTimes;
 +    // Paper start
diff --git a/patches/server/Adventure.patch b/patches/server/Adventure.patch
index a36b17bfe7..d8818edb91 100644
--- a/patches/server/Adventure.patch
+++ b/patches/server/Adventure.patch
@@ -2181,13 +2181,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      private static final float AVERAGE_TICK_TIME_SMOOTHING = 0.8F;
      private static final int TICK_STATS_SPAN = 100;
 @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+     private boolean preventProxyConnections;
+     private boolean pvp;
      private boolean allowFlight;
-     @Nullable
-     private String motd;
-+    @Nullable private net.kyori.adventure.text.Component cachedMotd; // Paper
+-    @Nullable
+-    private String motd;
++    private net.kyori.adventure.text.Component motd; // Paper - Adventure
      private int playerIdleTimeout;
      public final long[] tickTimes;
      @Nullable
+@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+     private ServerStatus buildServerStatus() {
+         ServerStatus.Players serverping_serverpingplayersample = this.buildPlayerStatus();
+ 
+-        return new ServerStatus(Component.nullToEmpty(this.motd), Optional.of(serverping_serverpingplayersample), Optional.of(ServerStatus.Version.current()), Optional.ofNullable(this.statusIcon), this.enforceSecureProfile());
++        return new ServerStatus(io.papermc.paper.adventure.PaperAdventure.asVanilla(this.motd), Optional.of(serverping_serverpingplayersample), Optional.of(ServerStatus.Version.current()), Optional.ofNullable(this.statusIcon), this.enforceSecureProfile()); // Paper - Adventure
+     }
+ 
+     private ServerStatus.Players buildPlayerStatus() {
 @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
          SpigotTimings.schedulerTimer.startTiming(); // Spigot
          this.server.getScheduler().mainThreadHeartbeat(this.tickCount); // CraftBukkit
@@ -2197,24 +2208,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          SpigotTimings.commandFunctionsTimer.startTiming(); // Spigot
          this.getFunctions().tick();
 @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
-         return this.motd;
+     public abstract boolean isCommandBlockEnabled();
+ 
+     public String getMotd() {
+-        return this.motd;
++        return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.motd); // Paper - Adventure
      }
  
-+    public net.kyori.adventure.text.Component getComponentMotd() {
-+        net.kyori.adventure.text.Component component = cachedMotd;
-+        if (this.motd != null && this.cachedMotd == null) {
-+            component = cachedMotd = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(this.motd);
-+        }
-+
-+        return component != null ? component : net.kyori.adventure.text.Component.empty();
+     public void setMotd(String motd) {
++        // Paper start - Adventure
++        this.motd = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserializeOr(motd, net.kyori.adventure.text.Component.empty());
 +    }
 +
-     public void setMotd(String motd) {
++    public net.kyori.adventure.text.Component motd() {
++        return this.motd;
++    }
++
++    public void motd(net.kyori.adventure.text.Component motd) {
++        // Paper end - Adventure
          this.motd = motd;
-+        this.cachedMotd = null; // Paper
      }
  
-     public boolean isStopped() {
 @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
      }
  
@@ -2937,14 +2951,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    // Paper start
 +    @Override
 +    public Inventory createInventory(InventoryHolder owner, InventoryType type, net.kyori.adventure.text.Component title) {
-+        Validate.isTrue(type.isCreatable(), "Cannot open an inventory of type ", type);
++        Preconditions.checkArgument(type.isCreatable(), "Cannot open an inventory of type ", type);
 +        return CraftInventoryCreator.INSTANCE.createInventory(owner, type, title);
 +    }
 +    // Paper end
 +
      @Override
      public Inventory createInventory(InventoryHolder owner, InventoryType type, String title) {
-         Validate.isTrue(type.isCreatable(), "Cannot open an inventory of type ", type);
+         Preconditions.checkArgument(type != null, "InventoryType cannot be null");
 @@ -0,0 +0,0 @@ public final class CraftServer implements Server {
          return CraftInventoryCreator.INSTANCE.createInventory(owner, size);
      }
@@ -2952,14 +2966,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    // Paper start
 +    @Override
 +    public Inventory createInventory(InventoryHolder owner, int size, net.kyori.adventure.text.Component title) throws IllegalArgumentException {
-+        Validate.isTrue(9 <= size && size <= 54 && size % 9 == 0, "Size for custom inventory must be a multiple of 9 between 9 and 54 slots (got " + size + ")");
++        Preconditions.checkArgument(9 <= size && size <= 54 && size % 9 == 0, "Size for custom inventory must be a multiple of 9 between 9 and 54 slots (got " + size + ")");
 +        return CraftInventoryCreator.INSTANCE.createInventory(owner, size, title);
 +    }
 +    // Paper end
 +
      @Override
      public Inventory createInventory(InventoryHolder owner, int size, String title) throws IllegalArgumentException {
-         Validate.isTrue(9 <= size && size <= 54 && size % 9 == 0, "Size for custom inventory must be a multiple of 9 between 9 and 54 slots (got " + size + ")");
+         Preconditions.checkArgument(9 <= size && size <= 54 && size % 9 == 0, "Size for custom inventory must be a multiple of 9 between 9 and 54 slots (got %s)", size);
          return CraftInventoryCreator.INSTANCE.createInventory(owner, size, title);
      }
  
@@ -2978,12 +2992,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          return Thread.currentThread().equals(console.serverThread) || this.console.hasStopped() || !org.spigotmc.AsyncCatcher.enabled; // All bets are off if we have shut down (e.g. due to watchdog)
      }
  
-+    // Paper start
++    // Paper start - Adventure
 +    @Override
 +    public net.kyori.adventure.text.Component motd() {
-+        return console.getComponentMotd();
++        return this.console.motd();
++    }
++    @Override
++    public void motd(final net.kyori.adventure.text.Component motd) {
++        this.console.motd(motd);
 +    }
 +    // Paper end
++
      @Override
      public String getMotd() {
          return this.console.getMotd();
@@ -3750,7 +3769,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
      @Override
      public void setCompassTarget(Location loc) {
-         if (this.getHandle().connection == null) return;
+         Preconditions.checkArgument(loc != null, "Location cannot be null");
 @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
          this.getHandle().connection.send(packet);
      }
@@ -3764,8 +3783,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        if (lines == null) {
 +            lines = new java.util.ArrayList<>(4);
 +        }
-+        Validate.notNull(loc, "Location cannot be null");
-+        Validate.notNull(dyeColor, "DyeColor cannot be null");
++        Preconditions.checkArgument(loc != null, "Location cannot be null");
++        Preconditions.checkArgument(dyeColor != null, "DyeColor cannot be null");
 +        if (lines.size() < 4) {
 +            throw new IllegalArgumentException("Must have at least 4 lines");
 +        }
@@ -3777,7 +3796,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public void sendSignChange(Location loc, String[] lines) {
          this.sendSignChange(loc, lines, DyeColor.BLACK);
 @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
-         }
+         if (this.getHandle().connection == null) return;
  
          Component[] components = CraftSign.sanitizeLines(lines);
 +        // Paper start - adventure
@@ -3823,10 +3842,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    // Paper start
 +    @Override
 +    public void setResourcePack(String url, byte[] hashBytes, net.kyori.adventure.text.Component prompt, boolean force) {
-+        Validate.notNull(url, "Resource pack URL cannot be null");
++        Preconditions.checkArgument(url != null, "Resource pack URL cannot be null");
 +        final String hash;
 +        if (hashBytes != null) {
-+            Validate.isTrue(hashBytes.length == 20, "Resource pack hash should be 20 bytes long but was " + hashBytes.length);
++            Preconditions.checkArgument(hashBytes.length == 20, "Resource pack hash should be 20 bytes long but was " + hashBytes.length);
 +            hash = BaseEncoding.base16().lowerCase().encode(hashBytes);
 +        } else {
 +            hash = "";
@@ -4218,7 +4237,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              this(owner, type.getDefaultSize(), type.getDefaultTitle());
              this.type = type;
 @@ -0,0 +0,0 @@ public class CraftInventoryCustom extends CraftInventory {
-             Validate.notNull(title, "Title cannot be null");
+             Preconditions.checkArgument(title != null, "title cannot be null");
              this.items = NonNullList.withSize(size, ItemStack.EMPTY);
              this.title = title;
 +            this.adventure$title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(title);
@@ -4229,7 +4248,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
 +        // Paper start
 +        public MinecraftInventory(final InventoryHolder owner, final int size, final net.kyori.adventure.text.Component title) {
-+            Validate.notNull(title, "Title cannot be null");
++            Preconditions.checkArgument(title != null, "Title cannot be null");
 +            this.items = NonNullList.withSize(size, ItemStack.EMPTY);
 +            this.title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(title);
 +            this.adventure$title = title;
@@ -4323,12 +4342,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
 +        @Deprecated // Paper - Adventure
          public MinecraftMerchant(String title) {
-             Validate.notNull(title, "Title cannot be null");
+             Preconditions.checkArgument(title != null, "Title cannot be null");
              this.title = CraftChatMessage.fromString(title)[0];
          }
 +        // Paper start
 +        public MinecraftMerchant(net.kyori.adventure.text.Component title) {
-+            Validate.notNull(title, "Title cannot be null");
++            Preconditions.checkArgument(title != null, "Title cannot be null");
 +            this.title = io.papermc.paper.adventure.PaperAdventure.asVanilla(title);
 +        }
 +        // Paper end
@@ -4339,9 +4358,9 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java b
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java
 +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java
-@@ -0,0 +0,0 @@
- package org.bukkit.craftbukkit.inventory;
+@@ -0,0 +0,0 @@ package org.bukkit.craftbukkit.inventory;
  
+ import com.google.common.base.Preconditions;
  import com.google.common.collect.ImmutableList;
 -import com.google.common.collect.ImmutableMap.Builder;
  import com.google.common.collect.Lists;
@@ -4379,7 +4398,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    @Override
 +    public net.kyori.adventure.text.Component page(final int page) {
-+        Validate.isTrue(isValidPage(page), "Invalid page number");
++        Preconditions.checkArgument(isValidPage(page), "Invalid page number");
 +        return this instanceof CraftMetaBookSigned ? net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson().deserialize(pages.get(page - 1)) : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(pages.get(page - 1));
 +    }
 +
@@ -4495,7 +4514,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    // Paper end
      @Override
      public String getPage(final int page) {
-         Validate.isTrue(this.isValidPage(page), "Invalid page number");
+         Preconditions.checkArgument(this.isValidPage(page), "Invalid page number (%s)", page);
 @@ -0,0 +0,0 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta {
      }
  
@@ -4758,7 +4777,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    // Paper end
      @Override
      public String getDisplayName() throws IllegalStateException {
-         CraftScoreboard scoreboard = this.checkState();
+         this.checkState();
 diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java
@@ -4785,12 +4804,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        if (displayName == null) {
 +            displayName = net.kyori.adventure.text.Component.empty();
 +        }
-+        Validate.notNull(name, "Objective name cannot be null");
-+        Validate.notNull(criteria, "Criteria cannot be null");
-+        Validate.notNull(displayName, "Display name cannot be null");
-+        Validate.notNull(renderType, "RenderType cannot be null");
-+        Validate.isTrue(name.length() <= Short.MAX_VALUE, "The name '" + name + "' is longer than the limit of 32767 characters");
-+        Validate.isTrue(board.getObjective(name) == null, "An objective of name '" + name + "' already exists");
++        Preconditions.checkArgument(name != null, "Objective name cannot be null");
++        Preconditions.checkArgument(criteria != null, "Criteria cannot be null");
++        Preconditions.checkArgument(renderType != null, "RenderType cannot be null");
++        Preconditions.checkArgument(name.length() <= Short.MAX_VALUE, "The name '%s' is longer than the limit of 32767 characters (%s)", name, name.length());
++        Preconditions.checkArgument(this.board.getObjective(name) == null, "An objective of name '%s' already exists", name);
 +        net.minecraft.world.scores.Objective objective = board.addObjective(name, ((CraftCriteria) criteria).criteria, io.papermc.paper.adventure.PaperAdventure.asVanilla(displayName), CraftScoreboardTranslations.fromBukkitRender(renderType));
 +        return new CraftObjective(this, objective);
 +    }
@@ -4802,13 +4820,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public CraftObjective registerNewObjective(String name, Criteria criteria, String displayName, RenderType renderType) throws IllegalArgumentException {
--        Validate.notNull(name, "Objective name cannot be null");
--        Validate.notNull(criteria, "Criteria cannot be null");
--        Validate.notNull(displayName, "Display name cannot be null");
--        Validate.notNull(renderType, "RenderType cannot be null");
--        Validate.isTrue(name.length() <= Short.MAX_VALUE, "The name '" + name + "' is longer than the limit of 32767 characters");
--        Validate.isTrue(displayName.length() <= 128, "The display name '" + displayName + "' is longer than the limit of 128 characters");
--        Validate.isTrue(this.board.getObjective(name) == null, "An objective of name '" + name + "' already exists");
+-        Preconditions.checkArgument(name != null, "Objective name cannot be null");
+-        Preconditions.checkArgument(criteria != null, "Criteria cannot be null");
+-        Preconditions.checkArgument(displayName != null, "Display name cannot be null");
+-        Preconditions.checkArgument(renderType != null, "RenderType cannot be null");
+-        Preconditions.checkArgument(name.length() <= Short.MAX_VALUE, "The name '%s' is longer than the limit of 32767 characters (%s)", name, name.length());
+-        Preconditions.checkArgument(displayName.length() <= 128, "The display name '%s' is longer than the limit of 128 characters (%s)", displayName, displayName.length());
+-        Preconditions.checkArgument(this.board.getObjective(name) == null, "An objective of name '%s' already exists", name);
 -
 -        net.minecraft.world.scores.Objective objective = this.board.addObjective(name, ((CraftCriteria) criteria).criteria, CraftChatMessage.fromStringOrNull(displayName), CraftScoreboardTranslations.fromBukkitRender(renderType));
 -        return new CraftObjective(this, objective);
@@ -4967,9 +4985,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
 -    HashSet<Player> makeReference() {
 +    protected HashSet<Player> makeReference() { // Paper - protected
-         if (reference != null) {
-             throw new IllegalStateException("Reference already created!");
-         }
+         Preconditions.checkState(reference == null, "Reference already created!");
          List<ServerPlayer> players = this.server.getPlayerList().players;
 +        // Paper start
 +        return makePlayerSet(this.server);
diff --git a/patches/server/Anti-Xray.patch b/patches/server/Anti-Xray.patch
index 98300adcc2..b4b6e5f001 100644
--- a/patches/server/Anti-Xray.patch
+++ b/patches/server/Anti-Xray.patch
@@ -1578,7 +1578,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
 @@ -0,0 +0,0 @@ public final class CraftServer implements Server {
      public ChunkGenerator.ChunkData createChunkData(World world) {
-         Validate.notNull(world, "World cannot be null");
+         Preconditions.checkArgument(world != null, "World cannot be null");
          ServerLevel handle = ((CraftWorld) world).getHandle();
 -        return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(Registries.BIOME));
 +        return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(Registries.BIOME), world); // Paper - Anti-Xray - Add parameters
diff --git a/patches/server/Be-a-bit-more-informative-in-maxHealth-exception.patch b/patches/server/Be-a-bit-more-informative-in-maxHealth-exception.patch
index d276f706d4..a1cd38131d 100644
--- a/patches/server/Be-a-bit-more-informative-in-maxHealth-exception.patch
+++ b/patches/server/Be-a-bit-more-informative-in-maxHealth-exception.patch
@@ -9,14 +9,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
 +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
 @@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
+     @Override
      public void setHealth(double health) {
          health = (float) health;
-         if ((health < 0) || (health > this.getMaxHealth())) {
--            throw new IllegalArgumentException("Health must be between 0 and " + this.getMaxHealth() + "(" + health + ")");
-+            // Paper - Be more informative
-+            throw new IllegalArgumentException("Health must be between 0 and " + getMaxHealth() + ", but was " + health
-+                + ". (attribute base value: " + this.getHandle().getAttribute(Attributes.MAX_HEALTH).getBaseValue()
-+                + (this instanceof CraftPlayer ? ", player: " + this.getName() + ')' : ')'));
-         }
+-        Preconditions.checkArgument(health >= 0 && health <= this.getMaxHealth(), "Health value (%s) must be between 0 and %s", health, this.getMaxHealth());
++        // Paper start - Be more informative
++        Preconditions.checkArgument(health >= 0 && health <= this.getMaxHealth(),
++            "Health value (%s) must be between 0 and %s. (attribute base value: %s%s)",
++            health, this.getMaxHealth(), this.getHandle().getAttribute(Attributes.MAX_HEALTH).getBaseValue(), this instanceof CraftPlayer ? ", player: " + this.getName() : ""
++        );
++        // Paper end
  
          // during world generation, we don't want to run logic for dropping items and xp
+         if (this.getHandle().generation && health == 0) {
diff --git a/patches/server/CB-fixes.patch b/patches/server/CB-fixes.patch
index 51a8cb2ea3..b002f67081 100644
--- a/patches/server/CB-fixes.patch
+++ b/patches/server/CB-fixes.patch
@@ -87,7 +87,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
 +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
 @@ -0,0 +0,0 @@ public final class CraftServer implements Server {
-         Validate.notNull(key, "NamespacedKey cannot be null");
+         Preconditions.checkArgument(key != null, "NamespacedKey key cannot be null");
  
          LootDataManager registry = this.getServer().getLootData();
 -        return new CraftLootTable(key, registry.getLootTable(CraftNamespacedKey.toMinecraft(key)));
diff --git a/patches/server/Complete-resource-pack-API.patch b/patches/server/Complete-resource-pack-API.patch
index 8dd5f910b7..5abbbc8202 100644
--- a/patches/server/Complete-resource-pack-API.patch
+++ b/patches/server/Complete-resource-pack-API.patch
@@ -54,8 +54,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    @Override
 +    public void setResourcePack(@NotNull String url, @NotNull String hash, boolean required, net.kyori.adventure.text.Component resourcePackPrompt) {
-+        Validate.notNull(url, "Resource pack URL cannot be null");
-+        Validate.notNull(hash, "Hash cannot be null");
++        Preconditions.checkArgument(url != null, "Resource pack URL cannot be null");
++        Preconditions.checkArgument(hash != null, "Hash cannot be null");
 +        net.minecraft.network.chat.Component promptComponent = resourcePackPrompt != null ?
 +                            io.papermc.paper.adventure.PaperAdventure.asVanilla(resourcePackPrompt) :
 +                           null;
diff --git a/patches/server/Ensure-commands-are-not-ran-async.patch b/patches/server/Ensure-commands-are-not-ran-async.patch
index cdab36f290..b2ed462c30 100644
--- a/patches/server/Ensure-commands-are-not-ran-async.patch
+++ b/patches/server/Ensure-commands-are-not-ran-async.patch
@@ -78,7 +78,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
 +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
 @@ -0,0 +0,0 @@ public final class CraftServer implements Server {
-         Validate.notNull(commandLine, "CommandLine cannot be null");
+         Preconditions.checkArgument(commandLine != null, "commandLine cannot be null");
          org.spigotmc.AsyncCatcher.catchOp("command dispatch"); // Spigot
  
 +        // Paper Start
@@ -111,7 +111,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
 +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
 @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
-     public void chat(String msg) {
+ 
          if (this.getHandle().connection == null) return;
  
 -        this.getHandle().connection.chat(msg, PlayerChatMessage.system(msg), false);
diff --git a/patches/server/Entity-Activation-Range-2.0.patch b/patches/server/Entity-Activation-Range-2.0.patch
index eeeebc881d..d24b803a52 100644
--- a/patches/server/Entity-Activation-Range-2.0.patch
+++ b/patches/server/Entity-Activation-Range-2.0.patch
@@ -579,7 +579,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        if (inactiveWakeUpImmunity > -1) {
 +            return inactiveWakeUpImmunity;
 +        }
-+        if (entity.remainingFireTicks > 0) {
++        if (entity.getRemainingFireTicks() > 0) {
 +            return 2;
 +        }
 +        if (entity.activatedImmunityTick >= MinecraftServer.currentTick) {
@@ -588,7 +588,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        long inactiveFor = MinecraftServer.currentTick - entity.activatedTick;
 +        // Paper end
          // quick checks.
--        if ( entity.wasTouchingWater || entity.remainingFireTicks > 0 )
+-        if ( entity.wasTouchingWater || entity.getRemainingFireTicks() > 0 )
 +        if ( (entity.activationType != ActivationType.WATER && entity.wasTouchingWater && entity.isPushedByFluid()) ) // Paper
          {
 -            return true;
diff --git a/patches/server/Entity-fromMobSpawner.patch b/patches/server/Entity-fromMobSpawner.patch
index 9699adb9d3..8208656405 100644
--- a/patches/server/Entity-fromMobSpawner.patch
+++ b/patches/server/Entity-fromMobSpawner.patch
@@ -41,13 +41,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
 +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
 @@ -0,0 +0,0 @@ public abstract class BaseSpawner {
-                             }
                              // Spigot End
                          }
+ 
 +                        entity.spawnedViaMobSpawner = true; // Paper
-                         // Spigot Start
+                         // CraftBukkit start
                          if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) {
-                             Entity vehicle = entity.getVehicle();
+                             continue;
 diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
diff --git a/patches/server/Entity-getEntitySpawnReason.patch b/patches/server/Entity-getEntitySpawnReason.patch
index 27d5f763a2..5a2eaecabf 100644
--- a/patches/server/Entity-getEntitySpawnReason.patch
+++ b/patches/server/Entity-getEntitySpawnReason.patch
@@ -100,12 +100,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
 +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
 @@ -0,0 +0,0 @@ public abstract class BaseSpawner {
-                             // Spigot End
                          }
+ 
                          entity.spawnedViaMobSpawner = true; // Paper
 +                        entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER; // Paper
                          flag = true; // Paper
-                         // Spigot Start
+                         // CraftBukkit start
                          if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) {
 diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
diff --git a/patches/server/Expand-World.spawnParticle-API-and-add-Builder.patch b/patches/server/Expand-World.spawnParticle-API-and-add-Builder.patch
index a27b1ece11..a6997032bd 100644
--- a/patches/server/Expand-World.spawnParticle-API-and-add-Builder.patch
+++ b/patches/server/Expand-World.spawnParticle-API-and-add-Builder.patch
@@ -41,13 +41,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public <T> void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) {
+-        if (data != null) {
 +        // Paper start - Particle API Expansion
 +        spawnParticle(particle, null, null, x, y, z, count, offsetX, offsetY, offsetZ, extra, data, force);
 +    }
 +    public <T> void spawnParticle(Particle particle, List<Player> receivers, Player sender, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) {
 +        // Paper end
-         if (data != null && !particle.getDataType().isInstance(data)) {
-             throw new IllegalArgumentException("data should be " + particle.getDataType() + " got " + data.getClass());
++        if (data != null && !particle.getDataType().isInstance(data)) {
+             Preconditions.checkArgument(particle.getDataType().isInstance(data), "data (%s) should be %s", data.getClass(), particle.getDataType());
          }
          this.getHandle().sendParticles(
 -                null, // Sender
diff --git a/patches/server/Expand-world-key-API.patch b/patches/server/Expand-world-key-API.patch
index 6043a6650c..eb642a04b1 100644
--- a/patches/server/Expand-world-key-API.patch
+++ b/patches/server/Expand-world-key-API.patch
@@ -39,8 +39,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          }
 +        // Paper end
  
-         if ((folder.exists()) && (!folder.isDirectory())) {
-             throw new IllegalArgumentException("File exists with the name '" + name + "' and isn't a folder");
+         if (folder.exists()) {
+             Preconditions.checkArgument(folder.isDirectory(), "File (%s) exists and isn't a folder", name);
 @@ -0,0 +0,0 @@ public final class CraftServer implements Server {
          } else if (name.equals(levelName + "_the_end")) {
              worldKey = net.minecraft.world.level.Level.END;
diff --git a/patches/server/Fix-CraftTeam-null-check.patch b/patches/server/Fix-CraftTeam-null-check.patch
deleted file mode 100644
index 8723505200..0000000000
--- a/patches/server/Fix-CraftTeam-null-check.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: foss-mc <69294560+foss-mc@users.noreply.github.com>
-Date: Sun, 30 Aug 2020 15:30:29 +0800
-Subject: [PATCH] Fix CraftTeam null check
-
-
-diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java
-+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java
-@@ -0,0 +0,0 @@ final class CraftTeam extends CraftScoreboardComponent implements Team {
- 
-     @Override
-     public boolean hasEntry(String entry) throws IllegalArgumentException, IllegalStateException {
--        Validate.notNull("Entry cannot be null");
-+        Validate.notNull(entry, "Entry cannot be null"); // Paper
- 
-         CraftScoreboard scoreboard = this.checkState();
- 
diff --git a/patches/server/Fix-Player-spawnParticle-x-y-z-precision-loss.patch b/patches/server/Fix-Player-spawnParticle-x-y-z-precision-loss.patch
index dbc58e8cfb..03fa44c9b9 100644
--- a/patches/server/Fix-Player-spawnParticle-x-y-z-precision-loss.patch
+++ b/patches/server/Fix-Player-spawnParticle-x-y-z-precision-loss.patch
@@ -9,8 +9,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
 +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
 @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
-         if (data != null && !particle.getDataType().isInstance(data)) {
-             throw new IllegalArgumentException("data should be " + particle.getDataType() + " got " + data.getClass());
+         if (data != null) {
+             Preconditions.checkArgument(particle.getDataType().isInstance(data), "data (%s) should be %s", data.getClass(), particle.getDataType());
          }
 -        ClientboundLevelParticlesPacket packetplayoutworldparticles = new ClientboundLevelParticlesPacket(CraftParticle.toNMS(particle, data), true, (float) x, (float) y, (float) z, (float) offsetX, (float) offsetY, (float) offsetZ, (float) extra, count);
 +        ClientboundLevelParticlesPacket packetplayoutworldparticles = new ClientboundLevelParticlesPacket(CraftParticle.toNMS(particle, data), true, x, y, z, (float) offsetX, (float) offsetY, (float) offsetZ, (float) extra, count); // Paper - Fix x/y/z coordinate precision loss
diff --git a/patches/server/Fix-and-optimise-world-force-upgrading.patch b/patches/server/Fix-and-optimise-world-force-upgrading.patch
index 67721102e9..971a551c06 100644
--- a/patches/server/Fix-and-optimise-world-force-upgrading.patch
+++ b/patches/server/Fix-and-optimise-world-force-upgrading.patch
@@ -366,14 +366,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
 +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
 @@ -0,0 +0,0 @@ public final class CraftServer implements Server {
-         worlddata.customDimensions = iregistry;
          worlddata.checkName(name);
          worlddata.setModdedInfo(this.console.getServerModName(), this.console.getModdedStatus().shouldReportAsModified());
--
+ 
 -        if (console.options.has("forceUpgrade")) {
--            net.minecraft.server.Main.forceUpgrade(worldSession, DataFixers.getDataFixer(), console.options.has("eraseCache"), () -> {
--                return true;
--            }, iregistry);
+-            net.minecraft.server.Main.forceUpgrade(worldSession, DataFixers.getDataFixer(), console.options.has("eraseCache"), () -> true, iregistry);
 -        }
 +        // Paper - move down
  
diff --git a/patches/server/Fix-api-checking-banned-ips.patch b/patches/server/Fix-api-checking-banned-ips.patch
index ab50cb67de..0334e1c24e 100644
--- a/patches/server/Fix-api-checking-banned-ips.patch
+++ b/patches/server/Fix-api-checking-banned-ips.patch
@@ -10,7 +10,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +++ b/src/main/java/org/bukkit/craftbukkit/CraftIpBanList.java
 @@ -0,0 +0,0 @@ public class CraftIpBanList implements org.bukkit.BanList {
      public boolean isBanned(String target) {
-         Validate.notNull(target, "Target cannot be null");
+         Preconditions.checkArgument(target != null, "Target cannot be null");
  
 -        return this.list.isBanned(InetSocketAddress.createUnresolved(target, 0));
 +        return this.list.isBanned(target); // Paper - fix checking banned ips
diff --git a/patches/server/Fix-chiseled-bookshelf-and-jukebox-setItem-with-air.patch b/patches/server/Fix-chiseled-bookshelf-and-jukebox-setItem-with-air.patch
index 627115dce1..3f36dd35f8 100644
--- a/patches/server/Fix-chiseled-bookshelf-and-jukebox-setItem-with-air.patch
+++ b/patches/server/Fix-chiseled-bookshelf-and-jukebox-setItem-with-air.patch
@@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -        if (stack.is(ItemTags.BOOKSHELF_BOOKS)) {
 +        if (stack.isEmpty() || stack.is(ItemTags.BOOKSHELF_BOOKS)) { // Paper
              this.items.set(slot, stack);
-             this.updateState(slot);
+             if (level != null) this.updateState(slot); // CraftBukkit - SPIGOT-7381: check for null world
          }
 diff --git a/src/main/java/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
diff --git a/patches/server/Fix-falling-block-spawn-methods.patch b/patches/server/Fix-falling-block-spawn-methods.patch
index aed8b641b8..f301545951 100644
--- a/patches/server/Fix-falling-block-spawn-methods.patch
+++ b/patches/server/Fix-falling-block-spawn-methods.patch
@@ -28,8 +28,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
 +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
 @@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
-         Validate.notNull(material, "Material cannot be null");
-         Validate.isTrue(material.isBlock(), "Material must be a block");
+         Preconditions.checkArgument(material != null, "Material cannot be null");
+         Preconditions.checkArgument(material.isBlock(), "Material.%s must be a block", material);
  
 -        FallingBlockEntity entity = FallingBlockEntity.fall(world, BlockPos.containing(location.getX(), location.getY(), location.getZ()), CraftMagicNumbers.getBlock(material).defaultBlockState(), SpawnReason.CUSTOM);
 +        // Paper start - restore API behavior for spawning falling blocks
@@ -42,8 +42,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }
  
 @@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
-         Validate.notNull(location, "Location cannot be null");
-         Validate.notNull(data, "BlockData cannot be null");
+         Preconditions.checkArgument(location != null, "Location cannot be null");
+         Preconditions.checkArgument(data != null, "BlockData cannot be null");
  
 -        FallingBlockEntity entity = FallingBlockEntity.fall(world, BlockPos.containing(location.getX(), location.getY(), location.getZ()), ((CraftBlockData) data).getState(), SpawnReason.CUSTOM);
 +        // Paper start - restore API behavior for spawning falling blocks
diff --git a/patches/server/Fix-removing-recipes-from-RecipeIterator.patch b/patches/server/Fix-removing-recipes-from-RecipeIterator.patch
index bc8285e1b6..6223be7c01 100644
--- a/patches/server/Fix-removing-recipes-from-RecipeIterator.patch
+++ b/patches/server/Fix-removing-recipes-from-RecipeIterator.patch
@@ -37,10 +37,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }
  
      @Override
-@@ -0,0 +0,0 @@ public class RecipeIterator implements Iterator<Recipe> {
-             throw new IllegalStateException("next() not yet called");
-         }
- 
+     public void remove() {
+         Preconditions.checkState(this.current != null, "next() not yet called");
++
 +        // Paper start - fix removing recipes
 +        if (this.currentRecipe instanceof org.bukkit.Keyed keyed) {
 +            MinecraftServer.getServer().getRecipeManager().byName.remove(org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(keyed.getKey()));
diff --git a/patches/server/Handle-Item-Meta-Inconsistencies.patch b/patches/server/Handle-Item-Meta-Inconsistencies.patch
index f20e245e8f..65c6d4fd97 100644
--- a/patches/server/Handle-Item-Meta-Inconsistencies.patch
+++ b/patches/server/Handle-Item-Meta-Inconsistencies.patch
@@ -73,17 +73,9 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
 +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
-@@ -0,0 +0,0 @@ import java.util.Map;
- import net.minecraft.nbt.CompoundTag;
- import net.minecraft.nbt.ListTag;
- import net.minecraft.world.item.Item;
--import net.minecraft.world.item.enchantment.EnchantmentHelper;
- import org.apache.commons.lang.Validate;
- import org.bukkit.Material;
- import org.bukkit.NamespacedKey;
 @@ -0,0 +0,0 @@ public final class CraftItemStack extends ItemStack {
      public void addUnsafeEnchantment(Enchantment ench, int level) {
-         Validate.notNull(ench, "Cannot add null enchantment");
+         Preconditions.checkArgument(ench != null, "Enchantment cannot be null");
  
 -        if (!CraftItemStack.makeTag(this.handle)) {
 -            return;
@@ -116,16 +108,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      static boolean makeTag(net.minecraft.world.item.ItemStack item) {
 @@ -0,0 +0,0 @@ public final class CraftItemStack extends ItemStack {
-         if (this.handle == null) {
-             return 0;
-         }
--        return EnchantmentHelper.getItemEnchantmentLevel(CraftEnchantment.getRaw(ench), handle);
-+        return net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(CraftEnchantment.getRaw(ench), handle); // Paper
-     }
- 
-     @Override
      public int removeEnchantment(Enchantment ench) {
-         Validate.notNull(ench, "Cannot remove null enchantment");
+         Preconditions.checkArgument(ench != null, "Enchantment cannot be null");
  
 -        ListTag list = CraftItemStack.getEnchantmentList(this.handle), listCopy;
 -        if (list == null) {
@@ -280,7 +264,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public boolean addEnchant(Enchantment ench, int level, boolean ignoreRestrictions) {
-         Validate.notNull(ench, "Enchantment cannot be null");
+         Preconditions.checkArgument(ench != null, "Enchantment cannot be null");
          if (this.enchantments == null) {
 -            this.enchantments = new LinkedHashMap<Enchantment, Integer>(4);
 +            this.enchantments = new EnchantmentMap(); // Paper
diff --git a/patches/server/Implement-World.getEntity-UUID-API.patch b/patches/server/Implement-World.getEntity-UUID-API.patch
index f1dbc00226..ddc1b7a0d5 100644
--- a/patches/server/Implement-World.getEntity-UUID-API.patch
+++ b/patches/server/Implement-World.getEntity-UUID-API.patch
@@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    // Paper start - getEntity by UUID API
 +    @Override
 +    public Entity getEntity(UUID uuid) {
-+        Validate.notNull(uuid, "UUID cannot be null");
++        Preconditions.checkArgument(uuid != null, "UUID cannot be null");
 +        net.minecraft.world.entity.Entity entity = world.getEntity(uuid);
 +        return entity == null ? null : entity.getBukkitEntity();
 +    }
diff --git a/patches/server/Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch b/patches/server/Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch
index 30a65d497a..1d6652dd7a 100644
--- a/patches/server/Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch
+++ b/patches/server/Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch
@@ -267,7 +267,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Override
 +    @SuppressWarnings("deprecation")
 +    public void setCanDestroy(Set<Material> canDestroy) {
-+        Validate.notNull(canDestroy, "Cannot replace with null set!");
++        Preconditions.checkArgument(canDestroy != null, "Cannot replace with null set!");
 +        legacyClearAndReplaceKeys(this.destroyableKeys, canDestroy);
 +    }
 +
@@ -280,7 +280,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Override
 +    @SuppressWarnings("deprecation")
 +    public void setCanPlaceOn(Set<Material> canPlaceOn) {
-+        Validate.notNull(canPlaceOn, "Cannot replace with null set!");
++        Preconditions.checkArgument(canPlaceOn != null, "Cannot replace with null set!");
 +        legacyClearAndReplaceKeys(this.placeableKeys, canPlaceOn);
 +    }
 +
@@ -291,8 +291,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    @Override
 +    public void setDestroyableKeys(Collection<Namespaced> canDestroy) {
-+        Validate.notNull(canDestroy, "Cannot replace with null collection!");
-+        Validate.isTrue(ofAcceptableType(canDestroy), "Can only use NamespacedKey or NamespacedTag objects!");
++        Preconditions.checkArgument(canDestroy != null, "Cannot replace with null collection!");
++        Preconditions.checkArgument(ofAcceptableType(canDestroy), "Can only use NamespacedKey or NamespacedTag objects!");
 +        this.destroyableKeys.clear();
 +        this.destroyableKeys.addAll(canDestroy);
 +    }
@@ -304,8 +304,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    @Override
 +    public void setPlaceableKeys(Collection<Namespaced> canPlaceOn) {
-+        Validate.notNull(canPlaceOn, "Cannot replace with null collection!");
-+        Validate.isTrue(ofAcceptableType(canPlaceOn), "Can only use NamespacedKey or NamespacedTag objects!");
++        Preconditions.checkArgument(canPlaceOn != null, "Cannot replace with null collection!");
++        Preconditions.checkArgument(ofAcceptableType(canPlaceOn), "Can only use NamespacedKey or NamespacedTag objects!");
 +        this.placeableKeys.clear();
 +        this.placeableKeys.addAll(canPlaceOn);
 +    }
diff --git a/patches/server/Implement-enchantWithLevels-API.patch b/patches/server/Implement-enchantWithLevels-API.patch
index 741db45c66..45dfaaa642 100644
--- a/patches/server/Implement-enchantWithLevels-API.patch
+++ b/patches/server/Implement-enchantWithLevels-API.patch
@@ -14,11 +14,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      // Paper start
 +    @Override
 +    public ItemStack enchantWithLevels(ItemStack itemStack, int levels, boolean allowTreasure, java.util.Random random) {
-+        Validate.notNull(itemStack, "Argument 'itemStack' must not be null");
-+        Validate.isTrue(itemStack.getType() != Material.AIR, "Argument 'itemStack' must not be of type AIR");
-+        Validate.isTrue(itemStack.getAmount() > 0, "Argument 'itemStack' amount must be greater than 0");
-+        Validate.isTrue(levels > 0 && levels <= 30, "Argument 'levels' must be in range [1, 30] (attempted " + levels + ")");
-+        Validate.notNull(random, "Argument 'random' must not be null");
++        Preconditions.checkArgument(itemStack != null, "Argument 'itemStack' must not be null");
++        Preconditions.checkArgument(itemStack.getType() != Material.AIR, "Argument 'itemStack' must not be of type AIR");
++        Preconditions.checkArgument(itemStack.getAmount() > 0, "Argument 'itemStack' amount must be greater than 0");
++        Preconditions.checkArgument(levels > 0 && levels <= 30, "Argument 'levels' must be in range [1, 30] (attempted " + levels + ")");
++        Preconditions.checkArgument(random != null, "Argument 'random' must not be null");
 +        final net.minecraft.world.item.ItemStack internalStack = CraftItemStack.asNMSCopy(itemStack);
 +        if (internalStack.getTag() != null) {
 +            internalStack.getTag().remove(net.minecraft.world.item.ItemStack.TAG_ENCH);
diff --git a/patches/server/Improve-scoreboard-entries.patch b/patches/server/Improve-scoreboard-entries.patch
index 1067f210d1..591fd72248 100644
--- a/patches/server/Improve-scoreboard-entries.patch
+++ b/patches/server/Improve-scoreboard-entries.patch
@@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    // Paper start
 +    @Override
 +    public Score getScoreFor(org.bukkit.entity.Entity entity) throws IllegalArgumentException, IllegalStateException {
-+        Validate.notNull(entity, "Entity cannot be null");
++        Preconditions.checkArgument(entity != null, "Entity cannot be null");
 +        return getScore(((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().getScoreboardName());
 +    }
 +    // Paper end
@@ -34,19 +34,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    // Paper start
 +    @Override
 +    public ImmutableSet<Score> getScoresFor(org.bukkit.entity.Entity entity) throws IllegalArgumentException {
-+        Validate.notNull(entity, "Entity cannot be null");
++        Preconditions.checkArgument(entity != null, "Entity cannot be null");
 +        return this.getScores(((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().getScoreboardName());
 +    }
 +
 +    @Override
 +    public void resetScoresFor(org.bukkit.entity.Entity entity) throws IllegalArgumentException {
-+        Validate.notNull(entity, "Entity cannot be null");
++        Preconditions.checkArgument(entity != null, "Entity cannot be null");
 +        this.resetScores(((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().getScoreboardName());
 +    }
 +
 +    @Override
 +    public Team getEntityTeam(org.bukkit.entity.Entity entity) throws IllegalArgumentException {
-+        Validate.notNull(entity, "Entity cannot be null");
++        Preconditions.checkArgument(entity != null, "Entity cannot be null");
 +        return this.getEntryTeam(((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().getScoreboardName());
 +    }
 +    // Paper end
@@ -62,19 +62,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    // Paper start
 +    @Override
 +    public void addEntity(org.bukkit.entity.Entity entity) throws IllegalStateException, IllegalArgumentException {
-+        Validate.notNull(entity, "Entity cannot be null");
++        Preconditions.checkArgument(entity != null, "Entity cannot be null");
 +        this.addEntry(((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().getScoreboardName());
 +    }
 +
 +    @Override
 +    public boolean removeEntity(org.bukkit.entity.Entity entity) throws IllegalStateException, IllegalArgumentException {
-+        Validate.notNull(entity, "Entity cannot be null");
++        Preconditions.checkArgument(entity != null, "Entity cannot be null");
 +        return this.removeEntry(((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().getScoreboardName());
 +    }
 +
 +    @Override
 +    public boolean hasEntity(org.bukkit.entity.Entity entity) throws IllegalStateException, IllegalArgumentException {
-+        Validate.notNull(entity, "Entity cannot be null");
++        Preconditions.checkArgument(entity != null, "Entity cannot be null");
 +        return this.hasEntry(((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().getScoreboardName());
 +    }
 +    // Paper end
diff --git a/patches/server/Improve-the-Saddle-API-for-Horses.patch b/patches/server/Improve-the-Saddle-API-for-Horses.patch
index 29ff4077ca..b83781e0ac 100644
--- a/patches/server/Improve-the-Saddle-API-for-Horses.patch
+++ b/patches/server/Improve-the-Saddle-API-for-Horses.patch
@@ -10,8 +10,8 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
 +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
-@@ -0,0 +0,0 @@ import net.minecraft.world.entity.ai.attributes.Attributes;
- import org.apache.commons.lang.Validate;
+@@ -0,0 +0,0 @@ import java.util.UUID;
+ import net.minecraft.world.entity.ai.attributes.Attributes;
  import org.bukkit.craftbukkit.CraftServer;
  import org.bukkit.craftbukkit.inventory.CraftInventoryAbstractHorse;
 +import org.bukkit.craftbukkit.inventory.CraftSaddledInventory;
diff --git a/patches/server/Improved-Async-Task-Scheduler.patch b/patches/server/Improved-Async-Task-Scheduler.patch
index 62bde04640..40968fe538 100644
--- a/patches/server/Improved-Async-Task-Scheduler.patch
+++ b/patches/server/Improved-Async-Task-Scheduler.patch
@@ -243,7 +243,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
      @Override
      public void cancelTasks(final Plugin plugin) {
-         Validate.notNull(plugin, "Cannot cancel tasks of null plugin");
+         Preconditions.checkArgument(plugin != null, "Cannot cancel tasks of null plugin");
 +        // Paper start
 +        if (!this.isAsyncScheduler) {
 +            this.asyncScheduler.cancelTasks(plugin);
@@ -318,8 +318,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
                  this.parsePending();
              } else {
-                 //this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass())); // Paper
--                this.executor.execute(new ServerSchedulerReportingWrapper(task)); // Paper
+                 // this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass())); // Paper
+-                this.executor.execute(new com.destroystokyo.paper.ServerSchedulerReportingWrapper(task)); // Paper
 +                task.getOwner().getLogger().log(Level.SEVERE, "Unexpected Async Task in the Sync Scheduler. Report this to Paper"); // Paper
                  // We don't need to parse pending
                  // (async tasks must live with race-conditions if they attempt to cancel between these few lines of code)
diff --git a/patches/server/Inventory-removeItemAnySlot.patch b/patches/server/Inventory-removeItemAnySlot.patch
index 1550c9a9f3..7af13a032d 100644
--- a/patches/server/Inventory-removeItemAnySlot.patch
+++ b/patches/server/Inventory-removeItemAnySlot.patch
@@ -41,7 +41,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    private HashMap<Integer, ItemStack> removeItem(boolean searchEntire, ItemStack... items) {
 +        // Paper end
-         Validate.notNull(items, "Items cannot be null");
+         Preconditions.checkArgument(items != null, "items cannot be null");
          HashMap<Integer, ItemStack> leftover = new HashMap<Integer, ItemStack>();
  
 @@ -0,0 +0,0 @@ public class CraftInventory implements Inventory {
diff --git a/patches/server/ItemStack-getMaxItemUseDuration.patch b/patches/server/ItemStack-getMaxItemUseDuration.patch
index c2e14fceb8..798951e6f3 100644
--- a/patches/server/ItemStack-getMaxItemUseDuration.patch
+++ b/patches/server/ItemStack-getMaxItemUseDuration.patch
@@ -22,4 +22,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
      @Override
      public void addUnsafeEnchantment(Enchantment ench, int level) {
-         Validate.notNull(ench, "Cannot add null enchantment");
+         Preconditions.checkArgument(ench != null, "Enchantment cannot be null");
diff --git a/patches/server/Lazily-track-plugin-scoreboards-by-default.patch b/patches/server/Lazily-track-plugin-scoreboards-by-default.patch
index 5391c70d8f..1c7ac091e9 100644
--- a/patches/server/Lazily-track-plugin-scoreboards-by-default.patch
+++ b/patches/server/Lazily-track-plugin-scoreboards-by-default.patch
@@ -26,13 +26,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      CraftScoreboard(Scoreboard board) {
          this.board = board;
 @@ -0,0 +0,0 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard {
-         Validate.notNull(renderType, "RenderType cannot be null");
-         Validate.isTrue(name.length() <= Short.MAX_VALUE, "The name '" + name + "' is longer than the limit of 32767 characters");
-         Validate.isTrue(board.getObjective(name) == null, "An objective of name '" + name + "' already exists");
+         Preconditions.checkArgument(renderType != null, "RenderType cannot be null");
+         Preconditions.checkArgument(name.length() <= Short.MAX_VALUE, "The name '%s' is longer than the limit of 32767 characters (%s)", name, name.length());
+         Preconditions.checkArgument(this.board.getObjective(name) == null, "An objective of name '%s' already exists", name);
 +        // Paper start - the block comment from the old registerNewObjective didnt cause a conflict when rebasing, so this block wasn't added to the adventure registerNewObjective
-+        if (((CraftCriteria) criteria).criteria != net.minecraft.world.scores.criteria.ObjectiveCriteria.DUMMY && !registeredGlobally) {
++        if (((CraftCriteria) criteria).criteria != net.minecraft.world.scores.criteria.ObjectiveCriteria.DUMMY && !this.registeredGlobally) {
 +            net.minecraft.server.MinecraftServer.getServer().server.getScoreboardManager().registerScoreboardForVanilla(this);
-+            registeredGlobally = true;
++            this.registeredGlobally = true;
 +        }
 +        // Paper end
          net.minecraft.world.scores.Objective objective = board.addObjective(name, ((CraftCriteria) criteria).criteria, io.papermc.paper.adventure.PaperAdventure.asVanilla(displayName), CraftScoreboardTranslations.fromBukkitRender(renderType));
diff --git a/patches/server/Line-Of-Sight-Changes.patch b/patches/server/Line-Of-Sight-Changes.patch
index 4fb1245c6b..be75468ada 100644
--- a/patches/server/Line-Of-Sight-Changes.patch
+++ b/patches/server/Line-Of-Sight-Changes.patch
@@ -43,16 +43,6 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
 +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
-@@ -0,0 +0,0 @@ import net.minecraft.world.entity.projectile.ThrownEgg;
- import net.minecraft.world.entity.projectile.ThrownEnderpearl;
- import net.minecraft.world.entity.projectile.ThrownExperienceBottle;
- import net.minecraft.world.entity.projectile.ThrownTrident;
-+import net.minecraft.world.level.ClipContext;
-+import net.minecraft.world.phys.HitResult;
-+import net.minecraft.world.phys.Vec3;
- import org.apache.commons.lang.Validate;
- import org.bukkit.FluidCollisionMode;
- import org.bukkit.Location;
 @@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
          return this.getHandle().hasLineOfSight(((CraftEntity) other).getHandle());
      }
@@ -61,11 +51,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Override
 +    public boolean hasLineOfSight(Location loc) {
 +        if (this.getHandle().level() != ((CraftWorld) loc.getWorld()).getHandle()) return false;
-+        Vec3 vec3d = new Vec3(this.getHandle().getX(), this.getHandle().getEyeY(), this.getHandle().getZ());
-+        Vec3 vec3d1 = new Vec3(loc.getX(), loc.getY(), loc.getZ());
++        net.minecraft.world.phys.Vec3 vec3d = new net.minecraft.world.phys.Vec3(this.getHandle().getX(), this.getHandle().getEyeY(), this.getHandle().getZ());
++        net.minecraft.world.phys.Vec3 vec3d1 = new net.minecraft.world.phys.Vec3(loc.getX(), loc.getY(), loc.getZ());
 +        if (vec3d1.distanceToSqr(vec3d) > 128D * 128D) return false; //Return early if the distance is greater than 128 blocks
 +
-+        return this.getHandle().level().clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this.getHandle())).getType() == HitResult.Type.MISS;
++        return this.getHandle().level().clip(new net.minecraft.world.level.ClipContext(vec3d, vec3d1, net.minecraft.world.level.ClipContext.Block.COLLIDER, net.minecraft.world.level.ClipContext.Fluid.NONE, this.getHandle())).getType() == net.minecraft.world.phys.HitResult.Type.MISS;
 +    }
 +    // Paper end
 +
diff --git a/patches/server/Missing-Entity-Behavior-API.patch b/patches/server/Missing-Entity-Behavior-API.patch
index 27fe53ab18..22a324a679 100644
--- a/patches/server/Missing-Entity-Behavior-API.patch
+++ b/patches/server/Missing-Entity-Behavior-API.patch
@@ -1151,8 +1151,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              this.getHandle().conversionStarter = null;
              this.getHandle().removeEffect(MobEffects.DAMAGE_BOOST, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.CONVERSION);
          } else {
--            this.getHandle().startConverting((UUID) null, time);
-+            this.getHandle().startConverting((UUID) null, time, broadcastEntityEvent); // Paper - missing entity behaviour api - converting without entity event
+-            this.getHandle().startConverting(null, time);
++            this.getHandle().startConverting(null, time, broadcastEntityEvent); // Paper - missing entity behaviour api - converting without entity event
          }
      }
  
diff --git a/patches/server/More-Projectile-API.patch b/patches/server/More-Projectile-API.patch
index 796d3edbe7..d9a94c08b2 100644
--- a/patches/server/More-Projectile-API.patch
+++ b/patches/server/More-Projectile-API.patch
@@ -439,11 +439,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java
 +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java
 @@ -0,0 +0,0 @@ public class CraftThrownPotion extends CraftThrowableProjectile implements Throw
-         Validate.notNull(item, "ItemStack cannot be null.");
- 
-         // The ItemStack must be a potion.
--        Validate.isTrue(item.getType() == Material.LINGERING_POTION || item.getType() == Material.SPLASH_POTION, "ItemStack must be a lingering or splash potion. This item stack was " + item.getType() + ".");
-+        //Validate.isTrue(item.getType() == Material.LINGERING_POTION || item.getType() == Material.SPLASH_POTION, "ItemStack must be a lingering or splash potion. This item stack was " + item.getType() + "."); // Paper - Projectile API
+     @Override
+     public void setItem(ItemStack item) {
+         Preconditions.checkArgument(item != null, "ItemStack cannot be null");
+-        Preconditions.checkArgument(item.getType() == Material.LINGERING_POTION || item.getType() == Material.SPLASH_POTION, "ItemStack material must be Material.LINGERING_POTION or Material.SPLASH_POTION but was Material.%s", item.getType());
++        // Preconditions.checkArgument(item.getType() == Material.LINGERING_POTION || item.getType() == Material.SPLASH_POTION, "ItemStack material must be Material.LINGERING_POTION or Material.SPLASH_POTION but was Material.%s", item.getType()); // Paper - Projectile API
 +        org.bukkit.inventory.meta.PotionMeta meta = (item.getType() == Material.LINGERING_POTION || item.getType() == Material.SPLASH_POTION) ? null : this.getPotionMeta(); // Paper - Projectile API
  
          this.getHandle().setItem(CraftItemStack.asNMSCopy(item));
diff --git a/patches/server/More-World-API.patch b/patches/server/More-World-API.patch
index d480a75424..7a2368a25b 100644
--- a/patches/server/More-World-API.patch
+++ b/patches/server/More-World-API.patch
@@ -77,7 +77,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
      @Override
      public Raid locateNearestRaid(Location location, int radius) {
-         Validate.notNull(location, "Location cannot be null");
+         Preconditions.checkArgument(location != null, "Location cannot be null");
 diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftVector.java b/src/main/java/org/bukkit/craftbukkit/util/CraftVector.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftVector.java
diff --git a/patches/server/Multiple-Entries-with-Scoreboards.patch b/patches/server/Multiple-Entries-with-Scoreboards.patch
index d15a125c23..7122d754a1 100644
--- a/patches/server/Multiple-Entries-with-Scoreboards.patch
+++ b/patches/server/Multiple-Entries-with-Scoreboards.patch
@@ -85,7 +85,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    @Override
 +    public void addEntries(java.util.Collection<String> entries) throws IllegalStateException, IllegalArgumentException {
-+        Validate.notNull(entries, "Entries cannot be null");
++        Preconditions.checkArgument(entries != null, "Entries cannot be null");
 +        CraftScoreboard scoreboard = this.checkState();
 +
 +        ((net.minecraft.server.ServerScoreboard) scoreboard.board).addPlayersToTeam(entries, this.team);
@@ -94,7 +94,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
      @Override
      public boolean removePlayer(OfflinePlayer player) throws IllegalStateException, IllegalArgumentException {
-         Validate.notNull(player, "OfflinePlayer cannot be null");
+         Preconditions.checkArgument(player != null, "OfflinePlayer cannot be null");
 @@ -0,0 +0,0 @@ final class CraftTeam extends CraftScoreboardComponent implements Team {
          return true;
      }
@@ -107,7 +107,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    @Override
 +    public boolean removeEntries(java.util.Collection<String> entries) throws IllegalStateException, IllegalArgumentException {
-+        Validate.notNull(entries, "Entry cannot be null");
++        Preconditions.checkArgument(entries != null, "Entry cannot be null");
 +        CraftScoreboard scoreboard = this.checkState();
 +
 +        for (String entry : entries) {
@@ -123,4 +123,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
      @Override
      public boolean hasPlayer(OfflinePlayer player) throws IllegalArgumentException, IllegalStateException {
-         Validate.notNull(player, "OfflinePlayer cannot be null");
+         Preconditions.checkArgument(player != null, "OfflinePlayer cannot be null");
diff --git a/patches/server/Only-refresh-abilities-if-needed.patch b/patches/server/Only-refresh-abilities-if-needed.patch
index e991d4f899..65ca592a39 100644
--- a/patches/server/Only-refresh-abilities-if-needed.patch
+++ b/patches/server/Only-refresh-abilities-if-needed.patch
@@ -13,8 +13,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
      public void setFlying(boolean value) {
 +        boolean needsUpdate = getHandle().getAbilities().flying != value; // Paper - Only refresh abilities if needed
-         if (!this.getAllowFlight() && value) {
-             throw new IllegalArgumentException("Cannot make player fly if getAllowFlight() is false");
+         if (!this.getAllowFlight()) {
+             Preconditions.checkArgument(!value, "Player is not allowed to fly (check #getAllowFlight())");
          }
  
          this.getHandle().getAbilities().flying = value;
diff --git a/patches/server/Player-elytra-boost-API.patch b/patches/server/Player-elytra-boost-API.patch
index a7579ee013..9d0569682a 100644
--- a/patches/server/Player-elytra-boost-API.patch
+++ b/patches/server/Player-elytra-boost-API.patch
@@ -15,9 +15,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    @Override
 +    public org.bukkit.entity.Firework boostElytra(ItemStack firework) {
-+        Validate.isTrue(isGliding(), "Player must be gliding");
-+        Validate.isTrue(firework != null, "firework == null");
-+        Validate.isTrue(firework.getType() == Material.FIREWORK_ROCKET, "Firework must be Material.FIREWORK_ROCKET");
++        Preconditions.checkState(this.isGliding(), "Player must be gliding");
++        Preconditions.checkArgument(firework != null, "firework == null");
++        Preconditions.checkArgument(firework.getType() == Material.FIREWORK_ROCKET, "Firework must be Material.FIREWORK_ROCKET");
 +
 +        net.minecraft.world.item.ItemStack item = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(firework);
 +        net.minecraft.world.level.Level world = ((CraftWorld) getWorld()).getHandle();
diff --git a/patches/server/Remap-fixes.patch b/patches/server/Remap-fixes.patch
index 7878987ece..fe43d021f9 100644
--- a/patches/server/Remap-fixes.patch
+++ b/patches/server/Remap-fixes.patch
@@ -103,6 +103,31 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          assertThat(color, is(Color.fromRGB(nmsColor)));
      }
  }
+diff --git a/src/test/java/org/bukkit/RegistryConstantsTest.java b/src/test/java/org/bukkit/RegistryConstantsTest.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/test/java/org/bukkit/RegistryConstantsTest.java
++++ b/src/test/java/org/bukkit/RegistryConstantsTest.java
+@@ -0,0 +0,0 @@ public class RegistryConstantsTest extends AbstractTestingBase {
+ 
+     @Test
+     public void testTrimMaterial() {
+-        this.testExcessConstants(TrimMaterial.class, Registry.TRIM_MATERIAL);
++        this.testExcessConstants(TrimMaterial.class, org.bukkit.Registry.TRIM_MATERIAL); // Paper - remap fix
+         this.testMissingConstants(TrimMaterial.class, Registries.TRIM_MATERIAL);
+     }
+ 
+     @Test
+     public void testTrimPattern() {
+-        this.testExcessConstants(TrimPattern.class, Registry.TRIM_PATTERN);
++        this.testExcessConstants(TrimPattern.class, org.bukkit.Registry.TRIM_PATTERN); // Paper - remap fix
+         this.testMissingConstants(TrimPattern.class, Registries.TRIM_PATTERN);
+     }
+ 
+-    private <T extends Keyed> void testExcessConstants(Class<T> clazz, Registry<T> registry) {
++    private <T extends Keyed> void testExcessConstants(Class<T> clazz, org.bukkit.Registry<T> registry) { // Paper - remap fix
+         List<NamespacedKey> excessKeys = new ArrayList<>();
+ 
+         for (Field field : clazz.getFields()) {
 diff --git a/src/test/java/org/bukkit/entity/EntityTypesTest.java b/src/test/java/org/bukkit/entity/EntityTypesTest.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/test/java/org/bukkit/entity/EntityTypesTest.java
diff --git a/patches/server/Remove-CraftScheduler-Async-Task-Debugger.patch b/patches/server/Remove-CraftScheduler-Async-Task-Debugger.patch
index 8184009915..f39e6390ef 100644
--- a/patches/server/Remove-CraftScheduler-Async-Task-Debugger.patch
+++ b/patches/server/Remove-CraftScheduler-Async-Task-Debugger.patch
@@ -17,8 +17,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  this.parsePending();
              } else {
 -                this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass()));
-+                //this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass())); // Paper
-                 this.executor.execute(new ServerSchedulerReportingWrapper(task)); // Paper
++                // this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass())); // Paper
+                 this.executor.execute(new com.destroystokyo.paper.ServerSchedulerReportingWrapper(task)); // Paper
                  // We don't need to parse pending
                  // (async tasks must live with race-conditions if they attempt to cancel between these few lines of code)
 @@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
diff --git a/patches/server/Reset-players-airTicks-on-respawn.patch b/patches/server/Reset-players-airTicks-on-respawn.patch
index 555cf4beaf..7f7b9f526a 100644
--- a/patches/server/Reset-players-airTicks-on-respawn.patch
+++ b/patches/server/Reset-players-airTicks-on-respawn.patch
@@ -13,6 +13,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          this.setHealth(this.getMaxHealth());
          this.stopUsingItem(); // CraftBukkit - SPIGOT-6682: Clear active item on reset
 +        this.setAirSupply(this.getMaxAirSupply()); // Paper
-         this.remainingFireTicks = 0;
+         this.setRemainingFireTicks(0);
          this.fallDistance = 0;
          this.foodData = new FoodData(this);
diff --git a/patches/server/Reset-spawner-timer-when-spawner-event-is-cancelled.patch b/patches/server/Reset-spawner-timer-when-spawner-event-is-cancelled.patch
index 5d29bf93c3..32c03e9080 100644
--- a/patches/server/Reset-spawner-timer-when-spawner-event-is-cancelled.patch
+++ b/patches/server/Reset-spawner-timer-when-spawner-event-is-cancelled.patch
@@ -9,13 +9,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
 +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
 @@ -0,0 +0,0 @@ public abstract class BaseSpawner {
-                             // Spigot End
                          }
+ 
                          entity.spawnedViaMobSpawner = true; // Paper
 +                        flag = true; // Paper
-                         // Spigot Start
+                         // CraftBukkit start
                          if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) {
-                             Entity vehicle = entity.getVehicle();
+                             continue;
 @@ -0,0 +0,0 @@ public abstract class BaseSpawner {
                              ((Mob) entity).spawnAnim();
                          }
diff --git a/patches/server/Rewrite-chunk-system.patch b/patches/server/Rewrite-chunk-system.patch
index a97061137c..2bd9250ba4 100644
--- a/patches/server/Rewrite-chunk-system.patch
+++ b/patches/server/Rewrite-chunk-system.patch
@@ -22644,7 +22644,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return io.papermc.paper.util.TickThread.isTickThread(); // Paper - rewrite chunk system
      }
  
-     // Paper start
+     // Paper start - Adventure
 diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
diff --git a/patches/server/Support-components-in-ItemMeta.patch b/patches/server/Support-components-in-ItemMeta.patch
index 68359caee6..2759fdd779 100644
--- a/patches/server/Support-components-in-ItemMeta.patch
+++ b/patches/server/Support-components-in-ItemMeta.patch
@@ -79,5 +79,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            } else
 +            // Paper end
              if (!(object instanceof String)) {
-                 if (object != null) {
-                     throw new IllegalArgumentException(addFrom + " cannot contain non-string " + object.getClass().getName());
+                 Preconditions.checkArgument(object == null, "%s cannot contain non-string %s", addFrom, object.getClass().getName());
+ 
diff --git a/patches/server/Throw-exception-on-world-create-while-being-ticked.patch b/patches/server/Throw-exception-on-world-create-while-being-ticked.patch
index 24e256ed66..a3b557b2bf 100644
--- a/patches/server/Throw-exception-on-world-create-while-being-ticked.patch
+++ b/patches/server/Throw-exception-on-world-create-while-being-ticked.patch
@@ -65,7 +65,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public World createWorld(WorldCreator creator) {
          Preconditions.checkState(this.console.getAllLevels().iterator().hasNext(), "Cannot create additional worlds on STARTUP");
 +        //Preconditions.checkState(!this.console.isIteratingOverLevels, "Cannot create a world while worlds are being ticked"); // Paper - Cat - Temp disable. We'll see how this goes.
-         Validate.notNull(creator, "Creator may not be null");
+         Preconditions.checkArgument(creator != null, "WorldCreator cannot be null");
  
          String name = creator.name();
 @@ -0,0 +0,0 @@ public final class CraftServer implements Server {
diff --git a/patches/server/Timings-v2.patch b/patches/server/Timings-v2.patch
index 1b8326017e..8f3533fbc6 100644
--- a/patches/server/Timings-v2.patch
+++ b/patches/server/Timings-v2.patch
@@ -1872,9 +1872,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  package org.bukkit.craftbukkit.scheduler;
  
 +import co.aikar.timings.MinecraftTimings; // Paper
+ import com.google.common.base.Preconditions;
  import com.google.common.util.concurrent.ThreadFactoryBuilder;
  import java.util.ArrayList;
- import java.util.Comparator;
 @@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
      }
  
diff --git a/patches/server/additions-to-PlayerGameModeChangeEvent.patch b/patches/server/additions-to-PlayerGameModeChangeEvent.patch
index 3b9982a734..b634a5d6b8 100644
--- a/patches/server/additions-to-PlayerGameModeChangeEvent.patch
+++ b/patches/server/additions-to-PlayerGameModeChangeEvent.patch
@@ -148,8 +148,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
 +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
 @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
-             throw new IllegalArgumentException("Mode cannot be null");
-         }
+         Preconditions.checkArgument(mode != null, "GameMode cannot be null");
+         if (this.getHandle().connection == null) return;
  
 -        this.getHandle().setGameMode(GameType.byId(mode.getValue()));
 +        this.getHandle().setGameMode(GameType.byId(mode.getValue()), org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.PLUGIN, null); // Paper
diff --git a/patches/server/fix-Instruments.patch b/patches/server/fix-Instruments.patch
index 2474dc42e9..30ef4d10ba 100644
--- a/patches/server/fix-Instruments.patch
+++ b/patches/server/fix-Instruments.patch
@@ -10,62 +10,32 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
 +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
 @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
-     public void playNote(Location loc, Instrument instrument, Note note) {
+ 
          if (this.getHandle().connection == null) return;
  
--        String instrumentName = null;
--        switch (instrument.ordinal()) {
--            case 0:
--                instrumentName = "harp";
--                break;
--            case 1:
--                instrumentName = "basedrum";
--                break;
--            case 2:
--                instrumentName = "snare";
--                break;
--            case 3:
--                instrumentName = "hat";
--                break;
--            case 4:
--                instrumentName = "bass";
--                break;
--            case 5:
--                instrumentName = "flute";
--                break;
--            case 6:
--                instrumentName = "bell";
--                break;
--            case 7:
--                instrumentName = "guitar";
--                break;
--            case 8:
--                instrumentName = "chime";
--                break;
--            case 9:
--                instrumentName = "xylophone";
--                break;
--            case 10:
--                instrumentName = "iron_xylophone";
--                break;
--            case 11:
--                instrumentName = "cow_bell";
--                break;
--            case 12:
--                instrumentName = "didgeridoo";
--                break;
--            case 13:
--                instrumentName = "bit";
--                break;
--            case 14:
--                instrumentName = "banjo";
--                break;
--            case 15:
--                instrumentName = "pling";
--                break;
--            case 16:
--                instrumentName = "xylophone";
--                break;
+-        String instrumentName = switch (instrument.ordinal()) {
+-            case 0 -> "harp";
+-            case 1 -> "basedrum";
+-            case 2 -> "snare";
+-            case 3 -> "hat";
+-            case 4 -> "bass";
+-            case 5 -> "flute";
+-            case 6 -> "bell";
+-            case 7 -> "guitar";
+-            case 8 -> "chime";
+-            case 9 -> "xylophone";
+-            case 10 -> "iron_xylophone";
+-            case 11 -> "cow_bell";
+-            case 12 -> "didgeridoo";
+-            case 13 -> "bit";
+-            case 14 -> "banjo";
+-            case 15 -> "pling";
+-            case 16 -> "xylophone";
+-            default -> null;
+-        };
+-
+-        float f = (float) Math.pow(2.0D, (note.getId() - 12.0D) / 12.0D);
+-        this.getHandle().connection.send(new ClientboundSoundPacket(BuiltInRegistries.SOUND_EVENT.wrapAsHolder(CraftSound.getSoundEffect("block.note_block." + instrumentName)), net.minecraft.sounds.SoundSource.RECORDS, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), 3.0f, f, this.getHandle().getRandom().nextLong()));
 +        // Paper start - fix all this (modeled off of NoteBlock)
 +        net.minecraft.world.level.block.state.properties.NoteBlockInstrument nms = CraftBlockData.toNMS(instrument, net.minecraft.world.level.block.state.properties.NoteBlockInstrument.class);
 +        float f;
@@ -73,9 +43,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            f = (float) Math.pow(2.0D, (note.getId() - 12.0D) / 12.0D);
 +        } else {
 +            f = 1.0f;
-         }
--        float f = (float) Math.pow(2.0D, (note.getId() - 12.0D) / 12.0D);
--        this.getHandle().connection.send(new ClientboundSoundPacket(BuiltInRegistries.SOUND_EVENT.wrapAsHolder(CraftSound.getSoundEffect("block.note_block." + instrumentName)), net.minecraft.sounds.SoundSource.RECORDS, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), 3.0f, f, this.getHandle().getRandom().nextLong()));
++        }
 +        if (!nms.hasCustomSound()) {
 +            this.getHandle().connection.send(new ClientboundSoundPacket(nms.getSoundEvent(), net.minecraft.sounds.SoundSource.RECORDS, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), 3.0f, f, this.getHandle().getRandom().nextLong()));
 +        }
diff --git a/work/Bukkit b/work/Bukkit
index 657df461c2..54e8ec7b47 160000
--- a/work/Bukkit
+++ b/work/Bukkit
@@ -1 +1 @@
-Subproject commit 657df461c253a66e3382d5dbe97bd31ce0ac1438
+Subproject commit 54e8ec7b47ec9a77e05d44d8898a0f247c8db046
diff --git a/work/CraftBukkit b/work/CraftBukkit
index fd92f1e654..6962456f98 160000
--- a/work/CraftBukkit
+++ b/work/CraftBukkit
@@ -1 +1 @@
-Subproject commit fd92f1e65447be1d336ce0c43f2e915f01f2fc1d
+Subproject commit 6962456f98f6e5075c8bf6dff772f3c2464ae60e
diff --git a/work/Spigot b/work/Spigot
index 16cfc98727..7e2af8b2d6 160000
--- a/work/Spigot
+++ b/work/Spigot
@@ -1 +1 @@
-Subproject commit 16cfc987271eddcc0ffeb5d8cc968ea16c19e986
+Subproject commit 7e2af8b2d6af54e66edd030abbf12359a8574e05