From a093b95db28ffcdc7160325541642d18c83cf359 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Thu, 26 May 2022 12:12:14 -0700
Subject: [PATCH] Provide ComponentSerializer services (#7527)

---
 patches/api/Add-API-for-quit-reason.patch     |   2 +-
 ...t-sendMessage-methods-to-CommandSend.patch |   2 +-
 patches/api/Add-PlayerKickEvent-causes.patch  |   4 +-
 patches/api/Add-UnknownCommandEvent.patch     |  11 +-
 ...ent-to-allow-plugins-to-handle-clien.patch |  10 +-
 patches/api/Adventure.patch                   | 114 ++--
 ...ault-permission-message-configurable.patch |   2 +-
 .../api/PlayerDeathEvent-getItemsToKeep.patch |   2 +-
 patches/api/ProfileWhitelistVerifyEvent.patch |   8 +-
 patches/api/Timings-v2.patch                  |   2 +-
 ...-command-sender-which-forwards-feedb.patch |   4 +-
 .../server/Add-PlayerKickEvent-causes.patch   |   6 +-
 ...n-for-console-having-all-permissions.patch |   2 +-
 ...pport-for-hex-color-codes-in-console.patch |   6 +-
 patches/server/Adventure.patch                | 506 ++++++++++++------
 ...-track-plugin-scoreboards-by-default.patch |   2 +-
 ...nilla-per-world-scoreboard-coloring-.patch |   6 +-
 ...vent-opening-inventories-when-frozen.patch |   4 +-
 .../server/ProfileWhitelistVerifyEvent.patch  |   4 +-
 ...store-custom-InventoryHolder-support.patch |   3 +-
 ...oleAppender-for-console-improvements.patch |   2 +-
 21 files changed, 448 insertions(+), 254 deletions(-)

diff --git a/patches/api/Add-API-for-quit-reason.patch b/patches/api/Add-API-for-quit-reason.patch
index cdd16e58f6..2be5edbfed 100644
--- a/patches/api/Add-API-for-quit-reason.patch
+++ b/patches/api/Add-API-for-quit-reason.patch
@@ -22,7 +22,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
 +    public PlayerQuitEvent(@NotNull final Player who, @Nullable final String quitMessage, @Nullable QuitReason quitReason) {
          super(who);
-         this.quitMessage = quitMessage != null ? org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(quitMessage) : null; // Paper
+         this.quitMessage = quitMessage != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(quitMessage) : null; // Paper
 +        this.reason = quitReason == null ? QuitReason.DISCONNECTED : quitReason;
      }
      // Paper start
diff --git a/patches/api/Add-BaseComponent-sendMessage-methods-to-CommandSend.patch b/patches/api/Add-BaseComponent-sendMessage-methods-to-CommandSend.patch
index 0fc048658e..8f878513fa 100644
--- a/patches/api/Add-BaseComponent-sendMessage-methods-to-CommandSend.patch
+++ b/patches/api/Add-BaseComponent-sendMessage-methods-to-CommandSend.patch
@@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  import org.jetbrains.annotations.NotNull;
 @@ -0,0 +0,0 @@ public interface CommandSender extends net.kyori.adventure.audience.Audience, Pe
      default void sendMessage(final @NotNull net.kyori.adventure.identity.Identity identity, final @NotNull net.kyori.adventure.text.Component message, final @NotNull net.kyori.adventure.audience.MessageType type) {
-         this.sendMessage(org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(message));
+         this.sendMessage(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(message));
      }
 +
 +    /**
diff --git a/patches/api/Add-PlayerKickEvent-causes.patch b/patches/api/Add-PlayerKickEvent-causes.patch
index 09e9defe67..c0deac3bd7 100644
--- a/patches/api/Add-PlayerKickEvent-causes.patch
+++ b/patches/api/Add-PlayerKickEvent-causes.patch
@@ -37,8 +37,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Deprecated // Paper
 @@ -0,0 +0,0 @@ public class PlayerKickEvent extends PlayerEvent implements Cancellable {
          super(playerKicked);
-         this.kickReason = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(kickReason); // Paper
-         this.leaveMessage = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(leaveMessage); // Paper
+         this.kickReason = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(kickReason); // Paper
+         this.leaveMessage = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(leaveMessage); // Paper
 +        this.cause  = Cause.UNKNOWN; // Paper
          this.cancel = false;
      }
diff --git a/patches/api/Add-UnknownCommandEvent.patch b/patches/api/Add-UnknownCommandEvent.patch
index 8c136b0000..152c19c168 100644
--- a/patches/api/Add-UnknownCommandEvent.patch
+++ b/patches/api/Add-UnknownCommandEvent.patch
@@ -13,11 +13,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +package org.bukkit.event.command;
 +
 +import net.kyori.adventure.text.Component;
-+import org.bukkit.Bukkit;
++import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
 +import org.bukkit.command.CommandSender;
-+import org.bukkit.event.HandlerList;
 +import org.bukkit.event.Event;
-+
++import org.bukkit.event.HandlerList;
 +import org.jetbrains.annotations.NotNull;
 +import org.jetbrains.annotations.Nullable;
 +
@@ -32,7 +31,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    @Deprecated
 +    public UnknownCommandEvent(@NotNull final CommandSender sender, @NotNull final String commandLine, @Nullable final String message) {
-+        this(sender, commandLine, message == null ? null : Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message));
++        this(sender, commandLine, message == null ? null : LegacyComponentSerializer.legacySection().deserialize(message));
 +    }
 +
 +    public UnknownCommandEvent(@NotNull final CommandSender sender, @NotNull final String commandLine, @Nullable final Component message) {
@@ -74,7 +73,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Nullable
 +    @Deprecated
 +    public String getMessage() {
-+        return this.message == null ? null : Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.message);
++        return this.message == null ? null : LegacyComponentSerializer.legacySection().serialize(this.message);
 +    }
 +
 +    /**
@@ -87,7 +86,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     */
 +    @Deprecated
 +    public void setMessage(@Nullable String message) {
-+        this.message(message == null ? null : Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message));
++        this.message(message == null ? null : LegacyComponentSerializer.legacySection().deserialize(message));
 +    }
 +
 +    /**
diff --git a/patches/api/Add-handshake-event-to-allow-plugins-to-handle-clien.patch b/patches/api/Add-handshake-event-to-allow-plugins-to-handle-clien.patch
index c7ea3064f6..ea17617eed 100644
--- a/patches/api/Add-handshake-event-to-allow-plugins-to-handle-clien.patch
+++ b/patches/api/Add-handshake-event-to-allow-plugins-to-handle-clien.patch
@@ -15,16 +15,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +import net.kyori.adventure.text.Component;
 +import net.kyori.adventure.text.format.NamedTextColor;
++import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
 +import org.apache.commons.lang.Validate;
-+import org.bukkit.Bukkit;
 +import org.bukkit.event.Cancellable;
 +import org.bukkit.event.Event;
 +import org.bukkit.event.HandlerList;
-+
-+import java.util.UUID;
 +import org.jetbrains.annotations.NotNull;
 +import org.jetbrains.annotations.Nullable;
 +
++import java.util.UUID;
++
 +/**
 + * This event is fired during a player handshake.
 + *
@@ -262,7 +262,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @NotNull
 +    @Deprecated
 +    public String getFailMessage() {
-+        return Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.failMessage());
++        return LegacyComponentSerializer.legacySection().serialize(this.failMessage());
 +    }
 +
 +    /**
@@ -274,7 +274,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated
 +    public void setFailMessage(@NotNull String failMessage) {
 +        Validate.notEmpty(failMessage, "fail message cannot be null or empty");
-+        this.failMessage(Bukkit.getUnsafe().legacyComponentSerializer().deserialize(failMessage));
++        this.failMessage(LegacyComponentSerializer.legacySection().deserialize(failMessage));
 +    }
 +
 +    @NotNull
diff --git a/patches/api/Adventure.patch b/patches/api/Adventure.patch
index ab621a1310..df4664ff68 100644
--- a/patches/api/Adventure.patch
+++ b/patches/api/Adventure.patch
@@ -398,10 +398,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * <p>Implementations may provide a serializer capable of processing any
 +     * information that requires access to implementation details.</p>
 +     *
-+     * @deprecated will be removed in adventure 5.0.0, use {@link #plainTextSerializer()}
 +     * @return a serializer to plain text
++     * @deprecated will be removed in adventure 5.0.0, use {@link PlainTextComponentSerializer#plainText()}
 +     */
-+    @Deprecated
++    @Deprecated(forRemoval = true)
 +    public static @NotNull PlainComponentSerializer plainSerializer() {
 +        return Bukkit.getUnsafe().plainComponentSerializer();
 +    }
@@ -414,7 +414,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * information that requires access to implementation details.</p>
 +     *
 +     * @return a serializer to plain text
