Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "stdafx.h"
#include "service_conn_mgr.h"
#include "vmpi.h"
#include "tier0/dbg.h"
#include "tcpsocket_helpers.h"
#define SERVICECONNMGR_CONNECT_ATTEMPT_INTERVAL 1000
// ------------------------------------------------------------------------------------------- //
// CServiceConn.
// ------------------------------------------------------------------------------------------- //
CServiceConn::CServiceConn() { m_pSocket = NULL; }
CServiceConn::~CServiceConn() { if ( m_pSocket ) m_pSocket->Release(); }
// ------------------------------------------------------------------------------------------- //
// CServiceConnMgr.
// ------------------------------------------------------------------------------------------- //
CServiceConnMgr::CServiceConnMgr() { m_bServer = false; m_bShuttingDown = false; m_pListenSocket = NULL; }
CServiceConnMgr::~CServiceConnMgr() { Term(); }
bool CServiceConnMgr::InitServer() { Term();
m_bServer = true; // Create a socket to listen on.
for ( int iPort=VMPI_SERVICE_FIRST_UI_PORT; iPort <= VMPI_SERVICE_LAST_UI_PORT; iPort++ ) { m_pListenSocket = CreateTCPListenSocketEmu( iPort, 5 ); if ( m_pListenSocket ) break; } if ( !m_pListenSocket ) return false;
return true; }
bool CServiceConnMgr::InitClient() { Term();
m_bServer = false;
AttemptConnect(); return true; }
void CServiceConnMgr::Term() { m_bShuttingDown = true; // This prevents some reentrancy.
// Get rid of our registry key.
if ( m_pListenSocket ) { m_pListenSocket->Release(); m_pListenSocket = NULL; }
m_Connections.PurgeAndDeleteElements();
m_bShuttingDown = false; }
bool CServiceConnMgr::IsConnected() { return m_Connections.Count() != 0; }
void CServiceConnMgr::Update() { DWORD curTime = GetTickCount();
// Connect if we're an unconnected client.
if ( m_bServer ) { if ( m_pListenSocket ) { // Listen for more connections.
while ( 1 ) { CIPAddr addr; ITCPSocket *pSocket = m_pListenSocket->UpdateListen( &addr ); if ( !pSocket ) break;
CServiceConn *pConn = new CServiceConn; pConn->m_ID = m_Connections.AddToTail( pConn ); pConn->m_LastRecvTime = curTime; pConn->m_pSocket = pSocket;
OnNewConnection( pConn->m_ID ); } } } else { if ( !IsConnected() && curTime - m_LastConnectAttemptTime >= SERVICECONNMGR_CONNECT_ATTEMPT_INTERVAL ) { AttemptConnect(); } }
// Check for timeouts and send acks.
int iNext; for ( int iCur=m_Connections.Head(); iCur != m_Connections.InvalidIndex(); iCur=iNext ) { iNext = m_Connections.Next( iCur ); CServiceConn *pConn = m_Connections[iCur];
if ( pConn->m_pSocket->IsConnected() ) { DWORD startTime = GetTickCount(); CUtlVector<unsigned char> data; while ( pConn->m_pSocket->Recv( data ) ) { HandlePacket( (char*)data.Base(), data.Count() ); // Don't sit in this loop too long.
if ( (GetTickCount() - startTime) > 50 ) break; } } else { OnTerminateConnection( iCur ); m_Connections.Remove( iCur ); delete pConn; } } }
void CServiceConnMgr::SendPacket( int id, const void *pData, int len ) { if ( id == -1 ) { FOR_EACH_LL( m_Connections, i ) { m_Connections[i]->m_pSocket->Send( pData, len ); } } else { m_Connections[id]->m_pSocket->Send( pData, len ); } }
void CServiceConnMgr::AttemptConnect() { m_LastConnectAttemptTime = GetTickCount();
ITCPSocket *pSocket = NULL; for ( int iPort=VMPI_SERVICE_FIRST_UI_PORT; iPort <= VMPI_SERVICE_LAST_UI_PORT; iPort++ ) { pSocket = CreateTCPSocketEmu(); if ( !pSocket || !pSocket->BindToAny( 0 ) ) return;
CIPAddr addr( 127, 0, 0, 1, iPort ); if ( TCPSocket_Connect( pSocket, &addr, 0.1 ) ) break;
pSocket->Release(); pSocket = NULL; }
if ( pSocket ) { CServiceConn *pConn = new CServiceConn; pConn->m_ID = m_Connections.AddToTail( pConn ); pConn->m_LastRecvTime = GetTickCount(); pConn->m_pSocket = pSocket;
OnNewConnection( pConn->m_ID ); } }
void CServiceConnMgr::OnNewConnection( int id ) { }
void CServiceConnMgr::OnTerminateConnection( int id ) { }
void CServiceConnMgr::HandlePacket( const char *pData, int len ) { }
|