--- a/net/minecraft/network/PacketEncoder.java +++ b/net/minecraft/network/PacketEncoder.java @@ -17,10 +17,12 @@ this.protocolInfo = state; } + static final ThreadLocal ADVENTURE_LOCALE = ThreadLocal.withInitial(() -> null); // Paper - adventure; set player's locale protected void encode(ChannelHandlerContext channelHandlerContext, Packet packet, ByteBuf byteBuf) throws Exception { PacketType> packetType = packet.type(); try { + ADVENTURE_LOCALE.set(channelHandlerContext.channel().attr(io.papermc.paper.adventure.PaperAdventure.LOCALE_ATTRIBUTE).get()); // Paper - adventure; set player's locale this.protocolInfo.codec().encode(byteBuf, packet); int i = byteBuf.readableBytes(); if (LOGGER.isDebugEnabled()) { @@ -31,14 +33,40 @@ JvmProfiler.INSTANCE.onPacketSent(this.protocolInfo.id(), packetType, channelHandlerContext.channel().remoteAddress(), i); } catch (Throwable var9) { - LOGGER.error("Error sending packet {}", packetType, var9); + LOGGER.error("Error sending packet {} (skippable? {})", packetType, packet.isSkippable(), var9); 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 }