mirror of
https://github.com/maciejpedzich/f1-game-packet-parser.git
synced 2025-04-16 01:51:12 +02:00
feat: add 2022 spec car telemetry packet parser
This commit is contained in:
parent
06b8bfe133
commit
8ea06e5a53
127
src/constants/driver_id.rs
Normal file
127
src/constants/driver_id.rs
Normal file
@ -0,0 +1,127 @@
|
||||
pub const CARLOS_SAINZ: u8 = 0;
|
||||
pub const DANILL_KVYAT: u8 = 1;
|
||||
pub const DANIEL_RICCIARDO: u8 = 2;
|
||||
pub const FERNANDO_ALONSO: u8 = 3;
|
||||
pub const FELIPE_MASSA: u8 = 4;
|
||||
pub const KIMI_RAIKKONEN: u8 = 6;
|
||||
pub const LEWIS_HAMILTON: u8 = 7;
|
||||
pub const MARCUS_ERICSSON: u8 = 8;
|
||||
pub const MAX_VERSTAPPEN: u8 = 9;
|
||||
pub const NICO_HULKENBERG: u8 = 10;
|
||||
pub const KEVIN_MAGNUSSEN: u8 = 11;
|
||||
pub const ROMAIN_GROSJEAN: u8 = 12;
|
||||
pub const SEBASTIAN_VETTEL: u8 = 13;
|
||||
pub const SERGIO_PEREZ: u8 = 14;
|
||||
pub const VALTTERI_BOTTAS: u8 = 15;
|
||||
pub const ESTEBAN_OCON: u8 = 17;
|
||||
pub const STOFFEL_VANDOORNE: u8 = 18;
|
||||
pub const LANCE_STROLL: u8 = 19;
|
||||
pub const ARRON_BARNES: u8 = 20;
|
||||
pub const MARTIN_GILES: u8 = 21;
|
||||
pub const ALEX_MURRAY: u8 = 22;
|
||||
pub const LUCAS_ROTH: u8 = 23;
|
||||
pub const IGOR_CORREIA: u8 = 24;
|
||||
pub const SOPHIE_LEVASSEUR: u8 = 25;
|
||||
pub const JONAS_SCHIFFER: u8 = 26;
|
||||
pub const ALAIN_FORREST: u8 = 27;
|
||||
pub const JAY_LETOURNEAU: u8 = 28;
|
||||
pub const ESTO_SAARI: u8 = 29;
|
||||
pub const YASAR_ATIEH: u8 = 30;
|
||||
pub const CALLISTO_CALABRESI: u8 = 31;
|
||||
pub const NAOTA_IZUMI: u8 = 32;
|
||||
pub const HOWARD_CLARKE: u8 = 33;
|
||||
pub const WILHELM_KAUFMANN: u8 = 34;
|
||||
pub const MARIE_LAURSEN: u8 = 35;
|
||||
pub const FLAVIO_NIEVES: u8 = 36;
|
||||
pub const PETER_BELOUSOV: u8 = 37;
|
||||
pub const KLIMEK_MICHALSKI: u8 = 38;
|
||||
pub const SANTIAGO_MORENO: u8 = 39;
|
||||
pub const BENJAMIN_COPPENS: u8 = 40;
|
||||
pub const NOAH_VISSER: u8 = 41;
|
||||
pub const GERT_WALDMULLER: u8 = 42;
|
||||
pub const JULIAN_QUESADA: u8 = 43;
|
||||
pub const DANIEL_JONES: u8 = 44;
|
||||
pub const ARTEM_MARKELOV: u8 = 45;
|
||||
pub const TADASUKE_MAKINO: u8 = 46;
|
||||
pub const SEAN_GELAEL: u8 = 47;
|
||||
pub const NYCK_DE_VRIES: u8 = 48;
|
||||
pub const JACK_AITKEN: u8 = 49;
|
||||
pub const GEORGE_RUSSELL: u8 = 50;
|
||||
pub const MAXIMILIAN_GUNTHER: u8 = 51;
|
||||
pub const NIREI_FUKUZUMI: u8 = 52;
|
||||
pub const LUCA_GHIOTTO: u8 = 53;
|
||||
pub const LANDO_NORRIS: u8 = 54;
|
||||
pub const SERGIO_SETTE_CAMARA: u8 = 55;
|
||||
pub const LOUIS_DELETRAZ: u8 = 56;
|
||||
pub const ANTONIO_FUOCCO: u8 = 57;
|
||||
pub const CHARLES_LECLERC: u8 = 58;
|
||||
pub const PIERRE_GASLY: u8 = 59;
|
||||
pub const BRENDON_HARTLEY: u8 = 60;
|
||||
pub const SERGEY_SIROTKIN: u8 = 61;
|
||||
pub const ALEXANDER_ALBON: u8 = 62;
|
||||
pub const NICHOLAS_LATIFI: u8 = 63;
|
||||
pub const DORIAN_BOCCOLACCI: u8 = 64;
|
||||
pub const NIKO_KARI: u8 = 65;
|
||||
pub const ROBERTO_MEHRI: u8 = 66;
|
||||
pub const ARJUN_MAINI: u8 = 67;
|
||||
pub const ALESSIO_LORANDI: u8 = 68;
|
||||
pub const RUBEN_MEIJER: u8 = 69;
|
||||
pub const RASHID_NAIR: u8 = 70;
|
||||
pub const JACK_TREMBLAY: u8 = 71;
|
||||
pub const ANTONIO_GIOVINAZZI: u8 = 74;
|
||||
pub const ROBERT_KUBICA: u8 = 75;
|
||||
pub const ALAIN_PROST: u8 = 76;
|
||||
pub const AYRTON_SENNA: u8 = 77;
|
||||
pub const NOBUHARU_MATSUSHITA: u8 = 78;
|
||||
pub const NIKITA_MAZEPIN: u8 = 79;
|
||||
pub const GUANYU_ZHOU: u8 = 80;
|
||||
pub const MICK_SCHUMACHER: u8 = 81;
|
||||
pub const CALLUM_ILOTT: u8 = 82;
|
||||
pub const JUAN_MANUEL_CORREA: u8 = 83;
|
||||
pub const JORDAN_KING: u8 = 84;
|
||||
pub const MAHAVEER_RAGUNATHAN: u8 = 85;
|
||||
pub const TATIANA_CALDERON: u8 = 86;
|
||||
pub const ANTHOINE_HUBERT: u8 = 87;
|
||||
pub const GUILIANO_ALESI: u8 = 88;
|
||||
pub const RALPH_BOSCHUNG: u8 = 89;
|
||||
pub const MICHAEL_SCHUMACHER: u8 = 90;
|
||||
pub const DAN_TICKTUM: u8 = 91;
|
||||
pub const MARCUS_ARMSTRONG: u8 = 92;
|
||||
pub const CHRISTIAN_LUNDGAARD: u8 = 93;
|
||||
pub const YUKI_TSUNODA: u8 = 94;
|
||||
pub const JEHAN_DARUVALA: u8 = 95;
|
||||
pub const GULHERME_SAMAIA: u8 = 96;
|
||||
pub const PEDRO_PIQUET: u8 = 97;
|
||||
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 CASPER_AKKERMAN: u8 = 103;
|
||||
pub const JENSON_BUTTON: u8 = 109;
|
||||
pub const DAVID_COULTHARD: u8 = 110;
|
||||
pub const NICO_ROSBERG: u8 = 111;
|
||||
pub const OSCAR_PIASTRI: u8 = 112;
|
||||
pub const LIAM_LAWSON: u8 = 113;
|
||||
pub const JURI_VIPS: u8 = 114;
|
||||
pub const THEO_POURCHAIRE: u8 = 115;
|
||||
pub const RICHARD_VERSCHOOR: u8 = 116;
|
||||
pub const LIRIM_ZENDELI: u8 = 117;
|
||||
pub const DAVID_BECKMANN: u8 = 118;
|
||||
pub const ALESSIO_DELEDDA: u8 = 121;
|
||||
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 JACK_DOOHAN: u8 = 136;
|
||||
pub const AMAURY_CORDEEL: u8 = 137;
|
||||
pub const MIKA_HAKKINEN: u8 = 138;
|
@ -1,4 +1,5 @@
|
||||
pub mod wheel_index;
|
||||
pub mod driver_id;
|
||||
|
||||
use binrw::BinRead;
|
||||
use bitflags::bitflags;
|
||||
@ -881,3 +882,104 @@ pub enum YourTelemetry {
|
||||
Restricted = 0,
|
||||
Public = 1,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(
|
||||
BinRead,
|
||||
Eq,
|
||||
PartialEq,
|
||||
Ord,
|
||||
PartialOrd,
|
||||
Copy,
|
||||
Clone,
|
||||
Debug,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
)]
|
||||
#[br(little, repr(u8))]
|
||||
pub enum Surface {
|
||||
Tarmac = 0,
|
||||
RumbleStrip = 1,
|
||||
Concrete = 2,
|
||||
Rock = 3,
|
||||
Gravel = 4,
|
||||
Mud = 5,
|
||||
Sand = 6,
|
||||
Grass = 7,
|
||||
Water = 8,
|
||||
Cobblestone = 9,
|
||||
Metal = 10,
|
||||
Ridged = 11,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
Ord,
|
||||
PartialOrd,
|
||||
Hash,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
)]
|
||||
pub struct RevLights(u16);
|
||||
|
||||
bitflags! {
|
||||
impl RevLights: u16 {
|
||||
/// 1st left (1st leftmost) LED. Has a value of `0x0001`.
|
||||
const LEFT_1 = 0x0001;
|
||||
/// 2nd left (2nd leftmost) LED. Has a value of `0x0002`.
|
||||
const LEFT_2 = 0x0002;
|
||||
/// 3rd left (3rd leftmost) LED. Has a value of `0x0004`.
|
||||
const LEFT_3 = 0x0004;
|
||||
/// 4th left (4th leftmost) LED. Has a value of `0x0008`.
|
||||
const LEFT_4 = 0x0008;
|
||||
/// 5th left (5th leftmost) LED. Has a value of `0x0010`.
|
||||
const LEFT_5 = 0x0010;
|
||||
/// 1st middle (6th leftmost) LED. Has a value of `0x0020`.
|
||||
const MIDDLE_1 = 0x0020;
|
||||
/// 2nd middle (7th leftmost) LED. Has a value of `0x0040`.
|
||||
const MIDDLE_2 = 0x0040;
|
||||
/// 3rd middle (8th leftmost) LED. Has a value of `0x0080`.
|
||||
const MIDDLE_3 = 0x0080;
|
||||
/// 4th middle (9th leftmost) LED . Has a value of `0x0100`.
|
||||
const MIDDLE_4 = 0x0100;
|
||||
/// 5th middle (10th leftmost) LED . Has a value of `0x0200`.
|
||||
const MIDDLE_5 = 0x0200;
|
||||
/// 1st right (11th leftmost) LED. Has a value of `0x0400`.
|
||||
const RIGHT_1 = 0x0400;
|
||||
/// 2nd right (12th leftmost) LED. Has a value of `0x0800`.
|
||||
const RIGHT_2 = 0x0800;
|
||||
/// 3rd right (13th leftmost) LED. Has a value of `0x1000`.
|
||||
const RIGHT_3 = 0x1000;
|
||||
/// 4th right (14th leftmost) LED. Has a value of `0x2000`.
|
||||
const RIGHT_4 = 0x2000;
|
||||
/// 5th right (15th leftmost) LED. Has a value of `0x4000`.
|
||||
const RIGHT_5 = 0x4000;
|
||||
}
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(
|
||||
BinRead,
|
||||
Eq,
|
||||
PartialEq,
|
||||
Ord,
|
||||
PartialOrd,
|
||||
Copy,
|
||||
Clone,
|
||||
Debug,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
)]
|
||||
#[br(little, repr(u8))]
|
||||
pub enum MfdPanelIndex {
|
||||
CarSetup = 0,
|
||||
Pits = 1,
|
||||
Damage = 2,
|
||||
Engine = 3,
|
||||
Temperatures = 4,
|
||||
Closed = 255,
|
||||
}
|
||||
|
@ -2,7 +2,11 @@ pub mod constants;
|
||||
pub mod packets;
|
||||
|
||||
use crate::constants::PacketId;
|
||||
use crate::packets::{F1PacketCarSetupsData, F1PacketEventData, F1PacketLapData, F1PacketMotionData, F1PacketParticipantsData, F1PacketSessionData};
|
||||
use crate::packets::{
|
||||
F1PacketCarSetupsData, F1PacketCarTelemetryData, F1PacketEventData,
|
||||
F1PacketLapData, F1PacketMotionData, F1PacketParticipantsData,
|
||||
F1PacketSessionData,
|
||||
};
|
||||
|
||||
use binrw::io::Cursor;
|
||||
use binrw::{BinRead, BinReaderExt, BinResult};
|
||||
@ -87,4 +91,6 @@ pub struct F1PacketBody {
|
||||
/// Car setups for each vehicle in the session.
|
||||
#[br(if(packet_id == PacketId::CarSetups), args(packet_format))]
|
||||
pub car_setups: Option<F1PacketCarSetupsData>,
|
||||
#[br(if(packet_id == PacketId::CarTelemetry), args(packet_format))]
|
||||
pub car_telemetry: Option<F1PacketCarTelemetryData>,
|
||||
}
|
||||
|
90
src/packets/car_telemetry.rs
Normal file
90
src/packets/car_telemetry.rs
Normal file
@ -0,0 +1,90 @@
|
||||
use super::u8_to_bool;
|
||||
use crate::constants::{RevLights, Surface};
|
||||
|
||||
use binrw::BinRead;
|
||||
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(
|
||||
(0..=100).contains(&clutch),
|
||||
"Car telemetry entry has an invalid clutch value: {}",
|
||||
clutch
|
||||
),
|
||||
assert(
|
||||
(-1..=8).contains(&gear),
|
||||
"Car telemetry entry has an invalid gear value: {}",
|
||||
gear
|
||||
),
|
||||
assert(
|
||||
(0..=100).contains(&rev_lights_percent),
|
||||
"Car telemetry entry has an invalid rev lights percentage: {}",
|
||||
rev_lights_percent
|
||||
),
|
||||
)]
|
||||
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)`.
|
||||
pub throttle: f32,
|
||||
/// Steering lock. Value in range `(-1.0..=1.0)`.
|
||||
pub steer: f32,
|
||||
/// Amount of brake applied. Value in range `(0.0..=1.0)`.
|
||||
pub brake: f32,
|
||||
/// Amount of clutch applied. Value in range `(0..=100)`.
|
||||
pub clutch: u8,
|
||||
/// Selected gear. Neutral = 0, reverse = -1.
|
||||
pub gear: i8,
|
||||
/// Engine RPM.
|
||||
pub engine_rpm: u16,
|
||||
/// Whether DRS is enabled.
|
||||
#[br(map(u8_to_bool))]
|
||||
pub drs_enabled: bool,
|
||||
/// Rev lights indicator (percentage).
|
||||
pub rev_lights_percent: u8,
|
||||
/// Bitmap of active rev lights.
|
||||
#[br(map(|bits: u16| RevLights::from_bits_truncate(bits)))]
|
||||
pub rev_lights_bit_value: RevLights,
|
||||
/// Brake temperatures in degrees Celsius.
|
||||
/// See [`wheel_index`](mod@crate::constants::wheel_index)
|
||||
/// for wheel order.
|
||||
pub brakes_temperature: [u16; 4],
|
||||
/// Tyres' surface temperature in degrees Celsius.
|
||||
/// See [`wheel_index`](mod@crate::constants::wheel_index)
|
||||
/// for wheel order.
|
||||
pub tyres_surface_temperature: [u8; 4],
|
||||
/// Tyres' inner temperature in degrees Celsius.
|
||||
/// See [`wheel_index`](mod@crate::constants::wheel_index)
|
||||
/// for wheel order.
|
||||
pub tyres_inner_temperature: [u8; 4],
|
||||
/// Engine's temperature in degrees Celsius
|
||||
pub engine_temperature: u16,
|
||||
/// Tyres' pressue temperature in degrees Celsius.
|
||||
/// See [`wheel_index`](mod@crate::constants::wheel_index)
|
||||
/// for wheel order.
|
||||
pub tyres_pressure: [f32; 4],
|
||||
/// Driving surface of each tyre.
|
||||
/// See [`wheel_index`](mod@crate::constants::wheel_index)
|
||||
/// for wheel order.
|
||||
pub surface_type: Option<[Surface; 4]>,
|
||||
}
|
@ -1,15 +1,16 @@
|
||||
pub mod car_setups;
|
||||
pub mod car_telemetry;
|
||||
pub mod event;
|
||||
pub mod lap_data;
|
||||
pub mod motion;
|
||||
pub mod participants;
|
||||
pub mod session;
|
||||
mod car_setups;
|
||||
|
||||
use crate::constants::{
|
||||
BrakingAssist, DynamicRacingLine, DynamicRacingLineType, ForecastAccuracy,
|
||||
Formula, GameMode, GearboxAssist, Ruleset, SafetyCarStatus, SessionLength,
|
||||
SessionType, TrackId, Weather, MAX_AI_DIFFICULTY, MAX_NUM_CARS,
|
||||
MAX_NUM_MARSHAL_ZONES, MAX_NUM_WEATHER_FORECAST_SAMPLES,
|
||||
Formula, GameMode, GearboxAssist, MfdPanelIndex, Ruleset, SafetyCarStatus,
|
||||
SessionLength, SessionType, TrackId, Weather, MAX_AI_DIFFICULTY,
|
||||
MAX_NUM_CARS, MAX_NUM_MARSHAL_ZONES, MAX_NUM_WEATHER_FORECAST_SAMPLES,
|
||||
};
|
||||
use crate::packets::event::EventDataDetails;
|
||||
use crate::packets::lap_data::LapData;
|
||||
@ -18,6 +19,7 @@ use crate::packets::participants::ParticipantsData;
|
||||
use crate::packets::session::{MarshalZone, WeatherForecastSample};
|
||||
|
||||
use crate::packets::car_setups::CarSetupData;
|
||||
use crate::packets::car_telemetry::CarTelemetryData;
|
||||
use binrw::BinRead;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::string::FromUtf8Error;
|
||||
@ -228,9 +230,10 @@ pub struct F1PacketParticipantsData {
|
||||
pub participants: Vec<ParticipantsData>,
|
||||
}
|
||||
|
||||
/// Packet detailing car setups for cars in the race.
|
||||
/// Car setups for all cars in the race.
|
||||
/// In multiplayer games, other player cars will appear as blank.
|
||||
/// You will only be able to see your car setup and AI cars.
|
||||
#[non_exhaustive]
|
||||
#[derive(
|
||||
BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize,
|
||||
)]
|
||||
@ -242,6 +245,36 @@ pub struct F1PacketCarSetupsData {
|
||||
pub car_setups: Vec<CarSetupData>,
|
||||
}
|
||||
|
||||
/// Telemetry (such as speed, DRS, throttle application, etc.)
|
||||
/// for all cars in the race.
|
||||
#[derive(
|
||||
BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize,
|
||||
)]
|
||||
#[br(
|
||||
little,
|
||||
import(packet_format: u16),
|
||||
assert(
|
||||
(-1..=8).contains(&suggested_gear),
|
||||
"Car telemetry entry has an invalid suggested gear value: {}",
|
||||
suggested_gear
|
||||
),
|
||||
)]
|
||||
pub struct F1PacketCarTelemetryData {
|
||||
/// Telemetry data for all cars on track.
|
||||
/// Should have a size of 22
|
||||
#[br(
|
||||
count(MAX_NUM_CARS),
|
||||
args{ inner: (packet_format,) }
|
||||
)]
|
||||
pub car_telemetry_data: Vec<CarTelemetryData>,
|
||||
/// Index of currently open MFD panel.
|
||||
pub mfd_panel_index: MfdPanelIndex,
|
||||
/// See [`mfd_panel_index`](field@F1PacketCarTelemetryData::mfd_panel_index)
|
||||
pub mfd_panel_index_secondary_player: MfdPanelIndex,
|
||||
/// Suggested gear (0 if no gear suggested).
|
||||
pub suggested_gear: i8,
|
||||
}
|
||||
|
||||
/// Extended motion data for player's car. Available as a:
|
||||
/// - part of [`F1PacketMotionData`] in the 2022 format
|
||||
/// - standalone packet from the 2023 format onwards
|
||||
|
Loading…
x
Reference in New Issue
Block a user