net_mc/packet/
types.rs

1use super::raw;
2use super::{Decoder, Encoder};
3use anyhow::{bail, Result};
4pub use nbt::Blob as Nbt;
5use std::{
6    borrow::Cow,
7    convert::{TryFrom, TryInto},
8    io, iter,
9    marker::PhantomData,
10    num::TryFromIntError,
11};
12pub use uuid::Uuid;
13
14impl Encoder for u8 {
15    fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
16        raw::write_unsigned_byte(w, *self)
17    }
18}
19
20impl Decoder for u8 {
21    fn read_from(r: &mut impl io::Read) -> Result<Self> {
22        raw::read_unsigned_byte(r)
23    }
24}
25
26impl Encoder for i8 {
27    fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
28        raw::write_byte(w, *self)
29    }
30}
31
32impl Decoder for i8 {
33    fn read_from(r: &mut impl io::Read) -> Result<Self> {
34        raw::read_byte(r)
35    }
36}
37
38impl Encoder for u16 {
39    fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
40        raw::write_unsigned_short(w, *self)
41    }
42}
43
44impl Decoder for u16 {
45    fn read_from(r: &mut impl io::Read) -> Result<Self> {
46        raw::read_unsigned_short(r)
47    }
48}
49
50impl Encoder for i16 {
51    fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
52        raw::write_short(w, *self)
53    }
54}
55
56impl Decoder for i16 {
57    fn read_from(r: &mut impl io::Read) -> Result<Self> {
58        raw::read_short(r)
59    }
60}
61
62impl Encoder for i32 {
63    fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
64        raw::write_int(w, *self)
65    }
66}
67
68impl Decoder for i32 {
69    fn read_from(r: &mut impl io::Read) -> Result<Self> {
70        raw::read_int(r)
71    }
72}
73
74impl Encoder for i64 {
75    fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
76        raw::write_long(w, *self)
77    }
78}
79
80impl Decoder for i64 {
81    fn read_from(r: &mut impl io::Read) -> Result<Self> {
82        raw::read_long(r)
83    }
84}
85
86impl Encoder for f32 {
87    fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
88        raw::write_float(w, *self)
89    }
90}
91
92impl Decoder for f32 {
93    fn read_from(r: &mut impl io::Read) -> Result<Self> {
94        raw::read_float(r)
95    }
96}
97
98impl Encoder for f64 {
99    fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
100        raw::write_double(w, *self)
101    }
102}
103
104impl Decoder for f64 {
105    fn read_from(r: &mut impl io::Read) -> Result<Self> {
106        raw::read_double(r)
107    }
108}
109
110impl Encoder for bool {
111    fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
112        raw::write_bool(w, *self)
113    }
114}
115
116impl Decoder for bool {
117    fn read_from(r: &mut impl io::Read) -> Result<Self> {
118        raw::read_bool(r)
119    }
120}
121
122impl<T> Encoder for Option<T>
123where
124    T: Encoder,
125{
126    fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
127        self.is_some().write_to(w)?;
128
129        if let Some(v) = self {
130            v.write_to(w)?;
131        }
132
133        Ok(())
134    }
135}
136
137impl<T> Decoder for Option<T>
138where
139    T: Decoder,
140{
141    fn read_from(r: &mut impl io::Read) -> Result<Self> {
142        let present = bool::read_from(r)?;
143
144        match present {
145            true => Ok(Some(T::read_from(r)?)),
146            false => Ok(None),
147        }
148    }
149}
150
151#[derive(Copy, Clone, Debug, PartialEq, Eq)]
152pub struct VarInt(pub i32);
153
154impl Encoder for VarInt {
155    fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
156        raw::write_var_int(w, self.0)
157    }
158}
159
160impl Decoder for VarInt {
161    fn read_from(r: &mut impl io::Read) -> Result<Self> {
162        Ok(Self(raw::read_var_int(r)?))
163    }
164}
165
166impl TryFrom<VarInt> for usize {
167    type Error = TryFromIntError;
168    fn try_from(value: VarInt) -> Result<Self, Self::Error> {
169        value.0.try_into()
170    }
171}
172
173impl From<usize> for VarInt {
174    fn from(v: usize) -> Self {
175        VarInt(v as i32)
176    }
177}
178
179impl From<VarInt> for i32 {
180    fn from(v: VarInt) -> Self {
181        v.0
182    }
183}
184
185impl From<i32> for VarInt {
186    fn from(v: i32) -> Self {
187        VarInt(v)
188    }
189}
190
191#[derive(Copy, Clone, Debug, PartialEq, Eq)]
192pub struct VarLong(pub i64);
193
194impl Decoder for VarLong {
195    fn read_from(r: &mut impl io::Read) -> Result<Self> {
196        Ok(Self(raw::read_var_long(r)?))
197    }
198}
199
200impl Encoder for VarLong {
201    fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
202        raw::write_var_long(w, self.0)
203    }
204}
205
206impl From<VarLong> for i64 {
207    fn from(v: VarLong) -> Self {
208        v.0
209    }
210}
211
212impl From<i64> for VarLong {
213    fn from(v: i64) -> Self {
214        VarLong(v)
215    }
216}
217
218impl Encoder for String {
219    fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
220        raw::write_string(w, self)
221    }
222}
223
224impl Decoder for String {
225    fn read_from(r: &mut impl io::Read) -> Result<Self> {
226        raw::read_string(r)
227    }
228}
229
230impl Encoder for Nbt {
231    fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
232        self.to_writer(w).map_err(From::from)
233    }
234}
235
236impl Decoder for Nbt {
237    fn read_from(r: &mut impl io::Read) -> Result<Self> {
238        Nbt::from_reader(r).map_err(From::from)
239    }
240}
241
242impl Encoder for Uuid {
243    fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
244        raw::write_uuid(w, *self)
245    }
246}
247
248impl Decoder for Uuid {
249    fn read_from(r: &mut impl io::Read) -> Result<Self> {
250        raw::read_uuid(r)
251    }
252}
253
254pub struct Position {
255    x: i32,
256    y: i32,
257    z: i32,
258}
259
260impl Encoder for Position {
261    fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
262        raw::write_position(w, self.x, self.y, self.z)
263    }
264}
265
266impl Decoder for Position {
267    fn read_from(r: &mut impl io::Read) -> Result<Self> {
268        let (x, y, z) = raw::read_position(r)?;
269        Ok(Self { x, y, z })
270    }
271}
272
273impl Encoder for Vec<i64> {
274    fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
275        raw::write_bitset(w, self)
276    }
277}
278
279impl Decoder for Vec<i64> {
280    fn read_from(r: &mut impl io::Read) -> Result<Self> {
281        raw::read_bitset(r)
282    }
283}
284
285impl Encoder for Vec<u8> {
286    fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
287        raw::write_byte_array(w, self)
288    }
289}
290
291pub struct Angle(u8);
292
293impl Encoder for Angle {
294    fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
295        raw::write_unsigned_byte(w, self.0)
296    }
297}
298
299impl Decoder for Angle {
300    fn read_from(r: &mut impl io::Read) -> Result<Self> {
301        Ok(Self(raw::read_unsigned_byte(r)?))
302    }
303}
304
305// The following code was taken from https://github.com/feather-rs/feather/blob/main/feather/protocol/src/io.rs which is licensed under Apache 2.0.
306// It was modified slightly to fit the traits of this module.
307// ------------------------------------------------------------------------------------------------------------------------------------------------
308
309pub const MAX_LENGTH: usize = 1024 * 1024; // 2^20 elements
310
311/// Reads and writes an array of inner `Writeable`s.
312/// The array is prefixed with a `VarInt` length.
313///
314/// This will reject arrays of lengths larger than MAX_LENGTH.
315pub struct LengthPrefixedVec<'a, P, T>(pub Cow<'a, [T]>, PhantomData<P>)
316where
317    [T]: ToOwned<Owned = Vec<T>>;
318
319impl<'a, P, T> Decoder for LengthPrefixedVec<'a, P, T>
320where
321    T: Decoder,
322    [T]: ToOwned<Owned = Vec<T>>,
323    P: TryInto<usize> + Decoder,
324    P::Error: std::error::Error + Send + Sync + 'static,
325{
326    fn read_from(r: &mut impl io::Read) -> anyhow::Result<Self>
327    where
328        Self: Sized,
329    {
330        let length: usize = P::read_from(r)?.try_into()?;
331
332        if length > MAX_LENGTH {
333            bail!("array length too large ({} > {})", length, MAX_LENGTH);
334        }
335
336        let vec = iter::repeat_with(|| T::read_from(r))
337            .take(length)
338            .collect::<anyhow::Result<Vec<T>>>()?;
339        Ok(Self(Cow::Owned(vec), PhantomData))
340    }
341}
342
343impl<'a, P, T> Encoder for LengthPrefixedVec<'a, P, T>
344where
345    T: Encoder,
346    [T]: ToOwned<Owned = Vec<T>>,
347    P: TryFrom<usize> + Encoder,
348    P::Error: std::error::Error + Send + Sync + 'static,
349{
350    fn write_to(&self, w: &mut impl io::Write) -> anyhow::Result<()> {
351        P::try_from(self.0.len())?.write_to(w)?;
352        self.0
353            .iter()
354            .for_each(|item| item.write_to(w).expect("failed to write to vec"));
355
356        Ok(())
357    }
358}
359
360impl<'a, P, T> From<LengthPrefixedVec<'a, P, T>> for Vec<T>
361where
362    [T]: ToOwned<Owned = Vec<T>>,
363{
364    fn from(x: LengthPrefixedVec<'a, P, T>) -> Self {
365        x.0.into_owned()
366    }
367}
368
369impl<'a, P, T> From<&'a [T]> for LengthPrefixedVec<'a, P, T>
370where
371    [T]: ToOwned<Owned = Vec<T>>,
372{
373    fn from(slice: &'a [T]) -> Self {
374        Self(Cow::Borrowed(slice), PhantomData)
375    }
376}
377
378impl<'a, P, T> From<Vec<T>> for LengthPrefixedVec<'a, P, T>
379where
380    [T]: ToOwned<Owned = Vec<T>>,
381{
382    fn from(vec: Vec<T>) -> Self {
383        Self(Cow::Owned(vec), PhantomData)
384    }
385}
386
387pub type VarIntPrefixedVec<'a, T> = LengthPrefixedVec<'a, VarInt, T>;
388pub type ShortPrefixedVec<'a, T> = LengthPrefixedVec<'a, u16, T>;
389
390/// A vector of bytes which consumes all remaining bytes in this packet.
391/// This is used by the plugin messaging packets, for one.
392pub struct LengthInferredVecU8<'a>(pub Cow<'a, [u8]>);
393
394impl<'a> Decoder for LengthInferredVecU8<'a> {
395    fn read_from(buffer: &mut impl io::Read) -> anyhow::Result<Self>
396    where
397        Self: Sized,
398    {
399        let mut vec = Vec::new();
400        buffer.read_to_end(&mut vec)?;
401        Ok(LengthInferredVecU8(Cow::Owned(vec)))
402    }
403}
404
405impl<'a> Encoder for LengthInferredVecU8<'a> {
406    fn write_to(&self, w: &mut impl io::Write) -> anyhow::Result<()> {
407        w.write_all(&self.0)?;
408        Ok(())
409    }
410}
411
412impl<'a> From<&'a [u8]> for LengthInferredVecU8<'a> {
413    fn from(slice: &'a [u8]) -> Self {
414        LengthInferredVecU8(Cow::Borrowed(slice))
415    }
416}
417
418impl<'a> From<LengthInferredVecU8<'a>> for Vec<u8> {
419    fn from(x: LengthInferredVecU8<'a>) -> Self {
420        x.0.into_owned()
421    }
422}
423
424// ------------------------------------------------------------------------------------------------------------------------------------------------
425
426// The following code was taken from https://github.com/feather-rs/feather/blob/main/feather/protocol/src/packets.rs
427
428// ------------------------------------------------------------------------------------------------------------------------------------------------
429
430/// Trait implemented for packets which can be converted from a packet
431/// enum. For example, `SpawnEntity` implements `VariantOf<ServerPlayPacket>`.
432pub trait VariantOf<Enum> {
433    /// Returns the unique ID used to determine whether
434    /// an enum variant matches this variant.
435    fn discriminant_id() -> u32;
436
437    /// Attempts to destructure the `Enum` into this type.
438    /// Returns `None` if `enum` is not the correct variant.
439    fn destructure(e: Enum) -> Option<Self>
440    where
441        Self: Sized;
442}
443
444// ------------------------------------------------------------------------------------------------------------------------------------------------