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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Try the latest build: https://modrinth.com/mod/axiom/version/4.1.1
    • *** buffer overflow detected ***: terminated /usr/bin/forge-1.12.2d: line 162: 15787 Aborted                 (core dumped) ${SUDO_CMD} screen -S "${SESSION_NAME}" -Q select . > /dev/null Starting server...There are several suitable screens on:     14630.forge-1.12.2    (Detached)     15796.forge-1.12.2    (Detached) Use -S to specify a session How do i fix this issue?
    • Oh I forgot to update the title. I figured out the issue and I'm rather embarrassed to say that it was a file path issue. The game already knew I was accessing the achievements so I wasn't suppose to include advancements in the file path. Minecraft file paths have always confused me a little bit... ResourceLocation advancementId = new ResourceLocation( TheDeadRise.MODID,"adventure/spawntrigger");
    • Can someone help my with this? My forge server won't open and I'm not that good with this stuff. It gave me this error message:   C:\Users\apbeu\Desktop\Forge server>java -Xmx4G -Xms1G -jar server.jar nogui 2024-12-11 18:21:01,054 main WARN Advanced terminal features are not available in this environment [18:21:01] [main/INFO] [cp.mo.mo.Launcher/MODLAUNCHER]: ModLauncher running: args [--gameDir, ., --launchTarget, fmlserver, --fml.forgeVersion, 36.2.34, --fml.mcpVersion, 20210115.111550, --fml.mcVersion, 1.16.5, --fml.forgeGroup, net.minecraftforge, nogui] [18:21:01] [main/INFO] [cp.mo.mo.Launcher/MODLAUNCHER]: ModLauncher 8.1.3+8.1.3+main-8.1.x.c94d18ec starting: java version 21.0.4 by Oracle Corporation Exception in thread "main" java.lang.IllegalAccessError: class cpw.mods.modlauncher.SecureJarHandler (in unnamed module @0x402e37bc) cannot access class sun.security.util.ManifestEntryVerifier (in module java.base) because module java.base does not export sun.security.util to unnamed module @0x402e37bc         at cpw.mods.modlauncher.SecureJarHandler.lambda$static$1(SecureJarHandler.java:45)         at cpw.mods.modlauncher.api.LamdbaExceptionUtils.uncheck(LamdbaExceptionUtils.java:95)         at cpw.mods.modlauncher.SecureJarHandler.<clinit>(SecureJarHandler.java:45)         at cpw.mods.modlauncher.Launcher.lambda$new$6(Launcher.java:55)         at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)         at cpw.mods.modlauncher.api.TypesafeMap.computeIfAbsent(TypesafeMap.java:52)         at cpw.mods.modlauncher.api.TypesafeMap.computeIfAbsent(TypesafeMap.java:47)         at cpw.mods.modlauncher.Environment.computePropertyIfAbsent(Environment.java:62)         at cpw.mods.modlauncher.Launcher.<init>(Launcher.java:55)         at cpw.mods.modlauncher.Launcher.main(Launcher.java:66)         at net.minecraftforge.server.ServerMain$Runner.runLauncher(ServerMain.java:63)         at net.minecraftforge.server.ServerMain$Runner.access$100(ServerMain.java:60)         at net.minecraftforge.server.ServerMain.main(ServerMain.java:57) C:\Users\apbeu\Desktop\Forge server>pause
    • Here is the url for the crash report if anyone can help me, please. https://mclo.gs/KGn5LWy  
  • Topics

×
×
  • Create New...

Important Information

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