Esempio n. 1
0
 public void Receive(byte[] buffer, out int length, out UnityEngine.Networking.NetworkEventType eventType)
 {
     lock (m_queueLock) {
         if (m_queue.Count == 0)
         {
             eventType = NetworkEventType.Nothing;
             buffer    = new byte[0];
             length    = 0;
         }
         else
         {
             var frame = m_queue.Dequeue();
             length    = frame.Length;
             eventType = frame.LastEventType;
             System.Buffer.BlockCopy(frame.Buffer, 0, buffer, 0, Mathf.Min(buffer.Length, frame.Length));
         }
     }
 }
Esempio n. 2
0
    public void ProcessBroadcasts()
    {
        int  connectionId;
        int  channelId;
        int  receivedSize;
        byte error;

        while (m_BroadcastHostId > -1)
        {
            UnityEngine.Networking.NetworkEventType ne = NetworkTransport.ReceiveFromHost(m_BroadcastHostId, out connectionId, out channelId, m_Buffer, m_Buffer.Length, out receivedSize, out error);

            if (ne == UnityEngine.Networking.NetworkEventType.Nothing)
            {
                break;
            }

            switch (ne)
            {
            case UnityEngine.Networking.NetworkEventType.BroadcastEvent:
            {
                int    _port;
                string address;
                NetworkTransport.GetBroadcastConnectionInfo(m_BroadcastHostId, out address, out _port, out error);
                NetworkTransport.GetBroadcastConnectionMessage(m_BroadcastHostId, m_Buffer, m_Buffer.Length, out receivedSize, out error);

                var reader = new NetworkReader(m_Buffer, null);

                int    port             = reader.ReadInt32();
                uint   token            = reader.ReadUInt32();
                string servername       = reader.ReadString();
                string levelname        = reader.ReadString();
                string gamemode         = reader.ReadString();
                int    connectedPlayers = reader.ReadInt32();
                int    maxPlayers       = reader.ReadInt32();

                if (address.StartsWith("::ffff:"))
                {
                    address = address.AfterFirst("::ffff:");
                }
                var        key = address + ":" + port;
                ServerInfo si  = null;
                for (var i = 0; i < m_KnownServers.Count; i++)
                {
                    if (m_KnownServers[i].Address == key)
                    {
                        si = m_KnownServers[i];
                        break;
                    }
                }
                if (si == null)
                {
                    si = new ServerInfo();
                    m_KnownServers.Add(si);
                    GameDebug.Log("New server: " + servername + " " + address + ":" + port + "  _port: " + _port);
                }
                si.Token        = token;
                si.Name         = servername;
                si.LevelName    = levelname;
                si.GameMode     = gamemode;
                si.Players      = connectedPlayers;
                si.MaxPlayers   = maxPlayers;
                si.Address      = key;
                si.LastSeenTime = Time.time;
            }
            break;
            }
        }
        for (var i = m_KnownServers.Count - 1; i >= 0; --i)
        {
            if (m_KnownServers[i].LastSeenTime < Time.time - 5.0f)
            {
                m_KnownServers.RemoveAt(i);
            }
        }
    }
Esempio n. 3
0
        public UdpTransport(bool useUnityThread = false, int queueSize = 16, int maxQueueSize = 34, int port = 12500)
        {
            Port = port;
            // Queue has to be at least 1 large
            queueSize          = Mathf.Max(queueSize, 1);
            maxQueueSize       = Mathf.Max(maxQueueSize, 4);
            m_nextConnectionId = 0;
            m_connectionIds    = new Dictionary <IPEndPoint, int> ();
            m_ips = new Dictionary <int, IPEndPoint> ();

            if (useUnityThread)
            {
            }

            m_udpClient = new UdpClient(Port);
            m_udpThread = new System.Threading.Thread(new ThreadStart(delegate {
                while (true)
                {
                    IPEndPoint remote = null;
                    var buffer        = m_udpClient.Receive(ref remote);

                    if (remote == null)
                    {
                        continue;
                    }

                    var isFirstConnection = false;
                    var connectionId      = -1;
                    if (!m_connectionIds.ContainsKey(remote))
                    {
                        m_nextConnectionId++;
                        connectionId             = m_nextConnectionId;
                        m_connectionIds [remote] = connectionId;
                        m_ips [connectionId]     = remote;
                        isFirstConnection        = true;
                    }
                    connectionId = m_connectionIds [remote];

                    UnityEngine.Networking.NetworkEventType eventType = NetworkEventType.Nothing;

                    if (isFirstConnection)
                    {
                        eventType = NetworkEventType.ConnectEvent;
                    }
                    else
                    {
                        eventType = NetworkEventType.DataEvent;
                    }

                    if (useUnityThread)
                    {
                        lock (m_queueLock) {
                            var frame = new Frame()
                            {
                                LastEventType = eventType,
                                Buffer        = buffer,
                                Length        = buffer.Length
                            };

                            // \O(1) but not \Theta(1) time

                            // If we have exceeded our queue size, toss K frames
                            if (m_queue.Count > queueSize)
                            {
                                // Since later frames have redundant input information, we can toss input frames
                                // TODO: We use Tcp for reliable messages
                                // m_queue.Clear ();
                                // In the meantime, inspect the frame and toss input frames if this is an input frame
                                if (buffer.Length > 0 &&
                                    buffer [0] == MessageType.Input)
                                {
                                    // Kill earlier input messages
                                    while (m_queue.Count > 0)
                                    {
                                        var upNext = m_queue.Peek();
                                        if (upNext.Length > 0 &&
                                            upNext.Buffer [0] == MessageType.Input)
                                        {
                                            m_queue.Dequeue();
                                        }
                                        else
                                        {
                                            // Clearly a connection or state event got in here...
                                            break;
                                        }
                                    }
                                }

                                if (buffer.Length > 0 &&
                                    buffer [0] == MessageType.AcknowledgeInput)
                                {
                                    // Kill earlier acknowledge input messages
                                    while (m_queue.Count > 0)
                                    {
                                        var upNext = m_queue.Peek();
                                        if (upNext.Length > 0 &&
                                            upNext.Buffer [0] == MessageType.AcknowledgeInput)
                                        {
                                            m_queue.Dequeue();
                                        }
                                        else
                                        {
                                            // Clearly a connection or state event got in here...
                                            break;
                                        }
                                    }
                                }
                            }

                            m_queue.Enqueue(frame);

                            if (m_queue.Count > maxQueueSize)
                            {
                                // "Throw an exception" outside of the lock
                                // TODO: Maybe this won't happen that often and memory won't leak.
                            }
                        }
                    }
                    else
                    {
                        if (Received != null)
                        {
                            Received(connectionId, UnreliableChannelId, eventType, buffer, 0, buffer.Length, 0);
                        }
                    }

                    if (m_shouldDisconnect)
                    {
                        break;
                    }
                }
                m_udpClient.Close();
            }));
        }