From efc1828b2911b3b7361ebe56d9d15d9ca988be4e Mon Sep 17 00:00:00 2001 From: Tom <25043847+Douile@users.noreply.github.com> Date: Wed, 27 Sep 2023 14:07:42 +0000 Subject: [PATCH] [Protocol] Make gamespy1 parsing less likely to fail (#107) * [Protocol] Gamespy1 don't skip "playername" field (#88) * [Protocol] Gamespy1 make more player fields optional (#88) These fields seem to be missing from bf1942 queries so make them optional. --- .../gamespy/protocols/one/protocol.rs | 38 +++++++------------ src/protocols/gamespy/protocols/one/types.rs | 10 ++--- 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/src/protocols/gamespy/protocols/one/protocol.rs b/src/protocols/gamespy/protocols/one/protocol.rs index cc0c67f..1700b19 100644 --- a/src/protocols/gamespy/protocols/one/protocol.rs +++ b/src/protocols/gamespy/protocols/one/protocol.rs @@ -113,7 +113,8 @@ fn extract_players(server_vars: &mut HashMap, players_maximum: u }; let early_return = match kind { - "team" | "player" | "ping" | "face" | "skin" | "mesh" | "frags" | "ngsecret" | "deaths" | "health" => false, + "team" | "player" | "playername" | "ping" | "face" | "skin" | "mesh" | "frags" | "ngsecret" | "deaths" + | "health" => false, _x => true, // println!("UNKNOWN {id} {x} {value}"); }; @@ -143,30 +144,19 @@ fn extract_players(server_vars: &mut HashMap, players_maximum: u .clone() } }, - team: player_data - .get("team") - .ok_or(GDErrorKind::PacketBad)? - .trim() - .parse() - .map_err(|e| TypeParse.context(e))?, + team: match player_data.get("team") { + Some(t) => Some(t.trim().parse().map_err(|e| TypeParse.context(e))?), + None => None, + }, ping: player_data .get("ping") .ok_or(GDErrorKind::PacketBad)? .trim() .parse() .map_err(|e| TypeParse.context(e))?, - face: player_data - .get("face") - .ok_or(GDErrorKind::PacketBad)? - .clone(), - skin: player_data - .get("skin") - .ok_or(GDErrorKind::PacketBad)? - .clone(), - mesh: player_data - .get("mesh") - .ok_or(GDErrorKind::PacketBad)? - .clone(), + face: player_data.get("face").cloned(), + skin: player_data.get("skin").cloned(), + mesh: player_data.get("mesh").cloned(), score: player_data .get("frags") .ok_or(GDErrorKind::PacketBad)? @@ -181,12 +171,10 @@ fn extract_players(server_vars: &mut HashMap, players_maximum: u Some(v) => Some(v.trim().parse().map_err(|e| TypeParse.context(e))?), None => None, }, - secret: player_data - .get("ngsecret") - .ok_or(GDErrorKind::PacketBad)? - .to_lowercase() - .parse() - .map_err(|e| TypeParse.context(e))?, + secret: match player_data.get("ngsecret") { + Some(s) => Some(s.to_lowercase().parse().map_err(|e| TypeParse.context(e))?), + None => None, + }, }; players.push(new_player); diff --git a/src/protocols/gamespy/protocols/one/types.rs b/src/protocols/gamespy/protocols/one/types.rs index a6e3aea..aab764c 100644 --- a/src/protocols/gamespy/protocols/one/types.rs +++ b/src/protocols/gamespy/protocols/one/types.rs @@ -12,16 +12,16 @@ use crate::protocols::GenericResponse; #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct Player { pub name: String, - pub team: u8, + pub team: Option, /// The ping from the server's perspective. pub ping: u16, - pub face: String, - pub skin: String, - pub mesh: String, + pub face: Option, + pub skin: Option, + pub mesh: Option, pub score: i32, pub deaths: Option, pub health: Option, - pub secret: bool, + pub secret: Option, } impl CommonPlayer for Player {