diff options
Diffstat (limited to 'networksystem/networkserver.cpp')
| -rw-r--r-- | networksystem/networkserver.cpp | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/networksystem/networkserver.cpp b/networksystem/networkserver.cpp new file mode 100644 index 0000000..9951e6c --- /dev/null +++ b/networksystem/networkserver.cpp @@ -0,0 +1,224 @@ +//========= 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 ); + } +} + + + |