Jump to content

[1.11.2] Help syncing tileentity IItemHandler from server to client


Recommended Posts

Posted

Hello, all!

I'm currently trying to develop a server-compatible mod for the first time, and I'm having some massive issues with my IItemHandler capability for a tileentity not properly syncing from the server to the client.  It runs fine in singleplayer-- the inventory has expected behavior, as seen here:

normal-inventory.gif

Everything seems to be working fine.  I can drag stacks around, they register in the top, etc.  No issues. (placeholder gui and .lang isn't set up, I know XD)

But when I host from a server and connect to it...

broken-server-inventory.gif

Clicking the item just ends with it glitching immediately back into its slot.  Shift-clicking duplicates the item into the slot as a ghost item, which immediately disappears when clicked on.

So this is definitely a big issue.  One of the most requested features I had for the mod was server compatibility, so I'm not about to just give up, however this is my first experience with servers and there seem to be few good explanations/examples of how this even works.  As I understand, IItemHandler doesn't automatically sync with the client the way IInventory does, but IInventory is an older, outdated method that's not the most effective one to use from what I've read.  It sounds like I need to set up a packet system to sync the server to the client and back again, but I have very little idea of how to do that with an inventory.  I've used packets before, but only ever for simple variables (i.e. ints and stuff), and I don't necessarily know enough about the inventories to know where I'd need to call/send these packets.  So if anyone has experience/advice here, I would definitely appreciate it.

If at all possible, I'd like to make this setup reusable-- though if that's not easily possible I understand.  I want to keep the mod as clean as possible, without reusing code if I can help it, so if there's some way I can set this up automatically for future TileEntity inventories (i.e. a custom extension of the container class?  Some way to automatically sync through my custom slot base class?) that is definitely preferable.

 

Current code:

Block

TileEntity

Container

GUI

GUIHandler

 

I do use a custom slot class, but the only thing I added is a restriction for isItemValid (the slot is a food bowl, so I've restricted it to only accept my kibble items).  You can see that code here:

@Override
public boolean isItemValid(ItemStack stack) {
	if (stack.isEmpty() || !(stack.getItem() instanceof ItemKibble))
    	return false;

    IItemHandler handler = this.getItemHandler();
    ItemStack remainder;
    if (handler instanceof IItemHandlerModifiable)
    {
        IItemHandlerModifiable handlerModifiable = (IItemHandlerModifiable) handler;
        ItemStack currentStack = handlerModifiable.getStackInSlot(index);

        handlerModifiable.setStackInSlot(index, ItemStack.EMPTY);

        remainder = handlerModifiable.insertItem(index, stack, true);

        handlerModifiable.setStackInSlot(index, currentStack);
    }
    else
    {
        remainder = handler.insertItem(index, stack, true);
    }
    return remainder.isEmpty() || remainder.getCount() < stack.getCount();
}

Thank you so much for your time, and have a great day!

Posted

Why are you using 1.11? Update.

 

Quote

public class BlockFoodDish extends BlockWildCraft implements ITileEntityProvider

Don't use ITileEntityProvider, it is outdated and unnecesarry. Just override Block#hasTileEntity and Block#createTileEntity. 

 

Also blockbase is an anti-pattern.

 

Don't invoke EntityPlayer#openGui on the client at all. Forge will do the networking for you. This is likely the cause of your issue.

 

Your health property is lost upon (de)serialization. You should probably include this in your (de)serialization methods too.

 

public int quantityDropped(Random random)
    {
        return 1;
    }

The default implementation already returns 1. Why did you override it?

 

Quote

Integer.valueOf(MathHelper.clamp(level, 0, 3)))

MathHelper.clamp already returns an int. Why do you need to ask the Integer class to get the value from it?

 

Quote

return ((Integer)state.getValue(FULLNESS)).intValue();

Same here.

 

Quote

this.FULLNESS.equals(fullness);

...What? FULLNESS is static thus your IDE should be screaming at you for using this access keyword. Also why are you comparing it to the argument? You do know that Object#equals returns a boolean that indicates the result of comparing two objects.

 

Quote

this.HEALTH.equals(health);

Same here.

 

if (tileentity != null)
        {
            tileentity.validate();
            worldIn.setTileEntity(pos, tileentity);
        }

You don't need to do this. Just override TileEntity#shouldRefresh in your TE class. Actually you are already doing that so there is no need for this code at all.

 

Quote

public class TileEntityFoodDish extends TileEntity implements ICapabilityProvider

TileEntity already implements ICapabilityProvider. You don't need to add this interface again.

 

Quote

BlockFoodDish blockfooddish;

Blocks are singletons. You can use @ObjectHolder to get the reference if you need it.

 

int metadata = getBlockMetadata();
		return new SPacketUpdateTileEntity(this.pos, metadata, nbt);

This is not what that parameter wants from you. As you are using a modded TE you can pass anything to it.

 

public BlockFoodDish getFoodDish()
	{
		return this.blockfooddish;
	}

Again, blocks are singletons. You do not need to store a block reference in each instance of your TE.

 

Quote

this.blockType = this.getBlockType();

...Why? It is already set to that.

Posted

I announced that I'll be releasing the complete version of the mod's first update in 1.11, so I'll be continuing to work in 1.11 for now.

There are a couple things here that were added unnecessarily, I'll take a look at those-- some can probably be deleted, while others may be for things I intend to alter later.  I will definitely take a look at the EntityPlayer#openGUI part, as if that is the cause then this may be a simple fix.  I'll update this later when I've had time to take a look at these suggestions.

Thank you for your advice.

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

    • When I first heard about Bitcoin back in 2018, I was skeptical. The idea of a decentralized, digital currency seemed too good to be true. But I was intrigued as I learned more about the technology behind it and its potential. I started small, investing just a few hundred dollars, dipping my toes into the cryptocurrency waters. At first, it was exhilarating to watch the value of my investment grow exponentially. I felt like I was part of the future, an early adopter of this revolutionary new asset. But that euphoria was short-lived. One day, I logged into my digital wallet only to find it empty - my Bitcoin had vanished without a trace. It turned out that the online exchange I had trusted had been hacked, and my funds were stolen. I was devastated, both financially and emotionally. All the potential I had seen in Bitcoin was tainted by the harsh reality that with decentralization came a lack of regulation and oversight. My hard-earned money was gone, lost to the ether of the digital world. This experience taught me a painful lesson about the price of trust in the uncharted territory of cryptocurrency. While the technology holds incredible promise, the risks can be catastrophic if you don't approach it with extreme caution. My Bitcoin investment gamble had failed, and I was left to pick up the pieces, wiser but poorer for having placed my faith in the wrong hands. My sincere appreciation goes to MUYERN TRUST HACKER. You are my hero in recovering my lost funds. Send a direct m a i l ( muyerntrusted ( @ ) mail-me ( . )c o m ) or message on whats app : + 1 ( 4-4-0 ) ( 3 -3 -5 ) ( 0-2-0-5 )
    • You could try posting a log (if there is no log at all, it may be the launcher you are using, the FAQ may have info on how to enable the log) as described in the FAQ, however this will probably need to be reported to/remedied by the mod author.
    • So me and a couple of friends are playing with a shitpost mod pack and one of the mods in the pack is corail tombstone and for some reason there is a problem with it, where on death to fire the player will get kicked out of the server and the tombstone will not spawn basically deleting an entire inventory, it doesn't matter what type of fire it is, whether it's from vanilla fire/lava, or from modded fire like ice&fire/lycanites and it's common enough to where everyone on the server has experienced at least once or twice and it doesn't give any crash log. a solution to this would be much appreciated thank you!
    • It is 1.12.2 - I have no idea if there is a 1.12 pack
  • Topics

×
×
  • Create New...

Important Information

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