Some minor improvements and fixes
This commit is contained in:
@@ -28,8 +28,7 @@ impl<'b> Container<'b> {
|
|||||||
return Err(ParseContainerError::MissingHeader);
|
return Err(ParseContainerError::MissingHeader);
|
||||||
}
|
}
|
||||||
|
|
||||||
let magic =
|
let magic = core::str::from_utf8(&input[..8]).map_err(ParseContainerError::InvalidMagic)?;
|
||||||
core::str::from_utf8(&input[..8]).map_err(ParseContainerError::InvalidMagic)?;
|
|
||||||
let raw_len: [u8; 4] = input[8..12]
|
let raw_len: [u8; 4] = input[8..12]
|
||||||
.try_into()
|
.try_into()
|
||||||
.expect("We know that the input buffer is at least 16 bytes large");
|
.expect("We know that the input buffer is at least 16 bytes large");
|
||||||
|
|||||||
26
src/frame.rs
26
src/frame.rs
@@ -23,15 +23,19 @@ impl<'b> Frame<'b> {
|
|||||||
where
|
where
|
||||||
'ib: 'b,
|
'ib: 'b,
|
||||||
{
|
{
|
||||||
let (input, raw_cmd) = crate::varint::parse_varint(input).map_err(FrameParseError::ParseVarint)?;
|
let (input, raw_cmd) =
|
||||||
let (input, tick) = crate::varint::parse_varint(input).map_err(FrameParseError::ParseVarint)?;
|
crate::varint::parse_varint(input).map_err(FrameParseError::ParseVarint)?;
|
||||||
let (input, size) = crate::varint::parse_varint(input).map_err(FrameParseError::ParseVarint)?;
|
let (input, tick) =
|
||||||
|
crate::varint::parse_varint(input).map_err(FrameParseError::ParseVarint)?;
|
||||||
|
let (input, size) =
|
||||||
|
crate::varint::parse_varint(input).map_err(FrameParseError::ParseVarint)?;
|
||||||
|
|
||||||
if input.len() < size as usize {
|
if input.len() < size as usize {
|
||||||
return Err(FrameParseError::NotEnoughBytes);
|
return Err(FrameParseError::NotEnoughBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
let demo_cmd = crate::DemoCommand::try_from((raw_cmd & !64) as i32).map_err(FrameParseError::ParseDemoCommand)?;
|
let demo_cmd = crate::DemoCommand::try_from((raw_cmd & !64) as i32)
|
||||||
|
.map_err(FrameParseError::ParseDemoCommand)?;
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
&input[size as usize..],
|
&input[size as usize..],
|
||||||
@@ -52,7 +56,10 @@ impl<'b> Frame<'b> {
|
|||||||
Some(self.inner.as_ref())
|
Some(self.inner.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decompress_with_buf<'s, 'buf>(&'s self, buf: &'b mut Vec<u8>) -> Result<&'buf [u8], FrameDecompressError>
|
pub fn decompress_with_buf<'s, 'buf>(
|
||||||
|
&'s self,
|
||||||
|
buf: &'b mut Vec<u8>,
|
||||||
|
) -> Result<&'buf [u8], FrameDecompressError>
|
||||||
where
|
where
|
||||||
's: 'buf,
|
's: 'buf,
|
||||||
{
|
{
|
||||||
@@ -60,16 +67,13 @@ impl<'b> Frame<'b> {
|
|||||||
return Ok(&self.inner);
|
return Ok(&self.inner);
|
||||||
}
|
}
|
||||||
|
|
||||||
let uncompressed_len = snap::raw::decompress_len(&self.inner).map_err(|e| {
|
let uncompressed_len = snap::raw::decompress_len(&self.inner)
|
||||||
FrameDecompressError::GettingDecompressedLength(e)
|
.map_err(|e| FrameDecompressError::GettingDecompressedLength(e))?;
|
||||||
})?;
|
|
||||||
buf.resize(uncompressed_len, 0);
|
buf.resize(uncompressed_len, 0);
|
||||||
|
|
||||||
snap::raw::Decoder::new()
|
snap::raw::Decoder::new()
|
||||||
.decompress(&self.inner, buf.as_mut_slice())
|
.decompress(&self.inner, buf.as_mut_slice())
|
||||||
.map_err(|e| {
|
.map_err(|e| FrameDecompressError::Decompressing(e))?;
|
||||||
FrameDecompressError::Decompressing(e)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(buf.as_slice())
|
Ok(buf.as_slice())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ mod container;
|
|||||||
pub use container::{Container, ParseContainerError};
|
pub use container::{Container, ParseContainerError};
|
||||||
|
|
||||||
mod frame;
|
mod frame;
|
||||||
pub use frame::{Frame, FrameIterator, FrameDecompressError, FrameParseError};
|
pub use frame::{Frame, FrameDecompressError, FrameIterator, FrameParseError};
|
||||||
|
|
||||||
mod democmd;
|
mod democmd;
|
||||||
pub use democmd::DemoCommand;
|
pub use democmd::DemoCommand;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::{packet::DemoEvent, DemoCommand, Frame, UserId, FrameDecompressError};
|
use crate::{packet::DemoEvent, DemoCommand, Frame, FrameDecompressError, UserId};
|
||||||
|
|
||||||
mod fieldpath;
|
mod fieldpath;
|
||||||
pub use fieldpath::{FieldPath, Paths};
|
pub use fieldpath::{FieldPath, Paths};
|
||||||
@@ -9,8 +9,8 @@ mod propcontroller;
|
|||||||
mod sendtables;
|
mod sendtables;
|
||||||
mod variant;
|
mod variant;
|
||||||
|
|
||||||
pub use variant::Variant;
|
|
||||||
pub use entities::EntityFilter;
|
pub use entities::EntityFilter;
|
||||||
|
pub use variant::Variant;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum FirstPassError {
|
pub enum FirstPassError {
|
||||||
@@ -62,7 +62,7 @@ impl EntityTickList {
|
|||||||
Self {
|
Self {
|
||||||
ticks: vec![EntityTickStates {
|
ticks: vec![EntityTickStates {
|
||||||
tick: 0,
|
tick: 0,
|
||||||
states: Vec::new()
|
states: Vec::new(),
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -338,7 +338,12 @@ fn inner_parse_packet(
|
|||||||
let raw: crate::csgo_proto::CnetMsgTick =
|
let raw: crate::csgo_proto::CnetMsgTick =
|
||||||
prost::Message::decode(msg_bytes.as_slice())?;
|
prost::Message::decode(msg_bytes.as_slice())?;
|
||||||
|
|
||||||
assert!(*current_tick <= raw.tick(), "Current Tick {} <= Tick Packet {}", *current_tick, raw.tick());
|
assert!(
|
||||||
|
*current_tick <= raw.tick(),
|
||||||
|
"Current Tick {} <= Tick Packet {}",
|
||||||
|
*current_tick,
|
||||||
|
raw.tick()
|
||||||
|
);
|
||||||
if raw.tick() > *current_tick {
|
if raw.tick() > *current_tick {
|
||||||
*current_tick = raw.tick();
|
*current_tick = raw.tick();
|
||||||
entity_states.new_tick(*current_tick);
|
entity_states.new_tick(*current_tick);
|
||||||
@@ -368,7 +373,7 @@ fn inner_parse_packet(
|
|||||||
|
|
||||||
if let Some(baseline_bytes) = baselines.get(&cls) {
|
if let Some(baseline_bytes) = baselines.get(&cls) {
|
||||||
let mut br = crate::bitreader::Bitreader::new(baseline_bytes);
|
let mut br = crate::bitreader::Bitreader::new(baseline_bytes);
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
// How should we handle is this?
|
// How should we handle is this?
|
||||||
let _state = update_entity(
|
let _state = update_entity(
|
||||||
@@ -394,7 +399,9 @@ fn inner_parse_packet(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
0b00 => {
|
0b00 => {
|
||||||
if raw.has_pvs_vis_bits() > 0 && bitreader.read_nbits(2)? & 0x01 == 1 {
|
if raw.has_pvs_vis_bits() > 0
|
||||||
|
&& bitreader.read_nbits(2)? & 0x01 == 1
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,8 +91,10 @@ impl EntityContext {
|
|||||||
value: result,
|
value: result,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
println!("Missing PropInfo for {:?}", fi);
|
// println!("Missing PropInfo for {:?} = {:?}", fi, result);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// println!("Missing Field Info for {:?} with {:?} = {:?}", field, path, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,6 +116,8 @@ impl EntityContext {
|
|||||||
|
|
||||||
impl EntityState {
|
impl EntityState {
|
||||||
pub fn get_prop(&self, name: &str) -> Option<&EntityProp> {
|
pub fn get_prop(&self, name: &str) -> Option<&EntityProp> {
|
||||||
self.props.iter().find(|p| p.prop_info.prop_name.as_ref() == name)
|
self.props
|
||||||
|
.iter()
|
||||||
|
.find(|p| p.prop_info.prop_name.as_ref() == name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,7 +106,42 @@ impl PropController {
|
|||||||
name_to_id: HashMap::new(),
|
name_to_id: HashMap::new(),
|
||||||
id_to_name: HashMap::new(),
|
id_to_name: HashMap::new(),
|
||||||
path_to_name: HashMap::new(),
|
path_to_name: HashMap::new(),
|
||||||
prop_infos: HashMap::new(),
|
prop_infos: [
|
||||||
|
(
|
||||||
|
WEAPON_SKIN_ID,
|
||||||
|
PropInfo {
|
||||||
|
id: WEAPON_SKIN_ID,
|
||||||
|
prop_name: "weapon_skin_id".into(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
WEAPON_PAINT_SEED,
|
||||||
|
PropInfo {
|
||||||
|
id: WEAPON_PAINT_SEED,
|
||||||
|
prop_name: "weapon_paint_seed".into(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
WEAPON_FLOAT,
|
||||||
|
PropInfo {
|
||||||
|
id: WEAPON_FLOAT,
|
||||||
|
prop_name: "weapon_float".into(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
MY_WEAPONS_OFFSET,
|
||||||
|
PropInfo {
|
||||||
|
id: MY_WEAPONS_OFFSET,
|
||||||
|
prop_name: "my_weapons_offset".into(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(ITEM_PURCHASE_COST, PropInfo {
|
||||||
|
id: ITEM_PURCHASE_COST,
|
||||||
|
prop_name: "item_purchase_cost".into(),
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,9 +173,11 @@ impl PropController {
|
|||||||
path.clone(),
|
path.clone(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Field::Array(ser) => if let Field::Value(v) = &mut ser.field_enum.as_mut() {
|
Field::Array(ser) => {
|
||||||
self.handle_prop(&(ser_name.clone() + "." + &v.name), v, path);
|
if let Field::Value(v) = &mut ser.field_enum.as_mut() {
|
||||||
},
|
self.handle_prop(&(ser_name.clone() + "." + &v.name), v, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
Field::Vector(_x) => {
|
Field::Vector(_x) => {
|
||||||
let vec_path = path.clone();
|
let vec_path = path.clone();
|
||||||
if let Ok(inner) = f.get_inner_mut(0) {
|
if let Ok(inner) = f.get_inner_mut(0) {
|
||||||
|
|||||||
@@ -18,19 +18,21 @@ fn mirage_1() {
|
|||||||
assert_eq!("de_mirage", output.header.map_name());
|
assert_eq!("de_mirage", output.header.map_name());
|
||||||
|
|
||||||
for event in output.events.iter() {
|
for event in output.events.iter() {
|
||||||
if let DemoEvent::GameEvent(gevent) = event { if let GameEvent::PlayerDeath(death) = gevent.as_ref() {
|
if let DemoEvent::GameEvent(gevent) = event {
|
||||||
assert!(
|
if let GameEvent::PlayerDeath(death) = gevent.as_ref() {
|
||||||
death.remaining.is_empty(),
|
assert!(
|
||||||
"Remaining for PlayerDeath: {:?}",
|
death.remaining.is_empty(),
|
||||||
death.remaining
|
"Remaining for PlayerDeath: {:?}",
|
||||||
);
|
death.remaining
|
||||||
|
);
|
||||||
|
|
||||||
let died_user = output
|
let died_user = output
|
||||||
.player_info
|
.player_info
|
||||||
.get(death.userid.as_ref().unwrap())
|
.get(death.userid.as_ref().unwrap())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
// dbg!(died_user);
|
// dbg!(died_user);
|
||||||
} };
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
todo!()
|
todo!()
|
||||||
|
|||||||
Reference in New Issue
Block a user