feat: add 2023 spec parser fields and constants

This commit is contained in:
Maciej Pędzich 2025-02-20 10:22:06 +01:00
parent ef07718495
commit c4f08877aa
Signed by: maciejpedzich
GPG Key ID: CE4A303D84882F0D
13 changed files with 406 additions and 121 deletions

View File

@ -8,7 +8,8 @@ fn main() -> Result<(), Box<dyn Error>> {
loop {
let (msg_size, _) = socket.recv_from(&mut buf)?;
let raw_data = &buf[..msg_size];
let _parse_result = parse(raw_data)?;
let data = &buf[..msg_size];
parse(data)?;
}
}

View File

@ -96,7 +96,7 @@ pub const FELIPE_DRUGOVICH: u8 = 98;
pub const ROBERT_SCHWARTZMAN: u8 = 99;
pub const ROY_NISSANY: u8 = 100;
pub const MARINO_SATO: u8 = 101;
pub const AIDEN_JACKSON: u8 = 102;
pub const AIDAN_JACKSON: u8 = 102;
pub const CASPER_AKKERMAN: u8 = 103;
pub const JENSON_BUTTON: u8 = 109;
pub const DAVID_COULTHARD: u8 = 110;
@ -113,15 +113,33 @@ pub const BENT_VISCAAL: u8 = 122;
pub const ENZO_FITTIPALDI: u8 = 123;
pub const MARK_WEBBER: u8 = 125;
pub const JACQUES_VILLENEUVE: u8 = 126;
pub const JAKE_HUGHES: u8 = 127;
pub const FREDERIK_VESTI: u8 = 128;
pub const OLLI_CALDWELL: u8 = 129;
pub const LOGAN_SARGEANT: u8 = 130;
pub const CEM_BOLUKBASI: u8 = 131;
pub const AYUMU_IWASA: u8 = 132;
pub const CLEMENT_NOVALAK: u8 = 133;
pub const DENNIS_HAUGER: u8 = 134;
pub const CALAN_WILLIAMS: u8 = 135;
pub const JAKE_HUGHES_2022: u8 = 127;
pub const FREDERIK_VESTI_2022: u8 = 128;
pub const OLLI_CALDWELL_2022: u8 = 129;
pub const LOGAN_SARGEANT_2022: u8 = 130;
pub const CEM_BOLUKBASI_2022: u8 = 131;
pub const AYUMU_IWASA_2022: u8 = 132;
pub const CLEMENT_NOVALAK_2022: u8 = 133;
pub const DENNIS_HAUGER_2022: u8 = 134;
pub const CALAN_WILLIAMS_2022: u8 = 135;
pub const JACK_DOOHAN_2022: u8 = 136;
pub const AMAURY_CORDEEL_2022: u8 = 137;
pub const MIKA_HAKKINEN_2022: u8 = 138;
pub const CALLIE_MAYER: u8 = 127;
pub const NOAH_BELL: u8 = 128;
pub const JAKE_HUGHES: u8 = 129;
pub const FREDERIK_VESTI: u8 = 130;
pub const OLLI_CALDWELL: u8 = 131;
pub const LOGAN_SARGEANT: u8 = 132;
pub const CEM_BOLUKBASI: u8 = 133;
pub const AYUMU_IWASA: u8 = 134;
pub const CLEMENT_NOVALAK: u8 = 135;
pub const JACK_DOOHAN: u8 = 136;
pub const AMAURY_CORDEEL: u8 = 137;
pub const MIKA_HAKKINEN: u8 = 138;
pub const DENNIS_HAUGER: u8 = 138;
pub const CALAN_WILLIAMS: u8 = 139;
pub const JAMIE_CHADWICK: u8 = 140;
pub const KAMUI_KOBAYASHI: u8 = 141;
pub const PASTOR_MALDONADO: u8 = 142;
pub const MIKA_HAKKINEN: u8 = 143;
pub const NIGEL_MANSELL: u8 = 144;

