/*
=================
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));
	}
}
Example #2
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);
		}
	}
}