Jump to content

[1.12.2] Need help with packets in a machine GUI


MayusYT

Recommended Posts

HI! I started Forge modding a few weeks ago and I'm stuck at understanding the packets I have to use when e.g. clicking on a button on a GUI of a block. Let's choose an enable/disable button for this example. The button will change its texture whether the machine is enabled or not. So I understand that I have to send a packet from the GUI click "listener" that has to change my boolean "enabled" in my tile class. But when you open the GUI, you should see whether the machine is enabled or not. How do I do the communication between the server and the client? I heard that sending a packet is unnecessary.

 

 

Thank you very much in advance!

Link to comment
Share on other sites

15 hours ago, MayusYT said:

HI! I started Forge modding a few weeks ago and I'm stuck at understanding the packets I have to use when e.g. clicking on a button on a GUI of a block. Let's choose an enable/disable button for this example. The button will change its texture whether the machine is enabled or not. So I understand that I have to send a packet from the GUI click "listener" that has to change my boolean "enabled" in my tile class. But when you open the GUI, you should see whether the machine is enabled or not. How do I do the communication between the server and the client? I heard that sending a packet is unnecessary.

 

 

Thank you very much in advance!

Ive just used my container class to get the tile entity into the gui. Using:

container.tileEntity.variables

 I just grab the variables I need straight from the tile entity. Not sure if this is the most correct way to do it but it works on both logical and physical servers with no issue.

  • Like 1
Link to comment
Share on other sites

Thanks for your answers!

2 hours ago, diesieben07 said:

You can use the vanilla container mechanics for simple values (number 0-65535), look at e.g. ContainerFurnace for example.

Otherwise you need to send your own packets from server to client as well.

Do you mean detectAndSendChanges()?

A dev of EnderCore gave me this snippet: https://github.com/SleepyTrousers/EnderCore/blob/1.12/src/main/java/com/enderio/core/common/ContainerEnderCap.java#L260

 

I copied the code into my container class but it still doesnt work. 

 

thanks!

 

PS: I distinguish the guis by checking whether the boolean in the tileentity class is true or false.

 

EDIT: Here is my code, might help:

Folder of my block (contains the important files):

https://github.com/MayusYT/ZPM-Mod/tree/master/src/main/java/mayus/zpmmod/blockControllerLarge

(the click handler is in guicontrollerlarge)

Edited by MayusYT
Link to comment
Share on other sites

6 minutes ago, diesieben07 said:

That snippet is not a magic fix for all your problems. In general, please don't just copy pieces of code without understanding what they do.

 

You can send two short values in Container#detectAndSendChanges using IContainerListener#sendWindowProperty, one named varToUpdate, one named newValue. Both can be whatever value you want, they will arrive as-is on the client in Container#updateProgressBar.

Look at ContainerFurnace for an example.

 

Alternatively you can send whatever packet you want in detectAndSendChanges.

Thanks for your answer. I‘ll have a look at ContainerFurnace but I think sending my own packet would be better (and easier) because I want toupdate multiple Values in the future.

 

I‘ll keep you updated!

 

thanks again!

Edited by MayusYT
Link to comment
Share on other sites

4 hours ago, diesieben07 said:

The vanilla system can handle multiple values just fine. In fact, ContainerFurnace does just that.

I added a second value but it doesn't seem to work anymore. This is my current code:
 

/**
     * A bit of a hack, but with Container#updateProgressBar you don't have to send a custom packet
     */
    @Override
    public void updateProgressBar(int id, int data) {
        if(id == 5) {
            isEnabled = data != 0;
        }
        if(id == 6) {
            redstoneBehaviour = data;
        }
    }

    @Override
    public void detectAndSendChanges() {
        super.detectAndSendChanges();

        for (IContainerListener containerListener : listeners) {
            if (containerListener instanceof EntityPlayerMP) {
                containerListener.sendWindowProperty(this, 5, te.isEnabled ? 1 : 0);
                containerListener.sendWindowProperty(this, 6, te.redstoneBehaviour);
            }
        }
    }

 

Link to comment
Share on other sites

Just now, diesieben07 said:
  • With your current behavior you are sending the values every tick, regardless of if they have changed or not. You need to compare them, like ContainerFurnace does.
  • Define "doesn't seem to work".
  • ok, I'm going to change that.
  • The value is set to a different value but is reset every time I click the button again.
Link to comment
Share on other sites

 

40 minutes ago, diesieben07 said:
  • With your current behavior you are sending the values every tick, regardless of if they have changed or not. You need to compare them, like ContainerFurnace does.
  • Define "doesn't seem to work".

 

By the way, this is the packet I send to the server:

public class PacketSetEnabled implements IMessage {

    // A default constructor is always required
    public PacketSetEnabled(){}

    @Override public void toBytes(ByteBuf buf) {}

    @Override public void fromBytes(ByteBuf buf) {}

    public static class Handler implements IMessageHandler<PacketSetEnabled, IMessage> {

        @Override public IMessage onMessage(PacketSetEnabled message, MessageContext ctx) {
            // This is the player the packet was sent to the server from
            EntityPlayerMP serverPlayer = ctx.getServerHandler().player;

            serverPlayer.getServerWorld().addScheduledTask(() -> {

                if (serverPlayer.openContainer instanceof ContainerControllerLarge) {
                    ContainerControllerLarge openContainer = (ContainerControllerLarge) serverPlayer.openContainer;
                    openContainer.te.isEnabled = openContainer.isEnabled;

                    if (openContainer.redstoneBehaviour == 0) {
                        openContainer.te.redstoneBehaviour = 1;
                    } else if (openContainer.redstoneBehaviour == 1) {
                        openContainer.te.redstoneBehaviour = 2;
                    } else {
                        openContainer.te.redstoneBehaviour = 0;
                    }
                    openContainer.te.markDirty();
                }
            });
            // No response packet
            return null;
        }
    }
}

 

Edited by MayusYT
Link to comment
Share on other sites

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.



×
×
  • Create New...

Important Information

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