プラグインを作っている最中にクリックイベントなどがついた本を保存しなければならない機会があり、NBTデータごと保存するのに手こずったので備忘録。

環境

  • Minecraft 1.12.2
  • CraftBukkit version: git-Spigot-642f6d2-ab13683
  • APIVersion: 1.12.2-R0.1-SNAPSHOT

セーブ

保存は簡単。

  1. まず、org.bukkit.inventory.ItemStackからnet.minecraft.server.v1_12_R1.ItemStackに変換する必要があるので、org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStackasNMSCopyメソッドを使う。
  2. 取得したItemStackから、net.minecraft.server.v1_12_R1.NBTTagCompoundを得るためにnmsItem.getTag()を使う。
  3. 取得したNBTTagCompoundtoString()する。
  4. 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

ロード

  1. セーブの4で保存したものをロードする。YamlConfiguration.loadConfigurationとかFileReaderとか。
  2. ロードしたNBTタグを保持させるnet.minecraft.server.v1_12_R1.ItemStackを作る。getByIdなのでアイテムの数値IDを使う。(記入済みの本なら387など)
  3. MojangsonParserを使ってNBTタグをパースする。net.minecraft.server.v1_12_R1.NBTBaseが返る。
  4. 2で作ったItemStackにNBTタグを設定する。この際NBTTagCompoundにキャストする。
  5. net.minecraft.server.v1_12_R1.ItemStackからorg.bukkit.inventory.ItemStackに変換するためにorg.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStackasBukkitCopyメソッドを使う。
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
Categories: 備忘録