rak_rs/protocol/
reliability.rs

1//! Reliability types for packets.
2//! Each packet sent on the RakNet protocol has a reliability type, which determines how the packet should be handled.
3//!
4//! ## Unreliable
5//! Unreliable packets are sent without any guarantee that they will be received by the other peer.
6//! In other words, the packet is sent and forgotten about, with no expectation of a response.
7//! This is the fastest reliability type, as it does not require any acks to be sent
8//! back to the sender. Generally used for packets that are not important, such as
9//! [`UnconnectedPing`] and [`UnconnectedPong`].
10//!
11//! ## Sequenced
12//! Sequenced packets are sent with a sequence index in each frame (datagram) that is sent.
13//! This is a number that is incremented after each packet. This allows us to implement a sliding window
14//! ([`ReliableWindow`]), which
15//! will discard any packets that are way too old or way too new.
16//!
17//! ## Ordered
18//! Ordered packets are sent with an order index in each frame, as well as an order channel.
19//! RakNet will use this information to order the packets in a specific way.
20//!
21//! The `order_channel` is used to determine which channel the packet should be sent on, in other words,
22//! this is a unique channel chosen by the sender to send the packet on, and the receiver will use this
23//! channel to re-order the packets in the correct order when they are sent.
24//!
25//! The `order_index` is used to determine the position of the packet in the order channel, this is
26//! incremented after each packet is sent, similar to the sequence index, without the sliding window.
27//!
28//! ## Reliable
29//! Reliable packets are sent with an ack system, meaning that the receiver will send an ack back to the
30//! sender, which the sender expects to recieve.
31//!
32//! If the sender does not receive the ack, it will resend the packet until it receives the ack, or until
33//! the connection is closed.
34//!
35//! [`UnconnectedPing`]: crate::protocol::packet::offline::UnconnectedPing
36//! [`UnconnectedPong`]: crate::protocol::packet::offline::UnconnectedPong
37//! [`ReliableWindow`]: crate::connection::controller::window::ReliableWindow
38//!
39/// The [RakNet Reliabilty] of a packet.
40///
41/// This is a bit flag encoded within each [`Frame`] that determines how the packet should be handled.
42/// As of writing the following reliability types are supported:
43/// - [`Unreliable`]
44/// - [`UnreliableSeq`]
45/// - [`Reliable`]
46/// - [`ReliableOrd`]
47/// - [`ReliableSeq`]
48///
49/// [RakNet Reliabilty]: https://github.com/facebookarchive/RakNet/blob/1a169895a900c9fc4841c556e16514182b75faf8/Source/PacketPriority.h#L46-L85
50/// [`Frame`]: crate::protocol::frame::Frame
51/// [`Unreliable`]: crate::protocol::reliability::Reliability::Unreliable
52/// [`UnreliableSeq`]: crate::protocol::reliability::Reliability::UnreliableSeq
53/// [`Reliable`]: crate::protocol::reliability::Reliability::Reliable
54/// [`ReliableOrd`]: crate::protocol::reliability::Reliability::ReliableOrd
55/// [`ReliableSeq`]: crate::protocol::reliability::Reliability::ReliableSeq
56#[derive(Clone, Debug, Copy)]
57#[repr(u8)]
58pub enum Reliability {
59    /// Unreliable (with no ack)
60    Unreliable = 0,
61    /// Unreliable with a sequence
62    UnreliableSeq,
63    /// Reliable
64    Reliable,
65    ReliableOrd,
66    /// Reliably sequenced **AND** ordered
67    ReliableSeq,
68    /// never used over the wire
69    UnreliableAck,
70    /// never used over the wire
71    ReliableAck,
72    /// never used over the wire
73    ReliableOrdAck,
74}
75
76impl Reliability {
77    /// Creates a new [`Reliability`] from the given flags.
78    /// This is used internally to decode the reliability from the given
79    /// bit flags.
80    ///
81    /// [`Reliability`]: crate::protocol::reliability::Reliability
82    pub fn from_flags(flags: u8) -> Self {
83        match (flags & 224) >> 5 {
84            0 => Reliability::Unreliable,
85            1 => Reliability::UnreliableSeq,
86            2 => Reliability::Reliable,
87            3 => Reliability::ReliableOrd,
88            4 => Reliability::ReliableSeq,
89            5 => Reliability::UnreliableAck,
90            6 => Reliability::ReliableAck,
91            7 => Reliability::ReliableOrdAck,
92            // we shouldn't error, but we'll just return unreliable
93            _ => Reliability::Unreliable,
94        }
95    }
96
97    /// Converts the [`Reliability`] into a bit flag.
98    /// This is useful for encoding the reliability into a packet.
99    pub fn to_flags(&self) -> u8 {
100        match self {
101            Reliability::Unreliable => 0 << 5,
102            Reliability::UnreliableSeq => 1 << 5,
103            Reliability::Reliable => 2 << 5,
104            Reliability::ReliableOrd => 3 << 5,
105            Reliability::ReliableSeq => 4 << 5,
106            Reliability::UnreliableAck => 5 << 5,
107            Reliability::ReliableAck => 6 << 5,
108            Reliability::ReliableOrdAck => 7 << 5,
109        }
110    }
111
112    /// This method checks whether the reliability is ordered, meaning that the packets
113    /// are either:
114    /// - [`ReliableOrd`]
115    /// - [`ReliableOrdAck`]
116    /// - [`UnreliableSeq`]
117    ///
118    /// [`ReliableOrd`]: crate::protocol::reliability::Reliability::ReliableOrd
119    /// [`ReliableOrdAck`]: crate::protocol::reliability::Reliability::ReliableOrdAck
120    /// [`UnreliableSeq`]: crate::protocol::reliability::Reliability::UnreliableSeq
121    pub fn is_ordered(&self) -> bool {
122        match self {
123            Self::UnreliableSeq | Self::ReliableOrd | Self::ReliableOrdAck => true,
124            _ => false,
125        }
126    }
127
128    /// Verifies whether or not the reliabilty is reliable, meaning that the packets
129    /// are either:
130    /// - [`Reliable`]
131    /// - [`ReliableOrd`]
132    /// - [`ReliableSeq`]
133    /// - [`ReliableAck`]
134    ///
135    /// Other reliabilities are not reliable, and will return `false`.
136    ///
137    /// [`Reliable`]: crate::protocol::reliability::Reliability::Reliable
138    /// [`ReliableOrd`]: crate::protocol::reliability::Reliability::ReliableOrd
139    /// [`ReliableSeq`]: crate::protocol::reliability::Reliability::ReliableSeq
140    /// [`ReliableAck`]: crate::protocol::reliability::Reliability::ReliableAck
141    pub fn is_reliable(&self) -> bool {
142        match self {
143            Self::Reliable | Self::ReliableOrd | Self::ReliableSeq | Self::ReliableOrdAck => true,
144            _ => false,
145        }
146    }
147
148    /// Verifies whether or not the reliabilty is unreliable, meaning that the packets
149    /// are either:
150    /// - [`Unreliable`]
151    /// - [`UnreliableSeq`]
152    /// - [`UnreliableAck`]
153    ///
154    /// Other reliabilities are not unreliable, and will return `false`.
155    ///
156    /// [`Unreliable`]: crate::protocol::reliability::Reliability::Unreliable
157    /// [`UnreliableSeq`]: crate::protocol::reliability::Reliability::UnreliableSeq
158    /// [`UnreliableAck`]: crate::protocol::reliability::Reliability::UnreliableAck
159    pub fn is_unreliable(&self) -> bool {
160        match self {
161            Self::Unreliable | Self::UnreliableSeq | Self::UnreliableAck => true,
162            _ => false,
163        }
164    }
165
166    /// Verifies whether or not the reliabilty is sequenced, meaning that the packets
167    /// are either:
168    /// - [`UnreliableSeq`]
169    /// - [`ReliableSeq`]
170    ///
171    /// Other reliabilities are not sequenced, and will return `false`.
172    ///
173    /// ## What is a sequenced packet?
174    /// A sequenced packet is a packet with an index that is incremented after each packet.
175    /// RakNet uses this internally to discard packets that are sent out of sequence, accepting
176    /// only the latest packet.
177    ///
178    /// [`UnreliableSeq`]: crate::protocol::reliability::Reliability::UnreliableSeq
179    /// [`ReliableSeq`]: crate::protocol::reliability::Reliability::ReliableSeq
180    pub fn is_sequenced(&self) -> bool {
181        match self {
182            Self::UnreliableSeq | Self::ReliableSeq => true,
183            _ => false,
184        }
185    }
186
187    /// Verifies whether or not the reliabilty is sequenced or ordered. This function
188    /// is a combination of [`Reliability::is_sequenced`] and [`Reliability::is_ordered`],
189    /// combined into one signature.
190    ///
191    /// [`Reliability::is_sequenced`]: crate::protocol::reliability::Reliability::is_sequenced
192    /// [`Reliability::is_ordered`]: crate::protocol::reliability::Reliability::is_ordered
193    pub fn is_sequenced_or_ordered(&self) -> bool {
194        match self {
195            Self::UnreliableSeq | Self::ReliableSeq | Self::ReliableOrd | Self::ReliableOrdAck => {
196                true
197            }
198            _ => false,
199        }
200    }
201
202    /// Verifies that the reliability is an ack ([`Ack`]).
203    /// This is primarily used internally to determine whether or not to send an ack.
204    ///
205    /// [`Ack`]: crate::protocol::ack::Ack
206    pub fn is_ack(&self) -> bool {
207        match self {
208            Self::UnreliableAck | Self::ReliableAck | Self::ReliableOrdAck => true,
209            _ => false,
210        }
211    }
212}