Skip to main content

Parser

Struct Parser 

Source
pub struct Parser { /* private fields */ }
Expand description

The main parser. Owns the demo file data (memory-mapped or in-memory).

Implementations§

Source§

impl Parser

Source

pub fn from_file(path: &Path) -> Result<Self>

Open a demo file and memory-map it for zero-copy parsing.

Source

pub fn from_bytes(bytes: Vec<u8>) -> Self

Create a parser from an in-memory byte buffer.

This is useful for testing, WASM targets (where mmap is unavailable), or when the demo data has already been loaded into memory.

Source

pub fn verify(&self) -> Result<()>

Verify magic bytes. Verify that the file has valid demo magic bytes.

Source

pub fn messages(&self) -> Result<Vec<MessageInfo>>

Iterate all commands and return metadata about each. Continues past DEM_Stop to capture DEM_FileInfo.

Source

pub fn file_header(&self) -> Result<CDemoFileHeader>

Find and decode the CDemoFileHeader message.

Source

pub fn file_info(&self) -> Result<CDemoFileInfo>

Decode CDemoFileInfo using the offset stored in the file header.

Source

pub fn events(&self, max_tick: Option<i32>) -> Result<Vec<GameEvent>>

Parse game events from the demo.

Extracts Source 1 legacy game events and Citadel user messages from DEM_Packet, DEM_SignonPacket, and DEM_FullPacket commands. If max_tick is set, stops parsing once the tick exceeds the limit.

Source

pub fn parse_send_tables(&self) -> Result<SerializerContainer>

Parse send tables from DEM_SendTables command.

Source

pub fn parse_class_info(&self) -> Result<ClassInfo>

Parse class info from DEM_ClassInfo command.

Source

pub fn parse_init(&self) -> Result<Context>

Parse all initialization data up to DEM_SyncTick and return a Context.

Source

pub fn parse_to_tick(&self, target_tick: i32) -> Result<Context>

Parse the demo to a specific tick, returning the full game state.

Uses an optimisation where it skips forward to the last DEM_FullPacket snapshot before target_tick, applies that snapshot, then replays individual packets until target_tick is reached.

Source

pub fn run_to_end<F>(&self, on_tick: F) -> Result<()>
where F: FnMut(&Context),

Parse the entire demo, calling a callback at each tick with the current context. This is more efficient than calling parse_to_tick repeatedly.

Source

pub fn run_to_end_filtered<F>( &self, class_filter: &HashSet<&str>, on_tick: F, ) -> Result<()>
where F: FnMut(&Context),

Parse the entire demo with entity class filtering. Only entities with classes in the filter are fully tracked. This is much faster when you only need specific entity types.

Source

pub fn full_packet_offsets(&self) -> Result<Vec<(usize, i32)>>

Byte offset (relative to the post-HEADER_SIZE data) and tick of every DEM_FullPacket keyframe, via a cheap header-only pre-scan.

Full packets are periodic complete-state snapshots that the parallel tick decoder cold-restarts from — each marks a segment boundary. Ascending order.

Source

pub fn decode_segment<F>( &self, start: Option<usize>, end_tick: i32, class_filter: &HashSet<&str>, on_tick: F, ) -> Result<()>
where F: FnMut(&Context),

Decode one contiguous segment of the demo, for the parallel tick path.

start selects where decoding begins: None starts from the signon baseline (the first segment); Some(offset) cold-restarts at the DEM_FullPacket at that byte offset (from full_packet_offsets), applying its complete snapshot. on_tick fires once per completed tick whose value is < end_tick (pass i32::MAX for the final segment).

Exact only for entities a full packet re-keyframes (player pawns and controllers). Those are snapshotted in full at every full packet, so a cold restart reproduces their exact state — which is what lets the per-segment decodes stitch back into the same result as one serial pass. “Sticky” entities that carry state across full packets are not re-keyed and would read stale from a cold restart, so this must not build datasets (e.g. the change-only ones) that depend on that carried state.

Source

pub fn distinct_ticks(&self) -> Result<Vec<i32>>

Every distinct tick in the demo (ascending), from a header-only pre-scan starting after DEM_SyncTick — i.e. the ticks a decode actually emits.

Lets a sampled snapshot pass resolve which ticks to sample once, up front, independent of how the demo is later split into parallel segments.

Source

pub fn run_to_end_with_events_filtered<F>( &self, class_filter: &HashSet<&str>, on_tick: F, ) -> Result<()>
where F: FnMut(&Context, &[GameEvent]),

Parse the entire demo with entity class filtering AND event collection. Combines run_to_end_filtered with process_packet_events in a single pass. The callback receives both the entity context and accumulated events for the tick.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.