From 1279cca971b2d32b6bd75103d3a555fbbd629392 Mon Sep 17 00:00:00 2001
From: Outfluencer <git@outfluencer.dev>
Date: Sat, 19 Apr 2025 15:40:09 +1000
Subject: [PATCH] #3810: Use retainedSlice if possible in MinecraftDecoder

---
 .../bungee/protocol/MinecraftDecoder.java     | 23 ++++++++++++++++---
 .../net/md_5/bungee/entitymap/EntityMap.java  | 16 ++-----------
 .../bungee/entitymap/EntityMap_1_16_2.java    |  6 -----
 3 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java
index d79d5e5c..abcb53bb 100644
--- a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java
@@ -12,12 +12,17 @@ import lombok.Setter;
 public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf>
 {
 
+    public MinecraftDecoder(Protocol protocol, boolean server, int protocolVersion)
+    {
+        this( protocol, server, protocolVersion, shouldCopyBuffer( protocol, protocolVersion ) );
+    }
+
     @Getter
-    @Setter
     private Protocol protocol;
     private final boolean server;
     @Setter
     private int protocolVersion;
+    private boolean copyBuffer;
 
     @Override
     protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception
@@ -30,8 +35,7 @@ public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf>
         }
 
         Protocol.DirectionData prot = ( server ) ? protocol.TO_SERVER : protocol.TO_CLIENT;
-        ByteBuf slice = in.copy(); // Can't slice this one due to EntityMap :(
-
+        ByteBuf slice = ( copyBuffer ) ? in.copy() : in.retainedSlice();
         try
         {
             int packetId = DefinedPacket.readVarInt( in );
@@ -60,4 +64,17 @@ public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf>
             }
         }
     }
+
+    public void setProtocol(Protocol protocol)
+    {
+        this.protocol = protocol;
+        this.copyBuffer = shouldCopyBuffer( protocol, protocolVersion );
+    }
+
+    private static boolean shouldCopyBuffer(Protocol protocol, int protocolVersion)
+    {
+        // We only use the entity map in game state, we can avoid many buffer copies by checking this
+        // EntityMap is removed for 1.20.2 and up
+        return protocol == Protocol.GAME && protocolVersion < ProtocolConstants.MINECRAFT_1_20_2;
+    }
 }
diff --git a/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java
index c8fdb2e9..eab5a947 100644
--- a/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java
+++ b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java
@@ -82,21 +82,9 @@ public abstract class EntityMap
             case ProtocolConstants.MINECRAFT_1_19_4:
             case ProtocolConstants.MINECRAFT_1_20:
                 return EntityMap_1_16_2.INSTANCE_1_19_4;
-            case ProtocolConstants.MINECRAFT_1_20_2:
-                return EntityMap_1_16_2.INSTANCE_1_20_2;
-            case ProtocolConstants.MINECRAFT_1_20_3:
-                return EntityMap_1_16_2.INSTANCE_1_20_3;
-            case ProtocolConstants.MINECRAFT_1_20_5:
-            case ProtocolConstants.MINECRAFT_1_21:
-                return EntityMap_1_16_2.INSTANCE_1_20_5;
-            case ProtocolConstants.MINECRAFT_1_21_2:
-                return EntityMap_1_16_2.INSTANCE_1_21_2;
-            case ProtocolConstants.MINECRAFT_1_21_4:
-                return EntityMap_1_16_2.INSTANCE_1_21_4;
-            case ProtocolConstants.MINECRAFT_1_21_5:
-                return EntityMap_1_16_2.INSTANCE_1_21_5;
+            default:
+                return null;
         }
-        throw new RuntimeException( "Version " + version + " has no entity map" );
     }
 
     protected void addRewrite(int id, ProtocolConstants.Direction direction, boolean varint)
diff --git a/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap_1_16_2.java b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap_1_16_2.java
index ce96ac9e..d46ec192 100644
--- a/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap_1_16_2.java
+++ b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap_1_16_2.java
@@ -20,12 +20,6 @@ class EntityMap_1_16_2 extends EntityMap
     static final EntityMap_1_16_2 INSTANCE_1_19 = new EntityMap_1_16_2( 0x02, 0x2F );
     static final EntityMap_1_16_2 INSTANCE_1_19_1 = new EntityMap_1_16_2( 0x02, 0x30 );
     static final EntityMap_1_16_2 INSTANCE_1_19_4 = new EntityMap_1_16_2( 0x03, 0x30 );
-    static final EntityMap_1_16_2 INSTANCE_1_20_2 = new EntityMap_1_16_2( -1, 0x33 );
-    static final EntityMap_1_16_2 INSTANCE_1_20_3 = new EntityMap_1_16_2( -1, 0x34 );
-    static final EntityMap_1_16_2 INSTANCE_1_20_5 = new EntityMap_1_16_2( -1, 0x37 );
-    static final EntityMap_1_16_2 INSTANCE_1_21_2 = new EntityMap_1_16_2( -1, 0x39 );
-    static final EntityMap_1_16_2 INSTANCE_1_21_4 = new EntityMap_1_16_2( -1, 0x3B );
-    static final EntityMap_1_16_2 INSTANCE_1_21_5 = new EntityMap_1_16_2( -1, 0x3C );
     //
     private final int spawnPlayerId;
     private final int spectateId;