diff --git a/src/constants/mod.rs b/src/constants/mod.rs index 5f57286..c13024c 100644 --- a/src/constants/mod.rs +++ b/src/constants/mod.rs @@ -1147,3 +1147,23 @@ pub enum VisualTyreCompound { F2Hard = 22, F2Wet = 15, } + +#[non_exhaustive] +#[derive( + BinRead, + Eq, + PartialEq, + Ord, + PartialOrd, + Copy, + Clone, + Debug, + Serialize, + Deserialize, +)] +#[br(little, repr(u8))] +pub enum ReadyStatus { + NotReady = 0, + Ready = 1, + Spectating = 2, +} diff --git a/src/packets/lobby.rs b/src/packets/lobby.rs new file mode 100644 index 0000000..8f4da57 --- /dev/null +++ b/src/packets/lobby.rs @@ -0,0 +1,24 @@ +use super::{read_name, u8_to_bool}; +use crate::constants::{Nationality, ReadyStatus, TeamId}; +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 LobbyInfoData { + /// Whether the vehicle is controlled by AI. + #[br(map(u8_to_bool))] + pub ai_controlled: bool, + /// Team's ID. + pub team_id: TeamId, + /// Driver's nationality. + pub nationality: Nationality, + /// Driver's name. + #[br(try_map(read_name))] + pub name: String, + /// Readiness status. + pub ready_status: ReadyStatus, +} diff --git a/src/packets/mod.rs b/src/packets/mod.rs index 1817397..c5e0e43 100644 --- a/src/packets/mod.rs +++ b/src/packets/mod.rs @@ -7,6 +7,7 @@ pub mod lap; pub mod motion; pub mod participants; pub mod session; +mod lobby; use crate::constants::{ BrakingAssist, DynamicRacingLine, DynamicRacingLineType, ForecastAccuracy, @@ -17,12 +18,13 @@ use crate::packets::car_setups::CarSetupData; use crate::packets::car_status::CarStatusData; use crate::packets::car_telemetry::CarTelemetryData; use crate::packets::event::EventDataDetails; +use crate::packets::final_classification::FinalClassificationData; use crate::packets::lap::LapData; +use crate::packets::lobby::LobbyInfoData; use crate::packets::motion::CarMotionData; use crate::packets::participants::ParticipantsData; use crate::packets::session::{MarshalZone, WeatherForecastSample}; -use crate::packets::final_classification::FinalClassificationData; use binrw::BinRead; use serde::{Deserialize, Serialize}; use std::string::FromUtf8Error; @@ -167,7 +169,7 @@ pub struct F1PacketSession { pub game_mode: GameMode, /// Ruleset's identifier. pub ruleset: Ruleset, - /// Local time of day - minutes since midnight + /// Local time of day - minutes since midnight. pub time_of_day: u32, /// Session's length. pub session_length: SessionLength, @@ -312,6 +314,30 @@ pub struct F1PacketFinalClassification { pub final_classification_data: Vec, } +/// Packet detailing all the players that are currently in a multiplayer lobby. +#[derive( + BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize, +)] +#[br( + little, + import(packet_format: u16), + assert( + num_players <= MAX_NUM_CARS, + "Lobby packet has an invalid number of players: {}", + num_players + ) +)] +pub struct F1PacketLobbyInfoData { + /// Number of players in the lobby (no greater than 22). + #[br(map(u8_to_usize))] + pub num_players: usize, + /// Lobby info data for all players. + /// Should have a size equal to + /// [`num_players`](field@F1PacketLobbyInfoData::num_players). + #[br(count(num_players), args{ inner: (packet_format,) })] + pub lobby_info_data: Vec, +} + /// Extended motion data for player's car. Available as a: /// - part of [`F1PacketMotion`] in the 2022 format /// - standalone packet from the 2023 format onwards