Beispiel #1
0
/*
 * =================
 * SV_ReadPackets
 * =================
 */
void SV_ReadPackets(void)
{
    int      i;
    client_t *cl;
    int      qport;

    while (NET_GetPacket(NS_SERVER, &net_from, &net_message))
    {
        // check for connectionless packet (0xffffffff) first
        if (*(int *)net_message.data == -1)
        {
            SV_ConnectionlessPacket();
            continue;
        }

        // read the qport out of the message so we can fix up
        // stupid address translating routers
        MSG_BeginReading(&net_message);
        MSG_ReadLong(&net_message);                     // sequence number
        MSG_ReadLong(&net_message);                     // sequence number
        qport = MSG_ReadShort(&net_message) & 0xffff;

        // check for packets from connected clients
        for (i = 0, cl = svs.clients; i < maxclients->value; i++, cl++)
        {
            if (cl->state == cs_free)
            {
                continue;
            }
            if (!NET_CompareBaseAdr(net_from, cl->netchan.remote_address))
            {
                continue;
            }
            if (cl->netchan.qport != qport)
            {
                continue;
            }
            if (cl->netchan.remote_address.port != net_from.port)
            {
                Com_Printf("SV_ReadPackets: fixing up a translated port\n");
                cl->netchan.remote_address.port = net_from.port;
            }

            if (Netchan_Process(&cl->netchan, &net_message))
            {                   // this is a valid, sequenced packet, so process it
                if (cl->state != cs_zombie)
                {
                    cl->lastmessage = svs.realtime;                     // don't timeout
                    SV_ExecuteClientMessage(cl);
                }
            }
            break;
        }

        if (i != maxclients->value)
        {
            continue;
        }
    }
}
Beispiel #2
0
/*
=================
SV_ReadPackets
=================
*/
void SV_PacketEvent( netadr_t from, msg_t *msg ) {
	int			i;
	client_t	*cl;
	int			qport;

	// check for connectionless packet (0xffffffff) first
	if ( msg->cursize >= 4 && *(int *)msg->data == -1) {
		SV_ConnectionlessPacket( from, msg );
		return;
	}

	// read the qport out of the message so we can fix up
	// stupid address translating routers
	MSG_BeginReading( msg );
	MSG_ReadLong( msg );				// sequence number
	MSG_ReadLong( msg );				// sequence number
	qport = MSG_ReadShort( msg ) & 0xffff;

	// find which client the message is from
	for (i=0, cl=svs.clients ; i < 1 ; i++,cl++) {
		if (cl->state == CS_FREE) {
			continue;
		}
		if ( !NET_CompareBaseAdr( from, cl->netchan.remoteAddress ) ) {
			continue;
		}
		// it is possible to have multiple clients from a single IP
		// address, so they are differentiated by the qport variable
		if (cl->netchan.qport != qport) {
			continue;
		}

		// the IP port can't be used to differentiate them, because
		// some address translating routers periodically change UDP
		// port assignments
		if (cl->netchan.remoteAddress.port != from.port) {
			Com_Printf( "SV_ReadPackets: fixing up a translated port\n" );
			cl->netchan.remoteAddress.port = from.port;
		}

		// make sure it is a valid, in sequence packet
		if (Netchan_Process(&cl->netchan, msg)) {
			// zombie clients stil neet to do the Netchan_Process
			// to make sure they don't need to retransmit the final
			// reliable message, but they don't do any other processing
			if (cl->state != CS_ZOMBIE) {
				cl->lastPacketTime = sv.time;	// don't timeout
				cl->frames[ cl->netchan.incomingAcknowledged & PACKET_MASK ]
					.messageAcked = sv.time;
				SV_ExecuteClientMessage( cl, msg );
			}
		}
		return;
	}
	
	// if we received a sequenced packet from an address we don't reckognize,
	// send an out of band disconnect packet to it
	NET_OutOfBandPrint( NS_SERVER, from, "disconnect" );
}
Beispiel #3
0
void SV_ReadPackets()
{
	guard(SV_ReadPackets);

	while (NET_GetPacket(NS_SERVER, &net_from, &net_message))
	{
		// check for connectionless packet (0xffffffff) first
		if (*(int *)net_message.data == -1)
		{
			SV_ConnectionlessPacket();
			continue;
		}

		// read the qport out of the message so we can fix up
		// stupid address translating routers
		net_message.BeginReading();
		MSG_ReadLong(&net_message);		// sequence number
		MSG_ReadLong(&net_message);		// sequence number
		int qport = MSG_ReadShort(&net_message) & 0xFFFF;

		// check for packets from connected clients
		int		i;
		client_t *cl;
		for (i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++)
		{
			if (cl->state == cs_free)
				continue;
			// compare address: ignore network port, but use qport
			if (!NET_CompareBaseAdr(&net_from, &cl->netchan.remote_address))
				continue;
			if (cl->netchan.port != qport)
				continue;
			// found a client
			if (cl->netchan.remote_address.port != net_from.port)
			{
				appWPrintf("SV_ReadPackets: fixing up a translated port\n");
				cl->netchan.remote_address.port = net_from.port;
			}

			if (cl->netchan.Process(&net_message))
			{	// this is a valid, sequenced packet, so process it
				if (cl->state != cs_zombie)
				{
					cl->lastmessage = svs.realtime;	// don't timeout
					SV_ExecuteClientMessage(cl);
				}
			}
			break;
		}

//		if (i != sv_maxclients->integer) continue;
	}

	unguard;
}
Beispiel #4
0
/**
 * @sa CL_ReadPacket
 * @sa NET_ReadMsg
 * @sa SV_Start
 */
