From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: granny Date: Mon, 23 Mar 2026 17:48:11 -0700 Subject: [PATCH] Alternative Keepalive Handling for Improved Keepalive Ping System diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java index b8a4b4cc02a2fc6b70f4b840796eed501aad6239..02c6733ce1de543dab3bf558148879039e501257 100644 --- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java @@ -40,10 +40,11 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack public final Connection connection; // Paper private final boolean transferred; //private long keepAliveTime; // Paper - improve keepalives - //private boolean keepAlivePending; // Paper - improve keepalives + private boolean keepAlivePending; // Paper - improve keepalives // Purpur - Alternative Keepalive Handling //private long keepAliveChallenge; // Paper - improve keepalives private long closedListenerTime; private boolean closed = false; + private it.unimi.dsi.fastutil.longs.LongList keepAlives = new it.unimi.dsi.fastutil.longs.LongArrayList(); // Purpur - Alternative Keepalive Handling private volatile int latency; // Paper - improve keepalives - make volatile private final io.papermc.paper.util.KeepAlive keepAlive; // Paper - improve keepalives private volatile boolean suspendFlushingOnServerThread = false; @@ -105,6 +110,18 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack // Paper start - improve keepalives long now = System.nanoTime(); io.papermc.paper.util.KeepAlive.PendingKeepAlive pending = this.keepAlive.pendingKeepAlives.peek(); + // Purpur start - Alternative Keepalive Handling + if (org.purpurmc.purpur.PurpurConfig.useAlternateKeepAlive) { + if (this.keepAlivePending && !keepAlives.isEmpty() && keepAlives.contains(packet.getId())) { + int ping = (int) (Util.getMillis() - packet.getId()); + int updatedLatency = (this.latency * 3 + ping) / 4; + this.latency = updatedLatency; + this.keepAlivePending = false; + keepAlives.clear(); // we got a valid response, lets roll with it and forget the rest + } + return; + } else + // Purpur end - Alternative Keepalive Handling if (pending != null && pending.challengeId() == packet.getId()) { this.keepAlive.pendingKeepAlives.remove(pending); @@ -264,6 +287,23 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack Profiler.get().push("keepAlive"); long millis = Util.getMillis(); // Paper start - improve keepalives + // Purpur start - Alternative Keepalive Handling + if (org.purpurmc.purpur.PurpurConfig.useAlternateKeepAlive) { + if (this.checkIfClosed(millis) && !this.processedDisconnect) { + long currTime = System.nanoTime(); + if ((currTime - this.keepAlive.lastKeepAliveTx) >= java.util.concurrent.TimeUnit.SECONDS.toNanos(1L)) { // 1 second + this.keepAlive.lastKeepAliveTx = currTime; + if (this.keepAlivePending && !this.processedDisconnect && keepAlives.size() * 1000L >= KEEPALIVE_LIMIT) { + this.disconnect(TIMEOUT_DISCONNECTION_MESSAGE, io.papermc.paper.connection.DisconnectionReason.TIMEOUT); + } else if (this.checkIfClosed(millis)) { + this.keepAlivePending = true; + this.keepAlives.add(millis); // currentTime is ID + this.send(new ClientboundKeepAlivePacket(millis)); + } + } + } + } else + // Purpur end - Alternative Keepalive Handling if (this.checkIfClosed(millis) && !this.processedDisconnect) { long currTime = System.nanoTime();