Jump to content

[1.7.2]Packets, and responses. I'm not understanding


hugo_the_dwarf

Recommended Posts

Hey so I want to make a GUI for players to change their class, so I need to send a packet to the server to make the change (easy I understand this)

However when the change is done, I'm guessing the player won't get the update (but will still have the effects of the class, just won't know it because the server instance of them was changed)

Now I notice that the "onMessage" method returns an IMessage and I'm used to just saying Null which I assume is no response. However I want to respond so the client can be updated the same as the server (can see current class, and or get a message of not enough credits to make the change, etc etc)

 

From the tutorials in the sub Board they explain how to make and setup the packets, send them, and receive them but saddly I have no idea how to send a response back to a player/client or better yet to a client/player in general.

 

the process I'm trying to do is "Player -> GUI -> Packet to Server -> Changes are done Message and status changed -> player updated on message, change, and status(this includes updating the GUI)"

 

Here is my "send To Server" packet that I made:

public class ClassPacket implements IMessage 
{

public String className;

public ClassPacket()
{

}

public ClassPacket(String className)
{
	this.className = className;
}

@Override
public void fromBytes(ByteBuf buf) 
{
	className = ByteBufUtils.readUTF8String(buf); // this class is very useful in general for writing more complex objects
}

@Override
public void toBytes(ByteBuf buf) 
{
	 ByteBufUtils.writeUTF8String(buf, className);
}

public static class ClassPackettHandler implements IMessageHandler<ClassPacket, IMessage> 
{

	@Override
	public IMessage onMessage(ClassPacket message, MessageContext ctx) 
	{
		EntityPlayer player = ctx.getServerHandler().playerEntity;
		if (ExtendPlayerRot.get(player).getCurrentClassName() == ExtendPlayerRot.classNames[0])
		{
			ExtendPlayerRot.get(player).setCurrentClass(message.className);
		}
		else
		{
			if (RotItems.checkForItemAndAmount(new ItemStack(Items.gold_ingot), 3, player.inventory))
			{
				for (int i = 0; i < 3; i++)
				{
					player.inventory.consumeInventoryItem(Items.gold_ingot);
				}
				ExtendPlayerRot.get(player).setCurrentClass(message.className);
			}
			else if (RotItems.checkForItemAndAmount(new ItemStack(Items.gold_nugget), 27, player.inventory))
			{
				for (int i = 0; i < 27; i++)
				{
					player.inventory.consumeInventoryItem(Items.gold_nugget);
				}
				ExtendPlayerRot.get(player).setCurrentClass(message.className);
			}
		}
		return null;
	}

}

}

 

Explanation and guidance in this matter is very appreciated, thanks in advance.

Link to comment
Share on other sites

Ah so I'd make a ClassRequestPacket(registered server), which is what code I posted. And a ClassResponsePacket(registered client) which will be the return of ClassRequestPacketHandler?

 

like:

return new ClassResponsePacket(message,className);

 

or would it be:

Rot.net.sendTo(new ClassResponcePacket("Good",className), ctx.getServerHandler().playerEntity);

return null;

Link to comment
Share on other sites

Ok so I figured I'd ask this here since it is directly related to this topic, at least using the request and response.

 

Alright So I made the request packet (works, sets the players class) and the response (works as well, updates the players HUD and client effects)

 

However when I save and load, the player sees that their class is back to no class, and their stamina and mana are at the defaults, however their chosen class effects still work. As the server knows what the class is, but the client doesn't.

 

Now I'm using two data watchers for mana and stamina (current) but not for my class. Should I have the server constantly send class packets to the player? Or is there a way to just do a one time check so I'm not spamming packets back and forth needlessly

 

EDIT:

ok so I looked at some events, and I decided to with EntityJoinWorldEvent, and the PlayerEvent.Clone event to send a "whatAmI" request and it's working as I want it to, but is there a better way? or did I just figure out the correct way?

Link to comment
Share on other sites

IDK for datawatcher as I've never used it, but AFAIK it automatically updates the client (correct me if I'm wrong)

 

The way I do it for when entity joins world is the way coolAlias have done it in his IExtendedEntityProperties tutorial. It took similar approach to what you've done, using EntityJoinWorldEvent.

 

However, when the player dies, he will lose it properties (on server), so you should make some registry in the server that saves properties on death, it will restore in EntityJoinWorldEvent when the player respawns, the way coolAlias has done it doesn't save the properties, but rather resets if the server was shutdown, so the player must respawn before server shutdown for the properties to return, but I'm sure you can save it in a way or another.

 

So pretty much you're doing it the right way, as long as you don't want anything to stay on death.

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.

Announcements



×
×
  • Create New...

Important Information

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