diff options
| author | mat <github@matdoes.dev> | 2022-05-08 18:55:49 -0500 |
|---|---|---|
| committer | mat <github@matdoes.dev> | 2022-05-08 18:55:49 -0500 |
| commit | ac392542ce223639c8615035a0be050fff12030a (patch) | |
| tree | 460f8019c2a7aeada10a714f624002ef53007be2 /azalea-protocol/src/mc_buf/read.rs | |
| parent | e0239865659b2f2750edda7556548f6a2b8d4127 (diff) | |
| parent | d783a0295b11c32f1b5425cab2461f9297f7f8fa (diff) | |
| download | azalea-drasl-ac392542ce223639c8615035a0be050fff12030a.tar.xz | |
Merge branch 'main' into chunk-decoding
Diffstat (limited to 'azalea-protocol/src/mc_buf/read.rs')
| -rw-r--r--[-rwxr-xr-x] | azalea-protocol/src/mc_buf/read.rs | 68 |
1 files changed, 51 insertions, 17 deletions
diff --git a/azalea-protocol/src/mc_buf/read.rs b/azalea-protocol/src/mc_buf/read.rs index a8c44bdf..ebafad92 100755..100644 --- a/azalea-protocol/src/mc_buf/read.rs +++ b/azalea-protocol/src/mc_buf/read.rs @@ -6,7 +6,7 @@ use azalea_core::{ }; use byteorder::{ReadBytesExt, BE}; use serde::Deserialize; -use std::io::Read; +use std::{collections::HashMap, hash::Hash, io::Read}; use tokio::io::{AsyncRead, AsyncReadExt}; use uuid::Uuid; @@ -236,11 +236,11 @@ where fn read_into(buf: &mut impl Read) -> Result<Self, String>; } -pub trait McBufVarintReadable +pub trait McBufVarReadable where Self: Sized, { - fn varint_read_into(buf: &mut impl Read) -> Result<Self, String>; + fn var_read_into(buf: &mut impl Read) -> Result<Self, String>; } impl McBufReadable for i32 { @@ -249,26 +249,37 @@ impl McBufReadable for i32 { } } -impl McBufVarintReadable for i32 { - fn varint_read_into(buf: &mut impl Read) -> Result<Self, String> { +impl McBufVarReadable for i32 { + fn var_read_into(buf: &mut impl Read) -> Result<Self, String> { buf.read_varint() } } -impl<T: McBufVarintReadable> McBufVarintReadable for Vec<T> { - fn varint_read_into(buf: &mut impl Read) -> Result<Self, String> { - let length = u32::varint_read_into(buf)?; - let mut vec = Vec::with_capacity(length as usize); - for _ in 0..length { - vec.push(T::varint_read_into(buf)?); +impl McBufVarReadable for i64 { + // fast varints modified from https://github.com/luojia65/mc-varint/blob/master/src/lib.rs#L54 + fn var_read_into(buf: &mut impl Read) -> Result<Self, String> { + let mut buffer = [0]; + let mut ans = 0; + for i in 0..8 { + buf.read_exact(&mut buffer) + .map_err(|_| "Invalid VarLong".to_string())?; + ans |= ((buffer[0] & 0b0111_1111) as i64) << 7 * i; + if buffer[0] & 0b1000_0000 == 0 { + break; + } } - Ok(vec) + Ok(ans) + } +} +impl McBufVarReadable for u64 { + fn var_read_into(buf: &mut impl Read) -> Result<Self, String> { + i64::var_read_into(buf).map(|i| i as u64) } } impl McBufReadable for UnsizedByteArray { fn read_into(buf: &mut impl Read) -> Result<Self, String> { - Ok(UnsizedByteArray(buf.read_bytes()?)) + Ok(buf.read_bytes()?.into()) } } @@ -283,6 +294,17 @@ impl<T: McBufReadable + Send> McBufReadable for Vec<T> { } } +impl<K: McBufReadable + Send + Eq + Hash, V: McBufReadable + Send> McBufReadable for HashMap<K, V> { + default fn read_into(buf: &mut impl Read) -> Result<Self, String> { + let length = buf.read_varint()? as usize; + let mut contents = HashMap::with_capacity(length); + for _ in 0..length { + contents.insert(K::read_into(buf)?, V::read_into(buf)?); + } + Ok(contents) + } +} + impl McBufReadable for Vec<u8> { fn read_into(buf: &mut impl Read) -> Result<Self, String> { buf.read_byte_array() @@ -311,8 +333,8 @@ impl McBufReadable for u32 { } // u32 varint -impl McBufVarintReadable for u32 { - fn varint_read_into(buf: &mut impl Read) -> Result<Self, String> { +impl McBufVarReadable for u32 { + fn var_read_into(buf: &mut impl Read) -> Result<Self, String> { buf.read_varint().map(|i| i as u32) } } @@ -332,12 +354,24 @@ impl McBufReadable for i16 { } // u16 varint -impl McBufVarintReadable for u16 { - fn varint_read_into(buf: &mut impl Read) -> Result<Self, String> { +impl McBufVarReadable for u16 { + fn var_read_into(buf: &mut impl Read) -> Result<Self, String> { buf.read_varint().map(|i| i as u16) } } +// Vec<T> varint +impl<T: McBufVarReadable> McBufVarReadable for Vec<T> { + fn var_read_into(buf: &mut impl Read) -> Result<Self, String> { + let length = buf.read_varint()? as usize; + let mut contents = Vec::with_capacity(length); + for _ in 0..length { + contents.push(T::var_read_into(buf)?); + } + Ok(contents) + } +} + // i64 impl McBufReadable for i64 { fn read_into(buf: &mut impl Read) -> Result<Self, String> { |
