По-другому даже не знаю как. Это, скорее всего, невозможно.
Ну... так-то вроде можно... но я не знаю, правильно ли это.
Когда я целый день гуглил по этому вопросу, я наткнулся на одно решение:
Код:
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.setLore(Arrays.asList("One", ChatColor.BOLD + "NYAN"));
itemStack.setItemMeta(itemMeta);
net.minecraft.server.v1_7_R3.ItemStack nms = CraftItemStack.asNMSCopy(itemStack);
NBTTagCompound tag;
if(nms.tag != null)
tag = nms.tag;
else
{
nms.tag = new NBTTagCompound();
tag = nms.tag;
}
tag.setInt("MyKek", 546);
itemStack = CraftItemStack.asCraftMirror(nms);
После чего я кинулся на гитхабе изучать код CraftBukkit'а, а если точнее, именно эти классы.
И решение было почти получено, но есть одно "но". В коде выше, мы не изменяем существующий ItemStack, а "пересоздаем" новый. А это не всегда удобно, особенно если нам надо изменить ItemStack в каком-нибудь событии, которое передано в аргументы события.
Но CraftBukkit очень гадкий. Он не дает расширить CraftItemMeta чтоб написать своё кастомное Meta поле.
Плюс ко всему, класс CraftItemStack (реализующий интерфейс ItemStack) тоже не дает никак получить meta информацию в виде Map<String, Object> (хотя сам где-то внутри себя хранит...).
Со временем, мне пришла в голову идея следующего кода:
Код:
CraftItemStack craftItemStack = (CraftItemStack) itemStack;
try {
Class c = craftItemStack.getClass();
Field nameField = c.getDeclaredField("handle");
nameField.setAccessible(true);
net.minecraft.server.v1_7_R3.ItemStack handle = (net.minecraft.server.v1_7_R3.ItemStack) nameField.get(craftItemStack);
NBTTagCompound tag;
if(handle.tag != null)
tag = handle.tag;
else
{
handle.tag = new NBTTagCompound();
tag = handle.tag;
}
if (tag.hasKey("MySuperLevel")) {
player.sendMessage("HAS KEY: " + tag.getInt("MySuperLevel"));
}
tag.setInt("MySuperLevel", 228);
player.sendMessage(craftItemStack.toString());
} catch (Exception e) {
e.printStackTrace();
}
Так как поле handle было приватным, я решил сделать его публичным. А затем получаю его и изменяю NBTTagCompound как хочу. И это тоже к счастью работает, без пересоздания ItemStack'а.
Я нашел только один минус

D Если мета-данные разные, то нельзя стакануть вещи. Например, если у меня есть 2 земли которые подверглись влиянию предыдущего кода, то они не смогут стакануться с другой землей, пока та другая земля тоже не будет иметь такой-же набор meta-данных.
Интересует больше всего правильность этого подхода. На сколько это корректно.
Кто-нибудь имел опыт с мета-данными вещей?