++     * @deprecated use {@link PlainTextComponentSerializer#plainText()}
 +     */
++    @Deprecated(forRemoval = true)
 +    public static @NotNull PlainTextComponentSerializer plainTextSerializer() {
 +        return Bukkit.getUnsafe().plainTextSerializer();
 +    }
@@ -428,7 +430,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * (pre-1.16) hover events.</p>
 +     *
 +     * @return a json component serializer
++     * @deprecated use {@link GsonComponentSerializer#gson()}
 +     */
++    @Deprecated(forRemoval = true)
 +    public static @NotNull GsonComponentSerializer gsonSerializer() {
 +        return Bukkit.getUnsafe().gsonComponentSerializer();
 +    }
@@ -443,7 +447,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * (pre-1.16) hover events.</p>
 +     *
 +     * @return a json component serializer
++     * @deprecated use {@link GsonComponentSerializer#colorDownsamplingGson()}
 +     */
++    @Deprecated(forRemoval = true)
 +    public static @NotNull GsonComponentSerializer colorDownsamplingGsonSerializer() {
 +        return Bukkit.getUnsafe().colorDownsamplingGsonComponentSerializer();
 +    }
@@ -461,7 +467,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * information that requires access to implementation details.</p>
 +     *
 +     * @return a section serializer
++     * @deprecated use {@link LegacyComponentSerializer#legacySection()}
 +     */
++    @Deprecated(forRemoval = true)
 +    public static @NotNull LegacyComponentSerializer legacySectionSerializer() {
 +        return Bukkit.getUnsafe().legacyComponentSerializer();
 +    }
@@ -1109,11 +1117,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  public interface UnsafeValues {
 +    // Paper start
 +    net.kyori.adventure.text.flattener.ComponentFlattener componentFlattener();
-+    @Deprecated net.kyori.adventure.text.serializer.plain.PlainComponentSerializer plainComponentSerializer();
-+    net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer plainTextSerializer();
-+    net.kyori.adventure.text.serializer.gson.GsonComponentSerializer gsonComponentSerializer();
-+    net.kyori.adventure.text.serializer.gson.GsonComponentSerializer colorDownsamplingGsonComponentSerializer();
-+    net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer legacyComponentSerializer();
++    @Deprecated(forRemoval = true) net.kyori.adventure.text.serializer.plain.PlainComponentSerializer plainComponentSerializer();
++    @Deprecated(forRemoval = true) net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer plainTextSerializer();
++    @Deprecated(forRemoval = true) net.kyori.adventure.text.serializer.gson.GsonComponentSerializer gsonComponentSerializer();
++    @Deprecated(forRemoval = true) net.kyori.adventure.text.serializer.gson.GsonComponentSerializer colorDownsamplingGsonComponentSerializer();
++    @Deprecated(forRemoval = true) net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer legacyComponentSerializer();
 +    // Paper end
  
      Material toLegacy(Material material);
@@ -1314,7 +1322,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public String getPermissionMessage() {
 -        return permissionMessage;
-+        return io.papermc.paper.text.PaperComponents.legacySectionSerializer().serializeOrNull(permissionMessage); // Paper
++        return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serializeOrNull(permissionMessage); // Paper
      }
  
      /**
@@ -1328,7 +1336,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public Command setPermissionMessage(@Nullable String permissionMessage) {
 -        this.permissionMessage = permissionMessage;
-+        this.permissionMessage = io.papermc.paper.text.PaperComponents.legacySectionSerializer().deserializeOrNull(permissionMessage); // Paper
++        this.permissionMessage = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserializeOrNull(permissionMessage); // Paper
          return this;
      }
  
@@ -1456,7 +1464,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    @Override
 +    default void sendMessage(final @NotNull net.kyori.adventure.identity.Identity identity, final @NotNull net.kyori.adventure.text.Component message, final @NotNull net.kyori.adventure.audience.MessageType type) {
-+        this.sendMessage(org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(message));
++        this.sendMessage(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(message));
 +    }
 +    // Paper end
  }
@@ -1469,7 +1477,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
              if (permissionMessage != null) {
 -                newCmd.setPermissionMessage(permissionMessage.toString());
-+                newCmd.permissionMessage(io.papermc.paper.text.PaperComponents.legacySectionSerializer().deserialize(permissionMessage.toString())); // Paper
++                newCmd.permissionMessage(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(permissionMessage.toString())); // Paper
              }
  
              pluginCmds.add(newCmd);
@@ -2158,7 +2166,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        // Paper start
 +        this.adventure$lines = new java.util.ArrayList<>();
 +        for (String theLine : theLines) {
-+            this.adventure$lines.add(org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(theLine));
++            this.adventure$lines.add(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(theLine));
 +        }
 +        // Paper end
      }
@@ -2214,7 +2222,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public String[] getLines() {
 -        return lines;
-+        return adventure$lines.stream().map(org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer()::serialize).toArray(String[]::new); // Paper
++        return adventure$lines.stream().map(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection()::serialize).toArray(String[]::new); // Paper
      }
  
      /**
@@ -2228,7 +2236,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public String getLine(int index) throws IndexOutOfBoundsException {
 -        return lines[index];
-+        return org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.adventure$lines.get(index)); // Paper
++        return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.adventure$lines.get(index)); // Paper
      }
  
      /**
@@ -2241,7 +2249,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public void setLine(int index, @Nullable String line) throws IndexOutOfBoundsException {
 -        lines[index] = line;
-+        adventure$lines.set(index, line != null ? org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(line) : null); // Paper
++        adventure$lines.set(index, line != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(line) : null); // Paper
      }
  
      @Override
@@ -2294,7 +2302,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          this.newTotalExp = newTotalExp;
          this.newLevel = newLevel;
          this.deathMessage = deathMessage;
-+        this.adventure$deathMessage = deathMessage != null ? org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(deathMessage) : net.kyori.adventure.text.Component.empty(); // Paper
++        this.adventure$deathMessage = deathMessage != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(deathMessage) : net.kyori.adventure.text.Component.empty(); // Paper
      }
  
      @NotNull
@@ -2332,7 +2340,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public void setDeathMessage(@Nullable String deathMessage) {
          this.deathMessage = deathMessage;
-+        this.adventure$deathMessage = deathMessage != null ? org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(deathMessage) : net.kyori.adventure.text.Component.empty(); // Paper
++        this.adventure$deathMessage = deathMessage != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(deathMessage) : net.kyori.adventure.text.Component.empty(); // Paper
      }
  
      /**
@@ -2350,7 +2358,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -
 +    // Paper start //TODO: add translation API to drop String deathMessage in favor of just Adventure
 +    private static String getDeathMessageString(net.kyori.adventure.text.Component component) {
-+        return org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(component);
++        return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(component);
 +    }
 +    // Paper end
      /**
@@ -2495,7 +2503,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @NotNull
 +    @Deprecated // Paper
 +    public String getKickMessage() {
-+        return org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.message); // Paper
++        return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.message); // Paper
 +    }
 +
 +    /**
@@ -2506,7 +2514,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     */
 +    @Deprecated // Paper
 +    public void setKickMessage(@NotNull final String message) {
-+        this.message = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message); // Paper
++        this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message); // Paper
 +    }
 +
      /**
@@ -2529,7 +2537,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public void disallow(@NotNull final Result result, @NotNull final String message) {
          this.result = result;
 -        this.message = message;
-+        this.message = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message); // Paper
++        this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message); // Paper
      }
  
      /**
@@ -2538,7 +2546,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public void disallow(@NotNull final PlayerPreLoginEvent.Result result, @NotNull final String message) {
          this.result = result == null ? null : Result.valueOf(result.name());
 -        this.message = message;
-+        this.message = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message); // Paper
++        this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message); // Paper
      }
  
      /**
@@ -2586,7 +2594,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper end
      public PlayerJoinEvent(@NotNull final Player playerJoined, @Nullable final String joinMessage) {
          super(playerJoined);
-+        this.joinMessage = joinMessage != null ? org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(joinMessage) : null; // Paper end
++        this.joinMessage = joinMessage != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(joinMessage) : null; // Paper end
 +    }
 +
 +    // Paper start
@@ -2619,7 +2627,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public String getJoinMessage() {
 -        return joinMessage;
-+        return this.joinMessage == null ? null : org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.joinMessage); // Paper
++        return this.joinMessage == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.joinMessage); // Paper
      }
  
      /**
@@ -2631,7 +2639,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public void setJoinMessage(@Nullable String joinMessage) {
 -        this.joinMessage = joinMessage;
-+        this.joinMessage = joinMessage != null ? org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(joinMessage) : null; // Paper
++        this.joinMessage = joinMessage != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(joinMessage) : null; // Paper
      }
  
      @NotNull
@@ -2652,8 +2660,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public PlayerKickEvent(@NotNull final Player playerKicked, @NotNull final String kickReason, @NotNull final String leaveMessage) {
 +        super(playerKicked);
-+        this.kickReason = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(kickReason); // Paper
-+        this.leaveMessage = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(leaveMessage); // Paper
++        this.kickReason = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(kickReason); // Paper
++        this.leaveMessage = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(leaveMessage); // Paper
 +        this.cancel = false;
 +    }
 +    // Paper start
@@ -2711,7 +2719,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public String getReason() {
 -        return kickReason;
-+        return org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.kickReason); // Paper
++        return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.kickReason); // Paper
      }
  
      /**
@@ -2724,7 +2732,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public String getLeaveMessage() {
 -        return leaveMessage;
-+        return org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.leaveMessage); // Paper
++        return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.leaveMessage); // Paper
      }
  
      @Override
@@ -2737,7 +2745,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public void setReason(@NotNull String kickReason) {
 -        this.kickReason = kickReason;
-+        this.kickReason = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(kickReason); // Paper
++        this.kickReason = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(kickReason); // Paper
      }
  
      /**
@@ -2749,7 +2757,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public void setLeaveMessage(@NotNull String leaveMessage) {
 -        this.leaveMessage = leaveMessage;
-+        this.leaveMessage = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(leaveMessage); // Paper
++        this.leaveMessage = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(leaveMessage); // Paper
      }
  
      @NotNull
@@ -2812,7 +2820,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public PlayerLoginEvent(@NotNull final Player player, @NotNull String hostname, @NotNull final InetAddress address, @NotNull final Result result, @NotNull final String message, @NotNull final InetAddress realAddress) { // Spigot
          this(player, hostname, address, realAddress); // Spigot
          this.result = result;
-+        this.message = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message); // Paper
++        this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message); // Paper
 +    }
 +
 +    // Paper start
@@ -2865,7 +2873,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public String getKickMessage() {
 -        return message;
-+        return org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.message); // Paper
++        return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.message); // Paper
      }
  
      /**
@@ -2877,7 +2885,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public void setKickMessage(@NotNull final String message) {
 -        this.message = message;
-+        this.message = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message); // Paper
++        this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message); // Paper
      }
  
      /**
@@ -2899,7 +2907,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper start
      public void disallow(@NotNull final Result result, @NotNull final String message) {
 +        this.result = result;
-+        this.message = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message);
++        this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message);
 +    }
 +    /**
 +     * Disallows the player from logging in, with the given reason
@@ -2981,7 +2989,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
 +    @NotNull
 +    public String getKickMessage() {
-+        return org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.message); // Paper
++        return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.message); // Paper
 +    }
 +
 +    /**
@@ -2992,7 +3000,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     */
 +    @Deprecated // Paper
 +    public void setKickMessage(@NotNull final String message) {
-+        this.message = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message); // Paper
++        this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message); // Paper
 +    }
 +
      /**
@@ -3015,7 +3023,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public void disallow(@NotNull final Result result, @NotNull final String message) {
          this.result = result;
 -        this.message = message;
-+        this.message = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message); // Paper
++        this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message); // Paper
      }
  
      /**
@@ -3033,7 +3041,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public PlayerQuitEvent(@NotNull final Player who, @Nullable final String quitMessage) {
          super(who);
-+        this.quitMessage = quitMessage != null ? org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(quitMessage) : null; // Paper
++        this.quitMessage = quitMessage != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(quitMessage) : null; // Paper
 +    }
 +    // Paper start
 +    public PlayerQuitEvent(@NotNull final Player who, @Nullable final net.kyori.adventure.text.Component quitMessage) {
@@ -3070,7 +3078,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public String getQuitMessage() {
 -        return quitMessage;
-+        return this.quitMessage == null ? null : org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.quitMessage); // Paper
++        return this.quitMessage == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.quitMessage); // Paper
      }
  
      /**
@@ -3082,7 +3090,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public void setQuitMessage(@Nullable String quitMessage) {
 -        this.quitMessage = quitMessage;
-+        this.quitMessage = quitMessage != null ? org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(quitMessage) : null; // Paper
++        this.quitMessage = quitMessage != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(quitMessage) : null; // Paper
      }
  
      @NotNull
@@ -3107,7 +3115,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public BroadcastMessageEvent(boolean isAsync, @NotNull String message, @NotNull Set<CommandSender> recipients) {
 +        // Paper start
 +        super(isAsync);
-+        this.message = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message);
++        this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message);
 +        this.recipients = recipients;
 +    }
 +
@@ -3152,7 +3160,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public String getMessage() {
 -        return message;
-+        return org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.message); // Paper
++        return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.message); // Paper
      }
  
      /**
@@ -3164,7 +3172,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public void setMessage(@NotNull String message) {
 -        this.message = message;
-+        this.message = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message); // Paper
++        this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message); // Paper
      }
  
      /**
@@ -3187,7 +3195,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          Validate.isTrue(numPlayers >= 0, "Cannot have negative number of players online", numPlayers);
          this.address = address;
 -        this.motd = motd;
-+        this.motd = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(motd); // Paper
++        this.motd = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(motd); // Paper
          this.numPlayers = numPlayers;
          this.maxPlayers = maxPlayers;
      }
@@ -3202,7 +3210,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        super(true);
 +        this.numPlayers = MAGIC_PLAYER_COUNT;
 +        this.address = address;
-+        this.motd = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(motd); // Paper
++        this.motd = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(motd); // Paper
 +        this.maxPlayers = maxPlayers;
 +    }
 +    // Paper start
@@ -3260,7 +3268,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public String getMotd() {
 -        return motd;
-+        return org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.motd); // Paper
++        return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.motd); // Paper
      }
  
      /**
@@ -3272,7 +3280,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public void setMotd(@NotNull String motd) {
 -        this.motd = motd;
-+        this.motd = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(motd); // Paper
++        this.motd = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(motd); // Paper
      }
  
      /**
@@ -3292,7 +3300,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
       */
      @NotNull
 +    public /*abstract*/ net.kyori.adventure.text.Component title() {
-+        return org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(this.getTitle());
++        return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(this.getTitle());
 +    }
 +    // Paper end
 +
@@ -3764,7 +3772,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          setRawType(type);
          this.visible = visible;
 -        this.caption = caption;
-+        this.caption = caption == null ? null : org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(caption); // Paper
++        this.caption = caption == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(caption); // Paper
      }
 +    // Paper start
 +    /**
@@ -3808,7 +3816,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          setType(type);
          this.visible = visible;
 -        this.caption = caption;
-+        this.caption = caption == null ? null : org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(caption); // Paper
++        this.caption = caption == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(caption); // Paper
      }
  
      /**
@@ -3844,7 +3852,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public String getCaption() {
 -        return caption;
-+        return this.caption == null ? null : org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.caption); // Paper
++        return this.caption == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.caption); // Paper
      }
  
      /**
@@ -3856,7 +3864,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public void setCaption(@Nullable String caption) {
 -        this.caption = caption;
-+        this.caption = caption == null ? null : org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(caption); // Paper
++        this.caption = caption == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(caption); // Paper
      }
  
      /**
diff --git a/patches/api/Make-the-default-permission-message-configurable.patch b/patches/api/Make-the-default-permission-message-configurable.patch
index ad25ffa9fc..511e252c8b 100644
--- a/patches/api/Make-the-default-permission-message-configurable.patch
+++ b/patches/api/Make-the-default-permission-message-configurable.patch
@@ -54,7 +54,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -            target.sendMessage(ChatColor.RED + "I'm sorry, but you do not have permission to perform this command. Please contact the server administrators if you believe that this is a mistake.");
              // Paper start - use components for permissionMessage
 -        } else if (!permissionMessage.equals(net.kyori.adventure.text.Component.empty())) {
-+        net.kyori.adventure.text.Component permissionMessage = this.permissionMessage != null ? this.permissionMessage : io.papermc.paper.text.PaperComponents.legacySectionSerializer().deserialize(Bukkit.getPermissionMessage());
++        net.kyori.adventure.text.Component permissionMessage = this.permissionMessage != null ? this.permissionMessage : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(Bukkit.getPermissionMessage());
 +        if (!permissionMessage.equals(net.kyori.adventure.text.Component.empty())) {
              target.sendMessage(permissionMessage.replaceText(net.kyori.adventure.text.TextReplacementConfig.builder().matchLiteral("<permission>").replacement(permission).build()));
              // Paper end
diff --git a/patches/api/PlayerDeathEvent-getItemsToKeep.patch b/patches/api/PlayerDeathEvent-getItemsToKeep.patch
index 6174332404..4d387d1cec 100644
--- a/patches/api/PlayerDeathEvent-getItemsToKeep.patch
+++ b/patches/api/PlayerDeathEvent-getItemsToKeep.patch
@@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          this(player, drops, droppedExp, 0, deathMessage);
      }
 @@ -0,0 +0,0 @@ public class PlayerDeathEvent extends EntityDeathEvent {
-         this.adventure$deathMessage = deathMessage != null ? org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(deathMessage) : net.kyori.adventure.text.Component.empty(); // Paper
+         this.adventure$deathMessage = deathMessage != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(deathMessage) : net.kyori.adventure.text.Component.empty(); // Paper
      }
  
 +    @Deprecated // Paper
diff --git a/patches/api/ProfileWhitelistVerifyEvent.patch b/patches/api/ProfileWhitelistVerifyEvent.patch
index 8691191c94..617d89de3d 100644
--- a/patches/api/ProfileWhitelistVerifyEvent.patch
+++ b/patches/api/ProfileWhitelistVerifyEvent.patch
@@ -40,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +import com.destroystokyo.paper.profile.PlayerProfile;
 +import net.kyori.adventure.text.Component;
-+import org.bukkit.Bukkit;
++import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
 +import org.bukkit.event.Event;
 +import org.bukkit.event.HandlerList;
 +import org.jetbrains.annotations.NotNull;
@@ -62,7 +62,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    @Deprecated
 +    public ProfileWhitelistVerifyEvent(@NotNull final PlayerProfile profile, boolean whitelistEnabled, boolean whitelisted, boolean isOp, @Nullable String kickMessage) {
-+        this(profile, whitelistEnabled, whitelisted, isOp, kickMessage == null ? null : Bukkit.getUnsafe().legacyComponentSerializer().deserialize(kickMessage));
++        this(profile, whitelistEnabled, whitelisted, isOp, kickMessage == null ? null : LegacyComponentSerializer.legacySection().deserialize(kickMessage));
 +    }
 +
 +    public ProfileWhitelistVerifyEvent(@NotNull final PlayerProfile profile, boolean whitelistEnabled, boolean whitelisted, boolean isOp, @Nullable Component kickMessage) {
@@ -80,7 +80,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated
 +    @Nullable
 +    public String getKickMessage() {
-+        return this.kickMessage == null ? null : Bukkit.getUnsafe().legacyComponentSerializer().serialize(kickMessage);
++        return this.kickMessage == null ? null : LegacyComponentSerializer.legacySection().serialize(kickMessage);
 +    }
 +
 +    /**
@@ -89,7 +89,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     */
 +    @Deprecated
 +    public void setKickMessage(@Nullable String kickMessage) {
-+        this.kickMessage(kickMessage == null ? null : Bukkit.getUnsafe().legacyComponentSerializer().deserialize(kickMessage));
++        this.kickMessage(kickMessage == null ? null : LegacyComponentSerializer.legacySection().deserialize(kickMessage));
 +    }
 +
 +    /**
diff --git a/patches/api/Timings-v2.patch b/patches/api/Timings-v2.patch
index 457577c6be..40c0d8cff5 100644
--- a/patches/api/Timings-v2.patch
+++ b/patches/api/Timings-v2.patch
@@ -2839,7 +2839,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/UnsafeValues.java
 +++ b/src/main/java/org/bukkit/UnsafeValues.java
 @@ -0,0 +0,0 @@ public interface UnsafeValues {
-     net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer legacyComponentSerializer();
+     @Deprecated(forRemoval = true) net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer legacyComponentSerializer();
      // Paper end
  
 +    void reportTimings(); // Paper
diff --git a/patches/server/API-for-creating-command-sender-which-forwards-feedb.patch b/patches/server/API-for-creating-command-sender-which-forwards-feedb.patch
index 82bc4da31e..7fb3bb2beb 100644
--- a/patches/server/API-for-creating-command-sender-which-forwards-feedb.patch
+++ b/patches/server/API-for-creating-command-sender-which-forwards-feedb.patch
@@ -13,12 +13,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +package io.papermc.paper.commands;
 +
 +import io.papermc.paper.adventure.PaperAdventure;
-+import io.papermc.paper.text.PaperComponents;
 +import java.util.UUID;
 +import java.util.function.Consumer;
 +import net.kyori.adventure.audience.MessageType;
 +import net.kyori.adventure.identity.Identity;
 +import net.kyori.adventure.text.Component;
++import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
 +import net.minecraft.commands.CommandSource;
 +import net.minecraft.commands.CommandSourceStack;
 +import net.minecraft.network.chat.TextComponent;
@@ -45,7 +45,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    @Override
 +    public void sendMessage(final String message) {
-+        this.sendMessage(PaperComponents.legacySectionSerializer().deserialize(message));
++        this.sendMessage(LegacyComponentSerializer.legacySection().deserialize(message));
 +    }
 +
 +    @Override
diff --git a/patches/server/Add-PlayerKickEvent-causes.patch b/patches/server/Add-PlayerKickEvent-causes.patch
index f01c709287..7ba1a38fe7 100644
--- a/patches/server/Add-PlayerKickEvent-causes.patch
+++ b/patches/server/Add-PlayerKickEvent-causes.patch
@@ -100,12 +100,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      public void disconnect(String s) {
          // Paper start
--        this.disconnect(PaperAdventure.LEGACY_SECTION_UXRC.deserialize(s));
-+        this.disconnect(PaperAdventure.LEGACY_SECTION_UXRC.deserialize(s), org.bukkit.event.player.PlayerKickEvent.Cause.UNKNOWN);
+-        this.disconnect(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(s));
++        this.disconnect(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(s), org.bukkit.event.player.PlayerKickEvent.Cause.UNKNOWN);
 +    }
 +
 +    public void disconnect(String s, PlayerKickEvent.Cause cause) {
-+        this.disconnect(PaperAdventure.LEGACY_SECTION_UXRC.deserialize(s), cause);
++        this.disconnect(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(s), cause);
      }
  
      public void disconnect(final Component reason) {
diff --git a/patches/server/Add-option-for-console-having-all-permissions.patch b/patches/server/Add-option-for-console-having-all-permissions.patch
index d3ad3d2d19..bba6948e03 100644
--- a/patches/server/Add-option-for-console-having-all-permissions.patch
+++ b/patches/server/Add-option-for-console-having-all-permissions.patch
@@ -24,7 +24,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +++ b/src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java
 @@ -0,0 +0,0 @@ public class CraftConsoleCommandSender extends ServerCommandSender implements Co
      public void sendMessage(final net.kyori.adventure.identity.Identity identity, final net.kyori.adventure.text.Component message, final net.kyori.adventure.audience.MessageType type) {
-         this.sendRawMessage(io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.serialize(message));
+         this.sendRawMessage(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(message));
      }
 +
 +    @Override
diff --git a/patches/server/Add-support-for-hex-color-codes-in-console.patch b/patches/server/Add-support-for-hex-color-codes-in-console.patch
index bf7bf78956..6e17dee51e 100644
--- a/patches/server/Add-support-for-hex-color-codes-in-console.patch
+++ b/patches/server/Add-support-for-hex-color-codes-in-console.patch
@@ -27,11 +27,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
  package com.destroystokyo.paper.console;
  
-+import io.papermc.paper.adventure.PaperAdventure;
 +import io.papermc.paper.console.HexFormattingConverter;
 +import net.kyori.adventure.audience.MessageType;
 +import net.kyori.adventure.identity.Identity;
 +import net.kyori.adventure.text.Component;
++import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
  import org.apache.logging.log4j.LogManager;
  import org.apache.logging.log4j.Logger;
  import org.bukkit.craftbukkit.command.CraftConsoleCommandSender;
@@ -41,7 +41,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public void sendRawMessage(String message) {
 -        // TerminalConsoleAppender supports color codes directly in log messages
 -        LOGGER.info(message);
-+        final Component msg = PaperAdventure.LEGACY_SECTION_UXRC.deserialize(message);
++        final Component msg = LegacyComponentSerializer.legacySection().deserialize(message);
 +        this.sendMessage(Identity.nil(), msg, MessageType.SYSTEM);
 +    }
 +
@@ -277,7 +277,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void sendMessage(Component message, UUID sender) {
--        MinecraftServer.LOGGER.info(io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.serialize(io.papermc.paper.adventure.PaperAdventure.asAdventure(message))); // Paper - Log message with colors
+-        MinecraftServer.LOGGER.info(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(io.papermc.paper.adventure.PaperAdventure.asAdventure(message))); // Paper - Log message with colors
 +        MinecraftServer.LOGGER.info(io.papermc.paper.console.HexFormattingConverter.SERIALIZER.serialize(io.papermc.paper.adventure.PaperAdventure.asAdventure(message))); // Paper - Log message with colors
      }
  
diff --git a/patches/server/Adventure.patch b/patches/server/Adventure.patch
index e07be043f8..55982c5ad3 100644
--- a/patches/server/Adventure.patch
+++ b/patches/server/Adventure.patch
@@ -39,6 +39,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import java.util.List;
 +import net.kyori.adventure.text.Component;
 +import net.kyori.adventure.text.TextComponent;
++import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
++import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
 +import net.minecraft.network.chat.MutableComponent;
 +import net.minecraft.network.chat.Style;
 +import net.minecraft.util.FormattedCharSequence;
@@ -82,7 +84,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    @Override
 +    public String getString() {
-+        return PaperAdventure.PLAIN.serialize(this.adventure);
++        return PlainTextComponentSerializer.plainText().serialize(this.adventure);
 +    }
 +
 +    @Override
@@ -108,7 +110,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    public static class Serializer implements JsonSerializer<AdventureComponent> {
 +        @Override
 +        public JsonElement serialize(final AdventureComponent src, final Type type, final JsonSerializationContext context) {
-+            return PaperAdventure.GSON.serializer().toJsonTree(src.adventure, Component.class);
++            return GsonComponentSerializer.gson().serializer().toJsonTree(src.adventure, Component.class);
 +        }
 +    }
 +}
@@ -133,6 +135,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import net.kyori.adventure.text.Component;
 +import net.kyori.adventure.text.TextReplacementConfig;
 +import net.kyori.adventure.text.event.ClickEvent;
++import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
 +import net.minecraft.server.MinecraftServer;
 +import net.minecraft.server.level.ServerPlayer;
 +import org.bukkit.craftbukkit.entity.CraftPlayer;
@@ -195,14 +198,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                this.processModern(
 +                    legacyRenderer(se.getFormat()),
 +                    this.viewersFromLegacy(se.getRecipients()),
-+                    PaperAdventure.LEGACY_SECTION_UXRC.deserialize(se.getMessage()),
++                    LegacyComponentSerializer.legacySection().deserialize(se.getMessage()),
 +                    se.isCancelled()
 +                );
 +            } else {
 +                this.processModern(
 +                    legacyRenderer(ae.getFormat()),
 +                    this.viewersFromLegacy(ae.getRecipients()),
-+                    PaperAdventure.LEGACY_SECTION_UXRC.deserialize(ae.getMessage()),
++                    LegacyComponentSerializer.legacySection().deserialize(ae.getMessage()),
 +                    ae.isCancelled()
 +                );
 +            }
@@ -284,7 +287,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        if (DEFAULT_LEGACY_FORMAT.equals(format)) {
 +            return ChatRenderer.defaultRenderer();
 +        }
-+        return ChatRenderer.viewerUnaware((player, displayName, message) -> PaperAdventure.LEGACY_SECTION_UXRC.deserialize(String.format(format, legacyDisplayName((CraftPlayer) player), PaperAdventure.LEGACY_SECTION_UXRC.serialize(message))).replaceText(URL_REPLACEMENT_CONFIG));
++        return ChatRenderer.viewerUnaware((player, displayName, message) -> LegacyComponentSerializer.legacySection().deserialize(String.format(format, legacyDisplayName((CraftPlayer) player), LegacyComponentSerializer.legacySection().serialize(message))).replaceText(URL_REPLACEMENT_CONFIG));
 +    }
 +
 +    private void queueIfAsyncOrRunImmediately(final Waitable<Void> waitable) {
@@ -318,6 +321,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package io.papermc.paper.adventure;
 +
++import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
 +import net.minecraft.server.level.ServerPlayer;
 +import org.bukkit.ChatColor;
 +import org.bukkit.craftbukkit.entity.CraftPlayer;
@@ -334,9 +338,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        final String legacy = player.displayName;
 +        if (legacy != null) {
 +            // thank you for being worse than wet socks, Bukkit
-+            return PaperAdventure.LEGACY_SECTION_UXRC.serialize(player.adventure$displayName) + ChatColor.getLastColors(player.displayName);
++            return LegacyComponentSerializer.legacySection().serialize(player.adventure$displayName) + ChatColor.getLastColors(player.displayName);
 +        }
-+        return PaperAdventure.LEGACY_SECTION_UXRC.serialize(player.adventure$displayName);
++        return LegacyComponentSerializer.legacySection().serialize(player.adventure$displayName);
 +    }
 +}
 diff --git a/src/main/java/io/papermc/paper/adventure/LazyChatAudienceSet.java b/src/main/java/io/papermc/paper/adventure/LazyChatAudienceSet.java
@@ -371,100 +375,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return audiences;
 +    }
 +}
-diff --git a/src/main/java/io/papermc/paper/adventure/NBTLegacyHoverEventSerializer.java b/src/main/java/io/papermc/paper/adventure/NBTLegacyHoverEventSerializer.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
---- /dev/null
-+++ b/src/main/java/io/papermc/paper/adventure/NBTLegacyHoverEventSerializer.java
-@@ -0,0 +0,0 @@
-+package io.papermc.paper.adventure;
-+
-+import com.mojang.brigadier.exceptions.CommandSyntaxException;
-+import java.io.IOException;
-+import java.util.UUID;
-+import net.kyori.adventure.key.Key;
-+import net.kyori.adventure.nbt.api.BinaryTagHolder;
-+import net.kyori.adventure.text.Component;
-+import net.kyori.adventure.text.event.HoverEvent;
-+import net.kyori.adventure.text.serializer.gson.LegacyHoverEventSerializer;
-+import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer;
-+import net.kyori.adventure.util.Codec;
-+import net.minecraft.nbt.CompoundTag;
-+import net.minecraft.nbt.Tag;
-+import net.minecraft.nbt.TagParser;
-+
-+final class NBTLegacyHoverEventSerializer implements LegacyHoverEventSerializer {
-+    public static final NBTLegacyHoverEventSerializer INSTANCE = new NBTLegacyHoverEventSerializer();
-+    private static final Codec<CompoundTag, String, CommandSyntaxException, RuntimeException> SNBT_CODEC = Codec.of(TagParser::parseTag, Tag::toString);
-+
-+    static final String ITEM_TYPE = "id";
-+    static final String ITEM_COUNT = "Count";
-+    static final String ITEM_TAG = "tag";
-+
-+    static final String ENTITY_NAME = "name";
-+    static final String ENTITY_TYPE = "type";
-+    static final String ENTITY_ID = "id";
-+
-+    NBTLegacyHoverEventSerializer() {
-+    }
-+
-+    @Override
-+    public HoverEvent.ShowItem deserializeShowItem(final Component input) throws IOException {
-+        final String raw = PlainComponentSerializer.plain().serialize(input);
-+        try {
-+            final CompoundTag contents = SNBT_CODEC.decode(raw);
-+            final CompoundTag tag = contents.getCompound(ITEM_TAG);
-+            return HoverEvent.ShowItem.of(
-+                Key.key(contents.getString(ITEM_TYPE)),
-+                contents.contains(ITEM_COUNT) ? contents.getByte(ITEM_COUNT) : 1,
-+                tag.isEmpty() ? null : BinaryTagHolder.encode(tag, SNBT_CODEC)
-+            );
-+        } catch (final CommandSyntaxException ex) {
-+            throw new IOException(ex);
-+        }
-+    }
-+
-+    @Override
-+    public HoverEvent.ShowEntity deserializeShowEntity(final Component input, final Codec.Decoder<Component, String, ? extends RuntimeException> componentCodec) throws IOException {
-+        final String raw = PlainComponentSerializer.plain().serialize(input);
-+        try {
-+            final CompoundTag contents = SNBT_CODEC.decode(raw);
-+            return HoverEvent.ShowEntity.of(
-+                Key.key(contents.getString(ENTITY_TYPE)),
-+                UUID.fromString(contents.getString(ENTITY_ID)),
-+                componentCodec.decode(contents.getString(ENTITY_NAME))
-+            );
-+        } catch (final CommandSyntaxException ex) {
-+            throw new IOException(ex);
-+        }
-+    }
-+
-+    @Override
-+    public Component serializeShowItem(final HoverEvent.ShowItem input) throws IOException {
-+        final CompoundTag tag = new CompoundTag();
-+        tag.putString(ITEM_TYPE, input.item().asString());
-+        tag.putByte(ITEM_COUNT, (byte) input.count());
-+        if (input.nbt() != null) {
-+            try {
-+                tag.put(ITEM_TAG, input.nbt().get(SNBT_CODEC));
-+            } catch (final CommandSyntaxException ex) {
-+                throw new IOException(ex);
-+            }
-+        }
-+        return Component.text(SNBT_CODEC.encode(tag));
-+    }
-+
-+    @Override
-+    public Component serializeShowEntity(final HoverEvent.ShowEntity input, final Codec.Encoder<Component, String, ? extends RuntimeException> componentCodec) throws IOException {
-+        final CompoundTag tag = new CompoundTag();
-+        tag.putString(ENTITY_ID, input.id().toString());
-+        tag.putString(ENTITY_TYPE, input.type().asString());
-+        if (input.name() != null) {
-+            tag.putString(ENTITY_NAME, componentCodec.encode(input.name()));
-+        }
-+        return Component.text(SNBT_CODEC.encode(tag));
-+    }
-+}
 diff --git a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
@@ -564,17 +474,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            }
 +        })
 +        .build();
-+    public static final LegacyComponentSerializer LEGACY_SECTION_UXRC = LegacyComponentSerializer.builder().flattener(FLATTENER).hexColors().useUnusualXRepeatedCharacterHexFormat().build();
-+    @Deprecated
-+    public static final PlainComponentSerializer PLAIN_COMPONENT = PlainComponentSerializer.builder().flattener(FLATTENER).build();
-+    public static final PlainTextComponentSerializer PLAIN = PlainTextComponentSerializer.builder().flattener(FLATTENER).build();
-+    public static final GsonComponentSerializer GSON = GsonComponentSerializer.builder()
-+        .legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.INSTANCE)
-+        .build();
-+    public static final GsonComponentSerializer COLOR_DOWNSAMPLING_GSON = GsonComponentSerializer.builder()
-+        .legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.INSTANCE)
-+        .downsampleColors()
-+        .build();
++    @Deprecated public static final PlainComponentSerializer PLAIN = PlainComponentSerializer.builder().flattener(FLATTENER).build();
 +    private static final Codec<CompoundTag, String, IOException, IOException> NBT_CODEC = new Codec<CompoundTag, String, IOException, IOException>() {
 +        @Override
 +        public @NotNull CompoundTag decode(final @NotNull String encoded) throws IOException {
@@ -611,7 +511,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    // Component
 +
 +    public static Component asAdventure(final net.minecraft.network.chat.Component component) {
-+        return component == null ? Component.empty() : GSON.serializer().fromJson(net.minecraft.network.chat.Component.Serializer.toJsonTree(component), Component.class);
++        return component == null ? Component.empty() : GsonComponentSerializer.gson().serializer().fromJson(net.minecraft.network.chat.Component.Serializer.toJsonTree(component), Component.class);
 +    }
 +
 +    public static ArrayList<Component> asAdventure(final List<net.minecraft.network.chat.Component> vanillas) {
@@ -641,7 +541,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    public static net.minecraft.network.chat.Component asVanilla(final Component component) {
 +        if (component == null) return null;
 +        if (true) return new AdventureComponent(component);
-+        return net.minecraft.network.chat.Component.Serializer.fromJson(GSON.serializer().toJsonTree(component));
++        return net.minecraft.network.chat.Component.Serializer.fromJson(GsonComponentSerializer.gson().serializer().toJsonTree(component));
 +    }
 +
 +    public static List<net.minecraft.network.chat.Component> asVanilla(final List<Component> adventures) {
@@ -653,7 +553,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    public static String asJsonString(final Component component, final Locale locale) {
-+        return GSON.serialize(translated(component, locale));
++        return GsonComponentSerializer.gson().serialize(translated(component, locale));
 +    }
 +
 +    public static String asJsonString(final net.minecraft.network.chat.Component component, final Locale locale) {
@@ -664,7 +564,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    public static String asPlain(final Component component, final Locale locale) {
-+        return PLAIN.serialize(translated(component, locale));
++        return PlainTextComponentSerializer.plainText().serialize(translated(component, locale));
 +    }
 +
 +    private static Component translated(final Component component, final Locale locale) {
@@ -872,6 +772,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +import net.kyori.adventure.text.Component;
 +import net.kyori.adventure.text.serializer.ComponentSerializer;
++import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
 +
 +final class WrapperAwareSerializer implements ComponentSerializer<Component, Component, net.minecraft.network.chat.Component> {
 +    @Override
@@ -879,12 +780,240 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        if (input instanceof AdventureComponent) {
 +            return ((AdventureComponent) input).adventure;
 +        }
-+        return PaperAdventure.GSON.serializer().fromJson(net.minecraft.network.chat.Component.Serializer.toJsonTree(input), Component.class);
++        return GsonComponentSerializer.gson().serializer().fromJson(net.minecraft.network.chat.Component.Serializer.toJsonTree(input), Component.class);
 +    }
 +
 +    @Override
 +    public net.minecraft.network.chat.Component serialize(final Component component) {
-+        return net.minecraft.network.chat.Component.Serializer.fromJson(PaperAdventure.GSON.serializer().toJsonTree(component));
++        return net.minecraft.network.chat.Component.Serializer.fromJson(GsonComponentSerializer.gson().serializer().toJsonTree(component));
++    }
++}
+diff --git a/src/main/java/io/papermc/paper/adventure/providers/GsonComponentSerializerProviderImpl.java b/src/main/java/io/papermc/paper/adventure/providers/GsonComponentSerializerProviderImpl.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/adventure/providers/GsonComponentSerializerProviderImpl.java
+@@ -0,0 +0,0 @@
++package io.papermc.paper.adventure.providers;
++
++import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
++import org.jetbrains.annotations.NotNull;
++
++import java.util.function.Consumer;
++
++@SuppressWarnings("UnstableApiUsage") // permitted provider
++public class GsonComponentSerializerProviderImpl implements GsonComponentSerializer.Provider {
++
++    @Override
++    public @NotNull GsonComponentSerializer gson() {
++        return GsonComponentSerializer.builder()
++            .legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.INSTANCE)
++            .build();
++    }
++
++    @Override
++    public @NotNull GsonComponentSerializer gsonLegacy() {
++        return GsonComponentSerializer.builder()
++            .legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.INSTANCE)
++            .downsampleColors()
++            .build();
++    }
++
++    @Override
++    public @NotNull Consumer<GsonComponentSerializer.Builder> builder() {
++        return builder -> builder.legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.INSTANCE);
++    }
++}
+diff --git a/src/main/java/io/papermc/paper/adventure/providers/LegacyComponentSerializerProviderImpl.java b/src/main/java/io/papermc/paper/adventure/providers/LegacyComponentSerializerProviderImpl.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/adventure/providers/LegacyComponentSerializerProviderImpl.java
+@@ -0,0 +0,0 @@
++package io.papermc.paper.adventure.providers;
++
++import io.papermc.paper.adventure.PaperAdventure;
++import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
++import org.jetbrains.annotations.NotNull;
++
++import java.util.function.Consumer;
++
++@SuppressWarnings("UnstableApiUsage") // permitted provider
++public class LegacyComponentSerializerProviderImpl implements LegacyComponentSerializer.Provider {
++
++    @Override
++    public @NotNull LegacyComponentSerializer legacyAmpersand() {
++        return LegacyComponentSerializer.builder()
++            .flattener(PaperAdventure.FLATTENER)
++            .character(LegacyComponentSerializer.AMPERSAND_CHAR)
++            .hexColors()
++            .useUnusualXRepeatedCharacterHexFormat()
++            .build();
++    }
++
++    @Override
++    public @NotNull LegacyComponentSerializer legacySection() {
++        return LegacyComponentSerializer.builder()
++            .flattener(PaperAdventure.FLATTENER)
++            .character(LegacyComponentSerializer.SECTION_CHAR)
++            .hexColors()
++            .useUnusualXRepeatedCharacterHexFormat()
++            .build();
++    }
++
++    @Override
++    public @NotNull Consumer<LegacyComponentSerializer.Builder> legacy() {
++        return builder -> builder.flattener(PaperAdventure.FLATTENER);
++    }
++}
+diff --git a/src/main/java/io/papermc/paper/adventure/providers/MiniMessageProviderImpl.java b/src/main/java/io/papermc/paper/adventure/providers/MiniMessageProviderImpl.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/adventure/providers/MiniMessageProviderImpl.java
+@@ -0,0 +0,0 @@
++package io.papermc.paper.adventure.providers;
++
++import net.kyori.adventure.text.minimessage.MiniMessage;
++import org.jetbrains.annotations.NotNull;
++
++import java.util.function.Consumer;
++
++@SuppressWarnings("UnstableApiUsage") // permitted provider
++public class MiniMessageProviderImpl implements MiniMessage.Provider {
++
++    @Override
++    public @NotNull MiniMessage miniMessage() {
++        return MiniMessage.builder().build();
++    }
++
++    @Override
++    public @NotNull Consumer<MiniMessage.Builder> builder() {
++        return builder -> {};
++    }
++}
+diff --git a/src/main/java/io/papermc/paper/adventure/providers/NBTLegacyHoverEventSerializer.java b/src/main/java/io/papermc/paper/adventure/providers/NBTLegacyHoverEventSerializer.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/adventure/providers/NBTLegacyHoverEventSerializer.java
+@@ -0,0 +0,0 @@
++package io.papermc.paper.adventure.providers;
++
++import com.mojang.brigadier.exceptions.CommandSyntaxException;
++import net.kyori.adventure.key.Key;
++import net.kyori.adventure.nbt.api.BinaryTagHolder;
++import net.kyori.adventure.text.Component;
++import net.kyori.adventure.text.event.HoverEvent;
++import net.kyori.adventure.text.serializer.gson.LegacyHoverEventSerializer;
++import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
++import net.kyori.adventure.util.Codec;
++import net.minecraft.nbt.CompoundTag;
++import net.minecraft.nbt.Tag;
++import net.minecraft.nbt.TagParser;
++
++import java.io.IOException;
++import java.util.UUID;
++
++final class NBTLegacyHoverEventSerializer implements LegacyHoverEventSerializer {
++    public static final NBTLegacyHoverEventSerializer INSTANCE = new NBTLegacyHoverEventSerializer();
++    private static final Codec<CompoundTag, String, CommandSyntaxException, RuntimeException> SNBT_CODEC = Codec.codec(TagParser::parseTag, Tag::toString);
++
++    static final String ITEM_TYPE = "id";
++    static final String ITEM_COUNT = "Count";
++    static final String ITEM_TAG = "tag";
++
++    static final String ENTITY_NAME = "name";
++    static final String ENTITY_TYPE = "type";
++    static final String ENTITY_ID = "id";
++
++    NBTLegacyHoverEventSerializer() {
++    }
++
++    @Override
++    public HoverEvent.ShowItem deserializeShowItem(final Component input) throws IOException {
++        final String raw = PlainTextComponentSerializer.plainText().serialize(input);
++        try {
++            final CompoundTag contents = SNBT_CODEC.decode(raw);
++            final CompoundTag tag = contents.getCompound(ITEM_TAG);
++            return HoverEvent.ShowItem.of(
++                Key.key(contents.getString(ITEM_TYPE)),
++                contents.contains(ITEM_COUNT) ? contents.getByte(ITEM_COUNT) : 1,
++                tag.isEmpty() ? null : BinaryTagHolder.encode(tag, SNBT_CODEC)
++            );
++        } catch (final CommandSyntaxException ex) {
++            throw new IOException(ex);
++        }
++    }
++
++    @Override
++    public HoverEvent.ShowEntity deserializeShowEntity(final Component input, final Codec.Decoder<Component, String, ? extends RuntimeException> componentCodec) throws IOException {
++        final String raw = PlainTextComponentSerializer.plainText().serialize(input);
++        try {
++            final CompoundTag contents = SNBT_CODEC.decode(raw);
++            return HoverEvent.ShowEntity.of(
++                Key.key(contents.getString(ENTITY_TYPE)),
++                UUID.fromString(contents.getString(ENTITY_ID)),
++                componentCodec.decode(contents.getString(ENTITY_NAME))
++            );
++        } catch (final CommandSyntaxException ex) {
++            throw new IOException(ex);
++        }
++    }
++
++    @Override
++    public Component serializeShowItem(final HoverEvent.ShowItem input) throws IOException {
++        final CompoundTag tag = new CompoundTag();
++        tag.putString(ITEM_TYPE, input.item().asString());
++        tag.putByte(ITEM_COUNT, (byte) input.count());
++        if (input.nbt() != null) {
++            try {
++                tag.put(ITEM_TAG, input.nbt().get(SNBT_CODEC));
++            } catch (final CommandSyntaxException ex) {
++                throw new IOException(ex);
++            }
++        }
++        return Component.text(SNBT_CODEC.encode(tag));
++    }
++
++    @Override
++    public Component serializeShowEntity(final HoverEvent.ShowEntity input, final Codec.Encoder<Component, String, ? extends RuntimeException> componentCodec) throws IOException {
++        final CompoundTag tag = new CompoundTag();
++        tag.putString(ENTITY_ID, input.id().toString());
++        tag.putString(ENTITY_TYPE, input.type().asString());
++        if (input.name() != null) {
++            tag.putString(ENTITY_NAME, componentCodec.encode(input.name()));
++        }
++        return Component.text(SNBT_CODEC.encode(tag));
++    }
++}
+diff --git a/src/main/java/io/papermc/paper/adventure/providers/PlainTextComponentSerializerProviderImpl.java b/src/main/java/io/papermc/paper/adventure/providers/PlainTextComponentSerializerProviderImpl.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/adventure/providers/PlainTextComponentSerializerProviderImpl.java
+@@ -0,0 +0,0 @@
++package io.papermc.paper.adventure.providers;
++
++import io.papermc.paper.adventure.PaperAdventure;
++import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
++import org.jetbrains.annotations.NotNull;
++
++import java.util.function.Consumer;
++
++@SuppressWarnings("UnstableApiUsage") // permitted provider
++public class PlainTextComponentSerializerProviderImpl implements PlainTextComponentSerializer.Provider {
++
++    @Override
++    public @NotNull PlainTextComponentSerializer plainTextSimple() {
++        return PlainTextComponentSerializer.builder()
++            .flattener(PaperAdventure.FLATTENER)
++            .build();
++    }
++
++    @Override
++    public @NotNull Consumer<PlainTextComponentSerializer.Builder> plainText() {
++        return builder -> builder.flattener(PaperAdventure.FLATTENER);
 +    }
 +}
 diff --git a/src/main/java/net/kyori/adventure/bossbar/HackyBossBarPlatformBridge.java b/src/main/java/net/kyori/adventure/bossbar/HackyBossBarPlatformBridge.java
@@ -1259,7 +1388,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -        this.disconnect(CraftChatMessage.fromComponent(reason));
 +    public void disconnect(String s) {
 +        // Paper start
-+        this.disconnect(PaperAdventure.LEGACY_SECTION_UXRC.deserialize(s));
++        this.disconnect(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(s));
      }
 -    // CraftBukkit end
  
@@ -1491,7 +1620,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          } else if (!this.isWhiteListed(gameprofile)) {
              chatmessage = new TranslatableComponent("multiplayer.disconnect.not_whitelisted");
 -            event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig.whitelistMessage); // Spigot
-+            event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, PaperAdventure.LEGACY_SECTION_UXRC.deserialize(org.spigotmc.SpigotConfig.whitelistMessage)); // Spigot // Paper - Adventure
++            event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.whitelistMessage)); // Spigot // Paper - Adventure
          } else if (this.getIpBans().isBanned(socketaddress) && !this.getIpBans().get(socketaddress).hasExpired()) {
              IpBanListEntry ipbanentry = this.ipBans.get(socketaddress);
  
@@ -1505,7 +1634,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              // return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile) ? new ChatMessage("multiplayer.disconnect.server_full") : null;
              if (this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile)) {
 -                event.disallow(PlayerLoginEvent.Result.KICK_FULL, org.spigotmc.SpigotConfig.serverFullMessage); // Spigot
-+                event.disallow(PlayerLoginEvent.Result.KICK_FULL, PaperAdventure.LEGACY_SECTION_UXRC.deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure
++                event.disallow(PlayerLoginEvent.Result.KICK_FULL, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure
              }
          }
  
@@ -1657,7 +1786,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
 +    public net.kyori.adventure.text.Component shutdownMessage() {
 +        String msg = getShutdownMessage();
-+        return msg != null ? io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(msg) : null;
++        return msg != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(msg) : null;
 +    }
 +    // Paper end
 +    @Override
@@ -1672,7 +1801,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Deprecated // Paper
      public int broadcast(String message, String permission) {
 +        // Paper start - Adventure
-+        return this.broadcast(io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(message), permission);
++        return this.broadcast(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message), permission);
 +    }
 +
 +    @Override
@@ -1977,21 +2106,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @Override
 +    public String[] getLines() {
 +        this.loadLines();
-+        return this.lines.stream().map(io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC::serialize).toArray(String[]::new); // Paper
++        return this.lines.stream().map(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection()::serialize).toArray(String[]::new); // Paper
 +    }
 +
      @Override
      public String getLine(int index) throws IndexOutOfBoundsException {
 -        return this.getLines()[index];
 +        this.loadLines();
-+        return io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.serialize(this.lines.get(index)); // Paper
++        return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.lines.get(index)); // Paper
      }
  
      @Override
      public void setLine(int index, String line) throws IndexOutOfBoundsException {
 -        this.getLines()[index] = line;
 +        this.loadLines();
-+        this.lines.set(index, line != null ? io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(line) : net.kyori.adventure.text.Component.empty()); // Paper
++        this.lines.set(index, line != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(line) : net.kyori.adventure.text.Component.empty()); // Paper
      }
  
      @Override
@@ -2081,7 +2210,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    // Paper start
 +    @Override
 +    public void sendMessage(final net.kyori.adventure.identity.Identity identity, final net.kyori.adventure.text.Component message, final net.kyori.adventure.audience.MessageType type) {
-+        this.sendRawMessage(io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.serialize(message));
++        this.sendRawMessage(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(message));
 +    }
 +    // Paper end
  }
@@ -2243,7 +2372,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -        String title = container.getBukkitView().getTitle();
 +        //String title = container.getBukkitView().getTitle(); // Paper - comment
 +        net.kyori.adventure.text.Component adventure$title = container.getBukkitView().title(); // Paper
-+        if (adventure$title == null) adventure$title = io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(container.getBukkitView().getTitle()); // Paper
++        if (adventure$title == null) adventure$title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(container.getBukkitView().getTitle()); // Paper
  
 -        player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, CraftChatMessage.fromString(title)[0]));
 +        //player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0])); // Paper // Paper - comment
@@ -2260,7 +2389,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +        //String title = inventory.getTitle(); // Paper - comment
 +        net.kyori.adventure.text.Component adventure$title = inventory.title(); // Paper
-+        if (adventure$title == null) adventure$title = io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(inventory.getTitle()); // Paper
++        if (adventure$title == null) adventure$title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(inventory.getTitle()); // Paper
 +        //player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0])); // Paper - comment
 +        player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper
          player.containerMenu = container;
@@ -2298,7 +2427,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Override
      public void setDisplayName(final String name) {
-+        this.getHandle().adventure$displayName = name != null ? io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(name) : net.kyori.adventure.text.Component.text(this.getName()); // Paper
++        this.getHandle().adventure$displayName = name != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(name) : net.kyori.adventure.text.Component.text(this.getName()); // Paper
          this.getHandle().displayName = name == null ? getName() : name;
      }
  
@@ -2340,26 +2469,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
      public String getPlayerListHeader() {
 -        return (this.playerListHeader == null) ? null : CraftChatMessage.fromComponent(playerListHeader);
-+        return (this.playerListHeader == null) ? null : io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.serialize(playerListHeader);
++        return (this.playerListHeader == null) ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(playerListHeader);
      }
  
      @Override
      public String getPlayerListFooter() {
 -        return (this.playerListFooter == null) ? null : CraftChatMessage.fromComponent(playerListFooter);
-+        return (this.playerListFooter == null) ? null : io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.serialize(playerListFooter); // Paper - Adventure
++        return (this.playerListFooter == null) ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(playerListFooter); // Paper - Adventure
      }
  
      @Override
      public void setPlayerListHeader(String header) {
 -        this.playerListHeader = CraftChatMessage.fromStringOrNull(header, true);
-+        this.playerListHeader = header == null ? null : io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(header); // Paper - Adventure
++        this.playerListHeader = header == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(header); // Paper - Adventure
          this.updatePlayerListHeaderFooter();
      }
  
      @Override
      public void setPlayerListFooter(String footer) {
 -        this.playerListFooter = CraftChatMessage.fromStringOrNull(footer, true);
-+        this.playerListFooter = footer == null ? null : io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(footer); // Paper - Adventure
++        this.playerListFooter = footer == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(footer); // Paper - Adventure
          this.updatePlayerListHeaderFooter();
      }
  
@@ -2367,8 +2496,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public void setPlayerListHeaderFooter(String header, String footer) {
 -        this.playerListHeader = CraftChatMessage.fromStringOrNull(header, true);
 -        this.playerListFooter = CraftChatMessage.fromStringOrNull(footer, true);
-+        this.playerListHeader = header == null ? null : io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(header); // Paper - Adventure
-+        this.playerListFooter = footer == null ? null : io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(footer); // Paper - Adventure
++        this.playerListHeader = header == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(header); // Paper - Adventure
++        this.playerListFooter = footer == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(footer); // Paper - Adventure
          this.updatePlayerListHeaderFooter();
      }
  
@@ -2795,7 +2924,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              Validate.notNull(title, "Title cannot be null");
              this.items = NonNullList.withSize(size, ItemStack.EMPTY);
              this.title = title;
-+            this.adventure$title = io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(title);
++            this.adventure$title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(title);
              this.viewers = new ArrayList<HumanEntity>();
              this.owner = owner;
              this.type = InventoryType.CHEST;
@@ -2805,7 +2934,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        public MinecraftInventory(final InventoryHolder owner, final int size, final net.kyori.adventure.text.Component title) {
 +            Validate.notNull(title, "Title cannot be null");
 +            this.items = NonNullList.withSize(size, ItemStack.EMPTY);
-+            this.title = io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.serialize(title);
++            this.title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(title);
 +            this.adventure$title = title;
 +            this.viewers = new ArrayList<HumanEntity>();
 +            this.owner = owner;
@@ -2943,30 +3072,30 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    // Paper start
 +    @Override
 +    public net.kyori.adventure.text.Component title() {
-+        return this.title == null ? null : io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(this.title);
++        return this.title == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(this.title);
 +    }
 +
 +    @Override
 +    public org.bukkit.inventory.meta.BookMeta title(net.kyori.adventure.text.Component title) {
-+        this.setTitle(title == null ? null : io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.serialize(title));
++        this.setTitle(title == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(title));
 +        return this;
 +    }
 +
 +    @Override
 +    public net.kyori.adventure.text.Component author() {
-+        return this.author == null ? null : io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(this.author);
++        return this.author == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(this.author);
 +    }
 +
 +    @Override
 +    public org.bukkit.inventory.meta.BookMeta author(net.kyori.adventure.text.Component author) {
-+        this.setAuthor(author == null ? null : io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.serialize(author));
++        this.setAuthor(author == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(author));
 +        return this;
 +    }
 +
 +    @Override
 +    public net.kyori.adventure.text.Component page(final int page) {
 +        Validate.isTrue(isValidPage(page), "Invalid page number");
-+        return this instanceof CraftMetaBookSigned ? net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson().deserialize(pages.get(page - 1)) : io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(pages.get(page - 1));
++        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));
 +    }
 +
 +    @Override
@@ -2977,7 +3106,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        if (data == null) {
 +            data = net.kyori.adventure.text.Component.empty();
 +        }
-+        pages.set(page - 1, this instanceof CraftMetaBookSigned ? net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson().serialize(data) : io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.serialize(data));
++        pages.set(page - 1, this instanceof CraftMetaBookSigned ? net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson().serialize(data) : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(data));
 +    }
 +
 +    @Override
@@ -2986,7 +3115,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        if (this instanceof CraftMetaBookSigned)
 +            return pages.stream().map(net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson()::deserialize).collect(ImmutableList.toImmutableList());
 +        else
-+            return pages.stream().map(io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC::deserialize).collect(ImmutableList.toImmutableList());
++            return pages.stream().map(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection()::deserialize).collect(ImmutableList.toImmutableList());
 +    }
 +
 +    @Override
@@ -3017,15 +3146,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                page = net.kyori.adventure.text.Component.empty();
 +            }
 +
-+            this.pages.add(this instanceof CraftMetaBookSigned ? net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson().serialize(page) : io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.serialize(page));
++            this.pages.add(this instanceof CraftMetaBookSigned ? net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson().serialize(page) : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(page));
 +        }
 +    }
 +
 +    private CraftMetaBook(net.kyori.adventure.text.Component title, net.kyori.adventure.text.Component author, List<net.kyori.adventure.text.Component> pages) {
 +        super((org.bukkit.craftbukkit.inventory.CraftMetaItem) org.bukkit.Bukkit.getItemFactory().getItemMeta(org.bukkit.Material.WRITABLE_BOOK));
-+        this.title = title == null ? null : io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.serialize(title);
-+        this.author = author == null ? null : io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.serialize(author);
-+        this.pages = pages.subList(0, Math.min(MAX_PAGES, pages.size())).stream().map(io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC::serialize).collect(java.util.stream.Collectors.toList());
++        this.title = title == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(title);
++        this.author = author == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(author);
++        this.pages = pages.subList(0, Math.min(MAX_PAGES, pages.size())).stream().map(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection()::serialize).collect(java.util.stream.Collectors.toList());
 +    }
 +
 +    static class CraftMetaBookBuilder implements BookMetaBuilder {
@@ -3116,8 +3245,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    // Paper start - adventure
 +    private CraftMetaBookSigned(net.kyori.adventure.text.Component title, net.kyori.adventure.text.Component author, java.util.List<net.kyori.adventure.text.Component> pages) {
 +        super((org.bukkit.craftbukkit.inventory.CraftMetaItem) org.bukkit.Bukkit.getItemFactory().getItemMeta(Material.WRITABLE_BOOK));
-+        this.title = title == null ? null : io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.serialize(title);
-+        this.author = author == null ? null : io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.serialize(author);
++        this.title = title == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(title);
++        this.author = author == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(author);
 +        this.pages = io.papermc.paper.adventure.PaperAdventure.asJson(pages.subList(0, Math.min(MAX_PAGES, pages.size())));
 +    }
 +
@@ -3382,7 +3511,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        CraftCriteria craftCriteria = CraftCriteria.getFromBukkit(criteria);
 +        ScoreboardObjective objective = board.registerObjective(name, craftCriteria.criteria, CraftChatMessage.fromStringOrNull(displayName), CraftScoreboardTranslations.fromBukkitRender(renderType));
 +        return new CraftObjective(this, objective);*/ // Paper
