From df47c40998e8083fec098aca409ea996e400675a Mon Sep 17 00:00:00 2001 From: Zhyren-git Date: Wed, 17 Dec 2025 18:01:40 -0400 Subject: [PATCH 1/5] Fixed player getting "Timed out" while standing still due to Keep-Alive not being sent correctly. --- .../loohp/limbo/network/ClientConnection.java | 132 ++++-------------- 1 file changed, 24 insertions(+), 108 deletions(-) diff --git a/src/main/java/com/loohp/limbo/network/ClientConnection.java b/src/main/java/com/loohp/limbo/network/ClientConnection.java index a276a74..ff70bc2 100644 --- a/src/main/java/com/loohp/limbo/network/ClientConnection.java +++ b/src/main/java/com/loohp/limbo/network/ClientConnection.java @@ -25,16 +25,7 @@ import com.loohp.limbo.events.connection.ConnectionEstablishedEvent; import com.loohp.limbo.events.inventory.AnvilRenameInputEvent; import com.loohp.limbo.events.inventory.InventoryCloseEvent; import com.loohp.limbo.events.inventory.InventoryCreativeEvent; -import com.loohp.limbo.events.player.PlayerInteractEvent; -import com.loohp.limbo.events.player.PlayerJoinEvent; -import com.loohp.limbo.events.player.PlayerLoginEvent; -import com.loohp.limbo.events.player.PlayerMoveEvent; -import com.loohp.limbo.events.player.PlayerQuitEvent; -import com.loohp.limbo.events.player.PlayerResourcePackStatusEvent; -import com.loohp.limbo.events.player.PlayerSelectedSlotChangeEvent; -import com.loohp.limbo.events.player.PlayerSpawnEvent; -import com.loohp.limbo.events.player.PlayerSwapHandItemsEvent; -import com.loohp.limbo.events.player.PluginMessageEvent; +import com.loohp.limbo.events.player.*; import com.loohp.limbo.events.status.StatusPingEvent; import com.loohp.limbo.file.ServerProperties; import com.loohp.limbo.inventory.AnvilInventory; @@ -42,77 +33,20 @@ import com.loohp.limbo.inventory.Inventory; import com.loohp.limbo.inventory.ItemStack; import com.loohp.limbo.location.GlobalPos; import com.loohp.limbo.location.Location; -import com.loohp.limbo.network.protocol.packets.ClientboundFinishConfigurationPacket; -import com.loohp.limbo.network.protocol.packets.ClientboundLevelChunkWithLightPacket; -import com.loohp.limbo.network.protocol.packets.ClientboundRegistryDataPacket; -import com.loohp.limbo.network.protocol.packets.PacketHandshakingIn; -import com.loohp.limbo.network.protocol.packets.PacketIn; -import com.loohp.limbo.network.protocol.packets.PacketLoginInLoginStart; -import com.loohp.limbo.network.protocol.packets.PacketLoginInPluginMessaging; -import com.loohp.limbo.network.protocol.packets.PacketLoginOutDisconnect; -import com.loohp.limbo.network.protocol.packets.PacketLoginOutLoginSuccess; -import com.loohp.limbo.network.protocol.packets.PacketLoginOutPluginMessaging; -import com.loohp.limbo.network.protocol.packets.PacketOut; -import com.loohp.limbo.network.protocol.packets.PacketPlayInBlockDig; -import com.loohp.limbo.network.protocol.packets.PacketPlayInBlockPlace; -import com.loohp.limbo.network.protocol.packets.PacketPlayInChat; -import com.loohp.limbo.network.protocol.packets.PacketPlayInCloseWindow; -import com.loohp.limbo.network.protocol.packets.PacketPlayInHeldItemChange; -import com.loohp.limbo.network.protocol.packets.PacketPlayInItemName; -import com.loohp.limbo.network.protocol.packets.PacketPlayInKeepAlive; -import com.loohp.limbo.network.protocol.packets.PacketPlayInPickItem; -import com.loohp.limbo.network.protocol.packets.PacketPlayInPluginMessaging; -import com.loohp.limbo.network.protocol.packets.PacketPlayInPosition; -import com.loohp.limbo.network.protocol.packets.PacketPlayInPositionAndLook; -import com.loohp.limbo.network.protocol.packets.PacketPlayInRotation; -import com.loohp.limbo.network.protocol.packets.PacketPlayInSetCreativeSlot; -import com.loohp.limbo.network.protocol.packets.PacketPlayInTabComplete; -import com.loohp.limbo.network.protocol.packets.PacketPlayInUseItem; -import com.loohp.limbo.network.protocol.packets.PacketPlayInWindowClick; -import com.loohp.limbo.network.protocol.packets.PacketPlayOutDeclareCommands; -import com.loohp.limbo.network.protocol.packets.PacketPlayOutDisconnect; -import com.loohp.limbo.network.protocol.packets.PacketPlayOutEntityMetadata; -import com.loohp.limbo.network.protocol.packets.PacketPlayOutGameStateChange; -import com.loohp.limbo.network.protocol.packets.PacketPlayOutHeldItemChange; -import com.loohp.limbo.network.protocol.packets.PacketPlayOutKeepAlive; -import com.loohp.limbo.network.protocol.packets.PacketPlayOutLogin; -import com.loohp.limbo.network.protocol.packets.PacketPlayOutPlayerAbilities; +import com.loohp.limbo.network.protocol.packets.*; import com.loohp.limbo.network.protocol.packets.PacketPlayOutPlayerAbilities.PlayerAbilityFlags; -import com.loohp.limbo.network.protocol.packets.PacketPlayOutPlayerInfo; import com.loohp.limbo.network.protocol.packets.PacketPlayOutPlayerInfo.PlayerInfoAction; import com.loohp.limbo.network.protocol.packets.PacketPlayOutPlayerInfo.PlayerInfoData; import com.loohp.limbo.network.protocol.packets.PacketPlayOutPlayerInfo.PlayerInfoData.PlayerInfoDataAddPlayer.PlayerSkinProperty; -import com.loohp.limbo.network.protocol.packets.PacketPlayOutPluginMessaging; -import com.loohp.limbo.network.protocol.packets.PacketPlayOutPositionAndLook; -import com.loohp.limbo.network.protocol.packets.PacketPlayOutSpawnPosition; -import com.loohp.limbo.network.protocol.packets.PacketPlayOutTabComplete; import com.loohp.limbo.network.protocol.packets.PacketPlayOutTabComplete.TabCompleteMatches; -import com.loohp.limbo.network.protocol.packets.PacketPlayOutUpdateViewPosition; -import com.loohp.limbo.network.protocol.packets.PacketStatusInPing; -import com.loohp.limbo.network.protocol.packets.PacketStatusInRequest; -import com.loohp.limbo.network.protocol.packets.PacketStatusOutPong; -import com.loohp.limbo.network.protocol.packets.PacketStatusOutResponse; -import com.loohp.limbo.network.protocol.packets.ServerboundChatCommandPacket; -import com.loohp.limbo.network.protocol.packets.ServerboundFinishConfigurationPacket; -import com.loohp.limbo.network.protocol.packets.ServerboundLoginAcknowledgedPacket; -import com.loohp.limbo.network.protocol.packets.ServerboundResourcePackPacket; import com.loohp.limbo.network.protocol.packets.ServerboundResourcePackPacket.Action; import com.loohp.limbo.player.Player; import com.loohp.limbo.player.PlayerInteractManager; import com.loohp.limbo.player.PlayerInventory; import com.loohp.limbo.registry.PacketRegistry; import com.loohp.limbo.registry.RegistryCustom; -import com.loohp.limbo.utils.BungeecordAdventureConversionUtils; -import com.loohp.limbo.utils.CheckedBiConsumer; -import com.loohp.limbo.utils.CustomStringUtils; -import com.loohp.limbo.utils.DataTypeIO; -import com.loohp.limbo.utils.DeclareCommands; -import com.loohp.limbo.utils.ForwardingUtils; -import com.loohp.limbo.utils.GameMode; -import com.loohp.limbo.utils.InventoryClickUtils; -import com.loohp.limbo.utils.MojangAPIUtils; +import com.loohp.limbo.utils.*; import com.loohp.limbo.utils.MojangAPIUtils.SkinResponse; -import com.loohp.limbo.world.BlockPosition; import com.loohp.limbo.world.BlockState; import com.loohp.limbo.world.World; import net.kyori.adventure.key.Key; @@ -127,28 +61,12 @@ import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; -import java.io.ByteArrayOutputStream; -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; +import java.io.*; import java.lang.reflect.Constructor; import java.net.InetAddress; import java.net.Socket; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Random; -import java.util.Set; -import java.util.Timer; -import java.util.TimerTask; -import java.util.UUID; +import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; @@ -157,6 +75,7 @@ public class ClientConnection extends Thread { private static final Key DEFAULT_HANDLER_NAMESPACE = Key.key("default"); private static final String BRAND_ANNOUNCE_CHANNEL = Key.key("brand").toString(); + private final AtomicLong lastKeepAliveResponse = new AtomicLong(System.currentTimeMillis()); private final Random random = new Random(); private final Socket clientSocket; @@ -646,27 +565,24 @@ public class ClientConnection extends Thread { player.sendPlayerListHeaderAndFooter(properties.getTabHeader(), properties.getTabFooter()); ready = true; - + keepAliveTask = new TimerTask() { @Override public void run() { - if (state.equals(ClientState.DISCONNECTED)) { - this.cancel(); - } else if (ready && state.equals(ClientState.PLAY)) { - long now = System.currentTimeMillis(); - if (now - getLastPacketTimestamp() > 15000) { - PacketPlayOutKeepAlive keepAlivePacket = new PacketPlayOutKeepAlive(now); - try { - sendPacket(keepAlivePacket); - setLastKeepAlivePayLoad(now); - } catch (Exception e) { - } - } - } + if (state != ClientState.PLAY || !ready) return; + + long now = System.currentTimeMillis(); + PacketPlayOutKeepAlive keepAlive = new PacketPlayOutKeepAlive(now); + try { + sendPacket(keepAlive); + setLastKeepAlivePayLoad(now); + } catch (IOException ignored) {} } }; - new Timer().schedule(keepAliveTask, 5000, 10000); - + + new Timer().schedule(keepAliveTask, 0, 10_000); + + while (clientSocket.isConnected()) { try { CheckedBiConsumer processMoveEvent = (event, originalTo) -> { @@ -717,12 +633,12 @@ public class ClientConnection extends Thread { processMoveEvent.consume(event, to); } } else if (packetIn instanceof PacketPlayInKeepAlive) { - long lastPayload = getLastKeepAlivePayLoad(); PacketPlayInKeepAlive alive = (PacketPlayInKeepAlive) packetIn; - if (lastPayload == -1) { - Limbo.getInstance().getConsole().sendMessage("Unsolicited KeepAlive packet for player " + player.getName()); - } else if (alive.getPayload() != lastPayload) { - Limbo.getInstance().getConsole().sendMessage("Incorrect Payload received in KeepAlive packet for player " + player.getName()); + + if (alive.getPayload() == getLastKeepAlivePayLoad()) { + lastKeepAliveResponse.set(System.currentTimeMillis()); + } else { + disconnect(Component.text("Bad keepalive payload")); break; } } else if (packetIn instanceof PacketPlayInTabComplete) { From 33dacf02db12e4c9b799d56f711a6eab577812c9 Mon Sep 17 00:00:00 2001 From: Zhyren-git Date: Wed, 17 Dec 2025 18:20:55 -0400 Subject: [PATCH 2/5] Fixed player getting "Timed out" while standing still due to Keep-Alive not being sent correctly \\ Replaced return with canceling the task (oops). --- src/main/java/com/loohp/limbo/network/ClientConnection.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/loohp/limbo/network/ClientConnection.java b/src/main/java/com/loohp/limbo/network/ClientConnection.java index ff70bc2..d8aa9ec 100644 --- a/src/main/java/com/loohp/limbo/network/ClientConnection.java +++ b/src/main/java/com/loohp/limbo/network/ClientConnection.java @@ -569,14 +569,14 @@ public class ClientConnection extends Thread { keepAliveTask = new TimerTask() { @Override public void run() { - if (state != ClientState.PLAY || !ready) return; + if (state != ClientState.PLAY || !ready) this.cancel(); // oops long now = System.currentTimeMillis(); PacketPlayOutKeepAlive keepAlive = new PacketPlayOutKeepAlive(now); try { sendPacket(keepAlive); setLastKeepAlivePayLoad(now); - } catch (IOException ignored) {} + } catch (IOException ignored) {cancel();} } }; From 28d735c9127be8461c2e922db1b5e4d49ea5c037 Mon Sep 17 00:00:00 2001 From: Zhyren-git Date: Wed, 17 Dec 2025 18:58:15 -0400 Subject: [PATCH 3/5] Fixed player getting "Timed out" while standing still due to Keep-Alive not being sent correctly. --- .../loohp/limbo/network/ClientConnection.java | 92 +++++++++++++++++-- 1 file changed, 86 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/loohp/limbo/network/ClientConnection.java b/src/main/java/com/loohp/limbo/network/ClientConnection.java index d8aa9ec..9b65287 100644 --- a/src/main/java/com/loohp/limbo/network/ClientConnection.java +++ b/src/main/java/com/loohp/limbo/network/ClientConnection.java @@ -25,7 +25,16 @@ import com.loohp.limbo.events.connection.ConnectionEstablishedEvent; import com.loohp.limbo.events.inventory.AnvilRenameInputEvent; import com.loohp.limbo.events.inventory.InventoryCloseEvent; import com.loohp.limbo.events.inventory.InventoryCreativeEvent; -import com.loohp.limbo.events.player.*; +import com.loohp.limbo.events.player.PlayerInteractEvent; +import com.loohp.limbo.events.player.PlayerJoinEvent; +import com.loohp.limbo.events.player.PlayerLoginEvent; +import com.loohp.limbo.events.player.PlayerMoveEvent; +import com.loohp.limbo.events.player.PlayerQuitEvent; +import com.loohp.limbo.events.player.PlayerResourcePackStatusEvent; +import com.loohp.limbo.events.player.PlayerSelectedSlotChangeEvent; +import com.loohp.limbo.events.player.PlayerSpawnEvent; +import com.loohp.limbo.events.player.PlayerSwapHandItemsEvent; +import com.loohp.limbo.events.player.PluginMessageEvent; import com.loohp.limbo.events.status.StatusPingEvent; import com.loohp.limbo.file.ServerProperties; import com.loohp.limbo.inventory.AnvilInventory; @@ -33,19 +42,74 @@ import com.loohp.limbo.inventory.Inventory; import com.loohp.limbo.inventory.ItemStack; import com.loohp.limbo.location.GlobalPos; import com.loohp.limbo.location.Location; -import com.loohp.limbo.network.protocol.packets.*; +import com.loohp.limbo.network.protocol.packets.ClientboundFinishConfigurationPacket; +import com.loohp.limbo.network.protocol.packets.ClientboundRegistryDataPacket; +import com.loohp.limbo.network.protocol.packets.PacketHandshakingIn; +import com.loohp.limbo.network.protocol.packets.PacketIn; +import com.loohp.limbo.network.protocol.packets.PacketLoginInLoginStart; +import com.loohp.limbo.network.protocol.packets.PacketLoginInPluginMessaging; +import com.loohp.limbo.network.protocol.packets.PacketLoginOutDisconnect; +import com.loohp.limbo.network.protocol.packets.PacketLoginOutLoginSuccess; +import com.loohp.limbo.network.protocol.packets.PacketLoginOutPluginMessaging; +import com.loohp.limbo.network.protocol.packets.PacketOut; +import com.loohp.limbo.network.protocol.packets.PacketPlayInBlockDig; +import com.loohp.limbo.network.protocol.packets.PacketPlayInBlockPlace; +import com.loohp.limbo.network.protocol.packets.PacketPlayInChat; +import com.loohp.limbo.network.protocol.packets.PacketPlayInCloseWindow; +import com.loohp.limbo.network.protocol.packets.PacketPlayInHeldItemChange; +import com.loohp.limbo.network.protocol.packets.PacketPlayInItemName; +import com.loohp.limbo.network.protocol.packets.PacketPlayInKeepAlive; +import com.loohp.limbo.network.protocol.packets.PacketPlayInPickItem; +import com.loohp.limbo.network.protocol.packets.PacketPlayInPluginMessaging; +import com.loohp.limbo.network.protocol.packets.PacketPlayInPosition; +import com.loohp.limbo.network.protocol.packets.PacketPlayInPositionAndLook; +import com.loohp.limbo.network.protocol.packets.PacketPlayInRotation; +import com.loohp.limbo.network.protocol.packets.PacketPlayInSetCreativeSlot; +import com.loohp.limbo.network.protocol.packets.PacketPlayInTabComplete; +import com.loohp.limbo.network.protocol.packets.PacketPlayInUseItem; +import com.loohp.limbo.network.protocol.packets.PacketPlayInWindowClick; +import com.loohp.limbo.network.protocol.packets.PacketPlayOutDeclareCommands; +import com.loohp.limbo.network.protocol.packets.PacketPlayOutDisconnect; +import com.loohp.limbo.network.protocol.packets.PacketPlayOutEntityMetadata; +import com.loohp.limbo.network.protocol.packets.PacketPlayOutGameStateChange; +import com.loohp.limbo.network.protocol.packets.PacketPlayOutHeldItemChange; +import com.loohp.limbo.network.protocol.packets.PacketPlayOutKeepAlive; +import com.loohp.limbo.network.protocol.packets.PacketPlayOutLogin; +import com.loohp.limbo.network.protocol.packets.PacketPlayOutPlayerAbilities; import com.loohp.limbo.network.protocol.packets.PacketPlayOutPlayerAbilities.PlayerAbilityFlags; +import com.loohp.limbo.network.protocol.packets.PacketPlayOutPlayerInfo; import com.loohp.limbo.network.protocol.packets.PacketPlayOutPlayerInfo.PlayerInfoAction; import com.loohp.limbo.network.protocol.packets.PacketPlayOutPlayerInfo.PlayerInfoData; import com.loohp.limbo.network.protocol.packets.PacketPlayOutPlayerInfo.PlayerInfoData.PlayerInfoDataAddPlayer.PlayerSkinProperty; +import com.loohp.limbo.network.protocol.packets.PacketPlayOutPluginMessaging; +import com.loohp.limbo.network.protocol.packets.PacketPlayOutPositionAndLook; +import com.loohp.limbo.network.protocol.packets.PacketPlayOutSpawnPosition; +import com.loohp.limbo.network.protocol.packets.PacketPlayOutTabComplete; import com.loohp.limbo.network.protocol.packets.PacketPlayOutTabComplete.TabCompleteMatches; +import com.loohp.limbo.network.protocol.packets.PacketPlayOutUpdateViewPosition; +import com.loohp.limbo.network.protocol.packets.PacketStatusInPing; +import com.loohp.limbo.network.protocol.packets.PacketStatusInRequest; +import com.loohp.limbo.network.protocol.packets.PacketStatusOutPong; +import com.loohp.limbo.network.protocol.packets.PacketStatusOutResponse; +import com.loohp.limbo.network.protocol.packets.ServerboundChatCommandPacket; +import com.loohp.limbo.network.protocol.packets.ServerboundFinishConfigurationPacket; +import com.loohp.limbo.network.protocol.packets.ServerboundLoginAcknowledgedPacket; +import com.loohp.limbo.network.protocol.packets.ServerboundResourcePackPacket; import com.loohp.limbo.network.protocol.packets.ServerboundResourcePackPacket.Action; import com.loohp.limbo.player.Player; import com.loohp.limbo.player.PlayerInteractManager; import com.loohp.limbo.player.PlayerInventory; import com.loohp.limbo.registry.PacketRegistry; import com.loohp.limbo.registry.RegistryCustom; -import com.loohp.limbo.utils.*; +import com.loohp.limbo.utils.BungeecordAdventureConversionUtils; +import com.loohp.limbo.utils.CheckedBiConsumer; +import com.loohp.limbo.utils.CustomStringUtils; +import com.loohp.limbo.utils.DataTypeIO; +import com.loohp.limbo.utils.DeclareCommands; +import com.loohp.limbo.utils.ForwardingUtils; +import com.loohp.limbo.utils.GameMode; +import com.loohp.limbo.utils.InventoryClickUtils; +import com.loohp.limbo.utils.MojangAPIUtils; import com.loohp.limbo.utils.MojangAPIUtils.SkinResponse; import com.loohp.limbo.world.BlockState; import com.loohp.limbo.world.World; @@ -61,12 +125,28 @@ import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; -import java.io.*; +import java.io.ByteArrayOutputStream; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; import java.lang.reflect.Constructor; import java.net.InetAddress; import java.net.Socket; import java.nio.charset.StandardCharsets; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Random; +import java.util.Set; +import java.util.Timer; +import java.util.TimerTask; +import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; @@ -569,7 +649,7 @@ public class ClientConnection extends Thread { keepAliveTask = new TimerTask() { @Override public void run() { - if (state != ClientState.PLAY || !ready) this.cancel(); // oops + if (state != ClientState.PLAY || !ready) this.cancel(); long now = System.currentTimeMillis(); PacketPlayOutKeepAlive keepAlive = new PacketPlayOutKeepAlive(now); From 952adcfe87d92c160292becca842e7d367733c96 Mon Sep 17 00:00:00 2001 From: LOOHP Date: Thu, 18 Dec 2025 16:56:44 +0000 Subject: [PATCH 4/5] Clean up --- .../loohp/limbo/network/ClientConnection.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/loohp/limbo/network/ClientConnection.java b/src/main/java/com/loohp/limbo/network/ClientConnection.java index 9b65287..dab48de 100644 --- a/src/main/java/com/loohp/limbo/network/ClientConnection.java +++ b/src/main/java/com/loohp/limbo/network/ClientConnection.java @@ -250,6 +250,9 @@ public class ClientConnection extends Thread { } catch (IOException ignored) { } try { + ServerProperties properties = Limbo.getInstance().getServerProperties(); + String str = (properties.isLogPlayerIPAddresses() ? inetAddress.getHostName() : "") + ":" + clientSocket.getPort(); + Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Player disconnected with the reason " + PlainTextComponentSerializer.plainText().serialize(reason)); clientSocket.close(); } catch (IOException ignored) { } @@ -649,19 +652,21 @@ public class ClientConnection extends Thread { keepAliveTask = new TimerTask() { @Override public void run() { - if (state != ClientState.PLAY || !ready) this.cancel(); + if (state != ClientState.PLAY || !ready) { + this.cancel(); + } long now = System.currentTimeMillis(); PacketPlayOutKeepAlive keepAlive = new PacketPlayOutKeepAlive(now); try { sendPacket(keepAlive); setLastKeepAlivePayLoad(now); - } catch (IOException ignored) {cancel();} + } catch (IOException e) { + cancel(); + } } }; - - new Timer().schedule(keepAliveTask, 0, 10_000); - + new Timer().schedule(keepAliveTask, 0, 10000); while (clientSocket.isConnected()) { try { @@ -718,7 +723,7 @@ public class ClientConnection extends Thread { if (alive.getPayload() == getLastKeepAlivePayLoad()) { lastKeepAliveResponse.set(System.currentTimeMillis()); } else { - disconnect(Component.text("Bad keepalive payload")); + disconnect(Component.text("Bad Keepalive Payload")); break; } } else if (packetIn instanceof PacketPlayInTabComplete) { From 8ec2d34a6096cd38c9b25c2706b3237be0b007d6 Mon Sep 17 00:00:00 2001 From: LOOHP Date: Thu, 18 Dec 2025 16:59:52 +0000 Subject: [PATCH 5/5] Refactor --- .../com/loohp/limbo/network/ClientConnection.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/loohp/limbo/network/ClientConnection.java b/src/main/java/com/loohp/limbo/network/ClientConnection.java index dab48de..1d0b10e 100644 --- a/src/main/java/com/loohp/limbo/network/ClientConnection.java +++ b/src/main/java/com/loohp/limbo/network/ClientConnection.java @@ -155,7 +155,6 @@ public class ClientConnection extends Thread { private static final Key DEFAULT_HANDLER_NAMESPACE = Key.key("default"); private static final String BRAND_ANNOUNCE_CHANNEL = Key.key("brand").toString(); - private final AtomicLong lastKeepAliveResponse = new AtomicLong(System.currentTimeMillis()); private final Random random = new Random(); private final Socket clientSocket; @@ -163,10 +162,12 @@ public class ClientConnection extends Thread { private boolean running; private volatile ClientState state; + private final AtomicLong lastPacketTimestamp; + private final AtomicLong lastKeepAlivePayLoad; + private final AtomicLong lastKeepAliveResponse; + private Player player; private TimerTask keepAliveTask; - private AtomicLong lastPacketTimestamp; - private AtomicLong lastKeepAlivePayLoad; private InetAddress inetAddress; private boolean ready; @@ -175,6 +176,7 @@ public class ClientConnection extends Thread { this.inetAddress = clientSocket.getInetAddress(); this.lastPacketTimestamp = new AtomicLong(-1); this.lastKeepAlivePayLoad = new AtomicLong(-1); + this.lastKeepAliveResponse = new AtomicLong(-1); this.channel = null; this.running = false; this.ready = false; @@ -192,6 +194,10 @@ public class ClientConnection extends Thread { this.lastKeepAlivePayLoad.set(payLoad); } + public long getLastKeepAliveResponse() { + return lastKeepAliveResponse.get(); + } + public long getLastPacketTimestamp() { return lastPacketTimestamp.get(); }