Skip to content

Commit

Permalink
refactors to second pass
Browse files Browse the repository at this point in the history
  • Loading branch information
LaihoE committed Aug 4, 2024
1 parent f78c6ad commit de9e015
Show file tree
Hide file tree
Showing 7 changed files with 451 additions and 406 deletions.
103 changes: 103 additions & 0 deletions src/parser/src/first_pass/sendtables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,20 @@ use super::read_bits::DemoParserError;
use crate::first_pass::parser_settings::needs_velocity;
use crate::first_pass::parser_settings::FirstPassParser;
use crate::first_pass::prop_controller::PropController;
use crate::first_pass::prop_controller::FLATTENED_VEC_MAX_LEN;
use crate::first_pass::prop_controller::ITEM_PURCHASE_COST;
use crate::first_pass::prop_controller::ITEM_PURCHASE_COUNT;
use crate::first_pass::prop_controller::ITEM_PURCHASE_DEF_IDX;
use crate::first_pass::prop_controller::ITEM_PURCHASE_HANDLE;
use crate::first_pass::prop_controller::ITEM_PURCHASE_NEW_DEF_IDX;
use crate::first_pass::prop_controller::MY_WEAPONS_OFFSET;
use crate::first_pass::prop_controller::WEAPON_SKIN_ID;
use crate::maps::BASETYPE_DECODERS;
use crate::second_pass::decoder::Decoder;
use crate::second_pass::decoder::Decoder::*;
use crate::second_pass::decoder::QfMapper;
use crate::second_pass::decoder::QuantalizedFloat;
use crate::second_pass::path_ops::FieldPath;
use crate::second_pass::variants::Variant;
use ahash::AHashMap;
use csgoproto::netmessages::ProtoFlattenedSerializer_t;
Expand All @@ -28,6 +37,13 @@ pub struct Serializer {
pub name: String,
pub fields: Vec<Field>,
}
#[derive(Debug, Clone, Copy)]
pub struct FieldInfo {
pub decoder: Decoder,
pub should_parse: bool,
pub prop_id: u32,
}

#[derive(Debug, Clone, PartialEq)]
pub enum FieldCategory {
Pointer,
Expand Down Expand Up @@ -402,6 +418,93 @@ pub fn field_from_msg(
};
Ok(f)
}
#[inline(always)]
pub fn find_field<'b>(fp: &FieldPath, ser: &'b Serializer) -> Result<&'b Field, DemoParserError> {
let f = match ser.fields.get(fp.path[0] as usize) {
Some(entry) => entry,
None => return Err(DemoParserError::IllegalPathOp),
};
match fp.last {
0 => Ok(f),
1 => Ok(f.get_inner(fp.path[1] as usize)?),
2 => Ok(f.get_inner(fp.path[1] as usize)?.get_inner(fp.path[2] as usize)?),
3 => Ok(f
.get_inner(fp.path[1] as usize)?
.get_inner(fp.path[2] as usize)?
.get_inner(fp.path[3] as usize)?),
4 => Ok(f
.get_inner(fp.path[1] as usize)?
.get_inner(fp.path[2] as usize)?
.get_inner(fp.path[3] as usize)?
.get_inner(fp.path[4] as usize)?),
5 => Ok(f
.get_inner(fp.path[1] as usize)?
.get_inner(fp.path[2] as usize)?
.get_inner(fp.path[3] as usize)?
.get_inner(fp.path[4] as usize)?
.get_inner(fp.path[5] as usize)?),
_ => return Err(DemoParserError::IllegalPathOp),
}
}
pub fn get_decoder_from_field(field: &Field) -> Result<Decoder, DemoParserError> {
let decoder = match field {
Field::Value(inner) => inner.decoder,
Field::Vector(_) => UnsignedDecoder,
Field::Pointer(inner) => inner.decoder,
_ => return Err(DemoParserError::FieldNoDecoder),
};
Ok(decoder)
}

pub fn get_propinfo(field: &Field, path: &FieldPath) -> Option<FieldInfo> {
let info = match field {
Field::Value(v) => Some(FieldInfo {
decoder: v.decoder,
should_parse: v.should_parse,
prop_id: v.prop_id,
}),
Field::Vector(v) => match field.get_inner(0) {
Ok(Field::Value(inner)) => Some(FieldInfo {
decoder: v.decoder,
should_parse: inner.should_parse,
prop_id: inner.prop_id,
}),
_ => None,
},
_ => None,
};
// Flatten vector props
if let Some(mut fi) = info {
if fi.prop_id == MY_WEAPONS_OFFSET {
if path.last == 1 {
} else {
fi.prop_id = MY_WEAPONS_OFFSET + path.path[2] as u32 + 1;
}
}
if fi.prop_id == WEAPON_SKIN_ID {
fi.prop_id = WEAPON_SKIN_ID + path.path[1] as u32;
}
if path.path[1] != 1 {
if fi.prop_id >= ITEM_PURCHASE_COUNT && fi.prop_id < ITEM_PURCHASE_COUNT + FLATTENED_VEC_MAX_LEN {
fi.prop_id = ITEM_PURCHASE_COUNT + path.path[2] as u32;
}
if fi.prop_id >= ITEM_PURCHASE_DEF_IDX && fi.prop_id < ITEM_PURCHASE_DEF_IDX + FLATTENED_VEC_MAX_LEN {
fi.prop_id = ITEM_PURCHASE_DEF_IDX + path.path[2] as u32;
}
if fi.prop_id >= ITEM_PURCHASE_COST && fi.prop_id < ITEM_PURCHASE_COST + FLATTENED_VEC_MAX_LEN {
fi.prop_id = ITEM_PURCHASE_COST + path.path[2] as u32;
}
if fi.prop_id >= ITEM_PURCHASE_HANDLE && fi.prop_id < ITEM_PURCHASE_HANDLE + FLATTENED_VEC_MAX_LEN {
fi.prop_id = ITEM_PURCHASE_HANDLE + path.path[2] as u32;
}
if fi.prop_id >= ITEM_PURCHASE_NEW_DEF_IDX && fi.prop_id < ITEM_PURCHASE_NEW_DEF_IDX + FLATTENED_VEC_MAX_LEN {
fi.prop_id = ITEM_PURCHASE_NEW_DEF_IDX + path.path[2] as u32;
}
}
return Some(fi);
}
return None;
}