-+        return registerNewObjective(name, criteria, io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(displayName), renderType); // Paper
++        return registerNewObjective(name, criteria, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(displayName), renderType); // Paper
      }
  
      @Override
@@ -3482,27 +3611,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    @Override
 +    public net.kyori.adventure.text.serializer.gson.GsonComponentSerializer colorDownsamplingGsonComponentSerializer() {
-+        return io.papermc.paper.adventure.PaperAdventure.COLOR_DOWNSAMPLING_GSON;
++        return net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.colorDownsamplingGson();
 +    }
 +
 +    @Override
 +    public net.kyori.adventure.text.serializer.gson.GsonComponentSerializer gsonComponentSerializer() {
-+        return io.papermc.paper.adventure.PaperAdventure.GSON;
++        return net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson();
 +    }
 +
 +    @Override
 +    public net.kyori.adventure.text.serializer.plain.PlainComponentSerializer plainComponentSerializer() {
-+        return io.papermc.paper.adventure.PaperAdventure.PLAIN_COMPONENT;
-+    }
-+
-+    @Override
-+    public net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer plainTextSerializer() {
 +        return io.papermc.paper.adventure.PaperAdventure.PLAIN;
 +    }
 +
 +    @Override
++    public net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer plainTextSerializer() {
++        return net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer.plainText();
++    }
++
++    @Override
 +    public net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer legacyComponentSerializer() {
-+        return io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC;
++        return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection();
 +    }
 +    // Paper end
 +
