Merge pull request #2 from conch2/fixlist

修复在Java中当Compound作为List元素时的读取和写入bug
This commit is contained in:
shenjack 2024-07-03 21:20:58 +08:00 committed by GitHub
commit bf87b48ca6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 32 additions and 16 deletions

View File

@ -63,10 +63,14 @@ pub mod nbt_version {
fn write_i64_array(writer: &mut Vec<u8>, data: &[i64]);
fn write_nbt_string(writer: &mut Vec<u8>, data: &str);
fn write_list(writer: &mut Vec<u8>, data: &[NbtValue]) -> NbtResult<()>;
/// 向 `writer` 写入一个复合标签类型(Compound)
///
/// * `is_list_element` 用于指示是否为列表元素。当复合标签类型为列表元素时是不用将名称写入的。
fn write_compound(
writer: &mut Vec<u8>,
name: Option<&String>,
data: &[(String, NbtValue)],
is_list_element: bool,
) -> NbtResult<()>;
fn write_to(value: &NbtValue, buff: &mut Vec<u8>) -> NbtResult<()>;

View File

@ -57,7 +57,7 @@ impl nbt_version::NbtReadTrait for nbt_version::Java {
7 => NbtValue::ByteArray(Java::read_i8_array(reader)?),
8 => NbtValue::String(Java::read_nbt_string(reader)?),
9 => NbtValue::List(Java::read_list(reader)?),
10 => NbtValue::Compound(None, nbt_version::Java::read_compound(reader)?),
10 => NbtValue::Compound(Some(name.clone()), nbt_version::Java::read_compound(reader)?),
11 => NbtValue::IntArray(Java::read_i32_array(reader)?),
12 => NbtValue::LongArray(Java::read_i64_array(reader)?),
_ => return Err(NbtError::UnknownType(tag_id)),

View File

@ -43,6 +43,8 @@ impl NbtWriteTrait for Java {
if data.is_empty() {
// 写入一个空的 tag
writer.extend_from_slice(&0i8.to_be_bytes());
// 写入空长度
writer.extend_from_slice(&0i32.to_be_bytes());
return Ok(());
}
// 遍历检查一遍所有的 tag 是否一致
@ -69,7 +71,7 @@ impl NbtWriteTrait for Java {
NbtValue::String(x) => Self::write_nbt_string(writer, x),
NbtValue::List(x) => Self::write_list(writer, x)?,
NbtValue::Compound(name, data) => {
Self::write_compound(writer, name.as_ref(), data)?
Self::write_compound(writer, name.as_ref(), data, true)?
}
}
}
@ -80,14 +82,21 @@ impl NbtWriteTrait for Java {
writer: &mut Vec<u8>,
name: Option<&String>,
data: &[(String, NbtValue)],
is_list_element: bool,
) -> NbtResult<()> {
// 写入自己的名字
Self::write_nbt_string(writer, name.unwrap_or(&"".to_string()));
// 如果是列表元素时不用写入名字和key
if !is_list_element {
// 写入自己的名字
Self::write_nbt_string(writer, name.unwrap_or(&"".to_string()));
}
for (key, value) in data {
// 写入 tag
writer.push(value.tag());
// 写入 key
Self::write_nbt_string(writer, key);
// 写入 key如果是Compound就不写入因为key就是名字
if let NbtValue::Compound(_, _) = value {}
else {
Self::write_nbt_string(writer, key)
};
// 写入 value
match value {
NbtValue::Byte(x) => writer.push(*x as u8),
@ -102,7 +111,7 @@ impl NbtWriteTrait for Java {
NbtValue::String(x) => Self::write_nbt_string(writer, x),
NbtValue::List(x) => Self::write_list(writer, x)?,
NbtValue::Compound(name, data) => {
Self::write_compound(writer, name.as_ref(), data)?
Self::write_compound(writer, name.as_ref(), data, false)?
}
}
}
@ -115,7 +124,7 @@ impl NbtWriteTrait for Java {
match value {
NbtValue::Compound(name, data) => {
buff.push(value.tag());
Self::write_compound(buff, name.as_ref(), data)?
Self::write_compound(buff, name.as_ref(), data, false)?
}
x => return Err(NbtError::WrongRootType(x.tag())),
}
@ -150,8 +159,9 @@ impl NbtWriteTrait for JavaNetAfter1_20_2 {
writer: &mut Vec<u8>,
name: Option<&String>,
data: &[(String, NbtValue)],
is_list_element: bool,
) -> NbtResult<()> {
Java::write_compound(writer, name, data)
Java::write_compound(writer, name, data, is_list_element)
}
#[inline]
fn write_to(value: &NbtValue, buff: &mut Vec<u8>) -> NbtResult<()> {
@ -179,7 +189,7 @@ impl NbtWriteTrait for JavaNetAfter1_20_2 {
NbtValue::String(x) => Self::write_nbt_string(buff, x),
NbtValue::List(x) => Self::write_list(buff, x)?,
NbtValue::Compound(name, data) => {
Self::write_compound(buff, name.as_ref(), data)?
Self::write_compound(buff, name.as_ref(), data, false)?
}
}
}
@ -268,7 +278,7 @@ impl NbtWriteTrait for BedrockDisk {
NbtValue::String(x) => Self::write_nbt_string(writer, x),
NbtValue::List(x) => Self::write_list(writer, x)?,
NbtValue::Compound(name, data) => {
Self::write_compound(writer, name.as_ref(), data)?
Self::write_compound(writer, name.as_ref(), data, true)?
}
}
}
@ -279,6 +289,7 @@ impl NbtWriteTrait for BedrockDisk {
writer: &mut Vec<u8>,
name: Option<&String>,
data: &[(String, NbtValue)],
_is_list_element: bool,
) -> NbtResult<()> {
// 写入自己的名字
Self::write_nbt_string(writer, name.unwrap_or(&"".to_string()));
@ -301,7 +312,7 @@ impl NbtWriteTrait for BedrockDisk {
NbtValue::String(x) => Self::write_nbt_string(writer, x),
NbtValue::List(x) => Self::write_list(writer, x)?,
NbtValue::Compound(name, data) => {
Self::write_compound(writer, name.as_ref(), data)?
Self::write_compound(writer, name.as_ref(), data, false)?
}
}
}
@ -315,7 +326,7 @@ impl NbtWriteTrait for BedrockDisk {
match value {
NbtValue::Compound(name, data) => {
buff.push(value.tag());
Self::write_compound(buff, name.as_ref(), data)?
Self::write_compound(buff, name.as_ref(), data, false)?
}
NbtValue::List(data) => {
buff.push(value.tag());
@ -467,7 +478,7 @@ impl NbtWriteTrait for BedrockNetVarInt {
NbtValue::String(x) => Self::write_nbt_string(writer, x),
NbtValue::List(x) => Self::write_list(writer, x)?,
NbtValue::Compound(name, data) => {
Self::write_compound(writer, name.as_ref(), data)?
Self::write_compound(writer, name.as_ref(), data, true)?
}
}
}
@ -477,6 +488,7 @@ impl NbtWriteTrait for BedrockNetVarInt {
writer: &mut Vec<u8>,
name: Option<&String>,
data: &[(String, NbtValue)],
_is_list_element: bool,
) -> NbtResult<()> {
// 写入自己的名字
Self::write_nbt_string(writer, name.unwrap_or(&"".to_string()));
@ -499,7 +511,7 @@ impl NbtWriteTrait for BedrockNetVarInt {
NbtValue::String(x) => Self::write_nbt_string(writer, x),
NbtValue::List(x) => Self::write_list(writer, x)?,
NbtValue::Compound(name, data) => {
Self::write_compound(writer, name.as_ref(), data)?
Self::write_compound(writer, name.as_ref(), data, false)?
}
}
}
@ -513,7 +525,7 @@ impl NbtWriteTrait for BedrockNetVarInt {
match value {
NbtValue::Compound(name, data) => {
buff.push(value.tag());
Self::write_compound(buff, name.as_ref(), data)?
Self::write_compound(buff, name.as_ref(), data, false)?
}
NbtValue::List(data) => {
buff.push(value.tag());