### Install Cargo-Fuzz Source: https://github.com/nickbabcock/boxcars/blob/master/README.md Installs the cargo-fuzz tool, which is required to run the fuzzing suite for boxcars. ```bash cargo install cargo-fuzz ``` -------------------------------- ### Example of legacy vector data format Source: https://github.com/nickbabcock/boxcars/blob/master/CHANGELOG.md Shows the previous JSON representation of vector data using bias values. ```json "location": { "bias": 262144, "dx": 457343, "dy": 15746, "dz": 263845 } ``` -------------------------------- ### Example of standard position data format Source: https://github.com/nickbabcock/boxcars/blob/master/CHANGELOG.md Shows the current JSON representation of position data using computed floating point values. ```json "position": { "X": 1951.99, "Y": -2463.98, "Z": 17.01 }, ``` -------------------------------- ### Extract Replay Properties with HeaderProp Source: https://context7.com/nickbabcock/boxcars/llms.txt Work with replay properties using the `HeaderProp` enum to safely extract values like scores, goals, and player statistics. This example demonstrates matching property keys and using accessor methods like `as_i32()` and `as_string()`. ```rust use boxcars::{ParserBuilder, HeaderProp}; use std::fs; fn main() -> Result<(), Box> { let data = fs::read("match.replay")?; let replay = ParserBuilder::new(&data) .never_parse_network_data() .parse()?; // Find specific properties for (key, value) in &replay.properties { match key.as_str() { "Team0Score" => { if let Some(score) = value.as_i32() { println!("Blue team score: {}", score); } } "Team1Score" => { if let Some(score) = value.as_i32() { println!("Orange team score: {}", score); } } "Goals" => { // Goals is an array of goal events if let Some(goals) = value.as_array() { for goal in goals { // Each goal is a map of properties for (prop_name, prop_val) in goal { match prop_name.as_str() { "frame" => println!(" Frame: {:?}", prop_val.as_i32()), "PlayerName" => println!(" Scorer: {:?}", prop_val.as_string()), "PlayerTeam" => println!(" Team: {:?}", prop_val.as_i32()), _ => {} } } } } } "PlayerStats" => { if let Some(stats) = value.as_array() { for player in stats { for (stat_name, stat_val) in player { if stat_name == "Name" { println!("Player: {:?}", stat_val.as_string()); } } } } } _ => {} } } Ok(()) } ``` -------------------------------- ### Parse Rocket League Replay to JSON Source: https://github.com/nickbabcock/boxcars/blob/master/README.md Parses a Rocket League replay file into a JSON structure. This example parses both header and network data, returning an error if either fails. It uses `serde_json` for output. ```rust use boxcars::{ParseError, Replay}; use std::error; use std::fs; use std::io::{self, Read}; fn parse_rl(data: &[u8]) -> Result { boxcars::ParserBuilder::new(data) .must_parse_network_data() .parse() } fn run(filename: &str) -> Result<(), Box> { let filename = "assets/replays/good/rumble.replay"; let buffer = fs::read(filename)?; let replay = parse_rl(&buffer)?; serde_json::to_writer(&mut io::stdout(), &replay)?; Ok(()) } ``` -------------------------------- ### Extract Header Properties in Rust Source: https://github.com/nickbabcock/boxcars/blob/master/CHANGELOG.md Demonstrates the transition from manual pattern matching to using convenience methods for extracting header properties. ```rust replay.properties .iter() .find(|&(key, _)| key == "MaxChannels") .and_then(|&(_, ref prop)| { if let HeaderProp::Int(v) = *prop { Some(v) } else { None } }) ``` ```rust self.properties .iter() .find(|&(key, _)| key == "MaxChannels") .and_then(|&(_, ref prop)| prop.as_i32()) ``` -------------------------------- ### Run Boxcars Benchmarks Source: https://github.com/nickbabcock/boxcars/blob/master/README.md Commands to run the Boxcars library benchmarks. Includes options for compiling with CPU-specific optimizations. ```bash cargo bench ``` ```bash # Or if you want to see if compiling for the # given cpu eeks out tangible improvements: # RUSTFLAGS="-C target-cpu=native" cargo bench ``` -------------------------------- ### Extract Replay Metadata with Header-Only Parsing in Rust Source: https://context7.com/nickbabcock/boxcars/llms.txt Skip network data to achieve significant performance gains when only header properties are required. ```rust use boxcars::{ParserBuilder, HeaderProp}; use std::fs; fn main() -> Result<(), Box> { let data = fs::read("match.replay")?; // Parse header only - extremely fast let replay = ParserBuilder::new(&data) .never_parse_network_data() // Skip network data for speed .on_error_check_crc() // Only check CRC if parsing fails .parse()?; // Extract properties from header for (key, value) in &replay.properties { match value { HeaderProp::Int(n) => println!("{}: {}", key, n), HeaderProp::Str(s) => println!("{}: {}", key, s), HeaderProp::Float(f) => println!("{}: {}", key, f), HeaderProp::Array(arr) => { // Goals and PlayerStats are stored as arrays println!("{}: {} entries", key, arr.len()); } _ => {} } } // Common properties: "TeamSize", "Team0Score", "Team1Score", // "Goals", "PlayerStats", "Date", "MapName", "NumFrames" Ok(()) } ``` -------------------------------- ### Parse Replay with Network Data in Rust Source: https://context7.com/nickbabcock/boxcars/llms.txt Use ParserBuilder to parse full replay data including network frames and CRC validation. ```rust use boxcars::{ParserBuilder, ParseError, Replay}; use std::fs; fn main() -> Result<(), Box> { // Read replay file from disk let data = fs::read("match.replay")?; // Parse with full network data and CRC validation let replay: Replay = ParserBuilder::new(&data) .always_check_crc() // Validate replay integrity .must_parse_network_data() // Parse network frames (required for positions/events) .parse()?; // Access header properties println!("Game type: {}", replay.game_type); println!("Version: {}.{}", replay.major_version, replay.minor_version); // Access network frames if parsed if let Some(ref network) = replay.network_frames { println!("Total frames: {}", network.frames.len()); } Ok(()) } ``` -------------------------------- ### Handle Parsing Errors in Rust Source: https://context7.com/nickbabcock/boxcars/llms.txt Demonstrates how to use ParserBuilder to parse a replay and match against specific error types like CrcMismatch and NetworkError. ```rust use boxcars::{ParserBuilder, ParseError, NetworkError}; use std::fs; fn main() { let data = match fs::read("match.replay") { Ok(d) => d, Err(e) => { eprintln!("Failed to read file: {}", e); return; } }; let result = ParserBuilder::new(&data) .always_check_crc() .must_parse_network_data() .parse(); match result { Ok(replay) => { println!("Successfully parsed replay"); println!("Frames: {:?}", replay.network_frames.as_ref().map(|n| n.frames.len())); } Err(ParseError::CrcMismatch(expected, found)) => { eprintln!("Replay is corrupt! CRC mismatch: expected {} got {}", expected, found); } Err(ParseError::CorruptReplay(section, inner)) => { eprintln!("Replay {} is corrupt: {}", section, inner); } Err(ParseError::NetworkError(net_err)) => { eprintln!("Network parsing failed: {}", net_err); // Network errors often occur with new game patches // Use IgnoreOnError to still get header data } Err(e) => { eprintln!("Parse error: {}", e); // Error implements std::error::Error for chaining if let Some(source) = std::error::Error::source(&e) { eprintln!("Caused by: {}", source); } } } } ``` -------------------------------- ### Update snapshot tests Source: https://github.com/nickbabcock/boxcars/blob/master/CONTRIBUTING.md Run tests with the update flag to automatically generate or update snapshot files for new replay test cases. ```sh INSTA_UPDATE=always cargo test ``` -------------------------------- ### Configure Network Data Parsing with NetworkParse Source: https://context7.com/nickbabcock/boxcars/llms.txt Control how network data is parsed using the `NetworkParse` enum. Options include `Always` to enforce parsing, `Never` to skip it, and `IgnoreOnError` to proceed even if errors occur, which is useful for new game patches. ```rust use boxcars::{ParserBuilder, NetworkParse}; use std::fs; fn main() -> Result<(), Box> { let data = fs::read("match.replay")?; // Option 1: Must parse network data (fail if network parsing fails) let replay = ParserBuilder::new(&data) .with_network_parse(NetworkParse::Always) .parse()?; // Option 2: Never parse network data (header only) let replay = ParserBuilder::new(&data) .with_network_parse(NetworkParse::Never) .parse()?; // Option 3: Ignore network errors (default) // Returns header data even if network parsing fails (useful for new patches) let replay = ParserBuilder::new(&data) .with_network_parse(NetworkParse::IgnoreOnError) .parse()?; // Check if network data was successfully parsed match &replay.network_frames { Some(frames) => println!("Parsed {} frames", frames.frames.len()), None => println!("Network data not available"), } Ok(()) } ``` -------------------------------- ### Serialize Replay to JSON using Serde Source: https://context7.com/nickbabcock/boxcars/llms.txt Exports parsed replay data to JSON format using Boxcars' built-in Serde support. Can output to stdout, a file, or a string. ```rust use boxcars::ParserBuilder; use std::fs; use std::io::{self, Write}; fn main() -> Result<(), Box> { let data = fs::read("match.replay")?; let replay = ParserBuilder::new(&data) .always_check_crc() .must_parse_network_data() .parse()?; // Output pretty-printed JSON to stdout let stdout = io::stdout(); let mut out = stdout.lock(); serde_json::to_writer_pretty(&mut out, &replay)?; // Or write to a file let json_output = fs::File::create("match.json")?; serde_json::to_writer(json_output, &replay)?; // Or get as string for further processing let json_string = serde_json::to_string(&replay)?; println!("JSON size: {} bytes", json_string.len()); Ok(()) } ``` -------------------------------- ### Access Frame-by-Frame Game State in Rust Source: https://context7.com/nickbabcock/boxcars/llms.txt Iterates through network frames to identify actor spawns, deletions, and attribute updates. Requires the replay to be parsed with network data enabled. ```rust use boxcars::{ParserBuilder, Frame, NewActor, UpdatedAttribute, ActorId}; use std::fs; fn main() -> Result<(), Box> { let data = fs::read("match.replay")?; let replay = ParserBuilder::new(&data) .must_parse_network_data() .parse()?; let network = replay.network_frames.as_ref().unwrap(); for frame in &network.frames { // Frame timing println!("Time: {}s (delta: {}s)", frame.time, frame.delta); // New actors spawned this frame for actor in &frame.new_actors { let object_name = &replay.objects[actor.object_id.0 as usize]; println!(" Spawned: {} (actor_id: {})", object_name, actor.actor_id.0); // Initial position if available if let Some(loc) = actor.initial_trajectory.location { println!(" Position: ({}, {}, {})", loc.x, loc.y, loc.z); } } // Actors deleted this frame for actor_id in &frame.deleted_actors { println!(" Deleted actor: {}", actor_id.0); } // Attribute updates (positions, velocities, game events) for update in &frame.updated_actors { let attr_name = &replay.objects[update.object_id.0 as usize]; println!(" Update: actor {} - {}", update.actor_id.0, attr_name); } } Ok(()) } ``` -------------------------------- ### Access Replay Data with Replay Struct Source: https://context7.com/nickbabcock/boxcars/llms.txt Access parsed replay data including version, game type, levels, keyframes, tick marks, object IDs, and names using the `Replay` struct. Ensure network data is parsed if needed using `must_parse_network_data()`. ```rust use boxcars::{ParserBuilder, Replay, HeaderProp}; use std::fs; fn main() -> Result<(), Box> { let data = fs::read("match.replay")?; let replay: Replay = ParserBuilder::new(&data) .must_parse_network_data() .parse()?; // Version information println!("Replay version: {}.{:.?}", replay.major_version, replay.minor_version, replay.net_version); // Game type (e.g., "TAGame.Replay_Soccar_TA") println!("Game type: {}", replay.game_type); // Levels played on for level in &replay.levels { println!("Level: {}", level); } // Keyframes for video-style seeking for kf in &replay.keyframes { println!("Keyframe at {}s, frame {}", kf.time, kf.frame); } // Tick marks (significant events like goals) for tick in &replay.tick_marks { println!("{} at frame {}", tick.description, tick.frame); } // Object names referenced by IDs in network data // Use: replay.objects[object_id] to get object name println!("Total objects: {}", replay.objects.len()); // Actor names referenced by IDs in network data // Use: replay.names[name_id] to get actor name println!("Total names: {}", replay.names.len()); Ok(()) } ``` -------------------------------- ### Extract Demolition Events from Replay Data Source: https://context7.com/nickbabcock/boxcars/llms.txt Correlates actor data across network frames to identify demolition events and resolve player names. Requires parsing network data. ```rust use boxcars::{ParserBuilder, Attribute, ActorId, ObjectId}; use boxcars::attributes::ActiveActor; use std::collections::HashMap; use std::fs; fn find_object_id(replay: &boxcars::Replay, name: &str) -> Option { replay.objects.iter() .position(|v| v == name) .map(|i| ObjectId(i as i32)) } fn main() -> Result<(), Box> { let data = fs::read("match.replay")?; let replay = ParserBuilder::new(&data) .must_parse_network_data() .parse()?; // Find relevant object IDs let pri_name_id = find_object_id(&replay, "Engine.PlayerReplicationInfo:PlayerName"); let car_pri_id = find_object_id(&replay, "Engine.Pawn:PlayerReplicationInfo"); let demolish_id = find_object_id(&replay, "TAGame.Car_TA:ReplicatedDemolish"); // Track actor relationships let mut car_to_pri: HashMap = HashMap::new(); let mut pri_to_name: HashMap = HashMap::new(); let network = replay.network_frames.as_ref().unwrap(); for frame in &network.frames { for attr in &frame.updated_actors { // Link cars to player replication info if Some(attr.object_id) == car_pri_id { if let Attribute::ActiveActor(ActiveActor { actor, .. }) = attr.attribute { if actor != ActorId(-1) { car_to_pri.insert(attr.actor_id, actor); } } } // Map player replication info to names if Some(attr.object_id) == pri_name_id { if let Attribute::String(ref name) = attr.attribute { pri_to_name.insert(attr.actor_id, name.clone()); } } // Detect demolitions if Some(attr.object_id) == demolish_id { if let Attribute::Demolish(d) = &attr.attribute { let attacker_name = car_to_pri.get(&d.attacker) .and_then(|pri| pri_to_name.get(pri)) .map(|s| s.as_str()) .unwrap_or("Unknown"); let victim_name = car_to_pri.get(&d.victim) .and_then(|pri| pri_to_name.get(pri)) .map(|s| s.as_str()) .unwrap_or("Unknown"); println!("t={:.2}s {} demolished {}", frame.time, attacker_name, victim_name); } } } } Ok(()) } ``` -------------------------------- ### Run Boxcars Fuzzing Suite Source: https://github.com/nickbabcock/boxcars/blob/master/README.md Executes the 'no-crc-body' fuzzing scenario for boxcars. This scenario is recommended as it fuzzes all aspects of the replay without a CRC check. ```bash cargo +nightly fuzz run no-crc-body ``` -------------------------------- ### Boxcars vs. Rattletrap BuildID JSON Structure Source: https://github.com/nickbabcock/boxcars/blob/master/README.md Illustrates the difference in how BuildID is represented in the JSON output between rattletrap and boxcars. Boxcars provides a direct integer value, while rattletrap nests it within a property structure. ```json "properties": { "value": { "BuildID": { "kind": "IntProperty", "size": "4", "value": { "int": 1401925076 } }, } } ``` ```json "properties": { "BuildID": 1401925076 } ``` -------------------------------- ### Define AppliedDamage struct Source: https://github.com/nickbabcock/boxcars/blob/master/CHANGELOG.md Represents damage application details including position and damage indices. ```rust pub struct AppliedDamage { pub id: u8, pub position: Vector3f, pub damage_index: i32, pub total_damage: i32, } ``` -------------------------------- ### Boxcars vs. Rattletrap Spawned Actor JSON Structure Source: https://github.com/nickbabcock/boxcars/blob/master/README.md Highlights the difference in representing spawned actor details. Rattletrap includes extensive initialization data, while boxcars provides a more concise set of core identifiers and trajectory information. ```json "value": { "spawned": { "class_name": "TAGame.GameEvent_Soccar_TA", "flag": true, "initialization": { "location": { "bias": 2, "size": { "limit": 21, "value": 0 }, "x": 0, "y": 0, "z": 0 } }, "name": "GRI_TA_1", "name_index": 0, "object_id": 85, "object_name": "Archetypes.GameEvent.GameEvent_Soccar" } } ``` ```json "actor_id": 1, "name_id": 1, "object_id": 85, "initial_trajectory": { "location": { "x": 0, "y": 0, "z": 0 }, "rotation": null } ``` -------------------------------- ### Calculate CRC-32 Checksum for Replay Validation Source: https://context7.com/nickbabcock/boxcars/llms.txt Calculates the CRC-32 checksum of replay file data using the `calc_crc` function from the `boxcars::crc` module. This matches the Unreal Engine implementation. ```rust use boxcars::crc::calc_crc; use std::fs; fn main() -> Result<(), Box> { let data = fs::read("match.replay")?; // Calculate CRC for the entire file let checksum = calc_crc(&data); println!("File CRC: {}", checksum); // CRC parameters for Rocket League replays: // - Width: 32 // - Poly: 0x04c11db7 // - XorIn: 0x10340dfe // - ReflectIn: false // - XorOut: 0xffffffff // - ReflectOut: false Ok(()) } ``` -------------------------------- ### Define DamageState struct Source: https://github.com/nickbabcock/boxcars/blob/master/CHANGELOG.md Contains state information for dropshot tiles and associated damage events. ```rust pub struct DamageState { /// State of the dropshot tile (0 - undamaged, 1 - damaged, 2 - destroyed) pub tile_state: u8, /// True if damaged pub damaged: bool, /// Player actor that inflicted the damage pub offender: ActorId, /// Position of the ball at the time of the damage pub ball_position: Vector3f, /// True for the dropshot tile that was hit by the ball (center tile of the damage area) pub direct_hit: bool, pub unknown1: bool, } ``` -------------------------------- ### Configure CRC Corruption Detection in Rust Source: https://context7.com/nickbabcock/boxcars/llms.txt Control integrity validation behavior using the CrcCheck enum to balance performance and error detection. ```rust use boxcars::{ParserBuilder, CrcCheck}; use std::fs; fn main() -> Result<(), Box> { let data = fs::read("match.replay")?; // Option 1: Always check CRC (catches tampering but slower) let replay = ParserBuilder::new(&data) .with_crc_check(CrcCheck::Always) .parse()?; // Option 2: Never check CRC (fastest, use when corruption doesn't matter) let replay = ParserBuilder::new(&data) .with_crc_check(CrcCheck::Never) .parse()?; // Option 3: Check CRC only on error (default - best of both worlds) // If parsing fails, CRC check determines if it's corruption or a bug let replay = ParserBuilder::new(&data) .with_crc_check(CrcCheck::OnError) .parse()?; Ok(()) } ``` -------------------------------- ### Define Quaternion structure Source: https://github.com/nickbabcock/boxcars/blob/master/CHANGELOG.md Represents rotation using a quaternion with x, y, z, and w components. ```rust Quaternion { x: f32, y: f32, z: f32, w: f32, } ``` -------------------------------- ### Define StatEvent struct Source: https://github.com/nickbabcock/boxcars/blob/master/CHANGELOG.md Represents a statistical event associated with an object ID. ```rust pub struct StatEvent { pub unknown1: bool, pub object_id: i32, } ``` -------------------------------- ### Decode Network Attribute Updates in Rust Source: https://context7.com/nickbabcock/boxcars/llms.txt Uses pattern matching on the Attribute enum to handle various actor updates such as rigid body physics, player names, and demolition events. ```rust use boxcars::{ParserBuilder, Attribute}; use std::fs; fn main() -> Result<(), Box> { let data = fs::read("match.replay")?; let replay = ParserBuilder::new(&data) .must_parse_network_data() .parse()?; let network = replay.network_frames.as_ref().unwrap(); for frame in &network.frames { for update in &frame.updated_actors { match &update.attribute { // Most common: rigid body state (position, rotation, velocity) Attribute::RigidBody(rb) => { println!("Actor {} at ({:.1}, {:.1}, {:.1})", update.actor_id.0, rb.location.x, rb.location.y, rb.location.z); if !rb.sleeping { if let Some(vel) = &rb.linear_velocity { println!(" Velocity: ({:.1}, {:.1}, {:.1})", vel.x, vel.y, vel.z); } } } // Player name updates Attribute::String(name) => { println!("Player name: {}", name); } // Demolition events Attribute::Demolish(demo) => { println!("Demolition! Attacker: {}, Victim: {}", demo.attacker.0, demo.victim.0); } // Boolean flags (e.g., ball touched, boost active) Attribute::Boolean(val) => { println!("Flag: {}", val); } // Camera settings Attribute::CamSettings(cam) => { println!("Camera FOV: {}, Distance: {}", cam.fov, cam.distance); } // Team colors Attribute::TeamPaint(paint) => { println!("Team {}: colors {}/{}", paint.team, paint.primary_color, paint.accent_color); } _ => {} // Many other attribute types available } } } Ok(()) } ``` -------------------------------- ### Boxcars vs. Rattletrap Attribute Update JSON Structure Source: https://github.com/nickbabcock/boxcars/blob/master/README.md Compares the JSON structure for attribute updates. Rattletrap nests the updated value, while boxcars flattens it and includes a stream_id. ```json { "actor_id": { "limit": 2047, "value": 7 }, "value": { "updated": [ { "id": { "limit": 98, "value": 34 }, "name": "Engine.PlayerReplicationInfo:PlayerName", "value": { "string": "Nadir" } } ] } } ``` ```json { "actor_id": 7, "stream_id": 34, "object_id": 161, "attribute": { "String": "Nadir" } } ``` -------------------------------- ### Boxcars vs. Rattletrap Actor ID JSON Structure Source: https://github.com/nickbabcock/boxcars/blob/master/README.md Shows the difference in actor_id representation. Rattletrap includes a limit and a nested value, while boxcars presents a direct integer. ```json "actor_id": { "limit": 2047, "value": 1 } ``` ```json "actor_id": 1 ``` -------------------------------- ### Define ExtendedExplosion struct Source: https://github.com/nickbabcock/boxcars/blob/master/CHANGELOG.md Represents an extended explosion event with secondary actor information. ```rust pub struct ExtendedExplosion { pub explosion: Explosion, pub unknown1: bool, pub secondary_actor: ActorId, } ``` -------------------------------- ### Define ActiveActor struct Source: https://github.com/nickbabcock/boxcars/blob/master/CHANGELOG.md Represents an active actor with a boolean state and an ActorId. ```rust pub struct ActiveActor { pub active: bool, pub actor: ActorId, } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.