Now keep track of entity state as well

This commit is contained in:
Lol3rrr
2024-09-21 15:42:32 +02:00
parent a6df2c2ad1
commit ba237795fd
5 changed files with 1453 additions and 1167 deletions

View File

@@ -4,6 +4,8 @@ mod fieldpath;
pub use fieldpath::{FieldPath, Paths}; pub use fieldpath::{FieldPath, Paths};
mod decoder; mod decoder;
mod entities;
mod propcontroller;
mod sendtables; mod sendtables;
mod variant; mod variant;
@@ -53,6 +55,7 @@ pub struct FirstPassOutput {
pub info: crate::csgo_proto::CDemoFileInfo, pub info: crate::csgo_proto::CDemoFileInfo,
pub events: Vec<DemoEvent>, pub events: Vec<DemoEvent>,
pub player_info: std::collections::HashMap<UserId, Player>, pub player_info: std::collections::HashMap<UserId, Player>,
pub entity_states: Vec<entities::EntityState>,
} }
#[derive(Debug)] #[derive(Debug)]
@@ -85,17 +88,22 @@ where
mapping: std::collections::HashMap::new(), mapping: std::collections::HashMap::new(),
}; };
let mut player_info = std::collections::HashMap::new(); let mut player_info = std::collections::HashMap::new();
let mut entities = std::collections::HashMap::new(); let mut entity_ctx = entities::EntityContext {
let mut cls_to_class = std::collections::HashMap::<u32, Class>::new(); entities: std::collections::HashMap::new(),
cls_to_class: std::collections::HashMap::new(),
};
let mut paths = Paths::new(); let mut paths = Paths::new();
let mut qf_mapper = decoder::QfMapper { let mut qf_mapper = decoder::QfMapper {
idx: 0, idx: 0,
map: std::collections::HashMap::new(), map: std::collections::HashMap::new(),
}; };
let mut prop_controller = propcontroller::PropController::new();
let mut serializers = std::collections::HashMap::new(); let mut serializers = std::collections::HashMap::new();
let mut baselines = std::collections::HashMap::new(); let mut baselines = std::collections::HashMap::new();
let mut entity_states = Vec::new();
for mut frame in frames.into_iter() { for mut frame in frames.into_iter() {
frame frame
.decompress() .decompress()
@@ -117,11 +125,12 @@ where
&mut events, &mut events,
&mut event_mapping, &mut event_mapping,
&mut player_info, &mut player_info,
&mut entities, &mut entity_ctx,
&mut cls_to_class,
&mut paths, &mut paths,
&mut qf_mapper, &mut qf_mapper,
&mut baselines, &mut baselines,
&prop_controller,
&mut entity_states
)?; )?;
} }
DemoCommand::FullPacket => { DemoCommand::FullPacket => {
@@ -130,11 +139,12 @@ where
&mut events, &mut events,
&mut event_mapping, &mut event_mapping,
&mut player_info, &mut player_info,
&mut entities, &mut entity_ctx,
&mut cls_to_class,
&mut paths, &mut paths,
&mut qf_mapper, &mut qf_mapper,
&mut baselines, &mut baselines,
&prop_controller,
&mut entity_states
)?; )?;
} }
// TODO // TODO
@@ -166,19 +176,23 @@ where
// std::fs::write("send_table.b", bytes.as_slice()); // std::fs::write("send_table.b", bytes.as_slice());
assert!(serializers.is_empty()); assert!(serializers.is_empty());
serializers = sendtables::get_serializers(&serializer_msg, &mut qf_mapper)?; serializers = sendtables::get_serializers(
&serializer_msg,
&mut qf_mapper,
&mut prop_controller,
)?;
} }
DemoCommand::ClassInfo => { DemoCommand::ClassInfo => {
let raw: crate::csgo_proto::CDemoClassInfo = prost::Message::decode(data)?; let raw: crate::csgo_proto::CDemoClassInfo = prost::Message::decode(data)?;
cls_to_class.clear(); entity_ctx.cls_to_class.clear();
for class_t in raw.classes { for class_t in raw.classes {
let cls_id = class_t.class_id(); let cls_id = class_t.class_id();
let network_name = class_t.network_name(); let network_name = class_t.network_name();
if let Some(ser) = serializers.remove(network_name) { if let Some(ser) = serializers.remove(network_name) {
cls_to_class.insert( entity_ctx.cls_to_class.insert(
cls_id as u32, cls_id as u32,
Class { Class {
name: network_name.to_owned(), name: network_name.to_owned(),
@@ -203,6 +217,7 @@ where
info, info,
events, events,
player_info, player_info,
entity_states,
}) })
} }
@@ -211,11 +226,12 @@ fn parse_fullpacket(
events: &mut Vec<DemoEvent>, events: &mut Vec<DemoEvent>,
event_mapper: &mut GameEventMapping, event_mapper: &mut GameEventMapping,
player_info: &mut std::collections::HashMap<UserId, Player>, player_info: &mut std::collections::HashMap<UserId, Player>,
entities: &mut std::collections::HashMap<i32, Entity>, entity_ctx: &mut entities::EntityContext,
cls_to_class: &mut std::collections::HashMap<u32, Class>,
paths: &mut Paths, paths: &mut Paths,
qf_mapper: &mut decoder::QfMapper, qf_mapper: &mut decoder::QfMapper,
baselines: &mut std::collections::HashMap<u32, Vec<u8>>, baselines: &mut std::collections::HashMap<u32, Vec<u8>>,
prop_controller: &propcontroller::PropController,
entity_states: &mut Vec<entities::EntityState>
) -> Result<(), FirstPassError> { ) -> Result<(), FirstPassError> {
let raw: crate::csgo_proto::CDemoFullPacket = prost::Message::decode(data)?; let raw: crate::csgo_proto::CDemoFullPacket = prost::Message::decode(data)?;
@@ -232,11 +248,12 @@ fn parse_fullpacket(
events, events,
event_mapper, event_mapper,
player_info, player_info,
entities, entity_ctx,
cls_to_class,
paths, paths,
qf_mapper, qf_mapper,
baselines, baselines,
prop_controller,
entity_states
)?; )?;
Ok(()) Ok(())
@@ -250,11 +267,12 @@ fn parse_packet(
events: &mut Vec<DemoEvent>, events: &mut Vec<DemoEvent>,
event_mapper: &mut GameEventMapping, event_mapper: &mut GameEventMapping,
player_info: &mut std::collections::HashMap<UserId, Player>, player_info: &mut std::collections::HashMap<UserId, Player>,
entities: &mut std::collections::HashMap<i32, Entity>, entity_ctx: &mut entities::EntityContext,
cls_to_class: &mut std::collections::HashMap<u32, Class>,
paths: &mut Paths, paths: &mut Paths,
qf_mapper: &mut decoder::QfMapper, qf_mapper: &mut decoder::QfMapper,
baselines: &mut std::collections::HashMap<u32, Vec<u8>>, baselines: &mut std::collections::HashMap<u32, Vec<u8>>,
prop_controller: &propcontroller::PropController,
entity_states: &mut Vec<entities::EntityState>
) -> Result<(), FirstPassError> { ) -> Result<(), FirstPassError> {
let raw: crate::csgo_proto::CDemoPacket = prost::Message::decode(data)?; let raw: crate::csgo_proto::CDemoPacket = prost::Message::decode(data)?;
@@ -263,11 +281,12 @@ fn parse_packet(
events, events,
event_mapper, event_mapper,
player_info, player_info,
entities, entity_ctx,
cls_to_class,
paths, paths,
qf_mapper, qf_mapper,
baselines, baselines,
prop_controller,
entity_states
)?; )?;
Ok(()) Ok(())
@@ -278,11 +297,12 @@ fn inner_parse_packet(
events: &mut Vec<DemoEvent>, events: &mut Vec<DemoEvent>,
event_mapper: &mut GameEventMapping, event_mapper: &mut GameEventMapping,
player_info: &mut std::collections::HashMap<UserId, Player>, player_info: &mut std::collections::HashMap<UserId, Player>,
entities: &mut std::collections::HashMap<i32, Entity>, entity_ctx: &mut entities::EntityContext,
cls_to_class: &mut std::collections::HashMap<u32, Class>,
paths: &mut Paths, paths: &mut Paths,
qf_mapper: &mut decoder::QfMapper, qf_mapper: &mut decoder::QfMapper,
baselines: &mut std::collections::HashMap<u32, Vec<u8>>, baselines: &mut std::collections::HashMap<u32, Vec<u8>>,
prop_controller: &propcontroller::PropController,
entity_states: &mut Vec<entities::EntityState>
) -> Result<(), FirstPassError> { ) -> Result<(), FirstPassError> {
let mut bitreader = crate::bitreader::Bitreader::new(raw.data()); let mut bitreader = crate::bitreader::Bitreader::new(raw.data());
@@ -347,34 +367,32 @@ fn inner_parse_packet(
match bitreader.read_nbits(2)? { match bitreader.read_nbits(2)? {
0b01 | 0b11 => { 0b01 | 0b11 => {
entities.remove(&entity_id); entity_ctx.entities.remove(&entity_id);
} }
0b10 => { 0b10 => {
let (id, entity) = create_entity(entity_id, &mut bitreader, baselines)?; let cls = entity_ctx.create_entity(entity_id, &mut bitreader)?;
let cls = entity.cls;
entities.insert(entity_id, entity);
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);
update_entity( let state = update_entity(
entity_id, entity_id,
&mut br, &mut br,
entities, entity_ctx,
cls_to_class,
paths, paths,
qf_mapper, qf_mapper,
prop_controller,
)?; )?;
} }
let state = update_entity(
update_entity(
entity_id, entity_id,
&mut bitreader, &mut bitreader,
entities, entity_ctx,
cls_to_class,
paths, paths,
qf_mapper, qf_mapper,
prop_controller,
)?; )?;
entity_states.push(state);
} }
0b00 => { 0b00 => {
if raw.has_pvs_vis_bits() > 0 { if raw.has_pvs_vis_bits() > 0 {
@@ -383,22 +401,21 @@ fn inner_parse_packet(
} }
} }
update_entity( let state = update_entity(
entity_id, entity_id,
&mut bitreader, &mut bitreader,
entities, entity_ctx,
cls_to_class,
paths, paths,
qf_mapper, qf_mapper,
prop_controller,
)?; )?;
entity_states.push(state);
} }
unknown => { unknown => {
panic!("{:?}", unknown); panic!("{:?}", unknown);
} }
}; };
} }
// dbg!("PacketEntities");
} }
crate::netmessagetypes::NetmessageType::svc_UserCmds => {} crate::netmessagetypes::NetmessageType::svc_UserCmds => {}
crate::netmessagetypes::NetmessageType::GE_SosStartSoundEvent => {} crate::netmessagetypes::NetmessageType::GE_SosStartSoundEvent => {}
@@ -482,84 +499,30 @@ fn inner_parse_packet(
Ok(()) Ok(())
} }
fn create_entity(
entity_id: i32,
bitreader: &mut crate::bitreader::Bitreader,
baselines: &mut std::collections::HashMap<u32, Vec<u8>>,
) -> Result<(i32, Entity), FirstPassError> {
let cls_id: u32 = bitreader.read_nbits(8)?;
let _serial = bitreader.read_nbits(17)?;
let _unknown = bitreader.read_varint()?;
Ok((entity_id, Entity { cls: cls_id }))
}
fn update_entity( fn update_entity(
entity_id: i32, entity_id: i32,
bitreader: &mut crate::bitreader::Bitreader, bitreader: &mut crate::bitreader::Bitreader,
entities: &mut std::collections::HashMap<i32, Entity>, entity_ctx: &mut entities::EntityContext,
cls_to_class: &mut std::collections::HashMap<u32, Class>,
paths: &mut Paths, paths: &mut Paths,
qf_mapper: &mut decoder::QfMapper, qf_mapper: &mut decoder::QfMapper,
) -> Result<(), FirstPassError> { prop_controller: &propcontroller::PropController,
) -> Result<entities::EntityState, FirstPassError> {
let n_updates = fieldpath::parse_paths(bitreader, paths)?; let n_updates = fieldpath::parse_paths(bitreader, paths)?;
let n_updated_values = decode_entity_update( let (n_updated_values, entity_state) = entity_ctx.decode_entity_update(
entity_id, entity_id,
bitreader, bitreader,
n_updates, n_updates,
entities,
cls_to_class,
paths, paths,
qf_mapper, qf_mapper,
prop_controller,
)?; )?;
if n_updated_values > 0 { if n_updated_values > 0 {
gather_extra_info()?;
}
Ok(())
}
fn gather_extra_info() -> Result<(), FirstPassError> {
// TODO // TODO
// Gather extra information
Ok(()) // gather_extra_info(entity_id, prop_controller)?;
}
fn decode_entity_update(
entity_id: i32,
bitreader: &mut crate::bitreader::Bitreader,
n_updates: usize,
entities: &mut std::collections::HashMap<i32, Entity>,
cls_to_class: &mut std::collections::HashMap<u32, Class>,
paths: &mut Paths,
qf_mapper: &mut decoder::QfMapper,
) -> Result<usize, FirstPassError> {
let entity = match entities.get_mut(&entity_id) {
Some(e) => e,
None => panic!("ID: {:?} - Entities: {:?}", entity_id, entities),
};
let class = match cls_to_class.get_mut(&entity.cls) {
Some(c) => c,
None => panic!(),
};
// dbg!(&class.name);
for path in paths.paths().take(n_updates) {
// dbg!(&path);
let field = path.find(&class.serializer)?;
let field_info = field.get_propinfo(path);
let decoder = field.get_decoder()?;
let result = decoder.decode(bitreader, qf_mapper)?;
// dbg!(&field, &field_info, &decoder, &result);
if let Some(fi) = field_info {
// dbg!(&fi);
}
} }
Ok(n_updates) Ok(entity_state)
} }
static HUFFMAN_LOOKUP_TABLE: std::sync::LazyLock<Vec<(u8, u8)>> = std::sync::LazyLock::new(|| { static HUFFMAN_LOOKUP_TABLE: std::sync::LazyLock<Vec<(u8, u8)>> = std::sync::LazyLock::new(|| {
@@ -570,54 +533,3 @@ static HUFFMAN_LOOKUP_TABLE: std::sync::LazyLock<Vec<(u8, u8)>> = std::sync::Laz
} }
huf2 huf2
}); });
fn do_op(
symbol: u8,
bitreader: &mut crate::bitreader::Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
use fieldpath::ops::*;
match symbol {
0 => plus_one(bitreader, field_path),
1 => plus_two(bitreader, field_path),
2 => plus_three(bitreader, field_path),
3 => plus_four(bitreader, field_path),
4 => plus_n(bitreader, field_path),
5 => push_one_left_delta_zero_right_zero(bitreader, field_path),
6 => push_one_left_delta_zero_right_non_zero(bitreader, field_path),
7 => push_one_left_delta_one_right_zero(bitreader, field_path),
8 => push_one_left_delta_one_right_non_zero(bitreader, field_path),
9 => push_one_left_delta_n_right_zero(bitreader, field_path),
10 => push_one_left_delta_n_right_non_zero(bitreader, field_path),
11 => push_one_left_delta_n_right_non_zero_pack6_bits(bitreader, field_path),
12 => push_one_left_delta_n_right_non_zero_pack8_bits(bitreader, field_path),
13 => push_two_left_delta_zero(bitreader, field_path),
14 => push_two_pack5_left_delta_zero(bitreader, field_path),
15 => push_three_left_delta_zero(bitreader, field_path),
16 => push_three_pack5_left_delta_zero(bitreader, field_path),
17 => push_two_left_delta_one(bitreader, field_path),
18 => push_two_pack5_left_delta_one(bitreader, field_path),
19 => push_three_left_delta_one(bitreader, field_path),
20 => push_three_pack5_left_delta_one(bitreader, field_path),
21 => push_two_left_delta_n(bitreader, field_path),
22 => push_two_pack5_left_delta_n(bitreader, field_path),
23 => push_three_left_delta_n(bitreader, field_path),
24 => push_three_pack5_left_delta_n(bitreader, field_path),
25 => push_n(bitreader, field_path),
26 => push_n_and_non_topological(bitreader, field_path),
27 => pop_one_plus_one(bitreader, field_path),
28 => pop_one_plus_n(bitreader, field_path),
29 => pop_all_but_one_plus_one(bitreader, field_path),
30 => pop_all_but_one_plus_n(bitreader, field_path),
31 => pop_all_but_one_plus_n_pack3_bits(bitreader, field_path),
32 => pop_all_but_one_plus_n_pack6_bits(bitreader, field_path),
33 => pop_n_plus_one(bitreader, field_path),
34 => pop_n_plus_n(bitreader, field_path),
35 => pop_n_and_non_topographical(bitreader, field_path),
36 => non_topo_complex(bitreader, field_path),
37 => non_topo_penultimate_plus_one(bitreader, field_path),
38 => non_topo_complex_pack4_bits(bitreader, field_path),
other => todo!("Other OP: {:?}", other),
}
}

