Skip to content

Commit 8021488

Browse files
authored
Disconnect State Fixes (#13616)
Replaces the processedDisconnect flag and executeBlocking cleanup with a force kill flag processed by the connection listener tick. executeBlocking(connection::handleDisconnection) did not actually Work, as the the channel is still open at that point because the disconnect packet hasn't been flushed. Replaced with handleConnectionDisconnectOnNextTick, which the connection listener processes on the next tick. processedDisconnect was an old flag preventing double disconnect. The same protection is now provided by vanilla's disconnectionHandled check on Connection. Drops the SPIGOT-924 player.doTick() call on quit. This is an ancient spigot bug fix that causes issues and weird event fires whilst the player is disconnected. Removes the login side disconnecting flag and the matching tick guard, since the connection now closes properly on its own. The login disconnect path moves to disconnectAsync so it doesn't block on IO.
1 parent 182b2f8 commit 8021488

16 files changed

Lines changed: 123 additions & 129 deletions

paper-server/patches/features/0001-Moonrise-optimisation-patches.patch

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23838,7 +23838,7 @@ index 3c1490ac7c259da04031db2f170e0c0a5f512191..470d7c770ae9d045b97e2df145cfe3cf
2383823838
}
2383923839
}
2384023840
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
23841-
index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896c81fc2ef 100644
23841+
index c11e2ce21e43f677bfccb65e6b5ad374912381fa..9aae782f8f9f1c0f7eae394ec0a1bda79e93f6f4 100644
2384223842
--- a/net/minecraft/server/MinecraftServer.java
2384323843
+++ b/net/minecraft/server/MinecraftServer.java
2384423844
@@ -191,7 +191,7 @@ import net.minecraft.world.scores.ScoreboardSaveData;
@@ -23943,7 +23943,7 @@ index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896
2394323943

2394423944
public MinecraftServer(
2394523945
// CraftBukkit start
23946-
@@ -843,7 +929,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
23946+
@@ -853,7 +939,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2394723947
level.setSpawnSettings(level.isSpawningMonsters()); // Paper - per level difficulty (from setDifficulty(ServerLevel, Difficulty, boolean))
2394823948
this.updateEffectiveRespawnData();
2394923949
this.forceTicks = false; // CraftBukkit
@@ -23952,7 +23952,7 @@ index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896
2395223952
new org.bukkit.event.world.WorldLoadEvent(level.getWorld()).callEvent(); // Paper - call WorldLoadEvent
2395323953
}
2395423954

23955-
@@ -866,6 +952,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
23955+
@@ -876,6 +962,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2395623956
public abstract boolean shouldRconBroadcast();
2395723957

2395823958
public boolean saveAllChunks(final boolean silent, final boolean flush, final boolean force) {
@@ -23964,7 +23964,7 @@ index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896
2396423964
this.scoreboard.storeToSaveDataIfDirty(this.getDataStorage().computeIfAbsent(ScoreboardSaveData.TYPE));
2396523965
boolean result = false;
2396623966

23967-
@@ -874,7 +965,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
23967+
@@ -884,7 +975,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2396823968
LOGGER.info("Saving chunks for level '{}'/{}", level, level.dimension().identifier());
2396923969
}
2397023970

@@ -23973,7 +23973,7 @@ index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896
2397323973
result = true;
2397423974
}
2397523975

23976-
@@ -971,7 +1062,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
23976+
@@ -981,7 +1072,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2397723977
}
2397823978
}
2397923979

@@ -23982,7 +23982,7 @@ index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896
2398223982
this.nextTickTimeNanos = Util.getNanos() + TimeUtil.NANOSECONDS_PER_MILLISECOND;
2398323983

2398423984
for (ServerLevel levelx : this.getAllLevels()) {
23985-
@@ -982,17 +1073,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
23985+
@@ -992,17 +1083,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2398623986
this.waitUntilNextTick();
2398723987
}
2398823988

@@ -24007,7 +24007,7 @@ index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896
2400724007

2400824008
this.isSaving = false;
2400924009
this.savedDataStorage.close();
24010-
@@ -1013,6 +1101,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
24010+
@@ -1023,6 +1111,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2401124011
this.services().nameToIdCache().save(false); // Paper - Perf: Async GameProfileCache saving
2401224012
}
2401324013
// Spigot end
@@ -24022,7 +24022,7 @@ index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896
2402224022
// Paper start - Improved watchdog support - move final shutdown items here
2402324023
Util.shutdownExecutors();
2402424024
this.onServerExit();
24025-
@@ -1107,16 +1203,31 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
24025+
@@ -1117,16 +1213,31 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2402624026
// execute small amounts of other tasks just in case the number of tasks we are
2402724027
// draining is large - chunk system and packet processing may be latency sensitive
2402824028