View File

@ -1,4 +1,5 @@
pub mod driver_id;
pub mod team_id;
pub mod wheel_index;
use binrw::BinRead;
@ -210,6 +211,8 @@ pub enum Formula {
Supercars = 5,
Esports = 6,
F22021 = 7,
F1World = 8,
F1Elimination = 9,
}
#[non_exhaustive]
@ -350,6 +353,7 @@ pub enum DynamicRacingLineType {
pub enum GameMode {
EventMode = 0,
GrandPrix = 3,
GrandPrix2023 = 4,
TimeTrial = 5,
Splitscreen = 6,
OnlineCustom = 7,
@ -359,8 +363,11 @@ pub enum GameMode {
Championship = 13,
OnlineChampionship = 14,
OnlineWeeklyEvent = 15,
BrakingPoint2023 = 17,
Career2022 = 19,
Career2022Online = 20,
Career2023 = 21,
Career2023Online = 22,
Benchmark = 127,
}
@ -583,6 +590,7 @@ pub enum InfringementType {
RetryPenalty = 49,
IllegalTimeGain = 50,
MandatoryPitStop = 51,
AttributeAssigned = 54,
}
#[derive(
@ -678,85 +686,6 @@ bitflags! {
}
}
#[non_exhaustive]
#[derive(
BinRead,
Eq,
PartialEq,
Ord,
PartialOrd,
Copy,
Clone,
Debug,
Serialize,
Deserialize,
)]
#[br(little, repr(u8))]
pub enum TeamId {
Mercedes = 0,
Ferrari = 1,
RedBull = 2,
Williams = 3,
AstonMartin = 4,
Alpine = 5,
/// Aliases: [`TeamId::AlphaTauri`]
Vcarb = 6,
Haas = 7,
McLaren = 8,
/// Aliases: [`TeamId::AlfaRomeo`]
Sauber = 9,
Mercedes2020 = 85,
Ferrari2020 = 86,
RedBull2020 = 87,
Williams2020 = 88,
RacingPoint2020 = 89,
Renault2020 = 90,
AlphaTauri2020 = 91,
Haas2020 = 92,
McLaren2020 = 93,
AlfaRomeo2020 = 94,
AstonMartinDb11V12 = 95,
AstonMartinVantage = 96,
AstonMartinSafetyCar = 97,
FerrariF8Tributo = 98,
FerrariRoma = 99,
McLaren720S = 100,
McLarenArtura = 101,
MercedesSafetyCar = 102,
MercedesAmgGtrPro = 103,
F1CustomTeam = 104,
Prema2021 = 106,
UniVirtuosi2021 = 107,
Carlin2021 = 108,
Hitech2021 = 109,
ArtGrandPrix2021 = 110,
MpMotorsport2021 = 111,
Charouz2021 = 112,
Dams2021 = 113,
Campos2021 = 114,
Bwt2021 = 115,
Trident2021 = 116,
MercedesAmgGtBlackSeries = 117,
Prema2022 = 118,
UniVirtuosi2022 = 119,
Carlin2022 = 120,
Hitech2022 = 121,
ArtGrandPrix2022 = 122,
MpMotorsport2022 = 123,
Charouz2022 = 124,
Dams2022 = 125,
Campos2022 = 126,
VanAmersfort2022 = 127,
Trident2022 = 128,
MyTeam = 255,
}
#[allow(non_upper_case_globals)]
impl TeamId {
pub const AlphaTauri: TeamId = TeamId::Vcarb;
pub const AlfaRomeo: TeamId = TeamId::Sauber;
}
#[non_exhaustive]
#[derive(
BinRead,
@ -1108,6 +1037,7 @@ pub enum ActualTyreCompound {
F1C3 = 18,
F1C2 = 19,
F1C1 = 20,
F1C0 = 21,
F1Inter = 7,
F1Wet = 8,
ClassicDry = 9,
@ -1185,13 +1115,74 @@ 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;
/// Whether the whole lap is valid. Has a value of `0x01`.
const OVERALL = 0x01;
/// Whether the sector 1 run is valid. Has a value of `0x02`.
const SECTOR_1 = 0x02;
/// Whether the sector 2 run is valid. Has a value of `0x04`.
const SECTOR_2 = 0x04;
/// Whether the sector 3 run is valid. Has a value of `0x08`.
const SECTOR_3 = 0x08;
}
}
#[non_exhaustive]
#[derive(
BinRead,
Eq,
PartialEq,
Ord,
PartialOrd,
Copy,
Clone,
Debug,
Serialize,
Deserialize,
)]
#[br(little, repr(u8))]
pub enum SpeedUnit {
MilesPerHour = 0,
KilometresPerHour = 1,
}
#[non_exhaustive]
#[derive(
BinRead,
Eq,
PartialEq,
Ord,
PartialOrd,
Copy,
Clone,
Debug,
Serialize,
Deserialize,
)]
#[br(little, repr(u8))]
pub enum TemperatureUnit {
Celsius = 0,
Fahrenheit = 1,
}
#[non_exhaustive]
#[derive(
BinRead,
Eq,
PartialEq,
Ord,
PartialOrd,
Copy,
Clone,
Debug,
Serialize,
Deserialize,
)]
#[br(little, repr(u8))]
pub enum Platform {
Invalid = 0,
Steam = 1,
PlayStation = 3,
Xbox = 4,
Origin = 6,
Unknown = 255,
}

