/// <summary>
        /// Add a reliable wrapper to a packet
        /// </summary>
        /// <param name="packet">Message Packet</param>
        /// <returns>New message packet</returns>
        public Byte[] GetReliablePacket(Byte[] packet)
        {
            // Create a new reliable packet
            ReliablePacket reliablePacket = new ReliablePacket();

            // Set the packet data
            reliablePacket.TransactionId = m_nTransactionId;
            reliablePacket.Message       = packet;
            reliablePacket.TimeStamp     = TimeSpan.FromMilliseconds(Environment.TickCount);

            // Increment the transaction identifier
            m_nTransactionId++;

            // Lock the mutex
            if (m_mutex.WaitOne(500, false))
            {
                // Add the reliable packet to the list to be acknowleged
                m_reliableList.Add(reliablePacket.TransactionId, reliablePacket);

                // release the mutex
                m_mutex.ReleaseMutex();
            }
            // return the packet data
            return(reliablePacket.Packet);
        }
Example #2
0
        public override ChanneledPacket CreateOutgoingMessage(byte[] payload, int offset, int length)
        {
            ReliablePacket message = new ReliablePacket(++_lastOutboundSequenceNumber, payload, offset, length);

            _outgoingPendingMessages.Add(message.Sequence, message);

            return(message);
        }
        /// <summary>
        /// Sends a packet to the connection.
        /// </summary>
        /// <param name="packet">The packet to send.</param>
        public void SendPacket(NetOutboundPacket packet)
        {
            if (packet.HasId)
            {
                throw new NetException(
                          "Cannot send packet twice, please create a new packet or clone this one before sending another time.");
            }

            // Remove the packets padding
            packet.RemovePadding();

            // Setup the packet and make it ready for sending
            SetupOutboundPacket(packet);

            // Write the packet's header and set it's Id
            WriteOutboundPacketHeader(packet);

            // Check if this packet needs to be split into a partial
            if (MTU > 0 && packet.Length > MTU && !packet.isPartial)
            {
                // Split the packet into partials
                NetOutboundPacket[] partials = SplitPacketIntoPartials(packet);
                for (int i = 0; i < partials.Length; i++)
                {
                    // Send the partials as seperate packets
                    SendPacket(partials[i]);
                }

                // Stop handling the too large packet
                return;
            }

            // Handle the sending based on delivery method
            if (packet.DeliveryMethod == NetDeliveryMethod.Unreliable)
            {
                // No extra work needed, just place in outbound queue
                AddPacketToChunkQueue(packet);
            }
            else if (packet.DeliveryMethod == NetDeliveryMethod.Reliable)
            {
                // Create the reliable packet handler and add it to the reliable queue
                ReliablePacket reliablePacket = new ReliablePacket(packet);
                if (!reliableOutboundPacketQueue.TryAdd(packet.Id, reliablePacket))
                {
                    NetLogger.LogError("Failed to add packet to the reliable outbound queue. Id: {0}, Type: {1}, DeliveryMethod: {2}",
                                       packet.Id, packet.Type, packet.DeliveryMethod);
                }

                // Attempt first send
                AddPacketToChunkQueue(packet);
            }
            else if (packet.DeliveryMethod == NetDeliveryMethod.ReliableOrdered)
            {
                // Create the reliable packet handler and add it to the ordered reliable queue
                ReliablePacket reliablePacket = new ReliablePacket(packet);
                reliableOrderedOutboundPacketQueue.Enqueue(reliablePacket);
            }
        }
Example #4
0
        public void ServerRoomManageAnswer()
        {
            MvsAServer t = new MvsAServer(socket, end, dataLenght, 4, 3);

            t.CreateRoom();
            ReliablePacket p = new ReliablePacket(5);

            p.command = (int)Command.DEATH;
            p.end     = t.CurrentEndPoint;
            t.rooms[0].reliablePackets.Add(p);
            t.rooms[0].ManageAnswer((int)Command.DEATH);

            Assert.That(t.rooms[0].reliablePackets.Count, Is.EqualTo(0));
        }
Example #5
0
        public override ChanneledPacket HandleIncomingMessagePoll(byte[] buffer, int size, out bool hasMore)
        {
            // Reliable has one message in equal no more than one out.
            hasMore = false;

            ReliablePacket packet = new ReliablePacket();

            packet.Read(buffer, size);

            if (packet.Sequence <= _incomingLowestAckedSequence || _incomingAckedPackets.ContainsKey(packet.Sequence))
            {
                // They didnt get our ack.

                // TODO: Send ack
                return(null);
            }
            else if (packet.Sequence == _incomingLowestAckedSequence + 1)
            {
                // This is the "next" packet

                do
                {
                    // Remove previous
                    _incomingAckedPackets.Remove(_incomingLowestAckedSequence);
                    _incomingLowestAckedSequence++;
                }while (packet.Sequence == _incomingLowestAckedSequence + 1);

                // TODO: Send ack

                return(packet);
            }
            else if (SequencingUtils.Distance(packet.Sequence, _incomingLowestAckedSequence, sizeof(ushort)) > 0 && !_incomingAckedPackets.ContainsKey(packet.Sequence))
            {
                // This is a future packet

                _incomingAckedPackets.Add(packet.Sequence, packet);

                // TODO: Send ack

                return(packet);
            }

            return(null);
        }
