diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b684fc..e2cea70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,58 @@ Crate: - The enum used for errors, `GDError` has been renamed to `GDErrorKind`. - `GDError` is now a struct that holds its kind, the source and a backtrace. +Generics: +- Renamed `CommonResponseJson`'s `game` field (and the function) to `game_mode`. +- Changed `players_maximum` and `players_online` (and their functions) types from `u64` to `u32`. +- Changed `score` type (and the function) of player from `u32` to `i32`. + +Protocol: +- Valve: +1. Renamed `protocol` to `protocol_version`. +2. Renamed `version` to `game_version`. +3. Renamed `game` to `game_mode`. +4. Changed `score` type of player from `u32` to `i32`. + +- GameSpy (1, 2, 3): +1. Renamed `version` to `game_version`. +2. Changed `players_maximum` and `players_online` (and their functions) types from `usize` to `u32`. + +- GameSpy 1: +1. Changed `score` type of player from `u32` to `i32`. + +- Quake (1, 2): +1. Renamed `game_type` to `game_mode`. + +- Minecraft Java +1. Renamed `version_protocol` to `protocol_version`. +2. Renamed `version_name` to `game_version`. +3. Renamed `players_sample` to `players`. + +- Minecraft Bedrock +1. Renamed `version_protocol` to `protocol_version`. + +- The Ship: +1. Renamed `protocol` to `protocol_version`. +2. Renamed `max_players` to `players_maximum` and changed its type from `u64` to `u32`. +3. Renamed `bots` to `players_bots`. and changed its type from `u64` to `u32`. +4. Renamed `players` to `players_online`. +5. Renamed `players_details` to `players`. +6. Renamed `game` to `game_mode`. +7. Added field `game_version`. +8. Changed `players_bots` type from `Option` to `Option`. +9. Changed `score` type of player from `u32` to `i32`. + +- Frontlines: Fuel of War: +1. Renamed `game_mode` to `game`. +2. Renamed `version` to `game_version`. +3. Renamed `protocol` to `protocol_version`. +4. Renamed `game` to `game_mode`. +5. Changed `players_maximum` and `players_minimum` types from `usize` to `u32`. + +- Just Cause 2: Multiplayer: +1. Renamed `version` to `game_version`. +2. Changed `players_maximum` and `players_minimum` types from `usize` to `u32`. + # 0.3.0 - 18/07/2023 ### Changes: Protocols: diff --git a/RESPONSES.md b/RESPONSES.md index 7196df4..aa1eeaa 100644 --- a/RESPONSES.md +++ b/RESPONSES.md @@ -5,50 +5,50 @@ In the case that a field that performs the same function exists in the current c # Response table -| Field | Generic | GameSpy(1) | GameSpy(2) | GameSpy(3) | Minecraft(Java) | Minecraft(Bedrock) | Valve | Quake | Proprietary: FFOW | Proprietary: TheShip | -| :--------------- | ---------------- | ------------ | ------------ | ------------ | ----------------- | -------------------- | -------- | -------- | -------- | --------- | -| name | `Option` | `String` | `String` | `String` | | `String` | `String` | `String` | `String` | `String` | -| description | `Option` | | | | `String` | | | | `String` | | -| game | `Option` | `String` (game_type) | | `String` (game_type) | | `Option` (game_mode) | `String` | | `String` (game_mode) | `String` | -| game_version | `Option` | `String` | | `String` | `String` (version_name) | | `String` (version) | `String` (version) | `String` (version) | `String` (version) | -| map | `Option` | `String` | `String` | `String` | | `Option` | `String` | `String` | `String` | `String` | -| players_maxmimum | `u64` | `usize` | `usize` | `usize` | `u32` | `u32` | `u8` | `u8` | `u8` | `u8` (max_players) | -| players_online | `u64` | `usize` | `usize` | `usize` | `u32` | `u32` | `u8` | `u8` | `u8` | `u8` (players) | -| players_bots | `Option` | | | | | | `u8` | | | `u8` (bots) | -| has_password | `Option` | `bool` | `bool` | `bool` | | | `bool` | | `bool` | `bool` | -| map_title | | `Option` | | | | | | | | | -| admin_contact | | `Option` | | | | | | | | | -| admin_name | | `Option` | | | | | | | | | -| players_minimum | | `Option` | `Option` | `Option` | | | | | | | -| players | | `Vec` | `Vec` | `Vec` | | | `Option>` | `Vec

