minecraftでデータファイルを書き換えクラッシュの原因となるブロックを置換する

minecraftでとあるmodを入れた所、modに不具合があり、とあるブロックを置いて操作をするとminecraftがクラッシュして、二度と起動しなくなってしまった（正確にはサーバの起動はできるが、プレイヤーがログインするとクラッシュするようになってしまった）。

minecraftのバージョンは1.12.2-forgeだ

クラッシュレポートには以下のように問題となったブロックの場所が書いてある

```

-- Head --
Thread: Server thread
Stacktrace:
        at com.legacy.aether.tile_entities.TileEntityFreezer.func_73660_a(TileEntityFreezer.java:83)

-- Block entity being ticked --
Details:
        Name: minecraft:aether_legacy_freezer // com.legacy.aether.tile_entities.TileEntityFreezer
        Block type: ID #276 (tile.freezer // com.legacy.aether.blocks.container.BlockFreezer)
        Block data value: 0 / 0x0 / 0b0000
        Block location: World: (-436,96,-1558), Chunk: (at 12,6,10 in -28,-98; contains blocks -448,0,-1568 to -433,255,-1553), Region: (-1,-4; contains chunks -32,-128 to -1,-97, blocks -512,0,-2048 to -1,255,-1537)
        Actual block type: ID #276 (tile.freezer // com.legacy.aether.blocks.container.BlockFreezer)
        Actual block data value: 0 / 0x0 / 0b0000
Stacktrace:
        at net.minecraft.world.World.func_72939_s(World.java:1832)
        at net.minecraft.world.WorldServer.func_72939_s(WorldServer.java:612)
```

これを見ると、`Block type ID #276`のブロックで問題が起きており、
そのブロックの場所は`World: (-436,96,-1558), Chunk: (at 12,6,10 in -28,-98; contains blocks -448,0,-1568 to -433,255,-1553), Region: (-1,-4; contains chunks -32,-128 to -1,-97, blocks -512,0,-2048 to -1,255,-1537)`であることがわかる

そこでminecraftのデータファイルを書き換えて、問題のブロックを別のブロックに書き換えて、クラッシュしないように試みた。

minecraftのデータの在り処だが、設定`level-name`で指定したディレクトリの、dimensionディレクトリ(DIM1等)の中、regionディレクトリの中にある.mcaファイルが実態だ。

```
(level-name設定値)
　└(dimension名)
　　└ region
  　　└ r.-1.-3.mca
  　　└ r.-1.-4.mca
```

このmcaというファイルのフォーマットはminecraft anvil フォーマットであり、その仕様は公式HPに書いてある→[公式HP](https://minecraft-ja.gamepedia.com/Chunk%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88)

このmcaファイルはNBTフォーマットらしく、中を見るには、[NBTExplorer](http://www.minecraftforum.net/forums/mapping-and-modding-java-edition/minecraft-tools/1262665-nbtexplorer-nbt-editor-for-windows-and-mac)が必要。

まずこれをダウンロードしてインストールする。

NBTExplorer起動したらOpenFolderで、minecraftサーバにあるDimensionディレクトリをオープンする。

オープンするとこんな感じ

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/33447/a02f79ea-cf3e-d1ca-e09e-9d088a22a8a8.png)

さてここから問題ブロックが書かれた場所を特定するのだが、regionの特定、chunkの特定、sectionの特定の順番で絞り込んでいく。

まずregionだが、クラッシュレポートにある`Region: (-1,-4; `という文字がregionの場所を表しているため、`r.-1.-4.mca`を+マークでドリルダウンする

次にchunkだが、`Chunk: (at 12,6,10 in -28,-98; ` にあるin -28, -98というのを手がかりに探して+マークでドリルダウンする

最後にsectionだが、チャンクの中はsectionという単位で16個に別れている。Yが0のsectionが一番下(地面)のデータでY=0~15までのデータを、Yが1のsectionがY=16～31までのデータを、そしてYが15のsectionが最も上のY=240~255データを格納している。問題となったブロックはy座標96にあるので、Yが6のセクションに入っているので+マークでドリルダウンする。

ここまでドリルダウンすると↓のような感じになる

![キャプチャ2.PNG](https://qiita-image-store.s3.amazonaws.com/0/33447/a7980b09-44ba-bbf2-dee5-f227e176b0f1.png)

最後に問題のブロックを特定するのだが、Blocksというキーの場所に各座標のブロックIDの下位8bitが、Addというキーの場所に各座標のブロックIDの上位4bitが格納されている。

今回問題となったブロックのIDは276なので、下位8bitは0x14 (0001 0100) 、上位4bitは0x01(0001)である。

なのでBlocksの中には0x14で現れるはずである。

Blocksの中のデータの格納順は、x座標、z座標、y座標の順番に格納されている。

このチャンクには`contains blocks -448,0,-1568 to -433,255,-1553)`と書かれていることから、(-448,0,-1568)から(-433,255,-1553)のブロックが格納されている。

なので、このsectionには(-448,96,-1568)から(-433,111,-1553)のブロックが格納されている。

なのでBlocksのデータは、左上から順に(-448,96,-1568),(-447,96,-1568),(-446,96,-1568)・・・となる。

問題のブロックは (-436,96,-1558)であるため、左から12番目、上から10番目になる↓

![キャプチャ3.PNG](https://qiita-image-store.s3.amazonaws.com/0/33447/fa59af9a-d275-7465-c89e-620c2e5c5e5c.png)

たしか、２つとなりにロングチェスト(アイテムID=36)をおいたことは覚えているため、間違いなさそうだ。
（このバイナリのプレビューモードは横が16であるため、この16進数の並びはminecraftにおける上から眺めたマップの断面図になっている。）

特定できたため、0x14を0x00に書き換えてやることにより、アイテムIDは0001 0000 0000に書き換わり、無害なものとなった。

書き換えた後は上書き保存すれば.mcaファイルが更新される。

これで起動することにより、無事問題のブロックが置き換えられ、minecraftをプレイすることが出来るようになった！