예제 #1
0
        private NetworkMessage ConvertOrderedUnreliableMessage(NetworkMessage input, Connection <T> connection)
        {
            if (input.sendType != NetworkMessageType.ORDERED_UNRELIABLE)
            {
                return(input);
            }
            int newSize = 12;

            if (input.data != null)
            {
                newSize += input.data.Length;
            }
            NetworkMessage converted = NetworkMessage.Create(-3, newSize, NetworkMessageType.UNORDERED_UNRELIABLE);

            DarkUtils.WriteInt32ToByteArray(connection.sendOrderID++, converted.data.data, 0);
            if (connection.sendOrderID == Int32.MaxValue)
            {
                connection.sendOrderID = 0;
            }
            DarkUtils.WriteInt32ToByteArray(input.type, converted.data.data, 4);
            DarkUtils.WriteInt32ToByteArray(newSize - 8, converted.data.data, 8);
            if (input.data != null)
            {
                Array.Copy(input.data.data, 0, converted.data.data, 12, input.data.Length);
            }
            input.Destroy();
            return(input);
        }
예제 #2
0
        public Connection <T> GetConnection(IPEndPoint endPoint)
        {
            Guid storeKey = DarkUtils.GuidFromIPEndpoint(endPoint);

            if (connections.ContainsKey(storeKey))
            {
                return(connections[storeKey]);
            }
            return(null);
        }
예제 #3
0
        internal void HandleRaw(byte[] data, int length, IPEndPoint endPoint)
        {
            if (length < 12)
            {
                return;
            }
            //Magic header, DARK
            if (data[0] != 68 || data[1] != 65 || data[2] != 82 || data[3] != 75)
            {
                return;
            }
            Connection <T> connection   = null;
            Guid           messageOwner = DarkUtils.GuidFromIPEndpoint(endPoint);

            if (!connections.ContainsKey(messageOwner))
            {
                if (connection == null)
                {
                    connection         = new Connection <T>();
                    connection.handler = this;
                    connection.reliableMessageHandler = new ReliableMessageHandler <T>(connection, this);
                    if (network.clientMode && serverConnection == null)
                    {
                        serverConnection = connection;
                    }
                }
                connection.lastReceiveTime = DateTime.UtcNow.Ticks;
                connection.remoteEndpoint  = endPoint;
                lock (connections)
                {
                    connections.Add(messageOwner, connection);
                }
                if (connectCallback != null)
                {
                    connection.state = connectCallback(connection);
                }
            }
            connection = connections[messageOwner];
            int messageType   = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 4));
            int messageLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 8));

            if (length < messageLength + 12)
            {
                //Malformed message
                return;
            }
            NetworkMessage nm = NetworkMessage.Create(messageType, messageLength, NetworkMessageType.UNORDERED_UNRELIABLE);

            if (nm.data != null && nm.data.Length > 0)
            {
                Array.Copy(data, 12, nm.data.data, 0, nm.data.Length);
            }
            Handle(nm, connection);
        }
예제 #4
0
 private void SendInitialHeartbeat(IPEndPoint endPoint)
 {
     DarkUtils.WriteMagicHeader(initialHeartBeat, 0);
     DarkUtils.WriteInt32ToByteArray(-1, initialHeartBeat, 4);
     DarkUtils.WriteInt32ToByteArray(8, initialHeartBeat, 8);
     DarkUtils.WriteInt64ToByteArray(DateTime.UtcNow.Ticks, initialHeartBeat, 12);
     //Send 4 times.
     for (int i = 0; i < 4; i++)
     {
         socket.SendTo(initialHeartBeat, endPoint);
     }
 }
예제 #5
0
 private int WriteRawMessageToBuffer(NetworkMessage nm)
 {
     DarkUtils.WriteMagicHeader(sendBuffer, 0);
     DarkUtils.WriteInt32ToByteArray(nm.type, sendBuffer, 4);
     if (nm.data == null || nm.data.Length == 0)
     {
         DarkUtils.WriteInt32ToByteArray(0, sendBuffer, 8);
         return(12);
     }
     DarkUtils.WriteInt32ToByteArray(nm.data.Length, sendBuffer, 8);
     Array.Copy(nm.data.data, 0, sendBuffer, 12, nm.data.Length);
     return(12 + nm.data.Length);
 }
