diff --git a/patches/api/Add-Player-Client-Options-API.patch b/patches/api/Add-Player-Client-Options-API.patch
index fe7f890512..092a578bd4 100644
--- a/patches/api/Add-Player-Client-Options-API.patch
+++ b/patches/api/Add-Player-Client-Options-API.patch
@@ -26,6 +26,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    public static final ClientOption<String> LOCALE = new ClientOption<>(String.class);
 +    public static final ClientOption<MainHand> MAIN_HAND = new ClientOption<>(MainHand.class);
 +    public static final ClientOption<Integer> VIEW_DISTANCE = new ClientOption<>(Integer.class);
++    public static final ClientOption<Boolean> ALLOW_SERVER_LISTINGS = new ClientOption<>(Boolean.class);
++    public static final ClientOption<Boolean> TEXT_FILTERING_ENABLED = new ClientOption<>(Boolean.class);
 +
 +    private final Class<T> type;
 +
@@ -97,16 +99,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import com.destroystokyo.paper.ClientOption;
 +import com.destroystokyo.paper.ClientOption.ChatVisibility;
 +import com.destroystokyo.paper.SkinParts;
-+
-+import org.jetbrains.annotations.NotNull;
-+
 +import org.bukkit.entity.Player;
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.bukkit.inventory.MainHand;
++import org.jetbrains.annotations.NotNull;
++
++import java.util.Map;
 +
 +/**
-+ * Called when the player changes his client settings
++ * Called when the player changes their client settings
 + */
 +public class PlayerClientOptionsChangeEvent extends PlayerEvent {
 +
@@ -118,7 +120,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private final boolean chatColors;
 +    private final SkinParts skinparts;
 +    private final MainHand mainHand;
++    private final boolean allowsServerListings;
++    private final boolean textFilteringEnabled;
 +
++    @Deprecated
 +    public PlayerClientOptionsChangeEvent(@NotNull Player player, @NotNull String locale, int viewDistance, @NotNull ChatVisibility chatVisibility, boolean chatColors, @NotNull SkinParts skinParts, @NotNull MainHand mainHand) {
 +        super(player);
 +        this.locale = locale;
@@ -127,6 +132,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        this.chatColors = chatColors;
 +        this.skinparts = skinParts;
 +        this.mainHand = mainHand;
++        this.allowsServerListings = false;
++        this.textFilteringEnabled = false;
++    }
++
++    public PlayerClientOptionsChangeEvent(@NotNull Player player, @NotNull Map<ClientOption<?>, ?> options) {
++        super(player);
++
++        this.locale = (String) options.get(ClientOption.LOCALE);
++        this.viewDistance = (int) options.get(ClientOption.VIEW_DISTANCE);
++        this.chatVisibility = (ChatVisibility) options.get(ClientOption.CHAT_VISIBILITY);
++        this.chatColors = (boolean) options.get(ClientOption.CHAT_COLORS_ENABLED);
++        this.skinparts = (SkinParts) options.get(ClientOption.SKIN_PARTS);
++        this.mainHand = (MainHand) options.get(ClientOption.MAIN_HAND);
++        this.allowsServerListings = (boolean) options.get(ClientOption.ALLOW_SERVER_LISTINGS);
++        this.textFilteringEnabled = (boolean) options.get(ClientOption.TEXT_FILTERING_ENABLED);
 +    }
 +
 +    @NotNull
@@ -181,6 +201,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return mainHand != player.getClientOption(ClientOption.MAIN_HAND);
 +    }
 +
