// Remove players that have disconnected
    void CleanClients()
    {
        List <NetworkObjects.NetworkPlayer> droppedPlayers = new List <NetworkObjects.NetworkPlayer>();

        for (int k = 0; k < players.Count; k++)
        {
            if ((System.DateTime.Now - players[k].lastBeat).TotalSeconds > 5.0f)
            {
                droppedPlayers.Add(players[k]);
                players.RemoveAt(k);
                --k;
            }
        }

        for (int i = 0; i < m_Connections.Length; i++)
        {
            if (!m_Connections[i].IsCreated)
            {
                for (int j = 0; j < players.Count; j++)
                {
                    m_Connections.RemoveAtSwapBack(i);
                }
                --i;
            }
        }

        if (droppedPlayers.Count > 0)
        {
            DropPlayerMsg dpMsg = new DropPlayerMsg(droppedPlayers);
            for (int i = 0; i < m_Connections.Length; i++)
            {
                SendToClient(JsonUtility.ToJson(dpMsg), m_Connections[i]);
            }
        }
    }
    void OnData(DataStreamReader stream)
    {
        NativeArray <byte> bytes = new NativeArray <byte>(stream.Length, Allocator.Temp);

        stream.ReadBytes(bytes);
        string        recMsg = Encoding.ASCII.GetString(bytes.ToArray());
        NetworkHeader header = JsonUtility.FromJson <NetworkHeader>(recMsg);

        switch (header.cmd)
        {
        case Commands.NEW_CLIENT:
            NewClientMsg ncMsg1 = JsonUtility.FromJson <NewClientMsg>(recMsg);
            SpawnPlayer(ncMsg1.player);
            Debug.Log("Client Msg: New Client message received!");
            break;

        case Commands.CLIENT_DROP:
            DropPlayerMsg dpMsg = JsonUtility.FromJson <DropPlayerMsg>(recMsg);
            RemovePlayers(dpMsg.players);
            Debug.Log("Client Msg: Client drop message received!");
            break;

        case Commands.CLIENT_LIST:
            PlayerListMsg nplMsg = JsonUtility.FromJson <PlayerListMsg>(recMsg);
            for (int i = 0; i < nplMsg.players.Length; i++)
            {
                SpawnPlayer(nplMsg.players[i]);
            }
            Debug.Log("Client Msg: Client list message received!");
            break;

        case Commands.PLAYER_UPDATE:
            PlayerUpdateMsg puMsg = JsonUtility.FromJson <PlayerUpdateMsg>(recMsg);
            PlayerUpdate(puMsg.updatedPlayers);
            break;

        case Commands.SERVER_UPDATE:
            ServerUpdateMsg suMsg = JsonUtility.FromJson <ServerUpdateMsg>(recMsg);
            Debug.Log("Client Msg: Server update message received!");
            break;

        case Commands.PLAYER_ID:
            NewClientMsg ncMsg2 = JsonUtility.FromJson <NewClientMsg>(recMsg);
            playerID = ncMsg2.player.id;
            SpawnPlayer(ncMsg2.player);
            break;

        default:
            Debug.Log("Client Msg: Unrecognized message received!");
            break;
        }
    }
    void OnData(DataStreamReader stream)
    {
        NativeArray <byte> bytes = new NativeArray <byte>(stream.Length, Allocator.Temp);

        stream.ReadBytes(bytes);
        string        recMsg = Encoding.ASCII.GetString(bytes.ToArray());
        NetworkHeader header = JsonUtility.FromJson <NetworkHeader>(recMsg);

        switch (header.cmd)
        {
        case Commands.NEW_CLIENT:
            NewClientMsg newClientMsg = JsonUtility.FromJson <NewClientMsg>(recMsg);
            SpawnPlayer(newClientMsg.player);
            Debug.Log("New client");
            break;

        case Commands.PLAYER_UPDATE:
            PlayerUpdateMsg puMsg = JsonUtility.FromJson <PlayerUpdateMsg>(recMsg);
            UpdatePlayer(puMsg.updatedPlayers);
            //Debug.Log("Player updated");
            break;

        case Commands.SERVER_UPDATE:
            ServerUpdateMsg suMsg = JsonUtility.FromJson <ServerUpdateMsg>(recMsg);
            Debug.Log("Server update message received!");
            break;

        case Commands.LIST_CLIENT:
            PlayerListMsg nplMsg = JsonUtility.FromJson <PlayerListMsg>(recMsg);
            SpawnPlayers(nplMsg.players);
            Debug.Log("List_Client");
            break;

        case Commands.MY_ID:
            NewClientMsg ncMsg = JsonUtility.FromJson <NewClientMsg>(recMsg);
            clientId = ncMsg.player.id;
            SpawnPlayer(ncMsg.player);
            break;

        case Commands.DROP_CLIENT:
            DropPlayerMsg dpMsg = JsonUtility.FromJson <DropPlayerMsg>(recMsg);
            DestroyPlayers(dpMsg.players);
            Debug.Log("Drop players");
            break;

        default:
            Debug.Log("Unrecognized message received!");
            break;
        }
    }
    void Update()
    {
        m_Driver.ScheduleUpdate().Complete();

        // CleanUpConnections
        for (int i = 0; i < m_Connections.Length; i++)
        {
            if (!m_Connections[i].IsCreated)
            {
                for (int j = 0; j < playerList.Count; j++)
                {
                    m_Connections.RemoveAtSwapBack(i);
                }
                i--;
            }
        }

        List <NetworkObjects.NetworkPlayer> droppedPlayers = new List <NetworkObjects.NetworkPlayer>();

        for (int i = 0; i < playerList.Count; i++)
        {
            if ((System.DateTime.Now - playerList[i].prevBeat).TotalSeconds > heartbeatTime)
            {
                NetworkObjects.NetworkPlayer temp = playerList[i];
                playerList.RemoveAt(i--);
                droppedPlayers.Add(temp);
            }
        }

        if (droppedPlayers.Count > 0)
        {
            DropPlayerMsg dpMsg = new DropPlayerMsg(droppedPlayers);
            for (int i = 0; i < m_Connections.Length; i++)
            {
                SendToClient(JsonUtility.ToJson(dpMsg), m_Connections[i]);
            }
        }

        // AcceptNewConnections
        NetworkConnection c = m_Driver.Accept();

        while (c != default(NetworkConnection))
        {
            OnConnect(c);

            // Check if there is another new connection
            c = m_Driver.Accept();
        }


        // Read Incoming Messages
        DataStreamReader stream;

        for (int i = 0; i < m_Connections.Length; i++)
        {
            Assert.IsTrue(m_Connections[i].IsCreated);

            NetworkEvent.Type cmd;
            cmd = m_Driver.PopEventForConnection(m_Connections[i], out stream);
            while (cmd != NetworkEvent.Type.Empty)
            {
                if (cmd == NetworkEvent.Type.Data)
                {
                    OnData(stream, i);
                }
                else if (cmd == NetworkEvent.Type.Disconnect)
                {
                    OnDisconnect(i);
                }

                cmd = m_Driver.PopEventForConnection(m_Connections[i], out stream);
            }
        }
    }