From 4c9961c7d1e89a758f36a1eda1adc4a0d1b3f375 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 5 Jan 2025 12:26:40 -0800 Subject: [PATCH] Alternative Keepalive Handling --- .../0017-Alternative-Keepalive-Handling.patch | 73 ------------------- .../ServerCommonPacketListenerImpl.java.patch | 48 ++++++++++++ .../org/purpurmc/purpur/PurpurConfig.java | 5 ++ 3 files changed, 53 insertions(+), 73 deletions(-) delete mode 100644 patches/server/0017-Alternative-Keepalive-Handling.patch diff --git a/patches/server/0017-Alternative-Keepalive-Handling.patch b/patches/server/0017-Alternative-Keepalive-Handling.patch deleted file mode 100644 index 28cbd5491..000000000 --- a/patches/server/0017-Alternative-Keepalive-Handling.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Fri, 11 Oct 2019 00:17:39 -0500 -Subject: [PATCH] Alternative Keepalive Handling - - -diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index 92749b57d3a2b2ffee79436319513248846296b6..df48c2754dc1ebd52addd8ae768cba5916ce3969 100644 ---- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -80,6 +80,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack - private long keepAliveChallenge; - private long closedListenerTime; - private boolean closed = false; -+ private it.unimi.dsi.fastutil.longs.LongList keepAlives = new it.unimi.dsi.fastutil.longs.LongArrayList(); // Purpur - private int latency; - private volatile boolean suspendFlushingOnServerThread = false; - public final java.util.Map packCallbacks = new java.util.concurrent.ConcurrentHashMap<>(); // Paper - adventure resource pack callbacks -@@ -137,6 +138,16 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack - - @Override - public void handleKeepAlive(ServerboundKeepAlivePacket packet) { -+ // Purpur start -+ if (org.purpurmc.purpur.PurpurConfig.useAlternateKeepAlive) { -+ if (this.keepAlivePending && !keepAlives.isEmpty() && keepAlives.contains(packet.getId())) { -+ int ping = (int) (Util.getMillis() - packet.getId()); -+ this.latency = (this.latency * 3 + ping) / 4; -+ this.keepAlivePending = false; -+ keepAlives.clear(); // we got a valid response, lets roll with it and forget the rest -+ } -+ } else -+ // Purpur end - //PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // CraftBukkit // Paper - handle ServerboundKeepAlivePacket async - if (this.keepAlivePending && packet.getId() == this.keepAliveChallenge) { - int i = (int) (Util.getMillis() - this.keepAliveTime); -@@ -269,6 +280,21 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack - long currentTime = Util.getMillis(); - long elapsedTime = currentTime - this.keepAliveTime; - -+ // Purpur start -+ if (org.purpurmc.purpur.PurpurConfig.useAlternateKeepAlive) { -+ if (elapsedTime >= 1000L) { // 1 second -+ if (this.keepAlivePending && !this.processedDisconnect && keepAlives.size() * 1000L >= KEEPALIVE_LIMIT) { -+ this.disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE, org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); -+ } else if (this.checkIfClosed(currentTime)) { -+ this.keepAlivePending = true; -+ this.keepAliveTime = currentTime; // hijack this field for 1 second intervals -+ this.keepAlives.add(currentTime); // currentTime is ID -+ this.send(new ClientboundKeepAlivePacket(currentTime)); -+ } -+ } -+ } else -+ // Purpur end -+ - if (!this.isSingleplayerOwner() && elapsedTime >= 15000L) { // Paper - use vanilla's 15000L between keep alive packets - if (this.keepAlivePending && !this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // Paper - check keepalive limit, don't fire if already disconnected - this.disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE, PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause -diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -index bfa985913f3f750a0727a567d3b5951b4d6ed4ca..2ca6cc6ba72339459d9591a89995521a3c81d111 100644 ---- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java -+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -@@ -201,6 +201,11 @@ public class PurpurConfig { - laggingThreshold = getDouble("settings.lagging-threshold", laggingThreshold); - } - -+ public static boolean useAlternateKeepAlive = false; -+ private static void useAlternateKeepAlive() { -+ useAlternateKeepAlive = getBoolean("settings.use-alternate-keepalive", useAlternateKeepAlive); -+ } -+ - public static int barrelRows = 3; - public static boolean enderChestSixRows = false; - public static boolean enderChestPermissionRows = false; diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch index 24e0e37f3..1532d11a4 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch @@ -1,5 +1,13 @@ --- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +@@ -41,6 +_,7 @@ + private long keepAliveChallenge; + 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 int latency; + private volatile boolean suspendFlushingOnServerThread = false; + // CraftBukkit start @@ -51,6 +_,7 @@ public final java.util.Map packCallbacks = new java.util.concurrent.ConcurrentHashMap<>(); // Paper - adventure resource pack callbacks private static final long KEEPALIVE_LIMIT = Long.getLong("paper.playerconnection.keepalive", 30) * 1000; // Paper - provide property to set keepalive limit @@ -8,6 +16,23 @@ public ServerCommonPacketListenerImpl(MinecraftServer server, Connection connection, CommonListenerCookie cookie, net.minecraft.server.level.ServerPlayer player) { // CraftBukkit this.server = server; +@@ -118,6 +_,16 @@ + + @Override + public void handleKeepAlive(ServerboundKeepAlivePacket packet) { ++ // 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()); ++ this.latency = (this.latency * 3 + ping) / 4; ++ this.keepAlivePending = false; ++ keepAlives.clear(); // we got a valid response, lets roll with it and forget the rest ++ } ++ } else ++ // Purpur end - Alternative Keepalive Handling + if (this.keepAlivePending && packet.getId() == this.keepAliveChallenge) { + int i = (int)(Util.getMillis() - this.keepAliveTime); + this.latency = (this.latency * 3 + i) / 4; @@ -159,6 +_,13 @@ ServerGamePacketListenerImpl.LOGGER.error("Couldn't register custom payload", ex); this.disconnect(Component.literal("Invalid payload REGISTER!"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause @@ -22,3 +47,26 @@ } else if (identifier.equals(ServerCommonPacketListenerImpl.CUSTOM_UNREGISTER)) { try { String channels = payload.toString(com.google.common.base.Charsets.UTF_8); +@@ -238,6 +_,22 @@ + // Paper start - give clients a longer time to respond to pings as per pre 1.12.2 timings + // This should effectively place the keepalive handling back to "as it was" before 1.12.2 + final long elapsedTime = millis - this.keepAliveTime; ++ ++ // Purpur start - Alternative Keepalive Handling ++ if (org.purpurmc.purpur.PurpurConfig.useAlternateKeepAlive) { ++ if (elapsedTime >= 1000L) { // 1 second ++ if (this.keepAlivePending && !this.processedDisconnect && keepAlives.size() * 1000L >= KEEPALIVE_LIMIT) { ++ this.disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE, org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); ++ } else if (this.checkIfClosed(millis)) { ++ this.keepAlivePending = true; ++ this.keepAliveTime = millis; // hijack this field for 1 second intervals ++ this.keepAlives.add(millis); // currentTime is ID ++ this.send(new ClientboundKeepAlivePacket(millis)); ++ } ++ } ++ } else ++ // Purpur end - Alternative Keepalive Handling ++ + if (!this.isSingleplayerOwner() && elapsedTime >= 15000L) { // use vanilla's 15000L between keep alive packets + if (this.keepAlivePending && !this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected + // Paper end - give clients a longer time to respond to pings as per pre 1.12.2 timings diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java index 67be5724c..76189a042 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java @@ -182,6 +182,11 @@ public class PurpurConfig { laggingThreshold = getDouble("settings.lagging-threshold", laggingThreshold); } + public static boolean useAlternateKeepAlive = false; + private static void useAlternateKeepAlive() { + useAlternateKeepAlive = getBoolean("settings.use-alternate-keepalive", useAlternateKeepAlive); + } + public static int barrelRows = 3; public static boolean enderChestSixRows = false; public static boolean enderChestPermissionRows = false;