Browse Source

query: show ping info

ipv6
Denis Drakhnia 1 year ago
parent
commit
e6bee38a18
  1. 44
      query/src/main.rs

44
query/src/main.rs

@ -31,7 +31,7 @@ enum Error {
} }
#[derive(Clone, Debug, Serialize)] #[derive(Clone, Debug, Serialize)]
#[serde(tag = "type")] #[serde(tag = "status")]
enum ServerResultKind { enum ServerResultKind {
#[serde(rename = "ok")] #[serde(rename = "ok")]
Ok { info: ServerInfo }, Ok { info: ServerInfo },
@ -48,28 +48,30 @@ enum ServerResultKind {
#[derive(Clone, Debug, Serialize)] #[derive(Clone, Debug, Serialize)]
struct ServerResult { struct ServerResult {
address: String, address: String,
ping: f32,
#[serde(flatten)] #[serde(flatten)]
kind: ServerResultKind, kind: ServerResultKind,
} }
impl ServerResult { impl ServerResult {
fn new(address: String, kind: ServerResultKind) -> Self { fn new(address: String, ping: f32, kind: ServerResultKind) -> Self {
Self { Self {
address: address.to_string(), address: address.to_string(),
ping,
kind, kind,
} }
} }
fn ok<T: Into<ServerInfo>>(address: String, info: T) -> Self { fn ok(address: String, ping: f32, info: ServerInfo) -> Self {
Self::new(address, ServerResultKind::Ok { info: info.into() }) Self::new(address, ping, ServerResultKind::Ok { info })
} }
fn timeout(address: String) -> Self { fn timeout(address: String) -> Self {
Self::new(address, ServerResultKind::Timeout) Self::new(address, 0.0, ServerResultKind::Timeout)
} }
fn protocol(address: String) -> Self { fn protocol(address: String, ping: f32) -> Self {
Self::new(address, ServerResultKind::Protocol) Self::new(address, ping, ServerResultKind::Protocol)
} }
fn error<T>(address: String, message: T) -> Self fn error<T>(address: String, message: T) -> Self
@ -78,18 +80,20 @@ impl ServerResult {
{ {
Self::new( Self::new(
address, address,
0.0,
ServerResultKind::Error { ServerResultKind::Error {
message: message.to_string(), message: message.to_string(),
}, },
) )
} }
fn invalid<T>(address: String, message: T, response: &[u8]) -> Self fn invalid<T>(address: String, ping: f32, message: T, response: &[u8]) -> Self
where where
T: fmt::Display, T: fmt::Display,
{ {
Self::new( Self::new(
address, address,
ping,
ServerResultKind::Invalid { ServerResultKind::Invalid {
message: message.to_string(), message: message.to_string(),
response: Str(response).to_string(), response: Str(response).to_string(),
@ -112,7 +116,7 @@ struct ServerInfo {
pub password: bool, pub password: bool,
} }
impl From<server::GetServerInfoResponse<&str>> for ServerInfo { impl ServerInfo {
fn from(other: server::GetServerInfoResponse<&str>) -> Self { fn from(other: server::GetServerInfoResponse<&str>) -> Self {
Self { Self {
gamedir: other.gamedir.to_owned(), gamedir: other.gamedir.to_owned(),
@ -251,10 +255,12 @@ fn get_server_info(
sock.connect(&addr)?; sock.connect(&addr)?;
sock.set_read_timeout(Some(timeout))?; sock.set_read_timeout(Some(timeout))?;
let mut ping = 0.0;
for &i in versions { for &i in versions {
let p = game::GetServerInfo::new(i); let p = game::GetServerInfo::new(i);
let mut buf = [0; 2048]; let mut buf = [0; 2048];
let n = p.encode(&mut buf)?; let n = p.encode(&mut buf)?;
let start = Instant::now();
sock.send(&buf[..n])?; sock.send(&buf[..n])?;
let n = match sock.recv(&mut buf) { let n = match sock.recv(&mut buf) {
@ -266,22 +272,24 @@ fn get_server_info(
_ => Err(e)?, _ => Err(e)?,
}, },
}; };
ping = start.elapsed().as_micros() as f32 / 1000.0;
let response = &buf[..n]; let response = &buf[..n];
match server::GetServerInfoResponse::decode(response) { match server::GetServerInfoResponse::decode(response) {
Ok(packet) => { Ok(packet) => {
return Ok(ServerResult::ok(addr, packet)); let info = ServerInfo::from(packet);
return Ok(ServerResult::ok(addr, ping, info));
} }
Err(ProtocolError::InvalidProtocolVersion) => { Err(ProtocolError::InvalidProtocolVersion) => {
// try another protocol version // try another protocol version
} }
Err(e) => { Err(e) => {
return Ok(ServerResult::invalid(addr, e, response)); return Ok(ServerResult::invalid(addr, ping, e, response));
} }
} }
} }
Ok(ServerResult::protocol(addr)) Ok(ServerResult::protocol(addr, ping))
} }
fn query_server_info(cli: &Arc<Cli>, servers: &[String]) -> Result<(), Error> { fn query_server_info(cli: &Arc<Cli>, servers: &[String]) -> Result<(), Error> {
@ -357,7 +365,7 @@ fn query_server_info(cli: &Arc<Cli>, servers: &[String]) -> Result<(), Error> {
} }
} else { } else {
for i in servers { for i in servers {
println!("server: {}", i.address); println!("server: {} [{:.3} ms]", i.address, i.ping);
macro_rules! p { macro_rules! p {
($($key:ident: $value:expr),+ $(,)?) => { ($($key:ident: $value:expr),+ $(,)?) => {
@ -368,7 +376,7 @@ fn query_server_info(cli: &Arc<Cli>, servers: &[String]) -> Result<(), Error> {
match &i.kind { match &i.kind {
ServerResultKind::Ok { info } => { ServerResultKind::Ok { info } => {
p! { p! {
type: "ok", status: "ok",
host: Colored::new(&info.host, cli.force_color), host: Colored::new(&info.host, cli.force_color),
gamedir: info.gamedir, gamedir: info.gamedir,
map: info.map, map: info.map,
@ -383,23 +391,23 @@ fn query_server_info(cli: &Arc<Cli>, servers: &[String]) -> Result<(), Error> {
} }
ServerResultKind::Timeout => { ServerResultKind::Timeout => {
p! { p! {
type: "timeout", status: "timeout",
} }
} }
ServerResultKind::Protocol => { ServerResultKind::Protocol => {
p! { p! {
type: "protocol", status: "protocol",
} }
} }
ServerResultKind::Error { message } => { ServerResultKind::Error { message } => {
p! { p! {
type: "error", status: "error",
message: message, message: message,
} }
} }
ServerResultKind::Invalid { message, response } => { ServerResultKind::Invalid { message, response } => {
p! { p! {
type: "invalid", status: "invalid",
message: message, message: message,
response: response, response: response,
} }

Loading…
Cancel
Save