feat: add 2024 spec parser fields and constants

This commit is contained in:
Maciej Pędzich 2025-02-21 21:00:56 +01:00
parent d2ded9da51
commit edaef5b865
Signed by: maciejpedzich
GPG Key ID: CE4A303D84882F0D
15 changed files with 357 additions and 154 deletions

View File

@ -1001,3 +1001,27 @@ pub enum RedFlags {
Standard = 2,
Increased = 3,
}
#[non_exhaustive]
#[derive(
BinRead, Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Debug, Serialize, Deserialize,
)]
#[br(little, repr(u8))]
pub enum SafetyCarType {
None = 0,
Full = 1,
Virtual = 2,
FormationLap = 3,
}
#[non_exhaustive]
#[derive(
BinRead, Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Debug, Serialize, Deserialize,
)]
#[br(little, repr(u8))]
pub enum SafetyCarEventType {
Deployed = 0,
Returning = 1,
Returned = 2,
ResumeRace = 3,
}

View File

@ -6,7 +6,7 @@ use crate::packets::{
u8_to_usize, F1PacketCarDamage, F1PacketCarSetups, F1PacketCarStatus,
F1PacketCarTelemetry, F1PacketEvent, F1PacketFinalClassification, F1PacketLap,
F1PacketLobbyInfo, F1PacketMotion, F1PacketMotionEx, F1PacketParticipants,
F1PacketSession, F1PacketSessionHistory, F1PacketTyreSets,
F1PacketSession, F1PacketSessionHistory, F1PacketTimeTrial, F1PacketTyreSets,
};
use binrw::io::Cursor;
@ -125,4 +125,8 @@ pub struct F1PacketBody {
/// Available from the 2023 format onwards.
#[br(if(packet_id == PacketId::MotionEx), args(packet_format))]
pub motion_ex: Option<F1PacketMotionEx>,
/// Extra information that's only relevant to time trial game mode.
/// Available from the 2024 format onwards.
#[br(if(packet_id == PacketId::TimeTrial), args(packet_format))]
pub time_trial: Option<F1PacketTimeTrial>,
}

View File

@ -18,44 +18,44 @@ pub struct CarDamageData {
/// See [`wheel_index`](mod@crate::constants::wheel_index)
/// for wheel order.
pub brakes_damage: [u8; 4],
/// Front left wing damage (percentage)
/// Front left wing damage (percentage).
pub front_left_wing_damage: u8,
/// Front right wing damage (percentage)
/// Front right wing damage (percentage).
pub front_right_wing_damage: u8,
/// Rear wing damage (percentage)
/// Rear wing damage (percentage).
pub rear_wing_damage: u8,
/// Floor damage (percentage)
/// Floor damage (percentage).
pub floor_damage: u8,
/// Diffuser damage (percentage)
/// Diffuser damage (percentage).
pub diffuser_damage: u8,
/// Sidepod damage (percentage)
/// Sidepod damage (percentage).
pub sidepod_damage: u8,
/// Whether DRS has failed
/// Whether DRS has failed.
#[br(try_map(u8_to_bool))]
pub drs_fault: bool,
/// Whether ERS has failed
/// Whether ERS has failed.
#[br(try_map(u8_to_bool))]
pub ers_fault: bool,
/// Gearbox damage (percentage)
/// Gearbox damage (percentage).
pub gearbox_damage: u8,
/// Engine damage (percentage)
/// Engine damage (percentage).
pub engine_damage: u8,
/// Engine MGU-H wear (percentage)
/// Engine MGU-H wear (percentage).
pub engine_mguh_wear: u8,
/// Engine ES wear (percentage)
/// Engine ES wear (percentage).
pub engine_es_wear: u8,
/// Engine CE wear (percentage)
/// Engine CE wear (percentage).
pub engine_ce_wear: u8,
/// Engine ICE wear (percentage)
/// Engine ICE wear (percentage).
pub engine_ice_wear: u8,
/// Engine MGU-K wear (percentage)
/// Engine MGU-K wear (percentage).
pub engine_mguk_wear: u8,
/// Engine TC wear (percentage)
/// Engine TC wear (percentage).
pub engine_tc_wear: u8,
/// Whether the engine has blown
/// Whether the engine has blown.
#[br(try_map(u8_to_bool))]
pub engine_blown: bool,
/// Whether the engine has seized
/// Whether the engine has seized.
#[br(try_map(u8_to_bool))]
pub engine_seized: bool,
}