fn create_field(
_sid: &String,
Expand Down
98 changes: 96 additions & 2 deletions src/parser/src/second_pass/collect_data.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
use ahash::AHashMap;

use super::entities::PlayerMetaData;
use super::variants::Sticker;
use super::variants::Variant;
use crate::first_pass::prop_controller::*;
use crate::first_pass::read_bits::DemoParserError;
use crate::maps::AGENTSMAP;
use crate::maps::BUTTONMAP;
use crate::maps::GRENADE_FRIENDLY_NAMES;
use crate::maps::PAINTKITS;
use crate::maps::STICKER_ID_TO_NAME;
use crate::maps::WEAPINDICIES;
use crate::second_pass::entities::EntityType;
use crate::second_pass::parser_settings::SecondPassParser;
use crate::second_pass::variants::PropColumn;
use crate::second_pass::variants::VarVec;
use ahash::AHashMap;
use std::fmt;

#[derive(Debug, Clone, Copy, PartialEq)]
Expand Down Expand Up @@ -939,6 +940,99 @@ impl<'a> SecondPassParser<'a> {
}
}
}
pub fn gather_extra_info(&mut self, entity_id: &i32, is_baseline: bool) -> Result<(), DemoParserError> {
// Boring stuff.. function does some bookkeeping
let entity = match self.entities.get(*entity_id as usize) {
Some(Some(entity)) => entity,
_ => return Err(DemoParserError::EntityNotFound),
};
if !(entity.entity_type == EntityType::PlayerController || entity.entity_type == EntityType::Team) {
return Ok(());
}
if entity.entity_type == EntityType::Team && !is_baseline {
if let Some(team_num_id) = self.prop_controller.special_ids.team_team_num {
if let Ok(Variant::U32(t)) = self.get_prop_from_ent(&team_num_id, entity_id) {
match t {
1 => self.teams.team1_entid = Some(*entity_id),
2 => self.teams.team2_entid = Some(*entity_id),
3 => self.teams.team3_entid = Some(*entity_id),
_ => {}
}
}
}
}

let team_num = match self.prop_controller.special_ids.teamnum {
Some(team_num_id) => match self.get_prop_from_ent(&team_num_id, entity_id) {
Ok(team_num) => match team_num {
Variant::U32(team_num) => Some(team_num),
_ => return Err(DemoParserError::IncorrectMetaDataProp),
},
Err(_) => None,
},
_ => None,
};

let name = match self.prop_controller.special_ids.player_name {
Some(id) => match self.get_prop_from_ent(&id, entity_id) {
Ok(team_num) => match team_num {
Variant::String(team_num) => Some(team_num),
_ => return Err(DemoParserError::IncorrectMetaDataProp),
},
Err(_) => None,
},
_ => None,
};
let steamid = match self.prop_controller.special_ids.steamid {
Some(id) => match self.get_prop_from_ent(&id, entity_id) {
Ok(team_num) => match team_num {
Variant::U64(team_num) => Some(team_num),
_ => return Err(DemoParserError::IncorrectMetaDataProp),
},
Err(_) => None,
},
_ => None,
};
let player_entid = match self.prop_controller.special_ids.player_pawn {
Some(id) => match self.get_prop_from_ent(&id, entity_id) {
Ok(player_entid) => match player_entid {
Variant::U32(handle) => Some((handle & 0x7FF) as i32),
_ => return Err(DemoParserError::IncorrectMetaDataProp),
},
Err(_) => None,
},
_ => None,
};
if let Some(e) = player_entid {
if e != PLAYER_ENTITY_HANDLE_MISSING && steamid != Some(0) && team_num != Some(SPECTATOR_TEAM_NUM) {
match self.should_remove(steamid) {
Some(eid) => {
self.players.remove(&eid);
}
None => {}
}
self.players.insert(
e,
PlayerMetaData {
name: name,
team_num: team_num,
player_entity_id: player_entid,
steamid: steamid,
controller_entid: Some(*entity_id),
},
);
}
}
Ok(())
}
fn should_remove(&self, steamid: Option<u64>) -> Option<i32> {
for (entid, player) in &self.players {
if player.steamid == steamid {
return Some(*entid);
}
}
None
}
}

fn coord_from_cell(
Expand Down
Loading

0 comments on commit de9e015

Please sign in to comment.