diff --git a/CHANGELOG.md b/CHANGELOG.md index edf6508..d6985f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,14 @@ Who knows what the future holds... -# 0.1.Y - DD/MM/2023 +# 0.X.Y - DD/MM/2023 +### Changes: +None. + +### Breaking: +None. + +# 0.2.0 - 18/02/2023 ### Changes: Games: - [Don't Starve Together](https://store.steampowered.com/app/322330/Dont_Starve_Together/) support. @@ -13,8 +20,20 @@ Games: - [Avorion](https://store.steampowered.com/app/445220/Avorion/) support. - [Operation: Harsh Doorstop](https://store.steampowered.com/app/736590/Operation_Harsh_Doorstop/) support. +Protocols: +- Valve: +1. `appid` is now a field in the `Response` struct. + ### Breaking: -Nothing. +Protocols: +- Valve: +due to some games being able to host a server from within the game AND from a dedicated server, +if you were to query one of them, the query would fail for the other one, as the `SteamID` enum +for that game could specify only one id. +1. `SteamID` is now `SteamApp`, was an u32 enum, and now it's a simple enum. +2. `App` is now `Engine`, the `Source` enum's structure has been changed from `Option` to +`Option>`, where the first parameter is the game app id and the second is +the dedicated server app id (if there is one). # 0.1.0 - 17/01/2023 ### Changes: diff --git a/Cargo.toml b/Cargo.toml index ff89607..584416a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gamedig" -version = "0.1.0" +version = "0.2.0" edition = "2021" authors = ["CosminPerRam [cosmin.p@live.com]", "node-GameDig [https://github.com/gamedig/node-gamedig]"] license = "MIT" diff --git a/LICENSE.md b/LICENSE.md index 7fa2763..9362443 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 CosminPerRam +Copyright (c) 2023 CosminPerRam Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index a36b697..9b202ef 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ use gamedig::games::tf2; fn main() { let response = tf2::query("127.0.0.1", None); // None is the default port (which is 27015), could also be Some(27015) - match response { + match response { // Result type, must check what it is... Err(error) => println!("Couldn't query, error: {}", error), Ok(r) => println!("{:#?}", r) } @@ -28,6 +28,7 @@ Response (note that some games have a different structure): name: "Team Fortress 2 Dedicated Server.", map: "ctf_turbine", game: "tf2", + appid: 440, players_online: 0, players_details: [], players_maximum: 69, diff --git a/examples/master_querant.rs b/examples/master_querant.rs index 1c8581d..e89c643 100644 --- a/examples/master_querant.rs +++ b/examples/master_querant.rs @@ -3,7 +3,7 @@ use std::env; use gamedig::{aliens, aoc, arma2oa, ase, asrd, avorion, bat1944, bb2, bm, bo, ccure, cosu, cs, cscz, csgo, css, dod, dods, doi, dst, GDResult, gm, hl2dm, hldms, ins, insmic, inss, l4d, l4d2, mc, ohd, onset, pz, ror2, rust, sc, sdtd, tf, tf2, tfc, ts, unturned}; use gamedig::protocols::minecraft::LegacyGroup; use gamedig::protocols::valve; -use gamedig::protocols::valve::App; +use gamedig::protocols::valve::Engine; fn main() -> GDResult<()> { let args: Vec = env::args().collect(); @@ -48,9 +48,9 @@ fn main() -> GDResult<()> { "ts" => println!("{:#?}", ts::query(ip, port)?), "cscz" => println!("{:#?}", cscz::query(ip, port)?), "dod" => println!("{:#?}", dod::query(ip, port)?), - "_src" => println!("{:#?}", valve::query(ip, port.unwrap(), App::Source(None), None, None)?), - "_gld" => println!("{:#?}", valve::query(ip, port.unwrap(), App::GoldSrc(false), None, None)?), - "_gld_f" => println!("{:#?}", valve::query(ip, port.unwrap(), App::GoldSrc(true), None, None)?), + "_src" => println!("{:#?}", valve::query(ip, port.unwrap(), Engine::Source(None), None, None)?), + "_gld" => println!("{:#?}", valve::query(ip, port.unwrap(), Engine::GoldSrc(false), None, None)?), + "_gld_f" => println!("{:#?}", valve::query(ip, port.unwrap(), Engine::GoldSrc(true), None, None)?), "mc" => println!("{:#?}", mc::query(ip, port)?), "mc_java" => println!("{:#?}", mc::query_java(ip, port)?), "mc_bedrock" => println!("{:#?}", mc::query_bedrock(ip, port)?), diff --git a/examples/tf2.rs b/examples/tf2.rs index 8a612c9..058fde8 100644 --- a/examples/tf2.rs +++ b/examples/tf2.rs @@ -3,7 +3,7 @@ use gamedig::games::tf2; fn main() { let response = tf2::query("127.0.0.1", None); //or Some(27015), None is the default protocol port (which is 27015) - match response { + match response { // Result type, must check what it is... 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 3e8dc43..07f55f2 100644 --- a/src/games/aliens.rs +++ b/src/games/aliens.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::ALIENS.as_app(), None, None)?; + }, SteamApp::ALIENS.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/aoc.rs b/src/games/aoc.rs index 55f1357..ff7e421 100644 --- a/src/games/aoc.rs +++ b/src/games/aoc.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::AOC.as_app(), None, None)?; + }, SteamApp::AOC.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/arma2oa.rs b/src/games/arma2oa.rs index 5ea6f86..c5b88ff 100644 --- a/src/games/arma2oa.rs +++ b/src/games/arma2oa.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 2304, Some(port) => port - }, SteamID::ARMA2OA.as_app(), None, None)?; + }, SteamApp::ARMA2OA.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/ase.rs b/src/games/ase.rs index 30d2092..e863186 100644 --- a/src/games/ase.rs +++ b/src/games/ase.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::ASE.as_app(), None, None)?; + }, SteamApp::ASE.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/asrd.rs b/src/games/asrd.rs index 4852233..5caf1f4 100644 --- a/src/games/asrd.rs +++ b/src/games/asrd.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::ASRD.as_app(), None, None)?; + }, SteamApp::ASRD.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/avorion.rs b/src/games/avorion.rs index a0b5a20..51f9fa1 100644 --- a/src/games/avorion.rs +++ b/src/games/avorion.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27020, Some(port) => port - }, SteamID::AVORION.as_app(), None, None)?; + }, SteamApp::AVORION.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/bat1944.rs b/src/games/bat1944.rs index 135038c..c564b8d 100644 --- a/src/games/bat1944.rs +++ b/src/games/bat1944.rs @@ -1,13 +1,13 @@ use crate::GDError::TypeParse; use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let mut valve_response = valve::query(address, match port { None => 7780, Some(port) => port - }, SteamID::BAT1944.as_app(), None, None)?; + }, SteamApp::BAT1944.as_engine(), None, None)?; if let Some(rules) = &mut valve_response.rules { if let Some(bat_max_players) = rules.get("bat_max_players_i") { diff --git a/src/games/bb2.rs b/src/games/bb2.rs index 14dc9e1..add46de 100644 --- a/src/games/bb2.rs +++ b/src/games/bb2.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::BB2.as_app(), None, None)?; + }, SteamApp::BB2.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/bm.rs b/src/games/bm.rs index 93daf35..4904fb0 100644 --- a/src/games/bm.rs +++ b/src/games/bm.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::BM.as_app(), None, None)?; + }, SteamApp::BM.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/bo.rs b/src/games/bo.rs index dcd9a54..8a8441a 100644 --- a/src/games/bo.rs +++ b/src/games/bo.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27016, Some(port) => port - }, SteamID::BO.as_app(), None, None)?; + }, SteamApp::BO.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/ccure.rs b/src/games/ccure.rs index 062b32f..ef1de45 100644 --- a/src/games/ccure.rs +++ b/src/games/ccure.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::CCURE.as_app(), None, None)?; + }, SteamApp::CCURE.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/cosu.rs b/src/games/cosu.rs index 0b883fd..bb033fe 100644 --- a/src/games/cosu.rs +++ b/src/games/cosu.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27004, Some(port) => port - }, SteamID::COSU.as_app(), None, None)?; + }, SteamApp::COSU.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/cs.rs b/src/games/cs.rs index 3e662cb..d117d06 100644 --- a/src/games/cs.rs +++ b/src/games/cs.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::CS.as_app(), None, None)?; + }, SteamApp::CS.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/cscz.rs b/src/games/cscz.rs index 56106dc..6cb4a3d 100644 --- a/src/games/cscz.rs +++ b/src/games/cscz.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::CSCZ.as_app(), None, None)?; + }, SteamApp::CSCZ.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/csgo.rs b/src/games/csgo.rs index 3786606..4502694 100644 --- a/src/games/csgo.rs +++ b/src/games/csgo.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::CSGO.as_app(), None, None)?; + }, SteamApp::CSGO.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/css.rs b/src/games/css.rs index 383a3f6..c054ceb 100644 --- a/src/games/css.rs +++ b/src/games/css.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::CSS.as_app(), None, None)?; + }, SteamApp::CSS.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/dod.rs b/src/games/dod.rs index 928f94f..99ad0b0 100644 --- a/src/games/dod.rs +++ b/src/games/dod.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::DOD.as_app(), None, None)?; + }, SteamApp::DOD.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/dods.rs b/src/games/dods.rs index 0e3cdd1..7d05166 100644 --- a/src/games/dods.rs +++ b/src/games/dods.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::DODS.as_app(), None, None)?; + }, SteamApp::DODS.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/doi.rs b/src/games/doi.rs index f5f8d69..53ccc0d 100644 --- a/src/games/doi.rs +++ b/src/games/doi.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::DOI.as_app(), None, None)?; + }, SteamApp::DOI.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/dst.rs b/src/games/dst.rs index 012f141..be27ba4 100644 --- a/src/games/dst.rs +++ b/src/games/dst.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27016, Some(port) => port - }, SteamID::DST.as_app(), None, None)?; + }, SteamApp::DST.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/gm.rs b/src/games/gm.rs index 7040c28..ca15b7b 100644 --- a/src/games/gm.rs +++ b/src/games/gm.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::GM.as_app(), None, None)?; + }, SteamApp::GM.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/hl2dm.rs b/src/games/hl2dm.rs index c45741e..187eb21 100644 --- a/src/games/hl2dm.rs +++ b/src/games/hl2dm.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::HL2DM.as_app(), None, None)?; + }, SteamApp::HL2DM.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/hldms.rs b/src/games/hldms.rs index 862c5e3..8049140 100644 --- a/src/games/hldms.rs +++ b/src/games/hldms.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::HLDMS.as_app(), None, None)?; + }, SteamApp::HLDMS.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/ins.rs b/src/games/ins.rs index 82341b3..819ee26 100644 --- a/src/games/ins.rs +++ b/src/games/ins.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::INS.as_app(), None, None)?; + }, SteamApp::INS.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/insmic.rs b/src/games/insmic.rs index cf31b69..9678a06 100644 --- a/src/games/insmic.rs +++ b/src/games/insmic.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::INSMIC.as_app(), None, None)?; + }, SteamApp::INSMIC.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/inss.rs b/src/games/inss.rs index d57c036..2f009f4 100644 --- a/src/games/inss.rs +++ b/src/games/inss.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27131, Some(port) => port - }, SteamID::INSS.as_app(), None, None)?; + }, SteamApp::INSS.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/l4d.rs b/src/games/l4d.rs index 58a861c..0bb98c6 100644 --- a/src/games/l4d.rs +++ b/src/games/l4d.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::L4D.as_app(), None, None)?; + }, SteamApp::L4D.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/l4d2.rs b/src/games/l4d2.rs index 23dded8..3fb161f 100644 --- a/src/games/l4d2.rs +++ b/src/games/l4d2.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::L4D2.as_app(), None, None)?; + }, SteamApp::L4D2.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/ohd.rs b/src/games/ohd.rs index c52c40b..245a05f 100644 --- a/src/games/ohd.rs +++ b/src/games/ohd.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27005, Some(port) => port - }, SteamID::OHD.as_app(), None, None)?; + }, SteamApp::OHD.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/onset.rs b/src/games/onset.rs index 1f82d52..c5b40bd 100644 --- a/src/games/onset.rs +++ b/src/games/onset.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 7776, Some(port) => port - }, SteamID::ONSET.as_app(), None, None)?; + }, SteamApp::ONSET.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/pz.rs b/src/games/pz.rs index 2188145..2a02a0a 100644 --- a/src/games/pz.rs +++ b/src/games/pz.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 16261, Some(port) => port - }, SteamID::PZ.as_app(), None, None)?; + }, SteamApp::PZ.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/ror2.rs b/src/games/ror2.rs index 9bb5e0d..625cf0a 100644 --- a/src/games/ror2.rs +++ b/src/games/ror2.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27016, Some(port) => port - }, SteamID::ROR2.as_app(), None, None)?; + }, SteamApp::ROR2.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/rust.rs b/src/games/rust.rs index 8f0e5a9..32845e6 100644 --- a/src/games/rust.rs +++ b/src/games/rust.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::RUST.as_app(), None, None)?; + }, SteamApp::RUST.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/sc.rs b/src/games/sc.rs index 7ab933d..27d1ae0 100644 --- a/src/games/sc.rs +++ b/src/games/sc.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::SC.as_app(), None, None)?; + }, SteamApp::SC.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/sdtd.rs b/src/games/sdtd.rs index 7ca1ec6..3d3db26 100644 --- a/src/games/sdtd.rs +++ b/src/games/sdtd.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 26900, Some(port) => port - }, SteamID::SDTD.as_app(), None, None)?; + }, SteamApp::SDTD.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/tf.rs b/src/games/tf.rs index 730573b..6e3fb5d 100644 --- a/src/games/tf.rs +++ b/src/games/tf.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27016, Some(port) => port - }, SteamID::TF.as_app(), None, None)?; + }, SteamApp::TF.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/tf2.rs b/src/games/tf2.rs index ba00201..79d9379 100644 --- a/src/games/tf2.rs +++ b/src/games/tf2.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::TF2.as_app(), None, None)?; + }, SteamApp::TF2.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/tfc.rs b/src/games/tfc.rs index aa8eef2..125f7e9 100644 --- a/src/games/tfc.rs +++ b/src/games/tfc.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::TFC.as_app(), None, None)?; + }, SteamApp::TFC.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/games/ts.rs b/src/games/ts.rs index 4809619..78d0143 100644 --- a/src/games/ts.rs +++ b/src/games/ts.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{Server, ServerPlayer, get_optional_extracted_data, SteamID}; +use crate::protocols::valve::{Server, ServerPlayer, get_optional_extracted_data, SteamApp}; #[derive(Debug)] pub struct TheShipPlayer { @@ -85,7 +85,7 @@ pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::TS.as_app(), None, None)?; + }, SteamApp::TS.as_engine(), None, None)?; Ok(Response::new_from_valve_response(valve_response)) } diff --git a/src/games/unturned.rs b/src/games/unturned.rs index 4d9c9b9..2871101 100644 --- a/src/games/unturned.rs +++ b/src/games/unturned.rs @@ -1,12 +1,12 @@ use crate::GDResult; use crate::protocols::valve; -use crate::protocols::valve::{game, SteamID}; +use crate::protocols::valve::{game, SteamApp}; pub fn query(address: &str, port: Option) -> GDResult { let valve_response = valve::query(address, match port { None => 27015, Some(port) => port - }, SteamID::UNTURNED.as_app(), None, None)?; + }, SteamApp::UNTURNED.as_engine(), None, None)?; Ok(game::Response::new_from_valve_response(valve_response)) } diff --git a/src/protocols/valve/protocol.rs b/src/protocols/valve/protocol.rs index d2c8c5c..258be29 100644 --- a/src/protocols/valve/protocol.rs +++ b/src/protocols/valve/protocol.rs @@ -4,7 +4,7 @@ use crate::GDResult; use crate::bufferer::{Bufferer, Endianess}; use crate::GDError::{BadGame, Decompress, UnknownEnumCast}; use crate::protocols::types::TimeoutSettings; -use crate::protocols::valve::{App, ModData, SteamID}; +use crate::protocols::valve::{Engine, ModData, SteamApp}; use crate::protocols::valve::types::{Environment, ExtraData, GatheringSettings, Request, Response, Server, ServerInfo, ServerPlayer, TheShip}; use crate::socket::{Socket, UdpSocket}; use crate::utils::u8_lower_upper; @@ -77,18 +77,18 @@ struct SplitPacket { } impl SplitPacket { - fn new(app: &App, protocol: u8, buffer: &mut Bufferer) -> GDResult { + fn new(engine: &Engine, protocol: u8, buffer: &mut Bufferer) -> GDResult { let header = buffer.get_u32()?; let id = buffer.get_u32()?; - let (total, number, size, compressed, decompressed_size, uncompressed_crc32) = match app { - App::GoldSrc(_) => { + let (total, number, size, compressed, decompressed_size, uncompressed_crc32) = match engine { + Engine::GoldSrc(_) => { let (lower, upper) = u8_lower_upper(buffer.get_u8()?); (lower, upper, 0, false, None, None) } - App::Source(_) => { + Engine::Source(_) => { let total = buffer.get_u8()?; let number = buffer.get_u8()?; - let size = match protocol == 7 && (*app == SteamID::CSS.as_app()) { //certain apps with protocol = 7 doesnt have this field + let size = match protocol == 7 && (*engine == SteamApp::CSS.as_engine()) { //certain apps with protocol = 7 dont have this field false => buffer.get_u16()?, true => 1248 }; @@ -155,20 +155,20 @@ impl ValveProtocol { }) } - fn receive(&mut self, app: &App, protocol: u8, buffer_size: usize) -> GDResult { + fn receive(&mut self, engine: &Engine, protocol: u8, buffer_size: usize) -> GDResult { let data = self.socket.receive(Some(buffer_size))?; let mut buffer = Bufferer::new_with_data(Endianess::Little, &data); let header = buffer.get_u8()?; buffer.move_position_backward(1); if header == 0xFE { //the packet is split - let mut main_packet = SplitPacket::new(&app, protocol, &mut buffer)?; + let mut main_packet = SplitPacket::new(&engine, protocol, &mut buffer)?; let mut chunk_packets = Vec::with_capacity((main_packet.total - 1) as usize); for _ in 1..main_packet.total { let new_data = self.socket.receive(Some(buffer_size))?; buffer = Bufferer::new_with_data(Endianess::Little, &new_data); - let chunk_packet = SplitPacket::new(&app, protocol, &mut buffer)?; + let chunk_packet = SplitPacket::new(&engine, protocol, &mut buffer)?; chunk_packets.push(chunk_packet); } @@ -187,11 +187,11 @@ impl ValveProtocol { } /// Ask for a specific request only. - fn get_request_data(&mut self, app: &App, protocol: u8, kind: Request) -> GDResult { + fn get_request_data(&mut self, engine: &Engine, protocol: u8, kind: Request) -> GDResult { let request_initial_packet = Packet::initial(kind).to_bytes(); self.socket.send(&request_initial_packet)?; - let packet = self.receive(app, protocol, PACKET_SIZE)?; + let packet = self.receive(engine, protocol, PACKET_SIZE)?; if packet.kind != 0x41 { //'A' let data = packet.payload.clone(); @@ -203,7 +203,7 @@ impl ValveProtocol { self.socket.send(&challenge_packet)?; - let data = self.receive(app, protocol, PACKET_SIZE)?.payload; + let data = self.receive(engine, protocol, PACKET_SIZE)?.payload; Ok(Bufferer::new_with_data(Endianess::Little, &data)) } @@ -267,10 +267,10 @@ impl ValveProtocol { } /// Get the server information's. - fn get_server_info(&mut self, app: &App) -> GDResult { - let mut buffer = self.get_request_data(&app, 0, Request::INFO)?; + fn get_server_info(&mut self, engine: &Engine) -> GDResult { + let mut buffer = self.get_request_data(&engine, 0, Request::INFO)?; - if let App::GoldSrc(force) = app { + if let Engine::GoldSrc(force) = engine { if *force { return ValveProtocol::get_goldsrc_server_info(&mut buffer); } @@ -299,7 +299,7 @@ impl ValveProtocol { }; let has_password = buffer.get_u8()? == 1; let vac_secured = buffer.get_u8()? == 1; - let the_ship = match *app == SteamID::TS.as_app() { + let the_ship = match *engine == SteamApp::TS.as_engine() { false => None, true => Some(TheShip { mode: buffer.get_u8()?, @@ -366,8 +366,8 @@ impl ValveProtocol { } /// Get the server player's. - fn get_server_players(&mut self, app: &App, protocol: u8) -> GDResult> { - let mut buffer = self.get_request_data(&app, protocol, Request::PLAYERS)?; + fn get_server_players(&mut self, engine: &Engine, protocol: u8) -> GDResult> { + let mut buffer = self.get_request_data(&engine, protocol, Request::PLAYERS)?; let count = buffer.get_u8()? as usize; let mut players: Vec = Vec::with_capacity(count); @@ -379,11 +379,11 @@ impl ValveProtocol { let score = buffer.get_u32()?; let duration = buffer.get_f32()?; - let deaths = match *app == SteamID::TS.as_app() { + let deaths = match *engine == SteamApp::TS.as_engine() { false => None, true => Some(buffer.get_u32()?) }; - let money = match *app == SteamID::TS.as_app() { + let money = match *engine == SteamApp::TS.as_engine() { false => None, true => Some(buffer.get_u32()?) }; @@ -403,8 +403,8 @@ impl ValveProtocol { } /// Get the server's rules. - fn get_server_rules(&mut self, app: &App, protocol: u8) -> GDResult> { - let mut buffer = self.get_request_data(&app, protocol, Request::RULES)?; + fn get_server_rules(&mut self, engine: &Engine, protocol: u8) -> GDResult> { + let mut buffer = self.get_request_data(&engine, protocol, Request::RULES)?; let count = buffer.get_u16()? as usize; let mut rules: HashMap = HashMap::with_capacity(count); @@ -416,7 +416,7 @@ impl ValveProtocol { rules.insert(name, value); } - if *app == SteamID::ROR2.as_app() { + if *engine == SteamApp::ROR2.as_engine() { rules.remove("Test"); } @@ -426,20 +426,30 @@ impl ValveProtocol { /// Query a server by providing the address, the port, the app, gather and timeout settings. /// Providing None to the settings results in using the default values for them (GatherSettings::[default](GatheringSettings::default), TimeoutSettings::[default](TimeoutSettings::default)). -pub fn query(address: &str, port: u16, app: App, gather_settings: Option, timeout_settings: Option) -> GDResult { +pub fn query(address: &str, port: u16, engine: Engine, gather_settings: Option, timeout_settings: Option) -> GDResult { let response_gather_settings = gather_settings.unwrap_or(GatheringSettings::default()); - get_response(address, port, app, response_gather_settings, timeout_settings) + get_response(address, port, engine, response_gather_settings, timeout_settings) } -fn get_response(address: &str, port: u16, app: App, gather_settings: GatheringSettings, timeout_settings: Option) -> GDResult { +fn get_response(address: &str, port: u16, engine: Engine, gather_settings: GatheringSettings, timeout_settings: Option) -> GDResult { let mut client = ValveProtocol::new(address, port, timeout_settings)?; - let info = client.get_server_info(&app)?; + let info = client.get_server_info(&engine)?; let protocol = info.protocol; - if let App::Source(source_app) = &app { - if let Some(appid) = source_app { - if *appid != info.appid { + if let Engine::Source(source_app) = &engine { + if let Some(appids) = source_app { + let mut is_specified_id = false; + + if appids.0 == info.appid { + is_specified_id = true; + } else if let Some(dedicated_appid) = appids.1 { + if dedicated_appid == info.appid { + is_specified_id = true; + } + } + + if !is_specified_id { return Err(BadGame(format!("AppId: {}", info.appid))); } } @@ -449,11 +459,11 @@ fn get_response(address: &str, port: u16, app: App, gather_settings: GatheringSe info, players: match gather_settings.players { false => None, - true => Some(client.get_server_players(&app, protocol)?) + true => Some(client.get_server_players(&engine, protocol)?) }, rules: match gather_settings.rules { false => None, - true => Some(client.get_server_rules(&app, protocol)?) + true => Some(client.get_server_rules(&engine, protocol)?) } }) } diff --git a/src/protocols/valve/types.rs b/src/protocols/valve/types.rs index 1074b45..8c24f9c 100644 --- a/src/protocols/valve/types.rs +++ b/src/protocols/valve/types.rs @@ -135,114 +135,161 @@ pub(crate) enum Request { RULES = 0x56 } -/// Supported steam apps id's -#[repr(u32)] +/// Supported steam apps #[derive(PartialEq, Clone)] -pub enum SteamID { +pub enum SteamApp { /// Counter-Strike - CS = 10, + CS, /// Team Fortress Classic - TFC = 20, + TFC, /// Day of Defeat - DOD = 30, + DOD, /// Counter-Strike: Condition Zero - CSCZ = 80, + CSCZ, /// Counter-Strike: Source - CSS = 240, + CSS, /// Day of Defeat: Source - DODS = 300, + DODS, /// Half-Life 2 Deathmatch - HL2DM = 320, + HL2DM, /// Half-Life Deathmatch: Source - HLDMS = 360, + HLDMS, /// Team Fortress 2 - TF2 = 440, + TF2, /// Left 4 Dead - L4D = 500, + L4D, /// Left 4 Dead - L4D2 = 550, + L4D2, /// Alien Swarm - ALIENS = 630, + ALIENS, /// Counter-Strike: Global Offensive - CSGO = 730, + CSGO, /// The Ship - TS = 2400, + TS, /// Garry's Mod - GM = 4000, + GM, /// Age of Chivalry - AOC = 17510, + AOC, /// Insurgency: Modern Infantry Combat - INSMIC = 17700, + INSMIC, /// ARMA 2: Operation Arrowhead - ARMA2OA = 33930, + ARMA2OA, /// Project Zomboid - PZ = 108600, + PZ, /// Insurgency - INS = 222880, + INS, /// Sven Co-op - SC = 225840, + SC, /// 7 Days To Die - SDTD = 251570, + SDTD, /// Rust - RUST = 252490, + RUST, /// Vallistic Overkill - BO = 296300, + BO, /// Don't Starve Together - DST = 322320, + DST, /// BrainBread 2 - BB2 = 346330, + BB2, /// Codename CURE - CCURE = 355180, + CCURE, /// Black Mesa - BM = 362890, + BM, /// Colony Survival - COSU = 366090, + COSU, /// Avorion - AVORION = 445220, + AVORION, /// Day of Infamy - DOI = 447820, - /// The Forrest - TF = 556450, //this is the id for the dedicated server, for the game its 242760 + DOI, + /// The Forest + TF, /// Unturned - UNTURNED = 304930, + UNTURNED, /// ARK: Survival Evolved - ASE = 346110, + ASE, /// Battalion 1944 - BAT1944 = 489940, + BAT1944, /// Insurgency: Sandstorm - INSS = 581320, + INSS, /// Alien Swarm: Reactive Drop - ASRD = 563560, + ASRD, /// Risk of Rain 2 - ROR2 = 632360, + ROR2, /// Operation: Harsh Doorstop - OHD = 950900, // this is the id for the dedicated server, for the game its 736590 + OHD, /// Onset - ONSET = 1105810, + ONSET, } -impl SteamID { - /// Get ID as App (the engine is specified). - pub fn as_app(&self) -> App { +impl SteamApp { + /// Get the specified app as engine. + pub fn as_engine(&self) -> Engine { match self { - SteamID::CS | SteamID::TFC | SteamID::DOD | SteamID::CSCZ | SteamID::SC => App::GoldSrc(false), - x => App::Source(Some(x.clone() as u32)) + SteamApp::CS => Engine::GoldSrc(false), //10 + SteamApp::TFC => Engine::GoldSrc(false), //20 + SteamApp::DOD => Engine::GoldSrc(false), //30 + SteamApp::CSCZ => Engine::GoldSrc(false), //80 + SteamApp::CSS => Engine::new_source(240), + SteamApp::DODS => Engine::new_source(300), + SteamApp::HL2DM => Engine::new_source(320), + SteamApp::HLDMS => Engine::new_source(360), + SteamApp::TF2 => Engine::new_source(440), + SteamApp::L4D => Engine::new_source(500), + SteamApp::L4D2 => Engine::new_source(550), + SteamApp::ALIENS => Engine::new_source(630), + SteamApp::CSGO => Engine::new_source(730), + SteamApp::TS => Engine::new_source(2400), + SteamApp::GM => Engine::new_source(4000), + SteamApp::AOC => Engine::new_source(17510), + SteamApp::INSMIC => Engine::new_source(17700), + SteamApp::ARMA2OA => Engine::new_source(33930), + SteamApp::PZ => Engine::new_source(108600), + SteamApp::INS => Engine::new_source(222880), + SteamApp::SC => Engine::GoldSrc(false), //225840 + SteamApp::SDTD => Engine::new_source(251570), + SteamApp::RUST => Engine::new_source(252490), + SteamApp::BO => Engine::new_source(296300), + SteamApp::DST => Engine::new_source(322320), + SteamApp::BB2 => Engine::new_source(346330), + SteamApp::CCURE => Engine::new_source(355180), + SteamApp::BM => Engine::new_source(362890), + SteamApp::COSU => Engine::new_source(366090), + SteamApp::AVORION => Engine::new_source(445220), + SteamApp::DOI => Engine::new_source(447820), + SteamApp::TF => Engine::new_source(556450), + SteamApp::UNTURNED => Engine::new_source(304930), + SteamApp::ASE => Engine::new_source(346110), + SteamApp::BAT1944 => Engine::new_source(489940), + SteamApp::INSS => Engine::new_source(581320), + SteamApp::ASRD => Engine::new_source(563560), + SteamApp::ROR2 => Engine::new_source(632360), + SteamApp::OHD => Engine::new_source_with_dedicated(736590, 950900), + SteamApp::ONSET => Engine::new_source(1105810) } } } -/// App type. +/// Engine type. #[derive(PartialEq, Clone)] -pub enum App { - /// A Source game, the argument represents the wanted response steam app id, if its **None**, - /// let the query find it, if its **Some**, the query fails if the response id is not the - /// specified one. - Source(Option), - /// A GoldSrc game, the argument indicates whether to enforce getting the obsolete A2S_INFO - /// goldsrc response or not. +pub enum Engine { + /// A Source game, the argument represents the possible steam app ids, if its **None**, let + /// the query find it, if its **Some**, the query fails if the response id is not the first + /// one, which is the game app id, or the other one, which is the dedicated server app id. + Source(Option<(u32, Option)>), + /// A GoldSrc game, the argument indicates whether to enforce + /// requesting the obsolete A2S_INFO response or not. GoldSrc(bool) } +impl Engine { + pub fn new_source(appid: u32) -> Self { + Engine::Source(Some((appid, None))) + } + + pub fn new_source_with_dedicated(appid: u32, dedicated_appid: u32) -> Self { + Engine::Source(Some((appid, Some(dedicated_appid)))) + } +} + /// What data to gather, purely used only with the query function. pub struct GatheringSettings { pub players: bool, @@ -298,6 +345,8 @@ pub mod game { pub map: String, /// The name of the game. pub game: String, + /// Server's app id. + pub appid: u32, /// Number of players on the server. pub players_online: u8, /// Details about the server's players (not all players necessarily). @@ -337,6 +386,7 @@ pub mod game { name: response.info.name, map: response.info.map, game: response.info.game, + appid: response.info.appid, players_online: response.info.players_online, players_details: response.players.unwrap_or(vec![]).iter().map(Player::from_valve_response).collect(), players_maximum: response.info.players_maximum,