NBT-API

NBT-API

98.9k Downloads

NBTItem problem

Kyumar opened this issue ยท 33 comments

commented

Server version: 1.12.2
api version: 2.8.0

I am applying a nbt to an item using NBTItem when the item is dropped, everything works correctly, dropping an item with another nbt (applied by another plugin) dropping the item you lose everything, name, lore etc, ideas?

commented

Check that you are updating the item in the inventory. NBTItem is a copy of the item in the inventory. Also print out the data before and after dropping. Noteworthy that the nbtapi has no event hooks, so basically has to be another plugin screwing up.

commented

when player drop item, execute that

public void apply(ItemStack itemStack, int id){
    NBTItem nbtItem = new NBTItem(itemStack);

    nbtItem.setInteger("dropID", id);
    nbtItem.applyNBT(itemStack);
}

when i pickup it nothing changes, when i test it in another server, if i drop an item with an nbt, all data disappears

commented

Thats not really the intended way to do that^^. Modify the data in the NBTItem and then event.setItemStack(nbtItem.getItem(). Also note the javadoc https://github.com/tr7zw/Item-NBT-API/blob/master/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTItem.java#L64 .

commented

It sets the entire nbt of the itemstack to that of NTBItem.

commented

Oh, so, if i use apply# it apply only the nbt who i applied?

commented

without adding back those who were there?

commented

Ok, thank you so much

commented

No.

public void apply(ItemStack itemStack, int id){
NBTItem nbtItem = new NBTItem(itemStack, true);
    nbtItem.setInteger("dropID", id);
}
commented

So, if i have to add an nbt to an item who might have custom nbt should i use mergeCustomNBT# ?

commented

You best case don't use any of these methods. Either use .getItem() to get back the modified item, or add true to the constructor of NBTItem to enable direct apply mode.

commented

public ItemStack apply(ItemStack itemStack, int id){
NBTItem nbtItem = new NBTItem(itemStack, true);

    nbtItem.setInteger("dropID", id);
    nbtItem.mergeCustomNBT(itemStack);
    return nbtItem.getItem();
}

something like that?

commented

oh, ok

commented

Thank you so much

commented

So what could the solution be? At the drop I generate an id and insert everything in the db, to take into account that that particular id is associated with that drop, how do I do it?

commented
commented

Do you perhaps mixup the items? Also don't mix changing nbt and itemmeta at the same time.

commented

Ehhhh that code shouldn't work at all? You are trying to update the event after it happened. Also, you could just store all of the data you are putting into the database onto the item^^

commented

i have to get dropID when a player pickup an item and get the ID

commented

Yes, but your event handler already technically shouldn't work and can have really bad side effects, because you are using an (async) task there.

commented

I need to async only the insert query in the database, everything else doing it syn should work as then?

commented

No what I'm saying is that your logic doesn't work. Yes you need to do the SQL stuff async, but that also means you can not use that during events like this. Your logic of "when something drops, note that in the database and then write it to the item" will just not work. You have a few options: ditch the database in general and just write that data to the item/item entity, generate random ids/keep track of the database ids and set it on the item/item entity before you are writing it to the database.

commented

so i shouldn't apply a nbt to the drop to account for it?

commented

Not retroactively.

commented

Hey sorry, even doing so continues to remove the other nbt tags and put only dropID

commented

I mean what are you even trying to achieve? Because at pickup you have the reverse issue of your SQL query will happen in the future after the person/hopper/entity has picked up the item.

commented

i can use entityID and on pickup set to the itemstack this ID

commented

Again, why do it this way then xD On drop write to the entity!(not the item stack) who dropped it and when. And at pickup get that data + who picked it up and when and write it async to the database.

commented

I need information on who dropped that item, who collected it and at what time

commented

Ah wait you are in 1.12, then you need to write it to the item instead of the entity.

commented

i need a database beacause i have to get all drops of a certain hour or of certain players, all works, the only problem was this nbt thing

commented

The issue is that your code breaks the spigot API logic. Please add a few
System.out.println(new NBTItem(event.getItemStack)); to a) before you do anything b) your async logic c) after updating the item.

commented

done, apply and correctly take the right nbt

commented

Ok, i think it's not a problem of NBTApi ...