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 dc56e527e..ecd40dc2d 100644 --- a/api/src/main/java/com/velocitypowered/api/proxy/Player.java +++ b/api/src/main/java/com/velocitypowered/api/proxy/Player.java @@ -33,6 +33,12 @@ public interface Player extends CommandSource, InboundConnection, ChannelMessage */ Optional getCurrentServer(); + /** + * 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 d5f040d2c..f1acfc652 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 @@ -32,7 +32,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<>(); @@ -57,11 +58,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) { @@ -148,7 +151,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; @@ -256,6 +259,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 1660f68b4..b477a07eb 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 @@ -52,6 +52,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; @@ -85,6 +86,15 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { return connection; } + @Override + public long getPing() { + return this.ping; + } + + public void setPing(long ping) { + this.ping = ping; + } + @Override public InetSocketAddress getRemoteAddress() { return (InetSocketAddress) connection.getChannel().remoteAddress();