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}