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(Error, Debug)]
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_string();
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 AzaleaReadLimited for String {
289 fn azalea_read_limited(buf: &mut Cursor<&[u8]>, limit: usize) -> Result<Self, BufReadError> {
290 read_utf_with_len(buf, limit as u32)
291 }
292}
293
294impl AzaleaRead for u32 {
295 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
296 Ok(i32::azalea_read(buf)? as u32)
297 }
298}
299
300impl AzaleaReadVar for u32 {
301 fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
302 Ok(i32::azalea_read_var(buf)? as u32)
303 }
304}
305
306impl AzaleaRead for u16 {
307 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
308 i16::azalea_read(buf).map(|i| i as u16)
309 }
310}
311
312impl AzaleaRead for i16 {
313 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
314 Ok(buf.read_i16::<BE>()?)
315 }
316}
317
318impl AzaleaReadVar for u16 {
319 fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
320 Ok(i32::azalea_read_var(buf)? as u16)
321 }
322}
323
324impl AzaleaRead for i64 {
325 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
326 Ok(buf.read_i64::<BE>()?)
327 }
328}
329
330impl AzaleaRead for u64 {
331 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
332 i64::azalea_read(buf).map(|i| i as u64)
333 }
334}
335
336impl AzaleaRead for bool {
337 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
338 let byte = u8::azalea_read(buf)?;
339 if byte > 1 {
340 warn!("Boolean value was not 0 or 1, but {}", byte);
341 }
342 Ok(byte != 0)
343 }
344}
345
346impl AzaleaRead for u8 {
347 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
348 Ok(buf.read_u8()?)
349 }
350}
351
352impl AzaleaRead for i8 {
353 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
354 u8::azalea_read(buf).map(|i| i as i8)
355 }
356}
357
358impl AzaleaRead for f32 {
359 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
360 Ok(buf.read_f32::<BE>()?)
361 }
362}
363
364impl AzaleaRead for f64 {
365 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
366 Ok(buf.read_f64::<BE>()?)
367 }
368}
369
370impl<T: AzaleaRead> AzaleaRead for Option<T> {
371 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
372 let present = bool::azalea_read(buf)?;
373 Ok(if present {
374 Some(T::azalea_read(buf)?)
375 } else {
376 None
377 })
378 }
379}
380
381impl<T: AzaleaReadVar> AzaleaReadVar for Option<T> {
382 fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
383 let present = bool::azalea_read(buf)?;
384 Ok(if present {
385 Some(T::azalea_read_var(buf)?)
386 } else {
387 None
388 })
389 }
390}
391impl<T: AzaleaReadLimited> AzaleaReadLimited for Option<T> {
392 fn azalea_read_limited(buf: &mut Cursor<&[u8]>, limit: usize) -> Result<Self, BufReadError> {
393 let present = bool::azalea_read(buf)?;
394 Ok(if present {
395 Some(T::azalea_read_limited(buf, limit)?)
396 } else {
397 None
398 })
399 }
400}
401
402impl<T: AzaleaRead, const N: usize> AzaleaRead for [T; N] {
404 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
405 let mut contents = Vec::with_capacity(N);
406 for _ in 0..N {
407 contents.push(T::azalea_read(buf)?);
408 }
409 contents.try_into().map_err(|_| {
410 unreachable!("Panic is not possible since the Vec is the same size as the array")
411 })
412 }
413}
414
415impl AzaleaRead for simdnbt::owned::NbtTag {
416 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
417 Ok(simdnbt::owned::read_tag(buf).map_err(simdnbt::Error::from)?)
418 }
419}
420
421impl AzaleaRead for simdnbt::owned::NbtCompound {
422 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
423 match simdnbt::owned::read_tag(buf).map_err(simdnbt::Error::from)? {
424 simdnbt::owned::NbtTag::Compound(compound) => Ok(compound),
425 _ => Err(BufReadError::Custom("Expected compound tag".to_string())),
426 }
427 }
428}
429
430impl AzaleaRead for simdnbt::owned::Nbt {
431 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
432 Ok(simdnbt::owned::read_unnamed(buf)?)
433 }
434}
435
436impl<T> AzaleaRead for Box<T>
437where
438 T: AzaleaRead,
439{
440 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
441 Ok(Box::new(T::azalea_read(buf)?))
442 }
443}
444
445impl<A: AzaleaRead, B: AzaleaRead> AzaleaRead for (A, B) {
446 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
447 Ok((A::azalea_read(buf)?, B::azalea_read(buf)?))
448 }
449}
450
451impl<T: AzaleaRead> AzaleaRead for Arc<T> {
452 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
453 Ok(Arc::new(T::azalea_read(buf)?))
454 }
455}