Skip to content

Sending a Packet from the Client to the Server

Valk edited this page Feb 3, 2023 · 1 revision

Create a new packet class in Scripts/Netcode/Packets

namespace Sankari.Netcode; // do not forget to include this

// All CPacketXXXX are sent from the client, likewise all SPacketXXXX are sent from the server

// All client packets should start with 'CPacket'
// Replace 'PlayerData' with whatever name suits the packet
public class CPacketPlayerData : APacketClient // the class must extend from APacketClient
{
    // Use properties to setup data variables here
    public Vector2 Position { get; set; }
    public int Health { get; set; }
    public Dictionary<ushort, byte> RandomData { get; set; } // I could not think of a better name

    public override void Write(PacketWriter writer)
    {
	// The order things are written matters
        writer.Write(Position);
	writer.Write(Health);

	// The length must be written whenever sending any kind of list of data
	writer.Write((ushort)RandomData.Count); // cast to ushort because don't need that many values as a int

	foreach (var element in RandomData)
	{
	    writer.Write((ushort)element.Key); // sometimes it helps to cast for readability
	    writer.Write((byte)element.Value);
	}
    }

    public override void Read(PacketReader reader)
    {
	// The order things are read matters
	// A common mistake I do all the time is forget to assign the reader.ReadValue() to a variable
	// Don't just leave it as 'reader.ReadValue()', do 'var myValue = reader.ReadValue()'
        Position = reader.ReadVector2();
	Health = reader.ReadInt();

	// Read the length from the dictionary
	var length = reader.ReadUShort();

	// Do not forget to initialize the dictionary
	RandomData = new Dictionary<ushort, byte>();

	for (int i = 0; i < length; i++)
	{
	    var key = reader.ReadUShort(); // do not make the mistake of doing reader.ReadShort();
	    var value = reader.ReadByte();

	    // do not use RandomData[key] = value; because this encourages duplicates not being handled
	    // if a duplicate is added with RandomData.Add(key, value); the game will crash but this
	    // is what we want as this should be handled accordingly
	    RandomData.Add(key, value); 
	}
    }

    public override void Handle(ENet.Peer peer)
    {
	// This is handled server-side
	// Do something with the data
	var player = Net.Server.Players[(byte)peer.ID];

        player.Position = Position;
	player.Health = Health;
	player.RandomData = RandomData;
    }
}

Send the client packet to the server

// The following code is thread-safe, it can be executed from anywhere or in this case from the player script
// You will need to create the ClientPacketOpcode.PlayerData enum value in the ClientPacketOpcode enum
// All netcode opcode enums are located in Scripts/Netcode/_Opcodes.cs
Net.Client.Send(ClientPacketOpcode.PlayerData, new CPacketPlayerPosition
{
    Position = PlayerPosition,
    Health = PlayerHealth,
    RandomData = PlayerRandomData
});
Clone this wiki locally