rusty_enet/
packet.rs

1use core::fmt::Debug;
2
3use crate::{
4    enet_packet_create, enet_packet_destroy, Box, ENetPacket, Vec, ENET_PACKET_FLAG_NO_ALLOCATE,
5    ENET_PACKET_FLAG_RELIABLE, ENET_PACKET_FLAG_SENT, ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT,
6    ENET_PACKET_FLAG_UNSEQUENCED,
7};
8
9/// Types of packets supported by ENet, used with [`Packet::new`].
10///
11/// See [`Sequencing`](`crate#sequencing`).
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
13pub enum PacketKind {
14    /// An unreliable packet, with optional sequencing. A sequenced unreliable packet will cause
15    /// unsequenced packets to simply be discarded if they were to be dispatched out of order.
16    ///
17    /// Note that packets of this kind will be sent reliably if they are too large to fit within the
18    /// maximum transmission unit (MTU). To avoid this behavior, use
19    /// [`PacketKind::AlwaysUnreliable`] instead.
20    Unreliable {
21        /// Should the packets be sequenced? Packets received out of order will be discarded.
22        sequenced: bool,
23    },
24    /// An unreliable packet, with optional sequencing. Guaranteed to be unreliable, see
25    /// [`PacketKind::Unreliable`].
26    AlwaysUnreliable {
27        /// Should the packets be sequenced? Packets received out of order will be discarded.
28        sequenced: bool,
29    },
30    /// An reliable packet, with enforced sequencing.
31    ///
32    /// See [`Reliability`](`crate#reliability`).
33    Reliable,
34}
35
36/// An ENet data packet that may be sent to or received from a peer.
37///
38/// See [`Fragmentation and Reassembly`](`crate#fragmentation-and-reassembly`).
39///
40/// For more information on the kinds of ENet packets, see [`PacketKind`].
41pub struct Packet {
42    pub(crate) packet: *mut ENetPacket,
43}
44
45unsafe impl Send for Packet {}
46unsafe impl Sync for Packet {}
47
48impl Packet {
49    /// Create a new packet manually from its data and kind.
50    ///
51    /// Some convenience methods exist that can be used instead:
52    /// - [`Packet::unreliable`]
53    /// - [`Packet::unreliable_unsequenced`]
54    /// - [`Packet::always_unreliable`]
55    /// - [`Packet::always_unreliable_unsequenced`]
56    /// - [`Packet::reliable`]
57    #[must_use]
58    pub fn new<P: ToRawPacket>(data: P, kind: PacketKind) -> Self {
59        let kind_flags = match kind {
60            PacketKind::Unreliable { sequenced: true } => 0,
61            PacketKind::Unreliable { sequenced: false } => ENET_PACKET_FLAG_UNSEQUENCED,
62            PacketKind::AlwaysUnreliable { sequenced: true } => {
63                ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT
64            }
65            PacketKind::AlwaysUnreliable { sequenced: false } => {
66                ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT | ENET_PACKET_FLAG_UNSEQUENCED
67            }
68            PacketKind::Reliable => ENET_PACKET_FLAG_RELIABLE,
69        };
70
71        let raw_packet = data.into_packet_data();
72
73        let packet = unsafe {
74            enet_packet_create(
75                raw_packet.data,
76                raw_packet.len,
77                kind_flags | ENET_PACKET_FLAG_NO_ALLOCATE,
78            )
79        };
80        unsafe {
81            (*packet).free_callback = Some(Self::drop_packet_data::<P>);
82            (*packet).user_data = raw_packet.user_data as *mut _;
83            (*packet).reference_count += 1;
84        }
85        Self { packet }
86    }
87
88    /// Create a new unreliable packet with
89    /// [`PacketKind::Unreliable { sequenced: true }`](`PacketKind::Unreliable`)
90    #[must_use]
91    pub fn unreliable(data: impl ToRawPacket) -> Self {
92        Self::new(data, PacketKind::Unreliable { sequenced: true })
93    }
94
95    /// Create a new unreliable packet with
96    /// [`PacketKind::Unreliable { sequenced: false }`](`PacketKind::Unreliable`)
97    #[must_use]
98    pub fn unreliable_unsequenced(data: impl ToRawPacket) -> Self {
99        Self::new(data, PacketKind::Unreliable { sequenced: false })
100    }
101
102    /// Create a new always unreliable packet with
103    /// [`PacketKind::AlwaysUnreliable { sequenced: true }`](`PacketKind::AlwaysUnreliable`)
104    #[must_use]
105    pub fn always_unreliable(data: impl ToRawPacket) -> Self {
106        Self::new(data, PacketKind::AlwaysUnreliable { sequenced: true })
107    }
108
109    /// Create a new always unreliable packet with
110    /// [`PacketKind::AlwaysUnreliable { sequenced: false }`](`PacketKind::AlwaysUnreliable`)
111    #[must_use]
112    pub fn always_unreliable_unsequenced(data: impl ToRawPacket) -> Self {
113        Self::new(data, PacketKind::AlwaysUnreliable { sequenced: false })
114    }
115
116    /// Create a new unreliable packet with [`PacketKind::Reliable`]
117    #[must_use]
118    pub fn reliable(data: impl ToRawPacket) -> Self {
119        Self::new(data, PacketKind::Reliable)
120    }
121
122    /// Get this packet's [`PacketKind`].
123    #[must_use]
124    pub fn kind(&self) -> PacketKind {
125        let flags = unsafe { (*self.packet).flags | !ENET_PACKET_FLAG_SENT };
126        let sequenced = flags & ENET_PACKET_FLAG_UNSEQUENCED == 0;
127        if flags & ENET_PACKET_FLAG_RELIABLE != 0 {
128            PacketKind::Reliable
129        } else if flags & ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT != 0 {
130            PacketKind::AlwaysUnreliable { sequenced }
131        } else {
132            PacketKind::Unreliable { sequenced }
133        }
134    }
135
136    /// Get the byte array contained in this packet.
137    #[must_use]
138    pub fn data(&self) -> &[u8] {
139        unsafe { super::from_raw_parts_or_empty((*self.packet).data, (*self.packet).data_length) }
140    }
141
142    pub(crate) fn new_from_ptr(packet: *mut ENetPacket) -> Self {
143        unsafe {
144            (*packet).reference_count += 1;
145        }
146        Self { packet }
147    }
148
149    unsafe fn drop_packet_data<P: ToRawPacket>(packet: *mut ENetPacket) {
150        P::drop_packet_data(RawPacket {
151            data: (*packet).data,
152            len: (*packet).data_length,
153            user_data: (*packet).user_data as usize,
154        });
155    }
156}
157
158impl Clone for Packet {
159    fn clone(&self) -> Self {
160        unsafe {
161            (*self.packet).reference_count += 1;
162        }
163        Self {
164            packet: self.packet,
165        }
166    }
167}
168
169impl Drop for Packet {
170    fn drop(&mut self) {
171        unsafe {
172            (*self.packet).reference_count -= 1;
173            if (*self.packet).reference_count == 0 {
174                enet_packet_destroy(self.packet);
175            }
176        }
177    }
178}
179
180impl Debug for Packet {
181    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
182        let packet = unsafe { &(*self.packet) };
183        f.debug_struct("Packet")
184            .field("data", &packet.data)
185            .field("dataLength", &packet.data_length)
186            .field("flags", &packet.flags)
187            .field("kind", &self.kind())
188            .finish()
189    }
190}
191
192/// Denotes a byte buffer that can be wrapped in a [`Packet`].
193pub trait ToRawPacket {
194    /// Takes ownership of this value and converts it into raw packet data.
195    fn into_packet_data(self) -> RawPacket;
196
197    /// Drops packet data that was previously created for this type.
198    ///
199    /// # Safety
200    ///
201    /// For this function call to be sound, `packet` must have been previously
202    /// created with [`Self::into_packet_data`].
203    unsafe fn drop_packet_data(packet: RawPacket);
204}
205
206impl ToRawPacket for &[u8] {
207    fn into_packet_data(self) -> RawPacket {
208        self.to_vec().into_packet_data()
209    }
210
211    unsafe fn drop_packet_data(packet: RawPacket) {
212        Vec::<u8>::drop_packet_data(packet);
213    }
214}
215
216impl ToRawPacket for Vec<u8> {
217    fn into_packet_data(mut self) -> RawPacket {
218        let data = self.as_mut_ptr();
219        let len = self.len();
220        let user_data = self.capacity();
221        core::mem::forget(self);
222        RawPacket {
223            data,
224            len,
225            user_data,
226        }
227    }
228
229    unsafe fn drop_packet_data(packet: RawPacket) {
230        Vec::from_raw_parts(packet.data, packet.len, packet.user_data);
231    }
232}
233
234impl ToRawPacket for Box<[u8]> {
235    fn into_packet_data(self) -> RawPacket {
236        let len = self.len();
237        let data = Box::into_raw(self).cast();
238        RawPacket {
239            data,
240            len,
241            user_data: 0,
242        }
243    }
244
245    unsafe fn drop_packet_data(packet: RawPacket) {
246        let _ = Box::from_raw(core::slice::from_raw_parts_mut(packet.data, packet.len));
247    }
248}
249
250impl<T: AsRef<[u8]> + Sized> ToRawPacket for Box<T> {
251    fn into_packet_data(self) -> RawPacket {
252        let slice = (*self).as_ref();
253        let data = slice.as_ptr().cast_mut();
254        let len = slice.len();
255        let user_data = Box::into_raw(self) as usize;
256        RawPacket {
257            data,
258            len,
259            user_data,
260        }
261    }
262
263    unsafe fn drop_packet_data(packet: RawPacket) {
264        let _ = Box::<T>::from_raw(packet.user_data as *mut _);
265    }
266}
267
268/// Describes a raw, Rust-owned packet object.
269pub struct RawPacket {
270    /// The underlying data.
271    pub data: *mut u8,
272    /// The length of the data in bytes.
273    pub len: usize,
274    /// Extra data identifying the object.
275    pub user_data: usize,
276}