Example #6
0
        /// <summary>
        /// Receive a packet from the server
        /// </summary>
        /// <returns>Received packet data</returns>
        public Byte[] ReceivePacket()
        {
            ReliablePacket   pReliablePacket = new ReliablePacket();
            AcknowlegePacket pAckPacket      = new AcknowlegePacket();

            Byte[]           pData             = new Byte[0];
            ClusteredPacket  pClusteredPacket  = new ClusteredPacket();
            ChunkBodyPacket  pChunkBodyPacket  = new ChunkBodyPacket();
            ChunkTailPacket  pChunkTailPacket  = new ChunkTailPacket();
            LargeChunkPacket pLargeChunkPacket = new LargeChunkPacket();

            // Check if there are any elements on the queue
            if (m_pReceiveQueue.Count > 0)
            {
                // Get the next element from the receive queue
                pData = (Byte[])(m_pReceiveQueue.Dequeue());

                if (pData != null)
                {
                    // Write the data to the packet loggers
                    m_packetLogger(PacketDirection.Receive, pData);

                    // Check if the message is reliable
                    if (pData[0] == 0x00)
                    {
                        switch (pData[1])
                        {
                        case 0x03:
                            // Set the packet information
                            pReliablePacket.Packet = pData;

                            // Extract the message
                            pData = pReliablePacket.Message;

                            // Increment the reliable receive counter
                            m_nReliablePacketsReceived++;

                            // Set the acknowlege transaction identifier and transmit
                            pAckPacket.TransactionId = pReliablePacket.TransactionId;
                            TransmitPacket(pAckPacket.Packet);
                            break;

                        case 0x04:
                            // Set the acknowlegement packet data
                            pAckPacket.Packet = pData;

                            // Handle the Acknowlege packet
                            m_reliableMessageHandler.HandleAcknowlegement(pAckPacket.TransactionId);
                            break;
                        }

                        // Check if the packet is a chunk body packet
                        if ((pData[0] == 0x00) && (pData[1] == 0x08))
                        {
                            // Set the chunk data packet
                            pChunkBodyPacket.Packet = pData;

                            // Get the message packet from the buffer
                            pData = pChunkBodyPacket.Message;

                            // Append the data to the buffer
                            m_chunkBuffer.Write(pData, 0, pData.Length);

                            // Clear the returned data
                            pData = new Byte[0];
                        }
                        // Check if the packet is a chunk tail packet
                        else if ((pData[0] == 0x00) && (pData[1] == 0x09))
                        {
                            // Set the chunk data packet
                            pChunkTailPacket.Packet = pData;

                            // Get the message packet from the buffer
                            pData = pChunkTailPacket.Message;

                            // Append the data to the chunk buffer
                            m_chunkBuffer.Write(pData, 0, pData.Length);

                            // return the full data packet
                            pData = m_chunkBuffer.ToArray();

                            // Clear the chunk buffer
                            m_chunkBuffer.Position = 0;
                        }
                        // Check if the packet is a large chunk packet
                        else if ((pData[0] == 0x00) && (pData[1] == 0x0A))
                        {
                            // Set the large chunk packet
                            pLargeChunkPacket.Packet = pData;

                            // Get the message packet from the buffer
                            pData = pLargeChunkPacket.Message;

                            // Append the message to the large buffer
                            m_largeBuffer.Write(pData, 0, pData.Length);

                            // Check if the packet is complete
                            if (m_largeBuffer.Length == pLargeChunkPacket.TotalLength)
                            {
                                // return the full data packet
                                pData = m_largeBuffer.ToArray();

                                // Clear the chunk buffer
                                m_largeBuffer.Position = 0;
                            }
                            else
                            {
                                // Clear the returned data
                                pData = new Byte[0];
                            }
                        }
                        // Check if the packet is a clustered packet
                        else if ((pData[0] == 0x00) && (pData[1] == 0x0E))
                        {
                            // Set the clustered packet data
                            pClusteredPacket.Packet = pData;

                            // Get the enumerator for the packet list
                            IEnumerator pEnum = pClusteredPacket.Packets.GetEnumerator();

                            while (pEnum.MoveNext())
                            {
                                // Add the next element to the receive queue
                                m_pReceiveQueue.Enqueue((Byte[])pEnum.Current);
                            }

                            // Clear the returned data
                            pData = new Byte[0];
                        }
                    }
                }
            }

            return(pData);
        }