aboutsummaryrefslogtreecommitdiffhomepage
path: root/Spigot-Server-Patches/0370-Handle-Large-Packets-disconnecting-client.patch
blob: 3aa860fedd5f2a366cb92c956adc3196de64998c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
From 68670b9f2491fd93af0b802272f6d9f08ed75474 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 3d32e005..a7fcc14f 100644
--- a/src/main/java/net/minecraft/server/NetworkManager.java
+++ b/src/main/java/net/minecraft/server/NetworkManager.java
@@ -112,6 +112,15 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
     }
 
     public void exceptionCaught(ChannelHandlerContext channelhandlercontext, Throwable throwable) throws Exception {
+        // Paper start
+        if (throwable instanceof io.netty.handler.codec.EncoderException && throwable.getCause() instanceof PacketEncoder.PacketTooLargeException) {
+            if (((PacketEncoder.PacketTooLargeException) throwable.getCause()).getPacket().packetTooLarge(this)) {
+                return;
+            } else {
+                throwable = throwable.getCause();
+            }
+        }
+        // Paper end
         ChatMessage chatmessage;
 
         if (throwable instanceof TimeoutException) {
diff --git a/src/main/java/net/minecraft/server/Packet.java b/src/main/java/net/minecraft/server/Packet.java
index fdc142b7..b283e155 100644
--- a/src/main/java/net/minecraft/server/Packet.java
+++ b/src/main/java/net/minecraft/server/Packet.java
@@ -8,5 +8,10 @@ public interface Packet<T extends PacketListener> {
 
     void b(PacketDataSerializer packetdataserializer) throws IOException;
 
+    // Paper start
+    default boolean packetTooLarge(NetworkManager manager) {
+        return false;
+    }
+    // Paper end
     void a(T t0);
 }
diff --git a/src/main/java/net/minecraft/server/PacketEncoder.java b/src/main/java/net/minecraft/server/PacketEncoder.java
index a6da6f5c..4e263aa8 100644
--- a/src/main/java/net/minecraft/server/PacketEncoder.java
+++ b/src/main/java/net/minecraft/server/PacketEncoder.java
@@ -44,11 +44,32 @@ public class PacketEncoder extends MessageToByteEncoder<Packet<?>> {
                     PacketEncoder.a.error(throwable);
                 }
 
+                // Paper start
+                int packetLength = bytebuf.readableBytes();
+                if (packetLength > MAX_PACKET_SIZE) {
+                    throw new PacketTooLargeException(packet, packetLength);
+                }
+                // Paper end
             }
         }
     }
 
-    protected void encode(ChannelHandlerContext channelhandlercontext, Object object, ByteBuf bytebuf) throws Exception {
+    // 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
+
+    protected void encode(ChannelHandlerContext channelhandlercontext, Packet<?> object, ByteBuf bytebuf) throws Exception { // Paper - decompile fix
         this.a(channelhandlercontext, (Packet) object, bytebuf);
     }
 }
diff --git a/src/main/java/net/minecraft/server/PacketPlayOutWindowItems.java b/src/main/java/net/minecraft/server/PacketPlayOutWindowItems.java
index bf47c824..e054757d 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) {
-- 
2.19.2