82
src/parser/entities.rs Normal file
View File

@@ -0,0 +1,82 @@
use super::{decoder, propcontroller, Class, Entity, FirstPassError, Paths};
pub struct EntityContext {
pub entities: std::collections::HashMap<i32, Entity>,
pub cls_to_class: std::collections::HashMap<u32, Class>,
}
#[derive(Debug, Clone)]
pub struct EntityState {
pub class: String,
pub cls: u32,
pub props: Vec<EntityProp>,
}
#[derive(Debug, Clone)]
pub struct EntityProp {
pub field_info: super::sendtables::FieldInfo,
pub prop_info: super::propcontroller::PropInfo,
pub value: super::variant::Variant,
}
impl EntityContext {
/// Returns the `cls_id`
pub fn create_entity(&mut self, entity_id: i32, bitreader: &mut crate::bitreader::Bitreader) -> Result<u32, super::FirstPassError> {
let cls_id: u32 = bitreader.read_nbits(8)?;
let _serial = bitreader.read_nbits(17)?;
let _unknown = bitreader.read_varint()?;
self.entities.insert(entity_id, Entity {
cls: cls_id,
});
Ok(cls_id)
}
pub fn decode_entity_update(
&mut self,
entity_id: i32,
bitreader: &mut crate::bitreader::Bitreader,
n_updates: usize,
paths: &mut Paths,
qf_mapper: &mut decoder::QfMapper,
prop_controller: &propcontroller::PropController,
) -> Result<(usize, EntityState), FirstPassError> {
let entity = match self.entities.get_mut(&entity_id) {
Some(e) => e,
None => panic!("ID: {:?} - Entities: {:?}", entity_id, self.entities),
};
let class = match self.cls_to_class.get_mut(&entity.cls) {
Some(c) => c,
None => panic!(),
};
let mut fields = Vec::new();
for path in paths.paths().take(n_updates) {
let field = path.find(&class.serializer)?;
let field_info = field.get_propinfo(path);
let decoder = field.get_decoder()?;
let result = decoder.decode(bitreader, qf_mapper)?;
if let Some(fi) = field_info {
if let Some(prop_info) = prop_controller
.prop_infos
.iter()
.find(|pi| fi.prop_id == pi.id)
{
fields.push(EntityProp {
field_info: fi,
prop_info: prop_info.clone(),
value: result,
});
}
}
}
Ok((n_updates, EntityState {
class: class.name.clone(),
cls: entity.cls,
props: fields,
}))
}
}