View File

@ -5,48 +5,48 @@ use serde::{Deserialize, Serialize};
#[derive(BinRead, PartialEq, PartialOrd, Copy, Clone, Debug, Serialize, Deserialize)]
#[br(little, import(_packet_format: u16))]
pub struct CarSetupData {
/// Front wing aero
/// Front wing aero.
pub front_wing: u8,
/// Rear wing aero
/// Rear wing aero.
pub rear_wing: u8,
/// Differential adjustment on throttle (percentage)
/// Differential adjustment on throttle (percentage).
pub on_throttle: u8,
/// Differential adjustment off throttle (percentage)
/// Differential adjustment off throttle (percentage).
pub off_throttle: u8,
/// Front camber angle (suspension geometry)
/// Front camber angle (suspension geometry).
pub front_camber: f32,
/// Rear camber angle (suspension geometry)
/// Rear camber angle (suspension geometry).
pub rear_camber: f32,
/// Front toe angle (suspension geometry)
/// Front toe angle (suspension geometry).
pub front_toe: f32,
/// Rear toe angle (suspension geometry)
/// Rear toe angle (suspension geometry).
pub rear_toe: f32,
/// Front suspension
/// Front suspension.
pub front_suspension: u8,
/// Rear suspension
/// Rear suspension.
pub rear_suspension: u8,
/// Front anti-roll bar
/// Front anti-roll bar.
pub front_anti_roll_bar: u8,
/// Rear anti-roll bar
/// Rear anti-roll bar.
pub rear_anti_roll_bar: u8,
/// Front ride height
/// Front ride height.
pub front_suspension_height: u8,
/// Rear ride height
/// Rear ride height.
pub rear_suspension_height: u8,
/// Brake pressure (percentage)
/// Brake pressure (percentage).
pub brake_pressure: u8,
/// Brake bias
/// Brake bias.
pub brake_bias: u8,
/// Rear left tyre pressure
/// Rear left tyre pressure.
pub rear_left_tyre_pressure: f32,
/// Rear right tyre pressure
/// Rear right tyre pressure.
pub rear_right_tyre_pressure: f32,
/// Front left tyre pressure
/// Front left tyre pressure.
pub front_left_tyre_pressure: f32,
/// Front right tyre pressure
/// Front right tyre pressure.
pub front_right_tyre_pressure: f32,
/// Ballast
/// Ballast.
pub ballast: u8,
/// Fuel load
/// Fuel load.
pub fuel_load: f32,
}

View File

@ -9,15 +9,7 @@ use serde::{Deserialize, Serialize};
#[non_exhaustive]
#[derive(BinRead, PartialEq, PartialOrd, Copy, Clone, Debug, Serialize, Deserialize)]
#[br(
little,
import(packet_format: u16),
assert(
max_gears <= 9,
"Car status entry has an invalid max number of gears: {}",
max_gears
)
)]
#[br(little, import(packet_format: u16))]
pub struct CarStatusData {
/// How much traction control is enabled.
pub traction_control: TractionControl,
@ -42,6 +34,13 @@ pub struct CarStatusData {
/// Car's idle RPM.
pub idle_rpm: u16,
/// Maximum number of gears.
#[br(
assert(
max_gears <= 9,
"Car status entry has an invalid max number of gears: {}",
max_gears
)
)]
pub max_gears: u8,
/// Whether DRS can be used (might be unknown).
pub drs_allowed: DrsAllowed,

View File

