mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-22 06:06:50 +00:00
225 lines
4.8 KiB
C++
225 lines
4.8 KiB
C++
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
//===========================================================================//
|
|
|
|
#include "networkserver.h"
|
|
#include "networksystem.h"
|
|
#include "icvar.h"
|
|
#include "filesystem.h"
|
|
#include "UDP_Socket.h"
|
|
#include "sm_protocol.h"
|
|
#include "NetChannel.h"
|
|
#include "UDP_Process.h"
|
|
#include <winsock.h>
|
|
#include "networkclient.h"
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Implementation of CPlayer
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
CNetworkServer::CNetworkServer( )
|
|
{
|
|
m_pSocket = new CUDPSocket;
|
|
}
|
|
|
|
CNetworkServer::~CNetworkServer()
|
|
{
|
|
delete m_pSocket;
|
|
}
|
|
|
|
bool CNetworkServer::Init( int nServerPort )
|
|
{
|
|
if ( !m_pSocket->Init( nServerPort ) )
|
|
{
|
|
Warning( "CNetworkServer: Unable to create socket!!!\n" );
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void CNetworkServer::Shutdown()
|
|
{
|
|
m_pSocket->Shutdown();
|
|
}
|
|
|
|
CNetChannel *CNetworkServer::FindNetChannel( const netadr_t& from )
|
|
{
|
|
CPlayer *pl = FindPlayerByAddress( from );
|
|
if ( pl )
|
|
return &pl->m_NetChan;
|
|
return NULL;
|
|
}
|
|
|
|
CPlayer *CNetworkServer::FindPlayerByAddress( const netadr_t& adr )
|
|
{
|
|
int c = m_Players.Count();
|
|
for ( int i = 0; i < c; ++i )
|
|
{
|
|
CPlayer *player = m_Players[ i ];
|
|
if ( player->GetRemoteAddress().CompareAdr( adr ) )
|
|
return player;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
CPlayer *CNetworkServer::FindPlayerByNetChannel( INetChannel *chan )
|
|
{
|
|
int c = m_Players.Count();
|
|
for ( int i = 0; i < c; ++i )
|
|
{
|
|
CPlayer *player = m_Players[ i ];
|
|
if ( &player->m_NetChan == chan )
|
|
return player;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
#define SPEW_MESSAGES
|
|
|
|
#if defined( SPEW_MESSAGES )
|
|
#define SM_SPEW_MESSAGE( code, remote ) \
|
|
Warning( "Message: %s from '%s'\n", #code, remote );
|
|
#else
|
|
#define SM_SPEW_MESSAGE( code, remote )
|
|
#endif
|
|
// process a connectionless packet
|
|
bool CNetworkServer::ProcessConnectionlessPacket( CNetPacket *packet )
|
|
{
|
|
int code = packet->m_Message.ReadByte();
|
|
switch ( code )
|
|
{
|
|
case c2s_connect:
|
|
{
|
|
SM_SPEW_MESSAGE( c2s_connect, packet->m_From.ToString() );
|
|
|
|
CPlayer *pl = FindPlayerByAddress( packet->m_From );
|
|
if ( pl )
|
|
{
|
|
Warning( "Player already exists for %s\n", packet->m_From.ToString() );
|
|
}
|
|
else
|
|
{
|
|
// Creates the connection
|
|
pl = new CPlayer( this, packet->m_From );
|
|
m_Players.AddToTail( pl );
|
|
|
|
// Now send the conn accepted message
|
|
AcceptConnection( packet->m_From );
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
Warning( "CNetworkServer::ProcessConnectionlessPacket: Unknown code '%i' from '%s'\n",
|
|
code, packet->m_From.ToString() );
|
|
}
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
void CNetworkServer::AcceptConnection( const netadr_t& remote )
|
|
{
|
|
byte data[ 512 ];
|
|
bf_write buf( "CNetworkServer::AcceptConnection", data, sizeof( data ) );
|
|
|
|
buf.WriteLong( -1 );
|
|
buf.WriteByte( s2c_connect_accept );
|
|
|
|
m_pSocket->SendTo( remote, buf.GetData(), buf.GetNumBytesWritten() );
|
|
}
|
|
|
|
void CNetworkServer::ReadPackets( void )
|
|
{
|
|
UDP_ProcessSocket( m_pSocket, this, this );
|
|
|
|
int c = m_Players.Count();
|
|
for ( int i = c - 1; i >= 0 ; --i )
|
|
{
|
|
if ( m_Players[ i ]->m_bMarkedForDeletion )
|
|
{
|
|
CPlayer *pl = m_Players[ i ];
|
|
m_Players.Remove( i );
|
|
delete pl;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CNetworkServer::SendUpdates()
|
|
{
|
|
int c = m_Players.Count();
|
|
for ( int i = 0; i < c; ++i )
|
|
{
|
|
m_Players[ i ]->SendUpdate();
|
|
}
|
|
}
|
|
|
|
void CNetworkServer::OnConnectionStarted( INetChannel *pChannel )
|
|
{
|
|
// Create a network event
|
|
NetworkConnectionEvent_t *pConnection = g_pNetworkSystemImp->CreateNetworkEvent< NetworkConnectionEvent_t >( );
|
|
pConnection->m_nType = NETWORK_EVENT_CONNECTED;
|
|
pConnection->m_pChannel = pChannel;
|
|
}
|
|
|
|
void CNetworkServer::OnConnectionClosing( INetChannel *pChannel, char const *reason )
|
|
{
|
|
Warning( "OnConnectionClosing '%s'\n", reason );
|
|
|
|
CPlayer *pPlayer = FindPlayerByNetChannel( pChannel );
|
|
if ( pPlayer )
|
|
{
|
|
pPlayer->Shutdown();
|
|
}
|
|
|
|
// Create a network event
|
|
NetworkDisconnectionEvent_t *pDisconnection = g_pNetworkSystemImp->CreateNetworkEvent< NetworkDisconnectionEvent_t >( );
|
|
pDisconnection->m_nType = NETWORK_EVENT_DISCONNECTED;
|
|
pDisconnection->m_pChannel = pChannel;
|
|
}
|
|
|
|
void CNetworkServer::OnPacketStarted( int inseq, int outseq )
|
|
{
|
|
}
|
|
|
|
void CNetworkServer::OnPacketFinished()
|
|
{
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Implementation of CPlayer
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
CPlayer::CPlayer( CNetworkServer *server, netadr_t& remote ) :
|
|
m_bMarkedForDeletion( false )
|
|
{
|
|
m_NetChan.Setup( true, &remote, server->m_pSocket, "player", server );
|
|
}
|
|
|
|
void CPlayer::Shutdown()
|
|
{
|
|
m_bMarkedForDeletion = true;
|
|
m_NetChan.Shutdown( "received disconnect\n" );
|
|
}
|
|
|
|
void CPlayer::SendUpdate()
|
|
{
|
|
if ( m_NetChan.CanSendPacket() )
|
|
{
|
|
m_NetChan.SendDatagram( NULL );
|
|
}
|
|
}
|
|
|
|
|
|
|