feat: add 2022 spec participants packet parser

This commit is contained in:
Maciej Pędzich 2025-02-18 11:17:11 +01:00
parent 70c51b5276
commit e92aed3159
Signed by: maciejpedzich
GPG Key ID: CE4A303D84882F0D
5 changed files with 275 additions and 10 deletions

View File

@ -678,3 +678,206 @@ bitflags! {
const UDP_ACTION_12 = 0x80000000;
}
}
#[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,
Eq,
PartialEq,
Ord,
PartialOrd,
Copy,
Clone,
Debug,
Serialize,
Deserialize,
)]
#[br(little, repr(u8))]
pub enum Nationality {
Unknown = 0,
American = 1,
Argentinian = 2,
Australian = 3,
Austrian = 4,
Azerbaijani = 5,
Bahraini = 6,
Belgian = 7,
Bolivian = 8,
Brazilian = 9,
British = 10,
Bulgarian = 11,
Cameroonian = 12,
Canadian = 13,
Chilean = 14,
Chinese = 15,
Colombian = 16,
CostaRican = 17,
Croatian = 18,
Cypriot = 19,
Czech = 20,
Danish = 21,
Dutch = 22,
Ecuadorian = 23,
English = 24,
Emirian = 25,
Estonian = 26,
Finnish = 27,
French = 28,
German = 29,
Ghanaian = 30,
Greek = 31,
Guatemalan = 32,
Honduran = 33,
HongKonger = 34,
Hungarian = 35,
Icelander = 36,
Indian = 37,
Indonesian = 38,
Irish = 39,
Israeli = 40,
Italian = 41,
Jamaican = 42,
Japanese = 43,
Jordanian = 44,
Kuwaiti = 45,
Latvian = 46,
Lebanese = 47,
Lithuanian = 48,
Luxembourger = 49,
Malaysian = 50,
Maltese = 51,
Mexican = 52,
Monegasque = 53,
NewZealander = 54,
Nicaraguan = 55,
NorthernIrish = 56,
Norwegian = 57,
Omani = 58,
Pakistani = 59,
Panamanian = 60,
Paraguayan = 61,
Peruvian = 62,
Polish = 63,
Portuguese = 64,
Qatari = 65,
Romanian = 66,
Russian = 67,
Salvadoran = 68,
Saudi = 69,
Scottish = 70,
Serbian = 71,
Singaporean = 72,
Slovakian = 73,
Slovenian = 74,
SouthKorean = 75,
SouthAfrican = 76,
Spanish = 77,
Swedish = 78,
Swiss = 79,
Thai = 80,
Turkish = 81,
Uruguayan = 82,
Ukrainian = 83,
Venezuelan = 84,
Welsh = 85,
Barbadian = 86,
Vietnamese = 87,
}
#[non_exhaustive]
#[derive(
BinRead,
Eq,
PartialEq,
Ord,
PartialOrd,
Copy,
Clone,
Debug,
Serialize,
Deserialize,
)]
#[br(little, repr(u8))]
pub enum YourTelemetry {
Restricted = 0,
Public = 1,
}

View File

@ -2,7 +2,7 @@ pub mod constants;
pub mod packets;
use crate::constants::PacketId;
use crate::packets::{F1PacketEventData, F1PacketLapData, F1PacketMotionData, F1PacketSessionData};
use crate::packets::{F1PacketEventData, F1PacketLapData, F1PacketMotionData, F1PacketParticipantsData, F1PacketSessionData};
use binrw::io::Cursor;
use binrw::{BinRead, BinReaderExt, BinResult};
@ -81,4 +81,7 @@ pub struct F1PacketBody {
/// Details of events that happen during the course of a session.
#[br(if(packet_id == PacketId::Event), args(packet_format))]
pub event: Option<F1PacketEventData>,
/// List of participants in the race.
#[br(if(packet_id == PacketId::Participants), args(packet_format))]
pub participants: Option<F1PacketParticipantsData>,
}

View File

@ -131,6 +131,6 @@ pub enum EventDataDetails {
Buttons {
/// Bit flags specifying which buttons are currently pressed.
#[br(map(|bits: u32| ButtonStatus::from_bits_truncate(bits)))]
button_status: ButtonStatus
button_status: ButtonStatus,
},
}

View File

@ -1,18 +1,19 @@
pub mod motion;
pub mod session;
pub mod lap_data;
pub mod event;
pub mod lap_data;
pub mod motion;
pub mod participants;
pub mod session;
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,
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,
};
use crate::packets::event::EventDataDetails;
use crate::packets::lap_data::LapData;
use crate::packets::motion::CarMotionData;
use crate::packets::participants::ParticipantsData;
use crate::packets::session::{MarshalZone, WeatherForecastSample};
use binrw::BinRead;
@ -251,6 +252,30 @@ pub struct F1PacketMotionExData {
pub front_wheels_angle: f32,
}
/// Data of participants in the session, mostly relevant for multiplayer.
#[derive(
BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize,
)]
#[br(
little,
import(packet_format: u16),
assert(
num_active_cars <= MAX_NUM_CARS,
"Participants packet has an invalid number of active cars: {}",
num_active_cars
)
)]
pub struct F1PacketParticipantsData {
/// Number of active cars in the data (no greater than 22)
#[br(map(u8_to_usize))]
pub num_active_cars: usize,
/// Data for all participants.
/// Should have a size equal to
/// [`num_active_cars`](field@F1PacketParticipantsData::num_active_cars)
#[br(count(num_active_cars), args{ inner: (packet_format,) })]
pub participants: Vec<ParticipantsData>,
}
pub(crate) fn u8_to_bool(value: u8) -> bool {
value == 1
}

View File

@ -0,0 +1,34 @@
use super::{read_name, u8_to_bool};
use crate::constants::{Nationality, TeamId, YourTelemetry};
use binrw::BinRead;
use serde::{Deserialize, Serialize};
#[non_exhaustive]
#[derive(
BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize,
)]
#[br(little, import(_packet_format: u16))]
pub struct ParticipantsData {
/// Whether the vehicle is controlled by AI
#[br(map(u8_to_bool))]
pub ai_controlled: bool,
/// Driver's ID
pub driver_id: u8,
/// Unique ID for network players
pub network_id: u8,
/// Team's ID
pub team_id: TeamId,
/// Whether my team is being used
#[br(map(u8_to_bool))]
pub my_team: bool,
/// Race number of the car
pub race_number: u8,
/// Driver's nationality
pub nationality: Nationality,
/// Driver's name
#[br(try_map(read_name))]
pub name: String,
/// Player's UDP visibility setting
pub your_telemetry: Option<YourTelemetry>,
}