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