@ -6,52 +6,54 @@ use serde::{Deserialize, Serialize};
#[non_exhaustive]
#[derive(BinRead, PartialEq, PartialOrd, Copy, Clone, Debug, Serialize, Deserialize)]
#[br(
little,
import(_packet_format: u16),
assert(
(0.0..=1.0).contains(&throttle),
"Car telemetry entry has an invalid throttle value: {}",
throttle
),
assert(
(-1.0..=1.0).contains(&steer),
"Car telemetry entry has an invalid steering lock value: {}",
steer
),
assert(
(0.0..=1.0).contains(&brake),
"Car telemetry entry has an invalid brake value: {}",
brake
),
assert(
clutch <= 100,
"Car telemetry entry has an invalid clutch value: {}",
clutch
),
assert(
(-1..=8).contains(&gear),
"Car telemetry entry has an invalid gear value: {}",
gear
),
assert(
rev_lights_percent <= 100,
"Car telemetry entry has an invalid rev lights percentage: {}",
rev_lights_percent
),
)]
#[br(little, import(_packet_format: u16))]
pub struct CarTelemetryData {
/// Speed of the car in kilometres per hour.
pub speed: u16,
/// Amount of throttle applied. Value in range `(0.0..=1.0)`.
#[br(
assert(
(0.0..=1.0).contains(&throttle),
"Car telemetry entry has an invalid throttle value: {}",
throttle
),
)]
pub throttle: f32,
/// Steering lock. Value in range `(-1.0..=1.0)`.
#[br(
assert(
(-1.0..=1.0).contains(&steer),
"Car telemetry entry has an invalid steering lock value: {}",
steer
),
)]
pub steer: f32,
/// Amount of brake applied. Value in range `(0.0..=1.0)`.
#[br(
assert(
(0.0..=1.0).contains(&brake),
"Car telemetry entry has an invalid brake value: {}",
brake
),
)]
pub brake: f32,
/// Amount of clutch applied (percentage).
#[br(
assert(
clutch <= 100,
"Car telemetry entry has an invalid clutch value: {}",
clutch
),
)]
pub clutch: u8,
/// Selected gear. Neutral = 0, reverse = -1.
#[br(
assert(
(-1..=8).contains(&gear),
"Car telemetry entry has an invalid gear value: {}",
gear
),
)]
pub gear: i8,
/// Engine RPM.
pub engine_rpm: u16,
@ -59,6 +61,13 @@ pub struct CarTelemetryData {
#[br(try_map(u8_to_bool))]
pub drs_enabled: bool,
/// Rev lights indicator (percentage).
#[br(
assert(
rev_lights_percent <= 100,
"Car telemetry entry has an invalid rev lights percentage: {}",
rev_lights_percent
),
)]
pub rev_lights_percent: u8,
/// Bitmap of active rev lights.
#[br(map(RevLights::from_bits_truncate))]

View File

@ -1,12 +1,14 @@
use super::{u8_to_bool, u8_to_usize};
use crate::constants::{ButtonStatus, InfringementType, PenaltyType};
use crate::constants::{
ButtonStatus, InfringementType, PenaltyType, SafetyCarEventType, SafetyCarType,
};
use binrw::BinRead;
use serde::{Deserialize, Serialize};
#[non_exhaustive]
#[derive(BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize)]
#[br(little)]
#[derive(BinRead, PartialEq, PartialOrd, Copy, Clone, Debug, Serialize, Deserialize)]
#[br(little, import(_packet_format: u16))]
pub enum EventDataDetails {
/// Sent when the session starts.
#[br(magic = b"SSTA")]
@ -142,4 +144,19 @@ pub enum EventDataDetails {
#[br(map(u8_to_usize))]
overtaken_vehicle_index: usize,
},
/// Sent when safety car gets deployed.
/// Available from the 2024 format onwards.
#[br(magic = b"SCAR")]
SafetyCar { safety_car_type: SafetyCarType, event_type: SafetyCarEventType },
/// Sent when two vehicles collide.
/// Available from the 2024 format onwards.
#[br(magic = b"COLL")]
Collision {
/// Index of the first vehicle involved in the collision.
#[br(map(u8_to_usize))]
vehicle1_index: usize,
/// Index of the second vehicle involved in the collision.
#[br(map(u8_to_usize))]
vehicle2_index: usize,
},
}

View File

