owengage / fastnbt

Fast serde serializer and deserializer for Minecraft's NBT and Anvil formats
MIT License
185 stars 35 forks source link

[Feature Request] Giving name for the root compound #102

Closed Jroid8 closed 5 months ago

Jroid8 commented 5 months ago

I have the following struct which represents a schematic

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "PascalCase")]
pub struct Schematic {
    blocks: ByteArray,
    data: ByteArray,
    tile_entities: Vec<Value>,
    entities: Vec<Value>,
    width: i16,
    height: i16,
    length: i16,
    materials: String,
}

But when I write it into a file I get the following error by WorldEdit "Tag 'Schematic' does not exist or is not first". Opening the file with an NBT Editor it shows me that the root compound's name is empty. Renaming the root compound to "Schematic" in the editor fixes the error. Is there a way to do this with fastnbt?

Jroid8 commented 5 months ago

adding

let mut bytes = fastnbt::to_bytes(&structure).unwrap();
bytes.splice(2..=2, b"\x09Schematic".to_owned());
bytes.extend([9,0]);

solved the issue temporarily

owengage commented 5 months ago

Hey, I don't think there's a built in way to do this at the moment. It doesn't neatly fit the serde data model as far I can tell, so it's not super clear how to add this.

Up until now it hasn't been a raised issue. It's good to have a real use for it. I will think on how to add this functionality.

owengage commented 5 months ago

fastnbt 2.5.0 now allows setting this with to_bytes_with_opts and to_writer_with_opts. There's some info in the ser module docs (once docs.rs catches up with 2.5 at least!).

You appear to be writing some bytes to the end of your output in your workaround. As far as I can tell that's not necessary, am I missing something? It's been a while since I took a hard look at NBT's format.

Jroid8 commented 5 months ago

I tested it now and it's working! Thank you very much 🌺

You appear to be writing some bytes to the end of your output in your workaround. As far as I can tell that's not necessary, am I missing something? It's been a while since I took a hard look at NBT's format.

I haven't ether so I don't know if it's necessary. I compared the correct schematic's binary with the generated one and saw it