1
0
Fork 0
mirror of https://codeberg.org/demostf/parser.git synced 2026-06-03 10:14:06 +02:00

dont save full serverclass in entity, only store classid

This commit is contained in:
Robin Appelman 2019-08-28 16:58:40 +02:00
commit 91e5b82f2f
5 changed files with 64 additions and 48 deletions

View file

@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr}; use serde_repr::{Deserialize_repr, Serialize_repr};
use crate::demo::message::stringtable::{log_base2, read_var_int}; use crate::demo::message::stringtable::{log_base2, read_var_int};
use crate::demo::packet::datatable::{SendTable, SendTableName, ServerClass}; use crate::demo::packet::datatable::{ClassId, SendTable, SendTableName, ServerClass};
use crate::demo::parser::ParseBitSkip; use crate::demo::parser::ParseBitSkip;
use crate::demo::sendprop::{SendProp, SendPropDefinition, SendPropValue}; use crate::demo::sendprop::{SendProp, SendPropDefinition, SendPropValue};
use crate::{MalformedDemoError, Parse, ParseError, ParserState, ReadResult, Result, Stream}; use crate::{MalformedDemoError, Parse, ParseError, ParserState, ReadResult, Result, Stream};
@ -46,7 +46,7 @@ pub enum PVS {
#[derive(Debug)] #[derive(Debug)]
pub struct PacketEntity { pub struct PacketEntity {
pub server_class: Rc<ServerClass>, pub server_class: ClassId,
pub entity_index: EntityId, pub entity_index: EntityId,
pub props: Vec<SendProp>, pub props: Vec<SendProp>,
pub in_pvs: bool, pub in_pvs: bool,
@ -57,7 +57,7 @@ pub struct PacketEntity {
impl fmt::Display for PacketEntity { impl fmt::Display for PacketEntity {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}({}) {{\n", self.entity_index, self.server_class.name)?; write!(f, "{}({}) {{\n", self.entity_index, self.server_class)?;
for child in self.props.iter() { for child in self.props.iter() {
write!(f, "\t{}\n", child)?; write!(f, "\t{}\n", child)?;
} }
@ -116,21 +116,29 @@ fn get_entity_for_update(
state: &ParserState, state: &ParserState,
entity_index: EntityId, entity_index: EntityId,
pvs: PVS, pvs: PVS,
) -> Result<PacketEntity> { ) -> Result<(PacketEntity, &ServerClass)> {
let server_class = state let class_id = *state
.entity_classes .entity_classes
.get(&entity_index) .get(&entity_index)
.ok_or_else(|| MalformedDemoError::UnknownEntity(entity_index))?; .ok_or_else(|| MalformedDemoError::UnknownEntity(entity_index))?;
Ok(PacketEntity { let server_class = state
server_class: Rc::clone(server_class), .server_classes
entity_index, .get(usize::from(class_id))
props: Vec::new(), .ok_or_else(|| MalformedDemoError::UnknownServerClass(class_id.into()))?;
in_pvs: false,
pvs, Ok((
serial_number: 0, PacketEntity {
delay: None, server_class: class_id,
}) entity_index,
props: Vec::new(),
in_pvs: false,
pvs,
serial_number: 0,
delay: None,
},
server_class,
))
} }
impl Parse for PacketEntitiesMessage { impl Parse for PacketEntitiesMessage {
@ -155,23 +163,23 @@ impl Parse for PacketEntitiesMessage {
let pvs = data.read()?; let pvs = data.read()?;
if pvs == PVS::Enter { if pvs == PVS::Enter {
let mut entity = let (mut entity, server_class) =
Self::read_enter(&mut data, entity_index, state, base_line as usize)?; Self::read_enter(&mut data, entity_index, state, base_line as usize)?;
let send_table = get_send_table(state, &entity.server_class.data_table)?; let send_table = get_send_table(state, &server_class.data_table)?;
let updated_props = Self::read_update(&mut data, send_table)?; let updated_props = Self::read_update(&mut data, send_table)?;
entity.apply_update(updated_props); entity.apply_update(updated_props);
entities.push(entity); entities.push(entity);
} else if pvs == PVS::Preserve { } else if pvs == PVS::Preserve {
let mut entity = get_entity_for_update(state, entity_index, pvs)?; let (mut entity, server_class) = get_entity_for_update(state, entity_index, pvs)?;
let send_table = get_send_table(state, &entity.server_class.data_table)?; let send_table = get_send_table(state, &server_class.data_table)?;
let updated_props = Self::read_update(&mut data, send_table)?; let updated_props = Self::read_update(&mut data, send_table)?;
entity.props = updated_props; entity.props = updated_props;
entities.push(entity); entities.push(entity);
} else if state.entity_classes.contains_key(&entity_index) { } else if state.entity_classes.contains_key(&entity_index) {
let entity = get_entity_for_update(state, entity_index, pvs)?; let (entity, server_class) = get_entity_for_update(state, entity_index, pvs)?;
entities.push(entity); entities.push(entity);
} }
} }
@ -194,12 +202,12 @@ impl Parse for PacketEntitiesMessage {
} }
impl PacketEntitiesMessage { impl PacketEntitiesMessage {
fn read_enter( fn read_enter<'a>(
stream: &mut Stream, stream: &mut Stream,
entity_index: EntityId, entity_index: EntityId,
state: &ParserState, state: &'a ParserState,
baseline_index: usize, baseline_index: usize,
) -> Result<PacketEntity> { ) -> Result<(PacketEntity, &'a ServerClass)> {
let bits = log_base2(state.server_classes.len()) + 1; let bits = log_base2(state.server_classes.len()) + 1;
let class_index = stream.read_sized::<u16>(bits as usize)? as usize; let class_index = stream.read_sized::<u16>(bits as usize)? as usize;
let server_class = state let server_class = state
@ -223,15 +231,18 @@ impl PacketEntitiesMessage {
}, },
}; };
Ok(PacketEntity { Ok((
server_class: Rc::clone(server_class), PacketEntity {
entity_index, server_class: server_class.id,
props, entity_index,
in_pvs: true, props,
pvs: PVS::Enter, in_pvs: true,
serial_number: serial, pvs: PVS::Enter,
delay: None, serial_number: serial,
}) delay: None,
},
server_class,
))
} }
pub fn read_update(stream: &mut Stream, send_table: &SendTable) -> Result<Vec<SendProp>> { pub fn read_update(stream: &mut Stream, send_table: &SendTable) -> Result<Vec<SendProp>> {

View file

@ -13,7 +13,7 @@ use std::ops::Deref;
use std::rc::Rc; use std::rc::Rc;
use std::str::FromStr; use std::str::FromStr;
#[derive(BitRead, Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] #[derive(BitRead, Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd, Display)]
pub struct ClassId(u16); pub struct ClassId(u16);
impl FromStr for ClassId { impl FromStr for ClassId {
@ -30,6 +30,12 @@ impl From<u16> for ClassId {
} }
} }
impl From<ClassId> for usize {
fn from(class: ClassId) -> Self {
class.0 as usize
}
}
#[derive(BitRead, PartialEq, Eq, Hash, Debug, Serialize, Deserialize, Clone, Display)] #[derive(BitRead, PartialEq, Eq, Hash, Debug, Serialize, Deserialize, Clone, Display)]
pub struct ServerClassName(Rc<String>); pub struct ServerClassName(Rc<String>);
@ -196,7 +202,7 @@ pub struct SendTable {
pub struct DataTablePacket { pub struct DataTablePacket {
pub tick: u32, pub tick: u32,
pub tables: Vec<SendTable>, pub tables: Vec<SendTable>,
pub server_classes: Vec<Rc<ServerClass>>, pub server_classes: Vec<ServerClass>,
} }
impl Parse for DataTablePacket { impl Parse for DataTablePacket {

View file

@ -97,11 +97,7 @@ impl<T: MessageHandler> DemoHandler<T> {
} }
} }
fn handle_data_table( fn handle_data_table(&mut self, send_tables: Vec<SendTable>, server_classes: Vec<ServerClass>) {
&mut self,
send_tables: Vec<SendTable>,
server_classes: Vec<Rc<ServerClass>>,
) {
self.state_handler self.state_handler
.handle_data_table(send_tables, server_classes); .handle_data_table(send_tables, server_classes);
} }

View file

@ -1,4 +1,4 @@
use std::collections::HashMap; use std::collections::{BTreeMap, HashMap};
use crate::demo::gamevent::GameEventDefinition; use crate::demo::gamevent::GameEventDefinition;
use crate::demo::message::gameevent::GameEventTypeId; use crate::demo::message::gameevent::GameEventTypeId;
@ -26,9 +26,9 @@ pub struct ParserState {
pub parsed_static_baselines: RefCell<HashMap<ClassId, Vec<SendProp>>>, pub parsed_static_baselines: RefCell<HashMap<ClassId, Vec<SendProp>>>,
pub event_definitions: Vec<GameEventDefinition>, pub event_definitions: Vec<GameEventDefinition>,
pub string_tables: Vec<StringTableMeta>, pub string_tables: Vec<StringTableMeta>,
pub entity_classes: HashMap<EntityId, Rc<ServerClass>>, pub entity_classes: HashMap<EntityId, ClassId>,
pub send_tables: HashMap<SendTableName, SendTable>, pub send_tables: HashMap<SendTableName, SendTable>,
pub server_classes: Vec<Rc<ServerClass>>, pub server_classes: Vec<ServerClass>,
pub instance_baselines: [HashMap<EntityId, Vec<SendProp>>; 2], pub instance_baselines: [HashMap<EntityId, Vec<SendProp>>; 2],
pub demo_meta: DemoMeta, pub demo_meta: DemoMeta,
analyser_handles: fn(message_type: MessageType) -> bool, analyser_handles: fn(message_type: MessageType) -> bool,
@ -88,7 +88,7 @@ impl ParserState {
pub fn handle_data_table( pub fn handle_data_table(
&mut self, &mut self,
send_tables: Vec<SendTable>, send_tables: Vec<SendTable>,
server_classes: Vec<Rc<ServerClass>>, server_classes: Vec<ServerClass>,
) { ) {
for table in send_tables { for table in send_tables {
self.send_tables.insert(table.name.clone(), table); self.send_tables.insert(table.name.clone(), table);
@ -154,7 +154,7 @@ impl ParserState {
self.entity_classes.remove(&entity.entity_index); self.entity_classes.remove(&entity.entity_index);
} }
self.entity_classes self.entity_classes
.insert(entity.entity_index, Rc::clone(&entity.server_class)); .insert(entity.entity_index, entity.server_class);
} }
Some(Message::PacketEntities(ent_message)) Some(Message::PacketEntities(ent_message))
} }

View file

@ -52,11 +52,11 @@ struct EntityDump {
} }
impl EntityDump { impl EntityDump {
pub fn from_entity(entity: PacketEntity, tick: u32) -> Self { pub fn from_entity(entity: PacketEntity, tick: u32, classes: &[ServerClass]) -> Self {
let id = entity.entity_index; let id = entity.entity_index;
EntityDump { EntityDump {
tick, tick,
server_class: entity.server_class.name.clone(), server_class: classes[usize::from(entity.server_class)].name.clone(),
id: entity.entity_index, id: entity.entity_index,
props: entity props: entity
.props .props
@ -69,7 +69,7 @@ impl EntityDump {
} }
struct EntityDumper { struct EntityDumper {
entities: Vec<EntityDump>, entities: Vec<(u32, PacketEntity)>,
} }
impl EntityDumper { impl EntityDumper {
@ -96,7 +96,7 @@ impl MessageHandler for EntityDumper {
entity_message entity_message
.entities .entities
.into_iter() .into_iter()
.map(|entity| EntityDump::from_entity(entity, tick)), .map(|entity| (tick, entity)),
), ),
_ => {} _ => {}
} }
@ -104,8 +104,11 @@ impl MessageHandler for EntityDumper {
fn handle_string_entry(&mut self, table: &String, _index: usize, entry: &StringTableEntry) {} fn handle_string_entry(&mut self, table: &String, _index: usize, entry: &StringTableEntry) {}
fn get_output(self, _state: ParserState) -> Self::Output { fn get_output(self, state: ParserState) -> Self::Output {
self.entities self.entities
.into_iter()
.map(|(tick, entity)| EntityDump::from_entity(entity, tick, &state.server_classes))
.collect()
} }
} }