feat: add 2022 spec session history packet parser

This commit is contained in:
Maciej Pędzich 2025-02-19 12:53:56 +01:00
parent d880590e8b
commit ac7130fae1
Signed by: maciejpedzich
GPG Key ID: CE4A303D84882F0D
4 changed files with 127 additions and 4 deletions

View File

@ -1167,3 +1167,30 @@ pub enum ReadyStatus {
Ready = 1,
Spectating = 2,
}
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
Ord,
PartialOrd,
Hash,
Serialize,
Deserialize,
)]
pub struct LapValid(u8);
bitflags! {
impl LapValid: u8 {
/// Whether the whole lap is valid. Has a value of `0b0001`
const Overall = 0b0001;
/// Whether the sector 1 run is valid. Has a value of `0b0010`
const Sector1 = 0b0010;
/// Whether the sector 2 run is valid. Has a value of `0b0100`
const Sector2 = 0b0100;
/// Whether the sector 3 run is valid. Has a value of `0b1000`
const Sector3 = 0b1000;
}
}

View File

@ -6,7 +6,7 @@ use crate::packets::{
F1PacketCarDamage, F1PacketCarSetups, F1PacketCarStatus,
F1PacketCarTelemetry, F1PacketEvent, F1PacketFinalClassification,
F1PacketLap, F1PacketLobbyInfo, F1PacketMotion, F1PacketParticipants,
F1PacketSession,
F1PacketSession, F1PacketSessionHistory,
};
use binrw::io::Cursor;
@ -107,4 +107,7 @@ pub struct F1PacketBody {
/// Car damage parameters for all cars in the session.
#[br(if(packet_id == PacketId::CarDamage), args(packet_format))]
pub car_damage: Option<F1PacketCarDamage>,
/// Session history data for a specific car.
#[br(if(packet_id == PacketId::SessionHistory), args(packet_format))]
pub session_history: Option<F1PacketSessionHistory>,
}

View File

@ -1,20 +1,22 @@
mod car_damage;
pub mod car_damage;
pub mod car_setups;
pub mod car_status;
pub mod car_telemetry;
pub mod event;
pub mod final_classification;
pub mod lap;
mod lobby;
pub mod lobby;
pub mod motion;
pub mod participants;
pub mod session;
pub mod session_history;
use crate::constants::{
BrakingAssist, DynamicRacingLine, DynamicRacingLineType, ForecastAccuracy,
Formula, GameMode, GearboxAssist, MfdPanelIndex, Ruleset, SafetyCarStatus,
SessionLength, SessionType, TrackId, Weather, MAX_NUM_CARS,
};
use crate::packets::car_damage::CarDamageData;
use crate::packets::car_setups::CarSetupData;
use crate::packets::car_status::CarStatusData;
use crate::packets::car_telemetry::CarTelemetryData;
@ -25,8 +27,8 @@ use crate::packets::lobby::LobbyInfoData;
use crate::packets::motion::CarMotionData;
use crate::packets::participants::ParticipantsData;
use crate::packets::session::{MarshalZone, WeatherForecastSample};
use crate::packets::session_history::{LapHistoryData, TyreStintHistoryData};
use crate::packets::car_damage::CarDamageData;
use binrw::BinRead;
use serde::{Deserialize, Serialize};
use std::string::FromUtf8Error;
@ -353,6 +355,60 @@ pub struct F1PacketCarDamage {
pub car_damage_data: Vec<CarDamageData>,
}
/// Packet detailing lap and tyre data history for a given driver in the session
#[non_exhaustive]
#[derive(
BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize,
)]
#[br(
little,
import(packet_format: u16),
assert(
vehicle_index < MAX_NUM_CARS,
"Session history packet has an invalid vehicle index: {}",
vehicle_index
),
assert(
num_laps <= 100,
"Session history packet has an invalid number of laps: {}",
num_laps
),
assert(
num_tyre_stints <= 8,
"Session history packet has an invalid number of tyre stints: {}",
num_tyre_stints
)
)]
pub struct F1PacketSessionHistory {
/// Index of the car this packet refers to
#[br(map(u8_to_usize))]
pub vehicle_index: usize,
/// Number of laps in the data (including the current one)
#[br(map(u8_to_usize))]
pub num_laps: usize,
/// Number of tyre stints in the data (including the current one)
#[br(map(u8_to_usize))]
pub num_tyre_stints: usize,
/// Number of the lap the best lap time was achieved on
#[br(map(u8_to_usize))]
pub best_lap_time_lap_num: usize,
/// Number of the lap the best sector 1 time was achieved on
#[br(map(u8_to_usize))]
pub best_sector1_lap_num: usize,
/// Number of the lap the best sector 2 time was achieved on
#[br(map(u8_to_usize))]
pub best_sector2_lap_num: usize,
/// Number of the lap the best sector 3 time was achieved on
#[br(map(u8_to_usize))]
pub best_sector3_lap_num: usize,
/// Up to 100 laps
#[br(count(100), args{ inner: (packet_format,) })]
pub lap_history_data: Vec<LapHistoryData>,
/// Up to 8 tyre stints
#[br(count(8), args{ inner: (packet_format,) })]
pub tyre_stint_history_data: Vec<TyreStintHistoryData>,
}
/// Extended motion data for player's car. Available as a:
/// - part of [`F1PacketMotion`] in the 2022 format
/// - standalone packet from the 2023 format onwards

View File

@ -0,0 +1,37 @@
use super::u8_to_usize;
use crate::constants::{ActualTyreCompound, LapValid, VisualTyreCompound};
use binrw::BinRead;
use serde::{Deserialize, Serialize};
#[derive(
BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize,
)]
#[br(little, import(_packet_format: u16))]
pub struct LapHistoryData {
/// Lap time in milliseconds.
pub lap_time_ms: u32,
/// Sector 1 time in milliseconds.
pub sector1_time_ms: u16,
/// Sector 2 time in milliseconds.
pub sector2_time_ms: u16,
/// Sector 3 time in milliseconds.
pub sector3_time_ms: u16,
/// Bitmap of lap validity across all sectors and overall.
#[br(map(LapValid::from_bits_truncate))]
pub lap_valid_bit_flags: LapValid,
}
#[derive(
BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize,
)]
#[br(little, import(_packet_format: u16))]
pub struct TyreStintHistoryData {
/// Lap the tyre usage ends on (255 if current tyre)
#[br(map(u8_to_usize))]
pub end_lap: usize,
/// Actual tyre compound used
pub actual_tyre_compound: ActualTyreCompound,
/// Visual tyre compound used
pub visual_tyre_compound: VisualTyreCompound,
}