Skip to content
This repository has been archived by the owner on Sep 13, 2023. It is now read-only.
/ fastnbt Public archive
forked from owengage/fastnbt

Fast serde serializer and deserializer for Minecraft's NBT and Anvil formats with patches for Rimecraft

License

Notifications You must be signed in to change notification settings

rimecraft-rs/fastnbt

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fastnbt project

fastnbt-shield fastnbt-version-shield fastnbt-docs-shield build-status-shield

fastanvil-shield fastanvil-version-shield fastanvil-docs-shield

FastNBT is a serde serializer and deserializer for Minecraft: Java Edition's NBT format, including Value type and nbt! macro.

FastAnvil allows rendering maps of worlds, and a Region for using the Region file format.

An in-browser Rust-to-WASM powered Minecraft map renderer demo is below. Supports 1.19 down to 1.15 inclusive. There is also a Tauri desktop UI application under app.

Demos

Demo of Hermitcraft season 8 and more at owengage.com/anvil

alt rendered map

The anvil binary from fastnbt-tools can render your world leveraging all of your CPU.

Examples

A bunch of examples can be found in fastnbt/examples, fastanvil/examples and tools/src. Some examples are recreated below.

Example: editing level.dat

The following edits the world spawn to 250, 200, 250 (probably not a good idea!). Full example in fastnbt/examples directory.

#[derive(Serialize, Deserialize)]
struct LevelDat {
    #[serde(rename = "Data")]
    data: Data,
}

#[derive(Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct Data {
    spawn_x: i32,
    spawn_y: i32,
    spawn_z: i32,

    #[serde(flatten)]
    other: HashMap<String, Value>,
}

fn main() {
    let args: Vec<_> = std::env::args_os().collect();
    let file = std::fs::File::open(&args[1]).unwrap();
    let mut decoder = GzDecoder::new(file);
    let mut bytes = vec![];
    decoder.read_to_end(&mut bytes).unwrap();

    let mut leveldat: LevelDat = fastnbt::from_bytes(&bytes).unwrap();

    leveldat.data.spawn_x = 250;
    leveldat.data.spawn_y = 200;
    leveldat.data.spawn_z = 250;

    let new_bytes = fastnbt::to_bytes(&leveldat).unwrap();
    let outfile = std::fs::File::create("level.dat").unwrap();
    let mut encoder = GzEncoder::new(outfile, Compression::fast());
    encoder.write_all(&new_bytes).unwrap();
}

Example: print player inventory

This example demonstrates printing out a players inventory and ender chest contents from the player dat files found in worlds. We

  • use serde's renaming attribute to have rustfmt conformant field names,
  • use lifetimes to save on string allocations, and
  • use the Value type to deserialize a field we don't specify the exact structure of.
#[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")]
struct PlayerDat<'a> {
    data_version: i32,

    #[serde(borrow)]
    inventory: Vec<InventorySlot<'a>>,
    ender_items: Vec<InventorySlot<'a>>,
}

#[derive(Deserialize, Debug)]
struct InventorySlot<'a> {
    id: &'a str,        // We avoid allocating a string here.
    tag: Option<Value>, // Also get the less structured properties of the object.

    // We need to rename fields a lot.
    #[serde(rename = "Count")]
    count: i8,
}

fn main() {
    let args: Vec<_> = std::env::args().skip(1).collect();
    let file = std::fs::File::open(args[0].clone()).unwrap();

    // Player dat files are compressed with GZip.
    let mut decoder = GzDecoder::new(file);
    let mut data = vec![];
    decoder.read_to_end(&mut data).unwrap();

    let player: Result<PlayerDat> = from_bytes(data.as_slice());

    println!("{:#?}", player);
}

Usage

For the libraries

[dependencies]
fastnbt = "2"
fastanvil = "0.26"

For the anvil executable

cargo install fastnbt-tools

About

Fast serde serializer and deserializer for Minecraft's NBT and Anvil formats with patches for Rimecraft

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Rust 100.0%