mirror of
https://github.com/maciejpedzich/f1-game-packet-parser.git
synced 2025-04-16 18:11:11 +02:00
feat: add 2022 spec session history packet parser
This commit is contained in:
parent
d880590e8b
commit
ac7130fae1
@ -1167,3 +1167,30 @@ pub enum ReadyStatus {
|
|||||||
Ready = 1,
|
Ready = 1,
|
||||||
Spectating = 2,
|
Spectating = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
Debug,
|
||||||
|
Clone,
|
||||||
|
Copy,
|
||||||
|
PartialEq,
|
||||||
|
Eq,
|
||||||
|
Ord,
|
||||||
|
PartialOrd,
|
||||||
|
Hash,
|
||||||
|
Serialize,
|
||||||
|
Deserialize,
|
||||||
|
)]
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,7 +6,7 @@ use crate::packets::{
|
|||||||
F1PacketCarDamage, F1PacketCarSetups, F1PacketCarStatus,
|
F1PacketCarDamage, F1PacketCarSetups, F1PacketCarStatus,
|
||||||
F1PacketCarTelemetry, F1PacketEvent, F1PacketFinalClassification,
|
F1PacketCarTelemetry, F1PacketEvent, F1PacketFinalClassification,
|
||||||
F1PacketLap, F1PacketLobbyInfo, F1PacketMotion, F1PacketParticipants,
|
F1PacketLap, F1PacketLobbyInfo, F1PacketMotion, F1PacketParticipants,
|
||||||
F1PacketSession,
|
F1PacketSession, F1PacketSessionHistory,
|
||||||
};
|
};
|
||||||
|
|
||||||
use binrw::io::Cursor;
|
use binrw::io::Cursor;
|
||||||
@ -107,4 +107,7 @@ pub struct F1PacketBody {
|
|||||||
/// Car damage parameters for all cars in the session.
|
/// Car damage parameters for all cars in the session.
|
||||||
#[br(if(packet_id == PacketId::CarDamage), args(packet_format))]
|
#[br(if(packet_id == PacketId::CarDamage), args(packet_format))]
|
||||||
pub car_damage: Option<F1PacketCarDamage>,
|
pub car_damage: Option<F1PacketCarDamage>,
|
||||||
|
/// Session history data for a specific car.
|
||||||
|
#[br(if(packet_id == PacketId::SessionHistory), args(packet_format))]
|
||||||
|
pub session_history: Option<F1PacketSessionHistory>,
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,22 @@
|
|||||||
mod car_damage;
|
pub mod car_damage;
|
||||||
pub mod car_setups;
|
pub mod car_setups;
|
||||||
pub mod car_status;
|
pub mod car_status;
|
||||||
pub mod car_telemetry;
|
pub mod car_telemetry;
|
||||||
pub mod event;
|
pub mod event;
|
||||||
pub mod final_classification;
|
pub mod final_classification;
|
||||||
pub mod lap;
|
pub mod lap;
|
||||||
mod lobby;
|
pub mod lobby;
|
||||||
pub mod motion;
|
pub mod motion;
|
||||||
pub mod participants;
|
pub mod participants;
|
||||||
pub mod session;
|
pub mod session;
|
||||||
|
pub mod session_history;
|
||||||
|
|
||||||
use crate::constants::{
|
use crate::constants::{
|
||||||
BrakingAssist, DynamicRacingLine, DynamicRacingLineType, ForecastAccuracy,
|
BrakingAssist, DynamicRacingLine, DynamicRacingLineType, ForecastAccuracy,
|
||||||
Formula, GameMode, GearboxAssist, MfdPanelIndex, Ruleset, SafetyCarStatus,
|
Formula, GameMode, GearboxAssist, MfdPanelIndex, Ruleset, SafetyCarStatus,
|
||||||
SessionLength, SessionType, TrackId, Weather, MAX_NUM_CARS,
|
SessionLength, SessionType, TrackId, Weather, MAX_NUM_CARS,
|
||||||
};
|
};
|
||||||
|
use crate::packets::car_damage::CarDamageData;
|
||||||
use crate::packets::car_setups::CarSetupData;
|
use crate::packets::car_setups::CarSetupData;
|
||||||
use crate::packets::car_status::CarStatusData;
|
use crate::packets::car_status::CarStatusData;
|
||||||
use crate::packets::car_telemetry::CarTelemetryData;
|
use crate::packets::car_telemetry::CarTelemetryData;
|
||||||
@ -25,8 +27,8 @@ use crate::packets::lobby::LobbyInfoData;
|
|||||||
use crate::packets::motion::CarMotionData;
|
use crate::packets::motion::CarMotionData;
|
||||||
use crate::packets::participants::ParticipantsData;
|
use crate::packets::participants::ParticipantsData;
|
||||||
use crate::packets::session::{MarshalZone, WeatherForecastSample};
|
use crate::packets::session::{MarshalZone, WeatherForecastSample};
|
||||||
|
use crate::packets::session_history::{LapHistoryData, TyreStintHistoryData};
|
||||||
|
|
||||||
use crate::packets::car_damage::CarDamageData;
|
|
||||||
use binrw::BinRead;
|
use binrw::BinRead;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::string::FromUtf8Error;
|
use std::string::FromUtf8Error;
|
||||||
@ -353,6 +355,60 @@ pub struct F1PacketCarDamage {
|
|||||||
pub car_damage_data: Vec<CarDamageData>,
|
pub car_damage_data: Vec<CarDamageData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Packet detailing lap and tyre data history for a given driver in the session
|
||||||
|
#[non_exhaustive]
|
||||||
|
#[derive(
|
||||||
|
BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize,
|
||||||
|
)]
|
||||||
|
#[br(
|
||||||
|
little,
|
||||||
|
import(packet_format: u16),
|
||||||
|
assert(
|
||||||
|
vehicle_index < MAX_NUM_CARS,
|
||||||
|
"Session history packet has an invalid vehicle index: {}",
|
||||||
|
vehicle_index
|
||||||
|
),
|
||||||
|
assert(
|
||||||
|
num_laps <= 100,
|
||||||
|
"Session history packet has an invalid number of laps: {}",
|
||||||
|
num_laps
|
||||||
|
),
|
||||||
|
assert(
|
||||||
|
num_tyre_stints <= 8,
|
||||||
|
"Session history packet has an invalid number of tyre stints: {}",
|
||||||
|
num_tyre_stints
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub struct F1PacketSessionHistory {
|
||||||
|
/// Index of the car this packet refers to
|
||||||
|
#[br(map(u8_to_usize))]
|
||||||
|
pub vehicle_index: usize,
|
||||||
|
/// Number of laps in the data (including the current one)
|
||||||
|
#[br(map(u8_to_usize))]
|
||||||
|
pub num_laps: usize,
|
||||||
|
/// Number of tyre stints in the data (including the current one)
|
||||||
|
#[br(map(u8_to_usize))]
|
||||||
|
pub num_tyre_stints: usize,
|
||||||
|
/// Number of the lap the best lap time was achieved on
|
||||||
|
#[br(map(u8_to_usize))]
|
||||||
|
pub best_lap_time_lap_num: usize,
|
||||||
|
/// Number of the lap the best sector 1 time was achieved on
|
||||||
|
#[br(map(u8_to_usize))]
|
||||||
|
pub best_sector1_lap_num: usize,
|
||||||
|
/// Number of the lap the best sector 2 time was achieved on
|
||||||
|
#[br(map(u8_to_usize))]
|
||||||
|
pub best_sector2_lap_num: usize,
|
||||||
|
/// Number of the lap the best sector 3 time was achieved on
|
||||||
|
#[br(map(u8_to_usize))]
|
||||||
|
pub best_sector3_lap_num: usize,
|
||||||
|
/// Up to 100 laps
|
||||||
|
#[br(count(100), args{ inner: (packet_format,) })]
|
||||||
|
pub lap_history_data: Vec<LapHistoryData>,
|
||||||
|
/// Up to 8 tyre stints
|
||||||
|
#[br(count(8), args{ inner: (packet_format,) })]
|
||||||
|
pub tyre_stint_history_data: Vec<TyreStintHistoryData>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Extended motion data for player's car. Available as a:
|
/// Extended motion data for player's car. Available as a:
|
||||||
/// - part of [`F1PacketMotion`] in the 2022 format
|
/// - part of [`F1PacketMotion`] in the 2022 format
|
||||||
/// - standalone packet from the 2023 format onwards
|
/// - standalone packet from the 2023 format onwards
|
||||||
|
37
src/packets/session_history.rs
Normal file
37
src/packets/session_history.rs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
use super::u8_to_usize;
|
||||||
|
use crate::constants::{ActualTyreCompound, LapValid, VisualTyreCompound};
|
||||||
|
|
||||||
|
use binrw::BinRead;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize,
|
||||||
|
)]
|
||||||
|
#[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 2 time in milliseconds.
|
||||||
|
pub sector2_time_ms: u16,
|
||||||
|
/// Sector 3 time in milliseconds.
|
||||||
|
pub sector3_time_ms: u16,
|
||||||
|
/// Bitmap of lap validity across all sectors and overall.
|
||||||
|
#[br(map(LapValid::from_bits_truncate))]
|
||||||
|
pub lap_valid_bit_flags: LapValid,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
BinRead, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize,
|
||||||
|
)]
|
||||||
|
#[br(little, import(_packet_format: u16))]
|
||||||
|
pub struct TyreStintHistoryData {
|
||||||
|
/// Lap the tyre usage ends on (255 if current tyre)
|
||||||
|
#[br(map(u8_to_usize))]
|
||||||
|
pub end_lap: usize,
|
||||||
|
/// Actual tyre compound used
|
||||||
|
pub actual_tyre_compound: ActualTyreCompound,
|
||||||
|
/// Visual tyre compound used
|
||||||
|
pub visual_tyre_compound: VisualTyreCompound,
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user