diff --git a/src/lazyparser.rs b/src/lazyparser.rs index 253e3ca..f8cecdf 100644 --- a/src/lazyparser.rs +++ b/src/lazyparser.rs @@ -1,7 +1,5 @@ use crate::{Container, FrameIterator}; -use std::collections::VecDeque; - mod events; pub use events::LazyEventIterator; @@ -43,6 +41,101 @@ impl<'b> LazyParser<'b> { None } + pub fn player_info(&self) -> std::collections::HashMap { + let mut result = std::collections::HashMap::new(); + + let mut buffer = Vec::new(); + + for frame in FrameIterator::parse(self.container.inner) { + let packet = match frame.cmd { + crate::DemoCommand::Packet | crate::DemoCommand::SignonPacket => { + let data = match frame.decompress_with_buf(&mut buffer) { + Ok(d) => d, + Err(_) => continue, + }; + let raw: crate::csgo_proto::CDemoPacket = match prost::Message::decode(data) { + Ok(d) => d, + Err(_) => continue, + }; + + raw + } + crate::DemoCommand::FullPacket => { + let data = match frame.decompress_with_buf(&mut buffer) { + Ok(d) => d, + Err(_) => continue, + }; + let raw: crate::csgo_proto::CDemoFullPacket = match prost::Message::decode(data) + { + Ok(d) => d, + Err(_) => continue, + }; + + match raw.packet { + Some(p) => p, + None => continue, + } + } + _ => continue, + }; + + let mut bitreader = crate::bitreader::Bitreader::new(packet.data()); + + while bitreader.bits_remaining().unwrap_or(0) > 8 { + let msg_type = match bitreader.read_u_bit_var() { + Ok(t) => t, + Err(e) => break, + }; + let size = match bitreader.read_varint() { + Ok(s) => s, + Err(e) => break, + }; + let msg_bytes = match bitreader.read_n_bytes(size as usize) { + Ok(s) => s, + Err(e) => break, + }; + + assert_eq!(msg_bytes.len(), size as usize); + + let net_msg_type = + match crate::netmessagetypes::NetmessageType::try_from(msg_type as i32) { + Ok(v) => v, + Err(e) => { + dbg!(e); + continue; + } + }; + + match net_msg_type { + crate::netmessagetypes::NetmessageType::CS_UM_EndOfMatchAllPlayersData => { + let raw: crate::csgo_proto::CcsUsrMsgEndOfMatchAllPlayersData = + match prost::Message::decode(msg_bytes.as_slice()) { + Ok(d) => d, + Err(e) => continue, + }; + + for data in raw.allplayerdata { + result.insert( + crate::UserId(data.slot()), + crate::parser::Player { + name: data.name.unwrap(), + xuid: data.xuid.unwrap(), + team: data.teamnumber.unwrap(), + color: data.playercolor.unwrap(), + }, + ); + } + } + _unknown => { + // dbg!(unknown); + } + }; + } + } + + result + } + pub fn events(&self) -> LazyEventIterator<'b> { LazyEventIterator::new(self) } diff --git a/src/parser.rs b/src/parser.rs index 39f44df..c2f4321 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -39,7 +39,7 @@ impl From for FirstPassError { } } -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub struct Player { pub xuid: u64, pub name: String, diff --git a/tests/lazy.rs b/tests/lazy.rs index c85e010..43f4e28 100644 --- a/tests/lazy.rs +++ b/tests/lazy.rs @@ -12,6 +12,8 @@ fn cmp_lazy_nonlazy_events() { let lazy_demo = csdemo::lazyparser::LazyParser::new(csdemo::Container::parse(&content).unwrap()); + assert_eq!(demo.player_info, lazy_demo.player_info()); + for (normal, lazied) in demo .events .into_iter() @@ -35,6 +37,8 @@ fn cmp_lazy_nonlazy_entities() { let lazy_demo = csdemo::lazyparser::LazyParser::new(csdemo::Container::parse(&content).unwrap()); + assert_eq!(demo.player_info, lazy_demo.player_info()); + let mut normal_iter = demo .entity_states .ticks