Skip to content

Commit

Permalink
dont stop prop and table name in sendprop
Browse files Browse the repository at this point in the history
  • Loading branch information
icewind1991 committed Feb 13, 2021
1 parent df9a6a1 commit 35519d5
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 216 deletions.
18 changes: 7 additions & 11 deletions src/demo/message/packetentities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,26 +69,22 @@ impl fmt::Display for PacketEntity {
}

impl PacketEntity {
fn get_prop_by_identifier(&mut self, identifier: &SendPropIdentifier) -> Option<&mut SendProp> {
self.props
.iter_mut()
.find(|prop| prop.identifier.index == identifier.index)
fn get_prop_by_identifier(&mut self, index: &SendPropIdentifier) -> Option<&mut SendProp> {
self.props.iter_mut().find(|prop| prop.index == *index)
}

pub fn apply_update(&mut self, props: Vec<SendProp>) {
for prop in props {
match self.get_prop_by_identifier(&prop.identifier) {
match self.get_prop_by_identifier(&prop.index) {
Some(existing_prop) => existing_prop.value = prop.value,
None => self.props.push(prop),
}
}
}

pub fn get_prop_by_name(&self, table_name: &str, name: &str) -> Option<&SendProp> {
self.props.iter().find(|prop| {
prop.identifier.owner_table.as_str() == table_name
&& prop.identifier.name.as_str() == name
})
let identifier = SendPropIdentifier::new(table_name, name);
self.props.iter().find(|prop| prop.index == identifier)
}
}

Expand Down Expand Up @@ -249,9 +245,9 @@ impl PacketEntitiesMessage {

match send_table.flattened_props.get(index as usize) {
Some(definition) => {
let value = SendPropValue::parse(stream, definition)?;
let value = SendPropValue::parse(stream, &definition.parse_definition)?;
props.push(SendProp {
identifier: definition.identifier(),
index: definition.identifier,
value,
});
}
Expand Down
61 changes: 22 additions & 39 deletions src/demo/packet/datatable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ use bitbuffer::BitRead;

use crate::demo::parser::MalformedSendPropDefinitionError;
use crate::demo::sendprop::{
RawSendPropDefinition, SendPropDefinition, SendPropDefinitionIndex, SendPropFlag, SendPropName,
SendPropType,
RawSendPropDefinition, SendPropDefinition, SendPropFlag, SendPropIdentifier, SendPropType,
};
use crate::{Parse, ParseError, ParserState, Result, Stream};
use parse_display::{Display, FromStr};
Expand Down Expand Up @@ -81,12 +80,12 @@ impl From<String> for SendTableName {
#[derive(Debug, Clone)]
pub struct ParseSendTable {
pub name: SendTableName,
pub props: Vec<Rc<RawSendPropDefinition>>,
pub props: Vec<RawSendPropDefinition>,
pub needs_decoder: bool,
}

impl ParseSendTable {
fn parse(stream: &mut Stream, _state: &ParserState, table_index: usize) -> Result<Self> {
fn parse(stream: &mut Stream, _state: &ParserState) -> Result<Self> {
let needs_decoder = stream.read()?;
let raw_name: String = stream.read()?;
let name: SendTableName = raw_name.into();
Expand All @@ -95,10 +94,8 @@ impl ParseSendTable {
let mut array_element_prop = None;
let mut props = Vec::with_capacity(min(prop_count, 128));

for prop_index in 0..prop_count {
let definition_index = SendPropDefinitionIndex::new(table_index, prop_index);
let prop: RawSendPropDefinition =
RawSendPropDefinition::read(stream, name.clone(), definition_index)?;
for _ in 0..prop_count {
let prop: RawSendPropDefinition = RawSendPropDefinition::read(stream, name.clone())?;
if prop.flags.contains(SendPropFlag::InsideArray) {
if array_element_prop.is_some() || prop.flags.contains(SendPropFlag::ChangesOften) {
return Err(MalformedSendPropDefinitionError::ArrayChangesOften.into());
Expand All @@ -109,9 +106,9 @@ impl ParseSendTable {
return Err(MalformedSendPropDefinitionError::UntypedArray.into());
}
array_element_prop = None;
props.push(Rc::new(prop.with_array_property(array_element)));
props.push(prop.with_array_property(array_element));
} else {
props.push(Rc::new(prop));
props.push(prop);
}
}

Expand All @@ -124,7 +121,7 @@ impl ParseSendTable {
}

impl ParseSendTable {
pub fn flatten_props(&self, tables: &[ParseSendTable]) -> Vec<Rc<RawSendPropDefinition>> {
pub fn flatten_props(&self, tables: &[ParseSendTable]) -> Vec<RawSendPropDefinition> {
let mut flat = Vec::with_capacity(32);
self.get_all_props(tables, &self.get_excludes(tables), &mut flat);

Expand All @@ -139,18 +136,18 @@ impl ParseSendTable {
}
}

flat.into_iter().map(|prop| Rc::clone(&prop)).collect()
flat
}

fn get_excludes<'a>(&'a self, tables: &'a [ParseSendTable]) -> Vec<Exclude<'a>> {
fn get_excludes<'a>(&'a self, tables: &'a [ParseSendTable]) -> Vec<SendPropIdentifier> {
let mut excludes = Vec::with_capacity(8);

for prop in self.props.iter() {
if let Some(exclude_table) = prop.get_exclude_table() {
excludes.push(Exclude {
table: exclude_table,
prop: &prop.identifier.name,
})
excludes.push(SendPropIdentifier::new(
exclude_table.as_str(),
prop.name.as_str(),
))
} else if let Some(table) = prop.get_data_table(tables) {
excludes.extend_from_slice(&table.get_excludes(tables));
}
Expand All @@ -163,8 +160,8 @@ impl ParseSendTable {
fn get_all_props(
&self,
tables: &[ParseSendTable],
excludes: &[Exclude],
props: &mut Vec<Rc<RawSendPropDefinition>>,
excludes: &[SendPropIdentifier],
props: &mut Vec<RawSendPropDefinition>,
) {
let mut local_props = Vec::new();

Expand All @@ -175,14 +172,14 @@ impl ParseSendTable {
fn get_all_props_iterator_props(
&self,
tables: &[ParseSendTable],
excludes: &[Exclude],
local_props: &mut Vec<Rc<RawSendPropDefinition>>,
props: &mut Vec<Rc<RawSendPropDefinition>>,
excludes: &[SendPropIdentifier],
local_props: &mut Vec<RawSendPropDefinition>,
props: &mut Vec<RawSendPropDefinition>,
) {
self.props
.iter()
.filter(|prop| !prop.is_exclude())
.filter(|prop| !excludes.iter().any(|exclude| exclude.matches(prop)))
.filter(|prop| !excludes.iter().any(|exclude| *exclude == prop.identifier()))
.for_each(|prop| {
if let Some(table) = prop.get_data_table(tables) {
if prop.flags.contains(SendPropFlag::Collapsible) {
Expand All @@ -191,24 +188,12 @@ impl ParseSendTable {
table.get_all_props(tables, excludes, props);
}
} else {
local_props.push(Rc::clone(prop));
local_props.push(prop.clone());
}
})
}
}

#[derive(Clone)]
struct Exclude<'a> {
table: &'a SendTableName,
prop: &'a SendPropName,
}

impl<'a> Exclude<'a> {
pub fn matches(&self, prop: &RawSendPropDefinition) -> bool {
self.table == &prop.identifier.owner_table && *self.prop == prop.identifier.name
}
}

#[derive(Debug, Clone)]
pub struct SendTable {
pub name: SendTableName,
Expand All @@ -230,10 +215,8 @@ impl Parse<'_> for DataTablePacket {
let mut packet_data = stream.read_bits(len * 8)?;

let mut tables = Vec::new();
let mut table_index = 0;
while packet_data.read_bool()? {
let table = ParseSendTable::parse(&mut packet_data, state, table_index)?;
table_index += 1;
let table = ParseSendTable::parse(&mut packet_data, state)?;
tables.push(table);
}

Expand Down
117 changes: 69 additions & 48 deletions src/demo/parser/gamestateanalyser.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use crate::demo::message::packetentities::{EntityId, PacketEntity};
use crate::demo::message::Message;
use crate::demo::packet::datatable::{ParseSendTable, ServerClass, ServerClassName};
use crate::demo::packet::datatable::{ParseSendTable, SendTableName, ServerClass, ServerClassName};
pub use crate::demo::parser::analyser::{Class, Team, UserId};
use crate::demo::parser::handler::BorrowMessageHandler;
use crate::demo::parser::MessageHandler;
use crate::demo::sendprop::{SendProp, SendPropValue};
use crate::demo::sendprop::{SendProp, SendPropIdentifier, SendPropName, SendPropValue};
use crate::demo::vector::{Vector, VectorXY};
use crate::{MessageType, ParserState};
use fnv::FnvHashMap;
use serde::{Deserialize, Serialize};
use std::convert::TryFrom;
use std::str::FromStr;
Expand Down Expand Up @@ -142,6 +143,7 @@ impl GameState {
#[derive(Default, Debug)]
pub struct GameStateAnalyser {
pub state: GameState,
prop_names: FnvHashMap<SendPropIdentifier, (SendTableName, SendPropName)>,
class_names: Vec<ServerClassName>, // indexed by ClassId
}

Expand All @@ -166,7 +168,20 @@ impl MessageHandler for GameStateAnalyser {
}
}

fn handle_data_tables(&mut self, _tables: &[ParseSendTable], server_classes: &[ServerClass]) {
fn handle_data_tables(
&mut self,
parse_tables: &[ParseSendTable],
server_classes: &[ServerClass],
) {
for table in parse_tables {
for prop_def in &table.props {
self.prop_names.insert(
prop_def.identifier(),
(prop_def.owner_table.clone(), prop_def.name.clone()),
);
}
}

self.class_names = server_classes
.iter()
.map(|class| &class.name)
Expand Down Expand Up @@ -206,27 +221,30 @@ impl GameStateAnalyser {

pub fn handle_player_resource(&mut self, entity: &PacketEntity) {
for prop in &entity.props {
if let Ok(player_id) = u32::from_str(prop.identifier.name.as_str()) {
let entity_id = EntityId::from(player_id);
if let Some(player) = self
.state
.players
.iter_mut()
.find(|player| player.entity == entity_id)
{
match prop.identifier.owner_table.as_str() {
"m_iTeam" => {
player.team = Team::new(i64::try_from(&prop.value).unwrap_or_default())
if let Some((table_name, prop_name)) = self.prop_names.get(&prop.index) {
if let Ok(player_id) = u32::from_str(prop_name.as_str()) {
let entity_id = EntityId::from(player_id);
if let Some(player) = self
.state
.players
.iter_mut()
.find(|player| player.entity == entity_id)
{
match table_name.as_str() {
"m_iTeam" => {
player.team =
Team::new(i64::try_from(&prop.value).unwrap_or_default())
}
"m_iMaxHealth" => {
player.max_health =
i64::try_from(&prop.value).unwrap_or_default() as u16
}
"m_iPlayerClass" => {
player.class =
Class::new(i64::try_from(&prop.value).unwrap_or_default())
}
_ => {}
}
"m_iMaxHealth" => {
player.max_health =
i64::try_from(&prop.value).unwrap_or_default() as u16
}
"m_iPlayerClass" => {
player.class =
Class::new(i64::try_from(&prop.value).unwrap_or_default())
}
_ => {}
}
}
}
Expand All @@ -237,37 +255,40 @@ impl GameStateAnalyser {
let player = self.state.get_or_create_player(entity.entity_index);

for prop in &entity.props {
match prop.identifier.owner_table.as_str() {
"DT_BasePlayer" => match prop.identifier.name.as_str() {
"m_iHealth" => {
player.health = i64::try_from(&prop.value).unwrap_or_default() as u16
}
"m_iMaxHealth" => {
player.max_health = i64::try_from(&prop.value).unwrap_or_default() as u16
}
"m_lifeState" => {
player.state =
PlayerState::new(i64::try_from(&prop.value).unwrap_or_default())
}
_ => {}
},
"DT_TFLocalPlayerExclusive" | "DT_TFNonLocalPlayerExclusive" => {
match prop.identifier.name.as_str() {
"m_vecOrigin" => {
let pos_xy = VectorXY::try_from(&prop.value).unwrap_or_default();
player.position.x = pos_xy.x;
player.position.y = pos_xy.y;
if let Some((table_name, prop_name)) = self.prop_names.get(&prop.index) {
match table_name.as_str() {
"DT_BasePlayer" => match prop_name.as_str() {
"m_iHealth" => {
player.health = i64::try_from(&prop.value).unwrap_or_default() as u16
}
"m_vecOrigin[2]" => {
player.position.z = f32::try_from(&prop.value).unwrap_or_default()
"m_iMaxHealth" => {
player.max_health =
i64::try_from(&prop.value).unwrap_or_default() as u16
}
"m_angEyeAngles[1]" => {
player.view_angle = f32::try_from(&prop.value).unwrap_or_default()
"m_lifeState" => {
player.state =
PlayerState::new(i64::try_from(&prop.value).unwrap_or_default())
}
_ => {}
},
"DT_TFLocalPlayerExclusive" | "DT_TFNonLocalPlayerExclusive" => {
match prop_name.as_str() {
"m_vecOrigin" => {
let pos_xy = VectorXY::try_from(&prop.value).unwrap_or_default();
player.position.x = pos_xy.x;
player.position.y = pos_xy.y;
}
"m_vecOrigin[2]" => {
player.position.z = f32::try_from(&prop.value).unwrap_or_default()
}
"m_angEyeAngles[1]" => {
player.view_angle = f32::try_from(&prop.value).unwrap_or_default()
}
_ => {}
}
}
_ => {}
}
_ => {}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/demo/parser/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ impl<'a> ParserState {
needs_decoder: parse_table.needs_decoder,
flattened_props: flat
.into_iter()
.map(|raw| SendPropDefinition::try_from(raw.as_ref()))
.map(|raw| SendPropDefinition::try_from(raw))
.collect::<std::result::Result<Vec<_>, _>>()?,
},
))
Expand Down
Loading

0 comments on commit 35519d5

Please sign in to comment.