From 94e0370bed7f7c8f151ed6cedf9d64d956c22b9c Mon Sep 17 00:00:00 2001
From: Nassim Jahnke <nassim@njahnke.dev>
Date: Mon, 22 Jan 2024 19:01:10 +0100
Subject: [PATCH] [ci skip] Add more patch identifying comments

---
 ...to-control-if-armor-stands-can-move.patch} |  2 +-
 ...Add-Channel-initialization-listeners.patch |  2 +-
 patches/server/Add-EntityZapEvent.patch       |  6 ++--
 .../server/Add-PlayerKickEvent-causes.patch   |  2 +-
 patches/server/Add-UnknownCommandEvent.patch  | 30 +++++++------------
 ...ke-parrots-stay-on-shoulders-despite.patch |  6 ++--
 ...n-to-nerf-pigmen-from-nether-portals.patch |  6 ++--
 ...predicate-for-blocks-when-raytracing.patch |  2 +-
 .../Add-support-for-Proxy-Protocol.patch      |  2 +-
 .../Alternative-item-despawn-rate.patch       |  2 +-
 ...blocking-on-Network-Manager-creation.patch | 14 ++++-----
 ...player-logins-during-server-shutdown.patch |  2 +-
 .../Bound-Treasure-Maps-to-World-Border.patch |  6 ++--
 .../Cache-user-authenticator-threads.patch    |  4 +--
 patches/server/Cap-Entity-Collisions.patch    | 10 +++----
 ...figurable-Cartographer-Treasure-Maps.patch | 10 +++----
 ...onfigurable-packet-in-spam-threshold.patch |  4 +--
 ...-profile-lookups-to-worldgen-threads.patch |  6 ++--
 .../server/Entity-Activation-Range-2.0.patch  |  6 ++--
 patches/server/Entity-fromMobSpawner.patch    |  2 +-
 ...PI-for-Reason-Source-Triggering-play.patch | 24 ++++++---------
 ...r-redstone-torch-rapid-clock-removal.patch | 10 +++----
 ...entity-nbt-data-from-falling-blocks.patch} |  4 +--
 patches/server/Fix-BanList-API.patch          |  2 +-
 ...x-and-optimise-world-force-upgrading.patch |  2 +-
 patches/server/Friction-API.patch             |  2 +-
 patches/server/Item-canEntityPickup.patch     |  6 ++--
 ...ptimise-BlockState-s-hashCode-equals.patch |  8 ++---
 ...ze-Level.hasChunkAt-BlockPosition-Z.patch} |  4 +--
 ...-Manager-and-add-advanced-packet-sup.patch | 12 ++++----
 .../server/PlayerAttemptPickupItemEvent.patch |  4 +--
 ...PlayerPickupItemEvent-setFlyAtPlayer.patch |  2 +-
 ...rom-being-processed-when-the-player-.patch |  2 +-
 .../server/ProfileWhitelistVerifyEvent.patch  |  6 ++--
 .../Properly-fix-item-duplication-bug.patch   |  4 +--
 ...rovide-E-TE-Chunk-count-stat-methods.patch |  4 +--
 .../Use-ConcurrentHashMap-in-JsonList.patch   |  2 +-
 .../Vanilla-command-permission-fixes.patch    |  2 +-
 ...atch => ensureServerConversions-API.patch} |  2 +-
 ...dle-ServerboundKeepAlivePacket-async.patch |  2 +-
 ...urable-option-to-disable-creeper-lin.patch |  2 +-
 41 files changed, 108 insertions(+), 122 deletions(-)
 rename patches/server/{Add-API-methods-to-control-if-armour-stands-can-move.patch => Add-API-methods-to-control-if-armor-stands-can-move.patch} (96%)
 rename patches/server/{Filter-bad-tile-entity-nbt-data-from-falling-blocks.patch => Filter-bad-block-entity-nbt-data-from-falling-blocks.patch} (85%)
 rename patches/server/{Optimize-World.isLoaded-BlockPosition-Z.patch => Optimize-Level.hasChunkAt-BlockPosition-Z.patch} (89%)
 rename patches/server/{Implement-ensureServerConversions-API.patch => ensureServerConversions-API.patch} (97%)

diff --git a/patches/server/Add-API-methods-to-control-if-armour-stands-can-move.patch b/patches/server/Add-API-methods-to-control-if-armor-stands-can-move.patch
similarity index 96%
rename from patches/server/Add-API-methods-to-control-if-armour-stands-can-move.patch
rename to patches/server/Add-API-methods-to-control-if-armor-stands-can-move.patch
index 9ac3870b3f..f0d3138b8c 100644
--- a/patches/server/Add-API-methods-to-control-if-armour-stands-can-move.patch
+++ b/patches/server/Add-API-methods-to-control-if-armor-stands-can-move.patch
@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Riley Park <rileysebastianpark@gmail.com>
 Date: Wed, 21 Dec 2016 11:47:25 -0600
-Subject: [PATCH] Add API methods to control if armour stands can move
+Subject: [PATCH] Add API methods to control if armor stands can move
 
 
 diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
diff --git a/patches/server/Add-Channel-initialization-listeners.patch b/patches/server/Add-Channel-initialization-listeners.patch
index 2dfe5b2ddf..a6393e3f25 100644
--- a/patches/server/Add-Channel-initialization-listeners.patch
+++ b/patches/server/Add-Channel-initialization-listeners.patch
@@ -146,7 +146,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
 +++ b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
 @@ -0,0 +0,0 @@ public class ServerConnectionListener {
-                     pending.add(object); // Paper
+                     pending.add(object); // Paper - prevent blocking on adding a new connection while the server is ticking
                      ((Connection) object).configurePacketHandler(channelpipeline);
                      ((Connection) object).setListenerForServerboundHandshake(new ServerHandshakePacketListenerImpl(ServerConnectionListener.this.server, (Connection) object));
 +                    io.papermc.paper.network.ChannelInitializeListenerHolder.callListeners(channel); // Paper - Add Channel initialization listeners
diff --git a/patches/server/Add-EntityZapEvent.patch b/patches/server/Add-EntityZapEvent.patch
index 2a60b912b2..58a84922e9 100644
--- a/patches/server/Add-EntityZapEvent.patch
+++ b/patches/server/Add-EntityZapEvent.patch
@@ -13,16 +13,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public void thunderHit(ServerLevel world, LightningBolt lightning) {
          if (world.getDifficulty() != Difficulty.PEACEFUL) {
 -            Villager.LOGGER.info("Villager {} was struck by lightning {}.", this, lightning);
-+            // Paper - move log down, event can cancel
++            // Paper - Add EntityZapEvent; move log down, event can cancel
              Witch entitywitch = (Witch) EntityType.WITCH.create(world);
  
              if (entitywitch != null) {
-+                // Paper start
++                // Paper start - Add EntityZapEvent
 +                if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityZapEvent(this, lightning, entitywitch).isCancelled()) {
 +                    return;
 +                }
 +                if (org.spigotmc.SpigotConfig.logVillagerDeaths) Villager.LOGGER.info("Villager {} was struck by lightning {}.", this, lightning); // Move down
-+                // Paper end
++                // Paper end - Add EntityZapEvent
 +
                  entitywitch.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot());
                  entitywitch.finalizeSpawn(world, world.getCurrentDifficultyAt(entitywitch.blockPosition()), MobSpawnType.CONVERSION, (SpawnGroupData) null, (CompoundTag) null);
diff --git a/patches/server/Add-PlayerKickEvent-causes.patch b/patches/server/Add-PlayerKickEvent-causes.patch
index 9d0b7811bf..147eff441a 100644
--- a/patches/server/Add-PlayerKickEvent-causes.patch
+++ b/patches/server/Add-PlayerKickEvent-causes.patch
@@ -110,7 +110,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -                this.disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE);
 +                this.disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE, org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause
              });
-             // Paper endg - This needs to be handled on the main thread for plugins
+             // Paper end - This needs to be handled on the main thread for plugins
          }
 @@ -0,0 +0,0 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
                  }
