Skip to content

Custom Packets

Ian edited this page Oct 17, 2019 · 22 revisions

Creating your own packet type is easy, but to make it even easier i would simply copy and paste one of the pre-existing packets, and modify it to your own.

First, here are some simple rules about creating a packet:

  • A packet must inherit Packet
  • A packet must have a constructor, taking in a string and passing it to base.

Here is the definition for the TestPacket:

  public class TestPacket : Packet<TestPacket>
    {
        public string testString;

        public TestPacket(string packet_name) : base(packet_name){}

        public override TestPacket OpenPacketFromMessage(NetIncomingMessage msg)
        {
            TestPacket packet = new TestPacket(packet_identifier)
            {
                testString = msg.ReadString()
            };

            return packet;
        }

        public override NetOutgoingMessage PackPacketIntoMessage(NetOutgoingMessage msg,  TestPacket packet)
        {
            msg.Write(packet.testString);
            return msg;
        }
       
    }

'OpenPacketFromMessage' is called when the packet is received. This expects a returned packet, with the information from the message. For each thing that is written to the packet in the 'PackPacketIntoMessage' method, 'OpenPacketFromMessage' expects you to read each field to a packet object.

'PackPacketIntoMessage' is called before a packet is packaged and sent. It requires you to write each field to the message, and return said message.

Let's create a custom packet, which can store an int, a string and a float.

  public class IntStringFloat: Packet<IntStringFloat>
    {
        public string int;
        public string string;
        public string float;

        public IntStringFloat(string packet_name) : base(packet_name){}

        public override IntStringFloatOpenPacketFromMessage(NetIncomingMessage msg)
        {
            IntStringFloat packet = new IntStringFloat(packet_identifier);
            int = msg.ReadInt32();
            string = msg.ReadString();
            float = msg.ReadFloat();

            return packet;
        }

        public override NetOutgoingMessage PackPacketIntoMessage(NetOutgoingMessage msg,  IntStringFloat packet)
        {
            msg.Write(packet.int);
            msg.Write(packet.string);
            msg.Write(packet.float);

            return msg;
        }
       
    }

With a connected client, we can simply do the following to send to the server.

IntStringFloat packet = new IntStringFloat("Example");
packet.int = 10;
packet.string = "Hello";
packet.float = 1.5f;

client.SendPacketToServer(packet);

This can then be received on the serverside:

 server.OnReceive("Example", packetObj => {
       PacketData<IntStringFloat> isfPacketData = new PacketData<IntStringFloat>(packetObj);

       Console.WriteLine("Received Int: " + isfPacketData.packet.int);
       Console.WriteLine("Received Int: " + isfPacketData.packet.string);
       Console.WriteLine("Received Int: " + isfPacketData.packet.float);

       return true;
});

Both the client and server have send and receive functions.

As you can see, this is a quite simple process. There are a few things to touch on.

"Example" is simply the name given to this packet, and is the packet the corresponding client or server's receive function looks for. This is defined above, and this name can be any string.

PacketData is a small wrapped used to easily access the received data. This is passed the data received from the method and then allows you access to the information contained in the packet. Including sender information.

Currently, the boolean returned on the receive method does nothing. Future updates to the library will include some functionality for this.

Clone this wiki locally