use crate::entity::field::*;
use crate::entity::*;
use crate::event::*;
use crate::string_table::*;
use crate::{FieldValue, HashMap};
use source2_demo_protobufs::CDemoFileInfo;
use std::rc::Rc;
pub struct Context {
pub(crate) classes: Classes,
pub(crate) entities: Entities,
pub(crate) string_tables: StringTables,
pub(crate) game_events: GameEventList,
pub(crate) tick: u32,
pub(crate) previous_tick: u32,
pub(crate) net_tick: u32,
pub(crate) game_build: u32,
pub(crate) replay_info: CDemoFileInfo,
pub(crate) baselines: BaselineContainer,
pub(crate) serializers: HashMap<Box<str>, Rc<Serializer>>,
pub(crate) last_full_packet_tick: u32,
}
impl Default for Context {
fn default() -> Self {
Context {
classes: Classes::default(),
entities: Entities::default(),
string_tables: StringTables::default(),
game_events: Default::default(),
tick: u32::MAX,
previous_tick: u32::MAX,
net_tick: u32::MAX,
game_build: 0,
replay_info: CDemoFileInfo::default(),
baselines: BaselineContainer::default(),
serializers: HashMap::default(),
last_full_packet_tick: u32::MAX,
}
}
}
impl Context {
pub(crate) fn new(replay_info: CDemoFileInfo) -> Self {
Context {
classes: Classes::default(),
entities: Entities::default(),
string_tables: StringTables::default(),
game_events: GameEventList::default(),
tick: u32::MAX,
previous_tick: u32::MAX,
net_tick: u32::MAX,
game_build: 0,
replay_info,
baselines: BaselineContainer::default(),
serializers: HashMap::default(),
last_full_packet_tick: u32::MAX,
}
}
}
impl Context {
pub fn classes(&self) -> &Classes {
&self.classes
}
pub fn entities(&self) -> &Entities {
&self.entities
}
pub fn string_tables(&self) -> &StringTables {
&self.string_tables
}
pub fn game_events(&self) -> &GameEventList {
&self.game_events
}
pub fn tick(&self) -> u32 {
self.tick
}
pub fn previous_tick(&self) -> u32 {
self.previous_tick
}
pub fn net_tick(&self) -> u32 {
self.net_tick
}
pub fn game_build(&self) -> u32 {
self.game_build
}
pub fn replay_info(&self) -> &CDemoFileInfo {
&self.replay_info
}
pub fn baseline_entities(&self) -> Vec<BaselineEntity> {
let mut entities = self
.baselines
.states
.keys()
.filter_map(|&class_id| {
self.classes
.get_by_id(class_id as usize)
.ok()
.map(|class| BaselineEntity {
class_id,
class_name: class.name().to_string(),
})
})
.collect::<Vec<_>>();
entities.sort_by_key(|entity| entity.class_id);
entities
}
pub fn baseline_fields(&self, class_id: i32) -> Option<Vec<EntityField<'_>>> {
let state = self.baselines.states.get(&class_id)?;
let class = self.classes.get_by_id(class_id as usize).ok()?;
class
.serializer
.get_paths(&mut FieldPath::default(), state)
.into_iter()
.map(|fp| {
let value = state.get_value(&fp);
EntityField {
path: (0..=fp.last).map(|idx| fp.path[idx]).collect(),
name: class.serializer.get_name(&fp).to_string(),
field_type: class.serializer.get_type(&fp).to_string(),
decoded_type: value.map(FieldValue::type_name),
value,
}
})
.collect::<Vec<_>>()
.into()
}
}