79
src/constants/team_id.rs Normal file
View File

@ -0,0 +1,79 @@
pub const MERCEDES: u8 = 0;
pub const FERRARI: u8 = 1;
pub const RED_BULL: u8 = 2;
pub const WILLIAMS: u8 = 3;
pub const ASTON_MARTIN: u8 = 4;
pub const ALPINE: u8 = 5;
pub const ALPHA_TAURI: u8 = 6;
pub const VCARB: u8 = 6;
pub const HAAS: u8 = 7;
pub const MCLAREN: u8 = 8;
pub const ALFA_ROMEO: u8 = 9;
pub const SAUBER: u8 = 9;
pub const MERCEDES_2020: u8 = 85;
pub const FERRARI_2020: u8 = 86;
pub const RED_BULL_2020: u8 = 87;
pub const WILLIAMS_2020: u8 = 88;
pub const RACING_POINT_2020: u8 = 89;
pub const RENAULT_2020: u8 = 90;
pub const ALPHA_TAURI_2020: u8 = 91;
pub const HAAS_2020: u8 = 92;
pub const MCLAREN_2020: u8 = 93;
pub const ALFA_ROMEO_2020: u8 = 94;
pub const ASTON_MARTIN_DB11_V12: u8 = 95;
pub const ASTON_MARTIN_VANTAGE: u8 = 96;
pub const ASTON_MARTIN_SAFETY_CAR: u8 = 97;
pub const FERRARI_F8_TRIBUTO: u8 = 98;
pub const FERRARI_ROMA: u8 = 99;
pub const MCLAREN_720S: u8 = 100;
pub const MCLAREN_ARTURA: u8 = 101;
pub const MERCEDES_SAFETY_CAR: u8 = 102;
pub const MERCEDES_AMG_GTR_PRO: u8 = 103;
pub const F1_CUSTOM_TEAM: u8 = 104;
pub const PREMA_2021: u8 = 106;
pub const UNI_VIRTUOSI_2021: u8 = 107;
pub const CARLIN_2021: u8 = 108;
pub const HITECH_2021: u8 = 109;
pub const ART_GP_2021: u8 = 110;
pub const MP_MOTORSPORT_2021: u8 = 111;
pub const CHAROUZ_2021: u8 = 112;
pub const DAMS_2021: u8 = 113;
pub const CAMPOS_2021: u8 = 114;
pub const BWT_2021: u8 = 115;
pub const TRIDENT_2021: u8 = 116;
pub const MERCEDES_AMG_GT_BLACK_SERIES: u8 = 117;
pub const F1_22_PREMA_2022: u8 = 118;
pub const F1_22_VIRTUOSI_2022: u8 = 119;
pub const F1_22_CARLIN_2022: u8 = 120;
pub const F1_22_HITECH_2022: u8 = 121;
pub const F1_22_ART_GP_2022: u8 = 122;
pub const F1_22_MP_MOTORSPORT_2022: u8 = 123;
pub const F1_22_CHAROUZ_2022: u8 = 124;
pub const F1_22_DAMS_2022: u8 = 125;
pub const F1_22_CAMPOS_2022: u8 = 126;
pub const F1_22_VAN_AMERSFORT_2022: u8 = 127;
pub const F1_22_TRIDENT_2022: u8 = 128;
pub const MERCEDES_2022: u8 = 118;
pub const FERRARI_2022: u8 = 119;
pub const RED_BULL_2022: u8 = 120;
pub const WILLIAMS_2022: u8 = 121;
pub const ASTON_MARTIN_2022: u8 = 122;
pub const ALPINE_2022: u8 = 123;
pub const ALPHA_TAURI_2022: u8 = 124;
pub const HAAS_2022: u8 = 125;
pub const MCLAREN_2022: u8 = 126;
pub const ALFA_ROMEO_2022: u8 = 127;
pub const KONNERSPORT_2022: u8 = 128;
pub const KONNERSPORT: u8 = 129;
pub const F1_23_PREMA_2022: u8 = 130;
pub const F1_23_VIRTUOSI_2022: u8 = 131;
pub const F1_23_CARLIN_2022: u8 = 132;
pub const F1_23_MP_MOTORSPORT_2022: u8 = 133;
pub const F1_23_CHAROUZ_2022: u8 = 134;
pub const F1_23_DAMS_2022: u8 = 135;
pub const F1_23_CAMPOS_2022: u8 = 136;
pub const F1_23_VAN_AMERSFORT_2022: u8 = 137;
pub const F1_23_TRIDENT_2022: u8 = 138;
pub const F1_23_HITECH_2022: u8 = 139;
pub const F1_23_ART_GP_2022: u8 = 140;
pub const MY_TEAM: u8 = 255;

