Rust 2021 edition、MSRV 1.75 です。
Cargo.toml に git 参照を書きます。
[dependencies]
spring-nbt-library = { git = "https://github.com/ScriptArts/SpringNBTLibrary", tag = "v1.0.0" }Cargo が自分で取得します。
ネットワークに繋がらない環境なら、Releases の
spring-nbt-library-<版>.crate(拡張子が違うだけの tar.gz)を展開してパス参照します。
tar xzf spring-nbt-library-1.0.0.crate[dependencies]
spring-nbt-library = { path = "spring-nbt-library-1.0.0" }Rust 版だけは例外ではなく Result<T, Error> を返します。
ErrorCode の集合は他言語と完全に一致します(adr/0005)。
use spring_nbt_library::error::{ErrorCode, Result};use spring_nbt_library::nbt::{read_file, NbtReadOptions};
// 圧縮方式(Gzip / Zlib / 無圧縮)は自動で判定される
let named = read_file("level.dat", &NbtReadOptions::default())?;
let data = named.tag.get_compound("Data")?;
println!("{}", data.get_string("LevelName")?);
println!("{}", data.get_int("DataVersion")?);型が違えば ErrorCode::UnexpectedTagType が返ります。
キーが無いかもしれないときは opt_* を使います(無ければ Ok(None))。
use spring_nbt_library::nbt::tag::{NbtCompound, NbtString, NbtTag};
use spring_nbt_library::nbt::{write_file, Compression, NamedTag, NbtWriteOptions};
let mut root = NbtCompound::new();
root.set("name", NbtTag::String(NbtString::new("SpringNBTLibrary")));
root.set("count", NbtTag::Int(42));
let options = NbtWriteOptions { compression: Compression::Gzip, ..Default::default() };
write_file("out.nbt", &NamedTag::new("", root), &options)?;Rust の String は UTF-8 に限られるので、NBT に現れうる孤立サロゲートを保持できません。
そこで NbtString を列挙にしています(spec/10 2.3)。
pub enum NbtString {
Text(String), // 通常の文字列。実データはほぼすべてこちら
Surrogates(Vec<u16>), // UTF-8 に写せない UTF-16 コード単位の列
}use spring_nbt_library::world::{MinecraftWorld, WorldOpenOptions};
let mut world = MinecraftWorld::open(world_path, WorldOpenOptions::default())?;
if let Some(overworld) = world.dimension("minecraft:overworld")? {
// 絶対座標。リージョンとチャンクの解決は内部で行う
if let Some(block) = overworld.get_block(100, 64, -200)? {
println!("{block}"); // minecraft:grass_block[snowy=false]
}
}
world.close()?;let options = WorldOpenOptions { writable: true, ..Default::default() };
let mut world = MinecraftWorld::open(world_path, options)?;
if let Some(overworld) = world.dimension("minecraft:overworld")? {
let stone = BlockState::parse("minecraft:stone")?;
overworld.set_block(100, 64, -200, &stone)?;
overworld.flush()?; // ここで初めてディスクへ書かれる
}
world.close()?;Minecraft を終了してから実行すること。 Rust 版は
stdにファイルロックが無いためsession.lockは確認しません(adr/0008)。 起動していないことは呼び出し側で担保してください。
ブロックを置き換えても Heightmaps と光源は再計算されません(adr/0004)。
NBT のネストは既定で深さ 512 まで許します。 debug ビルドでは 1 段あたり約 8 KB 使うので、 深いデータを扱うなら大きめのスタックを持つスレッドで走らせてください (spec/00 5.1)。