` | | `Vec` (player_details) | -| tournament | | `bool` | |`bool` | | | | | | | -| unused_entries | | `Hashmap` | | `HashMap` | | | `Option` (extra_data) | `HashMap` | | | -| teams | | | `Vec` | `Vec` | | | | | | | -| version_protocol | | | | | `i32` | `String` | `u8` (protocol) | | `u8` (protocol) | `u8` (protocol) | -| players_sample | | | | | `Option>` | | | | | | -| favicon | | | | | `Option` | | | | | | -| previews_chat | | | | | `Option` | | | | | | -| enforces_secure_chat | | | | | `Option` | | | | | | -| server_type | | | | | `Server` | `Server` | `Server` | | | `Server` | -| edition | | | | | | `String` | | | | | -| id | | | | | | `String` | | | | | -| rules | | | | | | | `Option>` | | | `HashMap` | -| folder | | | | | | | `String` | | | | -| appid | | | | | | | `u32` | | | | -| environment_type | | | | | | | `Environment` | | `Environment` | | -| vac_secured | | | | | | | `bool` | | `bool` | `bool` | -| the_ship | | | | | | | `Option` | | | | -| is_mod | | | | | | | `bool` | | | | -| mod_data | | | | | | | `Option` | | | | -| active_mod | | | | | | | | | `String` | | -| round | | | | | | | | | `u8` | | -| rounds_maximum | | | | | | | | | `u8` | | -| time_left | | | | | | | | | `u16` | | -| port | | | | | | | | | | `Option` | -| steam_id | | | | | | | | | | `Option` | -| tv_port | | | | | | | | | | `Option` | -| tv_name | | | | | | | | | | `Option` | -| keywords | | | | | | | | | | `Option` | -| mode | | | | | | | | | | `u8` | -| witnesses | | | | | | | | | | `u8` | -| duration | | | | | | | | | | `u8` | +| Field | Generic | GameSpy(1) | GameSpy(2) | GameSpy(3) | Minecraft(Java) | Minecraft(Bedrock) | Valve | Quake | Proprietary: FFOW | Proprietary: TheShip | Proprietary: JC2MP | +|:---------------------|------------------|---------------------------|---------------|---------------------------|-----------------------|----------------------|----------------------------------|---------------------------|-------------------|--------------------------|--------------------| +| name | `Option` | `String` | `String` | `String` | | `String` | `String` | `String` | `String` | `String` | `String` | +| description | `Option` | | | | `String` | | | | `String` | | `String` | +| game_mode | `Option` | `String` | | `String` | | `Option` | `String` | | `String` | `String` | | +| game_version | `Option` | `String` | | `String` | `String` | | `String` | `String` | `String` | `String` | `String` | +| map | `Option` | `String` | `String` | `String` | | `Option` | `String` | `String` | `String` | `String` | | +| players_maxmimum | `u32` | `u32` | `u32` | `u32` | `u32` | `u32` | `u8` | `u8` | `u8` | `u8` | `u32` | +| players_online | `u32` | `u32` | `u32` | `u32` | `u32` | `u32` | `u8` | `u8` | `u8` | `u8` | `u32` | +| players_bots | `Option` | | | | | | `u8` | | | `u8` | | +| has_password | `Option` | `bool` | `bool` | `bool` | | | `bool` | | `bool` | `bool` | `bool` | +| players_minimum | | `Option` | `Option` | `Option` | | | | | | | | +| players | | `Vec` | `Vec` | `Vec` | `Option>` | | `Option>` | `Vec