View File

@ -3,10 +3,11 @@ pub mod packets;
use crate::constants::PacketId;
use crate::packets::{
F1PacketCarDamage, F1PacketCarSetups, F1PacketCarStatus,
u8_to_usize, F1PacketCarDamage, F1PacketCarSetups, F1PacketCarStatus,
F1PacketCarTelemetry, F1PacketEvent, F1PacketFinalClassification,
F1PacketLap, F1PacketLobbyInfo, F1PacketMotion, F1PacketParticipants,
F1PacketSession, F1PacketSessionHistory,
F1PacketLap, F1PacketLobbyInfo, F1PacketMotion, F1PacketMotionEx,
F1PacketParticipants, F1PacketSession, F1PacketSessionHistory,
F1PacketTyreSets,
};
use binrw::io::Cursor;
@ -46,6 +47,10 @@ pub struct F1Packet {
pub struct F1PacketHeader {
/// Value of the "UDP Format" option in the game's telemetry settings.
pub packet_format: u16,
/// Game year (last two digits)
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub game_year: u8,
/// Game's major version - "X.00".
pub game_major_version: u8,
/// Game's minor version - "1.XX".
@ -60,11 +65,18 @@ pub struct F1PacketHeader {
pub session_time: f32,
/// Identifier for the frame the data was retrieved on.
pub frame_identifier: u32,
/// Overall identifier for the frame the data was retrieved on
/// (doesn't go back after flashbacks).
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub overall_frame_identifier: u32,
/// Index of player's car in the array.
pub player_car_index: u8,
#[br(map(u8_to_usize))]
pub player_car_index: usize,
/// Index of secondary player's car in the array in splitscreen mode.
/// Set to 255 if not in splitscreen mode.
pub secondary_player_car_index: u8,
#[br(map(u8_to_usize))]
pub secondary_player_car_index: usize,
}
/// F1 game packet's body.
@ -110,4 +122,12 @@ pub struct F1PacketBody {
/// Session history data for a specific car.
#[br(if(packet_id == PacketId::SessionHistory), args(packet_format))]
pub session_history: Option<F1PacketSessionHistory>,
/// In-depth details about tyre sets assigned to a vehicle during the session.
/// Available from the 2023 format onwards.
#[br(if(packet_id == PacketId::TyreSets), args(packet_format))]
pub tyre_sets: Option<F1PacketTyreSets>,
/// Extended player car only motion data.
/// Available from the 2023 format onwards.
#[br(if(packet_id == PacketId::MotionEx), args(packet_format))]
pub motion_ex: Option<F1PacketMotionEx>,
}

View File

@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};
)]
#[br(
little,
import(_packet_format: u16),
import(packet_format: u16),
assert(
max_gears <= 9,
"Car status entry has an invalid max number of gears: {}",
@ -56,6 +56,14 @@ pub struct CarStatusData {
pub tyres_age_laps: u8,
/// Flag the driver is currently being shown.
pub vehicle_fia_flag: VehicleFiaFlag,
/// Engine power output of ICE in watts.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub engine_power_ice: f32,
/// Engine power output of MGU-K in watts.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub engine_power_mguk: f32,
/// ERS energy store in Joules.
pub ers_store_energy: f32,
/// ERS deployment mode.

View File

@ -133,4 +133,15 @@ pub enum EventDataDetails {
#[br(map(ButtonStatus::from_bits_truncate))]
button_status: ButtonStatus,
},
/// Sent when a car has overtaken another.
/// Available from the 2023 format onwards.
#[br(magic = b"OVTK")]
Overtake {
/// Index of the overtaking vehicle.
#[br(map(u8_to_usize))]
overtaking_vehicle_index: usize,
/// Index of the overtaken vehicle.
#[br(map(u8_to_usize))]
overtaken_vehicle_index: usize,
},
}

View File

@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize};
)]
#[br(
little,
import(_packet_format: u16),
import(packet_format: u16),
assert(
sector <= 2,
"Lap data entry has an invalid sector number: {}",
@ -25,8 +25,24 @@ pub struct LapData {
pub current_lap_time_ms: u32,
/// Current sector 1 time in milliseconds.
pub sector1_time_ms: 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,
/// Sector 2 whole minute part.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub sector2_time_minutes: 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,
/// 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,
/// 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,
@ -52,7 +68,17 @@ 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.
#[br(if(packet_format >= 2023))]
pub corner_cutting_warnings: u8,
/// Number of unserved drive through penalties left to serve.
pub num_unserved_drive_through_pens: u8,
/// Number of unserved stop-go penalties left to serve.

View File

@ -1,5 +1,6 @@
use super::{read_name, u8_to_bool};
use crate::constants::{Nationality, ReadyStatus, TeamId};
use crate::constants::{Nationality, Platform, ReadyStatus};
use binrw::BinRead;
use serde::{Deserialize, Serialize};
@ -7,19 +8,23 @@ use serde::{Deserialize, Serialize};
#[derive(
BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize,
)]
#[br(little, import(_packet_format: u16))]
#[br(little, import(packet_format: u16))]
pub struct LobbyInfoData {
/// Whether the vehicle is controlled by AI.
#[br(map(u8_to_bool))]
pub ai_controlled: bool,
/// Team's ID.
pub team_id: TeamId,
pub team_id: u8,
/// Driver's nationality.
pub nationality: Nationality,
/// Player's platform.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub platform: Option<Platform>,
/// Driver's name.
#[br(try_map(read_name))]
pub name: String,
/// Player's car number
/// Player's car number.
pub car_number: u8,
/// Readiness status.
pub ready_status: ReadyStatus,

View File

@ -10,11 +10,13 @@ pub mod motion;
pub mod participants;
pub mod session;
pub mod session_history;
pub mod tyre_sets;
use crate::constants::{
BrakingAssist, DynamicRacingLine, DynamicRacingLineType, ForecastAccuracy,
Formula, GameMode, GearboxAssist, MfdPanelIndex, Ruleset, SafetyCarStatus,
SessionLength, SessionType, TrackId, Weather, MAX_NUM_CARS,
SessionLength, SessionType, SpeedUnit, TemperatureUnit, TrackId, Weather,
MAX_NUM_CARS,
};
use crate::packets::car_damage::CarDamageData;
use crate::packets::car_setups::CarSetupData;
@ -28,6 +30,7 @@ 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::tyre_sets::TyreSetData;
use binrw::BinRead;
use serde::{Deserialize, Serialize};
@ -43,7 +46,8 @@ pub struct F1PacketMotion {
/// Motion data for all cars on track.
#[br(count(MAX_NUM_CARS), args{ inner: (packet_format,) })]
pub car_motion_data: Vec<CarMotionData>,
/// Extra player car only motion data (2022 format only).
/// Extra player car only motion data.
/// Only in the 2022 format.
#[br(if(packet_format == 2022))]
pub motion_ex_data: Option<F1PacketMotionEx>,
}
@ -177,6 +181,34 @@ pub struct F1PacketSession {
pub time_of_day: u32,
/// Session's length.
pub session_length: SessionLength,
/// Speed unit used by player 1.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub speed_unit_lead_player: Option<SpeedUnit>,
/// Temperature unit used by player 1.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub temperature_unit_lead_player: Option<TemperatureUnit>,
/// Speed unit used by player 2.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub speed_unit_secondary_player: Option<SpeedUnit>,
/// Temperature unit used by player 2.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub temperature_unit_secondary_player: Option<TemperatureUnit>,
/// Number of full safety cars called during the session.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub num_safety_car_periods: u8,
/// Number of virtual safety cars called during the session.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub num_virtual_safety_car_periods: u8,
/// Number of red flags called during the session.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub num_red_flag_periods: u8,
}
/// Data about all the lap times of cars in the session.
@ -409,6 +441,25 @@ pub struct F1PacketSessionHistory {
pub tyre_stint_history_data: Vec<TyreStintHistoryData>,
}
/// In-depth details about tyre sets assigned to a vehicle during the session.
/// Available from the 2023 format onwards.
#[non_exhaustive]
#[derive(
BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize,
)]
#[br(little, import(packet_format: u16))]
pub struct F1PacketTyreSets {
/// Index of the car this packet relates to.
#[br(map(u8_to_usize))]
pub vehicle_index: usize,
/// 13 dry + 7 wet tyre sets.
#[br(count(20), args{ inner: (packet_format,) })]
pub tyre_set_data: Vec<TyreSetData>,
/// Index of fitted tyre set.
#[br(map(u8_to_usize))]
pub fitted_index: usize,
}
/// Extended motion data for player's car. Available as a:
/// - part of [`F1PacketMotion`] in the 2022 format
/// - standalone packet from the 2023 format onwards
@ -416,7 +467,7 @@ pub struct F1PacketSessionHistory {
#[derive(
BinRead, PartialEq, PartialOrd, Copy, Clone, Debug, Serialize, Deserialize,
)]
#[br(little, import(_packet_format: u16))]
#[br(little, import(packet_format: u16))]
pub struct F1PacketMotionEx {
/// Positions of suspension for each wheel.
/// See [`wheel_index`](mod@crate::constants::wheel_index)
@ -458,6 +509,12 @@ pub struct F1PacketMotionEx {
pub angular_acceleration_z: f32,
/// Current front wheels angle in radians.
pub front_wheels_angle: f32,
/// Vertical forces for each wheel.
/// See [`wheel_index`](mod@crate::constants::wheel_index)
/// for wheel order.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub wheel_vert_force: [f32; 4],
}
pub(crate) fn u8_to_bool(value: u8) -> bool {

View File

@ -1,5 +1,5 @@
use super::{read_name, u8_to_bool};
use crate::constants::{Nationality, TeamId, YourTelemetry};
use crate::constants::{Nationality, Platform, YourTelemetry};
use binrw::BinRead;
use serde::{Deserialize, Serialize};
@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
#[derive(
BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize,
)]
#[br(little, import(_packet_format: u16))]
#[br(little, import(packet_format: u16))]
pub struct ParticipantsData {
/// Whether the vehicle is controlled by AI
#[br(map(u8_to_bool))]
@ -18,7 +18,7 @@ pub struct ParticipantsData {
/// Unique ID for network players
pub network_id: u8,
/// Team's ID
pub team_id: TeamId,
pub team_id: u8,
/// Whether my team is being used
#[br(map(u8_to_bool))]
pub my_team: bool,
@ -31,4 +31,12 @@ pub struct ParticipantsData {
pub name: String,
/// 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), map(u8_to_bool))]
pub show_online_names: bool,
/// Player's platform.
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub platform: Option<Platform>,
}

View File

@ -7,16 +7,28 @@ use serde::{Deserialize, Serialize};
#[derive(
BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize,
)]
#[br(little, import(_packet_format: u16))]
#[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
/// 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
/// 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
/// Available from the 2023 format onwards.
#[br(if(packet_format >= 2023))]
pub sector3_time_minutes: u8,
/// Bitmap of lap validity across all sectors and overall.
#[br(map(LapValid::from_bits_truncate))]
pub lap_valid_bit_flags: LapValid,
@ -27,11 +39,11 @@ pub struct LapHistoryData {
)]
#[br(little, import(_packet_format: u16))]
pub struct TyreStintHistoryData {
/// Lap the tyre usage ends on (255 if current tyre)
/// Lap the tyre usage ends on (255 if current tyre).
#[br(map(u8_to_usize))]
pub end_lap: usize,
/// Actual tyre compound used
/// Actual tyre compound used.
pub actual_tyre_compound: ActualTyreCompound,
/// Visual tyre compound used
/// Visual tyre compound used.
pub visual_tyre_compound: VisualTyreCompound,
}

