From 9df4bddc09280fd97a904c4754492530619032ab Mon Sep 17 00:00:00 2001 From: cosminperram Date: Sun, 23 Oct 2022 17:34:22 +0300 Subject: [PATCH] Modularized reusable structs and changed files structure a bit --- CHANGELOG.md | 2 +- examples/tf2.rs | 2 +- src/games/aliens.rs | 75 +----- src/games/asrd.rs | 75 +----- src/games/csgo.rs | 18 +- src/games/css.rs | 75 +----- src/games/dods.rs | 75 +----- src/games/gm.rs | 75 +----- src/games/hl2dm.rs | 75 +----- src/games/ins.rs | 75 +----- src/games/insmic.rs | 75 +----- src/games/inss.rs | 75 +----- src/games/l4d.rs | 75 +----- src/games/l4d2.rs | 75 +----- src/games/tf2.rs | 75 +----- src/games/ts.rs | 22 +- src/protocols/valve/mod.rs | 5 + src/protocols/{valve.rs => valve/protocol.rs} | 160 +----------- src/protocols/valve/types.rs | 233 ++++++++++++++++++ 19 files changed, 279 insertions(+), 1063 deletions(-) create mode 100644 src/protocols/valve/mod.rs rename src/protocols/{valve.rs => valve/protocol.rs} (73%) create mode 100644 src/protocols/valve/types.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 9794873..529a821 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ Who knows what the future holds... # 0.0.4 - 23/10/2022 Queries now support DNS resolve. -Changed uses a bit, from `use gamedig::valve::ValveProtocol::query` to `use gamedig::protocols::valve::query`. +Changed uses a bit, example: from `use gamedig::valve::ValveProtocol::query` to `use gamedig::protocols::valve::query`. Changed Valve Protocol Query parameters to (ip, port, app, gather_settings), changes include: - the app is now optional, being None means to anonymously query the server. - gather_settings is now also an optional, being None means all query settings. diff --git a/examples/tf2.rs b/examples/tf2.rs index eb8c70a..728f7ef 100644 --- a/examples/tf2.rs +++ b/examples/tf2.rs @@ -2,7 +2,7 @@ use gamedig::games::tf2; fn main() { - let response = tf2::query("cosminperram.com", None); //or Some(27015), None is the default protocol port (which is 27015) + let response = tf2::query("91.216.250.10", None); //or Some(27015), None is the default protocol port (which is 27015) match response { Err(error) => println!("Couldn't query, error: {error}"), Ok(r) => println!("{:?}", r) diff --git a/src/games/aliens.rs b/src/games/aliens.rs index fa96d5d..05bad88 100644 --- a/src/games/aliens.rs +++ b/src/games/aliens.rs @@ -1,81 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{App, Server, ServerRule, ServerPlayer}; +use crate::protocols::valve::{App, game}; -#[derive(Debug)] -pub struct Player { - pub name: String, - pub score: u32, - pub duration: f32 -} - -impl Player { - fn from_valve_response(player: &ServerPlayer) -> Self { - Self { - name: player.name.clone(), - score: player.score, - duration: player.duration - } - } -} - -#[derive(Debug)] -pub struct Response { - pub protocol: u8, - pub name: String, - pub map: String, - pub game: String, - pub players: u8, - pub players_details: Vec, - pub max_players: u8, - pub bots: u8, - pub server_type: Server, - pub has_password: bool, - pub vac_secured: bool, - pub version: String, - pub port: Option, - pub steam_id: Option, - pub tv_port: Option, - pub tv_name: Option, - pub keywords: Option, - pub rules: Vec -} - -impl Response { - pub fn new_from_valve_response(response: valve::Response) -> Self { - let (port, steam_id, tv_port, tv_name, keywords) = match response.info.extra_data { - None => (None, None, None, None, None), - Some(ed) => (ed.port, ed.steam_id, ed.tv_port, ed.tv_name, ed.keywords) - }; - - Self { - protocol: response.info.protocol, - name: response.info.name, - map: response.info.map, - game: response.info.game, - players: response.info.players, - players_details: response.players.unwrap().iter().map(|p| Player::from_valve_response(p)).collect(), - max_players: response.info.max_players, - bots: response.info.bots, - server_type: response.info.server_type, - has_password: response.info.has_password, - vac_secured: response.info.vac_secured, - version: response.info.version, - port, - steam_id, - tv_port, - tv_name, - keywords, - rules: response.rules.unwrap() - } - } -} - -pub fn query(address: &str, port: Option) -> GDResult { +pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port }, Some(App::ALIENS), None)?; - Ok(Response::new_from_valve_response(valve_response)) + Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/asrd.rs b/src/games/asrd.rs index 1eefbe1..52c87d9 100644 --- a/src/games/asrd.rs +++ b/src/games/asrd.rs @@ -1,81 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{App, Server, ServerRule, ServerPlayer}; +use crate::protocols::valve::{App, game}; -#[derive(Debug)] -pub struct Player { - pub name: String, - pub score: u32, - pub duration: f32 -} - -impl Player { - fn from_valve_response(player: &ServerPlayer) -> Self { - Self { - name: player.name.clone(), - score: player.score, - duration: player.duration - } - } -} - -#[derive(Debug)] -pub struct Response { - pub protocol: u8, - pub name: String, - pub map: String, - pub game: String, - pub players: u8, - pub players_details: Vec, - pub max_players: u8, - pub bots: u8, - pub server_type: Server, - pub has_password: bool, - pub vac_secured: bool, - pub version: String, - pub port: Option, - pub steam_id: Option, - pub tv_port: Option, - pub tv_name: Option, - pub keywords: Option, - pub rules: Vec -} - -impl Response { - pub fn new_from_valve_response(response: valve::Response) -> Self { - let (port, steam_id, tv_port, tv_name, keywords) = match response.info.extra_data { - None => (None, None, None, None, None), - Some(ed) => (ed.port, ed.steam_id, ed.tv_port, ed.tv_name, ed.keywords) - }; - - Self { - protocol: response.info.protocol, - name: response.info.name, - map: response.info.map, - game: response.info.game, - players: response.info.players, - players_details: response.players.unwrap().iter().map(|p| Player::from_valve_response(p)).collect(), - max_players: response.info.max_players, - bots: response.info.bots, - server_type: response.info.server_type, - has_password: response.info.has_password, - vac_secured: response.info.vac_secured, - version: response.info.version, - port, - steam_id, - tv_port, - tv_name, - keywords, - rules: response.rules.unwrap() - } - } -} - -pub fn query(address: &str, port: Option) -> GDResult { +pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port }, Some(App::ASRD), None)?; - Ok(Response::new_from_valve_response(valve_response)) + Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/csgo.rs b/src/games/csgo.rs index 38f62cf..9af139b 100644 --- a/src/games/csgo.rs +++ b/src/games/csgo.rs @@ -1,23 +1,7 @@ use crate::GDResult; use crate::protocols::valve; use crate::protocols::valve::{App, Server, ServerPlayer, GatheringSettings}; - -#[derive(Debug)] -pub struct Player { - pub name: String, - pub score: u32, - pub duration: f32 -} - -impl Player { - fn from_valve_response(player: &ServerPlayer) -> Self { - Self { - name: player.name.clone(), - score: player.score, - duration: player.duration - } - } -} +use crate::protocols::valve::game::Player; #[derive(Debug)] pub struct Response { diff --git a/src/games/css.rs b/src/games/css.rs index db47618..004b870 100644 --- a/src/games/css.rs +++ b/src/games/css.rs @@ -1,81 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{App, Server, ServerRule, ServerPlayer}; +use crate::protocols::valve::{App, game}; -#[derive(Debug)] -pub struct Player { - pub name: String, - pub score: u32, - pub duration: f32 -} - -impl Player { - fn from_valve_response(player: &ServerPlayer) -> Self { - Self { - name: player.name.clone(), - score: player.score, - duration: player.duration - } - } -} - -#[derive(Debug)] -pub struct Response { - pub protocol: u8, - pub name: String, - pub map: String, - pub game: String, - pub players: u8, - pub players_details: Vec, - pub max_players: u8, - pub bots: u8, - pub server_type: Server, - pub has_password: bool, - pub vac_secured: bool, - pub version: String, - pub port: Option, - pub steam_id: Option, - pub tv_port: Option, - pub tv_name: Option, - pub keywords: Option, - pub rules: Vec -} - -impl Response { - pub fn new_from_valve_response(response: valve::Response) -> Self { - let (port, steam_id, tv_port, tv_name, keywords) = match response.info.extra_data { - None => (None, None, None, None, None), - Some(ed) => (ed.port, ed.steam_id, ed.tv_port, ed.tv_name, ed.keywords) - }; - - Self { - protocol: response.info.protocol, - name: response.info.name, - map: response.info.map, - game: response.info.game, - players: response.info.players, - players_details: response.players.unwrap().iter().map(|p| Player::from_valve_response(p)).collect(), - max_players: response.info.max_players, - bots: response.info.bots, - server_type: response.info.server_type, - has_password: response.info.has_password, - vac_secured: response.info.vac_secured, - version: response.info.version, - port, - steam_id, - tv_port, - tv_name, - keywords, - rules: response.rules.unwrap() - } - } -} - -pub fn query(address: &str, port: Option) -> GDResult { +pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port }, Some(App::CSS), None)?; - Ok(Response::new_from_valve_response(valve_response)) + Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/dods.rs b/src/games/dods.rs index 42fe9a5..4b3bfc1 100644 --- a/src/games/dods.rs +++ b/src/games/dods.rs @@ -1,81 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{App, Server, ServerRule, ServerPlayer}; +use crate::protocols::valve::{App, game}; -#[derive(Debug)] -pub struct Player { - pub name: String, - pub score: u32, - pub duration: f32 -} - -impl Player { - fn from_valve_response(player: &ServerPlayer) -> Self { - Self { - name: player.name.clone(), - score: player.score, - duration: player.duration - } - } -} - -#[derive(Debug)] -pub struct Response { - pub protocol: u8, - pub name: String, - pub map: String, - pub game: String, - pub players: u8, - pub players_details: Vec, - pub max_players: u8, - pub bots: u8, - pub server_type: Server, - pub has_password: bool, - pub vac_secured: bool, - pub version: String, - pub port: Option, - pub steam_id: Option, - pub tv_port: Option, - pub tv_name: Option, - pub keywords: Option, - pub rules: Vec -} - -impl Response { - pub fn new_from_valve_response(response: valve::Response) -> Self { - let (port, steam_id, tv_port, tv_name, keywords) = match response.info.extra_data { - None => (None, None, None, None, None), - Some(ed) => (ed.port, ed.steam_id, ed.tv_port, ed.tv_name, ed.keywords) - }; - - Self { - protocol: response.info.protocol, - name: response.info.name, - map: response.info.map, - game: response.info.game, - players: response.info.players, - players_details: response.players.unwrap().iter().map(|p| Player::from_valve_response(p)).collect(), - max_players: response.info.max_players, - bots: response.info.bots, - server_type: response.info.server_type, - has_password: response.info.has_password, - vac_secured: response.info.vac_secured, - version: response.info.version, - port, - steam_id, - tv_port, - tv_name, - keywords, - rules: response.rules.unwrap() - } - } -} - -pub fn query(address: &str, port: Option) -> GDResult { +pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port }, Some(App::DODS), None)?; - Ok(Response::new_from_valve_response(valve_response)) + Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/gm.rs b/src/games/gm.rs index cd08373..ff61d43 100644 --- a/src/games/gm.rs +++ b/src/games/gm.rs @@ -1,81 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{App, Server, ServerRule, ServerPlayer}; +use crate::protocols::valve::{App, game}; -#[derive(Debug)] -pub struct Player { - pub name: String, - pub score: u32, - pub duration: f32 -} - -impl Player { - fn from_valve_response(player: &ServerPlayer) -> Self { - Self { - name: player.name.clone(), - score: player.score, - duration: player.duration - } - } -} - -#[derive(Debug)] -pub struct Response { - pub protocol: u8, - pub name: String, - pub map: String, - pub game: String, - pub players: u8, - pub players_details: Vec, - pub max_players: u8, - pub bots: u8, - pub server_type: Server, - pub has_password: bool, - pub vac_secured: bool, - pub version: String, - pub port: Option, - pub steam_id: Option, - pub tv_port: Option, - pub tv_name: Option, - pub keywords: Option, - pub rules: Vec -} - -impl Response { - pub fn new_from_valve_response(response: valve::Response) -> Self { - let (port, steam_id, tv_port, tv_name, keywords) = match response.info.extra_data { - None => (None, None, None, None, None), - Some(ed) => (ed.port, ed.steam_id, ed.tv_port, ed.tv_name, ed.keywords) - }; - - Self { - protocol: response.info.protocol, - name: response.info.name, - map: response.info.map, - game: response.info.game, - players: response.info.players, - players_details: response.players.unwrap().iter().map(|p| Player::from_valve_response(p)).collect(), - max_players: response.info.max_players, - bots: response.info.bots, - server_type: response.info.server_type, - has_password: response.info.has_password, - vac_secured: response.info.vac_secured, - version: response.info.version, - port, - steam_id, - tv_port, - tv_name, - keywords, - rules: response.rules.unwrap() - } - } -} - -pub fn query(address: &str, port: Option) -> GDResult { +pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port }, Some(App::GM), None)?; - Ok(Response::new_from_valve_response(valve_response)) + Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/hl2dm.rs b/src/games/hl2dm.rs index 75c40c0..f84ab0c 100644 --- a/src/games/hl2dm.rs +++ b/src/games/hl2dm.rs @@ -1,81 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{App, Server, ServerRule, ServerPlayer}; +use crate::protocols::valve::{App, game}; -#[derive(Debug)] -pub struct Player { - pub name: String, - pub score: u32, - pub duration: f32 -} - -impl Player { - fn from_valve_response(player: &ServerPlayer) -> Self { - Self { - name: player.name.clone(), - score: player.score, - duration: player.duration - } - } -} - -#[derive(Debug)] -pub struct Response { - pub protocol: u8, - pub name: String, - pub map: String, - pub game: String, - pub players: u8, - pub players_details: Vec, - pub max_players: u8, - pub bots: u8, - pub server_type: Server, - pub has_password: bool, - pub vac_secured: bool, - pub version: String, - pub port: Option, - pub steam_id: Option, - pub tv_port: Option, - pub tv_name: Option, - pub keywords: Option, - pub rules: Vec -} - -impl Response { - pub fn new_from_valve_response(response: valve::Response) -> Self { - let (port, steam_id, tv_port, tv_name, keywords) = match response.info.extra_data { - None => (None, None, None, None, None), - Some(ed) => (ed.port, ed.steam_id, ed.tv_port, ed.tv_name, ed.keywords) - }; - - Self { - protocol: response.info.protocol, - name: response.info.name, - map: response.info.map, - game: response.info.game, - players: response.info.players, - players_details: response.players.unwrap().iter().map(|p| Player::from_valve_response(p)).collect(), - max_players: response.info.max_players, - bots: response.info.bots, - server_type: response.info.server_type, - has_password: response.info.has_password, - vac_secured: response.info.vac_secured, - version: response.info.version, - port, - steam_id, - tv_port, - tv_name, - keywords, - rules: response.rules.unwrap() - } - } -} - -pub fn query(address: &str, port: Option) -> GDResult { +pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port }, Some(App::HL2DM), None)?; - Ok(Response::new_from_valve_response(valve_response)) + Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/ins.rs b/src/games/ins.rs index bca0d06..bd51377 100644 --- a/src/games/ins.rs +++ b/src/games/ins.rs @@ -1,81 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{App, Server, ServerRule, ServerPlayer}; +use crate::protocols::valve::{App, game}; -#[derive(Debug)] -pub struct Player { - pub name: String, - pub score: u32, - pub duration: f32 -} - -impl Player { - fn from_valve_response(player: &ServerPlayer) -> Self { - Self { - name: player.name.clone(), - score: player.score, - duration: player.duration - } - } -} - -#[derive(Debug)] -pub struct Response { - pub protocol: u8, - pub name: String, - pub map: String, - pub game: String, - pub players: u8, - pub players_details: Vec, - pub max_players: u8, - pub bots: u8, - pub server_type: Server, - pub has_password: bool, - pub vac_secured: bool, - pub version: String, - pub port: Option, - pub steam_id: Option, - pub tv_port: Option, - pub tv_name: Option, - pub keywords: Option, - pub rules: Vec -} - -impl Response { - pub fn new_from_valve_response(response: valve::Response) -> Self { - let (port, steam_id, tv_port, tv_name, keywords) = match response.info.extra_data { - None => (None, None, None, None, None), - Some(ed) => (ed.port, ed.steam_id, ed.tv_port, ed.tv_name, ed.keywords) - }; - - Self { - protocol: response.info.protocol, - name: response.info.name, - map: response.info.map, - game: response.info.game, - players: response.info.players, - players_details: response.players.unwrap().iter().map(|p| Player::from_valve_response(p)).collect(), - max_players: response.info.max_players, - bots: response.info.bots, - server_type: response.info.server_type, - has_password: response.info.has_password, - vac_secured: response.info.vac_secured, - version: response.info.version, - port, - steam_id, - tv_port, - tv_name, - keywords, - rules: response.rules.unwrap() - } - } -} - -pub fn query(address: &str, port: Option) -> GDResult { +pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port }, Some(App::INS), None)?; - Ok(Response::new_from_valve_response(valve_response)) + Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/insmic.rs b/src/games/insmic.rs index 1146e36..123e9c9 100644 --- a/src/games/insmic.rs +++ b/src/games/insmic.rs @@ -1,81 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{App, Server, ServerRule, ServerPlayer}; +use crate::protocols::valve::{App, game}; -#[derive(Debug)] -pub struct Player { - pub name: String, - pub score: u32, - pub duration: f32 -} - -impl Player { - fn from_valve_response(player: &ServerPlayer) -> Self { - Self { - name: player.name.clone(), - score: player.score, - duration: player.duration - } - } -} - -#[derive(Debug)] -pub struct Response { - pub protocol: u8, - pub name: String, - pub map: String, - pub game: String, - pub players: u8, - pub players_details: Vec, - pub max_players: u8, - pub bots: u8, - pub server_type: Server, - pub has_password: bool, - pub vac_secured: bool, - pub version: String, - pub port: Option, - pub steam_id: Option, - pub tv_port: Option, - pub tv_name: Option, - pub keywords: Option, - pub rules: Vec -} - -impl Response { - pub fn new_from_valve_response(response: valve::Response) -> Self { - let (port, steam_id, tv_port, tv_name, keywords) = match response.info.extra_data { - None => (None, None, None, None, None), - Some(ed) => (ed.port, ed.steam_id, ed.tv_port, ed.tv_name, ed.keywords) - }; - - Self { - protocol: response.info.protocol, - name: response.info.name, - map: response.info.map, - game: response.info.game, - players: response.info.players, - players_details: response.players.unwrap().iter().map(|p| Player::from_valve_response(p)).collect(), - max_players: response.info.max_players, - bots: response.info.bots, - server_type: response.info.server_type, - has_password: response.info.has_password, - vac_secured: response.info.vac_secured, - version: response.info.version, - port, - steam_id, - tv_port, - tv_name, - keywords, - rules: response.rules.unwrap() - } - } -} - -pub fn query(address: &str, port: Option) -> GDResult { +pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port }, Some(App::INSMIC), None)?; - Ok(Response::new_from_valve_response(valve_response)) + Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/inss.rs b/src/games/inss.rs index f202002..e696c5d 100644 --- a/src/games/inss.rs +++ b/src/games/inss.rs @@ -1,81 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{App, Server, ServerRule, ServerPlayer}; +use crate::protocols::valve::{App, game}; -#[derive(Debug)] -pub struct Player { - pub name: String, - pub score: u32, - pub duration: f32 -} - -impl Player { - fn from_valve_response(player: &ServerPlayer) -> Self { - Self { - name: player.name.clone(), - score: player.score, - duration: player.duration - } - } -} - -#[derive(Debug)] -pub struct Response { - pub protocol: u8, - pub name: String, - pub map: String, - pub game: String, - pub players: u8, - pub players_details: Vec, - pub max_players: u8, - pub bots: u8, - pub server_type: Server, - pub has_password: bool, - pub vac_secured: bool, - pub version: String, - pub port: Option, - pub steam_id: Option, - pub tv_port: Option, - pub tv_name: Option, - pub keywords: Option, - pub rules: Vec -} - -impl Response { - pub fn new_from_valve_response(response: valve::Response) -> Self { - let (port, steam_id, tv_port, tv_name, keywords) = match response.info.extra_data { - None => (None, None, None, None, None), - Some(ed) => (ed.port, ed.steam_id, ed.tv_port, ed.tv_name, ed.keywords) - }; - - Self { - protocol: response.info.protocol, - name: response.info.name, - map: response.info.map, - game: response.info.game, - players: response.info.players, - players_details: response.players.unwrap().iter().map(|p| Player::from_valve_response(p)).collect(), - max_players: response.info.max_players, - bots: response.info.bots, - server_type: response.info.server_type, - has_password: response.info.has_password, - vac_secured: response.info.vac_secured, - version: response.info.version, - port, - steam_id, - tv_port, - tv_name, - keywords, - rules: response.rules.unwrap() - } - } -} - -pub fn query(address: &str, port: Option) -> GDResult { +pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27131, Some(port) => port }, Some(App::INSS), None)?; - Ok(Response::new_from_valve_response(valve_response)) + Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/l4d.rs b/src/games/l4d.rs index 4b945fa..f024be0 100644 --- a/src/games/l4d.rs +++ b/src/games/l4d.rs @@ -1,81 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{App, Server, ServerRule, ServerPlayer}; +use crate::protocols::valve::{App, game}; -#[derive(Debug)] -pub struct Player { - pub name: String, - pub score: u32, - pub duration: f32 -} - -impl Player { - fn from_valve_response(player: &ServerPlayer) -> Self { - Self { - name: player.name.clone(), - score: player.score, - duration: player.duration - } - } -} - -#[derive(Debug)] -pub struct Response { - pub protocol: u8, - pub name: String, - pub map: String, - pub game: String, - pub players: u8, - pub players_details: Vec, - pub max_players: u8, - pub bots: u8, - pub server_type: Server, - pub has_password: bool, - pub vac_secured: bool, - pub version: String, - pub port: Option, - pub steam_id: Option, - pub tv_port: Option, - pub tv_name: Option, - pub keywords: Option, - pub rules: Vec -} - -impl Response { - pub fn new_from_valve_response(response: valve::Response) -> Self { - let (port, steam_id, tv_port, tv_name, keywords) = match response.info.extra_data { - None => (None, None, None, None, None), - Some(ed) => (ed.port, ed.steam_id, ed.tv_port, ed.tv_name, ed.keywords) - }; - - Self { - protocol: response.info.protocol, - name: response.info.name, - map: response.info.map, - game: response.info.game, - players: response.info.players, - players_details: response.players.unwrap().iter().map(|p| Player::from_valve_response(p)).collect(), - max_players: response.info.max_players, - bots: response.info.bots, - server_type: response.info.server_type, - has_password: response.info.has_password, - vac_secured: response.info.vac_secured, - version: response.info.version, - port, - steam_id, - tv_port, - tv_name, - keywords, - rules: response.rules.unwrap() - } - } -} - -pub fn query(address: &str, port: Option) -> GDResult { +pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port }, Some(App::L4D), None)?; - Ok(Response::new_from_valve_response(valve_response)) + Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/l4d2.rs b/src/games/l4d2.rs index ca3d8d1..108bd84 100644 --- a/src/games/l4d2.rs +++ b/src/games/l4d2.rs @@ -1,81 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{App, Server, ServerRule, ServerPlayer}; +use crate::protocols::valve::{App, game}; -#[derive(Debug)] -pub struct Player { - pub name: String, - pub score: u32, - pub duration: f32 -} - -impl Player { - fn from_valve_response(player: &ServerPlayer) -> Self { - Self { - name: player.name.clone(), - score: player.score, - duration: player.duration - } - } -} - -#[derive(Debug)] -pub struct Response { - pub protocol: u8, - pub name: String, - pub map: String, - pub game: String, - pub players: u8, - pub players_details: Vec, - pub max_players: u8, - pub bots: u8, - pub server_type: Server, - pub has_password: bool, - pub vac_secured: bool, - pub version: String, - pub port: Option, - pub steam_id: Option, - pub tv_port: Option, - pub tv_name: Option, - pub keywords: Option, - pub rules: Vec -} - -impl Response { - pub fn new_from_valve_response(response: valve::Response) -> Self { - let (port, steam_id, tv_port, tv_name, keywords) = match response.info.extra_data { - None => (None, None, None, None, None), - Some(ed) => (ed.port, ed.steam_id, ed.tv_port, ed.tv_name, ed.keywords) - }; - - Self { - protocol: response.info.protocol, - name: response.info.name, - map: response.info.map, - game: response.info.game, - players: response.info.players, - players_details: response.players.unwrap().iter().map(|p| Player::from_valve_response(p)).collect(), - max_players: response.info.max_players, - bots: response.info.bots, - server_type: response.info.server_type, - has_password: response.info.has_password, - vac_secured: response.info.vac_secured, - version: response.info.version, - port, - steam_id, - tv_port, - tv_name, - keywords, - rules: response.rules.unwrap() - } - } -} - -pub fn query(address: &str, port: Option) -> GDResult { +pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port }, Some(App::L4D2), None)?; - Ok(Response::new_from_valve_response(valve_response)) + Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/tf2.rs b/src/games/tf2.rs index 7834d99..a695ec2 100644 --- a/src/games/tf2.rs +++ b/src/games/tf2.rs @@ -1,81 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{App, Server, ServerRule, ServerPlayer}; +use crate::protocols::valve::{App, game}; -#[derive(Debug)] -pub struct Player { - pub name: String, - pub score: u32, - pub duration: f32 -} - -impl Player { - fn from_valve_response(player: &ServerPlayer) -> Self { - Self { - name: player.name.clone(), - score: player.score, - duration: player.duration - } - } -} - -#[derive(Debug)] -pub struct Response { - pub protocol: u8, - pub name: String, - pub map: String, - pub game: String, - pub players: u8, - pub players_details: Vec, - pub max_players: u8, - pub bots: u8, - pub server_type: Server, - pub has_password: bool, - pub vac_secured: bool, - pub version: String, - pub port: Option, - pub steam_id: Option, - pub tv_port: Option, - pub tv_name: Option, - pub keywords: Option, - pub rules: Vec -} - -impl Response { - pub fn new_from_valve_response(response: valve::Response) -> Self { - let (port, steam_id, tv_port, tv_name, keywords) = match response.info.extra_data { - None => (None, None, None, None, None), - Some(ed) => (ed.port, ed.steam_id, ed.tv_port, ed.tv_name, ed.keywords) - }; - - Self { - protocol: response.info.protocol, - name: response.info.name, - map: response.info.map, - game: response.info.game, - players: response.info.players, - players_details: response.players.unwrap().iter().map(|p| Player::from_valve_response(p)).collect(), - max_players: response.info.max_players, - bots: response.info.bots, - server_type: response.info.server_type, - has_password: response.info.has_password, - vac_secured: response.info.vac_secured, - version: response.info.version, - port, - steam_id, - tv_port, - tv_name, - keywords, - rules: response.rules.unwrap() - } - } -} - -pub fn query(address: &str, port: Option) -> GDResult { +pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port }, Some(App::TF2), None)?; - Ok(Response::new_from_valve_response(valve_response)) + Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/ts.rs b/src/games/ts.rs index b5edb3b..ecc9baa 100644 --- a/src/games/ts.rs +++ b/src/games/ts.rs @@ -1,27 +1,7 @@ use crate::GDResult; use crate::protocols::valve; use crate::protocols::valve::{App, Server, ServerRule, ServerPlayer}; - -#[derive(Debug)] -pub struct Player { - pub name: String, - pub score: u32, - pub duration: f32, - pub deaths: u32, - pub money: u32 -} - -impl Player { - fn from_valve_response(player: &ServerPlayer) -> Self { - Self { - name: player.name.clone(), - score: player.score, - duration: player.duration, - deaths: player.deaths.unwrap(), - money: player.money.unwrap() - } - } -} +use crate::protocols::valve::game::Player; #[derive(Debug)] pub struct Response { diff --git a/src/protocols/valve/mod.rs b/src/protocols/valve/mod.rs new file mode 100644 index 0000000..ebc8f9f --- /dev/null +++ b/src/protocols/valve/mod.rs @@ -0,0 +1,5 @@ +pub mod protocol; +pub mod types; + +pub use protocol::*; +pub use types::*; diff --git a/src/protocols/valve.rs b/src/protocols/valve/protocol.rs similarity index 73% rename from src/protocols/valve.rs rename to src/protocols/valve/protocol.rs index 663da90..e5ca9c1 100644 --- a/src/protocols/valve.rs +++ b/src/protocols/valve/protocol.rs @@ -1,167 +1,9 @@ use std::net::UdpSocket; use bzip2_rs::decoder::Decoder; use crate::{GDError, GDResult}; +use crate::protocols::valve::types::{App, Environment, ExtraData, GatheringSettings, Request, Response, Server, ServerInfo, ServerPlayer, ServerRule, TheShip}; use crate::utils::{buffer, complete_address}; -/// The type of the server. -#[derive(Debug)] -pub enum Server { - Dedicated, - NonDedicated, - SourceTV -} - -/// The Operating System that the server is on. -#[derive(Debug)] -pub enum Environment { - Linux, - Windows, - Mac -} - -/// A query response. -#[derive(Debug)] -pub struct Response { - pub info: ServerInfo, - pub players: Option>, - pub rules: Option> -} - -/// General server information's. -#[derive(Debug)] -pub struct ServerInfo { - /// Protocol used by the server. - pub protocol: u8, - /// Name of the server. - pub name: String, - /// Map name. - pub map: String, - /// Name of the folder containing the game files. - pub folder: String, - /// Full name of the game. - pub game: String, - /// [Steam Application ID](https://developer.valvesoftware.com/wiki/Steam_Application_ID) of game. - pub appid: u32, - /// Number of players on the server. - pub players: u8, - /// Maximum number of players the server reports it can hold. - pub max_players: u8, - /// Number of bots on the server. - pub bots: u8, - /// Dedicated, NonDedicated or SourceTV - pub server_type: Server, - /// The Operating System that the server is on. - pub environment_type: Environment, - /// Indicated whether the server requires a password. - pub has_password: bool, - /// Indicated whether the server uses VAC. - pub vac_secured: bool, - /// [The ship](https://developer.valvesoftware.com/wiki/The_Ship) extra data - pub the_ship: Option, - /// Version of the game installed on the server. - pub version: String, - /// Some extra data that the server might provide or not. - pub extra_data: Option -} - -/// A server player. -#[derive(Debug)] -pub struct ServerPlayer { - /// Player's name. - pub name: String, - /// General score. - pub score: u32, - /// How long they've been on the server for. - pub duration: f32, - /// Only for [the ship](https://developer.valvesoftware.com/wiki/The_Ship): deaths count - pub deaths: Option, //the_ship - /// Only for [the ship](https://developer.valvesoftware.com/wiki/The_Ship): money amount - pub money: Option, //the_ship -} - -/// A server rule. -#[derive(Debug)] -pub struct ServerRule { - pub name: String, - pub value: String -} - -/// Only present for [the ship](https://developer.valvesoftware.com/wiki/The_Ship). -#[derive(Debug)] -pub struct TheShip { - pub mode: u8, - pub witnesses: u8, - pub duration: u8 -} - -/// Some extra data that the server might provide or not. -#[derive(Debug)] -pub struct ExtraData { - /// The server's game port number. - pub port: Option, - /// Server's SteamID. - pub steam_id: Option, - /// Spectator port number for SourceTV. - pub tv_port: Option, - /// Name of the spectator server for SourceTV. - pub tv_name: Option, - /// Tags that describe the game according to the server. - pub keywords: Option, - /// The server's 64-bit GameID. - pub game_id: Option -} - -/// The type of the request, see the [protocol](https://developer.valvesoftware.com/wiki/Server_queries). -#[derive(PartialEq, Clone)] -#[repr(u8)] -pub enum Request { - /// Known as `A2S_INFO` - INFO = 0x54, - /// Known as `A2S_PLAYERS` - PLAYERS = 0x55, - /// Known as `A2S_RULES` - RULES = 0x56 -} - -/// Supported app id's -#[derive(PartialEq, Clone)] -pub enum App { - /// Counter-Strike: Source - CSS = 240, - /// Day of Defeat: Source - DODS = 300, - /// Half-Life 2 Deathmatch - HL2DM = 320, - /// Team Fortress 2 - TF2 = 440, - /// Left 4 Dead - L4D = 500, - /// Left 4 Dead - L4D2 = 550, - /// Alien Swarm - ALIENS = 630, - /// Counter-Strike: Global Offensive - CSGO = 730, - /// The Ship - TS = 2400, - /// Garry's Mod - GM = 4000, - /// Insurgency: Modern Infantry Combat - INSMIC = 17700, - /// Insurgency - INS = 222880, - /// Insurgency: Sandstorm - INSS = 581320, - /// Alien Swarm: Reactive Drop - ASRD = 563560, -} - -/// What data to gather, purely used only with the query function. -pub struct GatheringSettings { - pub players: bool, - pub rules: bool -} - #[derive(Debug, Clone)] struct Packet { pub header: u32, diff --git a/src/protocols/valve/types.rs b/src/protocols/valve/types.rs new file mode 100644 index 0000000..9636197 --- /dev/null +++ b/src/protocols/valve/types.rs @@ -0,0 +1,233 @@ + +/// The type of the server. +#[derive(Debug)] +pub enum Server { + Dedicated, + NonDedicated, + SourceTV +} + +/// The Operating System that the server is on. +#[derive(Debug)] +pub enum Environment { + Linux, + Windows, + Mac +} + +/// A query response. +#[derive(Debug)] +pub struct Response { + pub info: ServerInfo, + pub players: Option>, + pub rules: Option> +} + +/// General server information's. +#[derive(Debug)] +pub struct ServerInfo { + /// Protocol used by the server. + pub protocol: u8, + /// Name of the server. + pub name: String, + /// Map name. + pub map: String, + /// Name of the folder containing the game files. + pub folder: String, + /// Full name of the game. + pub game: String, + /// [Steam Application ID](https://developer.valvesoftware.com/wiki/Steam_Application_ID) of game. + pub appid: u32, + /// Number of players on the server. + pub players: u8, + /// Maximum number of players the server reports it can hold. + pub max_players: u8, + /// Number of bots on the server. + pub bots: u8, + /// Dedicated, NonDedicated or SourceTV + pub server_type: Server, + /// The Operating System that the server is on. + pub environment_type: Environment, + /// Indicated whether the server requires a password. + pub has_password: bool, + /// Indicated whether the server uses VAC. + pub vac_secured: bool, + /// [The ship](https://developer.valvesoftware.com/wiki/The_Ship) extra data + pub the_ship: Option, + /// Version of the game installed on the server. + pub version: String, + /// Some extra data that the server might provide or not. + pub extra_data: Option +} + +/// A server player. +#[derive(Debug)] +pub struct ServerPlayer { + /// Player's name. + pub name: String, + /// General score. + pub score: u32, + /// How long they've been on the server for. + pub duration: f32, + /// Only for [the ship](https://developer.valvesoftware.com/wiki/The_Ship): deaths count + pub deaths: Option, //the_ship + /// Only for [the ship](https://developer.valvesoftware.com/wiki/The_Ship): money amount + pub money: Option, //the_ship +} + +/// A server rule. +#[derive(Debug)] +pub struct ServerRule { + pub name: String, + pub value: String +} + +/// Only present for [the ship](https://developer.valvesoftware.com/wiki/The_Ship). +#[derive(Debug)] +pub struct TheShip { + pub mode: u8, + pub witnesses: u8, + pub duration: u8 +} + +/// Some extra data that the server might provide or not. +#[derive(Debug)] +pub struct ExtraData { + /// The server's game port number. + pub port: Option, + /// Server's SteamID. + pub steam_id: Option, + /// Spectator port number for SourceTV. + pub tv_port: Option, + /// Name of the spectator server for SourceTV. + pub tv_name: Option, + /// Tags that describe the game according to the server. + pub keywords: Option, + /// The server's 64-bit GameID. + pub game_id: Option +} + +/// The type of the request, see the [protocol](https://developer.valvesoftware.com/wiki/Server_queries). +#[derive(PartialEq, Clone)] +#[repr(u8)] +pub enum Request { + /// Known as `A2S_INFO` + INFO = 0x54, + /// Known as `A2S_PLAYERS` + PLAYERS = 0x55, + /// Known as `A2S_RULES` + RULES = 0x56 +} + +/// Supported app id's +#[derive(PartialEq, Clone)] +pub enum App { + /// Counter-Strike: Source + CSS = 240, + /// Day of Defeat: Source + DODS = 300, + /// Half-Life 2 Deathmatch + HL2DM = 320, + /// Team Fortress 2 + TF2 = 440, + /// Left 4 Dead + L4D = 500, + /// Left 4 Dead + L4D2 = 550, + /// Alien Swarm + ALIENS = 630, + /// Counter-Strike: Global Offensive + CSGO = 730, + /// The Ship + TS = 2400, + /// Garry's Mod + GM = 4000, + /// Insurgency: Modern Infantry Combat + INSMIC = 17700, + /// Insurgency + INS = 222880, + /// Insurgency: Sandstorm + INSS = 581320, + /// Alien Swarm: Reactive Drop + ASRD = 563560, +} + +/// What data to gather, purely used only with the query function. +pub struct GatheringSettings { + pub players: bool, + pub rules: bool +} + +pub mod game { + use super::{Server, ServerRule, ServerPlayer}; + + #[derive(Debug)] + pub struct Player { + pub name: String, + pub score: u32, + pub duration: f32 + } + + impl Player { + pub fn from_valve_response(player: &ServerPlayer) -> Self { + Self { + name: player.name.clone(), + score: player.score, + duration: player.duration + } + } + } + + #[derive(Debug)] + pub struct Response { + pub protocol: u8, + pub name: String, + pub map: String, + pub game: String, + pub players: u8, + pub players_details: Vec, + pub max_players: u8, + pub bots: u8, + pub server_type: Server, + pub has_password: bool, + pub vac_secured: bool, + pub version: String, + pub port: Option, + pub steam_id: Option, + pub tv_port: Option, + pub tv_name: Option, + pub keywords: Option, + pub rules: Vec + } + + impl Response { + pub fn new_from_valve_response(response: super::Response) -> Self { + let (port, steam_id, tv_port, tv_name, keywords) = match response.info.extra_data { + None => (None, None, None, None, None), + Some(ed) => (ed.port, ed.steam_id, ed.tv_port, ed.tv_name, ed.keywords) + }; + + Self { + protocol: response.info.protocol, + name: response.info.name, + map: response.info.map, + game: response.info.game, + players: response.info.players, + players_details: response.players.unwrap().iter().map(|p| Player::from_valve_response(p)).collect(), + max_players: response.info.max_players, + bots: response.info.bots, + server_type: response.info.server_type, + has_password: response.info.has_password, + vac_secured: response.info.vac_secured, + version: response.info.version, + port, + steam_id, + tv_port, + tv_name, + keywords, + rules: response.rules.unwrap() + } + } + } +} +