f1_game_packet_parser/packets/
session.rs

1use crate::constants::{MarshalZoneFlag, TemperatureChange, Weather};
2use binrw::BinRead;
3use serde::{Deserialize, Serialize};
4
5pub(super) const MAX_NUM_MARSHAL_ZONES: usize = 21;
6pub(super) const MARSHAL_ZONE_RAW_SIZE: usize = 5;
7pub(super) const FORECAST_SAMPLE_RAW_SIZE: usize = 8;
8pub(super) const MAX_AI_DIFFICULTY: u8 = 110;
9pub(super) const MAX_NUM_SESSIONS: usize = 12;
10
11/// Section of the track supervised by marshals.
12#[non_exhaustive]
13#[derive(BinRead, PartialEq, PartialOrd, Copy, Clone, Debug, Serialize, Deserialize)]
14#[br(
15    little,
16    import(_packet_format: u16),
17    assert(
18        (0.0..1.0).contains(&zone_start),
19        "Marshal zone has an invalid zone start value: {}",
20        zone_start
21    )
22)]
23pub struct MarshalZone {
24    /// Fraction (in range `(0.0..1.0)`) of way through the lap the marshal zone starts.
25    pub zone_start: f32,
26    /// Flag that's currently being waved in the marshal zone.
27    pub zone_flag: MarshalZoneFlag,
28}
29
30#[non_exhaustive]
31/// Weather forecast sample for a given session.
32#[derive(
33    BinRead, Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Debug, Serialize, Deserialize,
34)]
35#[br(
36    little,
37    import(_packet_format: u16),
38    assert(
39        rain_percentage <= 100,
40        "Weather forecast sample has an invalid rain percentage value: {}",
41        rain_percentage
42    )
43)]
44pub struct WeatherForecastSample {
45    /// Session's type.
46    /// See [`session_type`](mod@crate::constants::session_type)
47    /// for possible values.
48    pub session_type: u8,
49    /// Time in minutes the forecast is for.
50    pub time_offset: u8,
51    /// Forecasted weather.
52    pub weather: Weather,
53    /// Track temperature in degrees Celsius.
54    pub track_temperature: i8,
55    /// Track temperature change.
56    pub track_temperature_change: TemperatureChange,
57    /// Air temperature in degrees Celsius.
58    pub air_temperature: i8,
59    /// Air temperature change.
60    pub air_temperature_change: TemperatureChange,
61    /// Chance of rain.
62    pub rain_percentage: u8,
63}
64
65pub(super) fn check_num_forecast_samples(packet_format: u16, num_samples: usize) -> bool {
66    num_samples <= get_max_num_samples(packet_format)
67}
68
69pub(super) fn get_forecast_samples_padding(
70    packet_format: u16,
71    num_samples: usize,
72) -> usize {
73    (get_max_num_samples(packet_format) - num_samples) * FORECAST_SAMPLE_RAW_SIZE
74}
75
76fn get_max_num_samples(packet_format: u16) -> usize {
77    if packet_format >= 2024 {
78        64
79    } else {
80        56
81    }
82}