- Preliminary v2.45 support for struct header properties and empty strings
- Support for v2.43 replays
- Deterministic JSON serialization
- Bump MSRV to 1.77
- Fix overflow edge cases in network parser
- Update bitter dependency to 0.7
- Support RL 2.39 Replays with Replicated Boost
- Add support for bot replays
- Add support for post match celebration attribute
- Support knockout replays
- Export all attribute types
- Add full Eq trait to all structs needed to allow full eq on UniqueId
- Support parsing patch v2.23 replays
- Improve dropshot compatibility
- Support parsing patch v2.21 replays
- 20% performance increase from bitter update from 0.5 to 0.6
- Support parsing voice chat related attributes (patch v2.15)
- Support parsing impulse attributes (patch v2.08)
- Additional support for recent rumble replays
- Support parsing rocket league v2.01 replays
- Derive
Hash
forUniqueId
andRemoteId
HeaderProp::Byte
now exposes parsed fields (breaking change for those who operate on this enum. This is in contrast to breaking changes in network attributes introduced in patch versions, as updating network attributes are needed to parse latest RL replays and should be considered routine).- MSRV is now 1.46.0
phf
dependency updated to 0.9
- Support gridiron replays
No changes in behavior, bump bitter
internal dependency to latest
- Allow missing trailers on replays instead of erroring as trailers are unused and not exposed
- Support additional LAN / RLCS replays
- Support replays that contain the rumble pickup attribute
- Support replays that contain the difficulty attribute
- Support for tournament replays:
MaxTimeWarningData_TA
and crew addedEngine.ReplicatedActor_ORS:ReplicatedOwner
attribute added
- Support latest rocket league patch (1.82) for Epic IDs
- Support latest rocket league patch (1.78) for demolish fx attributes
- Support latest rocket league patch (1.76) for heatseeker matches with godball.
A few breaking changes:
- Many data structures now use
i32
instead ofu32
, else-1
values would be recorded as 2^32 - 1 (4294967295) - APIs that represented actor ids are now wrapped in the
ActorId
type instead of the raw data type (eg:i32
). A good example of this is the Demolish attribute that changedattacker_actor_id: u32
toattacker: ActorId
Attribute::Loadout::unknown3
has been renamed toproduct_id
Attribute::Flagged(bool, u32)
has been moved toAttribute::ActiveActor(ActiveActor)
pub struct ActiveActor {
pub active: bool,
pub actor: ActorId,
}
Attribute::AppliedDamage
has moved to a dedicated type:
pub struct AppliedDamage {
pub id: u8,
pub position: Vector3f,
pub damage_index: i32,
pub total_damage: i32,
}
Attribute::DamageState
has moved to a dedicated type:
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,
}
Attribute::ExtendedExplosion
has moved to a dedicated type:
pub struct ExtendedExplosion {
pub explosion: Explosion,
pub unknown1: bool,
pub secondary_actor: ActorId,
}
Attribute::StatEvent
has moved to a dedicated type:
pub struct StatEvent {
pub unknown1: bool,
pub object_id: i32,
}
Add support for decoding new replays on the 1.74 patch via two new attributes:
- TAGame.PRI_TA:bIsDistracted (Attribute::Int)
- TAGame.GameEvent_Soccar_TA:MaxScore (Attribute::Boolean)
This is a performance release. Benchmarks improved by 40% when large network attributes were moved to a separate location on the heap, so that the size of the attribute data is the determined by the rigid body (the most common attribute). Below are the attributes that are now boxed:
- CamSettings
- Demolish
- Loadout
- TeamLoadout
- UniqueId
- Reservation
- PartyLeader
- PrivateMatch
While this is technically a breaking change to the API, I decided to release this as a patch release due to Box
being easily dereferenced, so usage of these attributes shouldn't change drastically.
Couple of breaking changes with how rigid bodies (and other vector based network attributes) are represented.
While boxcars could parse all replays, it nonsensically stored the quaternion information from rigid body attributes. v0.7.0 ensures that the quaternion logic now matches rattletrap, bakkes, and jjbott's implementation.
The x
, y
, and z
fields n a RigidBody
have been replaced with a rotation
field that is a quaternion:
Quaternion {
x: f32,
y: f32,
z: f32,
w: f32,
}
Previously boxcars would output the following vector data for rigid bodies:
"location": {
"bias": 262144,
"dx": 457343,
"dy": 15746,
"dz": 263845
}
This is correct, but does not conform to the other parsers (bakkes and jjbott) which look like:
"position": {
"X": 1951.99,
"Y": -2463.98,
"Z": 17.01
},
The vector fields are computed as ((X - bias) / 100). Important, the / 100
part of the formula is dropped for new actors. Thus there are two types
vectors: floating point and integer.
Having floating point and integer vectors necessitated splitting the Vector class into two: Vector3f and Vector3i (one for integer and the other for floating point -- side note: Vectorf and Vectori just didn't look right).
- Fix potential integer overflow / underflow on malicious input
- Remove unused errors: NetworkError::{ChannelsTooLarge, MaxStreamIdTooLarge}
- Overhaul error handling for network frame decoding. Whenever an error occurs, a significant amount of context is captured (what was the last actor added / updated, all previously decoded frames, actor ids, names, etc). This should make it more apparent why a replay failed to decode, and while this technically is a breaking change in the error API -- it's unlikely anyone is relying on the bowels of boxcar's error structure.
- Support decoding replays that contain duplicate object ids
- Support decoding RLCS / Lan replays
- Support decoding replays with many actors
- Remove the
multimap
dependency - Added convenience functions to extract properties from the header. Since properties in the header can be a multitude of types, one can extract the inside data if the type is known ahead of time. For instance,
MaxChannels
is a integer, so one can extract the integer withHeaderProp::as_i32
Before:
replay.properties
.iter()
.find(|&(key, _)| key == "MaxChannels")
.and_then(|&(_, ref prop)| {
if let HeaderProp::Int(v) = *prop {
Some(v)
} else {
None
}
})
After:
self.properties
.iter()
.find(|&(key, _)| key == "MaxChannels")
.and_then(|&(_, ref prop)| prop.as_i32())
- Added support for a additional attributes:
- Archetypes.GameEvent.GameEvent_SoccarLan
- Engine.Actor:bTearOff
- Engine.Pawn:HealthMax
- TAGame.Car_TA:ReplicatedCarScale
- TAGame.GameEvent_Soccar_TA:bMatchEnded
- TAGame.GameEvent_Soccar_TA:bNoContest
- TAGame.GameEvent_Soccar_TA:GameWinner
- TAGame.GameEvent_Soccar_TA:MatchWinner
- TAGame.GameEvent_Soccar_TA:MVP
- TAGame.GameEvent_TA:bAllowReadyUp
- TAGame.PRI_TA:RepStatTitles
- TAGame.Vehicle_TA:bPodiumMode
- Parse replays with QQ ids
- Parse replays from the tutorial
- Parse replays with the anniversary ball
- Parse replays that contain a ps4 platform id in the header
- Update network parser to be compatible with v1.68 rocket league replays
- Update internal phf dependency from 0.7 to 0.8
- Checking against corrupt replays using a new crc algorithm improved crc performance by 8x. This translates to a potential 20% overall performance improvement when the crc is needed / requested to be calculated when decoding a replay
- The
Replay
structure now owns all parsing data, there is no more lifetime parameter that is tied to the original raw data slice. For instance,replay.game_type
is now aString
, not aCow<'a, str>
. The impetus of this change stems from the difficulty of making a replay long lived when it's tied to the lifetime of another object. See issue 61 for more info. The result of this change should be an API that is more ergonomic. While performance decreased for those only interested in parsing the header, there was an overall performance win by moving to the new API.
- Expose error types as part of public API (#54).
- Include attribute object id on actor update, so now one can more easily derive the attribute's name with
replay.objects[attribute.object_id]
(#56)
- Update network parser to be compatible with v1.66 rocket league replays
- Update to multimap 0.6
Boxcars::ParserBuilder::parse
no longer returns afailure::Error
as the failure dependency has been removed. Instead aParseError
is returned. The same error enums are available as well as the same string representation.
- Support for haunted and rugby games.
- Improvement to error handling that gives detailed error messages on what new / updated actor may have received changes in the RL update. These error messages should only be helpful debugging new updates.
- Several security fixes:
- Malicious user could craft NumFrames property to be obscenely high and run the machine out of memory. An error is now thrown if the requested number of frames is greater than the number of bytes remaining.
- A class's network cache that referenced an out of range object id would cause a index out of bound panic. Now an error is raised.
- Other fixes are for panics in debug builds
- Update network parser to be compatible with v1.63 rocket league replays
- Update crc content from signed 32bits to unsigned 32bits as a negative checksum can be misleading.
- Additional decoding for PsyNet, Switch, and Ps4 remote ids. Instead of just a vector of opaque bytes, now the values contain a structure with additional fields like (
online_id
orname
). Any leftover data is still captured as opaque bytes.
- Update multimap requirement from 0.4 to 0.5
- Bugfix for newer replays with reservations involving psynet players
- Fix compilation edge case
- Update if_chain requirement from 0.1 to 1.0
- Minor version bump as the network API grew significantly. A lot of the network attributes were publicly opaque, so while one could access all the members (and write them out as JSON for instance) there was no way to access individual fields on these attributes (like RigidBody::sleeping was inaccessible). Hiding these fields was an oversight and has been fixed.
- Update encoding_rs from 0.7 to 0.8 (no discernible changes should be expected)
- Serialize 64bit numbers as strings, so that JSON parsers don't lose any data
in parsing them as 64bit floating point
- Javascript numbers are 64bit floating point. 64bit integers can't be represented wholly in floating point notation. Thus serialize them as strings so that downstream applications can decide on how best to interpret large numbers (like 76561198122624102). Affects Int64, QWord, Steam, and XBox attributes.
- QWord header property changes from i64 to u64 as some pointed out that negative numbers didn't make sense for QWord properties (OnlineId)
- Update network parser to be compatible with v1.61 rocket league replays
- Update network parser to be compatible with v1.59 rocket league replays
- Update network parser to be compatible with v1.50 rocket league replays
- Update network parser to be compatible with v1.45 rocket league replays
- Update network parser to be compatible with latest rocket league replays
- Improve throughput of network parsing by up to 10%
- Additional detailed error messages
- Update network parser to the latest rocket league replays
- Fixed several bugs surrounding parsing of the network data. More replays are now parseable
Initial release of the boxcars Rust library. v0.1.0 was never released on crates.io, but was used transitively with v0.1.0 of rrrocket (hence the initial version being v0.2.0 instead of v0.1.0)