Posted November 17, 20204 yr Hello! I have an Itemstack capability on client and server side and I want the client one syncronised with the server. Overriding Item#getShareTag and Item#readShareTag is not possible, because the capability is attached to every itemstack. With the help of google I found 2 answers to my question, however I'm struggling with implementation. The first solution I found was to send packaged through a simpleChannel. I know the basics of this method, because I succesfully implemented this type of networking for my entity capability. My problem is, that I don't know, when I would have to send the message. You can look at my code on this branch here for more details: https://github.com/Tavi007/ElementalCombat/tree/ItemSync-via-packets/src/main/java/Tavi007/ElementalCombat (check out the network package). For the entity one I knew the events, that were relevant, so I knew, when stuff would change. For Itemstack I do not know this yet. The second solution was to implement a containerListener, just like Choonsters did in his TestMod3. In an attempt to understand the code I copied his code, did some changes and somehow got it working. To be frank, I still don't fully understand his code, but it did sync up the capability. What's weird is, that I never specified to just sync up my capability nor did I define a message for it. I'm afraid, that this will cause issues with other mods down the line. (Also I don't like the fact, that I don't know, what my code is doing). You can look up the code for this attempt on this branch: https://github.com/Tavi007/ElementalCombat/tree/ItemSync-via-Listener/src/main/java/Tavi007/ElementalCombat (check out the capability and network package). Can someone please elaborate how this type of networking usually works?
November 17, 20204 yr Author 4 hours ago, Tavi007 said: To be frank, I still don't fully understand his code, but it did sync up the capability. What's weird is, that I never specified to just sync up my capability nor did I define a message for it. Just tested this part again and now the itemstack won't sync up. I swear they did before...
November 19, 20204 yr Author Bump. To rephrase my question: How can I syncronize itemstack capabilities without using Item#getShareTag/readShareTag? Are there some vanilla classes/ example mods, that implemented container listener, so I can check them out?
November 19, 20204 yr Author Since I attach my capability to every item, how could I synchronize it for lets say the vanilla iron sword?
November 19, 20204 yr Author Well that sucks. I found this thread which seems to have a work around with a container listener (hence why I mentioned it in the op). Do you know more on this topic? Cause I don't fully understand it yet.
November 19, 20204 yr Author It's just for displaying the data as tooltip. Also the data doesn't change that often, so it wouldn't need to be syncronized continously.
November 19, 20204 yr Author Sooo... 57 minutes ago, Tavi007 said: Do you know more on this topic? Cause I don't fully understand it yet.
November 20, 20204 yr With my system, each capability type that needs to be synced to the client has several sync-related classes: A single update network message (extending UpdateContainerCapabilityMessage) that syncs the capability data for a single slot of a Container. A bulk update network message (extending BulkUpdateContainerCapabilityMessage) that syncs the capability data for all slots of a Container. A "functions" class containing static methods used by both the single and bulk update messages. A container listener class (extending CapabilityContainerListener) that sends the single/bulk update messages when the Container's contents change. A factory function for the container listener is registered with CapabilityContainerListenerManager.registerListenerFactory at startup so that when a player opens a Container, a new listener can be created and added to it. The network messages have the concept of a "data" class, which is a simple POJO (or even a primitive type like int or long) containing only the data that needs to be synced from the server to the client. The base classes for the messages handle the functionality that's common to all capability types, the message classes for each capability just need to provide functions to do the following: On the server: Convert an instance of the capability handler (e.g. IFluidHandlerItem for a fluid tank) to a data object Encode (write) the data object to the packet buffer On the client: Decode (read) the data object from the packet buffer Apply the data from the data object to the capability handler instance These functions could be defined anywhere (they could even be lambdas passed directly to the base class methods), but I keep them as static methods in a "functions" class so they can be shared between the single and bulk messages. The system might be a bit over-engineered, but it means that I can easily add syncing for a new item capability without having to rewrite all the common syncing logic. There are several implementations of this in TestMod3 that you could use as examples: ILastUseTime, which tracks the time at which an item was last used. This is a simple implementation that syncs a single long value to the client, so it uses Long as its data class. Single update message Bulk update message Functions class Container listener Container listener registration (called during FMLCommonSetupEvent) IFluidHandlerItem, Forge's fluid tank capability. This is a slightly more complex implementation that syncs a FluidStack (the tank contents) and an int (the tank capacity), so it uses FluidTankSnapshot as its data class. Single update message Bulk update message Functions class Container listener (only syncs data for my own fluid tank item, to avoid conflicts with other mods' fluid handler items) Container listener registration (called during FMLCommonSetupEvent) 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.
November 23, 20204 yr Author Thank you so much for such an in depth answer! I think, I should be able to modify your code now (cause I really only have 2 capabilities, so my system doesn't have to be as flexible as yours)
December 3, 20204 yr Author Hey, so tried to implement what you said and I got it mostly working, but there is one last bug remaining. When I open the play inventory, the itemstacks won't get updated immediately. I have to move the itemstack at least once for it to update. Any other container is working as intended tho. If I open a chest, every itemstack has the right information directly. Any idea what the reason might be? Could it have to do something with the curios mod, which I'm using while developing? Some links of my github: https://github.com/Tavi007/ElementalCombat/tree/master/src/main/java/Tavi007/ElementalCombat/capabilities https://github.com/Tavi007/ElementalCombat/tree/master/src/main/java/Tavi007/ElementalCombat/network Edited December 3, 20204 yr by Tavi007
December 8, 20204 yr Author Bump. I really hope someone knows more about this stuf. This is basically the last hurdle for my mod and I would really like to have a proper release in this year.
December 8, 20204 yr On 12/4/2020 at 5:39 AM, Tavi007 said: Hey, so tried to implement what you said and I got it mostly working, but there is one last bug remaining. When I open the play inventory, the itemstacks won't get updated immediately. I have to move the itemstack at least once for it to update. Any other container is working as intended tho. If I open a chest, every itemstack has the right information directly. Any idea what the reason might be? Could it have to do something with the curios mod, which I'm using while developing? Some links of my github: https://github.com/Tavi007/ElementalCombat/tree/master/src/main/java/Tavi007/ElementalCombat/capabilities https://github.com/Tavi007/ElementalCombat/tree/master/src/main/java/Tavi007/ElementalCombat/network It looks like Forge patches Container#detectAndSendChanges to only call IContainerListener#sendSlotContents if a slot's Item, count or share tag has changed; which often won't be the case for capability-only updates. I may need to re-evaluate the IContainerListener system to see if there's any way around this. This change was actually introduced in August 2017 for 1.12.2, six months after I created my system. I thought it was working more recently than that, but I must not have tested it properly. 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.
December 17, 20204 yr I've had a brief look at this and can't see any easy way to work around it, so I've created a suggestion thread for a change here: I'm not sure if it will go anywhere. Edited December 17, 20204 yr by Choonster 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.
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.