net_mc/packet/
raw.rs

1use anyhow::{bail, Result};
2use byteorder::{ReadBytesExt, WriteBytesExt, BE};
3use std::io;
4use uuid::Uuid;
5
6#[inline]
7pub fn write_bool(t: &mut impl io::Write, v: bool) -> Result<()> {
8    t.write_u8(v as u8).map_err(From::from)
9}
10
11#[inline]
12pub fn read_bool(t: &mut impl io::Read) -> Result<bool> {
13    let i = t.read_u8()?;
14    if i == 0 {
15        return Ok(false);
16    } else if i == 1 {
17        return Ok(true);
18    }
19    Err(anyhow::Error::msg("not a bool"))
20}
21
22#[inline]
23pub fn write_byte(t: &mut impl io::Write, v: i8) -> Result<()> {
24    t.write_i8(v).map_err(From::from)
25}
26
27#[inline]
28pub fn read_byte(t: &mut impl io::Read) -> Result<i8> {
29    t.read_i8().map_err(From::from)
30}
31
32#[inline]
33pub fn write_unsigned_byte(t: &mut impl io::Write, v: u8) -> Result<()> {
34    t.write_u8(v).map_err(From::from)
35}
36
37#[inline]
38pub fn read_unsigned_byte(t: &mut impl io::Read) -> Result<u8> {
39    t.read_u8().map_err(From::from)
40}
41
42#[inline]
43pub fn write_short(t: &mut impl io::Write, v: i16) -> Result<()> {
44    t.write_i16::<BE>(v).map_err(From::from)
45}
46
47#[inline]
48pub fn read_short(t: &mut impl io::Read) -> Result<i16> {
49    t.read_i16::<BE>().map_err(From::from)
50}
51
52#[inline]
53pub fn write_unsigned_short(t: &mut impl io::Write, v: u16) -> Result<()> {
54    t.write_u16::<BE>(v).map_err(From::from)
55}
56
57#[inline]
58pub fn read_unsigned_short(t: &mut impl io::Read) -> Result<u16> {
59    t.read_u16::<BE>().map_err(From::from)
60}
61
62#[inline]
63pub fn write_int(t: &mut impl io::Write, v: i32) -> Result<()> {
64    t.write_i32::<BE>(v).map_err(From::from)
65}
66
67#[inline]
68pub fn read_int(t: &mut impl io::Read) -> Result<i32> {
69    t.read_i32::<BE>().map_err(From::from)
70}
71
72#[inline]
73pub fn write_long(t: &mut impl io::Write, v: i64) -> Result<()> {
74    t.write_i64::<BE>(v).map_err(From::from)
75}
76
77#[inline]
78pub fn read_long(t: &mut impl io::Read) -> Result<i64> {
79    t.read_i64::<BE>().map_err(From::from)
80}
81
82#[inline]
83pub fn write_float(t: &mut impl io::Write, v: f32) -> Result<()> {
84    t.write_f32::<BE>(v).map_err(From::from)
85}
86
87#[inline]
88pub fn read_float(t: &mut impl io::Read) -> Result<f32> {
89    t.read_f32::<BE>().map_err(From::from)
90}
91
92#[inline]
93pub fn write_double(t: &mut impl io::Write, v: f64) -> Result<()> {
94    t.write_f64::<BE>(v).map_err(From::from)
95}
96
97#[inline]
98pub fn read_double(t: &mut impl io::Read) -> Result<f64> {
99    t.read_f64::<BE>().map_err(From::from)
100}
101
102#[inline]
103pub fn write_string(t: &mut impl io::Write, v: &String) -> Result<()> {
104    write_var_int(t, v.len() as i32)?;
105    t.write_all(v.as_bytes()).map_err(From::from)
106}
107
108#[inline]
109pub fn read_string(t: &mut impl io::Read) -> Result<String> {
110    let len = read_var_int(t)? as usize;
111    let mut buf = vec![0; len];
112    t.read_exact(&mut buf)?;
113    Ok(String::from_utf8(buf)?)
114}
115
116#[inline]
117pub fn write_chat(t: &mut impl io::Write, v: &String) -> Result<()> {
118    if v.len() > 262144 {
119        return Err(anyhow::Error::msg(
120            "chat message exceeds maximum length of 26144",
121        ));
122    }
123    write_string(t, v)
124}
125
126#[inline]
127pub fn read_chat(t: &mut impl io::Read) -> Result<String> {
128    let chat = read_string(t)?;
129    if chat.len() > 262144 {
130        return Err(anyhow::Error::msg(
131            "chat message exceeds maximum length of 26144",
132        ));
133    }
134    Ok(chat)
135}
136
137#[inline]
138pub fn write_identifier(t: &mut impl io::Write, v: &String) -> Result<()> {
139    if v.len() > 32767 {
140        return Err(anyhow::Error::msg(
141            "identifier exceeds maximum length of 32767",
142        ));
143    }
144    write_string(t, v)
145}
146
147#[inline]
148pub fn read_identifier(t: &mut impl io::Read) -> Result<String> {
149    let id = read_string(t)?;
150    if id.len() > 32767 {
151        return Err(anyhow::Error::msg(
152            "identifier exceeds maximum length of 32767",
153        ));
154    }
155    Ok(id)
156}
157
158#[inline]
159pub fn write_uuid(t: &mut impl io::Write, v: Uuid) -> Result<()> {
160    t.write_all(v.as_bytes()).map_err(From::from)
161}
162
163#[inline]
164pub fn read_uuid(t: &mut impl io::Read) -> Result<Uuid> {
165    let mut bytes = [0; 16];
166    t.read_exact(&mut bytes)?;
167    Ok(Uuid::from_bytes(bytes))
168}
169
170#[inline]
171pub fn write_byte_array(t: &mut impl io::Write, v: &Vec<u8>) -> Result<()> {
172    write_var_int(t, v.len() as i32)?;
173    t.write_all(v.as_slice()).map_err(From::from)
174}
175
176#[inline]
177pub fn read_byte_array(t: &mut impl io::Read) -> Result<Vec<u8>> {
178    let len = read_var_int(t)? as usize;
179    let mut buf = vec![0; len];
180    t.read_exact(&mut buf[..])?;
181    Ok(buf)
182}
183
184#[inline]
185pub fn write_var_int(t: &mut impl io::Write, v: i32) -> Result<()> {
186    let mut x = v as u32;
187    loop {
188        let mut temp = (x & 0b0111_1111) as u8;
189        x >>= 7;
190        if x != 0 {
191            temp |= 0b1000_0000;
192        }
193
194        t.write_all(&[temp])?;
195
196        if x == 0 {
197            break;
198        }
199    }
200    Ok(())
201}
202
203#[inline]
204pub fn read_var_int(t: &mut impl io::Read) -> Result<i32> {
205    let mut num_read = 0;
206    let mut result = 0;
207
208    loop {
209        let read = t.read_u8()?;
210        let value = i32::from(read & 0b0111_1111);
211        result |= value.overflowing_shl(7 * num_read).0;
212
213        num_read += 1;
214
215        if num_read > 5 {
216            bail!("Varint is too large");
217        }
218        if read & 0b1000_0000 == 0 {
219            break;
220        }
221    }
222
223    Ok(result)
224}
225
226#[inline]
227pub fn write_var_long(t: &mut impl io::Write, v: i64) -> Result<()> {
228    let mut x = v as u64;
229    loop {
230        let mut temp = (x & 0b0111_1111) as u8;
231        x >>= 7;
232        if x != 0 {
233            temp |= 0b1000_0000;
234        }
235
236        t.write_u8(temp).unwrap();
237
238        if x == 0 {
239            break;
240        }
241    }
242
243    Ok(())
244}
245
246#[inline]
247pub fn read_var_long(t: &mut impl io::Read) -> Result<i64> {
248    let mut num_read = 0;
249    let mut result = 0;
250
251    loop {
252        let read = read_unsigned_byte(t)?;
253        let value = i64::from(read & 0b0111_1111);
254        result |= value.overflowing_shl(7 * num_read).0;
255
256        num_read += 1;
257
258        if num_read > 10 {
259            bail!("VarLong is too large.");
260        }
261        if read & 0b1000_0000 == 0 {
262            break;
263        }
264    }
265    Ok(result)
266}
267
268#[inline]
269pub fn write_bitset(t: &mut impl io::Write, v: &Vec<i64>) -> Result<()> {
270    write_var_int(t, v.len() as i32)?;
271    for i in v {
272        write_long(t, *i)?
273    }
274    Ok(())
275}
276
277#[inline]
278pub fn read_bitset(t: &mut impl io::Read) -> Result<Vec<i64>> {
279    let mut data: Vec<i64> = Vec::new();
280    let len = read_var_int(t)? as usize;
281    for i in 0..len {
282        data.insert(i, read_long(t)?);
283    }
284    Ok(data)
285}
286
287#[inline]
288pub fn write_position(t: &mut impl io::Write, x: i32, y: i32, z: i32) -> Result<()> {
289    t.write_u64::<BE>(
290        (x as u64 & 0x3FFFFFF) << 38 | (z as u64 & 0x3FFFFFF) << 12 | (y as u64 & 0xFFF),
291    )
292    .map_err(From::from)
293}
294
295#[inline]
296pub fn read_position(t: &mut impl io::Read) -> Result<(i32, i32, i32)> {
297    let v = read_long(t)?;
298
299    let mut x = (v >> 38) as i32;
300    let mut y = (v & 0xFFF) as i32;
301    let mut z = (v << 26 >> 38) as i32;
302
303    if x >= 1 << 25 {
304        x -= 1 << 26;
305    }
306    if y >= 1 << 11 {
307        y -= 1 << 12;
308    }
309    if z >= 1 << 25 {
310        z -= 1 << 26;
311    }
312    return Ok((x, y, z));
313}
314
315#[inline]
316pub fn write_nbt(t: &mut impl io::Write, v: &nbt::Blob) -> Result<()> {
317    v.to_writer(t).map_err(From::from)
318}
319
320#[inline]
321pub fn read_nbt(t: &mut impl io::Read) -> Result<nbt::Blob> {
322    nbt::Blob::from_reader(t).map_err(From::from)
323}