@ -4,17 +4,11 @@ use crate::constants::{ActualTyreCompound, ResultStatus, VisualTyreCompound};
use binrw::BinRead;
use serde::{Deserialize, Serialize};
const MAX_NUM_TYRE_STINTS: usize = 8;
#[non_exhaustive]
#[derive(BinRead, PartialEq, PartialOrd, Copy, Clone, Debug, Serialize, Deserialize)]
#[br(
little,
import(_packet_format: u16),
assert(
num_tyre_stints <= 8,
"Final classification entry has an invalid number of tyre stints: {}",
num_tyre_stints
)
)]
#[derive(BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize)]
#[br(little, import(_packet_format: u16))]
pub struct FinalClassificationData {
/// Finishing position.
pub position: u8,
@ -36,13 +30,26 @@ pub struct FinalClassificationData {
pub penalties_time: u8,
/// Number of penalties applied to this driver.
pub num_penalties: u8,
/// Number of tyre stints (no greater than 8).
#[br(map(u8_to_usize))]
/// Number of tyre stints.
#[br(
map(u8_to_usize),
assert(
num_tyre_stints <= MAX_NUM_TYRE_STINTS,
"Final classification entry has an invalid number of tyre stints: {}",
num_tyre_stints
)
)]
pub num_tyre_stints: usize,
/// Actual tyres used by the driver.
pub tyre_stints_actual: [ActualTyreCompound; 8],
/// Should have a size equal to `num_tyre_stints`.
#[br(count(num_tyre_stints), pad_after(MAX_NUM_TYRE_STINTS - num_tyre_stints))]
pub tyre_stints_actual: Vec<ActualTyreCompound>,
/// Visual tyres used by the driver.
pub tyre_stints_visual: [VisualTyreCompound; 8],
/// Should have a size equal to `num_tyre_stints`.
#[br(count(num_tyre_stints), pad_after(MAX_NUM_TYRE_STINTS - num_tyre_stints))]
pub tyre_stints_visual: Vec<VisualTyreCompound>,
/// The lap numbers the stints end on.
pub tyre_stints_end_laps: [u8; 8],
/// Should have a size equal to `num_tyre_stints`.
#[br(count(num_tyre_stints), pad_after(MAX_NUM_TYRE_STINTS - num_tyre_stints))]
pub tyre_stints_end_laps: Vec<u8>,
}

View File

