mirror of
https://codeberg.org/demostf/parser.git
synced 2026-06-03 18:24:05 +02:00
dont save full serverclass in entity, only store classid
This commit is contained in:
parent
b6f7ebb15a
commit
91e5b82f2f
5 changed files with 64 additions and 48 deletions
|
|
@ -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
|
||||||
|
.get(usize::from(class_id))
|
||||||
|
.ok_or_else(|| MalformedDemoError::UnknownServerClass(class_id.into()))?;
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
PacketEntity {
|
||||||
|
server_class: class_id,
|
||||||
entity_index,
|
entity_index,
|
||||||
props: Vec::new(),
|
props: Vec::new(),
|
||||||
in_pvs: false,
|
in_pvs: false,
|
||||||
pvs,
|
pvs,
|
||||||
serial_number: 0,
|
serial_number: 0,
|
||||||
delay: None,
|
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 {
|
||||||
|
server_class: server_class.id,
|
||||||
entity_index,
|
entity_index,
|
||||||
props,
|
props,
|
||||||
in_pvs: true,
|
in_pvs: true,
|
||||||
pvs: PVS::Enter,
|
pvs: PVS::Enter,
|
||||||
serial_number: serial,
|
serial_number: serial,
|
||||||
delay: None,
|
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>> {
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue