1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
//! Codec for modern F1 games use crate::nineteen::decode_nineteen; use crate::packet::Packet; use bytes::{Buf, BytesMut}; use std::io::{Cursor, Error, ErrorKind}; use tokio_util::codec::Decoder; /// Codec to decode UDP packets published by modern F1 games. /// /// This struct implements the `Decoder` trait for tokio-utils. It can be used to decode incoming /// UDP packets, and convert them into internal data representations. The F1 codec can decode the /// packets of all F1 games that are supported by this library. pub struct F1Codec; impl Decoder for F1Codec { type Item = Packet; type Error = Error; /// Decode a UDP packet and return its data. /// /// The `decode` method is called whenever a new data frame is received on a UDP socket, and the /// data frame is passed as an argument. This method has to make a few decisions then: /// /// 1. Does the data form a complete packet so that it can be decoded? /// 2. Is the packet a valid packet sent by an F1 game? /// 3. Can the packet be parsed? /// /// To answer these questions, the following process is used. First, the packet header is read /// to determine the game that sent the packet. With the game and the packet type from the /// header, the expected size of the packet can be determined by calling `buffer_size` from the /// `FromBytes` trait. If the packet is too small, `Ok(None)` is returned to signal that more /// data needs to be retrieved from the UDP socket. /// /// If the packet is complete, it is decoded using the `from_bytes` method in the `FromBytes` /// trait. If the packet can be decoded successfully, it is returned. Otherwise, the error from /// the decoding is returned, signaling that the UDP stream is corrupted and should be shut /// down. fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Error> { let mut cursor = Cursor::new(src); // Not enough data yet to decode the packet format. if cursor.remaining() < 2 { return Ok(None); } let packet_format = cursor.get_u16_le(); let packet = match packet_format { 2019 => decode_nineteen(&mut cursor), format => Err(Error::new( ErrorKind::InvalidData, format!("Unknown packet format {}.", format), )), }; match packet { Ok(packet) => Ok(Some(packet)), Err(error) => match error.kind() { ErrorKind::UnexpectedEof => Ok(None), _ => Err(error), }, } } }