Jump to content

Recommended Posts

Posted (edited)

Hello, 

I am currently having problems for syncing ItemStack capabilities to the client side for tools and other items.  Current my method of syncing is by override the onUpdate method of its Item Class and sending the NBT (of the capability) and the slot of the player. My slot checking code is as follows:

 

public static int getSlot(EntityPlayer ep, ItemStack is){
    	int i = ep.openContainer.inventorySlots.size();
    	for(int ii=0; ii<i;  ii++){
    		if(ep.openContainer.getSlot(ii).getHasStack()){
    			ItemStack item = ep.openContainer.getSlot(ii).getStack();
    			if (ItemStack.areItemStackTagsEqual(item, is)){
    				return ii;
    			}
    		}
    	}
    	return -1;
}

 

The client packet handler then receives these and obtains the itemstack via the same method, and calls the load() method and inputs the packet's nbt as the parameter.

 

This method has gave me various problems.

1) In creative mode, this completely breaks down.

2) Every time an item seems to change in capability value, the re-equip animation is called, breaking any EnumAction I am calling.

3) When it re-equips, the client seems to load the old data (or the data from the capability attach event) for a brief moment, making the tool-tips glitch.

I am not sure what caused these problems

 

 

Edited by kirinnee97
Posted

There are two main ways to sync item capability data:

  • Override Item#getNBTShareTag, as suggested in this PR and various other issues.
  • Register an IContainerListener for EntityPlayer#inventoryContainer on PlayerLoggedInEvent and PlayerEvent.Clone and for PlayerContainerEvent#getContainer on PlayerContainerEvent.Open.

I use the latter in my mod. This class is responsible for registering the IContainerListener instances with each Container, this is the base class for the IContainerListener implementations. The implementations are here, here, here and here.

  • Like 1

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Posted (edited)
1 hour ago, Choonster said:

There are two main ways to sync item capability data:

  • Override Item#getNBTShareTag, as suggested in this PR and various other issues.
  • Register an IContainerListener for EntityPlayer#inventoryContainer on PlayerLoggedInEvent and PlayerEvent.Clone and for PlayerContainerEvent#getContainer on PlayerContainerEvent.Open.

I use the latter in my mod. This class is responsible for registering the IContainerListener instances with each Container, this is the base class for the IContainerListener implementations. The implementations are here, here, here and here.

Hi, not to be spoon fed or anything but for the first suggestion, when is the vanilla update packet called? I cannot seemed to find. 

Tracing getNBTShareTag seem to lead me to some packets, but i do not exactly understand under what condition the packet is send to client side.

Do i have to manually check and send packets?

 

 

Edited by kirinnee97
Posted (edited)
30 minutes ago, kirinnee97 said:

Hi, not to be spoon fed or anything but for the first suggestion, when is the vanilla update packet called? I cannot seemed to find. 

Tracing getNBTShareTag seem to lead me to some packets, but i do not exactly understand under what condition the packet is send to client side.

Do i have to manually check and send packets?

 

Item#getNBTShareTag is called by PacketBuffer#writeItemStack, which is called by every packet that sends an ItemStack. The main one is SPacketSetSlot, which is sent by EntityPlayerMP#sendSlotContents (which implements IContainerListener#sendSlotContents); this is called by Container#detectAndSendChanges, which first checks if the current and previous ItemStack for the slot aren't equal using ItemStack.areItemStacksEqual.

 

ItemStack.areItemStacksEqual checks the Item, metadata, NBT and capabilities of the two ItemStacks.

 

Container#detectAndSendChanges is called on EntityPlayer#openContainer from various places, including EntityPlayerMP#onUpdate (called every tick). In general, you shouldn't need to manually send packets.

Edited by Choonster
  • Like 1

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Posted
5 hours ago, Choonster said:

 

Item#getNBTShareTag is called by PacketBuffer#writeItemStack, which is called by every packet that sends an ItemStack. The main one is SPacketSetSlot, which is sent by EntityPlayerMP#sendSlotContents (which implements IContainerListener#sendSlotContents); this is called by Container#detectAndSendChanges, which first checks if the current and previous ItemStack for the slot aren't equal using ItemStack.areItemStacksEqual.

 

ItemStack.areItemStacksEqual checks the Item, metadata, NBT and capabilities of the two ItemStacks.

 

Container#detectAndSendChanges is called on EntityPlayer#openContainer from various places, including EntityPlayerMP#onUpdate (called every tick). In general, you shouldn't need to manually send packets.

@Choonster Thank you very much. It seemed to have worked, except when I change an item's slot in creative, the capability seem to reset. 

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.