View File

@@ -56,7 +56,7 @@ pub fn parse_paths(
break; break;
} }
super::do_op(symbol, bitreader, &mut path)?; path.do_op(bitreader, symbol)?;
paths.write(&path, idx); paths.write(&path, idx);
idx += 1; idx += 1;
} }
@@ -92,119 +92,213 @@ impl FieldPath {
match self.last { match self.last {
0 => Ok(f), 0 => Ok(f),
1 => Ok(f.get_inner(self.path[1] as usize)?), 1 => Ok(f.get_inner(self.path[1] as usize)?),
2 => Ok(f.get_inner(self.path[1] as usize)?.get_inner(self.path[2] as usize)?), 2 => Ok(f
3 => Ok(f.get_inner(self.path[1] as usize)?.get_inner(self.path[2] as usize)?.get_inner(self.path[3] as usize)?), .get_inner(self.path[1] as usize)?
.get_inner(self.path[2] as usize)?),
3 => Ok(f
.get_inner(self.path[1] as usize)?
.get_inner(self.path[2] as usize)?
.get_inner(self.path[3] as usize)?),
other => panic!("{:?}", other), other => panic!("{:?}", other),
} }
} }
pub fn do_op(&mut self, bitreader: &mut crate::bitreader::Bitreader, symbol: u8) -> Result<(), super::FirstPassError> {
use ops::*;
match symbol {
0 => plus_one(bitreader, self),
1 => plus_two(bitreader, self),
2 => plus_three(bitreader, self),
3 => plus_four(bitreader, self),
4 => plus_n(bitreader, self),
5 => push_one_left_delta_zero_right_zero(bitreader, self),
6 => push_one_left_delta_zero_right_non_zero(bitreader, self),
7 => push_one_left_delta_one_right_zero(bitreader, self),
8 => push_one_left_delta_one_right_non_zero(bitreader, self),
9 => push_one_left_delta_n_right_zero(bitreader, self),
10 => push_one_left_delta_n_right_non_zero(bitreader, self),
11 => push_one_left_delta_n_right_non_zero_pack6_bits(bitreader, self),
12 => push_one_left_delta_n_right_non_zero_pack8_bits(bitreader, self),
13 => push_two_left_delta_zero(bitreader, self),
14 => push_two_pack5_left_delta_zero(bitreader, self),
15 => push_three_left_delta_zero(bitreader, self),
16 => push_three_pack5_left_delta_zero(bitreader, self),
17 => push_two_left_delta_one(bitreader, self),
18 => push_two_pack5_left_delta_one(bitreader, self),
19 => push_three_left_delta_one(bitreader, self),
20 => push_three_pack5_left_delta_one(bitreader, self),
21 => push_two_left_delta_n(bitreader, self),
22 => push_two_pack5_left_delta_n(bitreader, self),
23 => push_three_left_delta_n(bitreader, self),
24 => push_three_pack5_left_delta_n(bitreader, self),
25 => push_n(bitreader, self),
26 => push_n_and_non_topological(bitreader, self),
27 => pop_one_plus_one(bitreader, self),
28 => pop_one_plus_n(bitreader, self),
29 => pop_all_but_one_plus_one(bitreader, self),
30 => pop_all_but_one_plus_n(bitreader, self),
31 => pop_all_but_one_plus_n_pack3_bits(bitreader, self),
32 => pop_all_but_one_plus_n_pack6_bits(bitreader, self),
33 => pop_n_plus_one(bitreader, self),
34 => pop_n_plus_n(bitreader, self),
35 => pop_n_and_non_topographical(bitreader, self),
36 => non_topo_complex(bitreader, self),
37 => non_topo_penultimate_plus_one(bitreader, self),
38 => non_topo_complex_pack4_bits(bitreader, self),
other => todo!("Other OP: {:?}", other),
}
}
} }
pub mod ops { pub mod ops {
use super::FieldPath; use super::FieldPath;
use crate::{bitreader::Bitreader, parser::FirstPassError}; use crate::{bitreader::Bitreader, parser::FirstPassError};
pub fn plus_one(_bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn plus_one(
_bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 1; *field_path.get_entry_mut(field_path.last)? += 1;
Ok(()) Ok(())
} }
pub fn plus_two(_bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn plus_two(
_bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 2; *field_path.get_entry_mut(field_path.last)? += 2;
Ok(()) Ok(())
} }
pub fn plus_three(_bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn plus_three(
_bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 3; *field_path.get_entry_mut(field_path.last)? += 3;
Ok(()) Ok(())
} }
pub fn plus_four(_bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn plus_four(
_bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 4; *field_path.get_entry_mut(field_path.last)? += 4;
Ok(()) Ok(())
} }
pub fn plus_n(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn plus_n(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32 + 5; *field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32 + 5;
Ok(()) Ok(())
} }
pub fn push_one_left_delta_zero_right_zero(_bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_one_left_delta_zero_right_zero(
_bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = 0; *field_path.get_entry_mut(field_path.last)? = 0;
Ok(()) Ok(())
} }
pub fn push_one_left_delta_zero_right_non_zero(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_one_left_delta_zero_right_non_zero(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
Ok(()) Ok(())
} }
pub fn push_one_left_delta_one_right_zero(_bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_one_left_delta_one_right_zero(
_bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 1; *field_path.get_entry_mut(field_path.last)? += 1;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = 0; *field_path.get_entry_mut(field_path.last)? = 0;
Ok(()) Ok(())
} }
pub fn push_one_left_delta_one_right_non_zero(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_one_left_delta_one_right_non_zero(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 1; *field_path.get_entry_mut(field_path.last)? += 1;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = bitreader.read_ubit_var_fp()? as i32; *field_path.get_entry_mut(field_path.last)? = bitreader.read_ubit_var_fp()? as i32;
Ok(()) Ok(())
} }
pub fn push_one_left_delta_n_right_zero(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_one_left_delta_n_right_zero(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = 0; *field_path.get_entry_mut(field_path.last)? = 0;
Ok(()) Ok(())
} }
pub fn push_one_left_delta_n_right_non_zero(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_one_left_delta_n_right_non_zero(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32 + 2; *field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32 + 2;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = bitreader.read_ubit_var_fp()? as i32 + 1; *field_path.get_entry_mut(field_path.last)? = bitreader.read_ubit_var_fp()? as i32 + 1;
Ok(()) Ok(())
} }
pub fn push_one_left_delta_n_right_non_zero_pack6_bits( pub fn push_one_left_delta_n_right_non_zero_pack6_bits(
bitreader: &mut Bitreader, bitreader: &mut Bitreader,
field_path: &mut FieldPath, field_path: &mut FieldPath,
) -> Result<(), FirstPassError> { ) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += (bitreader.read_nbits(3)? + 2) as i32; *field_path.get_entry_mut(field_path.last)? += (bitreader.read_nbits(3)? + 2) as i32;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = (bitreader.read_nbits(3)? + 1) as i32; *field_path.get_entry_mut(field_path.last)? = (bitreader.read_nbits(3)? + 1) as i32;
Ok(()) Ok(())
} }
pub fn push_one_left_delta_n_right_non_zero_pack8_bits( pub fn push_one_left_delta_n_right_non_zero_pack8_bits(
bitreader: &mut Bitreader, bitreader: &mut Bitreader,
field_path: &mut FieldPath, field_path: &mut FieldPath,
) -> Result<(), FirstPassError> { ) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += (bitreader.read_nbits(4)? + 2) as i32; *field_path.get_entry_mut(field_path.last)? += (bitreader.read_nbits(4)? + 2) as i32;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = (bitreader.read_nbits(4)? + 1) as i32; *field_path.get_entry_mut(field_path.last)? = (bitreader.read_nbits(4)? + 1) as i32;
Ok(()) Ok(())
} }
pub fn push_two_left_delta_zero(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_two_left_delta_zero(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
Ok(()) Ok(())
} }
pub fn push_two_pack5_left_delta_zero(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_two_pack5_left_delta_zero(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = bitreader.read_nbits(5)? as i32; *field_path.get_entry_mut(field_path.last)? = bitreader.read_nbits(5)? as i32;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = bitreader.read_nbits(5)? as i32; *field_path.get_entry_mut(field_path.last)? = bitreader.read_nbits(5)? as i32;
Ok(()) Ok(())
} }
pub fn push_three_left_delta_zero(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_three_left_delta_zero(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
field_path.last += 1; field_path.last += 1;
@@ -212,9 +306,12 @@ pub fn push_three_left_delta_zero(bitreader: &mut Bitreader, field_path: &mut Fi
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
Ok(()) Ok(())
} }
pub fn push_three_pack5_left_delta_zero(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_three_pack5_left_delta_zero(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = bitreader.read_nbits(5)? as i32; *field_path.get_entry_mut(field_path.last)? = bitreader.read_nbits(5)? as i32;
field_path.last += 1; field_path.last += 1;
@@ -222,27 +319,36 @@ pub fn push_three_pack5_left_delta_zero(bitreader: &mut Bitreader, field_path: &
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = bitreader.read_nbits(5)? as i32; *field_path.get_entry_mut(field_path.last)? = bitreader.read_nbits(5)? as i32;
Ok(()) Ok(())
} }
pub fn push_two_left_delta_one(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_two_left_delta_one(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 1; *field_path.get_entry_mut(field_path.last)? += 1;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
Ok(()) Ok(())
} }
pub fn push_two_pack5_left_delta_one(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_two_pack5_left_delta_one(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 1; *field_path.get_entry_mut(field_path.last)? += 1;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32;
Ok(()) Ok(())
} }
pub fn push_three_left_delta_one(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_three_left_delta_one(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 1; *field_path.get_entry_mut(field_path.last)? += 1;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
@@ -251,9 +357,12 @@ pub fn push_three_left_delta_one(bitreader: &mut Bitreader, field_path: &mut Fie
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
Ok(()) Ok(())
} }
pub fn push_three_pack5_left_delta_one(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_three_pack5_left_delta_one(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 1; *field_path.get_entry_mut(field_path.last)? += 1;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32;
@@ -262,27 +371,36 @@ pub fn push_three_pack5_left_delta_one(bitreader: &mut Bitreader, field_path: &m
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32;
Ok(()) Ok(())
} }
pub fn push_two_left_delta_n(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_two_left_delta_n(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += (bitreader.read_u_bit_var()? + 2) as i32; *field_path.get_entry_mut(field_path.last)? += (bitreader.read_u_bit_var()? + 2) as i32;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
Ok(()) Ok(())
} }
pub fn push_two_pack5_left_delta_n(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_two_pack5_left_delta_n(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += (bitreader.read_u_bit_var()? + 2) as i32; *field_path.get_entry_mut(field_path.last)? += (bitreader.read_u_bit_var()? + 2) as i32;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32;
Ok(()) Ok(())
} }
pub fn push_three_left_delta_n(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_three_left_delta_n(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += (bitreader.read_u_bit_var()? + 2) as i32; *field_path.get_entry_mut(field_path.last)? += (bitreader.read_u_bit_var()? + 2) as i32;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
@@ -291,9 +409,12 @@ pub fn push_three_left_delta_n(bitreader: &mut Bitreader, field_path: &mut Field
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
Ok(()) Ok(())
} }
pub fn push_three_pack5_left_delta_n(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_three_pack5_left_delta_n(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += (bitreader.read_u_bit_var()? + 2) as i32; *field_path.get_entry_mut(field_path.last)? += (bitreader.read_u_bit_var()? + 2) as i32;
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32;
@@ -302,9 +423,12 @@ pub fn push_three_pack5_left_delta_n(bitreader: &mut Bitreader, field_path: &mut
field_path.last += 1; field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32;
Ok(()) Ok(())
} }
pub fn push_n(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_n(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
let n = bitreader.read_u_bit_var()? as i32; let n = bitreader.read_u_bit_var()? as i32;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_u_bit_var()? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_u_bit_var()? as i32;
for _ in 0..n { for _ in 0..n {
@@ -312,9 +436,12 @@ pub fn push_n(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32; *field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
} }
Ok(()) Ok(())
} }
pub fn push_n_and_non_topological(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn push_n_and_non_topological(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
for i in 0..field_path.last + 1 { for i in 0..field_path.last + 1 {
if bitreader.read_boolean()? { if bitreader.read_boolean()? {
*field_path.get_entry_mut(i)? += bitreader.read_varint32()? + 1; *field_path.get_entry_mut(i)? += bitreader.read_varint32()? + 1;
@@ -326,57 +453,84 @@ pub fn push_n_and_non_topological(bitreader: &mut Bitreader, field_path: &mut Fi
*field_path.get_entry_mut(field_path.last)? = bitreader.read_ubit_var_fp()? as i32; *field_path.get_entry_mut(field_path.last)? = bitreader.read_ubit_var_fp()? as i32;
} }
Ok(()) Ok(())
} }
pub fn pop_one_plus_one(_bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn pop_one_plus_one(
_bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
field_path.pop_special(1)?; field_path.pop_special(1)?;
*field_path.get_entry_mut(field_path.last)? += 1; *field_path.get_entry_mut(field_path.last)? += 1;
Ok(()) Ok(())
} }
pub fn pop_one_plus_n(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn pop_one_plus_n(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
field_path.pop_special(1)?; field_path.pop_special(1)?;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32 + 1; *field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32 + 1;
Ok(()) Ok(())
} }
pub fn pop_all_but_one_plus_one(_bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn pop_all_but_one_plus_one(
_bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
field_path.pop_special(field_path.last)?; field_path.pop_special(field_path.last)?;
*field_path.get_entry_mut(0)? += 1; *field_path.get_entry_mut(0)? += 1;
Ok(()) Ok(())
} }
pub fn pop_all_but_one_plus_n(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn pop_all_but_one_plus_n(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
field_path.pop_special(field_path.last)?; field_path.pop_special(field_path.last)?;
*field_path.get_entry_mut(0)? += bitreader.read_ubit_var_fp()? as i32 + 1; *field_path.get_entry_mut(0)? += bitreader.read_ubit_var_fp()? as i32 + 1;
Ok(()) Ok(())
} }
pub fn pop_all_but_one_plus_n_pack3_bits(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn pop_all_but_one_plus_n_pack3_bits(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
field_path.pop_special(field_path.last)?; field_path.pop_special(field_path.last)?;
*field_path.get_entry_mut(0)? += bitreader.read_nbits(3)? as i32 + 1; *field_path.get_entry_mut(0)? += bitreader.read_nbits(3)? as i32 + 1;
Ok(()) Ok(())
} }
pub fn pop_all_but_one_plus_n_pack6_bits(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn pop_all_but_one_plus_n_pack6_bits(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
field_path.pop_special(field_path.last)?; field_path.pop_special(field_path.last)?;
*field_path.get_entry_mut(0)? += bitreader.read_nbits(6)? as i32 + 1; *field_path.get_entry_mut(0)? += bitreader.read_nbits(6)? as i32 + 1;
Ok(()) Ok(())
} }
pub fn pop_n_plus_one(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn pop_n_plus_one(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
field_path.pop_special(bitreader.read_ubit_var_fp()? as usize)?; field_path.pop_special(bitreader.read_ubit_var_fp()? as usize)?;
*field_path.get_entry_mut(field_path.last)? += 1; *field_path.get_entry_mut(field_path.last)? += 1;
Ok(()) Ok(())
} }
pub fn pop_n_plus_n(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn pop_n_plus_n(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
field_path.pop_special(bitreader.read_ubit_var_fp()? as usize)?; field_path.pop_special(bitreader.read_ubit_var_fp()? as usize)?;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_varint32()?; *field_path.get_entry_mut(field_path.last)? += bitreader.read_varint32()?;
Ok(()) Ok(())
} }
pub fn pop_n_and_non_topographical(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn pop_n_and_non_topographical(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
field_path.pop_special(bitreader.read_ubit_var_fp()? as usize)?; field_path.pop_special(bitreader.read_ubit_var_fp()? as usize)?;
for i in 0..field_path.last + 1 { for i in 0..field_path.last + 1 {
if bitreader.read_boolean()? { if bitreader.read_boolean()? {
@@ -384,28 +538,37 @@ pub fn pop_n_and_non_topographical(bitreader: &mut Bitreader, field_path: &mut F
} }
} }
Ok(()) Ok(())
} }
pub fn non_topo_complex(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn non_topo_complex(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
for i in 0..field_path.last + 1 { for i in 0..field_path.last + 1 {
if bitreader.read_boolean()? { if bitreader.read_boolean()? {
*field_path.get_entry_mut(i)? += bitreader.read_varint32()?; *field_path.get_entry_mut(i)? += bitreader.read_varint32()?;
} }
} }
Ok(()) Ok(())
} }
pub fn non_topo_penultimate_plus_one(_bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn non_topo_penultimate_plus_one(
_bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last - 1)? += 1; *field_path.get_entry_mut(field_path.last - 1)? += 1;
Ok(()) Ok(())
} }
pub fn non_topo_complex_pack4_bits(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> { pub fn non_topo_complex_pack4_bits(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
for i in 0..field_path.last + 1 { for i in 0..field_path.last + 1 {
if bitreader.read_boolean()? { if bitreader.read_boolean()? {
*field_path.get_entry_mut(i)? += bitreader.read_nbits(4)? as i32 - 7; *field_path.get_entry_mut(i)? += bitreader.read_nbits(4)? as i32 - 7;
} }
} }
Ok(()) Ok(())
} }
} }

View File

@@ -0,0 +1,298 @@
pub const PLAYER_ENTITY_HANDLE_MISSING: i32 = 2047;
pub const SPECTATOR_TEAM_NUM: u32 = 1;
pub const BUTTONS_BASEID: u32 = 100000;
pub const NORMAL_PROP_BASEID: u32 = 1000;
pub const WEAPON_SKIN_NAME: u32 = 420420420;
pub const WEAPON_ORIGINGAL_OWNER_ID: u32 = 6942000;
pub const MY_WEAPONS_OFFSET: u32 = 500000;
pub const GRENADE_AMMO_ID: u32 = 1111111;
pub const INVENTORY_ID: u32 = 100000000;
pub const IS_ALIVE_ID: u32 = 100000001;
pub const GAME_TIME_ID: u32 = 100000002;
pub const ENTITY_ID_ID: u32 = 100000003;
pub const VELOCITY_X_ID: u32 = 100000004;
pub const VELOCITY_Y_ID: u32 = 100000005;
pub const VELOCITY_Z_ID: u32 = 100000006;
pub const VELOCITY_ID: u32 = 100000007;
pub const USERID_ID: u32 = 100000008;
pub const AGENT_SKIN_ID: u32 = 100000009;
pub const WEAPON_NAME_ID: u32 = 100000010;
pub const YAW_ID: u32 = 100000111;
pub const PITCH_ID: u32 = 100000012;
pub const TICK_ID: u32 = 100000013;
pub const STEAMID_ID: u32 = 100000014;
pub const NAME_ID: u32 = 100000015;
pub const PLAYER_X_ID: u32 = 100000016;
pub const PLAYER_Y_ID: u32 = 100000017;
pub const PLAYER_Z_ID: u32 = 100000018;
pub const WEAPON_STICKERS_ID: u32 = 100000019;
pub const INVENTORY_AS_IDS_ID: u32 = 100000020;
pub const IS_AIRBORNE_ID: u32 = 100000021;
pub const WEAPON_SKIN_ID: u32 = 10000000;
pub const WEAPON_PAINT_SEED: u32 = 10000001;
pub const WEAPON_FLOAT: u32 = 10000002;
pub const ITEM_PURCHASE_COUNT: u32 = 200000000;
pub const ITEM_PURCHASE_DEF_IDX: u32 = 300000000;
pub const ITEM_PURCHASE_COST: u32 = 400000000;
pub const ITEM_PURCHASE_HANDLE: u32 = 500000000;
pub const ITEM_PURCHASE_NEW_DEF_IDX: u32 = 600000000;
pub const FLATTENED_VEC_MAX_LEN: u32 = 100000;
pub const USERCMD_VIEWANGLE_X: u32 = 100000022;
pub const USERCMD_VIEWANGLE_Y: u32 = 100000023;
pub const USERCMD_VIEWANGLE_Z: u32 = 100000024;
pub const USERCMD_FORWARDMOVE: u32 = 100000025;
pub const USERCMD_IMPULSE: u32 = 100000026;
pub const USERCMD_MOUSE_DX: u32 = 100000027;
pub const USERCMD_MOUSE_DY: u32 = 100000028;
pub const USERCMD_BUTTONSTATE_1: u32 = 100000029;
pub const USERCMD_BUTTONSTATE_2: u32 = 100000030;
pub const USERCMD_BUTTONSTATE_3: u32 = 100000031;
pub const USERCMD_CONSUMED_SERVER_ANGLE_CHANGES: u32 = 100000032;
pub const USERCMD_LEFTMOVE: u32 = 100000033;
pub const USERCMD_WEAPON_SELECT: u32 = 100000034;
pub const USERCMD_SUBTICK_MOVE_ANALOG_FORWARD_DELTA: u32 = 100000035;
pub const USERCMD_SUBTICK_MOVE_ANALOG_LEFT_DELTA: u32 = 100000036;
pub const USERCMD_SUBTICK_MOVE_BUTTON: u32 = 100000037;
pub const USERCMD_SUBTICK_MOVE_WHEN: u32 = 100000038;
pub const USERCMD_SUBTICK_LEFT_HAND_DESIRED: u32 = 100000039;
pub const USERCMD_ATTACK_START_HISTORY_INDEX_1: u32 = 100000040;
pub const USERCMD_ATTACK_START_HISTORY_INDEX_2: u32 = 100000041;
pub const USERCMD_ATTACK_START_HISTORY_INDEX_3: u32 = 100000042;
pub const USERCMD_INPUT_HISTORY_BASEID: u32 = 100001000;
pub const INPUT_HISTORY_X_OFFSET: u32 = 0;
pub const INPUT_HISTORY_Y_OFFSET: u32 = 1;
pub const INPUT_HISTORY_Z_OFFSET: u32 = 2;
pub const INPUT_HISTORY_RENDER_TICK_COUNT_OFFSET: u32 = 3;
pub const INPUT_HISTORY_RENDER_TICK_FRACTION_OFFSET: u32 = 4;
pub const INPUT_HISTORY_PLAYER_TICK_COUNT_OFFSET: u32 = 5;
pub const INPUT_HISTORY_PLAYER_TICK_FRACTION_OFFSET: u32 = 6;
use super::sendtables::{Field, ValueField};
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct PropController {
pub id: u32,
pub special_ids: SpecialIDs,
pub name_to_id: HashMap<String, u32>,
pub id_to_name: HashMap<u32, String>,
pub path_to_name: HashMap<[i32; 7], String>,
pub prop_infos: Vec<PropInfo>,
}
#[derive(Debug, Clone)]
pub struct SpecialIDs {}
#[derive(Debug, Clone)]
pub struct PropInfo {
pub id: u32,
// pub prop_type: PropType,
pub prop_name: String,
// pub prop_friendly_name: String,
// pub is_player_prop: bool
}
impl PropController {
pub fn new() -> Self {
Self {
id: NORMAL_PROP_BASEID,
special_ids: SpecialIDs::new(),
name_to_id: HashMap::new(),
id_to_name: HashMap::new(),
path_to_name: HashMap::new(),
prop_infos: Vec::new(),
}
}
pub fn find_prop_name_paths(&mut self, serializer: &mut super::sendtables::Serializer) {
self.traverse_fields(&mut serializer.fields, serializer.name.clone(), Vec::new())
}
fn traverse_fields(&mut self, fields: &mut Vec<Field>, ser_name: String, path_og: Vec<i32>) {
for (idx, f) in fields.iter_mut().enumerate() {
let mut path = path_og.clone();
path.push(idx as i32);
match f {
Field::Value(x) => {
let full_name = ser_name.clone() + "." + &x.name;
self.handle_prop(&full_name, x, path);
}
Field::Serializer(ser) => {
self.traverse_fields(
&mut ser.serializer.fields,
ser_name.clone() + "." + &ser.serializer.name,
path.clone(),
);
}
Field::Pointer(ser) => {
self.traverse_fields(
&mut ser.serializer.fields,
ser_name.clone() + "." + &ser.serializer.name,
path.clone(),
);
}
Field::Array(ser) => match &mut ser.field_enum.as_mut() {
Field::Value(v) => {
self.handle_prop(&(ser_name.clone() + "." + &v.name), v, path);
}
_ => {}
},
Field::Vector(_x) => {
let vec_path = path.clone();
if let Ok(inner) = f.get_inner_mut(0) {
match inner {
Field::Serializer(s) => {
for (inner_idx, f) in
&mut s.serializer.fields.iter_mut().enumerate()
{
match f {
Field::Value(v) => {
let mut myp = vec_path.clone();
myp.push(inner_idx as i32);
self.handle_prop(
&(ser_name.clone() + "." + &v.name),
v,
myp,
);
}
_ => {}
}
}
self.traverse_fields(
&mut s.serializer.fields,
ser_name.clone() + "." + &s.serializer.name,
path_og.clone(),
)
}
Field::Value(x) => {
self.handle_prop(
&(ser_name.clone() + "." + &x.name),
x,
path.clone(),
);
}
_ => {}
}
}
}
Field::None => {}
};
}
}
fn handle_prop(&mut self, full_name: &str, f: &mut ValueField, path: Vec<i32>) {
f.full_name = full_name.to_owned();
// CAK47.m_iClip1 => ["CAK47", "m_iClip1"]
let split_at_dot: Vec<&str> = full_name.split(".").collect();
let is_weapon_prop = (split_at_dot[0].contains("Weapon") || split_at_dot[0].contains("AK"))
&& !split_at_dot[0].contains("Player")
|| split_at_dot[0].contains("Knife")
|| split_at_dot[0].contains("CDEagle")
|| split_at_dot[0].contains("C4")
|| split_at_dot[0].contains("Molo")
|| split_at_dot[0].contains("Inc")
|| split_at_dot[0].contains("Infer");
let is_projectile_prop = (split_at_dot[0].contains("Projectile")
|| split_at_dot[0].contains("Grenade")
|| split_at_dot[0].contains("Flash"))
&& !split_at_dot[0].contains("Player");
let is_grenade_or_weapon = is_weapon_prop || is_projectile_prop;
// Strip first part of name from grenades and weapons.
// if weapon prop: CAK47.m_iClip1 => m_iClip1
// if grenade: CSmokeGrenadeProjectile.CBodyComponentBaseAnimGraph.m_cellX => CBodyComponentBaseAnimGraph.m_cellX
let prop_name = match is_grenade_or_weapon {
true => split_at_dot[1..].join("."),
false => full_name.to_string(),
};
let mut a = [0, 0, 0, 0, 0, 0, 0];
for (idx, v) in path.iter().enumerate() {
a[idx] = *v;
}
self.path_to_name.insert(a, prop_name.to_string());
let prop_already_exists = self.name_to_id.contains_key(&(prop_name).to_string());
self.set_id(&prop_name, f, is_grenade_or_weapon);
if !prop_already_exists {
self.insert_propinfo(&prop_name, f);
}
f.should_parse = true;
if full_name == "CCSPlayerPawn.CCSPlayer_WeaponServices.m_hMyWeapons" {
f.prop_id = MY_WEAPONS_OFFSET as u32;
}
if full_name
== "CCSPlayerPawn.CCSPlayer_ActionTrackingServices.WeaponPurchaseCount_t.m_nCount"
{
f.prop_id = ITEM_PURCHASE_COUNT as u32;
}
if full_name == "CCSPlayerPawn.CCSPlayer_BuyServices.SellbackPurchaseEntry_t.m_unDefIdx" {
f.prop_id = ITEM_PURCHASE_DEF_IDX as u32;
}
if full_name == "CCSPlayerPawn.CCSPlayer_BuyServices.SellbackPurchaseEntry_t.m_nCost" {
f.prop_id = ITEM_PURCHASE_COST as u32;
}
if full_name == "CCSPlayerPawn.CCSPlayer_ActionTrackingServices.WeaponPurchaseCount_t.m_nItemDefIndex" {
f.prop_id = ITEM_PURCHASE_NEW_DEF_IDX as u32;
}
if full_name == "CCSPlayerPawn.CCSPlayer_BuyServices.SellbackPurchaseEntry_t.m_hItem" {
f.prop_id = ITEM_PURCHASE_HANDLE as u32;
}
if prop_name.contains("CEconItemAttribute.m_iRawValue32") {
f.prop_id = WEAPON_SKIN_ID as u32;
}
self.id += 1;
}
fn set_id(&mut self, weap_prop: &str, f: &mut ValueField, is_grenade_or_weapon: bool) {
match self.name_to_id.get(weap_prop) {
// If we already have an id for prop of same name then use that id.
// Mainly for weapon props. For example CAK47.m_iClip1 and CWeaponSCAR20.m_iClip1
// are the "same" prop. (they have same path and we want to refer to it with one id not ~20)
Some(id) => {
f.prop_id = *id as u32;
self.id_to_name.insert(*id, weap_prop.to_string());
self.set_special_ids(&weap_prop, is_grenade_or_weapon, *id);
return;
}
None => {
self.name_to_id.insert(weap_prop.to_string(), self.id);
self.id_to_name.insert(self.id, weap_prop.to_string());
f.prop_id = self.id as u32;
self.set_special_ids(&weap_prop, is_grenade_or_weapon, self.id);
}
}
}
fn insert_propinfo(&mut self, prop_name: &str, f: &mut ValueField) {
self.prop_infos.push(PropInfo {
id: f.prop_id as u32,
prop_name: prop_name.to_string(),
});
}
pub fn set_special_ids(&mut self, weap_prop: &str, is_grenade_or_weapon: bool, id: u32) {
// TODO
if is_grenade_or_weapon {
match weap_prop {
_ => {}
};
} else {
match weap_prop {
_ => {}
};
}
}
}
impl SpecialIDs {
pub fn new() -> Self {
Self {}
}
}

File diff suppressed because it is too large Load Diff