s2protocol/
protocol_version_decoder.rs1use super::*;
10use crate::versions::protocol87702::byte_aligned::{ReplaySHeader, SVersion};
12use nom::bytes::complete::*;
13use nom::error::dbg_dmp;
14use nom_mpq::MPQ;
15use nom_mpq::parser::peek_hex;
16
17#[derive(Debug, PartialEq, Clone)]
19pub struct ProtocolHeader {
20 pub m_signature: Vec<u8>,
21 pub m_version: SVersion,
22}
23
24impl ProtocolHeader {
25 #[tracing::instrument(level = "debug", skip(input), fields(input = peek_hex(input)))]
26 pub fn parse(input: &[u8]) -> S2ProtoResult<&[u8], Self> {
27 let (tail, _) = validate_struct_tag(input)?;
28 let (tail, _) = dbg_dmp(tag(&b"\x12"[..]), "Protocol Header struct size")(tail)?;
29 let (tail, m_signature) = Self::parse_m_signature(tail)?;
32 let (tail, _) = dbg_dmp(tag(&b"\x02"[..]), "Protocol Header.Version struct Tag")(tail)?;
33 let (tail, m_version) = SVersion::parse(tail)?;
34 Ok((
35 tail,
36 Self {
37 m_signature,
38 m_version,
39 },
40 ))
41 }
42
43 #[tracing::instrument(level = "debug", skip(input), fields(input = peek_hex(input)))]
44 pub fn parse_m_signature(input: &[u8]) -> S2ProtoResult<&[u8], Vec<u8>> {
45 let (tail, _) = dbg_dmp(tag(&b"\x00"[..]), "m_signature field tag")(input)?;
46 let (tail, m_signature) = tagged_blob(tail)?;
47 Ok((tail, m_signature))
48 }
49}
50
51pub fn read_protocol_header(mpq: &MPQ) -> S2ProtoResult<&[u8], ReplaySHeader> {
53 let user_data = mpq
54 .user_data
55 .as_ref()
56 .expect("Unable to locate protocol version, missing user data in MPQ");
57 ReplaySHeader::parse(&user_data.content)
58}