@@ -3545,3 +3674,60 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          HashSet<Player> reference = new HashSet<Player>(players.size());
          for (ServerPlayer player : players) {
              reference.add(player.getBukkitEntity());
+diff --git a/src/main/resources/META-INF/services/net.kyori.adventure.text.minimessage.MiniMessage$Provider b/src/main/resources/META-INF/services/net.kyori.adventure.text.minimessage.MiniMessage$Provider
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/resources/META-INF/services/net.kyori.adventure.text.minimessage.MiniMessage$Provider
+@@ -0,0 +1 @@
++io.papermc.paper.adventure.providers.MiniMessageProviderImpl
+diff --git a/src/main/resources/META-INF/services/net.kyori.adventure.text.serializer.gson.GsonComponentSerializer$Provider b/src/main/resources/META-INF/services/net.kyori.adventure.text.serializer.gson.GsonComponentSerializer$Provider
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/resources/META-INF/services/net.kyori.adventure.text.serializer.gson.GsonComponentSerializer$Provider
+@@ -0,0 +1 @@
++io.papermc.paper.adventure.providers.GsonComponentSerializerProviderImpl
+diff --git a/src/main/resources/META-INF/services/net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer$Provider b/src/main/resources/META-INF/services/net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer$Provider
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/resources/META-INF/services/net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer$Provider
+@@ -0,0 +1 @@
++io.papermc.paper.adventure.providers.LegacyComponentSerializerProviderImpl
+diff --git a/src/main/resources/META-INF/services/net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer$Provider b/src/main/resources/META-INF/services/net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer$Provider
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/resources/META-INF/services/net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer$Provider
+@@ -0,0 +1 @@
++io.papermc.paper.adventure.providers.PlainTextComponentSerializerProviderImpl
+diff --git a/src/test/java/io/papermc/paper/adventure/ComponentServicesTest.java b/src/test/java/io/papermc/paper/adventure/ComponentServicesTest.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/test/java/io/papermc/paper/adventure/ComponentServicesTest.java
+@@ -0,0 +0,0 @@
++package io.papermc.paper.adventure;
++
++import net.kyori.adventure.text.Component;
++import net.kyori.adventure.text.format.NamedTextColor;
++import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
++import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
++import org.junit.Test;
++
++import static org.junit.Assert.assertEquals;
++
++public class ComponentServicesTest {
++
++    @Test
++    public void testPlainTextComponentSerializerProvider() {
++        assertEquals("Done", PlainTextComponentSerializer.plainText().serialize(Component.translatable("narrator.loading.done")));
++    }
++
++    @Test
++    public void testLegacyComponentSerializerProvider() {
++        assertEquals("§cDone", LegacyComponentSerializer.legacySection().serialize(Component.translatable("narrator.loading.done", NamedTextColor.RED)));
++        assertEquals("&cDone", LegacyComponentSerializer.legacyAmpersand().serialize(Component.translatable("narrator.loading.done", NamedTextColor.RED)));
++    }
++}
diff --git a/patches/server/Lazily-track-plugin-scoreboards-by-default.patch b/patches/server/Lazily-track-plugin-scoreboards-by-default.patch
index 1337252a6f..766c194022 100644
--- a/patches/server/Lazily-track-plugin-scoreboards-by-default.patch
+++ b/patches/server/Lazily-track-plugin-scoreboards-by-default.patch
@@ -66,7 +66,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        // Paper end
          ScoreboardObjective objective = board.registerObjective(name, craftCriteria.criteria, CraftChatMessage.fromStringOrNull(displayName), CraftScoreboardTranslations.fromBukkitRender(renderType));
          return new CraftObjective(this, objective);*/ // Paper
-         return registerNewObjective(name, criteria, io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(displayName), renderType); // Paper
+         return registerNewObjective(name, criteria, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(displayName), renderType); // Paper
 diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java
diff --git a/patches/server/Option-to-use-vanilla-per-world-scoreboard-coloring-.patch b/patches/server/Option-to-use-vanilla-per-world-scoreboard-coloring-.patch
index ffd030ab7e..1dec6f482b 100644
--- a/patches/server/Option-to-use-vanilla-per-world-scoreboard-coloring-.patch
+++ b/patches/server/Option-to-use-vanilla-per-world-scoreboard-coloring-.patch
@@ -29,8 +29,8 @@ diff --git a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java b/src/m
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java
 +++ b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java
-@@ -0,0 +0,0 @@ import net.kyori.adventure.text.TextReplacementConfig;
- import net.kyori.adventure.text.event.ClickEvent;
+@@ -0,0 +0,0 @@ import net.kyori.adventure.text.event.ClickEvent;
+ import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
  import net.minecraft.server.MinecraftServer;
  import net.minecraft.server.level.ServerPlayer;
 +import org.bukkit.ChatColor;
@@ -43,7 +43,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      private static String legacyDisplayName(final CraftPlayer player) {
 +        if (((CraftWorld) player.getWorld()).getHandle().paperConfig.useVanillaScoreboardColoring) {
-+            return PaperAdventure.LEGACY_SECTION_UXRC.serialize(player.teamDisplayName()) + ChatColor.RESET;
++            return LegacyComponentSerializer.legacySection().serialize(player.teamDisplayName()) + ChatColor.RESET;
 +        }
          return player.getDisplayName();
      }
diff --git a/patches/server/Prevent-opening-inventories-when-frozen.patch b/patches/server/Prevent-opening-inventories-when-frozen.patch
index 802dc6eb4c..506cff1f9b 100644
--- a/patches/server/Prevent-opening-inventories-when-frozen.patch
+++ b/patches/server/Prevent-opening-inventories-when-frozen.patch
@@ -31,7 +31,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
 +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
 @@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
-         if (adventure$title == null) adventure$title = io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(container.getBukkitView().getTitle()); // Paper
+         if (adventure$title == null) adventure$title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(container.getBukkitView().getTitle()); // Paper
  
          //player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0])); // Paper // Paper - comment
 -        player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper
@@ -41,7 +41,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }
 @@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
          net.kyori.adventure.text.Component adventure$title = inventory.title(); // Paper