` | | `Vec` | `Vec` | +| tournament | | `bool` | | `bool` | | | | | | | | +| unused_entries | | `Hashmap` | | `HashMap` | | | | `HashMap` | | | | +| teams | | | `Vec` | `Vec` | | | | | | | | +| protocol_version | | | | | `i32` | `String` | `u8` | | `u8` | `u8` | | +| server_type | | | | | `Server` | `Server` | `Server` | | | `Server` | | +| rules | | | | | | | `Option>` | | | `HashMap` | | +| environment_type | | | | | | | `Environment` | | `Environment` | | | +| vac_secured | | | | | | | `bool` | | `bool` | `bool` | | +| map_title | | `Option` | | | | | | | | | | +| admin_contact | | `Option` | | | | | | | | | | +| admin_name | | `Option` | | | | | | | | | | +| favicon | | | | | `Option` | | | | | | | +| previews_chat | | | | | `Option` | | | | | | | +| enforces_secure_chat | | | | | `Option` | | | | | | | +| edition | | | | | | `String` | | | | | | +| id | | | | | | `String` | | | | | | +| the_ship | | | | | | | `Option` | | | | | +| is_mod | | | | | | | `bool` | | | | | +| extra_data | | | | | | | `Option` | | | | | +| mod_data | | | | | | | `Option` | | | | | +| folder | | | | | | | `String` | | | | | +| appid | | | | | | | `u32` | | | | | +| active_mod | | | | | | | | | `String` | | | +| round | | | | | | | | | `u8` | | | +| rounds_maximum | | | | | | | | | `u8` | | | +| time_left | | | | | | | | | `u16` | | | +| port | | | | | | | | | | `Option` | | +| steam_id | | | | | | | | | | `Option` | | +| tv_port | | | | | | | | | | `Option` | | +| tv_name | | | | | | | | | | `Option` | | +| keywords | | | | | | | | | | `Option` | | +| mode | | | | | | | | | | `u8` | | +| witnesses | | | | | | | | | | `u8` | | +| duration | | | | | | | | | | `u8` | | diff --git a/src/games/bat1944.rs b/src/games/bat1944.rs index f5f61cc..a55e56e 100644 --- a/src/games/bat1944.rs +++ b/src/games/bat1944.rs @@ -35,7 +35,7 @@ pub fn query(address: &IpAddr, port: Option) -> GDResult { } if let Some(bat_gamemode) = rules.get("bat_gamemode_s") { - valve_response.info.game = bat_gamemode.clone(); + valve_response.info.game_mode = bat_gamemode.clone(); rules.remove("bat_gamemode_s"); } diff --git a/src/games/ffow.rs b/src/games/ffow.rs index 4546ed2..9cbbdfc 100644 --- a/src/games/ffow.rs +++ b/src/games/ffow.rs @@ -13,17 +13,17 @@ use std::net::{IpAddr, SocketAddr}; #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct Response { /// Protocol used by the server. - pub protocol: u8, + pub protocol_version: u8, /// Name of the server. pub name: String, /// Map name. pub active_mod: String, /// Running game mode. pub game_mode: String, + /// The version that the server is running on. + pub game_version: String, /// Description of the server. pub description: String, - /// The version that the server is running on. - pub version: String, /// Current map. pub map: String, /// Number of players on the server. @@ -50,13 +50,13 @@ impl CommonResponse for Response { fn as_original(&self) -> GenericResponse { GenericResponse::FFOW(self) } fn name(&self) -> Option<&str> { Some(&self.name) } - fn game(&self) -> Option<&str> { Some(&self.game_mode) } + fn game_mode(&self) -> Option<&str> { Some(&self.game_mode) } fn description(&self) -> Option<&str> { Some(&self.description) } - fn game_version(&self) -> Option<&str> { Some(&self.version) } + fn game_version(&self) -> Option<&str> { Some(&self.game_version) } fn map(&self) -> Option<&str> { Some(&self.map) } fn has_password(&self) -> Option { Some(self.has_password) } - fn players_maximum(&self) -> u64 { self.players_maximum.into() } - fn players_online(&self) -> u64 { self.players_online.into() } + fn players_maximum(&self) -> u32 { self.players_maximum.into() } + fn players_online(&self) -> u32 { self.players_online.into() } } pub fn query(address: &IpAddr, port: Option) -> GDResult { query_with_timeout(address, port, None) } @@ -79,13 +79,13 @@ pub fn query_with_timeout( let mut buffer = Buffer::::new(&data); - let protocol = buffer.read::()?; + let protocol_version = buffer.read::()?; let name = buffer.read_string::(None)?; let map = buffer.read_string::(None)?; let active_mod = buffer.read_string::(None)?; let game_mode = buffer.read_string::(None)?; let description = buffer.read_string::(None)?; - let version = buffer.read_string::(None)?; + let game_version = buffer.read_string::(None)?; buffer.move_cursor(2)?; let players_online = buffer.read::()?; let players_maximum = buffer.read::()?; @@ -99,12 +99,12 @@ pub fn query_with_timeout( let time_left = buffer.read::()?; Ok(Response { - protocol, + protocol_version, name, active_mod, game_mode, + game_version, description, - version, map, players_online, players_maximum, diff --git a/src/games/jc2mp.rs b/src/games/jc2mp.rs index a1cfe49..2adfa0f 100644 --- a/src/games/jc2mp.rs +++ b/src/games/jc2mp.rs @@ -27,28 +27,24 @@ impl CommonPlayer for Player { #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct Response { - version: String, + game_version: String, description: String, name: String, has_password: bool, players: Vec, - players_maximum: usize, - players_online: usize, + players_maximum: u32, + players_online: u32, } impl CommonResponse for Response { fn as_original(&self) -> GenericResponse { GenericResponse::JC2MP(self) } - fn game_version(&self) -> Option<&str> { Some(&self.version) } + fn game_version(&self) -> Option<&str> { Some(&self.game_version) } fn description(&self) -> Option<&str> { Some(&self.description) } fn name(&self) -> Option<&str> { Some(&self.name) } fn has_password(&self) -> Option { Some(self.has_password) } - fn players_maximum(&self) -> u64 { - // If usize doesn't fit in u64 silently return 0 as this is extremely unlikely - // for a player count - self.players_maximum.try_into().unwrap_or(0) - } - fn players_online(&self) -> u64 { self.players_online.try_into().unwrap_or(0) } + fn players_maximum(&self) -> u32 { self.players_maximum } + fn players_online(&self) -> u32 { self.players_online } fn players(&self) -> Option> { Some( @@ -113,10 +109,10 @@ pub fn query_with_timeout( false => reported_players, } } - }; + } as u32; Ok(Response { - version: server_vars + game_version: server_vars .remove("version") .ok_or(GDErrorKind::PacketBad)?, description: server_vars diff --git a/src/games/ts.rs b/src/games/ts.rs index d28552f..a92e141 100644 --- a/src/games/ts.rs +++ b/src/games/ts.rs @@ -17,7 +17,7 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, PartialEq, PartialOrd)] pub struct TheShipPlayer { pub name: String, - pub score: u32, + pub score: i32, pub duration: f32, pub deaths: u32, pub money: u32, @@ -39,24 +39,24 @@ impl CommonPlayer for TheShipPlayer { fn as_original(&self) -> GenericPlayer { GenericPlayer::TheShip(self) } fn name(&self) -> &str { &self.name } - fn score(&self) -> Option { Some(self.score) } + fn score(&self) -> Option { Some(self.score) } } #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[derive(Debug, Clone, PartialEq)] pub struct Response { - pub protocol: u8, + pub protocol_version: 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 game_mode: String, + pub game_version: String, + pub players: Vec, + pub players_online: u8, + pub players_maximum: u8, + pub players_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, @@ -73,15 +73,15 @@ impl CommonResponse for Response { fn name(&self) -> Option<&str> { Some(&self.name) } fn map(&self) -> Option<&str> { Some(&self.map) } - fn game(&self) -> Option<&str> { Some(&self.game) } - fn players_maximum(&self) -> u64 { self.max_players.into() } - fn players_online(&self) -> u64 { self.players.into() } - fn players_bots(&self) -> Option { Some(self.bots.into()) } + fn game_mode(&self) -> Option<&str> { Some(&self.game_mode) } + fn players_maximum(&self) -> u32 { self.players_maximum.into() } + fn players_online(&self) -> u32 { self.players_online.into() } + fn players_bots(&self) -> Option { Some(self.players_bots.into()) } fn has_password(&self) -> Option { Some(self.has_password) } fn players(&self) -> Option> { Some( - self.players_details + self.players .iter() .map(|p| p as &dyn CommonPlayer) .collect(), @@ -96,23 +96,23 @@ impl Response { let the_unwrapped_ship = response.info.the_ship.unwrap(); Self { - protocol: response.info.protocol, + protocol_version: response.info.protocol_version, name: response.info.name, map: response.info.map, - game: response.info.game, - players: response.info.players_online, - players_details: response + game_mode: response.info.game_mode, + game_version: response.info.game_version, + players_online: response.info.players_online, + players: response .players .unwrap() .iter() .map(TheShipPlayer::new_from_valve_player) .collect(), - max_players: response.info.players_maximum, - bots: response.info.players_bots, + players_maximum: response.info.players_maximum, + players_bots: response.info.players_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, diff --git a/src/protocols/gamespy/protocols/one/protocol.rs b/src/protocols/gamespy/protocols/one/protocol.rs index a2737bb..ec7d4f8 100644 --- a/src/protocols/gamespy/protocols/one/protocol.rs +++ b/src/protocols/gamespy/protocols/one/protocol.rs @@ -87,8 +87,8 @@ fn get_server_values( Ok(server_values) } -fn extract_players(server_vars: &mut HashMap, players_maximum: usize) -> GDResult> { - let mut players_data: Vec> = Vec::with_capacity(players_maximum); +fn extract_players(server_vars: &mut HashMap, players_maximum: u32) -> GDResult> { + let mut players_data: Vec> = Vec::with_capacity(players_maximum as usize); server_vars.retain(|key, value| { let split: Vec<&str> = key.split('_').collect(); @@ -201,7 +201,7 @@ pub fn query_vars( pub fn query(address: &SocketAddr, timeout_settings: Option) -> GDResult { let mut server_vars = query_vars(address, timeout_settings)?; - let players_maximum = server_vars + let players_maximum: u32 = server_vars .remove("maxplayers") .ok_or(GDErrorKind::PacketBad)? .parse() @@ -226,14 +226,14 @@ pub fn query(address: &SocketAddr, timeout_settings: Option) -> .remove("AdminName") .or_else(|| server_vars.remove("admin")), has_password: has_password(&mut server_vars)?, - game_type: server_vars + game_mode: server_vars .remove("gametype") .ok_or(GDErrorKind::PacketBad)?, game_version: server_vars .remove("gamever") .ok_or(GDErrorKind::PacketBad)?, players_maximum, - players_online: players.len(), + players_online: players.len() as u32, players_minimum, players, tournament: server_vars diff --git a/src/protocols/gamespy/protocols/one/types.rs b/src/protocols/gamespy/protocols/one/types.rs index f21f83c..a6e3aea 100644 --- a/src/protocols/gamespy/protocols/one/types.rs +++ b/src/protocols/gamespy/protocols/one/types.rs @@ -18,7 +18,7 @@ pub struct Player { pub face: String, pub skin: String, pub mesh: String, - pub score: u32, + pub score: i32, pub deaths: Option, pub health: Option, pub secret: bool, @@ -28,7 +28,7 @@ impl CommonPlayer for Player { fn as_original(&self) -> GenericPlayer { GenericPlayer::Gamespy(VersionedPlayer::One(self)) } fn name(&self) -> &str { &self.name } - fn score(&self) -> Option { Some(self.score) } + fn score(&self) -> Option { Some(self.score) } } /// A query response. @@ -41,10 +41,10 @@ pub struct Response { pub admin_contact: Option, pub admin_name: Option, pub has_password: bool, - pub game_type: String, + pub game_mode: String, pub game_version: String, - pub players_maximum: usize, - pub players_online: usize, + pub players_maximum: u32, + pub players_online: u32, pub players_minimum: Option, pub players: Vec, pub tournament: bool, @@ -57,10 +57,10 @@ impl CommonResponse for Response { fn name(&self) -> Option<&str> { Some(&self.name) } fn map(&self) -> Option<&str> { Some(&self.map) } fn has_password(&self) -> Option { Some(self.has_password) } - fn game(&self) -> Option<&str> { Some(&self.game_type) } + fn game_mode(&self) -> Option<&str> { Some(&self.game_mode) } fn game_version(&self) -> Option<&str> { Some(&self.game_version) } - fn players_maximum(&self) -> u64 { self.players_maximum.try_into().unwrap_or(0) } - fn players_online(&self) -> u64 { self.players_online.try_into().unwrap_or(0) } + fn players_maximum(&self) -> u32 { self.players_maximum } + fn players_online(&self) -> u32 { self.players_online } fn players(&self) -> Option> { Some( diff --git a/src/protocols/gamespy/protocols/three/protocol.rs b/src/protocols/gamespy/protocols/three/protocol.rs index 23ed7cf..f0f46a8 100644 --- a/src/protocols/gamespy/protocols/three/protocol.rs +++ b/src/protocols/gamespy/protocols/three/protocol.rs @@ -358,7 +358,7 @@ pub fn query(address: &SocketAddr, timeout_settings: Option) -> None => None, Some(v) => Some(v.parse::().map_err(|e| TypeParse.context(e))?), }; - let players_online = match server_vars.remove("numplayers") { + let players_online: u32 = match server_vars.remove("numplayers") { None => players.len(), Some(v) => { let reported_players = v.parse().map_err(|e| TypeParse.context(e))?; @@ -367,7 +367,7 @@ pub fn query(address: &SocketAddr, timeout_settings: Option) -> false => reported_players, } } - }; + } as u32; Ok(Response { name: server_vars @@ -377,7 +377,7 @@ pub fn query(address: &SocketAddr, timeout_settings: Option) -> .remove("mapname") .ok_or(GDErrorKind::PacketBad)?, has_password: has_password(&mut server_vars)?, - game_type: server_vars + game_mode: server_vars .remove("gametype") .ok_or(GDErrorKind::PacketBad)?, game_version: server_vars diff --git a/src/protocols/gamespy/protocols/three/types.rs b/src/protocols/gamespy/protocols/three/types.rs index 7eb40ad..bfb8858 100644 --- a/src/protocols/gamespy/protocols/three/types.rs +++ b/src/protocols/gamespy/protocols/three/types.rs @@ -24,7 +24,7 @@ impl CommonPlayer for Player { } fn name(&self) -> &str { &self.name } - fn score(&self) -> Option { Some(self.score.try_into().unwrap_or(0)) } + fn score(&self) -> Option { Some(self.score) } } /// A team's details @@ -42,10 +42,10 @@ pub struct Response { pub name: String, pub map: String, pub has_password: bool, - pub game_type: String, + pub game_mode: String, pub game_version: String, - pub players_maximum: usize, - pub players_online: usize, + pub players_maximum: u32, + pub players_online: u32, pub players_minimum: Option, pub players: Vec, pub teams: Vec, @@ -59,10 +59,10 @@ impl CommonResponse for Response { fn name(&self) -> Option<&str> { Some(&self.name) } fn map(&self) -> Option<&str> { Some(&self.map) } fn has_password(&self) -> Option { Some(self.has_password) } - fn game(&self) -> Option<&str> { Some(&self.game_type) } + fn game_mode(&self) -> Option<&str> { Some(&self.game_mode) } fn game_version(&self) -> Option<&str> { Some(&self.game_version) } - fn players_maximum(&self) -> u64 { self.players_maximum.try_into().unwrap_or(0) } - fn players_online(&self) -> u64 { self.players_online.try_into().unwrap_or(0) } + fn players_maximum(&self) -> u32 { self.players_maximum } + fn players_online(&self) -> u32 { self.players_online } fn players(&self) -> Option> { Some( diff --git a/src/protocols/gamespy/protocols/two/protocol.rs b/src/protocols/gamespy/protocols/two/protocol.rs index f1c3e55..613315a 100644 --- a/src/protocols/gamespy/protocols/two/protocol.rs +++ b/src/protocols/gamespy/protocols/two/protocol.rs @@ -173,10 +173,10 @@ pub fn query(address: &SocketAddr, timeout_settings: Option) -> false => reported_players, } } - }; + } as u32; let players_minimum = match server_vars.remove("minplayers") { None => None, - Some(v) => Some(v.parse::().map_err(|e| TypeParse.context(e))?), + Some(v) => Some(v.parse::().map_err(|e| TypeParse.context(e))?), }; Ok(Response { diff --git a/src/protocols/gamespy/protocols/two/types.rs b/src/protocols/gamespy/protocols/two/types.rs index 9149688..cbff535 100644 --- a/src/protocols/gamespy/protocols/two/types.rs +++ b/src/protocols/gamespy/protocols/two/types.rs @@ -27,7 +27,7 @@ impl CommonPlayer for Player { fn as_original(&self) -> GenericPlayer { GenericPlayer::Gamespy(VersionedPlayer::Two(self)) } fn name(&self) -> &str { &self.name } - fn score(&self) -> Option { Some(self.score.into()) } + fn score(&self) -> Option { Some(self.score.into()) } } #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -37,9 +37,9 @@ pub struct Response { pub map: String, pub has_password: bool, pub teams: Vec, - pub players_maximum: usize, - pub players_online: usize, - pub players_minimum: Option, + pub players_maximum: u32, + pub players_online: u32, + pub players_minimum: Option, pub players: Vec, pub unused_entries: HashMap, } @@ -50,8 +50,8 @@ impl CommonResponse for Response { fn name(&self) -> Option<&str> { Some(&self.name) } fn map(&self) -> Option<&str> { Some(&self.map) } fn has_password(&self) -> Option { Some(self.has_password) } - fn players_maximum(&self) -> u64 { self.players_maximum.try_into().unwrap_or(0) } - fn players_online(&self) -> u64 { self.players_online.try_into().unwrap_or(0) } + fn players_maximum(&self) -> u32 { self.players_maximum } + fn players_online(&self) -> u32 { self.players_online } fn players(&self) -> Option> { Some( diff --git a/src/protocols/minecraft/protocol/bedrock.rs b/src/protocols/minecraft/protocol/bedrock.rs index cbc8a0a..e9b9ca3 100644 --- a/src/protocols/minecraft/protocol/bedrock.rs +++ b/src/protocols/minecraft/protocol/bedrock.rs @@ -83,7 +83,7 @@ impl Bedrock { edition: status[0].to_string(), name: status[1].to_string(), version_name: status[3].to_string(), - version_protocol: status[2].to_string(), + protocol_version: status[2].to_string(), players_maximum: status[5].parse().map_err(|e| TypeParse.context(e))?, players_online: status[4].parse().map_err(|e| TypeParse.context(e))?, id: status.get(6).map(|v| v.to_string()), diff --git a/src/protocols/minecraft/protocol/java.rs b/src/protocols/minecraft/protocol/java.rs index 0e12735..cbf6afa 100644 --- a/src/protocols/minecraft/protocol/java.rs +++ b/src/protocols/minecraft/protocol/java.rs @@ -96,11 +96,11 @@ impl Java { let json_response = get_string(&mut buffer)?; let value_response: Value = serde_json::from_str(&json_response).map_err(|e| JsonParse.context(e))?; - let version_name = value_response["version"]["name"] + let game_version = value_response["version"]["name"] .as_str() .ok_or(PacketBad)? .to_string(); - let version_protocol = value_response["version"]["protocol"] + let protocol_version = value_response["version"]["protocol"] .as_i64() .ok_or(PacketBad)? as i32; @@ -108,7 +108,7 @@ impl Java { let online_players = value_response["players"]["online"] .as_u64() .ok_or(PacketBad)? as u32; - let sample_players: Option> = match value_response["players"]["sample"].is_null() { + let players: Option> = match value_response["players"]["sample"].is_null() { true => None, false => { Some({ @@ -130,11 +130,11 @@ impl Java { }; Ok(JavaResponse { - version_name, - version_protocol, + game_version, + protocol_version, players_maximum: max_players, players_online: online_players, - players_sample: sample_players, + players, description: value_response["description"].to_string(), favicon: value_response["favicon"].as_str().map(str::to_string), previews_chat: value_response["previewsChat"].as_bool(), diff --git a/src/protocols/minecraft/protocol/legacy_bv1_8.rs b/src/protocols/minecraft/protocol/legacy_bv1_8.rs index 31da3d2..d6b40af 100644 --- a/src/protocols/minecraft/protocol/legacy_bv1_8.rs +++ b/src/protocols/minecraft/protocol/legacy_bv1_8.rs @@ -51,11 +51,11 @@ impl LegacyBV1_8 { let max_players = split[2].parse().map_err(|e| PacketBad.context(e))?; Ok(JavaResponse { - version_name: "Beta 1.8+".to_string(), - version_protocol: -1, + game_version: "Beta 1.8+".to_string(), + protocol_version: -1, players_maximum: max_players, players_online: online_players, - players_sample: None, + players: None, description, favicon: None, previews_chat: None, diff --git a/src/protocols/minecraft/protocol/legacy_v1_4.rs b/src/protocols/minecraft/protocol/legacy_v1_4.rs index 6d7aad2..9d0fa06 100644 --- a/src/protocols/minecraft/protocol/legacy_v1_4.rs +++ b/src/protocols/minecraft/protocol/legacy_v1_4.rs @@ -54,11 +54,11 @@ impl LegacyV1_4 { let max_players = split[2].parse().map_err(|e| PacketBad.context(e))?; Ok(JavaResponse { - version_name: "1.4+".to_string(), - version_protocol: -1, + game_version: "1.4+".to_string(), + protocol_version: -1, players_maximum: max_players, players_online: online_players, - players_sample: None, + players: None, description, favicon: None, previews_chat: None, diff --git a/src/protocols/minecraft/protocol/legacy_v1_6.rs b/src/protocols/minecraft/protocol/legacy_v1_6.rs index 02b1214..939f9b4 100644 --- a/src/protocols/minecraft/protocol/legacy_v1_6.rs +++ b/src/protocols/minecraft/protocol/legacy_v1_6.rs @@ -52,11 +52,11 @@ impl LegacyV1_6 { pub(crate) fn get_response(buffer: &mut Buffer) -> GDResult { // This is a specific order! - let version_protocol = buffer + let protocol_version = buffer .read_string::>(None)? .parse() .map_err(|e| PacketBad.context(e))?; - let version_name = buffer.read_string::>(None)?; + let game_version = buffer.read_string::>(None)?; let description = buffer.read_string::>(None)?; let online_players = buffer .read_string::>(None)? @@ -68,11 +68,11 @@ impl LegacyV1_6 { .map_err(|e| PacketBad.context(e))?; Ok(JavaResponse { - version_name, - version_protocol, + game_version, + protocol_version, players_maximum: max_players, players_online: online_players, - players_sample: None, + players: None, description, favicon: None, previews_chat: None, diff --git a/src/protocols/minecraft/types.rs b/src/protocols/minecraft/types.rs index 2f63d10..6110984 100644 --- a/src/protocols/minecraft/types.rs +++ b/src/protocols/minecraft/types.rs @@ -66,16 +66,16 @@ pub enum VersionedResponse<'a> { #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct JavaResponse { /// Version name, example: "1.19.2". - pub version_name: String, - /// Version protocol, example: 760 (for 1.19.2). Note that for versions - /// below 1.6 this field is always -1. - pub version_protocol: i32, + pub game_version: String, + /// Protocol version, example: 760 (for 1.19.1 or 1.19.2). + /// Note that for versions below 1.6 this field is always -1. + pub protocol_version: i32, /// Number of server capacity. pub players_maximum: u32, /// Number of online players. pub players_online: u32, /// Some online players (can be missing). - pub players_sample: Option>, + pub players: Option>, /// Server's description or MOTD. pub description: String, /// The favicon (can be missing). @@ -92,12 +92,12 @@ impl CommonResponse for JavaResponse { fn as_original(&self) -> GenericResponse { GenericResponse::Minecraft(VersionedResponse::Java(self)) } fn description(&self) -> Option<&str> { Some(&self.description) } - fn players_maximum(&self) -> u64 { self.players_maximum.into() } - fn players_online(&self) -> u64 { self.players_online.into() } - fn game_version(&self) -> Option<&str> { Some(&self.version_name) } + fn players_maximum(&self) -> u32 { self.players_maximum } + fn players_online(&self) -> u32 { self.players_online } + fn game_version(&self) -> Option<&str> { Some(&self.game_version) } fn players(&self) -> Option> { - self.players_sample + self.players .as_ref() .map(|players| players.iter().map(|p| p as &dyn CommonPlayer).collect()) } @@ -113,8 +113,8 @@ pub struct BedrockResponse { pub name: String, /// Version name, example: "1.19.40". pub version_name: String, - /// Version protocol, example: 760 (for 1.19.2). - pub version_protocol: String, + /// Protocol version, example: 760 (for 1.19.2). + pub protocol_version: String, /// Maximum number of players the server reports it can hold. pub players_maximum: u32, /// Number of players on the server. @@ -135,18 +135,18 @@ impl CommonResponse for BedrockResponse { fn name(&self) -> Option<&str> { Some(&self.name) } fn map(&self) -> Option<&str> { self.map.as_deref() } fn game_version(&self) -> Option<&str> { Some(&self.version_name) } - fn players_maximum(&self) -> u64 { self.players_maximum.into() } - fn players_online(&self) -> u64 { self.players_online.into() } + fn players_maximum(&self) -> u32 { self.players_maximum } + fn players_online(&self) -> u32 { self.players_online } } impl JavaResponse { pub fn from_bedrock_response(response: BedrockResponse) -> Self { Self { - version_name: response.version_name, - version_protocol: 0, + game_version: response.version_name, + protocol_version: 0, players_maximum: response.players_maximum, players_online: response.players_online, - players_sample: None, + players: None, description: response.name, favicon: None, previews_chat: None, diff --git a/src/protocols/quake/client.rs b/src/protocols/quake/client.rs index c67c76d..5af6ab1 100644 --- a/src/protocols/quake/client.rs +++ b/src/protocols/quake/client.rs @@ -118,7 +118,7 @@ pub(crate) fn client_query( .parse() .map_err(|e| TypeParse.context(e))?, players, - version: server_vars + game_version: server_vars .remove("version") .or(server_vars.remove("*version")), unused_entries: server_vars, diff --git a/src/protocols/quake/one.rs b/src/protocols/quake/one.rs index 38d1cc1..528b841 100644 --- a/src/protocols/quake/one.rs +++ b/src/protocols/quake/one.rs @@ -33,7 +33,7 @@ impl CommonPlayer for Player { fn as_original(&self) -> GenericPlayer { GenericPlayer::QuakeOne(self) } fn name(&self) -> &str { &self.name } - fn score(&self) -> Option { Some(self.score.into()) } + fn score(&self) -> Option { Some(self.score.into()) } } pub(crate) struct QuakeOne; diff --git a/src/protocols/quake/two.rs b/src/protocols/quake/two.rs index 77a5d51..d70daa4 100644 --- a/src/protocols/quake/two.rs +++ b/src/protocols/quake/two.rs @@ -32,7 +32,7 @@ impl CommonPlayer for Player { fn name(&self) -> &str { &self.name } - fn score(&self) -> Option { Some(self.score.try_into().unwrap_or(0)) } + fn score(&self) -> Option { Some(self.score) } } pub(crate) struct QuakeTwo; diff --git a/src/protocols/quake/types.rs b/src/protocols/quake/types.rs index 2479b6d..ebb05b8 100644 --- a/src/protocols/quake/types.rs +++ b/src/protocols/quake/types.rs @@ -22,7 +22,7 @@ pub struct Response

{ /// Maximum number of players the server reports it can hold. pub players_maximum: u8, /// The server version. - pub version: Option, + pub game_version: Option, /// Other server entries that weren't used. pub unused_entries: HashMap, } @@ -35,10 +35,10 @@ impl CommonResponse for Response

{ fn as_original(&self) -> GenericResponse { GenericResponse::Quake(P::version(self)) } fn name(&self) -> Option<&str> { Some(&self.name) } - fn game_version(&self) -> Option<&str> { self.version.as_deref() } + fn game_version(&self) -> Option<&str> { self.game_version.as_deref() } fn map(&self) -> Option<&str> { Some(&self.map) } - fn players_maximum(&self) -> u64 { self.players_maximum.into() } - fn players_online(&self) -> u64 { self.players_online.into() } + fn players_maximum(&self) -> u32 { self.players_maximum.into() } + fn players_online(&self) -> u32 { self.players_online.into() } fn players(&self) -> Option> { Some( diff --git a/src/protocols/types.rs b/src/protocols/types.rs index 687bb52..b26ab7f 100644 --- a/src/protocols/types.rs +++ b/src/protocols/types.rs @@ -66,7 +66,7 @@ pub trait CommonResponse { CommonResponseJson { name: self.name(), description: self.description(), - game: self.game(), + game_mode: self.game_mode(), game_version: self.game_version(), has_password: self.has_password(), map: self.map(), @@ -84,17 +84,17 @@ pub trait CommonResponse { /// Description of the server fn description(&self) -> Option<&str> { None } /// Name of the current game or game mode - fn game(&self) -> Option<&str> { None } + fn game_mode(&self) -> Option<&str> { None } /// Version of the game being run on the server fn game_version(&self) -> Option<&str> { None } /// The current map name fn map(&self) -> Option<&str> { None } /// Maximum number of players allowed to connect - fn players_maximum(&self) -> u64; + fn players_maximum(&self) -> u32; /// Number of players currently connected - fn players_online(&self) -> u64; + fn players_online(&self) -> u32; /// Number of bots currently connected - fn players_bots(&self) -> Option { None } + fn players_bots(&self) -> Option { None } /// Whether the server requires a password to join fn has_password(&self) -> Option { None } /// Currently connected players @@ -106,12 +106,12 @@ pub trait CommonResponse { pub struct CommonResponseJson<'a> { pub name: Option<&'a str>, pub description: Option<&'a str>, - pub game: Option<&'a str>, + pub game_mode: Option<&'a str>, pub game_version: Option<&'a str>, pub map: Option<&'a str>, - pub players_maximum: u64, - pub players_online: u64, - pub players_bots: Option, + pub players_maximum: u32, + pub players_online: u32, + pub players_bots: Option, pub has_password: Option, pub players: Option>>, } @@ -131,14 +131,14 @@ pub trait CommonPlayer { /// Player name fn name(&self) -> &str; /// Player score - fn score(&self) -> Option { None } + fn score(&self) -> Option { None } } #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[derive(Debug, Clone, PartialEq)] pub struct CommonPlayerJson<'a> { pub name: &'a str, - pub score: Option, + pub score: Option, } /// Timeout settings for socket operations diff --git a/src/protocols/valve/protocol.rs b/src/protocols/valve/protocol.rs index 778fe99..c344ae9 100644 --- a/src/protocols/valve/protocol.rs +++ b/src/protocols/valve/protocol.rs @@ -211,7 +211,7 @@ impl ValveProtocol { let name = buffer.read_string::(None)?; let map = buffer.read_string::(None)?; let folder = buffer.read_string::(None)?; - let game = buffer.read_string::(None)?; + let game_mode = buffer.read_string::(None)?; let players = buffer.read()?; let max_players = buffer.read()?; let protocol = buffer.read()?; @@ -245,11 +245,11 @@ impl ValveProtocol { let bots = buffer.read::()?; Ok(ServerInfo { - protocol, + protocol_version: protocol, name, map, folder, - game, + game_mode, appid: 0, // not present in the obsolete response players_online: players, players_maximum: max_players, @@ -259,7 +259,7 @@ impl ValveProtocol { has_password, vac_secured, the_ship: None, - version: "".to_string(), // a version field only for the mod + game_version: "".to_string(), // a version field only for the mod extra_data: None, is_mod, mod_data, @@ -281,7 +281,7 @@ impl ValveProtocol { let name = buffer.read_string::(None)?; let map = buffer.read_string::(None)?; let folder = buffer.read_string::(None)?; - let game = buffer.read_string::(None)?; + let game_mode = buffer.read_string::(None)?; let mut appid = buffer.read::()? as u32; let players = buffer.read()?; let max_players = buffer.read()?; @@ -300,7 +300,7 @@ impl ValveProtocol { }) } }; - let version = buffer.read_string::(None)?; + let game_version = buffer.read_string::(None)?; let extra_data = match buffer.read::() { Err(_) => None, Ok(value) => { @@ -339,11 +339,11 @@ impl ValveProtocol { }; Ok(ServerInfo { - protocol, + protocol_version: protocol, name, map, folder, - game, + game_mode, appid, players_online: players, players_maximum: max_players, @@ -353,7 +353,7 @@ impl ValveProtocol { has_password, vac_secured, the_ship, - version, + game_version, extra_data, is_mod: false, mod_data: None, @@ -436,7 +436,6 @@ fn get_response( let mut client = ValveProtocol::new(address, timeout_settings)?; let info = client.get_server_info(&engine)?; - let protocol = info.protocol; if let Engine::Source(Some(appids)) = &engine { let mut is_specified_id = false; @@ -454,6 +453,8 @@ fn get_response( } } + let protocol = info.protocol_version; + Ok(Response { info, players: match gather_settings.players { diff --git a/src/protocols/valve/types.rs b/src/protocols/valve/types.rs index 207a46f..9299934 100644 --- a/src/protocols/valve/types.rs +++ b/src/protocols/valve/types.rs @@ -61,12 +61,12 @@ impl CommonResponse for Response { fn as_original(&self) -> GenericResponse { GenericResponse::Valve(self) } fn name(&self) -> Option<&str> { Some(&self.info.name) } - fn game(&self) -> Option<&str> { Some(&self.info.game) } - fn game_version(&self) -> Option<&str> { Some(&self.info.version) } + fn game_mode(&self) -> Option<&str> { Some(&self.info.game_mode) } + fn game_version(&self) -> Option<&str> { Some(&self.info.game_version) } fn map(&self) -> Option<&str> { Some(&self.info.map) } - fn players_maximum(&self) -> u64 { self.info.players_maximum.into() } - fn players_online(&self) -> u64 { self.info.players_online.into() } - fn players_bots(&self) -> Option { Some(self.info.players_bots.into()) } + fn players_maximum(&self) -> u32 { self.info.players_maximum.into() } + fn players_online(&self) -> u32 { self.info.players_online.into() } + fn players_bots(&self) -> Option { Some(self.info.players_bots.into()) } fn has_password(&self) -> Option { Some(self.info.has_password) } fn players(&self) -> Option> { @@ -81,15 +81,15 @@ impl CommonResponse for Response { #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct ServerInfo { /// Protocol used by the server. - pub protocol: u8, + pub protocol_version: u8, /// Name of the server. pub name: String, /// Map name. pub map: String, /// Name of the folder containing the game files. pub folder: String, - /// The name of the game. - pub game: String, + /// The server-declared name of the game/game mode. + pub game_mode: String, /// [Steam Application ID](https://developer.valvesoftware.com/wiki/Steam_Application_ID) of game. pub appid: u32, /// Number of players on the server. @@ -109,7 +109,7 @@ pub struct ServerInfo { /// [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, + pub game_version: String, /// Some extra data that the server might provide or not. pub extra_data: Option, /// GoldSrc only: Indicates whether the hosted game is a mod. @@ -125,7 +125,7 @@ pub struct ServerPlayer { /// Player's name. pub name: String, /// General score. - pub score: u32, + pub score: i32, /// How long a player has been in the server (seconds). pub duration: f32, /// Only for [the ship](https://developer.valvesoftware.com/wiki/The_Ship): deaths count @@ -137,7 +137,7 @@ pub struct ServerPlayer { impl CommonPlayer for ServerPlayer { fn as_original(&self) -> GenericPlayer { GenericPlayer::Valve(self) } fn name(&self) -> &str { &self.name } - fn score(&self) -> Option { Some(self.score) } + fn score(&self) -> Option { Some(self.score) } } /// Only present for [the ship](https://developer.valvesoftware.com/wiki/The_Ship). @@ -447,7 +447,7 @@ pub mod game { /// Player's name. pub name: String, /// Player's score. - pub score: u32, + pub score: i32, /// How long a player has been in the server (seconds). pub duration: f32, } @@ -511,10 +511,10 @@ pub mod game { let (port, steam_id, tv_port, tv_name, keywords) = get_optional_extracted_data(response.info.extra_data); Self { - protocol: response.info.protocol, + protocol: response.info.protocol_version, name: response.info.name, map: response.info.map, - game: response.info.game, + game: response.info.game_mode, appid: response.info.appid, players_online: response.info.players_online, players_details: response @@ -528,7 +528,7 @@ pub mod game { server_type: response.info.server_type, has_password: response.info.has_password, vac_secured: response.info.vac_secured, - version: response.info.version, + version: response.info.game_version, port, steam_id, tv_port,