aboutsummaryrefslogtreecommitdiff
path: root/azalea-protocol/src/mc_buf/read.rs
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2022-05-08 18:55:49 -0500
committermat <github@matdoes.dev>2022-05-08 18:55:49 -0500
commitac392542ce223639c8615035a0be050fff12030a (patch)
tree460f8019c2a7aeada10a714f624002ef53007be2 /azalea-protocol/src/mc_buf/read.rs
parente0239865659b2f2750edda7556548f6a2b8d4127 (diff)
parentd783a0295b11c32f1b5425cab2461f9297f7f8fa (diff)
downloadazalea-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.rs68
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> {