diff --git a/api/src/main/java/com/velocitypowered/api/proxy/Player.java b/api/src/main/java/com/velocitypowered/api/proxy/Player.java index c6a1a8fa0..7e72b5d9b 100644 --- a/api/src/main/java/com/velocitypowered/api/proxy/Player.java +++ b/api/src/main/java/com/velocitypowered/api/proxy/Player.java @@ -36,6 +36,12 @@ public interface Player extends CommandSource, InboundConnection, ChannelMessage PlayerSettings getPlayerSettings(); + /** + * Returns the current player's ping + * @return the player's ping or -1 if ping information is currently unknown + */ + long getPing(); + /** * Sends a chat message to the player's client. * @param component the chat message to send diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java index f74ae2b5a..95dc18b00 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java @@ -28,7 +28,8 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler { private static final int MAX_PLUGIN_CHANNELS = 128; private final ConnectedPlayer player; - private long lastPing = -1; + private long lastPingID = -1; + private long lastPingSent = -1; private boolean spawned = false; private final List serverBossBars = new ArrayList<>(); private final Set clientPluginMsgChannels = new HashSet<>(); @@ -53,11 +54,13 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler { public void handle(MinecraftPacket packet) { if (packet instanceof KeepAlive) { KeepAlive keepAlive = (KeepAlive) packet; - if (keepAlive.getRandomId() != lastPing) { + if (keepAlive.getRandomId() != lastPingID) { // The last keep alive we got was probably from a different server. Let's ignore it, and hope the next // ping is alright. return; } + player.setPing(System.currentTimeMillis() - lastPingSent); + resetPingData(); } if (packet instanceof ClientSettings) { @@ -144,7 +147,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler { } public void handleBackendJoinGame(JoinGame joinGame) { - lastPing = Long.MIN_VALUE; // reset last ping + resetPingData(); // reset ping data; if (!spawned) { // nothing special to do here spawned = true; @@ -252,6 +255,12 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler { } public void setLastPing(long lastPing) { - this.lastPing = lastPing; + this.lastPingID = lastPing; + this.lastPingSent = System.currentTimeMillis(); + } + + private void resetPingData() { + this.lastPingID = -1; + this.lastPingSent = -1; } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java index 9b39e30df..7c5d19db6 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java @@ -54,6 +54,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { private final GameProfile profile; private PermissionFunction permissionFunction = null; private int tryIndex = 0; + private long ping = -1; private VelocityServerConnection connectedServer; private ClientSettings clientSettings; private VelocityServerConnection connectionInFlight; @@ -89,6 +90,14 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { } @Override + public long getPing() { + return this.ping; + } + + public void setPing(long ping) { + this.ping = ping; + } + public PlayerSettings getPlayerSettings() { return settings == null ? ClientSettingsWrapper.DEFAULT : this.settings; }