void SV_ReadPacket (struct net_stream *s)
{
	client_t *cl = (client_t *)NET_StreamGetData(s);
	struct dbuffer *msg;

	while ((msg = NET_ReadMsg(s))) {
		const int cmd = NET_ReadByte(msg);

		if (cmd == clc_oob)
			SV_ConnectionlessPacket(s, msg);
		else if (cl)
			SV_ExecuteClientMessage(cl, cmd, msg);
		else
			NET_StreamFree(s);

		free_dbuffer(msg);
	}
}
/*
=================
SV_ReadPackets
=================
*/
static void SV_ReadPackets (void)
{
	int			i;
	client_t	*cl;

	while (NET_GetPacket ())
	{
		if (SV_FilterPacket ())
		{
			SV_SendBan ();	// tell them we aren't listening...
			continue;
		}

		// check for connectionless packet (0xffffffff) first
		if (*(int *)net_message.data == -1)
		{
			SV_ConnectionlessPacket ();
			continue;
		}

		// check for packets from connected clients
		for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++)
		{
			if (cl->state == cs_free)
				continue;
			if (!NET_CompareAdr (net_from, cl->netchan.remote_address))
				continue;
			if (Netchan_Process(&cl->netchan))
			{	// this is a valid, sequenced packet, so process it
				svs.stats.packets++;
				cl->send_message = true;	// reply at end of frame
				if (cl->state != cs_zombie)
					SV_ExecuteClientMessage (cl);
			}
			break;
		}

		if (i != MAX_CLIENTS)
			continue;

		// packet is not from a known client
		//	Con_Printf ("%s:sequenced packet without connection\n", NET_AdrToString(net_from));
	}
}
Beispiel #6
0
/**
 * @sa CL_ReadPacket
 * @sa NET_ReadMsg
 * @sa SV_Start
 */
