summaryrefslogtreecommitdiff
path: root/networksystem/networkserver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'networksystem/networkserver.cpp')
-rw-r--r--networksystem/networkserver.cpp224
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 );
+ }
+}
+
+
+