From 53d10b8e5b30fbec66ff565d9873e6db59015662 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Tue, 23 Apr 2024 02:03:42 -0700 Subject: [PATCH] Adjust large packet handler to run when above protocol limit Previously, PacketEncoder assumed that a packet value larger than the protocol limit would be compressed to become smaller than the protocol limit. However, not all packets will compress below the protocol limit. To try to better handle this, we will run the large packet handler when the packet size is above the protocol limit when the packet has a large packet fallback to avoid a case where the packet does not compress below protocol limit (at which point, it is too late to run the large packet handler). --- ...e-Large-Packets-disconnecting-client.patch | 33 ++++++++++++++----- ...-Manager-and-add-advanced-packet-sup.patch | 17 +++++----- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/patches/server/0273-Handle-Large-Packets-disconnecting-client.patch b/patches/server/0273-Handle-Large-Packets-disconnecting-client.patch index 65d62e20f2..183b46bcde 100644 --- a/patches/server/0273-Handle-Large-Packets-disconnecting-client.patch +++ b/patches/server/0273-Handle-Large-Packets-disconnecting-client.patch @@ -34,7 +34,7 @@ index 02b3f5c67b47a098f7fe15ddba0df6cb586a9ae5..157f055df00faf3a7870df8109e84fdb Connection.LOGGER.debug("Skipping packet due to errors", throwable.getCause()); } else { diff --git a/src/main/java/net/minecraft/network/PacketEncoder.java b/src/main/java/net/minecraft/network/PacketEncoder.java -index 0d80fcee1831af59b06c4d00dc713bd4dad947fc..061eada043325142d33a0cec02e9e484d14a7fca 100644 +index 0d80fcee1831af59b06c4d00dc713bd4dad947fc..3fe047a6ea4eedb92a795dc747d30c0815c2baf2 100644 --- a/src/main/java/net/minecraft/network/PacketEncoder.java +++ b/src/main/java/net/minecraft/network/PacketEncoder.java @@ -41,7 +41,7 @@ public class PacketEncoder extends MessageToByteEncoder> { @@ -46,13 +46,13 @@ index 0d80fcee1831af59b06c4d00dc713bd4dad947fc..061eada043325142d33a0cec02e9e484 throw new IllegalArgumentException("Packet too big (is " + k + ", should be less than 8388608): " + packet); } -@@ -54,9 +54,34 @@ public class PacketEncoder extends MessageToByteEncoder> { +@@ -54,9 +54,37 @@ public class PacketEncoder extends MessageToByteEncoder> { throw var13; } finally { + // Paper start - Handle large packets disconnecting client + int packetLength = friendlyByteBuf.readableBytes(); -+ if (packetLength > MAX_PACKET_SIZE) { ++ if (packetLength > MAX_PACKET_SIZE || (packetLength > MAX_FINAL_PACKET_SIZE && packet.hasLargePacketFallback())) { + throw new PacketTooLargeException(packet, this.codecKey, packetLength); + } + // Paper end - Handle large packets disconnecting client @@ -63,7 +63,10 @@ index 0d80fcee1831af59b06c4d00dc713bd4dad947fc..061eada043325142d33a0cec02e9e484 } + + // Paper start -+ private static int MAX_PACKET_SIZE = 8388608; ++ // packet size is encoded into 3-byte varint ++ private static final int MAX_FINAL_PACKET_SIZE = (1 << 21) - 1; ++ // Vanilla Max size for the encoder (before compression) ++ private static final int MAX_PACKET_SIZE = 8388608; + + public static class PacketTooLargeException extends RuntimeException { + private final Packet packet; @@ -82,14 +85,21 @@ index 0d80fcee1831af59b06c4d00dc713bd4dad947fc..061eada043325142d33a0cec02e9e484 + // Paper end } diff --git a/src/main/java/net/minecraft/network/protocol/Packet.java b/src/main/java/net/minecraft/network/protocol/Packet.java -index 700418bb0c9fbed3f161611881b1e222248ca4eb..cc658a61065d5c0021a4b88fa58b40211b94f8ec 100644 +index 700418bb0c9fbed3f161611881b1e222248ca4eb..c920bf67002f1ca969b5e1559cdfdc2704dead4b 100644 --- a/src/main/java/net/minecraft/network/protocol/Packet.java +++ b/src/main/java/net/minecraft/network/protocol/Packet.java -@@ -10,6 +10,12 @@ public interface Packet { +@@ -10,6 +10,19 @@ public interface Packet { void handle(T listener); + // Paper start ++ default boolean hasLargePacketFallback() { ++ return false; ++ } ++ ++ /** ++ * override {@link #hasLargePacketFallback()} to return true when overriding in subclasses ++ */ + default boolean packetTooLarge(net.minecraft.network.Connection manager) { + return false; + } @@ -99,15 +109,20 @@ index 700418bb0c9fbed3f161611881b1e222248ca4eb..cc658a61065d5c0021a4b88fa58b4021 return false; } diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java -index 6206d4d71dfe95b454b22f5b3055623638e145c0..6765175c98d52e5cbc191e88e0d545a05606dfd4 100644 +index 6206d4d71dfe95b454b22f5b3055623638e145c0..3d52fd6de8b33e45450bb601697920bf94493fb9 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java -@@ -31,6 +31,16 @@ public class ClientboundContainerSetContentPacket implements Packet { - void handle(T listener); - - // Paper start +@@ -21,6 +21,31 @@ public interface Packet { + default boolean packetTooLarge(net.minecraft.network.Connection manager) { + return false; + } ++ + /** + * @param player Null if not at PLAY stage yet + */ @@ -364,9 +365,9 @@ index cc658a61065d5c0021a4b88fa58b40211b94f8ec..da11266a0a23f446196e6facf2c358cf + default java.util.List> getExtraPackets() { + return null; + } - default boolean packetTooLarge(net.minecraft.network.Connection manager) { - return false; - } + // Paper end + + default boolean isSkippable() { diff --git a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java index 4f330a44c77a7ec3237a86fda04921a8c4a1c00f..a4a29a7ea0035ecf4c61ee8547a9eb24acb667d0 100644 --- a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java