mirror of
https://github.com/maciejpedzich/f1-game-packet-parser.git
synced 2025-04-16 01:51:12 +02:00
feat: add 2023 spec parser fields and constants
This commit is contained in:
parent
ef07718495
commit
c4f08877aa
@ -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)?;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
79
src/constants/team_id.rs
Normal 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;
|
30
src/lib.rs
30
src/lib.rs
@ -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>,
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
},
|
||||
}
|
||||
|
@ -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 hasn’t 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.
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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>,
|
||||
}
|
||||
|
@ -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
49
src/packets/tyre_sets.rs
Normal 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,
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user