@ -21,26 +21,34 @@ pub struct LapData {
pub last_lap_time_ms: u32,
/// Current lap time in milliseconds.
pub current_lap_time_ms: u32,
/// Current sector 1 time in milliseconds.
pub sector1_time_ms: u16,
/// Current sector 1 time millisecond part.
pub sector1_time_ms_part: u16,
/// Sector 1 whole minute part.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub sector1_time_minutes: u8,
/// Current sector 2 time in milliseconds.
pub sector2_time_ms: u16,
pub sector1_time_minutes_part: u8,
/// Current sector 2 time millisecond part.
pub sector2_time_ms_part: u16,
/// Sector 2 whole minute part.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub sector2_time_minutes: u8,
pub sector2_time_minutes_part: u8,
/// Time delta to car in front in milliseconds.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub delta_to_car_in_front_ms: u16,
pub delta_to_car_in_front_ms_part: u16,
/// Time delta to car in front whole minute part.
/// Available from the 2024 format onwards.
#[br(if(packet_format >= 2024))]
pub delta_to_car_in_front_minutes_part: u8,
/// Time delta to race leader in milliseconds.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub delta_to_race_leader_ms: u16,
/// Time delta to car in front whole minute part.
/// Available from the 2024 format onwards.
#[br(if(packet_format >= 2024))]
pub delta_to_race_leader_minutes_part: u8,
/// The distance the vehicle is around current lap in metres.
/// It may be negative if the start/finish line hasnt been crossed yet.
pub lap_distance: f32,
@ -66,12 +74,6 @@ pub struct LapData {
/// Accumulated time penalties to be added in seconds.
pub penalties: u8,
/// Accumulated number of warnings issued.
/// Available only in the 2022 format.
#[br(if(packet_format == 2022))]
pub warnings: u8,
/// Accumulated number of warnings issued.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub total_warnings: u8,
/// Accumulated number of corner cutting warnings issued.
/// Available from the 2023 format onwards.
@ -97,4 +99,13 @@ pub struct LapData {
/// Whether the car should serve a penalty at this stop.
#[br(try_map(u8_to_bool))]
pub pit_stop_should_serve_pen: bool,
/// Fastest speed through speed trap for this car in kilometres per hour.
/// Available from the 2024 format onwards.
#[br(if(packet_format >= 2024))]
pub speed_trap_fastest_speed: f32,
/// Number of the lap the fastest speed was achieved on
/// (255 means "not set")
/// Available from the 2024 format onwards.
#[br(if(packet_format >= 2024))]
pub speed_trap_fastest_lap: u8,
}

View File

@ -1,11 +1,13 @@
use super::{read_name, u8_to_bool};
use crate::constants::{Nationality, Platform, ReadyStatus};
use crate::constants::{Nationality, Platform, ReadyStatus, YourTelemetry};
use binrw::BinRead;
use serde::{Deserialize, Serialize};
#[non_exhaustive]
#[derive(BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize)]
#[derive(
BinRead, Eq, PartialEq, Ord, PartialOrd, Clone, Debug, Serialize, Deserialize,
)]
#[br(little, import(packet_format: u16))]
pub struct LobbyInfoData {
/// Whether the vehicle is controlled by AI.
@ -24,6 +26,18 @@ pub struct LobbyInfoData {
pub name: String,
/// Player's car number.
pub car_number: u8,
/// The player's "Your Telemetry" visibility setting.
/// Available from the 2024 format onwards.
#[br(if(packet_format >= 2024))]
pub your_telemetry: Option<YourTelemetry>,
/// Whether the player has enabled the "Show online names" setting.
/// Available from the 2024 format onwards.
#[br(if(packet_format >= 2024), try_map(u8_to_bool))]
pub show_online_names: bool,
/// F1 World tech level.
/// Available from the 2024 format onwards.
#[br(if(packet_format >= 2024))]
pub tech_level: u16,
/// Readiness status.
pub ready_status: ReadyStatus,
}

View File

@ -10,6 +10,7 @@ pub mod motion;
pub mod participants;
pub mod session;
pub mod session_history;
pub mod time_trial;
pub mod tyre_sets;
use crate::constants::{
@ -39,6 +40,7 @@ use crate::packets::session_history::{
LapHistoryData, TyreStintHistoryData, LAP_HISTORY_RAW_SIZE, MAX_NUM_LAPS,
MAX_NUM_TYRE_STINTS,
};
use crate::packets::time_trial::TimeTrialDataSet;
use crate::packets::tyre_sets::{TyreSetData, NUM_TYRE_SETS};
use binrw::BinRead;
@ -54,7 +56,7 @@ pub struct F1PacketMotion {
#[br(count(MAX_NUM_CARS), args{ inner: (packet_format,) })]
pub car_motion_data: Vec<CarMotionData>,
/// Extra player car only motion data.
/// Only in the 2022 format.
/// Available only in the 2022 format.
#[br(if(packet_format == 2022))]
pub motion_ex_data: Option<F1PacketMotionEx>,
}
@ -370,7 +372,7 @@ pub struct F1PacketLap {
/// Various notable events that happen during a session.
#[non_exhaustive]
#[derive(BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize)]
#[br(little, import(_packet_format: u16))]
#[br(little, import(packet_format: u16))]
pub struct F1PacketEvent {
/// 4-letter event code.
#[br(
@ -379,6 +381,7 @@ pub struct F1PacketEvent {
)]
pub event_string_code: String,
/// Extra data for this event.
#[br(args(packet_format))]
pub event_details: EventDataDetails,
}
@ -389,18 +392,18 @@ pub struct F1PacketEvent {
little,
import(packet_format: u16),
assert(
num_cars <= MAX_NUM_CARS,
num_active_cars <= MAX_NUM_CARS,
"Participants packet has an invalid number of cars: {}",
num_cars
num_active_cars
)
)]
pub struct F1PacketParticipants {
/// Number of active cars in the session.
#[br(map(u8_to_usize))]
pub num_cars: usize,
pub num_active_cars: usize,
/// Data for all participants.
/// Should have a size equal to `num_cars`.
#[br(count(num_cars), args{ inner: (packet_format,) })]
#[br(count(num_active_cars), args{ inner: (packet_format,) })]
pub participants_data: Vec<ParticipantsData>,
}
@ -414,6 +417,10 @@ pub struct F1PacketCarSetups {
/// Setup data for all cars on track.
#[br(count(MAX_NUM_CARS), args{ inner: (packet_format,) })]
pub car_setups_data: Vec<CarSetupData>,
/// Value of front wing after next pit stop - player only.
/// Available from the 2024 format onwards
#[br(if(packet_format >= 2024))]
pub next_front_wing_value: f32,
}
/// Telemetry (such as speed, DRS, throttle application, etc.)
@ -454,7 +461,7 @@ pub struct F1PacketCarStatus {
#[derive(BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize)]
#[br(little, import(packet_format: u16))]
pub struct F1PacketFinalClassification {
/// Number of cars in the final classification (no greater than 22).
/// Number of cars in the final classification.
#[br(
map(u8_to_usize),
assert(
@ -597,22 +604,44 @@ pub struct F1PacketMotionEx {
/// See [`wheel_index`](mod@crate::constants::wheel_index)
/// for wheel order.
pub suspension_position: [f32; 4],
/// Velocities of suspension.
/// Velocity values of suspension for each wheel.
/// See [`wheel_index`](mod@crate::constants::wheel_index)
/// for wheel order.
pub suspension_velocity: [f32; 4],
/// Accelerations of suspension in the following order:
/// Acceleration values of suspension for each wheel.
/// See [`wheel_index`](mod@crate::constants::wheel_index)
/// for wheel order.
pub suspension_acceleration: [f32; 4],
/// Speed of each wheel in the following order:
/// Speed of each wheel.
/// See [`wheel_index`](mod@crate::constants::wheel_index)
/// for wheel order.
pub wheel_speed: [f32; 4],
/// Slip ratio of each wheel in the following order:
/// Slip ratio for each wheel.
/// See [`wheel_index`](mod@crate::constants::wheel_index)
/// for wheel order.
pub wheel_slip: [f32; 4],
pub wheel_slip_ratio: [f32; 4],
/// Slip angles for each wheel.
/// See [`wheel_index`](mod@crate::constants::wheel_index)
/// for wheel order.
/// Available from the 2024 format onwards.
#[br(if(packet_format >= 2024))]
pub wheel_slip_angle: [f32; 4],
/// Lateral forces for each wheel.
/// See [`wheel_index`](mod@crate::constants::wheel_index)
/// for wheel order.
/// Available from the 2024 format onwards.
#[br(if(packet_format >= 2024))]
pub wheel_lat_force: [f32; 4],
/// Longitudinal forces for each wheel.
/// See [`wheel_index`](mod@crate::constants::wheel_index)
/// for wheel order.
/// Available from the 2024 format onwards.
#[br(if(packet_format >= 2024))]
pub wheel_long_force: [f32; 4],
/// Height of centre of gravity above ground.
/// Available from the 2024 format onwards.
#[br(if(packet_format >= 2024))]
pub height_of_cog_above_ground: f32,
/// X velocity in local space.
pub local_velocity_x: f32,
/// Y velocity in local space.
@ -639,6 +668,42 @@ pub struct F1PacketMotionEx {
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub wheel_vert_force: [f32; 4],
/// Front plank edge height above road surface.
/// Available from the 2024 format onwards.
#[br(if(packet_format >= 2024))]
pub front_aero_height: f32,
/// Rear plank edge height above road surface.
/// Available from the 2024 format onwards.
#[br(if(packet_format >= 2024))]
pub rear_aero_height: f32,
/// Roll angle of the front suspension.
/// Available from the 2024 format onwards.
#[br(if(packet_format >= 2024))]
pub front_roll_angle: f32,
/// Roll angle of the rear suspension.
/// Available from the 2024 format onwards.
#[br(if(packet_format >= 2024))]
pub rear_roll_angle: f32,
/// Yaw angle of the chassis relative to the direction of motion - radians.
/// Available from the 2024 format onwards.
#[br(if(packet_format >= 2024))]
pub chassis_yaw: f32,
}
/// Extra information that's only relevant to time trial game mode.
/// Available from the 2024 format onwards.
#[non_exhaustive]
#[derive(
BinRead, Eq, PartialEq, Ord, PartialOrd, Clone, Debug, Serialize, Deserialize,
)]
#[br(little, import(_packet_format: u16))]
pub struct F1PacketTimeTrial {
/// Data set of player's best run this session.
pub player_session_best_data_set: TimeTrialDataSet,
/// Data set of player's personal best run.
pub personal_best_data_set: TimeTrialDataSet,
/// Data set of rival's best run.
pub rival_data_set: TimeTrialDataSet,
}
#[derive(Debug, PartialEq)]

View File

@ -5,34 +5,40 @@ use binrw::BinRead;
use serde::{Deserialize, Serialize};
#[non_exhaustive]
#[derive(BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize)]
#[derive(
BinRead, Eq, PartialEq, Ord, PartialOrd, Clone, Debug, Serialize, Deserialize,
)]
#[br(little, import(packet_format: u16))]
pub struct ParticipantsData {
/// Whether the vehicle is controlled by AI
/// Whether the vehicle is controlled by AI.
#[br(try_map(u8_to_bool))]
pub ai_controlled: bool,
/// Driver's ID
/// Driver's ID.
pub driver_id: u8,
/// Unique ID for network players
/// Unique ID for network players.
pub network_id: u8,
/// Team's ID
/// Team's ID.
pub team_id: u8,
/// Whether my team is being used
/// Whether my team is being used.
#[br(try_map(u8_to_bool))]
pub my_team: bool,
/// Race number of the car
/// Race number of the car.
pub race_number: u8,
/// Driver's nationality
/// Driver's nationality.
pub nationality: Nationality,
/// Driver's name
/// Driver's name.
#[br(try_map(read_name))]
pub name: String,
/// Player's UDP visibility setting
/// Player's UDP visibility setting.
pub your_telemetry: Option<YourTelemetry>,
/// Whether this player's "show online names" setting is on.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023), try_map(u8_to_bool))]
pub show_online_names: bool,
/// F1 World tech level.
/// Available from the 2024 format onwards.
#[br(if(packet_format >= 2024))]
pub tech_level: u16,
/// Player's platform.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]

View File

@ -29,7 +29,9 @@ pub struct MarshalZone {
#[non_exhaustive]
/// Weather forecast sample for a given session.
#[derive(BinRead, PartialEq, PartialOrd, Copy, Clone, Debug, Serialize, Deserialize)]
#[derive(
BinRead, Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Debug, Serialize, Deserialize,
)]
#[br(
little,
import(_packet_format: u16),

View File

@ -7,29 +7,30 @@ use serde::{Deserialize, Serialize};
pub(super) const MAX_NUM_LAPS: usize = 100;
pub(super) const LAP_HISTORY_RAW_SIZE: usize = 14;
pub(super) const MAX_NUM_TYRE_STINTS: usize = 8;
pub(super) const TYRE_STINT_RAW_SIZE: usize = 3;
#[non_exhaustive]
#[derive(BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize)]
#[derive(
BinRead, Eq, PartialEq, Ord, PartialOrd, Copy, 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 1 whole minute part
/// Sector 1 time milliseconds part.
pub sector1_time_ms_part: u16,
/// Sector 1 whole minute part.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub sector1_time_minutes: u8,
/// Sector 2 time in milliseconds.
pub sector2_time_ms: u16,
/// Sector 2 whole minute part
pub sector1_time_minutes_part: u8,
/// Sector 2 time milliseconds part.
pub sector2_time_ms_part: u16,
/// Sector 2 whole minute part.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub sector2_time_minutes: u8,
/// Sector 3 time in milliseconds.
pub sector3_time_ms: u16,
/// Sector 3 whole minute part
pub sector2_time_minutes_part: u8,
/// Sector 3 time milliseconds part.
pub sector3_time_ms_part: u16,
/// Sector 3 whole minute part.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub sector3_time_minutes: u8,
@ -39,7 +40,9 @@ pub struct LapHistoryData {
}
#[non_exhaustive]
#[derive(BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize)]
#[derive(
BinRead, Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Debug, Serialize, Deserialize,
)]
#[br(little, import(_packet_format: u16))]
pub struct TyreStintHistoryData {
/// Lap the tyre usage ends on (255 if current tyre).

42
src/packets/time_trial.rs Normal file
View File

@ -0,0 +1,42 @@
use super::{u8_to_bool, u8_to_usize};
use crate::constants::{GearboxAssist, TractionControl};
use binrw::BinRead;
use serde::{Deserialize, Serialize};
#[non_exhaustive]
#[derive(
BinRead, Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Debug, Serialize, Deserialize,
)]
#[br(little, import(_packet_format: u16))]
pub struct TimeTrialDataSet {
/// Index of the car this data set relates to.
#[br(map(u8_to_usize))]
pub vehicle_index: usize,
/// Team's ID.
pub team_id: u8,
/// Lap time in milliseconds.
pub lap_time_ms: u32,
/// Sector 1 time in milliseconds.
pub sector1_time_ms: u32,
/// Sector 2 time in milliseconds.
pub sector2_time_ms: u32,
/// Sector 3 time in milliseconds.
pub sector3_time_ms: u32,
/// Type of traction control assist enabled.
pub traction_control: TractionControl,
/// Type of gearbox assist enabled.
pub gearbox_assist: GearboxAssist,
/// Whether ABS is enabled.
#[br(try_map(u8_to_bool))]
pub anti_lock_brakes: bool,
/// Whether equal car performance is enabled.
#[br(try_map(u8_to_bool))]
pub equal_car_performance: bool,
/// Whether custom setup is in use.
#[br(try_map(u8_to_bool))]
pub custom_setup: bool,
/// Whether this lap is valid.
#[br(try_map(u8_to_bool))]
pub valid: bool,
}