diff --git a/.github/badges/node.svg b/.github/badges/node.svg index df3be384..dcc08338 100644 --- a/.github/badges/node.svg +++ b/.github/badges/node.svg @@ -1,5 +1,5 @@ - - Node game coverage: 14.02% + + Node game coverage: 13.98% @@ -13,8 +13,8 @@ \ No newline at end of file diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 69c1e152..3628e8db 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -1,10 +1,7 @@ use std::net::{IpAddr, ToSocketAddrs}; use clap::{Parser, ValueEnum}; -use gamedig::{ - games::*, - protocols::types::{CommonResponse, ExtraRequestSettings, TimeoutSettings}, -}; +use gamedig::{games::*, protocols::types::CommonResponse, ExtraRequestSettings, TimeoutSettings}; mod error; diff --git a/crates/lib/examples/generic.rs b/crates/lib/examples/generic.rs index 2b47ffab..d54a0b30 100644 --- a/crates/lib/examples/generic.rs +++ b/crates/lib/examples/generic.rs @@ -1,8 +1,10 @@ use gamedig::{ - protocols::types::{CommonResponse, ExtraRequestSettings, TimeoutSettings}, + protocols::types::CommonResponse, query_with_timeout_and_extra_settings, + ExtraRequestSettings, GDResult, Game, + TimeoutSettings, GAMES, }; diff --git a/crates/lib/examples/valve_protocol_query.rs b/crates/lib/examples/valve_protocol_query.rs index a77b41f1..f6ca6fff 100644 --- a/crates/lib/examples/valve_protocol_query.rs +++ b/crates/lib/examples/valve_protocol_query.rs @@ -1,6 +1,6 @@ -use gamedig::protocols::types::TimeoutSettings; use gamedig::protocols::valve; use gamedig::protocols::valve::{Engine, GatheringSettings}; +use gamedig::TimeoutSettings; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::time::Duration; diff --git a/crates/lib/src/games/mod.rs b/crates/lib/src/games/mod.rs index 98b2a6e4..32467b5c 100644 --- a/crates/lib/src/games/mod.rs +++ b/crates/lib/src/games/mod.rs @@ -1,8 +1,5 @@ //! Currently supported games. -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; - pub mod gamespy; pub mod quake; pub mod unreal2; @@ -26,135 +23,14 @@ pub mod savage2; /// The Ship pub mod theship; -use crate::protocols::gamespy::GameSpyVersion; -use crate::protocols::quake::QuakeVersion; -use crate::protocols::types::{CommonResponse, ExtraRequestSettings, ProprietaryProtocol, TimeoutSettings}; -use crate::protocols::{self, Protocol}; -use crate::GDResult; -use std::net::{IpAddr, SocketAddr}; +pub mod types; +pub use types::*; -/// Definition of a game -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Game { - /// Full name of the game - pub name: &'static str, - /// Default port used by game - pub default_port: u16, - /// The protocol the game's query uses - pub protocol: Protocol, - /// Request settings. - pub request_settings: ExtraRequestSettings, -} +pub mod query; +pub use query::*; #[cfg(feature = "game_defs")] mod definitions; #[cfg(feature = "game_defs")] pub use definitions::GAMES; - -/// Make a query given a game definition -#[inline] -pub fn query(game: &Game, address: &IpAddr, port: Option) -> GDResult> { - query_with_timeout_and_extra_settings(game, address, port, None, None) -} - -/// Make a query given a game definition and timeout settings -#[inline] -pub fn query_with_timeout( - game: &Game, - address: &IpAddr, - port: Option, - timeout_settings: Option, -) -> GDResult> { - query_with_timeout_and_extra_settings(game, address, port, timeout_settings, None) -} - -/// Make a query given a game definition, timeout settings, and extra settings -pub fn query_with_timeout_and_extra_settings( - game: &Game, - address: &IpAddr, - port: Option, - timeout_settings: Option, - extra_settings: Option, -) -> GDResult> { - let socket_addr = SocketAddr::new(*address, port.unwrap_or(game.default_port)); - Ok(match &game.protocol { - Protocol::Valve(engine) => { - protocols::valve::query( - &socket_addr, - *engine, - extra_settings - .or_else(|| Option::from(game.request_settings.clone())) - .map(ExtraRequestSettings::into), - timeout_settings, - ) - .map(Box::new)? - } - Protocol::Gamespy(version) => { - match version { - 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, 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)?, - } - } - Protocol::Unreal2 => { - protocols::unreal2::query( - &socket_addr, - &extra_settings - .map(ExtraRequestSettings::into) - .unwrap_or_default(), - timeout_settings, - ) - .map(Box::new)? - } - Protocol::PROPRIETARY(protocol) => { - match protocol { - ProprietaryProtocol::Savage2 => { - savage2::query_with_timeout(address, port, timeout_settings).map(Box::new)? - } - ProprietaryProtocol::TheShip => { - theship::query_with_timeout(address, port, timeout_settings).map(Box::new)? - } - ProprietaryProtocol::FFOW => ffow::query_with_timeout(address, port, timeout_settings).map(Box::new)?, - ProprietaryProtocol::JC2M => jc2m::query_with_timeout(address, port, timeout_settings).map(Box::new)?, - ProprietaryProtocol::Minecraft(version) => { - match version { - Some(minecraft::Server::Java) => { - minecraft::protocol::query_java( - &socket_addr, - timeout_settings, - extra_settings.map(ExtraRequestSettings::into), - ) - .map(Box::new)? - } - Some(minecraft::Server::Bedrock) => { - minecraft::protocol::query_bedrock(&socket_addr, timeout_settings).map(Box::new)? - } - Some(minecraft::Server::Legacy(group)) => { - minecraft::protocol::query_legacy_specific(*group, &socket_addr, timeout_settings) - .map(Box::new)? - } - None => { - minecraft::protocol::query( - &socket_addr, - timeout_settings, - extra_settings.map(ExtraRequestSettings::into), - ) - .map(Box::new)? - } - } - } - } - } - }) -} diff --git a/crates/lib/src/games/query.rs b/crates/lib/src/games/query.rs new file mode 100644 index 00000000..d37cdd82 --- /dev/null +++ b/crates/lib/src/games/query.rs @@ -0,0 +1,117 @@ +//! Generic query functions + +use std::net::{IpAddr, SocketAddr}; + +use crate::games::types::Game; +use crate::games::{ffow, jc2m, minecraft, savage2, theship}; +use crate::protocols; +use crate::protocols::gamespy::GameSpyVersion; +use crate::protocols::quake::QuakeVersion; +use crate::protocols::types::{CommonResponse, ExtraRequestSettings, ProprietaryProtocol, Protocol, TimeoutSettings}; +use crate::GDResult; + +/// Make a query given a game definition +#[inline] +pub fn query(game: &Game, address: &IpAddr, port: Option) -> GDResult> { + query_with_timeout_and_extra_settings(game, address, port, None, None) +} + +/// Make a query given a game definition and timeout settings +#[inline] +pub fn query_with_timeout( + game: &Game, + address: &IpAddr, + port: Option, + timeout_settings: Option, +) -> GDResult> { + query_with_timeout_and_extra_settings(game, address, port, timeout_settings, None) +} + +/// Make a query given a game definition, timeout settings, and extra settings +pub fn query_with_timeout_and_extra_settings( + game: &Game, + address: &IpAddr, + port: Option, + timeout_settings: Option, + extra_settings: Option, +) -> GDResult> { + let socket_addr = SocketAddr::new(*address, port.unwrap_or(game.default_port)); + Ok(match &game.protocol { + Protocol::Valve(engine) => { + protocols::valve::query( + &socket_addr, + *engine, + extra_settings + .or_else(|| Option::from(game.request_settings.clone())) + .map(ExtraRequestSettings::into), + timeout_settings, + ) + .map(Box::new)? + } + Protocol::Gamespy(version) => { + match version { + 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, 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)?, + } + } + Protocol::Unreal2 => { + protocols::unreal2::query( + &socket_addr, + &extra_settings + .map(ExtraRequestSettings::into) + .unwrap_or_default(), + timeout_settings, + ) + .map(Box::new)? + } + Protocol::PROPRIETARY(protocol) => { + match protocol { + ProprietaryProtocol::Savage2 => { + savage2::query_with_timeout(address, port, timeout_settings).map(Box::new)? + } + ProprietaryProtocol::TheShip => { + theship::query_with_timeout(address, port, timeout_settings).map(Box::new)? + } + ProprietaryProtocol::FFOW => ffow::query_with_timeout(address, port, timeout_settings).map(Box::new)?, + ProprietaryProtocol::JC2M => jc2m::query_with_timeout(address, port, timeout_settings).map(Box::new)?, + ProprietaryProtocol::Minecraft(version) => { + match version { + Some(minecraft::Server::Java) => { + minecraft::protocol::query_java( + &socket_addr, + timeout_settings, + extra_settings.map(ExtraRequestSettings::into), + ) + .map(Box::new)? + } + Some(minecraft::Server::Bedrock) => { + minecraft::protocol::query_bedrock(&socket_addr, timeout_settings).map(Box::new)? + } + Some(minecraft::Server::Legacy(group)) => { + minecraft::protocol::query_legacy_specific(*group, &socket_addr, timeout_settings) + .map(Box::new)? + } + None => { + minecraft::protocol::query( + &socket_addr, + timeout_settings, + extra_settings.map(ExtraRequestSettings::into), + ) + .map(Box::new)? + } + } + } + } + } + }) +} diff --git a/crates/lib/src/games/types.rs b/crates/lib/src/games/types.rs new file mode 100644 index 00000000..3868e21e --- /dev/null +++ b/crates/lib/src/games/types.rs @@ -0,0 +1,20 @@ +//! Game related types + +use crate::protocols::types::{ExtraRequestSettings, Protocol}; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; + +/// Definition of a game +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Game { + /// Full name of the game + pub name: &'static str, + /// Default port used by game + pub default_port: u16, + /// The protocol the game's query uses + pub protocol: Protocol, + /// Request settings. + pub request_settings: ExtraRequestSettings, +} diff --git a/crates/lib/src/lib.rs b/crates/lib/src/lib.rs index 7cafba7c..b17777c6 100644 --- a/crates/lib/src/lib.rs +++ b/crates/lib/src/lib.rs @@ -15,7 +15,7 @@ //! //! ## Using a game definition //! ``` -//! use gamedig::games::{GAMES, query}; +//! use gamedig::{GAMES, query}; //! //! let game = GAMES.get("teamfortress2").unwrap(); // Get a game definition, the full list can be found in src/games/mod.rs //! let response = query(game, &"127.0.0.1".parse().unwrap(), None); // None will use the default port @@ -48,5 +48,10 @@ mod utils; pub use errors::*; #[cfg(feature = "games")] pub use games::*; +#[cfg(feature = "games")] +pub use query::*; #[cfg(feature = "services")] pub use services::*; + +// Re-export types needed to call games::query::query in the root +pub use protocols::types::{ExtraRequestSettings, TimeoutSettings};