📂
BukkitプラグインでNBTデータをファイル保存する
プラグインを作っている最中にクリックイベントなどがついた本を保存しなければならない機会があり、NBT データごと保存するのに手こずったので備忘録。
注意事項
この記事に記載されている内容を実行し、発生したいかなる問題について執筆者は一切責任を負いません。自己責任でお願いします。
環境
- Minecraft 1.12.2(後述するリフレクションを使用する方法であれば 1.16.5 等でも使用可能)
- CraftBukkit version: Git-Spigot-642f6d2-ab13683
- APIVersion: 1.12.2-R0.1-SNAPSHOT
CraftBukkit が Maven に追加できる場合
Maven への詳しい説明はしませんが、CraftBukkit を何かしらの手段で Maven に追加できる場合はこの方法が楽です。(Spigot)
セーブ
保存は簡単。
- まず、
org.bukkit.inventory.ItemStack
からnet.minecraft.server.v1_12_R1.ItemStack
に変換する必要があるので、org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack
のasNMSCopy
メソッドを使う。 - 取得した ItemStack から、
net.minecraft.server.v1_12_R1.NBTTagCompound
を得るためにnmsItem.getTag()
を使う。 - 取得した
NBTTagCompound
をtoString()
する。 -
toString()
で取得できた String が NBT タグ情報。適当に保存する。
保存は YamlConfiguration(FileConfiguration)
で保存するなり、FileWriter
を使って保存してもよし。
なお、ここで取得した NBT タグ情報は /give
のデータタグと同じなので、1.12.2 なら /give @p <item> 1 0 <NBTタグ>
で give できる。
ItemStack item = player.getInventory().getItemInMainHand(); // ここでは例としてプレイヤーのメインハンドのアイテムを取得。
net.minecraft.server.v1_12_R1.ItemStack nmsItem = CraftItemStack.asNMSCopy(item); // 1
NBTTagCompound nbttag = nmsItem.getTag(); // 2
String tag = nbttag.toString(); // 3
save(tag); // 4
ロード
- セーブの 4 で保存したものをロードする。
YamlConfiguration.loadConfiguration
とかFileReader
とか。 - ロードした NBT タグを保持させる
net.minecraft.server.v1_12_R1.ItemStack
を作る。getById
なのでアイテムの数値 ID を使う。(記入済みの本なら387
など) -
MojangsonParser
を使って NBT タグをパースする。net.minecraft.server.v1_12_R1.NBTBase
が返る。 - 2 で作った
ItemStack
に NBT タグを設定する。この際NBTTagCompound
にキャストする。 -
net.minecraft.server.v1_12_R1.ItemStack
からorg.bukkit.inventory.ItemStack
に変換するためにorg.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack
のasBukkitCopy
メソッドを使う。
String tag = load(); // 1
net.minecraft.server.v1_12_R1.ItemStack nmsItem = new net.minecraft.server.v1_12_R1.ItemStack(Item.getById(1)); // 2
NBTBase nbtbase = MojangsonParser.parse(tag); // 3
nmsItem.setTag((NBTTagCompound) nbtbase); // 4
ItemStack item = CraftItemStack.asBukkitCopy(nmsItem); // 5
CraftBukkit が Maven に追加できない場合
CraftBukkit を Maven に追加できない場合(複数人開発で BuildTools を強制できないなど)の場合はリフレクションを使って頑張るしかありません。
以下は、私が作った ItemStack から NBT タグを取得できるようにしたライブラリコードの Gist リンクです。
これをプロジェクトに追加し、 NMSManager.getNBT(ItemStack)
を実行すれば String で NBT タグの文字列が返ってきます。
Discussion