Handle Large Packets disconnecting client

If a players inventory is too big to send in a single packet,
split the inventory set into multiple packets instead.
This commit is contained in:
Aikar
2018-11-27 21:18:06 -05:00
parent ba71d372a5
commit 236dce4925
5 changed files with 126 additions and 15 deletions

View File

@@ -13,7 +13,7 @@
this.protocolInfo.codec().encode(byteBuf, packet);
int i = byteBuf.readableBytes();
if (LOGGER.isDebugEnabled()) {
@@ -31,7 +33,7 @@
@@ -31,14 +33,40 @@
JvmProfiler.INSTANCE.onPacketSent(this.protocolInfo.id(), packetType, channelHandlerContext.channel().remoteAddress(), i);
} catch (Throwable var9) {
@@ -22,3 +22,36 @@
if (packet.isSkippable()) {
throw new SkipPacketException(var9);
}
throw var9;
} finally {
+ // Paper start - Handle large packets disconnecting client
+ int packetLength = byteBuf.readableBytes();
+ if (packetLength > MAX_PACKET_SIZE || (packetLength > MAX_FINAL_PACKET_SIZE && packet.hasLargePacketFallback())) {
+ throw new PacketTooLargeException(packet, packetLength);
+ }
+ // Paper end - Handle large packets disconnecting client
ProtocolSwapHandler.handleOutboundTerminalPacket(channelHandlerContext, packet);
}
}
+
+ // Paper start
+ // 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;
+
+ PacketTooLargeException(Packet<?> packet, int packetLength) {
+ super("PacketTooLarge - " + packet.getClass().getSimpleName() + " is " + packetLength + ". Max is " + MAX_PACKET_SIZE);
+ this.packet = packet;
+ }
+
+ public Packet<?> getPacket() {
+ return this.packet;
+ }
+ }
+ // Paper end
}