Files
Purpur/patches/server/0024-FEAT-Alternative-keepalive-handling.patch
2021-09-16 15:17:30 -07:00

89 lines
5.1 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Fri, 11 Oct 2019 00:17:39 -0500
Subject: [PATCH] |FEAT| Alternative keepalive handling
Replaces Mojang's keep-alive packet processing with a completely different implementation.
This new implementation will send out a keep alive packet every 1 second, and if any of these
packets are responded to within 30 seconds the connection is considered alive and the player
will not be kicked.
$-----------------------------$
settings:
use-alternate-keepalive:
default: false
description: |-
Uses a different approach to keepalive ping timeouts.
Enabling this sends a keepalive packet once per second to a player and only kicks for timeout if none of them were responded to in 30 seconds.
Responding to any of them in any order will keep the player connected. AKA, it won't kick your players because 1 packet gets dropped somewhere along the lines
$-----------------------------$
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index c69c663d9f569cf15381ed63031a34a5e2ffac7d..94d526fd0c1e8c68638fdeadf088b70889452d5f 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -228,6 +228,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
private long keepAliveTime = Util.getMillis();
private boolean keepAlivePending;
private long keepAliveChallenge;
+ private java.util.List<Long> keepAlives = new java.util.ArrayList<>(); // Purpur
// CraftBukkit start - multithreaded fields
private AtomicInteger chatSpamTickCount = new AtomicInteger();
private final java.util.concurrent.atomic.AtomicInteger tabSpamLimiter = new java.util.concurrent.atomic.AtomicInteger(); // Paper - configurable tab spam limits
@@ -372,6 +373,21 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
long currentTime = Util.getMillis();
long elapsedTime = currentTime - this.keepAliveTime;
+ // Purpur start
+ if (net.pl3x.purpur.PurpurConfig.useAlternateKeepAlive) {
+ if (elapsedTime >= 1000L) { // 1 second
+ if (!processedDisconnect && keepAlives.size() > KEEPALIVE_LIMIT) {
+ LOGGER.warn("{} was kicked due to keepalive timeout!", player.getName());
+ disconnect(new TranslatableComponent("disconnect.timeout"));
+ } else {
+ keepAliveTime = currentTime; // hijack this field for 1 second intervals
+ keepAlives.add(currentTime); // currentTime is ID
+ send(new ClientboundKeepAlivePacket(currentTime));
+ }
+ }
+ } else
+ // Purpur end
+
if (this.keepAlivePending) {
if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected
ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked due to keepalive timeout!", this.player.getScoreboardName()); // more info
@@ -3106,6 +3122,16 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
@Override
public void handleKeepAlive(ServerboundKeepAlivePacket packet) {
+ // Purpur start
+ if (net.pl3x.purpur.PurpurConfig.useAlternateKeepAlive) {
+ long id = packet.getId();
+ if (keepAlives.size() > 0 && keepAlives.contains(id)) {
+ int ping = (int) (Util.getMillis() - id);
+ player.latency = (player.latency * 3 + ping) / 4;
+ keepAlives.clear(); // we got a valid response, lets roll with it and forget the rest
+ }
+ } else
+ // Purpur end
//PlayerConnectionUtils.ensureMainThread(packetplayinkeepalive, this, this.player.getWorldServer()); // CraftBukkit // Paper - This shouldn't be on the main thread
if (this.keepAlivePending && packet.getId() == this.keepAliveChallenge) {
int i = (int) (Util.getMillis() - this.keepAliveTime);
diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java
index c0e7027ad804d7b801ef8cb94963c113c95735d1..4b6bb477db0af506508e73dd42155429777b49d0 100644
--- a/src/main/java/net/pl3x/purpur/PurpurConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java
@@ -193,6 +193,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;