aboutsummaryrefslogtreecommitdiff
path: root/azalea-nbt/src
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2023-09-21 11:16:29 -0500
committerGitHub <noreply@github.com>2023-09-21 11:16:29 -0500
commit7b3e2e4bf793466a351510c7fbbd08234e93bb0e (patch)
tree7177a919de9982d9e3c7f36a76d2025696f465b6 /azalea-nbt/src
parent83cce236145cdab1872a472a70943b669a880965 (diff)
downloadazalea-drasl-7b3e2e4bf793466a351510c7fbbd08234e93bb0e.tar.xz
1.20.2 (#99)
* add configuration state * start updating to 23w31a * implement a bit more of 23w31a * chunk batching * start adding configuration state * ioasfhjgsd * almost works * configuration state mostly implemented * handle other packets in configuration state and fix keepalive * cleanup, fix warnings * 23w32a * fix some doctests * 23w33a * 23w35a * 1.20.2-pre2 * fix system conflicts * 1.20.2-pre4 * make tests compile * tests pass * 1.20.2-rc2 * 1.20.2 * Revert "1.20.2" This reverts commit dd152fd265332ead333c919e585ded6d609d7468. * didn't mean to commit that code --------- Co-authored-by: mat <git@matdoes.dev>
Diffstat (limited to 'azalea-nbt/src')
-rwxr-xr-xazalea-nbt/src/decode.rs16
-rwxr-xr-xazalea-nbt/src/encode.rs91
-rwxr-xr-xazalea-nbt/src/tag.rs10
3 files changed, 76 insertions, 41 deletions
diff --git a/azalea-nbt/src/decode.rs b/azalea-nbt/src/decode.rs
index 35392b15..b2cc8c77 100755
--- a/azalea-nbt/src/decode.rs
+++ b/azalea-nbt/src/decode.rs
@@ -255,6 +255,9 @@ impl Nbt {
}
/// Read the NBT data. This will return a compound tag with a single item.
+ ///
+ /// Minecraft usually uses this function when reading from files.
+ /// [`Nbt::read_any_tag`] is used when reading from the network.
pub fn read(stream: &mut Cursor<&[u8]>) -> Result<Nbt, Error> {
// default to compound tag
@@ -271,6 +274,17 @@ impl Nbt {
Ok(Nbt::Compound(map))
}
+ /// Read the NBT data. There is no guarantee that the tag will be a compound
+ /// with a single item.
+ ///
+ /// The Minecraft protocol uses this function when reading from the network.
+ /// [`Nbt::read`] is usually used when reading from files.
+ pub fn read_any_tag(stream: &mut Cursor<&[u8]>) -> Result<Nbt, Error> {
+ let tag_id = stream.read_u8().unwrap_or(0);
+ let tag = Nbt::read_known(stream, tag_id)?;
+ Ok(tag)
+ }
+
/// Read the NBT data compressed wtih zlib.
pub fn read_zlib(stream: &mut impl BufRead) -> Result<Nbt, Error> {
let mut gz = ZlibDecoder::new(stream);
@@ -290,7 +304,7 @@ impl Nbt {
impl McBufReadable for Nbt {
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
- Ok(Nbt::read(buf)?)
+ Ok(Nbt::read_any_tag(buf)?)
}
}
impl From<Error> for BufReadError {
diff --git a/azalea-nbt/src/encode.rs b/azalea-nbt/src/encode.rs
index 76b70b6e..34c451d2 100755
--- a/azalea-nbt/src/encode.rs
+++ b/azalea-nbt/src/encode.rs
@@ -16,51 +16,55 @@ fn write_compound(writer: &mut impl Write, value: &NbtCompound, end_tag: bool) {
for (key, tag) in value.iter() {
writer.write_u8(tag.id()).unwrap();
write_string(writer, key);
- match tag {
- Nbt::End => {}
- Nbt::Byte(value) => {
- writer.write_i8(*value).unwrap();
- }
- Nbt::Short(value) => {
- writer.write_i16::<BE>(*value).unwrap();
- }
- Nbt::Int(value) => {
- writer.write_i32::<BE>(*value).unwrap();
- }
- Nbt::Long(value) => {
- writer.write_i64::<BE>(*value).unwrap();
- }
- Nbt::Float(value) => {
- writer.write_f32::<BE>(*value).unwrap();
- }
- Nbt::Double(value) => {
- writer.write_f64::<BE>(*value).unwrap();
- }
- Nbt::ByteArray(value) => {
- write_byte_array(writer, value);
- }
- Nbt::String(value) => {
- write_string(writer, value);
- }
- Nbt::List(value) => {
- write_list(writer, value);
- }
- Nbt::Compound(value) => {
- write_compound(writer, value, true);
- }
- Nbt::IntArray(value) => {
- write_int_array(writer, value);
- }
- Nbt::LongArray(value) => {
- write_long_array(writer, value);
- }
- }
+ write_known(writer, tag);
}
if end_tag {
writer.write_u8(END_ID).unwrap();
}
}
+fn write_known(writer: &mut impl Write, tag: &Nbt) {
+ match tag {
+ Nbt::End => {}
+ Nbt::Byte(value) => {
+ writer.write_i8(*value).unwrap();
+ }
+ Nbt::Short(value) => {
+ writer.write_i16::<BE>(*value).unwrap();
+ }
+ Nbt::Int(value) => {
+ writer.write_i32::<BE>(*value).unwrap();
+ }
+ Nbt::Long(value) => {
+ writer.write_i64::<BE>(*value).unwrap();
+ }
+ Nbt::Float(value) => {
+ writer.write_f32::<BE>(*value).unwrap();
+ }
+ Nbt::Double(value) => {
+ writer.write_f64::<BE>(*value).unwrap();
+ }
+ Nbt::ByteArray(value) => {
+ write_byte_array(writer, value);
+ }
+ Nbt::String(value) => {
+ write_string(writer, value);
+ }
+ Nbt::List(value) => {
+ write_list(writer, value);
+ }
+ Nbt::Compound(value) => {
+ write_compound(writer, value, true);
+ }
+ Nbt::IntArray(value) => {
+ write_int_array(writer, value);
+ }
+ Nbt::LongArray(value) => {
+ write_long_array(writer, value);
+ }
+ }
+}
+
#[inline]
fn write_list(writer: &mut impl Write, value: &NbtList) {
writer.write_u8(value.id()).unwrap();
@@ -256,6 +260,13 @@ impl Nbt {
}
}
+ /// Write any tag as NBT data. This is used by Minecraft when writing to the
+ /// network, otherwise [`Nbt::write`] is usually used instead.
+ pub fn write_any(&self, writer: &mut impl Write) {
+ writer.write_u8(self.id()).unwrap();
+ write_known(writer, self);
+ }
+
/// Write the compound tag as NBT data compressed wtih zlib.
///
/// # Errors
@@ -279,7 +290,7 @@ impl Nbt {
impl McBufWritable for Nbt {
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- self.write(buf);
+ self.write_any(buf);
Ok(())
}
}
diff --git a/azalea-nbt/src/tag.rs b/azalea-nbt/src/tag.rs
index efb6bdd2..224db2d3 100755
--- a/azalea-nbt/src/tag.rs
+++ b/azalea-nbt/src/tag.rs
@@ -226,6 +226,16 @@ impl NbtCompound {
self.inner.len() >= 32
}
}
+
+impl IntoIterator for NbtCompound {
+ type Item = (NbtString, Nbt);
+ type IntoIter = std::vec::IntoIter<Self::Item>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.inner.into_iter()
+ }
+}
+
#[cfg(feature = "serde")]
impl Serialize for NbtCompound {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {