From bee44d32b50b2f54d095a5ecfa02d8dad76e7c78 Mon Sep 17 00:00:00 2001 From: Riley Sutton <5704543+rileysu@users.noreply.github.com> Date: Wed, 15 Feb 2023 17:22:14 +1100 Subject: [PATCH] Add ping calculation system (#243) ## Description Add the ping computation system and capability to send ping to connecting clients. Currently the player list will only update upon connection. Should another ticket be made for updating this since it seems out of scope for this issue? ## Test Plan Printing ping per keepalive packet on a different computer on my network. It seems to work fine but would need extra feedback. #### Related #207 --- crates/valence/src/client.rs | 13 ++++++++++++- crates/valence/src/client/event.rs | 1 + crates/valence/src/player_list.rs | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/crates/valence/src/client.rs b/crates/valence/src/client.rs index b4683bf..4312b50 100644 --- a/crates/valence/src/client.rs +++ b/crates/valence/src/client.rs @@ -1,6 +1,7 @@ use std::borrow::Cow; use std::net::IpAddr; use std::num::Wrapping; +use std::time::Instant; use anyhow::{bail, Context}; use bevy_ecs::prelude::*; @@ -69,6 +70,8 @@ pub struct Client { entities_to_despawn: Vec, got_keepalive: bool, last_keepalive_id: u64, + keepalive_sent_time: Instant, + ping: i32, /// Counts up as teleports are made. teleport_id_counter: u32, /// The number of pending client teleports that have yet to receive a @@ -142,6 +145,8 @@ impl Client { has_respawn_screen: false, got_keepalive: true, last_keepalive_id: 0, + keepalive_sent_time: Instant::now(), + ping: -1, teleport_id_counter: 0, pending_teleports: 0, cursor_item: None, @@ -422,6 +427,10 @@ impl Client { }); } + pub fn ping(&self) -> i32 { + self.ping + } + /// The item that the client thinks it's holding under the mouse /// cursor. Only relevant when the client has an open inventory. pub fn cursor_item(&self) -> Option<&ItemStack> { @@ -717,8 +726,10 @@ fn update_one_client( if client.got_keepalive { let id = rand::random(); client.enc.write_packet(&KeepAliveS2c { id }); - client.last_keepalive_id = id; + client.got_keepalive = false; + client.last_keepalive_id = id; + client.keepalive_sent_time = Instant::now(); } else { bail!("timed out (no keepalive response)"); } diff --git a/crates/valence/src/client/event.rs b/crates/valence/src/client/event.rs index 204397a..3613916 100644 --- a/crates/valence/src/client/event.rs +++ b/crates/valence/src/client/event.rs @@ -924,6 +924,7 @@ fn handle_one_packet( ); } else { client.got_keepalive = true; + client.ping = client.keepalive_sent_time.elapsed().as_millis() as i32; } } C2sPlayPacket::LockDifficulty(p) => { diff --git a/crates/valence/src/player_list.rs b/crates/valence/src/player_list.rs index acd174f..8942bb0 100644 --- a/crates/valence/src/player_list.rs +++ b/crates/valence/src/player_list.rs @@ -62,7 +62,7 @@ impl PlayerList { .with_username(client.username()) .with_properties(client.properties()) .with_game_mode(client.game_mode()) - .with_ping(-1); // TODO + .with_ping(client.ping()); player_list.insert(client.uuid(), entry); }