Crate faf_replay_parser

Source
Expand description

A parser for Supreme Commander: Forged Alliance replay data.

§The Replay Format

Replays are a sequence of game commands that are executed in the sim (game simulation). This includes actions taken by the players as well as automated “driver” commands that tell the sim to run and verify the sim state.

The most common command present in the replay is the Advance command. This tells the sim to run a certain number of in game ticks. In practice the number of ticks appears to always be 1. Counting the total number of ticks present in Advance commands can tell you how much in game time has passed in a replay, as ticks always happen at a consistent rate of 10 ticks per in game second. As counting the number of ticks is a fairly common use case, this library offers some specially optimized functions for doing this, and we will use this for many examples of how to use the library.

§Parser Interfaces

There are two main ways to interface with the parser, depending on how your data is available. If most general interfaces uses std::io::Read to inspect the command data and can be used directly on any objects that implement it such as files, network sockets, and non-contiguous structures. However, it can be significantly more efficient to work with byte slices directly, so there are a number of functions for that specific case.

§Examples

Lets look at some examples of using the parser to count the ticks in a replay.

§Using the optimized functions

use faf_replay_parser::{body_offset, body_ticks};
use std::fs::File;
use std::io::Read;

let mut data = Vec::new();
File::open("tests/data/6176549.scfareplay")
    .expect("Failed to open file")
    .read_to_end(&mut data)
    .expect("Failed to read file");

// Find the index where the header stops and the replay data begins
let offset = body_offset(&data).expect("Malformed replay header");
// Count the number of ticks present in the replay data
let ticks = body_ticks(&data[offset..]).expect("Corrupt replay data");

assert_eq!(ticks, 28917);

For more details on the available functions see scfa::bytes.

§Using the byte iterator

use faf_replay_parser::iter::prelude::*;
use faf_replay_parser::scfa::{replay_command, ReplayCommand};
use faf_replay_parser::{body_offset, SCFA};
use std::fs::File;
use std::io::Read;

let mut data = Vec::new();
File::open("tests/data/6176549.scfareplay")
    .expect("Failed to open file")
    .read_to_end(&mut data)
    .expect("Failed to read file");

// Find the index where the header stops and the replay data begins
let offset = body_offset(&data).expect("Malformed replay header");
let body = &data[offset..];

// Count the number of ticks present in the replay data, stopping on the first error.
let ticks = body
    .iter_command_frames_raw()
    .filter(|frame| frame.cmd == replay_command::ADVANCE)
    .parse_command::<SCFA>()
    .while_ok()
    .map(|command| match command {
        ReplayCommand::Advance { ticks } => ticks,
        _ => unreachable!(),
    })
    .sum::<u32>();

assert_eq!(ticks, 28917);

For more details on the available functions see iter.

§Using the generic Parser

use faf_replay_parser::{Parser, SCFA};
use std::fs::File;
use std::io::{BufReader, Read};

let file = File::open("tests/data/6176549.scfareplay")
    .expect("Failed to open file");
let mut reader = BufReader::new(file);

let parser = Parser::<SCFA>::new();
let replay = parser.parse(&mut reader).expect("Corrupt replay data");

let ticks = replay.body.sim.tick;

assert_eq!(ticks, 28917);

Note that functions which parse the header also require std::io::BufRead to be implemented.

For more details on the available functions see parser.

Re-exports§

pub use iter::CommandFrameAdapters;
pub use iter::CommandIter;
pub use parser::Parser;
pub use parser::StreamParser;
pub use scfa::body_offset;
pub use scfa::body_ticks;
pub use scfa::has_frame;
pub use sc2::SC2;
pub use scfa::SCFA;
pub use version::Version;

Modules§

aggregator
Convenience functions for extracting useful data from replays
iter
Iterators for composing flexible replay parsing pipelines
lua
Handling of lua types
parser
Parse replays from generic Readers
replay
Generic struct definitions for Supreme Commander replay files.
sc2
scfa
Supreme Commander: Forged Alliance data format
version
Trait definitions for parsing different replay versions

Macros§

lua
Provides a simple syntax for constructing lua objects.

Structs§

ParserBuilder
A builder for configuring replay Parsers. See build for an example.

Enums§

ReplayReadError

Type Aliases§

ReplayResult