diff --git a/patches/server/0061-Purpur-Alternative-Keepalive-Handling.patch b/patches/server/0061-Purpur-Alternative-Keepalive-Handling.patch new file mode 100644 index 0000000..ec83385 --- /dev/null +++ b/patches/server/0061-Purpur-Alternative-Keepalive-Handling.patch @@ -0,0 +1,90 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Etil <81570777+etil2jz@users.noreply.github.com> +Date: Sun, 26 Sep 2021 14:30:00 +0200 +Subject: [PATCH] (Purpur) Alternative Keepalive Handling + + +diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index a31e066571b98d18cd6805c4037ebc0cefc1f17f..63fd225c449d5ec1e84b4e561b310ae502eb88f4 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 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 +@@ -357,6 +358,21 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser + // This should effectively place the keepalive handling back to "as it was" before 1.12.2 + long currentTime = Util.getMillis(); + long elapsedTime = currentTime - this.keepAliveTime; ++ ++ // Purpur start ++ if (xyz.arthurb.mirai.MiraiConfig.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 +@@ -3072,6 +3088,16 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser + + @Override + public void handleKeepAlive(ServerboundKeepAlivePacket packet) { ++ // Purpur start ++ if (xyz.arthurb.mirai.MiraiConfig.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/xyz/arthurb/mirai/MiraiConfig.java b/src/main/java/xyz/arthurb/mirai/MiraiConfig.java +index 72dad6f85c1307aa99b0506d2dfd6e376b2dd11d..0888a159b08b49ea333d88e1c110c0f9ea707f27 100644 +--- a/src/main/java/xyz/arthurb/mirai/MiraiConfig.java ++++ b/src/main/java/xyz/arthurb/mirai/MiraiConfig.java +@@ -1,10 +1,15 @@ + package xyz.arthurb.mirai; + ++import co.aikar.timings.TimingsManager; + import com.destroystokyo.paper.PaperCommand; + import com.google.common.base.Throwables; ++import com.google.common.collect.ImmutableMap; + import net.minecraft.server.MinecraftServer; ++import net.minecraft.world.entity.EntityDimensions; ++import net.minecraft.world.entity.EntityType; + import org.bukkit.Bukkit; + import org.bukkit.command.Command; ++import org.bukkit.configuration.ConfigurationSection; + import org.bukkit.configuration.InvalidConfigurationException; + import org.bukkit.configuration.file.YamlConfiguration; + +@@ -210,5 +215,11 @@ public class MiraiConfig { + private static void dontSendUselessEntityPackets() { + dontSendUselessEntityPackets = getBoolean("settings.dont-send-useless-entity-packets", dontSendUselessEntityPackets); + } ++ ++ public static boolean useAlternateKeepAlive = false; ++ ++ private static void useAlternateKeepAlive() { ++ useAlternateKeepAlive = getBoolean("settings.use-alternate-keepalive", useAlternateKeepAlive); ++ } + + } +\ No newline at end of file