49
src/packets/tyre_sets.rs Normal file
View File

@ -0,0 +1,49 @@
use super::u8_to_bool;
use crate::constants::{ActualTyreCompound, SessionType, VisualTyreCompound};
use binrw::BinRead;
use serde::{Deserialize, Serialize};
#[derive(
BinRead,
Eq,
PartialEq,
Ord,
PartialOrd,
Copy,
Clone,
Debug,
Serialize,
Deserialize,
)]
#[br(
little,
import(_packet_format: u16),
assert(
wear <= 100,
"Tyre set entry has an invalid wear percentage: {}",
wear
)
)]
pub struct TyreSetData {
/// Actual tyre compound.
pub actual_tyre_compound: ActualTyreCompound,
/// Visual tyre compound.
pub visual_tyre_compound: VisualTyreCompound,
/// Tyre wear (percentage).
pub wear: u8,
/// Whether this set is currently available.
#[br(map(u8_to_bool))]
pub available: bool,
/// Recommended session for this tyre set.
pub recommended_session: SessionType,
/// Laps left in this set.
pub life_span: u8,
/// Max number of laps recommended for this compound.
pub usable_life: u8,
/// Lap time delta in milliseconds compared to fitted set.
pub lap_delta_time: i16,
/// Whether this set is fitted or not.
#[br(map(u8_to_bool))]
pub fitted: bool,
}