Skip to content

Commit

Permalink
fix edge case with reading FormattedText as nbt
Browse files Browse the repository at this point in the history
  • Loading branch information
mat-1 committed Apr 20, 2024
1 parent f919fb6 commit 0ddad8b
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 57 deletions.
139 changes: 82 additions & 57 deletions azalea-chat/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,65 +308,89 @@ impl simdnbt::FromNbtTag for FormattedText {
} else if let Some(translate) = compound.get("translate") {
let translate = translate.string()?.into();
if let Some(with) = compound.get("with") {
let with = with.list()?.compounds()?;
let mut with_array = Vec::with_capacity(with.len());
for item in with {
// if it's a string component with no styling and no siblings, just add
// a string to with_array otherwise add the
// component to the array
if let Some(primitive) = item.get("") {
// minecraft does this sometimes, for example
// for the /give system messages
match primitive {
simdnbt::borrow::NbtTag::Byte(b) => {
// interpreted as boolean
with_array.push(StringOrComponent::String(
if *b != 0 { "true" } else { "false" }.to_string(),
let mut with_array = Vec::new();
match with.list()? {
simdnbt::borrow::NbtList::Empty => {}
simdnbt::borrow::NbtList::String(with) => {
for item in with {
with_array.push(StringOrComponent::String(item.to_string()));
}
}
simdnbt::borrow::NbtList::Compound(with) => {
for item in with {
// if it's a string component with no styling and no siblings,
// just add a string to
// with_array otherwise add the
// component to the array
if let Some(primitive) = item.get("") {
// minecraft does this sometimes, for example
// for the /give system messages
match primitive {
simdnbt::borrow::NbtTag::Byte(b) => {
// interpreted as boolean
with_array.push(StringOrComponent::String(
if *b != 0 { "true" } else { "false" }
.to_string(),
));
}
simdnbt::borrow::NbtTag::Short(s) => {
with_array
.push(StringOrComponent::String(s.to_string()));
}
simdnbt::borrow::NbtTag::Int(i) => {
with_array
.push(StringOrComponent::String(i.to_string()));
}
simdnbt::borrow::NbtTag::Long(l) => {
with_array
.push(StringOrComponent::String(l.to_string()));
}
simdnbt::borrow::NbtTag::Float(f) => {
with_array
.push(StringOrComponent::String(f.to_string()));
}
simdnbt::borrow::NbtTag::Double(d) => {
with_array
.push(StringOrComponent::String(d.to_string()));
}
simdnbt::borrow::NbtTag::String(s) => {
with_array
.push(StringOrComponent::String(s.to_string()));
}
_ => {
warn!("couldn't parse {item:?} as FormattedText because it has a disallowed primitive");
with_array.push(StringOrComponent::String(
"?".to_string(),
));
}
}
} else if let Some(c) = FormattedText::from_nbt_tag(
&simdnbt::borrow::NbtTag::Compound(item.clone()),
) {
if let FormattedText::Text(text_component) = c {
if text_component.base.siblings.is_empty()
&& text_component.base.style.is_empty()
{
with_array.push(StringOrComponent::String(
text_component.text,
));
continue;
}
}
with_array.push(StringOrComponent::FormattedText(
FormattedText::from_nbt_tag(
&simdnbt::borrow::NbtTag::Compound(item.clone()),
)?,
));
}
simdnbt::borrow::NbtTag::Short(s) => {
with_array.push(StringOrComponent::String(s.to_string()));
}
simdnbt::borrow::NbtTag::Int(i) => {
with_array.push(StringOrComponent::String(i.to_string()));
}
simdnbt::borrow::NbtTag::Long(l) => {
with_array.push(StringOrComponent::String(l.to_string()));
}
simdnbt::borrow::NbtTag::Float(f) => {
with_array.push(StringOrComponent::String(f.to_string()));
}
simdnbt::borrow::NbtTag::Double(d) => {
with_array.push(StringOrComponent::String(d.to_string()));
}
simdnbt::borrow::NbtTag::String(s) => {
with_array.push(StringOrComponent::String(s.to_string()));
}
_ => {
warn!("couldn't parse {item:?} as FormattedText because it has a disallowed primitive");
} else {
warn!("couldn't parse {item:?} as FormattedText");
with_array.push(StringOrComponent::String("?".to_string()));
}
}
} else if let Some(c) = FormattedText::from_nbt_tag(
&simdnbt::borrow::NbtTag::Compound(item.clone()),
) {
if let FormattedText::Text(text_component) = c {
if text_component.base.siblings.is_empty()
&& text_component.base.style.is_empty()
{
with_array
.push(StringOrComponent::String(text_component.text));
continue;
}
}
with_array.push(StringOrComponent::FormattedText(
FormattedText::from_nbt_tag(
&simdnbt::borrow::NbtTag::Compound(item.clone()),
)?,
));
} else {
warn!("couldn't parse {item:?} as FormattedText");
with_array.push(StringOrComponent::String("?".to_string()));
}
_ => {
warn!("couldn't parse {with:?} as FormattedText because it's not a list of compounds");
return None;
}
}
component = FormattedText::Translatable(TranslatableComponent::new(
Expand Down Expand Up @@ -448,8 +472,9 @@ impl McBufReadable for FormattedText {
fn read_from(buf: &mut std::io::Cursor<&[u8]>) -> Result<Self, BufReadError> {
let nbt = simdnbt::borrow::NbtTag::read_optional(buf)?;
if let Some(nbt) = nbt {
FormattedText::from_nbt_tag(&nbt)
.ok_or(BufReadError::Custom("couldn't read nbt".to_owned()))
FormattedText::from_nbt_tag(&nbt).ok_or(BufReadError::Custom(
"couldn't convert nbt to chat message".to_owned(),
))
} else {
Ok(FormattedText::default())
}
Expand Down
13 changes: 13 additions & 0 deletions azalea-protocol/src/packets/game/clientbound_system_chat_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,17 @@ mod tests {
"[py5: Gave 1 [Diamond Pickaxe] to py5]".to_string()
);
}

#[test]
fn test_translate_with_string_array_clientbound_system_chat_packet() {
#[rustfmt::skip]
let bytes = [
10, 9, 0, 4, 119, 105, 116, 104, 8, 0, 0, 0, 1, 0, 14, 109, 105, 110, 101, 99, 114, 97, 102, 116, 58, 100, 117, 115, 116, 8, 0, 9, 116, 114, 97, 110, 115, 108, 97, 116, 101, 0, 25, 99, 111, 109, 109, 97, 110, 100, 115, 46, 112, 97, 114, 116, 105, 99, 108, 101, 46, 115, 117, 99, 99, 101, 115, 115, 0, 0
];
let packet = ClientboundSystemChatPacket::read_from(&mut Cursor::new(&bytes)).unwrap();
assert_eq!(
packet.content.to_string(),
"Displaying particle minecraft:dust".to_string()
);
}
}

0 comments on commit 0ddad8b

Please sign in to comment.