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
This commit is contained in:
Riley Sutton 2023-02-15 17:22:14 +11:00 committed by GitHub
parent f0027aa097
commit bee44d32b5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 14 additions and 2 deletions

View file

@ -1,6 +1,7 @@
use std::borrow::Cow; use std::borrow::Cow;
use std::net::IpAddr; use std::net::IpAddr;
use std::num::Wrapping; use std::num::Wrapping;
use std::time::Instant;
use anyhow::{bail, Context}; use anyhow::{bail, Context};
use bevy_ecs::prelude::*; use bevy_ecs::prelude::*;
@ -69,6 +70,8 @@ pub struct Client {
entities_to_despawn: Vec<VarInt>, entities_to_despawn: Vec<VarInt>,
got_keepalive: bool, got_keepalive: bool,
last_keepalive_id: u64, last_keepalive_id: u64,
keepalive_sent_time: Instant,
ping: i32,
/// Counts up as teleports are made. /// Counts up as teleports are made.
teleport_id_counter: u32, teleport_id_counter: u32,
/// The number of pending client teleports that have yet to receive a /// The number of pending client teleports that have yet to receive a
@ -142,6 +145,8 @@ impl Client {
has_respawn_screen: false, has_respawn_screen: false,
got_keepalive: true, got_keepalive: true,
last_keepalive_id: 0, last_keepalive_id: 0,
keepalive_sent_time: Instant::now(),
ping: -1,
teleport_id_counter: 0, teleport_id_counter: 0,
pending_teleports: 0, pending_teleports: 0,
cursor_item: None, 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 /// The item that the client thinks it's holding under the mouse
/// cursor. Only relevant when the client has an open inventory. /// cursor. Only relevant when the client has an open inventory.
pub fn cursor_item(&self) -> Option<&ItemStack> { pub fn cursor_item(&self) -> Option<&ItemStack> {
@ -717,8 +726,10 @@ fn update_one_client(
if client.got_keepalive { if client.got_keepalive {
let id = rand::random(); let id = rand::random();
client.enc.write_packet(&KeepAliveS2c { id }); client.enc.write_packet(&KeepAliveS2c { id });
client.last_keepalive_id = id;
client.got_keepalive = false; client.got_keepalive = false;
client.last_keepalive_id = id;
client.keepalive_sent_time = Instant::now();
} else { } else {
bail!("timed out (no keepalive response)"); bail!("timed out (no keepalive response)");
} }

View file

@ -924,6 +924,7 @@ fn handle_one_packet(
); );
} else { } else {
client.got_keepalive = true; client.got_keepalive = true;
client.ping = client.keepalive_sent_time.elapsed().as_millis() as i32;
} }
} }
C2sPlayPacket::LockDifficulty(p) => { C2sPlayPacket::LockDifficulty(p) => {

View file

@ -62,7 +62,7 @@ impl PlayerList {
.with_username(client.username()) .with_username(client.username())
.with_properties(client.properties()) .with_properties(client.properties())
.with_game_mode(client.game_mode()) .with_game_mode(client.game_mode())
.with_ping(-1); // TODO .with_ping(client.ping());
player_list.insert(client.uuid(), entry); player_list.insert(client.uuid(), entry);
} }