++    public boolean allowsServerListings() {
++        return allowsServerListings;
++    }
++
++    public boolean hasAllowServerListingsChanged() {
++        return allowsServerListings != player.getClientOption(ClientOption.ALLOW_SERVER_LISTINGS);
++    }
++
++    public boolean hasTextFilteringEnabled() {
++        return textFilteringEnabled;
++    }
++
++    public boolean hasTextFilteringChanged() {
++        return textFilteringEnabled != player.getClientOption(ClientOption.TEXT_FILTERING_ENABLED);
++    }
++
 +    @Override
 +    @NotNull
 +    public HandlerList getHandlers() {
diff --git a/patches/server/Implement-Player-Client-Options-API.patch b/patches/server/Implement-Player-Client-Options-API.patch
index cf9b660a10..e488e033b0 100644
--- a/patches/server/Implement-Player-Client-Options-API.patch
+++ b/patches/server/Implement-Player-Client-Options-API.patch
@@ -89,10 +89,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
 +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 @@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
+         return s;
+     }
+ 
++    // Paper start - Client option API
++    private java.util.Map<com.destroystokyo.paper.ClientOption<?>, ?> getClientOptionMap(String locale, int viewDistance, com.destroystokyo.paper.ClientOption.ChatVisibility chatVisibility, boolean chatColors, com.destroystokyo.paper.PaperSkinParts skinParts, org.bukkit.inventory.MainHand mainHand, boolean allowsServerListing, boolean textFilteringEnabled) {
++        java.util.Map<com.destroystokyo.paper.ClientOption<?>, Object> map = new java.util.HashMap<>();
++        map.put(com.destroystokyo.paper.ClientOption.LOCALE, locale);
++        map.put(com.destroystokyo.paper.ClientOption.VIEW_DISTANCE, viewDistance);
++        map.put(com.destroystokyo.paper.ClientOption.CHAT_VISIBILITY, chatVisibility);
++        map.put(com.destroystokyo.paper.ClientOption.CHAT_COLORS_ENABLED, chatColors);
++        map.put(com.destroystokyo.paper.ClientOption.SKIN_PARTS, skinParts);
++        map.put(com.destroystokyo.paper.ClientOption.MAIN_HAND, mainHand);
++        map.put(com.destroystokyo.paper.ClientOption.ALLOW_SERVER_LISTINGS, allowsServerListing);
++        map.put(com.destroystokyo.paper.ClientOption.TEXT_FILTERING_ENABLED, textFilteringEnabled);
++        return map;
++    }
++    // Paper end
      public String locale = null; // CraftBukkit - add, lowercase // Paper - default to null
      public java.util.Locale adventure$locale = java.util.Locale.US; // Paper
      public void updateOptions(ServerboundClientInformationPacket packet) {
-+        new com.destroystokyo.paper.event.player.PlayerClientOptionsChangeEvent(getBukkitEntity(), packet.language, packet.viewDistance, com.destroystokyo.paper.ClientOption.ChatVisibility.valueOf(packet.chatVisibility().name()), packet.chatColors(), new com.destroystokyo.paper.PaperSkinParts(packet.modelCustomisation()), packet.mainHand() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT).callEvent(); // Paper - settings event
++        new com.destroystokyo.paper.event.player.PlayerClientOptionsChangeEvent(getBukkitEntity(), getClientOptionMap(packet.language, packet.viewDistance, com.destroystokyo.paper.ClientOption.ChatVisibility.valueOf(packet.chatVisibility().name()), packet.chatColors(), new com.destroystokyo.paper.PaperSkinParts(packet.modelCustomisation()), packet.mainHand() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT, packet.allowsListing(), packet.textFilteringEnabled())).callEvent(); // Paper - settings event
          // CraftBukkit start
          if (getMainArm() != packet.mainHand()) {
              PlayerChangedMainHandEvent event = new PlayerChangedMainHandEvent(this.getBukkitEntity(), getMainArm() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT);
@@ -107,18 +124,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    @Override
 +    public <T> T getClientOption(com.destroystokyo.paper.ClientOption<T> type) {
-+        if(com.destroystokyo.paper.ClientOption.SKIN_PARTS.equals(type)) {
++        if (com.destroystokyo.paper.ClientOption.SKIN_PARTS == type) {
 +            return type.getType().cast(new com.destroystokyo.paper.PaperSkinParts(getHandle().getEntityData().get(net.minecraft.world.entity.player.Player.DATA_PLAYER_MODE_CUSTOMISATION)));
-+        } else if(com.destroystokyo.paper.ClientOption.CHAT_COLORS_ENABLED.equals(type)) {
++        } else if (com.destroystokyo.paper.ClientOption.CHAT_COLORS_ENABLED == type) {
 +            return type.getType().cast(getHandle().canChatInColor());
-+        } else if(com.destroystokyo.paper.ClientOption.CHAT_VISIBILITY.equals(type)) {
++        } else if (com.destroystokyo.paper.ClientOption.CHAT_VISIBILITY == type) {
 +            return type.getType().cast(getHandle().getChatVisibility() == null ? com.destroystokyo.paper.ClientOption.ChatVisibility.UNKNOWN : com.destroystokyo.paper.ClientOption.ChatVisibility.valueOf(getHandle().getChatVisibility().name()));
-+        } else if(com.destroystokyo.paper.ClientOption.LOCALE.equals(type)) {
++        } else if (com.destroystokyo.paper.ClientOption.LOCALE == type) {
 +            return type.getType().cast(getLocale());
-+        } else if(com.destroystokyo.paper.ClientOption.MAIN_HAND.equals(type)) {
++        } else if (com.destroystokyo.paper.ClientOption.MAIN_HAND == type) {
 +            return type.getType().cast(getMainHand());
-+        } else if(com.destroystokyo.paper.ClientOption.VIEW_DISTANCE.equals(type)) {
++        } else if (com.destroystokyo.paper.ClientOption.VIEW_DISTANCE == type) {
 +            return type.getType().cast(getClientViewDistance());
++        } else if (com.destroystokyo.paper.ClientOption.ALLOW_SERVER_LISTINGS == type) {
++            return type.getType().cast(getHandle().allowsListing());
++        } else if (com.destroystokyo.paper.ClientOption.TEXT_FILTERING_ENABLED == type) {
++            return type.getType().cast(getHandle().isTextFilteringEnabled());
 +        }
 +        throw new RuntimeException("Unknown settings type");
 +    }