void *FileTransferManager_tep(void *arg)
{
  CFileTransferManager *ftman = (CFileTransferManager *)arg;

  fd_set f_recv, f_send;
  struct timeval *tv;
  struct timeval tv_updates = { 2, 0 };
  int l, nSocketsAvailable, nCurrentSocket;
  char buf[2];

  if (ftman->m_nDirection == D_SENDER)
  {
    if (!ftman->ConnectToFileServer(ftman->m_nPort))
    {
      ftman->PushFileTransferEvent(FT_ERRORxCONNECT);
      return NULL;
    }
  }
  else if (ftman->m_nDirection != D_RECEIVER)
    return NULL;

  while (true)
  {
    f_recv = ftman->sockman.SocketSet();
    l = ftman->sockman.LargestSocket() + 1;

    // Add the new socket pipe descriptor
    FD_SET(ftman->pipe_thread[PIPE_READ], &f_recv);
    if (ftman->pipe_thread[PIPE_READ] >= l)
      l = ftman->pipe_thread[PIPE_READ] + 1;

    // Set up the send descriptor
    FD_ZERO(&f_send);
    if (ftman->m_nState == FT_STATE_SENDINGxFILE)
    {
      FD_SET(ftman->ftSock.Descriptor(), &f_send);
      // No need to check "l" as ftSock is already in the read list
    }

    // Prepare max timeout if necessary
    if (ftman->m_nUpdatesEnabled &&
        (ftman->m_nState == FT_STATE_SENDINGxFILE ||
         ftman->m_nState == FT_STATE_RECEIVINGxFILE) )
    {
      tv_updates.tv_sec = ftman->m_nUpdatesEnabled;
      tv_updates.tv_usec = 0;
      tv = &tv_updates;
    }
    else
    {
      tv = NULL;
    }

    nSocketsAvailable = select(l, &f_recv, &f_send, NULL, tv);

    // Check if we timed out
    if (tv != NULL && nSocketsAvailable == 0)
    {
      ftman->PushFileTransferEvent(FT_UPDATE);
      gettimeofday(&ftman->tv_lastupdate, NULL);
    }

    nCurrentSocket = 0;
    while (nSocketsAvailable > 0 && nCurrentSocket < l)
    {
      if (FD_ISSET(nCurrentSocket, &f_recv))
      {
        // New socket event ----------------------------------------------------
        if (nCurrentSocket == ftman->pipe_thread[PIPE_READ])
        {
          read(ftman->pipe_thread[PIPE_READ], buf, 1);
          if (buf[0] == 'R')
          {
            DEBUG_THREADS("[FileTransferManager_tep] Reloading socket info.\n");
          }
          else if (buf[0] == 'X')
          {
            DEBUG_THREADS("[FileTransferManager_tep] Exiting.\n");
            pthread_exit(NULL);
          }
        }

        // Connection on the server port ---------------------------------------
        else if (nCurrentSocket == ftman->ftServer.Descriptor())
        {
          if (ftman->ftSock.Descriptor() != -1)
          {
            gLog.Warn(tr("%sFile Transfer: Receiving repeat incoming connection.\n"), L_WARNxSTR);
          }
          else
          {
            ftman->ftServer.RecvConnection(ftman->ftSock);
            ftman->sockman.AddSocket(&ftman->ftSock);
            ftman->sockman.DropSocket(&ftman->ftSock);

            ftman->m_nState = FT_STATE_HANDSHAKE;
            gLog.Info(tr("%sFile Transfer: Received connection.\n"), L_TCPxSTR);
          }
        }

        // Message from connected socket----------------------------------------
        else if (nCurrentSocket == ftman->ftSock.Descriptor())
        {
          ftman->ftSock.Lock();
          bool ok = ftman->ProcessPacket();
          ftman->ftSock.Unlock();
          if (!ok)
          {
            ftman->CloseConnection();
            ftman->PushFileTransferEvent(ftman->m_nResult);
          }
        }

        else
        {
          gLog.Warn(tr("%sFile Transfer: No such socket.\n"), L_WARNxSTR);
        }

        nSocketsAvailable--;
      }
      else if (FD_ISSET(nCurrentSocket, &f_send))
      {
        if (nCurrentSocket == ftman->ftSock.Descriptor())
        {
          ftman->ftSock.Lock();
          bool ok = ftman->SendFilePacket();
          ftman->ftSock.Unlock();
          if (!ok)
          {
            ftman->CloseConnection();
            ftman->PushFileTransferEvent(ftman->m_nResult);
          }
        }
        nSocketsAvailable--;
      }

      nCurrentSocket++;
    }
  }
  return NULL;
}
Example #2
0
void *FileTransferManager_tep(void *arg)
{
  CFileTransferManager *ftman = (CFileTransferManager *)arg;

  fd_set f_recv, f_send;
  struct timeval *tv;
  struct timeval tv_updates = { 2, 0 };
  int l, nSocketsAvailable, nCurrentSocket;

  if (!ftman->isReceiver())
  {
    if (!ftman->ConnectToFileServer(ftman->m_nPort))
    {
      ftman->PushFileTransferEvent(FT_ERRORxCONNECT);
      return NULL;
    }
  }
  else if (!ftman->isReceiver())
    return NULL;

  while (true)
  {
    f_recv = ftman->sockman.socketSet();
    l = ftman->sockman.LargestSocket() + 1;

    // Add the new socket pipe descriptor
    FD_SET(ftman->myThreadPipe.getReadFd(), &f_recv);
    if (ftman->myThreadPipe.getReadFd() >= l)
      l = ftman->myThreadPipe.getReadFd() + 1;

    // Set up the send descriptor
    FD_ZERO(&f_send);
    if (ftman->m_nState == FT_STATE_SENDINGxFILE)
    {
      FD_SET(ftman->ftSock.Descriptor(), &f_send);
      // No need to check "l" as ftSock is already in the read list
    }

    // Prepare max timeout if necessary
    if (ftman->m_nUpdatesEnabled &&
        (ftman->m_nState == FT_STATE_SENDINGxFILE ||
         ftman->m_nState == FT_STATE_RECEIVINGxFILE) )
    {
      tv_updates.tv_sec = ftman->m_nUpdatesEnabled;
      tv_updates.tv_usec = 0;
      tv = &tv_updates;
    }
    else
    {
      tv = NULL;
    }

    nSocketsAvailable = select(l, &f_recv, &f_send, NULL, tv);

    if (nSocketsAvailable == -1)
    {
      // Something is very wrong, most likely we've lost control of a file
      //   descriptor and select will continue to fail causing this thread to
      //   spin so better to just give up and exit.

      gLog.warning(tr("File Transfer: select failed, aborting thread: %s"), strerror(errno));
      pthread_exit(NULL);
    }

    // Check if we timed out
    if (tv != NULL && nSocketsAvailable == 0)
    {
      ftman->PushFileTransferEvent(FT_UPDATE);
      gettimeofday(&ftman->tv_lastupdate, NULL);
    }

    nCurrentSocket = 0;
    while (nSocketsAvailable > 0 && nCurrentSocket < l)
    {
      if (FD_ISSET(nCurrentSocket, &f_recv))
      {
        // New socket event ----------------------------------------------------
        if (nCurrentSocket == ftman->myThreadPipe.getReadFd())
        {
          char buf = ftman->myThreadPipe.getChar();
          if (buf == 'R')
          {
            DEBUG_THREADS("[FileTransferManager_tep] Reloading socket info.\n");
          }
          else if (buf == 'X')
          {
            DEBUG_THREADS("[FileTransferManager_tep] Exiting.\n");
            pthread_exit(NULL);
          }
        }

        // Connection on the server port ---------------------------------------
        else if (nCurrentSocket == ftman->ftServer.Descriptor())
        {
          if (ftman->ftSock.Descriptor() != -1)
          {
            gLog.warning(tr("File Transfer: Receiving repeat incoming connection."));

            // Dump the extra connection to clear the listen socket queue
            Licq::TCPSocket ts;
            if (ftman->ftServer.RecvConnection(ts))
              ts.CloseConnection();
          }
          else
          {
            if (ftman->ftServer.RecvConnection(ftman->ftSock))
            {
              ftman->sockman.AddSocket(&ftman->ftSock);
              ftman->sockman.DropSocket(&ftman->ftSock);

              ftman->m_nState = FT_STATE_HANDSHAKE;
              gLog.info(tr("File Transfer: Received connection."));
            }
            else
            {
              gLog.error(tr("File Transfer: Unable to receive new connection."));
            }
          }
        }

        // Message from connected socket----------------------------------------
        else if (nCurrentSocket == ftman->ftSock.Descriptor())
        {
          ftman->ftSock.Lock();
          bool ok = ftman->ProcessPacket();
          ftman->ftSock.Unlock();
          if (!ok)
          {
            ftman->CloseConnection();
            ftman->PushFileTransferEvent(ftman->m_nResult);
          }
        }

        else
        {
          gLog.warning(tr("File Transfer: No such socket."));
        }

        nSocketsAvailable--;
      }
      else if (FD_ISSET(nCurrentSocket, &f_send))
      {
        if (nCurrentSocket == ftman->ftSock.Descriptor())
        {
          ftman->ftSock.Lock();
          bool ok = ftman->SendFilePacket();
          ftman->ftSock.Unlock();
          if (!ok)
          {
            ftman->CloseConnection();
            ftman->PushFileTransferEvent(ftman->m_nResult);
          }
        }
        nSocketsAvailable--;
      }

      nCurrentSocket++;
    }
  }
  return NULL;
}
void CNetworkManager::Process()
{
	// Get our file transfer manager
	CFileTransferManager * pFileTransferManager = g_pClient->GetFileTransfer();

	// If our file transfer class exists process it
	if(pFileTransferManager)
		pFileTransferManager->Process();

	// Have we joined a server and not joined a game yet?
	if(m_bJoinedServer && !m_bJoinedGame)
	{
		// Get our local player
		CLocalPlayer * pLocalPlayer = g_pClient->GetLocalPlayer();

		// Is the file transfer list empty?
		if(pFileTransferManager->IsComplete() && pLocalPlayer->IsConnectFinished())
		{
			// Flag ourselves as joined a game
			m_bJoinedGame = true;

			// Respawn the local player
			pLocalPlayer->Respawn();
		}
	}

	if(!m_pNetClient)
		return;

	// Process the net client
	m_pNetClient->Process();

	// Are we connected to a server?
	if(m_pNetClient->IsConnected())
	{
		// If our streamer exists, process it
		CStreamer * pStreamer = g_pClient->GetStreamer();

		if(pStreamer)
			pStreamer->Pulse();

		// Is our script timer manager exists, process it
		CScriptTimerManager * pScriptTimerManager = g_pClient->GetClientScriptManager()->GetScriptTimerManager();
		if(pScriptTimerManager)
			pScriptTimerManager->Pulse();

		// If our player manager exists process it
		CPlayerManager * pPlayerManager = g_pClient->GetPlayerManager();

		if(pPlayerManager)
			pPlayerManager->Pulse();

		// If our vehicle manager exists process it
		CVehicleManager * pVehicleManager = g_pClient->GetVehicleManager();

		if(pVehicleManager)
			pVehicleManager->Pulse();

		// If our checkpoint manager exists process it
		CCheckpointManager * pCheckpointManager = g_pClient->GetCheckpointManager();

		if(pCheckpointManager)
			pCheckpointManager->Pulse();

		// If our object manager exists process it
		CObjectManager * pObjectManager = g_pClient->GetObjectManager();

		if(pObjectManager)
			pObjectManager->Process();

		// Process the audio manager
		CAudioManager * pAudioManager = g_pClient->GetAudioManager();

		if(pAudioManager)
			pAudioManager->Process();

		// Process the actor manager
		CActorManager * pActorManager = g_pClient->GetActorManager();

		if(pActorManager)
			pActorManager->Process();
	}
}