diff --git a/src/parser.rs b/src/parser.rs index 36d02cb..010ed74 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -27,11 +27,18 @@ impl From for FirstPassError { } } +#[derive(Debug)] +pub struct Player { + pub xuid: u64, + pub name: String, +} + #[derive(Debug)] pub struct FirstPassOutput { pub header: crate::csgo_proto::CDemoFileHeader, pub info: crate::csgo_proto::CDemoFileInfo, pub events: Vec, + pub player_info: std::collections::HashMap, } #[derive(Debug)] @@ -50,6 +57,7 @@ where let mut event_mapping = GameEventMapping { mapping: std::collections::HashMap::new(), }; + let mut player_info = std::collections::HashMap::new(); for mut frame in frames.into_iter() { frame @@ -67,10 +75,10 @@ where file_info = Some(raw); } DemoCommand::SignonPacket | DemoCommand::Packet => { - parse_packet(data, &mut events, &mut event_mapping)?; + parse_packet(data, &mut events, &mut event_mapping, &mut player_info)?; } DemoCommand::FullPacket => { - parse_fullpacket(data, &mut events, &mut event_mapping)?; + parse_fullpacket(data, &mut events, &mut event_mapping, &mut player_info)?; } _ => {} } @@ -79,13 +87,14 @@ where let header = header.ok_or(FirstPassError::MissingFileHeader)?; let info = file_info.ok_or(FirstPassError::MissingFileInfo)?; - Ok(FirstPassOutput { header, info, events }) + Ok(FirstPassOutput { header, info, events, player_info }) } fn parse_fullpacket( data: &[u8], events: &mut Vec, event_mapper: &mut GameEventMapping, + player_info: &mut std::collections::HashMap, ) -> Result<(), FirstPassError> { let raw: crate::csgo_proto::CDemoFullPacket = prost::Message::decode(data)?; @@ -94,7 +103,7 @@ fn parse_fullpacket( match raw.packet { Some(packet) => { - inner_parse_packet(&packet, events, event_mapper)?; + inner_parse_packet(&packet, events, event_mapper, player_info)?; Ok(()) } @@ -106,10 +115,11 @@ fn parse_packet( data: &[u8], events: &mut Vec, event_mapper: &mut GameEventMapping, + player_info: &mut std::collections::HashMap, ) -> Result<(), FirstPassError> { let raw: crate::csgo_proto::CDemoPacket = prost::Message::decode(data)?; - inner_parse_packet(&raw, events, event_mapper)?; + inner_parse_packet(&raw, events, event_mapper, player_info)?; Ok(()) } @@ -118,6 +128,7 @@ fn inner_parse_packet( raw: &crate::csgo_proto::CDemoPacket, events: &mut Vec, event_mapper: &mut GameEventMapping, + player_info: &mut std::collections::HashMap, ) -> Result<(), FirstPassError> { let mut bitreader = crate::bitreader::Bitreader::new(raw.data()); @@ -155,7 +166,10 @@ fn inner_parse_packet( events.push(DemoEvent::ServerInfo(raw)); } - crate::netmessagetypes::NetmessageType::net_SignonState => {} + crate::netmessagetypes::NetmessageType::net_SignonState => { + let raw: crate::csgo_proto::CnetMsgSignonState = prost::Message::decode(msg_bytes.as_slice())?; + dbg!(raw); + } crate::netmessagetypes::NetmessageType::net_Tick => { let raw: crate::csgo_proto::CnetMsgTick = prost::Message::decode(msg_bytes.as_slice())?; @@ -181,6 +195,7 @@ fn inner_parse_packet( match crate::game_event::EVENT_PARSERS.get(&name) { Some(parser) => { let parsed = parser.parse(keys.as_slice(), raw.clone())?; + events.push(DemoEvent::GameEvent(parsed)); } None => { @@ -212,7 +227,16 @@ fn inner_parse_packet( crate::netmessagetypes::NetmessageType::TE_WorldDecal => {} crate::netmessagetypes::NetmessageType::TE_EffectDispatch => {} crate::netmessagetypes::NetmessageType::CS_UM_PlayerStatsUpdate => {} - crate::netmessagetypes::NetmessageType::CS_UM_EndOfMatchAllPlayersData => {} + crate::netmessagetypes::NetmessageType::CS_UM_EndOfMatchAllPlayersData => { + let raw: crate::csgo_proto::CcsUsrMsgEndOfMatchAllPlayersData = prost::Message::decode(msg_bytes.as_slice())?; + + for data in raw.allplayerdata { + player_info.insert(data.slot(), Player { + name: data.name.unwrap(), + xuid: data.xuid.unwrap(), + }); + } + } crate::netmessagetypes::NetmessageType::TE_PhysicsProp => {} crate::netmessagetypes::NetmessageType::UM_TextMsg => {} crate::netmessagetypes::NetmessageType::CS_UM_VoteFailed => {} diff --git a/testfiles/de_ancient.dem b/testfiles/de_ancient.dem new file mode 100644 index 0000000..ccabe46 --- /dev/null +++ b/testfiles/de_ancient.dem @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e97b3f0a1484e52bb584730d30d2299fac7c60fd6c418fa00a41b32bce397ce +size 254036241 diff --git a/tests/parse.rs b/tests/parse.rs index 3bd4b82..7495222 100644 --- a/tests/parse.rs +++ b/tests/parse.rs @@ -13,3 +13,19 @@ fn mirage_1() { todo!() } + +#[test] +fn ancient_1() { + let content = std::fs::read("testfiles/de_ancient.dem").unwrap(); + + let container = csdemo::Container::parse(&content).unwrap(); + + let frame_iter = csdemo::FrameIterator::parse(container.inner); + assert_eq!(116676, frame_iter.count()); + + let output = csdemo::parser::parse(csdemo::FrameIterator::parse(container.inner)).unwrap(); + + assert_eq!("de_ancient", output.header.map_name()); + + todo!() +}