@@ -24057,15 +24057,15 @@ index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896
2405724057
profiler.pop(); // moonrise:run_all_chunk
2405824058
profiler.pop(); // moonrise:run_all_tasks
2405924059

24060-
@@ -1417,6 +1528,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
24060+
@@ -1427,6 +1538,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2406124061

2406224062
private boolean pollTaskInternal() {
2406324063
if (super.pollTask()) {
2406424064
+ this.moonrise$executeMidTickTasks(); // Paper - rewrite chunk system
2406524065
return true;
2406624066
} else {
2406724067
boolean ret = false; // Paper - force execution of all worlds, do not just bias the first
24068-
@@ -1558,6 +1670,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
24068+
@@ -1568,6 +1680,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2406924069
// Paper - improve tick loop - moved into runAllTasksAtTickStart
2407024070
this.runAllTasksAtTickStart(); // Paper - improve tick loop
2407124071
this.tickServer(sprinting ? () -> false : this::haveTime);
@@ -24079,7 +24079,7 @@ index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896
2407924079
this.tickFrame.end();
2408024080
this.recordEndOfTick(); // Paper - improve tick loop
2408124081
profiler.pop();
24082-
@@ -2600,6 +2719,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
24082+
@@ -2610,6 +2729,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2408324083
}
2408424084
}
2408524085

