diff --git a/protocol/src/filter.rs b/protocol/src/filter.rs index ec52682..e5e2b50 100644 --- a/protocol/src/filter.rs +++ b/protocol/src/filter.rs @@ -9,6 +9,7 @@ //! | --------- | ---- | ------------------------------ | -------- | //! | map | str | Map name | `crossfire`, `de_dust` | //! | gamedir | str | Game directory | `valve`, `cstrike` | +//! | protocol | u8 | Game directory | `48`, `49` | //! | dedicated | bool | Server running dedicated | `0`, `1` | //! | lan | bool | Server is LAN | `0`, `1` | //! | nat | bool | Server behind NAT | `0`, `1` | @@ -162,6 +163,8 @@ pub struct Filter<'a> { pub map: Option>, /// Client version. pub clver: Option, + /// Protocol version + pub protocol: Option, pub key: Option, pub flags: FilterFlags, @@ -177,7 +180,8 @@ impl Filter<'_> { pub fn matches(&self, _addr: SocketAddrV4, info: &ServerInfo) -> bool { !((info.flags & self.flags_mask) != self.flags || self.gamedir.map_or(false, |s| *s != &*info.gamedir) - || self.map.map_or(false, |s| *s != &*info.map)) + || self.map.map_or(false, |s| *s != &*info.map) + || self.protocol.map_or(false, |s| s != info.protocol)) } } @@ -200,6 +204,7 @@ impl<'a> TryFrom<&'a [u8]> for Filter<'a> { b"secure" => filter.insert_flag(FilterFlags::SECURE, cur.get_key_value()?), b"gamedir" => filter.gamedir = Some(cur.get_key_value()?), b"map" => filter.map = Some(cur.get_key_value()?), + b"protocol" => filter.protocol = Some(cur.get_key_value()?), b"empty" => filter.insert_flag(FilterFlags::EMPTY, cur.get_key_value()?), b"full" => filter.insert_flag(FilterFlags::FULL, cur.get_key_value()?), b"password" => filter.insert_flag(FilterFlags::PASSWORD, cur.get_key_value()?), @@ -266,7 +271,9 @@ impl fmt::Display for &Filter<'_> { if let Some(x) = self.key { write!(fmt, "\\key\\{:x}", x)?; } - + if let Some(x) = self.protocol { + write!(fmt, "\\protocol\\{}", x)?; + } Ok(()) } } @@ -319,6 +326,11 @@ mod tests { clver: Some(Version::with_patch(0, 19, 3)), } } + parse_protocol { + b"\\protocol\\48" => { + protocol: Some(48) + } + } parse_dedicated(flags_mask: FilterFlags::DEDICATED) { b"\\dedicated\\0" => {} b"\\dedicated\\1" => { @@ -388,9 +400,11 @@ mod tests { \\noplayers\\1\ \\password\\1\ \\secure\\1\ + \\protocol\\49\ " => { gamedir: Some(Str(&b"valve"[..])), map: Some(Str(&b"crossfire"[..])), + protocol: Some(49), clver: Some(Version::new(0, 20)), flags: FilterFlags::all(), flags_mask: FilterFlags::all(), @@ -568,4 +582,16 @@ mod tests { matches!(servers, b"\\map\\de_dust", 2); matches!(servers, b"\\map\\cs_office", 3); } + + #[test] + fn match_protocol() { + let s = servers! { + "0.0.0.0:0" => b"\\protocol\\47" + "0.0.0.0:0" => b"\\protocol\\48" + "0.0.0.0:0" => b"\\protocol\\49" + }; + matches!(s, b"", 0, 1, 2); + matches!(s, b"\\protocol\\48", 1); + matches!(s, b"\\protocol\\49", 2); + } } diff --git a/protocol/src/game.rs b/protocol/src/game.rs index 5ba96d7..7353161 100644 --- a/protocol/src/game.rs +++ b/protocol/src/game.rs @@ -124,6 +124,7 @@ mod tests { gamedir: Some(Str(&b"valve"[..])), map: Some(Str(&b"crossfire"[..])), key: Some(0xdeadbeef), + protocol: Some(49), clver: Some(Version::new(0, 20)), flags: FilterFlags::all(), flags_mask: FilterFlags::all(), @@ -141,6 +142,7 @@ mod tests { last: SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 0), filter: Filter { gamedir: None, + protocol: Some(48), map: None, key: None, clver: Some(Version::new(0, 20)), diff --git a/protocol/src/server_info.rs b/protocol/src/server_info.rs index 6a40f63..ec785f1 100644 --- a/protocol/src/server_info.rs +++ b/protocol/src/server_info.rs @@ -8,6 +8,7 @@ use super::types::Str; #[derive(Clone, Debug)] pub struct ServerInfo { pub version: Version, + pub protocol: u8, pub gamedir: Box<[u8]>, pub map: Box<[u8]>, pub flags: FilterFlags, @@ -18,6 +19,7 @@ impl ServerInfo { pub fn new(info: &ServerAdd>) -> Self { Self { version: info.version, + protocol: info.protocol, gamedir: info.gamedir.to_vec().into_boxed_slice(), map: info.map.to_vec().into_boxed_slice(), flags: FilterFlags::from(info),