aboutsummaryrefslogtreecommitdiff
path: root/azalea-protocol/src/mc_buf/write.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/write.rs
parente0239865659b2f2750edda7556548f6a2b8d4127 (diff)
parentd783a0295b11c32f1b5425cab2461f9297f7f8fa (diff)
downloadazalea-drasl-ac392542ce223639c8615035a0be050fff12030a.tar.xz
Merge branch 'main' into chunk-decoding
Diffstat (limited to 'azalea-protocol/src/mc_buf/write.rs')
-rw-r--r--[-rwxr-xr-x]azalea-protocol/src/mc_buf/write.rs71
1 files changed, 54 insertions, 17 deletions
diff --git a/azalea-protocol/src/mc_buf/write.rs b/azalea-protocol/src/mc_buf/write.rs
index cc5f2284..7fe61752 100755..100644
--- a/azalea-protocol/src/mc_buf/write.rs
+++ b/azalea-protocol/src/mc_buf/write.rs
@@ -5,7 +5,7 @@ use azalea_core::{
serializable_uuid::SerializableUuid, BlockPos, Direction, Slot,
};
use byteorder::{BigEndian, WriteBytesExt};
-use std::io::Write;
+use std::{collections::HashMap, io::Write};
use uuid::Uuid;
pub trait Writable: Write {
@@ -146,8 +146,8 @@ pub trait McBufWritable {
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error>;
}
-pub trait McBufVarintWritable {
- fn varint_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error>;
+pub trait McBufVarWritable {
+ fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error>;
}
impl McBufWritable for i32 {
@@ -156,8 +156,8 @@ impl McBufWritable for i32 {
}
}
-impl McBufVarintWritable for i32 {
- fn varint_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+impl McBufVarWritable for i32 {
+ fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
buf.write_varint(*self)
}
}
@@ -168,14 +168,24 @@ impl McBufWritable for UnsizedByteArray {
}
}
-// TODO: use specialization when that gets stabilized into rust
-// to optimize for Vec<u8> byte arrays
impl<T: McBufWritable> McBufWritable for Vec<T> {
default fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
buf.write_list(self, |buf, i| T::write_into(i, buf))
}
}
+impl<K: McBufWritable, V: McBufWritable> McBufWritable for HashMap<K, V> {
+ default fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ u32::var_write_into(&(self.len() as u32), buf)?;
+ for (key, value) in self {
+ key.write_into(buf)?;
+ value.write_into(buf)?;
+ }
+
+ Ok(())
+ }
+}
+
impl McBufWritable for Vec<u8> {
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
buf.write_byte_array(self)
@@ -204,16 +214,32 @@ impl McBufWritable for u32 {
}
// u32 varint
-impl McBufVarintWritable for u32 {
- fn varint_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- i32::varint_write_into(&(*self as i32), buf)
+impl McBufVarWritable for u32 {
+ fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ i32::var_write_into(&(*self as i32), buf)
}
}
-// Vec<T> varint
-impl<T: McBufVarintWritable> McBufVarintWritable for Vec<T> {
- fn varint_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- buf.write_list(self, |buf, i| i.varint_write_into(buf))
+impl McBufVarWritable for i64 {
+ fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ let mut buffer = [0];
+ let mut cnt = 0;
+ let mut value = *self;
+ while value != 0 {
+ buffer[0] = (value & 0b0111_1111) as u8;
+ value = (value >> 7) & (i64::max_value() >> 6);
+ if value != 0 {
+ buffer[0] |= 0b1000_0000;
+ }
+ cnt += buf.write(&mut buffer)?;
+ }
+ Ok(())
+ }
+}
+
+impl McBufVarWritable for u64 {
+ fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ i64::var_write_into(&(*self as i64), buf)
}
}
@@ -225,9 +251,20 @@ impl McBufWritable for u16 {
}
// u16 varint
-impl McBufVarintWritable for u16 {
- fn varint_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- i32::varint_write_into(&(*self as i32), buf)
+impl McBufVarWritable for u16 {
+ fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ i32::var_write_into(&(*self as i32), buf)
+ }
+}
+
+// Vec<T> varint
+impl<T: McBufVarWritable> McBufVarWritable for Vec<T> {
+ fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ u32::var_write_into(&(self.len() as u32), buf)?;
+ for i in self {
+ i.var_write_into(buf)?;
+ }
+ Ok(())
}
}