Paper/Spigot-Server-Patches/0315-Handle-Large-Packets-disconnecting-client.patch
Mariell Hoversholm 654b792caf Updated Upstream (CraftBukkit)
Upstream has released updates that appears to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

CraftBukkit Changes:
a339310c #755: Fix NPE when calling getInventory() for virtual EnderChests
2577f9bf Increase outdated build delay
1dabfdc8 #754: Fix pre-1.16 serialized SkullMeta being broken on 1.16+, losing textures
2020-09-27 11:04:51 -04:00

123 lines
5.4 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Tue, 27 Nov 2018 21:18:06 -0500
Subject: [PATCH] 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.
diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/java/net/minecraft/server/NetworkManager.java
index 2fda6f6965916e99e603ff87af4226b5ab8417ee..9ea4ce3aa6a43906eb7bf9593de0191a94242da2 100644
--- a/src/main/java/net/minecraft/server/NetworkManager.java
+++ b/src/main/java/net/minecraft/server/NetworkManager.java
@@ -12,6 +12,7 @@ import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.local.LocalChannel;
import io.netty.channel.local.LocalServerChannel;
import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.handler.codec.EncoderException; // Paper
import io.netty.handler.timeout.TimeoutException;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.Future;
@@ -97,6 +98,15 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
}
public void exceptionCaught(ChannelHandlerContext channelhandlercontext, Throwable throwable) {
+ // Paper start
+ if (throwable instanceof EncoderException && throwable.getCause() instanceof PacketEncoder.PacketTooLargeException) {
+ if (((PacketEncoder.PacketTooLargeException) throwable.getCause()).getPacket().packetTooLarge(this)) {
+ return;
+ } else {
+ throwable = throwable.getCause();
+ }
+ }
+ // Paper end
if (throwable instanceof SkipEncodeException) {
NetworkManager.LOGGER.debug("Skipping packet due to errors", throwable.getCause());
} else {
diff --git a/src/main/java/net/minecraft/server/Packet.java b/src/main/java/net/minecraft/server/Packet.java
index 601d4d0fa2a0b3e90f81aed55a2d3473c66c7875..2d8e6a2f4a0c3c5d74a647d7164b0028781d3bf5 100644
--- a/src/main/java/net/minecraft/server/Packet.java
+++ b/src/main/java/net/minecraft/server/Packet.java
@@ -10,6 +10,12 @@ public interface Packet<T extends PacketListener> {
void a(T t0);
+ // Paper start
+ default boolean packetTooLarge(NetworkManager manager) {
+ return false;
+ }
+ // Paper end
+
default boolean a() {
return false;
}
diff --git a/src/main/java/net/minecraft/server/PacketEncoder.java b/src/main/java/net/minecraft/server/PacketEncoder.java
index 63c4dbd327beb7b6ab42eb44650d68accd3b0de6..b0cfef52cbb5e23beae528668e4e98cedecf603c 100644
--- a/src/main/java/net/minecraft/server/PacketEncoder.java
+++ b/src/main/java/net/minecraft/server/PacketEncoder.java
@@ -49,7 +49,31 @@ public class PacketEncoder extends MessageToByteEncoder<Packet<?>> {
throw throwable;
}
}
+
+ // Paper start
+ int packetLength = bytebuf.readableBytes();
+ if (packetLength > MAX_PACKET_SIZE) {
+ throw new PacketTooLargeException(packet, packetLength);
+ }
+ // Paper end
}
}
}
+
+ // Paper start
+ private static int MAX_PACKET_SIZE = 2097152;
+
+ 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 packet;
+ }
+ }
+ // Paper end
}
diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
index 0ef4fbb19fc816f578ad741c4406790f4185093d..34e92e544f37167317d58af4242acde49e588673 100644
--- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
+++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
@@ -79,7 +79,7 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
int i = packetdataserializer.i();
- if (i > 2097152) {
+ if (i > 2097152) { // Paper - if this changes, update PacketEncoder
throw new RuntimeException("Chunk Packet trying to allocate too much memory on read.");
} else {
this.f = new byte[i];
diff --git a/src/main/java/net/minecraft/server/PacketPlayOutWindowItems.java b/src/main/java/net/minecraft/server/PacketPlayOutWindowItems.java
index e32db2baf84dcb192800e6048cadf3511da28181..6fb3168fd6de0074b1b378e992e4706c50ae15ab 100644
--- a/src/main/java/net/minecraft/server/PacketPlayOutWindowItems.java
+++ b/src/main/java/net/minecraft/server/PacketPlayOutWindowItems.java
@@ -9,6 +9,15 @@ public class PacketPlayOutWindowItems implements Packet<PacketListenerPlayOut> {
private int a;
private List<ItemStack> b;
+ //Paper start
+ @Override
+ public boolean packetTooLarge(NetworkManager manager) {
+ for (int i = 0 ; i < this.b.size() ; i++) {
+ manager.sendPacket(new PacketPlayOutSetSlot(this.a, i, this.b.get(i)));
+ }
+ return true;
+ }
+ // Paper end
public PacketPlayOutWindowItems() {}
public PacketPlayOutWindowItems(int i, NonNullList<ItemStack> nonnulllist) {