Rust 2021 edition、MSRV 1.75です。
Cargo.tomlにgit参照を書きます。
以下の<版>は、使うリリースの版(Releasesのタグ名から先頭のvを除いたもの)に読み替えてください。
[dependencies]
spring-nbt-library = { git = "https://github.com/ScriptArts/SpringNBTLibrary", tag = "v<版>" }Cargoが自分で取得します。
ネットワークに繋がらない環境なら、Releasesのspring-nbt-library-<版>.crate(拡張子が違うだけのtar.gz)を展開してパス参照します。
tar xzf spring-nbt-library-<版>.crate[dependencies]
spring-nbt-library = { path = "spring-nbt-library-<版>" }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()?;use spring_nbt_library::world::{BlockState, MinecraftWorld, WorldOpenOptions};
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)。