1use std::{
2 backtrace::Backtrace,
3 collections::HashMap,
4 hash::Hash,
5 io::{self, Cursor, Read},
6 sync::Arc,
7};
8
9use byteorder::{BE, ReadBytesExt};
10use indexmap::IndexMap;
11use thiserror::Error;
12use tracing::warn;
13
14use super::{MAX_STRING_LENGTH, UnsizedByteArray};
15
16#[derive(Debug, Error)]
17pub enum BufReadError {
18 #[error("Invalid VarInt")]
19 InvalidVarInt,
20 #[error("Invalid VarLong")]
21 InvalidVarLong,
22 #[error("Error reading bytes")]
23 CouldNotReadBytes,
24 #[error(
25 "The received encoded string buffer length is longer than maximum allowed ({length} > {max_length})"
26 )]
27 StringLengthTooLong { length: u32, max_length: u32 },
28 #[error("The received Vec length is longer than maximum allowed ({length} > {max_length})")]
29 VecLengthTooLong { length: u32, max_length: u32 },
30 #[error("{source}")]
31 Io {
32 #[from]
33 #[backtrace]
34 source: io::Error,
35 },
36 #[error("Invalid UTF-8: {bytes:?} (lossy: {lossy:?})")]
37 InvalidUtf8 {
38 bytes: Vec<u8>,
39 lossy: String,
40 },
42 #[error("Unexpected enum variant {id}")]
43 UnexpectedEnumVariant { id: i32 },
44 #[error("Unexpected enum variant {id}")]
45 UnexpectedStringEnumVariant { id: String },
46 #[error("Tried to read {attempted_read} bytes but there were only {actual_read}")]
47 UnexpectedEof {
48 attempted_read: usize,
49 actual_read: usize,
50 backtrace: Backtrace,
51 },
52 #[error("{0}")]
53 Custom(String),
54 #[cfg(feature = "serde_json")]
55 #[error("{source}")]
56 Deserialization {
57 #[from]
58 #[backtrace]
59 source: serde_json::Error,
60 },
61 #[error("{source}")]
62 Nbt {
63 #[from]
64 #[backtrace]
65 source: simdnbt::Error,
66 },
67 #[error("{source}")]
68 DeserializeNbt {
69 #[from]
70 #[backtrace]
71 source: simdnbt::DeserializeError,
72 },
73}
74
75fn read_bytes<'a>(buf: &'a mut Cursor<&[u8]>, length: usize) -> Result<&'a [u8], BufReadError> {
76 if length > (buf.get_ref().len() - buf.position() as usize) {
77 return Err(BufReadError::UnexpectedEof {
78 attempted_read: length,
79 actual_read: buf.get_ref().len() - buf.position() as usize,
80 backtrace: Backtrace::capture(),
81 });
82 }
83 let initial_position = buf.position() as usize;
84 buf.set_position(buf.position() + length as u64);
85 let data = &buf.get_ref()[initial_position..initial_position + length];
86 Ok(data)
87}
88
89fn read_utf_with_len(buf: &mut Cursor<&[u8]>, max_length: u32) -> Result<String, BufReadError> {
90 let length = u32::azalea_read_var(buf)?;
91 if length > max_length * 4 {
93 return Err(BufReadError::StringLengthTooLong {
94 length,
95 max_length: max_length * 4,
96 });
97 }
98
99 let buffer = read_bytes(buf, length as usize)?;
100 let string = std::str::from_utf8(buffer)
101 .map_err(|_| BufReadError::InvalidUtf8 {
102 bytes: buffer.to_vec(),
103 lossy: String::from_utf8_lossy(buffer).to_string(),
104 })?
106 .to_owned();
107 if string.len() > length as usize {
108 return Err(BufReadError::StringLengthTooLong { length, max_length });
109 }
110
111 Ok(string)
112}
113
114pub trait AzaleaRead
115where
116 Self: Sized,
117{
118 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError>;
119}
120
121pub trait AzaleaReadVar
122where
123 Self: Sized,
124{
125 fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError>;
126}
127
128pub trait AzaleaReadLimited
132where
133 Self: Sized,
134{
135 fn azalea_read_limited(buf: &mut Cursor<&[u8]>, limit: usize) -> Result<Self, BufReadError>;
136}
137
138impl AzaleaRead for () {
139 fn azalea_read(_buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
140 Ok(())
141 }
142}
143
144impl AzaleaRead for i32 {
145 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
146 Ok(buf.read_i32::<BE>()?)
147 }
148}
149
150impl AzaleaReadVar for i32 {
151 fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
153 let mut buffer = [0];
155 let mut ans = 0;
156 for i in 0..5 {
157 buf.read_exact(&mut buffer)?;
158 ans |= ((buffer[0] & 0b0111_1111) as i32) << (7 * i);
159 if buffer[0] & 0b1000_0000 == 0 {
160 break;
161 }
162 }
163 Ok(ans)
164 }
165}
166
167impl AzaleaReadVar for i64 {
168 fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
169 let mut buffer = [0];
170 let mut ans = 0;
171 for i in 0..10 {
172 buf.read_exact(&mut buffer)
173 .map_err(|_| BufReadError::InvalidVarLong)?;
174 ans |= ((buffer[0] & 0b0111_1111) as i64) << (7 * i);
175 if buffer[0] & 0b1000_0000 == 0 {
176 break;
177 }
178 }
179 Ok(ans)
180 }
181}
182impl AzaleaReadVar for u64 {
183 fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
184 i64::azalea_read_var(buf).map(|i| i as u64)
185 }
186}
187
188impl AzaleaRead for UnsizedByteArray {
189 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
190 let data = buf.get_ref()[buf.position() as usize..].to_vec();
192 buf.set_position((buf.position()) + data.len() as u64);
193 Ok(UnsizedByteArray(data))
194 }
195}
196
197macro_rules! impl_for_map_type {
198 ($ty: ident) => {
199 impl<K: AzaleaRead + Send + Eq + Hash, V: AzaleaRead + Send> AzaleaRead for $ty<K, V> {
200 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
201 let length = i32::azalea_read_var(buf)? as usize;
202 let mut contents = Self::with_capacity(usize::min(length, 65536));
203 for _ in 0..length {
204 contents.insert(K::azalea_read(buf)?, V::azalea_read(buf)?);
205 }
206 Ok(contents)
207 }
208 }
209 impl<K: AzaleaRead + Send + Eq + Hash, V: AzaleaReadVar + Send> AzaleaReadVar
210 for $ty<K, V>
211 {
212 fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
213 let length = i32::azalea_read_var(buf)? as usize;
214 let mut contents = Self::with_capacity(usize::min(length, 65536));
215 for _ in 0..length {
216 contents.insert(K::azalea_read(buf)?, V::azalea_read_var(buf)?);
217 }
218 Ok(contents)
219 }
220 }
221 };
222}
223
224impl_for_map_type!(HashMap);
225impl_for_map_type!(IndexMap);
226
227macro_rules! impl_for_list_type {
228 ($ty: ty) => {
229 impl<T: AzaleaRead> AzaleaRead for $ty {
230 default fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
231 let length = u32::azalea_read_var(buf)? as usize;
232 let mut contents = Vec::with_capacity(usize::min(length, 65536));
234 for _ in 0..length {
235 contents.push(T::azalea_read(buf)?);
236 }
237 Ok(contents.into())
238 }
239 }
240 impl<T: AzaleaReadVar> AzaleaReadVar for $ty {
241 fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
242 let length = i32::azalea_read_var(buf)? as usize;
243 let mut contents = Vec::with_capacity(usize::min(length, 65536));
244 for _ in 0..length {
245 contents.push(T::azalea_read_var(buf)?);
246 }
247 Ok(contents.into())
248 }
249 }
250 impl<T: AzaleaRead> AzaleaReadLimited for $ty {
251 fn azalea_read_limited(
252 buf: &mut Cursor<&[u8]>,
253 limit: usize,
254 ) -> Result<Self, BufReadError> {
255 let length = u32::azalea_read_var(buf)? as usize;
256 if length > limit {
257 return Err(BufReadError::VecLengthTooLong {
258 length: length as u32,
259 max_length: limit as u32,
260 });
261 }
262
263 let mut contents = Vec::with_capacity(usize::min(length, 65536));
264 for _ in 0..length {
265 contents.push(T::azalea_read(buf)?);
266 }
267 Ok(contents.into())
268 }
269 }
270 };
271}
272
273impl_for_list_type!(Vec<T>);
274impl_for_list_type!(Box<[T]>);
275
276impl AzaleaRead for Vec<u8> {
277 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
278 let length = i32::azalea_read_var(buf)? as usize;
279 read_bytes(buf, length).map(|b| b.to_vec())
280 }
281}
282
283impl AzaleaRead for String {
284 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
285 read_utf_with_len(buf, MAX_STRING_LENGTH.into())
286 }
287}
288impl AzaleaRead for Box<str> {
289 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
290 String::azalea_read(buf).map(Into::into)
291 }
292}
293impl AzaleaReadLimited for String {
294 fn azalea_read_limited(buf: &mut Cursor<&[u8]>, limit: usize) -> Result<Self, BufReadError> {
295 read_utf_with_len(buf, limit as u32)
296 }
297}
298impl AzaleaReadLimited for Box<str> {
299 fn azalea_read_limited(buf: &mut Cursor<&[u8]>, limit: usize) -> Result<Self, BufReadError> {
300 String::azalea_read_limited(buf, limit).map(Into::into)
301 }
302}
303
304impl AzaleaRead for u32 {
305 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
306 Ok(i32::azalea_read(buf)? as u32)
307 }
308}
309
310impl AzaleaReadVar for u32 {
311 fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
312 Ok(i32::azalea_read_var(buf)? as u32)
313 }
314}
315
316impl AzaleaRead for u16 {
317 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
318 i16::azalea_read(buf).map(|i| i as u16)
319 }
320}
321
322impl AzaleaRead for i16 {
323 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
324 Ok(buf.read_i16::<BE>()?)
325 }
326}
327
328impl AzaleaReadVar for u16 {
329 fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
330 Ok(i32::azalea_read_var(buf)? as u16)
331 }
332}
333
334impl AzaleaRead for i64 {
335 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
336 Ok(buf.read_i64::<BE>()?)
337 }
338}
339
340impl AzaleaRead for u64 {
341 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
342 i64::azalea_read(buf).map(|i| i as u64)
343 }
344}
345
346impl AzaleaRead for bool {
347 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
348 let byte = u8::azalea_read(buf)?;
349 if byte > 1 {
350 warn!("Boolean value was not 0 or 1, but {}", byte);
351 }
352 Ok(byte != 0)
353 }
354}
355
356impl AzaleaRead for u8 {
357 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
358 Ok(buf.read_u8()?)
359 }
360}
361
362impl AzaleaRead for i8 {
363 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
364 u8::azalea_read(buf).map(|i| i as i8)
365 }
366}
367
368impl AzaleaRead for f32 {
369 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
370 Ok(buf.read_f32::<BE>()?)
371 }
372}
373
374impl AzaleaRead for f64 {
375 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
376 Ok(buf.read_f64::<BE>()?)
377 }
378}
379
380impl<T: AzaleaRead> AzaleaRead for Option<T> {
381 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
382 let present = bool::azalea_read(buf)?;
383 Ok(if present {
384 Some(T::azalea_read(buf)?)
385 } else {
386 None
387 })
388 }
389}
390
391impl<T: AzaleaReadVar> AzaleaReadVar for Option<T> {
392 fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
393 let present = bool::azalea_read(buf)?;
394 Ok(if present {
395 Some(T::azalea_read_var(buf)?)
396 } else {
397 None
398 })
399 }
400}
401impl<T: AzaleaReadLimited> AzaleaReadLimited for Option<T> {
402 fn azalea_read_limited(buf: &mut Cursor<&[u8]>, limit: usize) -> Result<Self, BufReadError> {
403 let present = bool::azalea_read(buf)?;
404 Ok(if present {
405 Some(T::azalea_read_limited(buf, limit)?)
406 } else {
407 None
408 })
409 }
410}
411
412impl<T: AzaleaRead, const N: usize> AzaleaRead for [T; N] {
414 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
415 let mut contents = Vec::with_capacity(N);
416 for _ in 0..N {
417 contents.push(T::azalea_read(buf)?);
418 }
419 contents.try_into().map_err(|_| {
420 unreachable!("Panic is not possible since the Vec is the same size as the array")
421 })
422 }
423}
424
425impl AzaleaRead for simdnbt::owned::NbtTag {
426 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
427 Ok(simdnbt::owned::read_tag(buf).map_err(simdnbt::Error::from)?)
428 }
429}
430
431impl AzaleaRead for simdnbt::owned::NbtCompound {
432 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
433 match simdnbt::owned::read_tag(buf).map_err(simdnbt::Error::from)? {
434 simdnbt::owned::NbtTag::Compound(compound) => Ok(compound),
435 _ => Err(BufReadError::Custom("Expected compound tag".to_owned())),
436 }
437 }
438}
439
440impl AzaleaRead for simdnbt::owned::Nbt {
441 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
442 Ok(simdnbt::owned::read_unnamed(buf)?)
443 }
444}
445
446impl<T> AzaleaRead for Box<T>
447where
448 T: AzaleaRead,
449{
450 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
451 Ok(Box::new(T::azalea_read(buf)?))
452 }
453}
454
455impl<A: AzaleaRead, B: AzaleaRead> AzaleaRead for (A, B) {
456 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
457 Ok((A::azalea_read(buf)?, B::azalea_read(buf)?))
458 }
459}
460
461impl<T: AzaleaRead> AzaleaRead for Arc<T> {
462 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
463 Ok(Arc::new(T::azalea_read(buf)?))
464 }
465}