-         if (adventure$title == null) adventure$title = io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(inventory.getTitle()); // Paper
+         if (adventure$title == null) adventure$title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(inventory.getTitle()); // Paper
          //player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0])); // Paper - comment
 -        player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper
 +        if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper
diff --git a/patches/server/ProfileWhitelistVerifyEvent.patch b/patches/server/ProfileWhitelistVerifyEvent.patch
index 523b33e6b7..6aeb10414d 100644
--- a/patches/server/ProfileWhitelistVerifyEvent.patch
+++ b/patches/server/ProfileWhitelistVerifyEvent.patch
@@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              event.disallow(PlayerLoginEvent.Result.KICK_BANNED, PaperAdventure.asAdventure(chatmessage)); // Paper - Adventure
 -        } else if (!this.isWhiteListed(gameprofile)) {
 -            chatmessage = new TranslatableComponent("multiplayer.disconnect.not_whitelisted");
--            event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, PaperAdventure.LEGACY_SECTION_UXRC.deserialize(org.spigotmc.SpigotConfig.whitelistMessage)); // Spigot // Paper - Adventure
+-            event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.whitelistMessage)); // Spigot // Paper - Adventure
 +        } else if (!this.isWhitelisted(gameprofile, event)) { // Paper
 +            //chatmessage = new ChatMessage("multiplayer.disconnect.not_whitelisted"); // Paper
 +            //event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig.whitelistMessage); // Spigot // Paper - moved to isWhitelisted
@@ -38,7 +38,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        event.callEvent();
 +        if (!event.isWhitelisted()) {
 +            if (loginEvent != null) {
-+                loginEvent.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, PaperAdventure.LEGACY_SECTION_UXRC.deserialize(event.getKickMessage() == null ? org.spigotmc.SpigotConfig.whitelistMessage : event.getKickMessage()));
++                loginEvent.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(event.getKickMessage() == null ? org.spigotmc.SpigotConfig.whitelistMessage : event.getKickMessage()));
 +            }
 +            return false;
 +        }
