Jump to content

Recommended Posts

Posted

Hello,

I am trying to, upon the right click of an item it will send a packet to the server, requesting information from a custom capability I added, a reply packet will then be sent, containing the information unique to the player.

 

The packet is being registered to be sent to the server, and I assume the reply will come to the client, which is where I want it. However I am rather confused when it comes to using the same packet handler for both the send and receive packets. For example, the handler takes the request packet, and based off it's contents, it returns a reply packet to the client. Now how do I access the returned information aka. the reply packet? Especially if it uses the same method for handling as the sent packet, wouldn't this throw off the message parameter for the reply packet? In addition, I am assuming the reply packet is sent to the client, but isn't the handler for the packet always on the side passed in during registerPacket()? In this case that would make the handler only exist on the server?

 

Looking at this all in retrospect, would I just use static fields to get the information to other classes, such as my gui class in this scenario?

 

Thanks!

Posted

One packet = one handler. This is best practice.

It is possible to have bipolar packets. Simply register same packet and same handler (or different) to proper sides (Side.CLIENT and Side.SERVER).

 

(CLIENT) ItemStack use -> send packet 1 -> (SERVER) receive packet 1 -> handle packet 1 (using assigned Side.SERVER handler) -> within handler send packet to client -> send packet 2 -> (CLIENT) receive packet 2 -> handle packet 2 (using assigned Side.CLIENT handler) -> end.

 

Now - as of 1.8.9, quote:

In 1.8.9 the return value in IMessageHandler is pretty pointless, since you have to schedule your handler on the main thread anyways, which means you cannot return the response in the actual IMessageHandler method.

Basically - don't return response packet, just send it like you normally would.

If you don't get it yet - http://greyminecraftcoder.blogspot.com.au/2015/01/thread-safety-with-network-messages.html

WHATEVER you do, you always do it from MC threads - that includes response packets.

 

EDIT

 

So direct answer for your questions:

1. One handler = one action. You can have one packet for server->client and client->server, but in this case you will always need 2 handlers or one handler with if statements (each for one side).

2. Yes - packet handler is the one that will be changing data on proper side. You can modify currently opened gui, some static fields, really anything, as long as you can access it somehow. Note: Do everything from Runnable() posted to MC thread.

1.7.10 is no longer supported by forge, you are on your own.

Posted

Looking at this all in retrospect, would I just use static fields to get the information to other classes, such as my gui class in this scenario?

Absolutely not. They will not do what you think they will.

 

Each IMessage is created once when you send it, then a new instance is created on the other side and reads the data sent over the network. Once that's done, an instance of the IMessageHandler is created and the message passed to it.

 

So, if you send a message in return, it will be recreated on the other side and another new instance of the IMessageHandler created to handle that.

 

This is why a single handler can handle both sides, but if doing so you have to check which side you are on before doing anything if your message behaves differently on different sides.

 

When a single message can be handled on both sides, you need to register it twice - once on each side - and using the same discriminator byte (at least that's what I've found).

 

However, it's somewhat rare for a single message to be useful on both sides, so you may want to carefully evaluate whether one message type is sufficient, or whether you really need two.

Posted

Going from memory:

client side: player.currentScreen

server side: player.openContainer

 

Those will give you the actual GUI and Container instances, if any, which you can cast to yours and do whatever you want.

 

Also, since GUI screens are client-side only, you could technically get away with using static fields, e.g. MyGui.field = 42, but keep in mind that it is almost always better to use an actual instance of the class and non-static members.

Posted

That was a random example.

 

Modifying as in changing values. Simple as that.

 

E.g situation: Say you click button in GUI. Client sends packet that you clicked. Server handles pakcet, does something (logic) and then decides to send a response packet.

Client receives response packet which essentially goes to Minecraft#currentScreen or player#currentScreen (I think) checks instanceof and if it is some GuiExample then changes some values based on packet data (e.g: add new entry to some list in gui).

This is what I meant.

 

P.S: Oh well... coolAlias was faster :P

1.7.10 is no longer supported by forge, you are on your own.

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



×
×
  • Create New...

Important Information

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