diff --git a/patches/server/Add-UnknownCommandEvent.patch b/patches/server/Add-UnknownCommandEvent.patch
index 2b2db9abb4..6087146f01 100644
--- a/patches/server/Add-UnknownCommandEvent.patch
+++ b/patches/server/Add-UnknownCommandEvent.patch
@@ -13,14 +13,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }
  
      public void sendFailure(Component message) {
-+        // Paper start
++        // Paper start - Add UnknownCommandEvent
 +        this.sendFailure(message, true);
 +    }
 +    public void sendFailure(Component message, boolean withStyle) {
-+        // Paper end
++        // Paper end - Add UnknownCommandEvent
          if (this.source.acceptsFailure() && !this.silent) {
 -            this.source.sendSystemMessage(Component.empty().append(message).withStyle(ChatFormatting.RED));
-+            this.source.sendSystemMessage(withStyle ? Component.empty().append(message).withStyle(ChatFormatting.RED) : message); // Paper
++            this.source.sendSystemMessage(withStyle ? Component.empty().append(message).withStyle(ChatFormatting.RED) : message); // Paper - Add UnknownCommandEvent
          }
  
      }
@@ -32,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public static final int LEVEL_ADMINS = 3;
      public static final int LEVEL_OWNERS = 4;
      private final com.mojang.brigadier.CommandDispatcher<CommandSourceStack> dispatcher = new com.mojang.brigadier.CommandDispatcher();
-+    public final java.util.List<CommandNode<CommandSourceStack>> vanillaCommandNodes = new java.util.ArrayList<>(); // Paper
++    public final java.util.List<CommandNode<CommandSourceStack>> vanillaCommandNodes = new java.util.ArrayList<>(); // Paper - Add UnknownCommandEvent
  
      public Commands(Commands.CommandSelection environment, CommandBuildContext commandRegistryAccess) {
          this(); // CraftBukkit
@@ -40,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          if (environment.includeIntegrated) {
              PublishCommand.register(this.dispatcher);
          }
-+        this.vanillaCommandNodes.addAll(this.dispatcher.getRoot().getChildren()); // Paper
++        this.vanillaCommandNodes.addAll(this.dispatcher.getRoot().getChildren()); // Paper - Add UnknownCommandEvent
  
          // CraftBukkit start
      }
@@ -49,7 +49,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              return "/" + s;
          });
 -        ContextChain contextchain = Commands.finishParsing(parseresults, s, commandlistenerwrapper, label); // CraftBukkit
