Posted February 26, 20196 yr 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!
February 27, 20196 yr 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.
February 27, 20196 yr Author 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 February 27, 20196 yr by MayusYT
February 27, 20196 yr Author 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 February 27, 20196 yr by MayusYT
February 27, 20196 yr Author 1 hour ago, diesieben07 said: The vanilla system can handle multiple values just fine. In fact, ContainerFurnace does just that. It works! Thank you soo much!
February 27, 20196 yr Author 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); } } }
February 27, 20196 yr Author 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.
February 27, 20196 yr Author 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 February 27, 20196 yr by MayusYT
February 27, 20196 yr Author Found the bug! Just forgot to set the variables in the Container according to the ones in the TileEntity.
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.