mirror of
https://github.com/tribufu/rust-gamedig
synced 2026-05-06 15:27:28 +00:00
* [Generic] Add struct for all extra request settings Adds a new struct `ExtraRequestSettings` that contains all possible extra settings for all protocols, and can be implicitly converted with `.into()` into each protocol's extra settings type. This is then used in a new query method `query_with_timeout_and_extra_settings()` that passes the object on to the selected protocol. This also updates the generic example to set some of these generic settings so that it can be used for certain queries like "mc.hypixel.net". * [Minecraft] Add `request_settings` parameter to auto query This allows generic queries to pass through request settings when using the `mc` game so that servers like `mc.hypixel.net` will still work when using auto query. * Fix generic examples tests (and enable example tests in pre-commit)
99 lines
2.8 KiB
Rust
99 lines
2.8 KiB
Rust
use gamedig::{
|
|
protocols::types::{CommonResponse, ExtraRequestSettings, TimeoutSettings},
|
|
query_with_timeout_and_extra_settings,
|
|
GDResult,
|
|
GAMES,
|
|
};
|
|
|
|
use std::net::{IpAddr, SocketAddr, ToSocketAddrs};
|
|
|
|
/// Make a query given the name of a game
|
|
fn generic_query(
|
|
game_name: &str,
|
|
addr: &IpAddr,
|
|
port: Option<u16>,
|
|
timeout_settings: Option<TimeoutSettings>,
|
|
extra_settings: Option<ExtraRequestSettings>,
|
|
) -> GDResult<Box<dyn CommonResponse>> {
|
|
let game = GAMES
|
|
.get(game_name)
|
|
.expect("Game doesn't exist, run without arguments to see a list of games");
|
|
|
|
println!("Querying {:#?} with game {:#?}.", addr, game);
|
|
|
|
let response = query_with_timeout_and_extra_settings(game, addr, port, timeout_settings, extra_settings)?;
|
|
println!("Response: {:#?}", response.as_json());
|
|
|
|
let common = response.as_original();
|
|
println!("Common response: {:#?}", common);
|
|
|
|
Ok(response)
|
|
}
|
|
|
|
fn main() {
|
|
let mut args = std::env::args().skip(1);
|
|
|
|
// Handle arguments
|
|
if let Some(game_name) = args.next() {
|
|
let hostname = args.next().expect("Must provide an address");
|
|
// Use to_socket_addrs to resolve hostname to IP
|
|
let addr: SocketAddr = format!("{}:0", hostname)
|
|
.to_socket_addrs()
|
|
.unwrap()
|
|
.next()
|
|
.expect("Could not lookup host");
|
|
let port: Option<u16> = args.next().map(|s| s.parse().unwrap());
|
|
|
|
let extra_settings = ExtraRequestSettings::default()
|
|
.set_hostname(hostname.to_string())
|
|
.set_gather_rules(true)
|
|
.set_gather_players(true)
|
|
.set_check_app_id(false);
|
|
|
|
generic_query(&game_name, &addr.ip(), port, None, Some(extra_settings)).unwrap();
|
|
} else {
|
|
// Without arguments print a list of games
|
|
|
|
for (name, game) in gamedig::games::GAMES.entries() {
|
|
println!("{}\t{}", name, game.name);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
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) {
|
|
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, None).is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn battlefield() { test_game("bf1942"); }
|
|
|
|
#[test]
|
|
fn minecraft() { test_game("mc"); }
|
|
|
|
#[test]
|
|
fn tf2() { test_game("tf2"); }
|
|
|
|
#[test]
|
|
fn quake() { test_game("quake3a"); }
|
|
|
|
#[test]
|
|
fn all_games() {
|
|
for game_name in GAMES.keys() {
|
|
test_game(game_name);
|
|
}
|
|
}
|
|
}
|