-+        ContextChain contextchain = this.finishParsing(parseresults, s, commandlistenerwrapper, label); // CraftBukkit // Paper - make finishParsing not static
++        ContextChain contextchain = this.finishParsing(parseresults, s, commandlistenerwrapper, label); // CraftBukkit // Paper - Add UnknownCommandEvent
  
          try {
              if (contextchain != null) {
@@ -58,7 +58,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      @Nullable
 -    private static ContextChain<CommandSourceStack> finishParsing(ParseResults<CommandSourceStack> parseresults, String s, CommandSourceStack commandlistenerwrapper, String label) { // CraftBukkit
-+    private ContextChain<CommandSourceStack> finishParsing(ParseResults<CommandSourceStack> parseresults, String s, CommandSourceStack commandlistenerwrapper, String label) { // CraftBukkit // Paper - make not static
++    private ContextChain<CommandSourceStack> finishParsing(ParseResults<CommandSourceStack> parseresults, String s, CommandSourceStack commandlistenerwrapper, String label) { // CraftBukkit // Paper - Add UnknownCommandEvent
          try {
              Commands.validateParseResults(parseresults);
              return (ContextChain) ContextChain.tryFlatten(parseresults.getContext().build(s)).orElseThrow(() -> {
@@ -66,7 +66,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              });
          } catch (CommandSyntaxException commandsyntaxexception) {
 -            commandlistenerwrapper.sendFailure(ComponentUtils.fromMessage(commandsyntaxexception.getRawMessage()));
-+            // Paper start
++            // Paper start - Add UnknownCommandEvent
 +            final net.kyori.adventure.text.TextComponent.Builder builder = net.kyori.adventure.text.Component.text();
 +            if ((parseresults.getContext().getNodes().isEmpty() || !this.vanillaCommandNodes.contains(parseresults.getContext().getNodes().get(0).getNode()))) {
 +                if (!org.spigotmc.SpigotConfig.unknownCommandMessage.isEmpty()) {
@@ -75,24 +75,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            } else {
 +                // commandlistenerwrapper.sendFailure(ComponentUtils.fromMessage(commandsyntaxexception.getRawMessage()));
 +                builder.color(net.kyori.adventure.text.format.NamedTextColor.RED).append(io.papermc.paper.brigadier.PaperBrigadier.componentFromMessage(commandsyntaxexception.getRawMessage()));
-+                // Paper end
++                // Paper end - Add UnknownCommandEvent
              if (commandsyntaxexception.getInput() != null && commandsyntaxexception.getCursor() >= 0) {
                  int i = Math.min(commandsyntaxexception.getInput().length(), commandsyntaxexception.getCursor());
                  MutableComponent ichatmutablecomponent = Component.empty().withStyle(ChatFormatting.GRAY).withStyle((chatmodifier) -> {
-@@ -0,0 +0,0 @@ public class Commands {
-                     ichatmutablecomponent.append(CommonComponents.ELLIPSIS);
-                 }
- 
-+
-                 ichatmutablecomponent.append(commandsyntaxexception.getInput().substring(Math.max(0, i - 10), i));
-                 if (i < commandsyntaxexception.getInput().length()) {
-                     MutableComponent ichatmutablecomponent1 = Component.literal(commandsyntaxexception.getInput().substring(i)).withStyle(ChatFormatting.RED, ChatFormatting.UNDERLINE);
 @@ -0,0 +0,0 @@ public class Commands {
                  }
  
                  ichatmutablecomponent.append((Component) Component.translatable("command.context.here").withStyle(ChatFormatting.RED, ChatFormatting.ITALIC));
 -                commandlistenerwrapper.sendFailure(ichatmutablecomponent);
-+                // Paper start
++                // Paper start - Add UnknownCommandEvent
 +                // commandlistenerwrapper.sendFailure(ichatmutablecomponent);
 +                builder
 +                    .append(net.kyori.adventure.text.Component.newline())
@@ -103,7 +95,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            org.bukkit.Bukkit.getServer().getPluginManager().callEvent(event);
 +            if (event.message() != null) {
 +                commandlistenerwrapper.sendFailure(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.message()), false);
-+                // Paper end
++                // Paper end - Add UnknownCommandEvent
              }
  
              return null;
diff --git a/patches/server/Add-option-to-make-parrots-stay-on-shoulders-despite.patch b/patches/server/Add-option-to-make-parrots-stay-on-shoulders-despite.patch
index 011ccefd37..4b72aff7f7 100644
--- a/patches/server/Add-option-to-make-parrots-stay-on-shoulders-despite.patch
+++ b/patches/server/Add-option-to-make-parrots-stay-on-shoulders-despite.patch
@@ -22,11 +22,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              case PRESS_SHIFT_KEY:
                  this.player.setShiftKeyDown(true);
 +
-+                // Paper start - Hang on!
++                // Paper start - Add option to make parrots stay
 +                if (this.player.level().paperConfig().entities.behavior.parrotsAreUnaffectedByPlayerMovement) {
 +                    this.player.removeEntitiesOnShoulder();
 +                }
-+                // Paper end
++                // Paper end - Add option to make parrots stay
 +
                  break;
              case RELEASE_SHIFT_KEY:
@@ -39,7 +39,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          this.playShoulderEntityAmbientSound(this.getShoulderEntityLeft());
          this.playShoulderEntityAmbientSound(this.getShoulderEntityRight());
          if (!this.level().isClientSide && (this.fallDistance > 0.5F || this.isInWater()) || this.abilities.flying || this.isSleeping() || this.isInPowderSnow) {
-+            if (!this.level().paperConfig().entities.behavior.parrotsAreUnaffectedByPlayerMovement) // Paper - Hang on!
++            if (!this.level().paperConfig().entities.behavior.parrotsAreUnaffectedByPlayerMovement) // Paper - Add option to make parrots stay
              this.removeEntitiesOnShoulder();
          }
  
diff --git a/patches/server/Add-option-to-nerf-pigmen-from-nether-portals.patch b/patches/server/Add-option-to-nerf-pigmen-from-nether-portals.patch
index e101025b41..f85ca861e0 100644
--- a/patches/server/Add-option-to-nerf-pigmen-from-nether-portals.patch
+++ b/patches/server/Add-option-to-nerf-pigmen-from-nether-portals.patch
@@ -9,13 +9,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/net/minecraft/world/entity/Entity.java
 +++ b/src/main/java/net/minecraft/world/entity/Entity.java
 @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
-     // Paper start
+     protected int numCollisions = 0; // Paper - Cap entity collisions
      public long activatedImmunityTick = Integer.MIN_VALUE; // Paper
-     public boolean isTemporarilyActive = false; // Paper
+     public boolean isTemporarilyActive; // Paper
 +    public boolean fromNetherPortal; // Paper - Add option to nerf pigmen from nether portals
-     protected int numCollisions = 0; // Paper
      public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one
      @javax.annotation.Nullable
+     private org.bukkit.util.Vector origin;
 @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
              if (spawnedViaMobSpawner) {
                  nbttagcompound.putBoolean("Paper.FromMobSpawner", true);
diff --git a/patches/server/Add-predicate-for-blocks-when-raytracing.patch b/patches/server/Add-predicate-for-blocks-when-raytracing.patch
index ac190fc7ae..5d310d368c 100644
--- a/patches/server/Add-predicate-for-blocks-when-raytracing.patch
+++ b/patches/server/Add-predicate-for-blocks-when-raytracing.patch
@@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              }
              // Paper end - Prevent raytrace from loading chunks
 -            if (iblockdata.isAir()) return null; // Paper - Perf: optimise air cases
-+            if (iblockdata.isAir() || (canCollide != null && this instanceof LevelAccessor levelAccessor && !canCollide.test(org.bukkit.craftbukkit.block.CraftBlock.at(levelAccessor, blockposition)))) return null; // Paper - Perf: optimise air cases &g check canCollide predicate
++            if (iblockdata.isAir() || (canCollide != null && this instanceof LevelAccessor levelAccessor && !canCollide.test(org.bukkit.craftbukkit.block.CraftBlock.at(levelAccessor, blockposition)))) return null; // Paper - Perf: optimise air cases & check canCollide predicate
              FluidState fluid = iblockdata.getFluidState(); // Paper - Perf: don't need to go to world state again
              Vec3 vec3d = raytrace1.getFrom();
              Vec3 vec3d1 = raytrace1.getTo();
diff --git a/patches/server/Add-support-for-Proxy-Protocol.patch b/patches/server/Add-support-for-Proxy-Protocol.patch
index 9ce365d16b..e0112e3308 100644
--- a/patches/server/Add-support-for-Proxy-Protocol.patch
+++ b/patches/server/Add-support-for-Proxy-Protocol.patch
@@ -60,6 +60,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                        });
 +                    }
 +                    // Paper end - Add support for proxy protocol
-                     pending.add(object); // Paper
+                     pending.add(object); // Paper - prevent blocking on adding a new connection while the server is ticking
                      ((Connection) object).configurePacketHandler(channelpipeline);
                      ((Connection) object).setListenerForServerboundHandshake(new ServerHandshakePacketListenerImpl(ServerConnectionListener.this.server, (Connection) object));
diff --git a/patches/server/Alternative-item-despawn-rate.patch b/patches/server/Alternative-item-despawn-rate.patch
index 545d649253..df2e89b2bf 100644
--- a/patches/server/Alternative-item-despawn-rate.patch
+++ b/patches/server/Alternative-item-despawn-rate.patch
@@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@ public class ItemEntity extends Entity implements TraceableEntity {
      public final float bobOffs;
      private int lastTick = MinecraftServer.currentTick - 1; // CraftBukkit
-     public boolean canMobPickup = true; // Paper
+     public boolean canMobPickup = true; // Paper - Item#canEntityPickup
 +    private int despawnRate = -1; // Paper - Alternative item-despawn-rate
  
      public ItemEntity(EntityType<? extends ItemEntity> type, Level world) {
diff --git a/patches/server/Avoid-blocking-on-Network-Manager-creation.patch b/patches/server/Avoid-blocking-on-Network-Manager-creation.patch
index ba22f8524a..bd26b12da1 100644
--- a/patches/server/Avoid-blocking-on-Network-Manager-creation.patch
+++ b/patches/server/Avoid-blocking-on-Network-Manager-creation.patch
@@ -13,15 +13,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public volatile boolean running;
      private final List<ChannelFuture> channels = Collections.synchronizedList(Lists.newArrayList());
      final List<Connection> connections = Collections.synchronizedList(Lists.newArrayList());
-+    // Paper start - prevent blocking on adding a new network manager while the server is ticking
++    // Paper start - prevent blocking on adding a new connection while the server is ticking
 +    private final java.util.Queue<Connection> pending = new java.util.concurrent.ConcurrentLinkedQueue<>();
 +    private final void addPending() {
-+        Connection manager = null;
-+        while ((manager = pending.poll()) != null) {
-+            connections.add(manager);
++        Connection connection;
++        while ((connection = pending.poll()) != null) {
++            connections.add(connection);
 +        }
 +    }
-+    // Paper end
++    // Paper end - prevent blocking on adding a new connection while the server is ticking
  
      public ServerConnectionListener(MinecraftServer server) {
          this.server = server;
@@ -31,7 +31,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
 -                    ServerConnectionListener.this.connections.add(object);
 +                    //ServerConnectionListener.this.connections.add(object); // Paper
-+                    pending.add(object); // Paper
++                    pending.add(object); // Paper - prevent blocking on adding a new connection while the server is ticking
                      ((Connection) object).configurePacketHandler(channelpipeline);
                      ((Connection) object).setListenerForServerboundHandshake(new ServerHandshakePacketListenerImpl(ServerConnectionListener.this.server, (Connection) object));
                  }
@@ -39,7 +39,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
          synchronized (this.connections) {
              // Spigot Start
-+            this.addPending(); // Paper
++            this.addPending(); // Paper - prevent blocking on adding a new connection while the server is ticking
              // This prevents players from 'gaming' the server, and strategically relogging to increase their position in the tick order
              if ( org.spigotmc.SpigotConfig.playerShuffle > 0 && MinecraftServer.currentTick % org.spigotmc.SpigotConfig.playerShuffle == 0 )
              {
diff --git a/patches/server/Block-player-logins-during-server-shutdown.patch b/patches/server/Block-player-logins-during-server-shutdown.patch
index 29c66f204e..dbd3633f4d 100644
--- a/patches/server/Block-player-logins-during-server-shutdown.patch
+++ b/patches/server/Block-player-logins-during-server-shutdown.patch
@@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            this.disconnect(org.bukkit.craftbukkit.util.CraftChatMessage.fromString(org.spigotmc.SpigotConfig.restartMessage)[0]);
 +            return;
 +        }
-+        // Paper end
++        // Paper end - Do not allow logins while the server is shutting down
          if (this.state == ServerLoginPacketListenerImpl.State.VERIFYING) {
              this.verifyLoginAndFinishConnectionSetup((GameProfile) Objects.requireNonNull(this.authenticatedProfile));
          }
diff --git a/patches/server/Bound-Treasure-Maps-to-World-Border.patch b/patches/server/Bound-Treasure-Maps-to-World-Border.patch
index 695f2ef34d..3cbac9d03a 100644
--- a/patches/server/Bound-Treasure-Maps-to-World-Border.patch
+++ b/patches/server/Bound-Treasure-Maps-to-World-Border.patch
@@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          return (double) (pos.getX() + 1) > this.getMinX() && (double) pos.getX() < this.getMaxX() && (double) (pos.getZ() + 1) > this.getMinZ() && (double) pos.getZ() < this.getMaxZ();
      }
  
-+    // Paper start
++    // Paper start - Bound treasure maps to world border
 +    private final BlockPos.MutableBlockPos mutPos = new BlockPos.MutableBlockPos();
 +    public boolean isBlockInBounds(int chunkX, int chunkZ) {
 +        this.mutPos.set(chunkX, 64, chunkZ);
@@ -28,7 +28,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        this.mutPos.set(((chunkX << 4) + 15), 64, (chunkZ << 4) + 15);
 +        return this.isWithinBounds(this.mutPos);
 +    }
-+    // Paper end
++    // Paper end - Bound treasure maps to world border
 +
      public boolean isWithinBounds(ChunkPos pos) {
          return (double) pos.getMaxBlockX() > this.getMinX() && (double) pos.getMinBlockX() < this.getMaxX() && (double) pos.getMaxBlockZ() > this.getMinZ() && (double) pos.getMinBlockZ() < this.getMaxZ();
@@ -41,7 +41,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
              while (iterator.hasNext()) {
                  ChunkPos chunkcoordintpair = (ChunkPos) iterator.next();
-+                if (!world.getWorldBorder().isChunkInBounds(chunkcoordintpair.x, chunkcoordintpair.z)) { continue; } // Paper
++                if (!world.getWorldBorder().isChunkInBounds(chunkcoordintpair.x, chunkcoordintpair.z)) { continue; } // Paper - Bound treasure maps to world border
  
                  blockposition_mutableblockposition.set(SectionPos.sectionToBlockCoord(chunkcoordintpair.x, 8), 32, SectionPos.sectionToBlockCoord(chunkcoordintpair.z, 8));
                  double d1 = blockposition_mutableblockposition.distSqr(center);
diff --git a/patches/server/Cache-user-authenticator-threads.patch b/patches/server/Cache-user-authenticator-threads.patch
index 1e95f302ba..ddd6a25ae3 100644
--- a/patches/server/Cache-user-authenticator-threads.patch
+++ b/patches/server/Cache-user-authenticator-threads.patch
@@ -35,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -                thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(ServerLoginPacketListenerImpl.LOGGER));
 -                thread.start();
 +                });
-+                // Paper end
++                // Paper end - Cache authenticator threads
                  // CraftBukkit end
              }
  
@@ -58,7 +58,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -        thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(ServerLoginPacketListenerImpl.LOGGER));
 -        thread.start();
 +        });
-+        // Paper end
++        // Paper end - Cache authenticator threads
      }
  
      // CraftBukkit start
diff --git a/patches/server/Cap-Entity-Collisions.patch b/patches/server/Cap-Entity-Collisions.patch
index 299249e727..c92cdca283 100644
--- a/patches/server/Cap-Entity-Collisions.patch
+++ b/patches/server/Cap-Entity-Collisions.patch
@@ -19,7 +19,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public void inactiveTick() { }
      // Spigot end
      // Paper start
-+    protected int numCollisions = 0; // Paper
++    protected int numCollisions = 0; // Paper - Cap entity collisions
      @javax.annotation.Nullable
      private org.bukkit.util.Vector origin;
      @javax.annotation.Nullable
@@ -31,14 +31,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  }
  
                  Iterator iterator1 = list.iterator();
-+                this.numCollisions = Math.max(0, this.numCollisions - this.level().paperConfig().collisions.maxEntityCollisions); // Paper
++                this.numCollisions = Math.max(0, this.numCollisions - this.level().paperConfig().collisions.maxEntityCollisions); // Paper - Cap entity collisions
  
 -                while (iterator1.hasNext()) {
-+                while (iterator1.hasNext() && this.numCollisions < this.level().paperConfig().collisions.maxEntityCollisions) { // Paper
++                while (iterator1.hasNext() && this.numCollisions < this.level().paperConfig().collisions.maxEntityCollisions) { // Paper - Cap entity collisions
                      Entity entity1 = (Entity) iterator1.next();
 -
-+                    entity1.numCollisions++; // Paper
-+                    this.numCollisions++; // Paper
++                    entity1.numCollisions++; // Paper - Cap entity collisions
++                    this.numCollisions++; // Paper - Cap entity collisions
                      this.doPush(entity1);
                  }
              }
diff --git a/patches/server/Configurable-Cartographer-Treasure-Maps.patch b/patches/server/Configurable-Cartographer-Treasure-Maps.patch
index d086e46733..3cb0536e66 100644
--- a/patches/server/Configurable-Cartographer-Treasure-Maps.patch
+++ b/patches/server/Configurable-Cartographer-Treasure-Maps.patch
@@ -17,8 +17,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              } else {
                  ServerLevel serverLevel = (ServerLevel)entity.level();
 -                BlockPos blockPos = serverLevel.findNearestMapStructure(this.destination, entity.blockPosition(), 100, true);
-+                if (!serverLevel.paperConfig().environment.treasureMaps.enabled) return null; // Paper
-+                BlockPos blockPos = serverLevel.findNearestMapStructure(this.destination, entity.blockPosition(), 100, !serverLevel.paperConfig().environment.treasureMaps.findAlreadyDiscoveredVillager); // Paper
++                if (!serverLevel.paperConfig().environment.treasureMaps.enabled) return null; // Paper - Configurable cartographer treasure maps
++                BlockPos blockPos = serverLevel.findNearestMapStructure(this.destination, entity.blockPosition(), 100, !serverLevel.paperConfig().environment.treasureMaps.findAlreadyDiscoveredVillager); // Paper - Configurable cartographer treasure maps
                  if (blockPos != null) {
                      ItemStack itemStack = MapItem.create(serverLevel, blockPos.getX(), blockPos.getZ(), (byte)2, true, true);
                      MapItem.renderBiomePreviewMap(serverLevel, itemStack);
@@ -31,7 +31,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              if (vec3 != null) {
                  ServerLevel serverLevel = context.getLevel();
 -                BlockPos blockPos = serverLevel.findNearestMapStructure(this.destination, BlockPos.containing(vec3), this.searchRadius, this.skipKnownStructures);
-+                // Paper start
++                // Paper start - Configurable cartographer treasure maps
 +                if (!serverLevel.paperConfig().environment.treasureMaps.enabled) {
 +                    /*
 +                     * NOTE: I fear users will just get a plain map as their "treasure"
@@ -39,8 +39,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                     */
 +                    return stack;
 +                }
-+                // Paper end
-+                BlockPos blockPos = serverLevel.findNearestMapStructure(this.destination, BlockPos.containing(vec3), this.searchRadius, !serverLevel.paperConfig().environment.treasureMaps.findAlreadyDiscoveredLootTable.or(!this.skipKnownStructures)); // Paper
++                BlockPos blockPos = serverLevel.findNearestMapStructure(this.destination, BlockPos.containing(vec3), this.searchRadius, !serverLevel.paperConfig().environment.treasureMaps.findAlreadyDiscoveredLootTable.or(!this.skipKnownStructures));
++                // Paper end - Configurable cartographer treasure maps
                  if (blockPos != null) {
                      ItemStack itemStack = MapItem.create(serverLevel, blockPos.getX(), blockPos.getZ(), this.zoom, true, true);
                      MapItem.renderBiomePreviewMap(serverLevel, itemStack);
diff --git a/patches/server/Configurable-packet-in-spam-threshold.patch b/patches/server/Configurable-packet-in-spam-threshold.patch
index a6ff586248..7937f27565 100644
--- a/patches/server/Configurable-packet-in-spam-threshold.patch
+++ b/patches/server/Configurable-packet-in-spam-threshold.patch
@@ -16,12 +16,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      private boolean checkLimit(long timestamp) {
 -        if (this.lastLimitedPacket != -1 && timestamp - this.lastLimitedPacket < 30 && this.limitedPackets++ >= 4) {
-+        if (this.lastLimitedPacket != -1 && timestamp - this.lastLimitedPacket < getSpamThreshold() && this.limitedPackets++ >= 8) { // Paper - Use threshold, raise packet limit to 8
++        if (this.lastLimitedPacket != -1 && timestamp - this.lastLimitedPacket < getSpamThreshold() && this.limitedPackets++ >= 8) { // Paper - Configurable threshold; raise packet limit to 8
              return false;
          }
  
 -        if (this.lastLimitedPacket == -1 || timestamp - this.lastLimitedPacket >= 30) {
-+        if (this.lastLimitedPacket == -1 || timestamp - this.lastLimitedPacket >= getSpamThreshold()) { // Paper
++        if (this.lastLimitedPacket == -1 || timestamp - this.lastLimitedPacket >= getSpamThreshold()) { // Paper - Configurable threshold
              this.lastLimitedPacket = timestamp;
              this.limitedPackets = 0;
              return true;
diff --git a/patches/server/Do-not-submit-profile-lookups-to-worldgen-threads.patch b/patches/server/Do-not-submit-profile-lookups-to-worldgen-threads.patch
index da1483ab17..4325b7bca3 100644
--- a/patches/server/Do-not-submit-profile-lookups-to-worldgen-threads.patch
+++ b/patches/server/Do-not-submit-profile-lookups-to-worldgen-threads.patch
@@ -45,7 +45,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  CompletableFuture<Optional<GameProfile>> completablefuture1 = CompletableFuture.supplyAsync(() -> {
                      return this.get(username);
 -                }, Util.backgroundExecutor()).whenCompleteAsync((optional, throwable) -> {
-+                }, Util.PROFILE_EXECUTOR).whenCompleteAsync((optional, throwable) -> { // Paper - not a good idea to use BLOCKING OPERATIONS on the worldgen executor
++                }, Util.PROFILE_EXECUTOR).whenCompleteAsync((optional, throwable) -> { // Paper - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread
                      this.requests.remove(username);
                  }, this.executor);
  
@@ -58,7 +58,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  return Optional.empty();
              }
 -        }, Util.backgroundExecutor());
-+        }, Util.PROFILE_EXECUTOR); // Paper - not a good idea to use BLOCKING OPERATIONS on the worldgen executor
++        }, Util.PROFILE_EXECUTOR); // Paper - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread
      }
  
      @Override
@@ -71,7 +71,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
      public CompletableFuture<PlayerProfile> update() {
 -        return CompletableFuture.supplyAsync(this::getUpdatedProfile, Util.backgroundExecutor());
-+        return CompletableFuture.supplyAsync(this::getUpdatedProfile, Util.PROFILE_EXECUTOR); // Paper - not a good idea to use BLOCKING OPERATIONS on the worldgen executor
++        return CompletableFuture.supplyAsync(this::getUpdatedProfile, Util.PROFILE_EXECUTOR); // Paper - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread
      }
  
      private CraftPlayerProfile getUpdatedProfile() {
diff --git a/patches/server/Entity-Activation-Range-2.0.patch b/patches/server/Entity-Activation-Range-2.0.patch
index a963ee30f0..b6b79e9472 100644
--- a/patches/server/Entity-Activation-Range-2.0.patch
+++ b/patches/server/Entity-Activation-Range-2.0.patch
@@ -116,14 +116,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/net/minecraft/world/entity/Entity.java
 +++ b/src/main/java/net/minecraft/world/entity/Entity.java
 @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
-     public void inactiveTick() { }
      // Spigot end
      // Paper start
+     protected int numCollisions = 0; // Paper - Cap entity collisions
 +    public long activatedImmunityTick = Integer.MIN_VALUE; // Paper
-+    public boolean isTemporarilyActive = false; // Paper
-     protected int numCollisions = 0; // Paper
++    public boolean isTemporarilyActive; // Paper
      public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one
      @javax.annotation.Nullable
+     private org.bukkit.util.Vector origin;
 @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
          } else {
              this.wasOnFire = this.isOnFire();
diff --git a/patches/server/Entity-fromMobSpawner.patch b/patches/server/Entity-fromMobSpawner.patch
index f00d0bb7e5..0048fc9744 100644
--- a/patches/server/Entity-fromMobSpawner.patch
+++ b/patches/server/Entity-fromMobSpawner.patch
@@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
      // Spigot end
      // Paper start
-     protected int numCollisions = 0; // Paper
+     protected int numCollisions = 0; // Paper - Cap entity collisions
 +    public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one
      @javax.annotation.Nullable
      private org.bukkit.util.Vector origin;
diff --git a/patches/server/ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch b/patches/server/ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch
index 768454e4ff..88bba48421 100644
--- a/patches/server/ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch
+++ b/patches/server/ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch
@@ -35,11 +35,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    public java.util.UUID triggerEntityId;
 +    public org.bukkit.entity.ExperienceOrb.SpawnReason spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN;
 +
-+    private void loadPaperNBT(CompoundTag nbttagcompound) {
-+        if (!nbttagcompound.contains("Paper.ExpData", net.minecraft.nbt.Tag.TAG_COMPOUND)) {
++    private void loadPaperNBT(CompoundTag tag) {
++        if (!tag.contains("Paper.ExpData", net.minecraft.nbt.Tag.TAG_COMPOUND)) {
 +            return;
 +        }
-+        CompoundTag comp = nbttagcompound.getCompound("Paper.ExpData");
++        CompoundTag comp = tag.getCompound("Paper.ExpData");
 +        if (comp.hasUUID("source")) {
 +            this.sourceEntityId = comp.getUUID("source");
 +        }
@@ -55,7 +55,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            }
 +        }
 +    }
-+    private void savePaperNBT(CompoundTag nbttagcompound) {
++    private void savePaperNBT(CompoundTag tag) {
 +        CompoundTag comp = new CompoundTag();
 +        if (this.sourceEntityId != null) {
 +            comp.putUUID("source", this.sourceEntityId);
@@ -66,7 +66,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        if (this.spawnReason != null && this.spawnReason != org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN) {
 +            comp.putString("reason", this.spawnReason.name());
 +        }
-+        nbttagcompound.put("Paper.ExpData", comp);
++        tag.put("Paper.ExpData", comp);
 +    }
  
 +    @io.papermc.paper.annotation.DoNotUse
@@ -75,25 +75,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        this(world, x, y, z, amount, null, null);
 +    }
 +
-+    public ExperienceOrb(Level world, double d0, double d1, double d2, int i, @javax.annotation.Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @javax.annotation.Nullable Entity triggerId) {
-+        this(world, d0, d1, d2, i, reason, triggerId, null);
++    public ExperienceOrb(Level world, double x, double y, double z, int amount, @javax.annotation.Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @javax.annotation.Nullable Entity triggerId) {
++        this(world, x, y, z, amount, reason, triggerId, null);
 +    }
 +
-+    public ExperienceOrb(Level world, double d0, double d1, double d2, int i, @javax.annotation.Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @javax.annotation.Nullable Entity triggerId, @javax.annotation.Nullable Entity sourceId) {
++    public ExperienceOrb(Level world, double x, double y, double z, int amount, @javax.annotation.Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @javax.annotation.Nullable Entity triggerId, @javax.annotation.Nullable Entity sourceId) {
          this(EntityType.EXPERIENCE_ORB, world);
--        this.setPos(x, y, z);
 +        this.sourceEntityId = sourceId != null ? sourceId.getUUID() : null;
 +        this.triggerEntityId = triggerId != null ? triggerId.getUUID() : null;
 +        this.spawnReason = reason != null ? reason : org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN;
 +        // Paper end
-+        this.setPos(d0, d1, d2);
+         this.setPos(x, y, z);
          this.setYRot((float) (this.random.nextDouble() * 360.0D));
          this.setDeltaMovement((this.random.nextDouble() * 0.20000000298023224D - 0.10000000149011612D) * 2.0D, this.random.nextDouble() * 0.2D * 2.0D, (this.random.nextDouble() * 0.20000000298023224D - 0.10000000149011612D) * 2.0D);
--        this.value = amount;
-+        this.value = i;
-     }
- 
-     public ExperienceOrb(EntityType<? extends ExperienceOrb> type, Level world) {
 @@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
      }
  
diff --git a/patches/server/Faster-redstone-torch-rapid-clock-removal.patch b/patches/server/Faster-redstone-torch-rapid-clock-removal.patch
index 7d8fddde6e..8eda83cc2f 100644
--- a/patches/server/Faster-redstone-torch-rapid-clock-removal.patch
+++ b/patches/server/Faster-redstone-torch-rapid-clock-removal.patch
@@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      private org.spigotmc.TickLimiter tileLimiter;
      private int tileTickPosition;
      public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
-+    public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here
++    public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos; // Paper - Faster redstone torch rapid clock removal; Move from Map in BlockRedstoneTorch to here
  
      public CraftWorld getWorld() {
          return this.world;
@@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public static final MapCodec<RedstoneTorchBlock> CODEC = simpleCodec(RedstoneTorchBlock::new);
      public static final BooleanProperty LIT = BlockStateProperties.LIT;
 -    private static final Map<BlockGetter, List<RedstoneTorchBlock.Toggle>> RECENT_TOGGLES = new WeakHashMap();
-+    // Paper - Move the mapped list to World
++    // Paper - Faster redstone torch rapid clock removal; Move the mapped list to World
      public static final int RECENT_TOGGLE_TIMER = 60;
      public static final int MAX_RECENT_TOGGLES = 8;
      public static final int RESTART_DELAY = 160;
@@ -38,7 +38,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -
 -        while (list != null && !list.isEmpty() && world.getGameTime() - ((RedstoneTorchBlock.Toggle) list.get(0)).when > 60L) {
 -            list.remove(0);
-+        // Paper start
++        // Paper start - Faster redstone torch rapid clock removal
 +        java.util.ArrayDeque<RedstoneTorchBlock.Toggle> redstoneUpdateInfos = world.redstoneUpdateInfos;
 +        if (redstoneUpdateInfos != null) {
 +            RedstoneTorchBlock.Toggle curr;
@@ -46,7 +46,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                redstoneUpdateInfos.poll();
 +            }
          }
-+        // Paper end
++        // Paper end - Faster redstone torch rapid clock removal
  
          // CraftBukkit start
          org.bukkit.plugin.PluginManager manager = world.getCraftServer().getPluginManager();
@@ -57,7 +57,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -        List<RedstoneTorchBlock.Toggle> list = (List) RedstoneTorchBlock.RECENT_TOGGLES.computeIfAbsent(world, (iblockaccess) -> {
 -            return Lists.newArrayList();
 -        });
-+        // Paper start
++        // Paper start - Faster redstone torch rapid clock removal
 +        java.util.ArrayDeque<RedstoneTorchBlock.Toggle> list = world.redstoneUpdateInfos;
 +        if (list == null) {
 +            list = world.redstoneUpdateInfos = new java.util.ArrayDeque<>();
diff --git a/patches/server/Filter-bad-tile-entity-nbt-data-from-falling-blocks.patch b/patches/server/Filter-bad-block-entity-nbt-data-from-falling-blocks.patch
similarity index 85%
rename from patches/server/Filter-bad-tile-entity-nbt-data-from-falling-blocks.patch
rename to patches/server/Filter-bad-block-entity-nbt-data-from-falling-blocks.patch
index 18418821fc..5b0db4e49e 100644
--- a/patches/server/Filter-bad-tile-entity-nbt-data-from-falling-blocks.patch
+++ b/patches/server/Filter-bad-block-entity-nbt-data-from-falling-blocks.patch
@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Zach Brown <1254957+zachbr@users.noreply.github.com>
 Date: Sat, 12 Nov 2016 23:25:22 -0600
-Subject: [PATCH] Filter bad tile entity nbt data from falling blocks
+Subject: [PATCH] Filter bad block entity nbt data from falling blocks
 
 
 diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
@@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          }
  
 -        if (nbt.contains("TileEntityData", 10)) {
-+        if (nbt.contains("TileEntityData", 10) && !(this.level().paperConfig().entities.spawning.filterBadTileEntityNbtFromFallingBlocks && this.blockState.getBlock() instanceof net.minecraft.world.level.block.GameMasterBlock)) { // Paper
++        if (nbt.contains("TileEntityData", 10) && !(this.level().paperConfig().entities.spawning.filterBadTileEntityNbtFromFallingBlocks && this.blockState.getBlock() instanceof net.minecraft.world.level.block.GameMasterBlock)) { // Paper - Filter bad block entity nbt data from falling blocks
              this.blockData = nbt.getCompound("TileEntityData").copy();
          }
  
diff --git a/patches/server/Fix-BanList-API.patch b/patches/server/Fix-BanList-API.patch
index 49acfb1302..b5c73b3e0f 100644
--- a/patches/server/Fix-BanList-API.patch
+++ b/patches/server/Fix-BanList-API.patch
@@ -274,7 +274,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
 -    public CompletableFuture<PlayerProfile> update() {
 +    public CompletableFuture update() { // Paper - have to remove generic to avoid clashing between bukkit.PlayerProfile and paper.PlayerProfile
-         return CompletableFuture.supplyAsync(this::getUpdatedProfile, Util.PROFILE_EXECUTOR); // Paper - not a good idea to use BLOCKING OPERATIONS on the worldgen executor
+         return CompletableFuture.supplyAsync(this::getUpdatedProfile, Util.PROFILE_EXECUTOR); // Paper - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread
      }
  
 @@ -0,0 +0,0 @@ public final class CraftPlayerProfile implements PlayerProfile, com.destroystoky
diff --git a/patches/server/Fix-and-optimise-world-force-upgrading.patch b/patches/server/Fix-and-optimise-world-force-upgrading.patch
index af9d1eb5b7..e38005af80 100644
--- a/patches/server/Fix-and-optimise-world-force-upgrading.patch
+++ b/patches/server/Fix-and-optimise-world-force-upgrading.patch
@@ -303,7 +303,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +++ b/src/main/java/net/minecraft/world/level/Level.java
 @@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
      public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
-     public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here
+     public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos; // Paper - Faster redstone torch rapid clock removal; Move from Map in BlockRedstoneTorch to here
  
 +    // Paper start - fix and optimise world upgrading
 +    // copied from below
diff --git a/patches/server/Friction-API.patch b/patches/server/Friction-API.patch
index 598281fac4..b2464444b3 100644
--- a/patches/server/Friction-API.patch
+++ b/patches/server/Friction-API.patch
@@ -60,7 +60,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
 @@ -0,0 +0,0 @@ public class ItemEntity extends Entity implements TraceableEntity {
      private int lastTick = MinecraftServer.currentTick - 1; // CraftBukkit
-     public boolean canMobPickup = true; // Paper
+     public boolean canMobPickup = true; // Paper - Item#canEntityPickup
      private int despawnRate = -1; // Paper - Alternative item-despawn-rate
 +    public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API
  
diff --git a/patches/server/Item-canEntityPickup.patch b/patches/server/Item-canEntityPickup.patch
index fbe3e9fcbc..ff4930f793 100644
--- a/patches/server/Item-canEntityPickup.patch
+++ b/patches/server/Item-canEntityPickup.patch
@@ -12,11 +12,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  ItemEntity entityitem = (ItemEntity) iterator.next();
  
                  if (!entityitem.isRemoved() && !entityitem.getItem().isEmpty() && !entityitem.hasPickUpDelay() && this.wantsToPickUp(entityitem.getItem())) {
-+                    // Paper start
++                    // Paper start - Item#canEntityPickup
 +                    if (!entityitem.canMobPickup) {
 +                        continue;
 +                    }
-+                    // Paper end
++                    // Paper end - Item#canEntityPickup
                      this.pickUpItem(entityitem);
                  }
              }
@@ -28,7 +28,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public UUID target;
      public final float bobOffs;
      private int lastTick = MinecraftServer.currentTick - 1; // CraftBukkit
-+    public boolean canMobPickup = true; // Paper
++    public boolean canMobPickup = true; // Paper - Item#canEntityPickup
  
      public ItemEntity(EntityType<? extends ItemEntity> type, Level world) {
          super(type, world);
diff --git a/patches/server/Optimise-BlockState-s-hashCode-equals.patch b/patches/server/Optimise-BlockState-s-hashCode-equals.patch
index 462daf27b0..473c11d70e 100644
--- a/patches/server/Optimise-BlockState-s-hashCode-equals.patch
+++ b/patches/server/Optimise-BlockState-s-hashCode-equals.patch
@@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
 -    @Override
 -    public boolean equals(Object object) {
-+    public boolean equals_unused(Object object) { // Paper
++    public boolean equals_unused(Object object) { // Paper - Perf: Optimize hashCode/equals
          if (this == object) {
              return true;
          } else {
@@ -32,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
 -    @Override
 -    public boolean equals(Object object) {
-+    public boolean equals_unused(Object object) { // Paper
++    public boolean equals_unused(Object object) { // Paper - Perf: Optimize hashCode/equals
          if (this == object) {
              return true;
          } else {
@@ -46,7 +46,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
 -    @Override
 -    public boolean equals(Object object) {
-+    public boolean equals_unused(Object object) { // Paper
++    public boolean equals_unused(Object object) { // Paper - Perf: Optimize hashCode/equals
          if (this == object) {
              return true;
          } else {
@@ -66,7 +66,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -            Property<?> property = (Property)object;
 -            return this.clazz.equals(property.clazz) && this.name.equals(property.name);
 -        }
-+        return this == object; // Paper
++        return this == object; // Paper - Perf: Optimize hashCode/equals
      }
  
      @Override
diff --git a/patches/server/Optimize-World.isLoaded-BlockPosition-Z.patch b/patches/server/Optimize-Level.hasChunkAt-BlockPosition-Z.patch
similarity index 89%
rename from patches/server/Optimize-World.isLoaded-BlockPosition-Z.patch
rename to patches/server/Optimize-Level.hasChunkAt-BlockPosition-Z.patch
index 55e4b8c5c5..d5db1430b1 100644
--- a/patches/server/Optimize-World.isLoaded-BlockPosition-Z.patch
+++ b/patches/server/Optimize-Level.hasChunkAt-BlockPosition-Z.patch
@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Aikar <aikar@aikar.co>
 Date: Fri, 2 Dec 2016 00:11:43 -0500
-Subject: [PATCH] Optimize World.isLoaded(BlockPosition)Z
+Subject: [PATCH] Optimize Level.hasChunkAt(BlockPosition)Z
 
 Reduce method invocations for World.isLoaded(BlockPosition)Z
 
@@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
 +    @Override
 +    public final boolean hasChunkAt(BlockPos pos) {
-+        return getChunkIfLoaded(pos.getX() >> 4, pos.getZ() >> 4) != null; // Paper
++        return getChunkIfLoaded(pos.getX() >> 4, pos.getZ() >> 4) != null; // Paper - Perf: Optimize Level.hasChunkAt(BlockPosition)Z
 +    }
 +
      public final boolean isLoadedAndInBounds(BlockPos blockposition) { // Paper - final for inline
diff --git a/patches/server/Optimize-Network-Manager-and-add-advanced-packet-sup.patch b/patches/server/Optimize-Network-Manager-and-add-advanced-packet-sup.patch
index 3442c50a9d..60a5061bb9 100644
--- a/patches/server/Optimize-Network-Manager-and-add-advanced-packet-sup.patch
+++ b/patches/server/Optimize-Network-Manager-and-add-advanced-packet-sup.patch
@@ -373,17 +373,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +++ b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
 @@ -0,0 +0,0 @@ public class ServerConnectionListener {
      final List<Connection> connections = Collections.synchronizedList(Lists.newArrayList());
-     // Paper start - prevent blocking on adding a new network manager while the server is ticking
+     // Paper start - prevent blocking on adding a new connection while the server is ticking
      private final java.util.Queue<Connection> pending = new java.util.concurrent.ConcurrentLinkedQueue<>();
 +    private static final boolean disableFlushConsolidation = Boolean.getBoolean("Paper.disableFlushConsolidate"); // Paper - Optimize network
      private final void addPending() {
-         Connection manager = null;
-         while ((manager = pending.poll()) != null) {
-             connections.add(manager);
-+            manager.isPending = false; // Paper - Optimize network
+         Connection connection;
+         while ((connection = pending.poll()) != null) {
+             connections.add(connection);
++            connection.isPending = false; // Paper - Optimize network
          }
      }
-     // Paper end
+     // Paper end - prevent blocking on adding a new connection while the server is ticking
 @@ -0,0 +0,0 @@ public class ServerConnectionListener {
                          ;
                      }
diff --git a/patches/server/PlayerAttemptPickupItemEvent.patch b/patches/server/PlayerAttemptPickupItemEvent.patch
index bf3e7fc61a..477ca45b54 100644
--- a/patches/server/PlayerAttemptPickupItemEvent.patch
+++ b/patches/server/PlayerAttemptPickupItemEvent.patch
@@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              int remaining = i - canHold;
              boolean flyAtPlayer = false; // Paper
  
-+            // Paper start
++            // Paper start - PlayerAttemptPickupItemEvent
 +            if (this.pickupDelay <= 0) {
 +                PlayerAttemptPickupItemEvent attemptEvent = new PlayerAttemptPickupItemEvent((org.bukkit.entity.Player) player.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining);
 +                this.level().getCraftServer().getPluginManager().callEvent(attemptEvent);
@@ -34,7 +34,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                    return;
 +                }
 +            }
-+            // Paper end
++            // Paper end - PlayerAttemptPickupItemEvent
 +
              if (this.pickupDelay <= 0 && canHold > 0) {
                  itemstack.setCount(canHold);
diff --git a/patches/server/PlayerPickupItemEvent-setFlyAtPlayer.patch b/patches/server/PlayerPickupItemEvent-setFlyAtPlayer.patch
index 4e8f1fa4b7..6888157f2e 100644
--- a/patches/server/PlayerPickupItemEvent-setFlyAtPlayer.patch
+++ b/patches/server/PlayerPickupItemEvent-setFlyAtPlayer.patch
@@ -35,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              // CraftBukkit end
  
              if (this.pickupDelay == 0 && (this.target == null || this.target.equals(player.getUUID())) && player.getInventory().add(itemstack)) {
-+                if (flyAtPlayer) // Paper
++                if (flyAtPlayer) // Paper - PlayerPickupItemEvent
                  player.take(this, i);
                  if (itemstack.isEmpty()) {
                      this.discard();
diff --git a/patches/server/Prevent-logins-from-being-processed-when-the-player-.patch b/patches/server/Prevent-logins-from-being-processed-when-the-player-.patch
index d32197f55c..ffdd1bd866 100644
--- a/patches/server/Prevent-logins-from-being-processed-when-the-player-.patch
+++ b/patches/server/Prevent-logins-from-being-processed-when-the-player-.patch
@@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
 @@ -0,0 +0,0 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
          }
-         // Paper end
+         // Paper end - Do not allow logins while the server is shutting down
          if (this.state == ServerLoginPacketListenerImpl.State.VERIFYING) {
 +            if (this.connection.isConnected()) { // Paper - prevent logins to be processed even though disconnect was called
              this.verifyLoginAndFinishConnectionSetup((GameProfile) Objects.requireNonNull(this.authenticatedProfile));
diff --git a/patches/server/ProfileWhitelistVerifyEvent.patch b/patches/server/ProfileWhitelistVerifyEvent.patch
index f91b1f67e6..f838bdb8e1 100644
--- a/patches/server/ProfileWhitelistVerifyEvent.patch
+++ b/patches/server/ProfileWhitelistVerifyEvent.patch
@@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -        } else if (!this.isWhiteListed(gameprofile)) {
 -            ichatmutablecomponent = Component.translatable("multiplayer.disconnect.not_whitelisted");
 -            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
++        } else if (!this.isWhiteListed(gameprofile, event)) { // Paper - ProfileWhitelistVerifyEvent
 +            //ichatmutablecomponent = Component.translatable("multiplayer.disconnect.not_whitelisted"); // Paper
 +            //event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.whitelistMessage)); // Spigot // Paper - Adventure - moved to isWhitelisted
          } else if (this.getIpBans().isBanned(socketaddress) && !this.getIpBans().get(socketaddress).hasExpired()) {
@@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      public boolean isWhiteListed(GameProfile profile) {
 -        return !this.doWhiteList || this.ops.contains(profile) || this.whitelist.contains(profile);
-+        // Paper start
++        // Paper start - ProfileWhitelistVerifyEvent
 +        return isWhiteListed(profile, null);
 +    }
 +    public boolean isWhiteListed(GameProfile gameprofile, org.bukkit.event.player.PlayerLoginEvent loginEvent) {
@@ -42,7 +42,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            return false;
 +        }
 +        return true;
-+        // Paper end
++        // Paper end - ProfileWhitelistVerifyEvent
      }
  
      public boolean isOp(GameProfile profile) {
diff --git a/patches/server/Properly-fix-item-duplication-bug.patch b/patches/server/Properly-fix-item-duplication-bug.patch
index 5b433e4b16..31a744a5e3 100644
--- a/patches/server/Properly-fix-item-duplication-bug.patch
+++ b/patches/server/Properly-fix-item-duplication-bug.patch
@@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
      public boolean isImmobile() {
 -        return super.isImmobile() || !this.getBukkitEntity().isOnline();
-+        return super.isImmobile() || (this.connection != null && this.connection.isDisconnected()); // Paper
++        return super.isImmobile() || (this.connection != null && this.connection.isDisconnected()); // Paper - Fix duplication bugs
      }
  
      @Override
@@ -27,7 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      public final boolean isDisconnected() {
 -        return !this.player.joining && !this.connection.isConnected();
-+        return (!this.player.joining && !this.connection.isConnected()) || this.processedDisconnect; // Paper
++        return (!this.player.joining && !this.connection.isConnected()) || this.processedDisconnect; // Paper - Fix duplication bugs
      }
      // CraftBukkit end
  
diff --git a/patches/server/Provide-E-TE-Chunk-count-stat-methods.patch b/patches/server/Provide-E-TE-Chunk-count-stat-methods.patch
index 9e9f6e3920..0f4626f556 100644
--- a/patches/server/Provide-E-TE-Chunk-count-stat-methods.patch
+++ b/patches/server/Provide-E-TE-Chunk-count-stat-methods.patch
@@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public static final int MAX_ENTITY_SPAWN_Y = 20000000;
      public static final int MIN_ENTITY_SPAWN_Y = -20000000;
 -    protected final List<TickingBlockEntity> blockEntityTickers = Lists.newArrayList();
-+    protected final List<TickingBlockEntity> blockEntityTickers = Lists.newArrayList(); public final int getTotalTileEntityTickers() { return this.blockEntityTickers.size(); } // Paper
++    public final List<TickingBlockEntity> blockEntityTickers = Lists.newArrayList(); // Paper - public
      protected final NeighborUpdater neighborUpdater;
      private final List<TickingBlockEntity> pendingBlockEntityTickers = Lists.newArrayList();
      private boolean tickingBlockEntities;
@@ -55,7 +55,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    @Override
 +    public int getTickableTileEntityCount() {
-+        return world.getTotalTileEntityTickers();
++        return world.blockEntityTickers.size();
 +    }
 +
 +    @Override
diff --git a/patches/server/Use-ConcurrentHashMap-in-JsonList.patch b/patches/server/Use-ConcurrentHashMap-in-JsonList.patch
index 860b40a6e5..4d519a0dd7 100644
--- a/patches/server/Use-ConcurrentHashMap-in-JsonList.patch
+++ b/patches/server/Use-ConcurrentHashMap-in-JsonList.patch
@@ -27,7 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/net/minecraft/server/players/PlayerList.java
 +++ b/src/main/java/net/minecraft/server/players/PlayerList.java
 @@ -0,0 +0,0 @@ public abstract class PlayerList {
-         } else if (!this.isWhiteListed(gameprofile, event)) { // Paper
+         } else if (!this.isWhiteListed(gameprofile, event)) { // Paper - ProfileWhitelistVerifyEvent
              //ichatmutablecomponent = Component.translatable("multiplayer.disconnect.not_whitelisted"); // Paper
              //event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.whitelistMessage)); // Spigot // Paper - Adventure - moved to isWhitelisted
 -        } else if (this.getIpBans().isBanned(socketaddress) && !this.getIpBans().get(socketaddress).hasExpired()) {
diff --git a/patches/server/Vanilla-command-permission-fixes.patch b/patches/server/Vanilla-command-permission-fixes.patch
index 9e67cb63a6..c152b0c69c 100644
--- a/patches/server/Vanilla-command-permission-fixes.patch
+++ b/patches/server/Vanilla-command-permission-fixes.patch
@@ -38,7 +38,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +++ b/src/main/java/net/minecraft/commands/Commands.java
 @@ -0,0 +0,0 @@ public class Commands {
          }
-         this.vanillaCommandNodes.addAll(this.dispatcher.getRoot().getChildren()); // Paper
+         this.vanillaCommandNodes.addAll(this.dispatcher.getRoot().getChildren()); // Paper - Add UnknownCommandEvent
  
 +        // Paper start - Vanilla command permission fixes
 +        for (final CommandNode<CommandSourceStack> node : this.dispatcher.getRoot().getChildren()) {
diff --git a/patches/server/Implement-ensureServerConversions-API.patch b/patches/server/ensureServerConversions-API.patch
similarity index 97%
rename from patches/server/Implement-ensureServerConversions-API.patch
rename to patches/server/ensureServerConversions-API.patch
index 10af69a257..d7ebe3485e 100644
--- a/patches/server/Implement-ensureServerConversions-API.patch
+++ b/patches/server/ensureServerConversions-API.patch
@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Aikar <aikar@aikar.co>
 Date: Wed, 4 May 2016 22:43:12 -0400
-Subject: [PATCH] Implement ensureServerConversions API
+Subject: [PATCH] ensureServerConversions API
 
 This will take a Bukkit ItemStack and run it through any conversions a server process would perform on it,
 to ensure it meets latest minecraft expectations.
diff --git a/patches/server/handle-ServerboundKeepAlivePacket-async.patch b/patches/server/handle-ServerboundKeepAlivePacket-async.patch
index be68a56d12..24bdebec47 100644
--- a/patches/server/handle-ServerboundKeepAlivePacket-async.patch
+++ b/patches/server/handle-ServerboundKeepAlivePacket-async.patch
@@ -35,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            server.submit(() -> {
 +                this.disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE);
 +            });
-+            // Paper endg - This needs to be handled on the main thread for plugins
++            // Paper end - This needs to be handled on the main thread for plugins
          }
  
      }
diff --git a/patches/server/provide-a-configurable-option-to-disable-creeper-lin.patch b/patches/server/provide-a-configurable-option-to-disable-creeper-lin.patch
index 6c00b79745..255cf954ea 100644
--- a/patches/server/provide-a-configurable-option-to-disable-creeper-lin.patch
+++ b/patches/server/provide-a-configurable-option-to-disable-creeper-lin.patch
@@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          Collection<MobEffectInstance> collection = this.getActiveEffects();
  
 -        if (!collection.isEmpty()) {
-+        if (!collection.isEmpty() && !this.level().paperConfig().entities.behavior.disableCreeperLingeringEffect) { // Paper
++        if (!collection.isEmpty() && !this.level().paperConfig().entities.behavior.disableCreeperLingeringEffect) { // Paper - Option to disable creeper lingering effect
              AreaEffectCloud entityareaeffectcloud = new AreaEffectCloud(this.level(), this.getX(), this.getY(), this.getZ());
  
              entityareaeffectcloud.setOwner(this); // CraftBukkit