Skip to content

Latest commit

 

History

History
137 lines (98 loc) · 4.49 KB

csharp.md

File metadata and controls

137 lines (98 loc) · 4.49 KB

はじめに(C#)

.NET 8 / C# 12以上が必要です。

C#は基準実装です。 仕様の解釈に迷ったら、まずここを見てください。

導入

Releasesに2通り置いてあります。 どちらでも中身は同じです。 以下の<版>は、使うリリースの版(Releasesのタグ名から先頭のvを除いたもの)に読み替えてください。

.nupkgを使う(おすすめ)

NuGetへは公開していないので、落としたファイルを置いたフォルダをソースとして教えます。

  1. SpringNBTLibrary.<版>.nupkgを、プロジェクト直下のpackages/へ置きます

  2. .csprojと同じ場所にnuget.configを作ります

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <packageSources>
        <add key="springnbt" value="packages" />
      </packageSources>
    </configuration>
  3. 参照に足します

    dotnet add package SpringNBTLibrary --version <版>

ドキュメントの置き場所はNuGetが面倒を見るので、補完に説明が出ます。 nuget.configをプロジェクトに置くのは、この設定をリポジトリで共有できるからです。 dotnet nuget add sourceは利用者ごとの設定を書き換えるので、他の人の手元では動きません。

.zipを使う

dllを直接参照したいときはこちらです。

  1. SpringNBTLibrary-<版>-dotnet8.zipを展開します。中身は次のとおりです

    SpringNBTLibrary.dll   ライブラリ本体
    SpringNBTLibrary.xml   ドキュメント(IDE の補完に出る)
    LICENSE / README.md
    
  2. プロジェクトの適当な場所(lib/など)へdllとxmlを隣り合わせで置きます。 xmlが無いと補完に説明が出ません

  3. .csprojから参照します

    <ItemGroup>
      <Reference Include="SpringNBTLibrary">
        <HintPath>lib/SpringNBTLibrary.dll</HintPath>
      </Reference>
    </ItemGroup>

NBTファイルを読む

using SpringNBTLibrary.Nbt;

// 圧縮方式(Gzip / Zlib / 無圧縮)は自動で判定される
NamedTag named = NbtIo.ReadFile("level.dat");
NbtCompound data = named.Tag.GetCompound("Data");

Console.WriteLine(data.GetString("LevelName"));
Console.WriteLine(data.GetInt("DataVersion"));

型が違えばUNEXPECTED_TAG_TYPEの例外になります。 キーが無いかもしれないときはOpt*を使います。

// 無ければ null。あるが型違いなら例外
string? name = data.OptString("LevelName");

書く

NbtCompound root = new NbtCompound();
root.Set("name", new NbtString("SpringNBTLibrary"));
root.Set("count", new NbtInt(42));

NbtIo.WriteFile("out.nbt", new NamedTag("", root),
    new NbtWriteOptions { Compression = Compression.Gzip });

ワールドのブロックを読む

using SpringNBTLibrary.World;

using MinecraftWorld world = MinecraftWorld.Open(worldPath);
Dimension? overworld = world.Dimension("minecraft:overworld");

if (overworld is not null)
{
    // 絶対座標。リージョンとチャンクの解決は内部で行う
    BlockState? block = overworld.GetBlock(100, 64, -200);
    Console.WriteLine(block);   // minecraft:grass_block[snowy=false]
}

ブロックを書き換える

書き込みは明示的に許可したときだけ行えます。

WorldOpenOptions options = new WorldOpenOptions { Writable = true };

using MinecraftWorld world = MinecraftWorld.Open(worldPath, options);
Dimension overworld = world.Dimension("minecraft:overworld")!;

overworld.SetBlock(100, 64, -200, BlockState.Parse("minecraft:stone"));
overworld.Flush();   // ここで初めてディスクへ書かれる

Minecraftを終了してから実行してください。 起動中のワールドへ書き込むとデータがおかしくなります。 C#版はsession.lockを確認して防いでいます(adr/0008)。

ブロックを置き換えてもHeightmapsと光源は再計算されません(adr/0004)。 Chunk.ClearHeightmaps() / InvalidateLighting()でゲーム側に再計算させてください。

次に読むもの