@@ -28487,10 +28487,10 @@ index 83af9ee3ba150da85b9b694cd76a5fabb5b2d8ef..1fb40837bd02672850ec9adc2797190d
2848728487
PrepareSpawnTask.this.loadListener.updateFocus(this.spawnLevel.dimension(), spawnChunk);
2848828488
}
2848928489
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
28490-
index 0c4de29676732f5e84d7584e1f89d508addc1cc4..0613b053f4a75c0884280011ee092d9d108b3857 100644
28490+
index c4f8f0e1013809260977c0874205fbaeebb27e95..b928b58ea5f0b4268b999ce4a23fe2fbc3042f4e 100644
2849128491
--- a/net/minecraft/server/players/PlayerList.java
2849228492
+++ b/net/minecraft/server/players/PlayerList.java
28493-
@@ -983,8 +983,8 @@ public abstract class PlayerList {
28493+
@@ -982,8 +982,8 @@ public abstract class PlayerList {
2849428494
player.connection.send(this.server.clockManager().createFullSyncPacket());
2849528495
player.connection.send(new ClientboundSetDefaultSpawnPositionPacket(level.getRespawnData()));
2849628496
// Paper start - view distances
@@ -28501,7 +28501,7 @@ index 0c4de29676732f5e84d7584e1f89d508addc1cc4..0613b053f4a75c0884280011ee092d9d
2850128501
// Paper end - view distances
2850228502
if (level.isRaining()) {
2850328503
// CraftBukkit start - handle player weather
28504-
@@ -1201,7 +1201,7 @@ public abstract class PlayerList {
28504+
@@ -1200,7 +1200,7 @@ public abstract class PlayerList {
2850528505

2850628506
public void setViewDistance(final int viewDistance) {
2850728507
this.viewDistance = viewDistance;
@@ -28510,7 +28510,7 @@ index 0c4de29676732f5e84d7584e1f89d508addc1cc4..0613b053f4a75c0884280011ee092d9d
2851028510

2851128511
for (ServerLevel level : this.server.getAllLevels()) {
2851228512
level.getChunkSource().setViewDistance(viewDistance);
28513-
@@ -1210,7 +1210,7 @@ public abstract class PlayerList {
28513+
@@ -1209,7 +1209,7 @@ public abstract class PlayerList {
2851428514

2851528515
public void setSimulationDistance(final int simulationDistance) {
2851628516
this.simulationDistance = simulationDistance;
@@ -30053,7 +30053,7 @@ index e07a7bda45146686a6ac2d20507df9fc8630514f..f84e651e2a34e76a0a71993332e4be1b
3005330053

3005430054
// Paper start - Affects Spawning API
3005530055
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
30056-
index 81c3f9f04040b6cfa014ce55e517bd9b374ec252..0958fe0438c3e934b885acf78a0f8003ef8bb694 100644
30056+
index 30183d8752aa397a5c1fc554da49f595be286534..5566f449fb79b04822e533df4fd6de42116ffd14 100644
3005730057
--- a/net/minecraft/world/level/Level.java
3005830058
+++ b/net/minecraft/world/level/Level.java
3005930059
@@ -87,6 +87,7 @@ import net.minecraft.world.level.storage.LevelData;

paper-server/patches/features/0003-Optimize-Connection-and-add-advanced-packet-support.patch

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ and then catch exceptions and close if they fire.
2828
Part of this commit was authored by: Spottedleaf, sandtechnology
2929

3030
diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java
31-
index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6b33beff8 100644
31+
index 1511cbd2e6123a00d22694353ee4989d539fe0f0..104976b3eb04d80e5be5bd020cf16c647b1cde27 100644
3232
--- a/net/minecraft/network/Connection.java
3333
+++ b/net/minecraft/network/Connection.java
3434
@@ -65,7 +65,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
@@ -40,7 +40,7 @@ index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6
4040
public Channel channel;
4141
public SocketAddress address;
4242
// Spigot start
43-
@@ -123,6 +123,10 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
43+
@@ -124,6 +124,10 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
4444
public boolean handledLegacyLoginEvent; // Paper - playerloginevent
4545
public net.minecraft.server.level.@Nullable ServerPlayer savedPlayerForLegacyEvents; // Paper - playerloginevent & PlayerSpawnLocationEvent
4646
public org.bukkit.event.player.PlayerResourcePackStatusEvent.@Nullable Status resourcePackStatus; // Paper
@@ -51,7 +51,7 @@ index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6
5151

5252
public Connection(final PacketFlow receiving) {
5353
this.receiving = receiving;
54-
@@ -393,11 +397,38 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
54+
@@ -394,11 +398,38 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
5555
}
5656

5757
public void send(final Packet<?> packet, final @Nullable ChannelFutureListener listener, final boolean flush) {
@@ -93,7 +93,7 @@ index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6
9393
}
9494
}
9595

96-
@@ -406,7 +437,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
96+
@@ -407,7 +438,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
9797
this.flushQueue();
9898
action.accept(this);
9999
} else {
@@ -102,7 +102,7 @@ index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6
102102
}
103103
}
104104

105-
@@ -420,21 +451,41 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
105+
@@ -421,21 +452,42 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
106106
}
107107

108108
private void doSendPacket(final Packet<?> packet, final @Nullable ChannelFutureListener listener, final boolean flush) {
@@ -133,7 +133,8 @@ index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6
133133
+ }
134134
+ } catch (final Exception e) {
135135
+ LOGGER.error("NetworkException: {}", player, e);
136-
+ this.disconnect(Component.translatable("disconnect.genericReason", "Internal Exception: " + e.getMessage()));
136+
+ Component reason = Component.translatable("disconnect.genericReason", "Internal Exception: " + e.getMessage());
137+
+ this.send(new ClientboundDisconnectPacket(reason), PacketSendListener.thenRun(() -> this.disconnect(reason)));
137138
+ packet.onPacketDispatchFinish(player, null);
138139
}
139140
+ // Paper end - Optimize network
@@ -148,7 +149,7 @@ index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6
148149
}
149150
}
150151

151-
@@ -446,16 +497,57 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
152+
@@ -447,16 +499,57 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
152153
}
153154
}
154155

@@ -211,15 +212,15 @@ index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6
211212

212213
private static final int MAX_PER_TICK = io.papermc.paper.configuration.GlobalConfiguration.get().misc.maxJoinsPerTick; // Paper - Buffer joins to world
213214
private static int joinAttemptsThisTick; // Paper - Buffer joins to world
214-
@@ -525,6 +617,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
215+
@@ -526,6 +619,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
215216

216217
public void disconnect(final DisconnectionDetails details) {
217218
this.preparing = false; // Spigot
218219
+ this.clearPacketQueue(); // Paper - Optimize network
219220
if (this.channel == null) {
220221
this.delayedDisconnect = details;
221222
}
222-
@@ -714,7 +807,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
223+
@@ -715,7 +809,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
223224
public void handleDisconnection() {
224225
if (this.channel != null && !this.channel.isOpen()) {
225226
if (this.disconnectionHandled) {
@@ -228,7 +229,7 @@ index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6
228229
} else {
229230
this.disconnectionHandled = true;
230231
PacketListener packetListener = this.getPacketListener();
231-
@@ -725,7 +818,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
232+
@@ -726,7 +820,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
232233
);
233234
disconnectListener.onDisconnect(details);
234235
}
@@ -237,7 +238,7 @@ index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6
237238
// Paper start - Add PlayerConnectionCloseEvent
238239
if (packetListener instanceof net.minecraft.server.network.ServerCommonPacketListenerImpl commonPacketListener) {
239240
/* Player was logged in, either game listener or configuration listener */
240-
@@ -760,4 +853,96 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
241+
@@ -761,4 +855,96 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
241242
public void setBandwidthLogger(final LocalSampleLogger bandwidthLogger) {
242243
this.bandwidthDebugMonitor = new BandwidthDebugMonitor(bandwidthLogger);
243244
}
@@ -371,7 +372,7 @@ index 1480d0db90f5797e3dee19503e52d1e783493ac3..bd76e55ea56dd7c1e232806d1d13a747
371372
+ // Paper end
372373
}
373374
diff --git a/net/minecraft/server/network/ServerConnectionListener.java b/net/minecraft/server/network/ServerConnectionListener.java
374-
index b0445b4ad9adb6d2dec08537559d2ed243ca69bb..b266e4f7b437578356568d86910e3b428ee66523 100644
375+
index 387ac8a4e67ef07df73ce98d0add0937314ee497..9ae7c79e5088d9e1e3fb7e0dca00bb15fee118b6 100644
375376
--- a/net/minecraft/server/network/ServerConnectionListener.java
376377
+++ b/net/minecraft/server/network/ServerConnectionListener.java
377378
@@ -52,11 +52,13 @@ public class ServerConnectionListener {

paper-server/patches/features/0008-Use-Velocity-compression-and-cipher-natives.patch

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -266,10 +266,10 @@ index 319325e741cc314b84844bb49ea569aaf014f319..20b5cfe1ce36d74cd6b2f95566a1bc34
266266
+ // Paper end - Use Velocity cipher
267267
}
268268
diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java
269-
index 9cd6ec17981da310be1d35054af080d6b33beff8..d7ed1621709c491525daaf7adc8e9f0d781c93e1 100644
269+
index 104976b3eb04d80e5be5bd020cf16c647b1cde27..5a23f95aff982ecc58d2e2bc994f4e495285069c 100644
270270
--- a/net/minecraft/network/Connection.java
271271
+++ b/net/minecraft/network/Connection.java
272-
@@ -738,11 +738,22 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
272+
@@ -740,11 +740,22 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
273273
return connection;
274274
}
275275

@@ -296,7 +296,7 @@ index 9cd6ec17981da310be1d35054af080d6b33beff8..d7ed1621709c491525daaf7adc8e9f0d
296296

297297
public boolean isEncrypted() {
298298
return this.encrypted;
299-
@@ -780,16 +791,17 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
299+
@@ -782,16 +793,17 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
300300

301301
public void setupCompression(final int threshold, final boolean validateDecompressed) {
302302
if (threshold >= 0) {
@@ -318,7 +318,7 @@ index 9cd6ec17981da310be1d35054af080d6b33beff8..d7ed1621709c491525daaf7adc8e9f0d
318318
this.channel.pipeline().fireUserEventTriggered(io.papermc.paper.network.ConnectionEvent.COMPRESSION_THRESHOLD_SET); // Paper - Add Channel initialization listeners
319319
} else {
320320
diff --git a/net/minecraft/server/network/ServerConnectionListener.java b/net/minecraft/server/network/ServerConnectionListener.java
321-
index b266e4f7b437578356568d86910e3b428ee66523..0b57e3bcd0319e4e9571fddbcb85db5a3105b8b2 100644
321+
index 9ae7c79e5088d9e1e3fb7e0dca00bb15fee118b6..eb0d51ffcc888204881b48a8b1408d0b54b252e4 100644
322322
--- a/net/minecraft/server/network/ServerConnectionListener.java
323323
+++ b/net/minecraft/server/network/ServerConnectionListener.java
324324
@@ -77,6 +77,10 @@ public class ServerConnectionListener {
@@ -333,10 +333,10 @@ index b266e4f7b437578356568d86910e3b428ee66523..0b57e3bcd0319e4e9571fddbcb85db5a
333333
.add(
334334
new ServerBootstrap()
335335
diff --git a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
336-
index 8203765d5570644b4c8f6790f361bca2c7066b25..718f00ad9c587a4b0c12f351c10d462113f16ac3 100644
336+
index fb2ed24931c2f468ab6f228a202f22562784febd..72bf241ee7ebd02781b539a24c1df8e7f62fb94d 100644
337337
--- a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
338338
+++ b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
339-
@@ -245,11 +245,9 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
339+
@@ -253,11 +253,9 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
340340
}
341341

342342
SecretKey secretKey = packet.getSecretKey(serverPrivateKey);

0 commit comments

Comments
 (0)