void SV_ReadPacket (struct net_stream *s)
{
	client_t *cl = static_cast<client_t *>(NET_StreamGetData(s));
	dbuffer *msg;

	while ((msg = NET_ReadMsg(s))) {
		const int cmd = NET_ReadByte(msg);

		if (cmd == clc_oob)
			SV_ConnectionlessPacket(s, msg);
		else if (cl)
			SV_ExecuteClientMessage(cl, cmd, msg);
		else {
			NET_StreamFree(s);
			s = NULL;
		}

		delete msg;
	}
}
Beispiel #7
0
/*
=================
SV_ReadPackets
=================
*/
void SV_ReadPackets (void)
{
	int			i;
	client_t	*cl;
	int			qport;

	// first deal with delayed packets from connected clients
	for (i = 0, cl=svs.clients; i < MAX_CLIENTS; i++, cl++) {
		if (cl->state == cs_free)
			continue;

		net_from = cl->netchan.remote_address;

		while (cl->packets && svs.realtime - cl->packets->time >= cl->delay) {
			SZ_Clear(&net_message);
			SZ_Write(&net_message, cl->packets->msg.data, cl->packets->msg.cursize);
			SV_ExecuteClientMessage(cl);
			SV_FreeHeadDelayedPacket(cl);
		}		
	}

	// now deal with new packets
	while (NET_GetPacket(NS_SERVER))
	{
		if (SV_FilterPacket ())
		{
			SV_SendBan ();	// tell them we aren't listening...
			continue;
		}

		// check for connectionless packet (0xffffffff) first
		if (*(int *)net_message.data == -1)
		{
			SV_ConnectionlessPacket ();
			continue;
		}
		
		// read the qport out of the message so we can fix up
		// stupid address translating routers
		MSG_BeginReading ();
		MSG_ReadLong ();		// sequence number
		MSG_ReadLong ();		// sequence number
		qport = MSG_ReadShort () & 0xffff;

		// check which client sent this packet
		for (i=0, cl=svs.clients ; i<MAX_CLIENTS ; i++,cl++)
		{
			if (cl->state == cs_free)
				continue;
			if (!NET_CompareBaseAdr (net_from, cl->netchan.remote_address))
				continue;
			if (cl->netchan.qport != qport)
				continue;
			if (cl->netchan.remote_address.port != net_from.port)
			{
				Com_DPrintf ("SV_ReadPackets: fixing up a translated port\n");
				cl->netchan.remote_address.port = net_from.port;
			}

			break;
		}

		if (i == MAX_CLIENTS)
			continue;

		// ok, we know who sent this packet, but do we need to delay executing it?
		if (cl->delay > 0) {
			if (!svs.free_packets) // packet has to be dropped..
				break;

			// insert at end of list
			if (!cl->packets) {
				cl->last_packet = cl->packets = svs.free_packets;
			} else {
				// this works because '=' associates from right to left
				cl->last_packet = cl->last_packet->next = svs.free_packets;
			}

			svs.free_packets = svs.free_packets->next;
			cl->last_packet->next = NULL;
			
			cl->last_packet->time = svs.realtime;
			SZ_Clear(&cl->last_packet->msg);
			SZ_Write(&cl->last_packet->msg, net_message.data, net_message.cursize);
		} else {
			SV_ExecuteClientMessage (cl);
		}
	}
}
Beispiel #8
0
/*
=================
SV_ReadPackets
=================
*/
void SV_PacketEvent( netadr_t from, msg_t *msg ) {
	int			i;
	client_t	*cl;
	int			qport;

	// check for connectionless packet (0xffffffff) first
	if ( msg->cursize >= 4 && *(int *)msg->data == -1) {
		SV_ConnectionlessPacket( from, msg );
		return;
	}

	// Broadcast packets should never be treated as sequenced packets!
	// Don't even bother telling them to go away. It's not our game!
//	if ( broadcast )
//		return;

	// read the qport out of the message so we can fix up
	// stupid address translating routers
	MSG_BeginReadingOOB( msg );
	MSG_ReadLong( msg );				// sequence number
	qport = MSG_ReadShort( msg ) & 0xffff;

	// find which client the message is from
	for (i=0, cl=svs.clients ; i < sv_maxclients->integer ; i++,cl++) {
#ifdef _XBOX
		ClientManager::ActivateClient(i);
#endif
		if (cl->state == CS_FREE) {
			continue;
		}
		if ( !NET_CompareBaseAdr( from, cl->netchan.remoteAddress ) ) {
			continue;
		}
		// it is possible to have multiple clients from a single IP
		// address, so they are differentiated by the qport variable
		if (cl->netchan.qport != qport) {
			continue;
		}

		// the IP port can't be used to differentiate them, because
		// some address translating routers periodically change UDP
		// port assignments
		if (cl->netchan.remoteAddress.port != from.port) {
			Com_Printf( "SV_ReadPackets: fixing up a translated port\n" );
			cl->netchan.remoteAddress.port = from.port;
		}

		// make sure it is a valid, in sequence packet
		if (SV_Netchan_Process(cl, msg)) {
			// zombie clients still need to do the Netchan_Process
			// to make sure they don't need to retransmit the final
			// reliable message, but they don't do any other processing
			if (cl->state != CS_ZOMBIE) {
				cl->lastPacketTime = svs.time;	// don't timeout
				SV_ExecuteClientMessage( cl, msg );
			}
		}
		return;
	}
	
	// if we received a sequenced packet from an address we don't reckognize,
	// send an out of band disconnect packet to it
	NET_OutOfBandPrint( NS_SERVER, from, "disconnect" );
}
Beispiel #9
0
/*
=================
SV_ReadPackets
=================
*/
void SV_ReadPackets( void )
{
	sv_client_t	*cl;
	int		i, qport, curSize;

	while( NET_GetPacket( NS_SERVER, &net_from, net_message_buffer, &curSize ))
	{
		BF_Init( &net_message, "ClientPacket", net_message_buffer, curSize );

		// check for connectionless packet (0xffffffff) first
		if( BF_GetMaxBytes( &net_message ) >= 4 && *(int *)net_message.pData == -1 )
		{
			SV_ConnectionlessPacket( net_from, &net_message );
			continue;
		}

		// read the qport out of the message so we can fix up
		// stupid address translating routers
		BF_Clear( &net_message );
		BF_ReadLong( &net_message );	// sequence number
		BF_ReadLong( &net_message );	// sequence number
		qport = (int)BF_ReadShort( &net_message ) & 0xffff;

		// check for packets from connected clients
		for( i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++ )
		{
			if( cl->state == cs_free || cl->fakeclient )
				continue;

			if( !NET_CompareBaseAdr( net_from, cl->netchan.remote_address ))
				continue;

			if( cl->netchan.qport != qport )
				continue;

			if( cl->netchan.remote_address.port != net_from.port )
			{
				MsgDev( D_INFO, "SV_ReadPackets: fixing up a translated port\n");
				cl->netchan.remote_address.port = net_from.port;
			}

			if( Netchan_Process( &cl->netchan, &net_message ))
			{	
				cl->send_message = true; // reply at end of frame

				// this is a valid, sequenced packet, so process it
				if( cl->state != cs_zombie )
				{
					cl->lastmessage = host.realtime; // don't timeout
					SV_ExecuteClientMessage( cl, &net_message );
					svgame.globals->frametime = host.frametime;
					svgame.globals->time = sv.time;
				}
			}

			// fragmentation/reassembly sending takes priority over all game messages, want this in the future?
			if( Netchan_IncomingReady( &cl->netchan ))
			{
				if( Netchan_CopyNormalFragments( &cl->netchan, &net_message ))
				{
					BF_Clear( &net_message );
					SV_ExecuteClientMessage( cl, &net_message );
				}

				if( Netchan_CopyFileFragments( &cl->netchan, &net_message ))
				{
					SV_ProcessFile( cl, cl->netchan.incomingfilename );
				}
			}
			break;
		}

		if( i != sv_maxclients->integer )
			continue;
	}
}