예제 #6
0
        internal void SendHeartbeat()
        {
            lock (connections)
            {
                long currentTime = DateTime.UtcNow.Ticks;
                foreach (KeyValuePair <Guid, Connection <T> > c in connections)
                {
                    if (currentTime > c.Value.lastReceiveTime + TimeSpan.TicksPerSecond * 20)
                    {
                        disconnectList.Add(c.Key);
                    }
                    if (currentTime > (c.Value.lastHeartbeatTime + TimeSpan.TicksPerSecond))
                    {
                        c.Value.lastHeartbeatTime = currentTime;
                        NetworkMessage nm = NetworkMessage.Create(-1, 8, NetworkMessageType.UNORDERED_UNRELIABLE);
                        DarkUtils.WriteInt64ToByteArray(DateTime.UtcNow.Ticks, nm.data.data, 0);
                        SendMessageWithHighPriority(nm, c.Value);
                    }
                    RateControl <T> .Update(c.Value);

                    c.Value.reliableMessageHandler.Send();
                }
                foreach (Guid disconnectConnectionGuid in disconnectList)
                {
                    Connection <T> disconnectConnection = connections[disconnectConnectionGuid];
                    if (disconnectCallback != null)
                    {
                        disconnectCallback(disconnectConnection);
                    }
                    disconnectConnection.reliableMessageHandler.ReleaseAllObjects();
                    network.ReleaseAllObjects(disconnectConnection);
                    connections.Remove(disconnectConnectionGuid);
                }
                disconnectList.Clear();
            }
        }
        public NetworkMessage GetMessage(int id, Connection <T> connection)
        {
            if (finished)
            {
                return(null);
            }
            int checkedThisRound = 0;
            //Always assume at least 10ms lag
            long latency = connection.latency;

            if (latency < 10 * TimeSpan.TicksPerMillisecond)
            {
                latency = 10 * TimeSpan.TicksPerMillisecond;
            }
            //Resend message if it has been 2 RTT's
            long checkTime = DateTime.UtcNow.Ticks - (latency * 2);
            bool found     = false;

            while (!found)
            {
                if (sendParts[nextSendPart] >= 0 && checkTime > sendParts[nextSendPart])
                {
                    found = true;
                }
                else
                {
                    nextSendPart++;
                    if (nextSendPart == sendPartsLength)
                    {
                        nextSendPart = 0;
                    }
                    checkedThisRound++;
                    if (checkedThisRound == sendPartsLength)
                    {
                        //We checked to see if we could send any chunks and didn't find any.
                        break;
                    }
                }
            }
            if (found)
            {
                int totalSize = 4;
                if (networkMessage.data != null)
                {
                    totalSize += networkMessage.data.Length;
                }
                int thisSendSize = 500;
                if (nextSendPart == (sendPartsLength - 1))
                {
                    thisSendSize = totalSize % 500;
                }
                //This is a retransmit, count the lost data
                if (sendParts[nextSendPart] != 0)
                {
                    connection.dataLoss += thisSendSize;
                }
                connection.dataSent += thisSendSize;
                NetworkMessage sendMessage = NetworkMessage.Create(-4, 12 + thisSendSize, NetworkMessageType.UNORDERED_UNRELIABLE);
                DarkUtils.WriteInt32ToByteArray(id, sendMessage.data.data, 0);
                DarkUtils.WriteInt32ToByteArray(nextSendPart, sendMessage.data.data, 4);
                //Don't include the header in the message length, we know it's there
                DarkUtils.WriteInt32ToByteArray(totalSize - 4, sendMessage.data.data, 8);
                if (nextSendPart == 0)
                {
                    DarkUtils.WriteInt32ToByteArray(networkMessage.type, sendMessage.data.data, 12);
                    if (networkMessage.data != null && networkMessage.data.Length > 0)
                    {
                        Array.Copy(networkMessage.data.data, 0, sendMessage.data.data, 16, thisSendSize - 4);
                    }
                }
                else
                {
                    Array.Copy(networkMessage.data.data, (nextSendPart * 500) - 4, sendMessage.data.data, 12, thisSendSize);
                }
                sendParts[nextSendPart] = -2;
                nextSendPart++;
                if (nextSendPart == sendPartsLength)
                {
                    nextSendPart = 0;
                }
                return(sendMessage);
            }
            return(null);
        }