From 8316dac2cc99fac68e8671945a1f17c2cef9dcca Mon Sep 17 00:00:00 2001 From: Tom <25043847+Douile@users.noreply.github.com> Date: Mon, 26 Jun 2023 21:50:06 +0000 Subject: [PATCH] [Games] Add method to query with timeout options (#60) --- examples/generic.rs | 29 ++++++++++++++++++++++------- src/games/mod.rs | 37 +++++++++++++++++++++++++------------ 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/examples/generic.rs b/examples/generic.rs index 0a84f6e..4121a15 100644 --- a/examples/generic.rs +++ b/examples/generic.rs @@ -1,13 +1,23 @@ -use gamedig::{protocols::types::CommonResponse, query, GDResult, GAMES}; +use gamedig::{ + protocols::types::{CommonResponse, TimeoutSettings}, + query_with_timeout, + GDResult, + GAMES, +}; use std::net::IpAddr; -fn generic_query(game_name: &str, addr: &IpAddr, port: Option) -> GDResult> { +fn generic_query( + game_name: &str, + addr: &IpAddr, + port: Option, + timeout_settings: Option, +) -> GDResult> { let game = GAMES.get(game_name).expect("Game doesn't exist"); println!("Querying {:#?} with game {:#?}.", addr, game); - let response = query(game, addr, port)?; + let response = query_with_timeout(game, addr, port, timeout_settings)?; println!("Response: {:#?}", response.as_json()); let common = response.as_original(); @@ -26,20 +36,25 @@ fn main() { .expect("Must provide address"); let port: Option = args.next().map(|s| s.parse().unwrap()); - generic_query(&game_name, &addr, port).unwrap(); + generic_query(&game_name, &addr, port, None).unwrap(); } #[cfg(test)] mod test { - use gamedig::GAMES; - use std::net::{IpAddr, Ipv4Addr}; + use gamedig::{protocols::types::TimeoutSettings, GAMES}; + use std::{ + net::{IpAddr, Ipv4Addr}, + time::Duration, + }; use super::generic_query; const ADDR: IpAddr = IpAddr::V4(Ipv4Addr::LOCALHOST); fn test_game(game_name: &str) { - assert!(generic_query(game_name, &ADDR, None).is_err()); + let timeout_settings = + Some(TimeoutSettings::new(Some(Duration::from_nanos(1)), Some(Duration::from_nanos(1))).unwrap()); + assert!(generic_query(game_name, &ADDR, None, timeout_settings).is_err()); } #[test] diff --git a/src/games/mod.rs b/src/games/mod.rs index 0d5741d..7447f23 100644 --- a/src/games/mod.rs +++ b/src/games/mod.rs @@ -114,7 +114,7 @@ pub mod vr; use crate::protocols::gamespy::GameSpyVersion; use crate::protocols::quake::QuakeVersion; -use crate::protocols::types::{CommonResponse, ProprietaryProtocol}; +use crate::protocols::types::{CommonResponse, ProprietaryProtocol, TimeoutSettings}; use crate::protocols::{self, Protocol}; use crate::GDResult; use std::net::{IpAddr, SocketAddr}; @@ -139,39 +139,52 @@ pub use definitions::GAMES; /// Make a query given a game definition pub fn query(game: &Game, address: &IpAddr, port: Option) -> GDResult> { + query_with_timeout(game, address, port, None) +} + +/// Make a query given a game definition and timeout settings +pub fn query_with_timeout( + game: &Game, + address: &IpAddr, + port: Option, + timeout_settings: Option, +) -> GDResult> { let socket_addr = SocketAddr::new(*address, port.unwrap_or(game.default_port)); Ok(match &game.protocol { Protocol::Valve(steam_app) => { - protocols::valve::query(&socket_addr, steam_app.as_engine(), None, None).map(Box::new)? + protocols::valve::query(&socket_addr, steam_app.as_engine(), None, timeout_settings).map(Box::new)? } Protocol::Minecraft(version) => { match version { Some(protocols::minecraft::Server::Java) => { - protocols::minecraft::query_java(&socket_addr, None).map(Box::new)? + protocols::minecraft::query_java(&socket_addr, timeout_settings).map(Box::new)? } Some(protocols::minecraft::Server::Bedrock) => { - protocols::minecraft::query_bedrock(&socket_addr, None).map(Box::new)? + protocols::minecraft::query_bedrock(&socket_addr, timeout_settings).map(Box::new)? } Some(protocols::minecraft::Server::Legacy(group)) => { - protocols::minecraft::query_legacy_specific(*group, &socket_addr, None).map(Box::new)? + protocols::minecraft::query_legacy_specific(*group, &socket_addr, timeout_settings).map(Box::new)? } - None => protocols::minecraft::query(&socket_addr, None).map(Box::new)?, + None => protocols::minecraft::query(&socket_addr, timeout_settings).map(Box::new)?, } } Protocol::Gamespy(version) => { match version { - GameSpyVersion::One => protocols::gamespy::one::query(&socket_addr, None).map(Box::new)?, - GameSpyVersion::Two => protocols::gamespy::two::query(&socket_addr, None).map(Box::new)?, - GameSpyVersion::Three => protocols::gamespy::three::query(&socket_addr, None).map(Box::new)?, + GameSpyVersion::One => protocols::gamespy::one::query(&socket_addr, timeout_settings).map(Box::new)?, + GameSpyVersion::Two => protocols::gamespy::two::query(&socket_addr, timeout_settings).map(Box::new)?, + GameSpyVersion::Three => { + protocols::gamespy::three::query(&socket_addr, timeout_settings).map(Box::new)? + } } } Protocol::Quake(version) => { match version { - QuakeVersion::One => protocols::quake::one::query(&socket_addr, None).map(Box::new)?, - QuakeVersion::Two => protocols::quake::two::query(&socket_addr, None).map(Box::new)?, - QuakeVersion::Three => protocols::quake::three::query(&socket_addr, None).map(Box::new)?, + QuakeVersion::One => protocols::quake::one::query(&socket_addr, timeout_settings).map(Box::new)?, + QuakeVersion::Two => protocols::quake::two::query(&socket_addr, timeout_settings).map(Box::new)?, + QuakeVersion::Three => protocols::quake::three::query(&socket_addr, timeout_settings).map(Box::new)?, } } + // TODO: No way to query proprietary games with timeout Protocol::PROPRIETARY(protocol) => { match protocol { ProprietaryProtocol::TheShip => ts::query(address, port).map(Box::new)?,