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
123 lines
5.4 KiB
Diff
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) {
|