Search code examples
javaminecraftbukkit

Get "Custom id" for ItemStack in bukkit


firstly I want to apologize for my very bad English xD. So, I'm developing an economy plugin just to learn and in this plugin, I'm creating a sign shop. Everything was going fine, but when I was trying my shop, I got stuck with enchanted items, for example, because I can't get the id with only:

ItemStack item = player.getItemInHand();
item.getTypeId();

This only returns me the id of the real item, without enchantment. Someone can tell me if Has a method I can make to set some custom id, in the lore of item, for example, that I can use later to make a sign shop?

EDIT:

Now works fine to save item data, but still giving error. What i'm using now is:

public static void saveItem(Player player){
    ItemStack item = player.getItemInHand();
    //config.createSection("eco.sell.aFirstItem");
    ConfigurationSection configToEdit = config.createSection("eco.sell.aFirstItem");
    configToEdit.set("type", item.getType().name());
    configToEdit.set("amount", item.getAmount());
    if(item.hasItemMeta()){
        ItemMeta meta = item.getItemMeta();
        configToEdit.set("meta.name", meta.getDisplayName());
        List<String> enchants = new ArrayList<>();
        meta.getEnchants().forEach((en, lvl) -> enchants.add(en.getName() + ":" + lvl));
        configToEdit.set("meta.enchant", enchants);
        save();

    }
}

So, to restore data i'm using:

public static void restoreData(Player player){
    //config.getConfigurationSection("eco.sell.aFirstItem");
    ConfigurationSection configToEdit = config.createSection("eco.sell.aFirstItem");
    ItemStack item = new ItemStack(Material.valueOf(configToEdit.getString("type")), configToEdit.getInt("amount")); 

    if(configToEdit.contains("meta")) {
        player.sendMessage("Contains( Meta )");
        ItemMeta meta = item.getItemMeta();
        meta.setDisplayName(configToEdit.getString("meta.name"));
        List<String> enchants = configToEdit.getStringList("meta.enchants"); 
        enchants.forEach(line -> {
            String[] split = line.split(":"); 
            item.addEnchantment(Enchantment.getByName(split[0]), Integer.parseInt(split[1]));

        });

    }
    player.getInventory().addItem(item);
    player.updateInventory();
}

Solution

  • You can't have a unique ID like that.

    But, there is two ways :

    1. Store full object. For example, create a json that contains the item id, item name, enchants... Then store it as you want to save ids.

    For example, we will save an item and restore it. We will use the default config of spigot.

    Save the item

    Configuration objConfig = plugin.getConfig().createSection("eco.sell.aFirstItem"); // create new section in plugin config
    // now we will add all content from item to config
    objConfig.set("type", item.getType().name()); // item type
    objConfig.set("amount", item.getAmount()); // amount of item
    if(item.hasMetadata()) {
       ItemMeta meta = item.getItemMeta();
       objConfig.set("meta.name", meta.getDisplayName()); // item name
       List<String> enchants = new ArrayList<>(); // create hashmap that will be saved
       meta.getEnchants().forEach((en, lvl) -> enchants.add(en.name() + ":" + lvl));
       objConfig.set("meta.enchants", enchants); // all items enchants
    }
    plugin.saveConfig();
    

    Now, we will restore data from config :

    Configuration objConfig = plugin.getConfig().getConfigurationSection("eco.sell.aFirstItem"); // retrieve section
    ItemStack item = new ItemStack(Material.valueOf(objConfig.getString("type")), objConfig.getInt("amount")); // here we have an item that we can edit
    if(objConfig.contains("meta")) {
       ItemMeta meta = item.getItemMeta();
       meta.setDisplayName(objConfig.getString("meta.name"));
       List<String> enchants = objConfig.getStringList("meta.enchants"); // get all enchants
       enchants.forEach(line -> {
          String[] split = line.split(":"); // split enchantName:enchantLevel
          item.addEnchant(Enchantement.valueOf(split[0]), Integer.parse(split[1])); // get spigot objects
       });
    }
    

    Warn: few line can don't work because I don't test this exact code, but that's how it should work.

    1. Create a list of items which have an ID, then refer this id where you want. And you just have to make the link between both (such as SQL database works).

    The second can be useful if you always are selling same items. I think in your case the first solution will be better.