diff --git a/patches/server/Restore-custom-InventoryHolder-support.patch b/patches/server/Restore-custom-InventoryHolder-support.patch
index 4b66dbc3f4..e715d9ce83 100644
--- a/patches/server/Restore-custom-InventoryHolder-support.patch
+++ b/patches/server/Restore-custom-InventoryHolder-support.patch
@@ -19,6 +19,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +import io.papermc.paper.adventure.PaperAdventure;
 +import net.kyori.adventure.text.Component;
++import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
 +import net.minecraft.world.Container;
 +import net.minecraft.world.entity.player.Player;
 +import net.minecraft.world.item.ItemStack;
@@ -55,7 +56,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            adventure$title = type.defaultTitle();
 +        }
 +        this.adventure$title = adventure$title;
-+        this.title = PaperAdventure.LEGACY_SECTION_UXRC.serialize(this.adventure$title);
++        this.title = LegacyComponentSerializer.legacySection().serialize(this.adventure$title);
 +    }
 +
 +    public Component title() {
diff --git a/patches/server/Use-TerminalConsoleAppender-for-console-improvements.patch b/patches/server/Use-TerminalConsoleAppender-for-console-improvements.patch
index 3931c6b3d1..18a951d64c 100644
--- a/patches/server/Use-TerminalConsoleAppender-for-console-improvements.patch
+++ b/patches/server/Use-TerminalConsoleAppender-for-console-improvements.patch
@@ -166,7 +166,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
      public void sendMessage(Component message, UUID sender) {
 -        MinecraftServer.LOGGER.info(message.getString());
-+        MinecraftServer.LOGGER.info(io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.serialize(io.papermc.paper.adventure.PaperAdventure.asAdventure(message))); // Paper - Log message with colors
++        MinecraftServer.LOGGER.info(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(io.papermc.paper.adventure.PaperAdventure.asAdventure(message))); // Paper - Log message with colors
      }
  
      public KeyPair getKeyPair() {