Add support for loading player info from lazy-parser

This commit is contained in:
Lol3rrr
2024-10-18 13:47:29 +02:00
parent a0eab7c68f
commit 4b1cb50566
3 changed files with 100 additions and 3 deletions

View File

@@ -1,7 +1,5 @@
use crate::{Container, FrameIterator}; use crate::{Container, FrameIterator};
use std::collections::VecDeque;
mod events; mod events;
pub use events::LazyEventIterator; pub use events::LazyEventIterator;
@@ -43,6 +41,101 @@ impl<'b> LazyParser<'b> {
None None
} }
pub fn player_info(&self) -> std::collections::HashMap<crate::UserId, crate::parser::Player> {
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> { pub fn events(&self) -> LazyEventIterator<'b> {
LazyEventIterator::new(self) LazyEventIterator::new(self)
} }

View File

@@ -39,7 +39,7 @@ impl From<crate::game_event::ParseGameEventError> for FirstPassError {
} }
} }
#[derive(Debug)] #[derive(Debug, PartialEq)]
pub struct Player { pub struct Player {
pub xuid: u64, pub xuid: u64,
pub name: String, pub name: String,

View File

@@ -12,6 +12,8 @@ fn cmp_lazy_nonlazy_events() {
let lazy_demo = let lazy_demo =
csdemo::lazyparser::LazyParser::new(csdemo::Container::parse(&content).unwrap()); csdemo::lazyparser::LazyParser::new(csdemo::Container::parse(&content).unwrap());
assert_eq!(demo.player_info, lazy_demo.player_info());
for (normal, lazied) in demo for (normal, lazied) in demo
.events .events
.into_iter() .into_iter()
@@ -35,6 +37,8 @@ fn cmp_lazy_nonlazy_entities() {
let lazy_demo = let lazy_demo =
csdemo::lazyparser::LazyParser::new(csdemo::Container::parse(&content).unwrap()); csdemo::lazyparser::LazyParser::new(csdemo::Container::parse(&content).unwrap());
assert_eq!(demo.player_info, lazy_demo.player_info());
let mut normal_iter = demo let mut normal_iter = demo
.entity_states .entity_states
.ticks .ticks