Esempio n. 1
0
/*
* CL_ParseGetServersResponseMessage
* Handle a reply from getservers message to master server
*/
static void CL_ParseGetServersResponseMessage( msg_t *msg, qboolean extended )
{
	const char *header;
	char adrString[64];
	qbyte addr[16];
	unsigned short port;
	netadr_t adr;

	MSG_BeginReading( msg );
	MSG_ReadLong( msg ); // skip the -1

	//jump over the command name
	header = ( extended ? "getserversExtResponse" : "getserversResponse" );
	if( !MSG_SkipData( msg, strlen( header ) ) )
	{
		Com_Printf( "Invalid master packet ( missing %s )\n", header );
		return;
	}

	while( msg->readcount + 7 <= msg->cursize )
	{
		char prefix = MSG_ReadChar( msg );

		switch( prefix )
		{
		case '\\':
			MSG_ReadData( msg, addr, 4 );
			port = ShortSwap( MSG_ReadShort( msg ) ); // both endians need this swapped.
			Q_snprintfz( adrString, sizeof( adrString ), "%u.%u.%u.%u:%u", addr[0], addr[1], addr[2], addr[3], port );
			break;

		case '/':
			if( extended )
			{
				MSG_ReadData( msg, addr, 16 );
				port = ShortSwap( MSG_ReadShort( msg ) ); // both endians need this swapped.
				Q_snprintfz( adrString, sizeof( adrString ), "[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%hu",
								addr[ 0], addr[ 1], addr[ 2], addr[ 3], addr[ 4], addr[ 5], addr[ 6], addr[ 7],
								addr[ 8], addr[ 9], addr[10], addr[11], addr[12], addr[13], addr[14], addr[15],
								port );
			}
			else
			{
				Com_Printf( "Invalid master packet ( IPv6 prefix in a non-extended response )\n" );
				return;
			}

			break;

		default:
			Com_Printf( "Invalid master packet ( missing separator )\n" );
			return;
		}

		if( port == 0 )  // last server seen
			return;

		Com_DPrintf( "%s\n", adrString );
		if( !NET_StringToAddress( adrString, &adr ) )
		{
			Com_Printf( "Bad address: %s\n", adrString );
			continue;
		}

		CL_AddServerToList( &masterList, adrString, 0 );
	}
}
Esempio n. 2
0
/*
* TV_Relay_ParseServerMessage
*/
void TV_Relay_ParseServerMessage( relay_t *relay, msg_t *msg )
{
	int cmd;

	assert( relay && relay->state >= CA_HANDSHAKE );
	assert( msg );

	// parse the message
	while( relay->state >= CA_HANDSHAKE )
	{
		if( msg->readcount > msg->cursize )
			TV_Relay_Error( relay, "Bad server message" );

		cmd = MSG_ReadByte( msg );
		/*if( cmd == -1 )
		Com_Printf( "%3i:CMD %i %s\n", msg->readcount-1, cmd, "EOF" );
		else
		Com_Printf( "%3i:CMD %i %s\n", msg->readcount-1, cmd, !svc_strings[cmd] ? "bad" : svc_strings[cmd] );*/

		if( cmd == -1 )
			break;

		// other commands
		switch( cmd )
		{
		default:
			TV_Relay_Error( relay, "Illegible server message" );

		case svc_nop:
			break;

		case svc_servercmd:
			if( !relay->reliable )
			{
				int cmdNum = MSG_ReadLong( msg );
				if( cmdNum < 0 )
					TV_Relay_Error( relay, "Invalid cmdNum value" );
				if( cmdNum <= relay->lastExecutedServerCommand )
				{
					MSG_ReadString( msg ); // read but ignore
					break;
				}
				relay->lastExecutedServerCommand = cmdNum;
			}
			// fall trough
		case svc_servercs: // configstrings from demo files. they don't have acknowledge
			TV_Relay_ParseServerCommand( relay, msg );
			break;

		case svc_serverdata:
			if( relay->upstream->demo.playing )
				TV_Relay_ReconnectClients( relay );

			if( relay->state == CA_HANDSHAKE )
			{
				Cbuf_Execute(); // make sure any stuffed commands are done
				TV_Relay_ParseServerData( relay, msg );
			}
			else
			{
				return; // ignore rest of the packet (serverdata is always sent alone)
			}
			break;

		case svc_spawnbaseline:
			TV_Relay_ParseBaseline( relay, msg );
			break;

		case svc_download:
			//CL_ParseDownload( msg );
			break;

		case svc_clcack:
			if( relay->reliable )
				TV_Relay_Error( relay, "clack message while reliable" );
			MSG_ReadLong( msg ); // reliableAcknowledge
			MSG_ReadLong( msg ); // ucmdAcknowledged
			break;

		case svc_frame:
			TV_Relay_ParseFrame( relay, msg );
			break;

		case svc_demoinfo:
			{
				int length;
				
				length = MSG_ReadLong( msg );
				MSG_SkipData( msg, length );
			}
			break;

		case svc_playerinfo:
		case svc_packetentities:
		case svc_match:
			TV_Relay_Error( relay, "Out of place frame data" );
			break;

		case svc_extension:
			if( 1 )
			{
				int len;

				MSG_ReadByte( msg );			// extension id
				MSG_ReadByte( msg );			// version number
				len = MSG_ReadShort( msg );		// command length
				MSG_SkipData( msg, len );		// command data
			}
			break;
		}
	}
}
Esempio n. 3
0
/*
* CL_ParseServerMessage
*/
void CL_ParseServerMessage( msg_t *msg )
{
	int cmd;

	if( cl_shownet->integer == 1 )
	{
		Com_Printf( "%i ", msg->cursize );
	}
	else if( cl_shownet->integer >= 2 )
	{
		Com_Printf( "------------------\n" );
	}

	// parse the message
	while( 1 )
	{
		if( msg->readcount > msg->cursize )
		{
			Com_Error( ERR_DROP, "CL_ParseServerMessage: Bad server message" );
			break;
		}

		cmd = MSG_ReadByte( msg );
		if( cl_debug_serverCmd->integer & 4 )
		{
			if( cmd == -1 )
				Com_Printf( "%3i:CMD %i %s\n", msg->readcount-1, cmd, "EOF" );
			else
				Com_Printf( "%3i:CMD %i %s\n", msg->readcount-1, cmd, !svc_strings[cmd] ? "bad" : svc_strings[cmd] );
		}

		if( cmd == -1 )
		{
			SHOWNET( msg, "END OF MESSAGE" );
			break;
		}

		if( cl_shownet->integer >= 2 )
		{
			if( !svc_strings[cmd] )
				Com_Printf( "%3i:BAD CMD %i\n", msg->readcount-1, cmd );
			else
				SHOWNET( msg, svc_strings[cmd] );
		}

		// other commands
		switch( cmd )
		{
		default:
			Com_Error( ERR_DROP, "CL_ParseServerMessage: Illegible server message" );
			break;

		case svc_nop:
			// Com_Printf( "svc_nop\n" );
			break;

		case svc_servercmd:
			if( !cls.reliable )
			{
				int cmdNum = MSG_ReadLong( msg );
				if( cmdNum < 0 )
				{
					Com_Error( ERR_DROP, "CL_ParseServerMessage: Invalid cmdNum value received: %i\n",
						cmdNum );
					return;
				}
				if( cmdNum <= cls.lastExecutedServerCommand )
				{
					MSG_ReadString( msg ); // read but ignore
					break;
				}
				cls.lastExecutedServerCommand = cmdNum;
			}
			// fall through
		case svc_servercs: // configstrings from demo files. they don't have acknowledge
			CL_ParseServerCommand( msg );	
			break;

		case svc_serverdata:
			if( cls.state == CA_HANDSHAKE )
			{
				Cbuf_Execute(); // make sure any stuffed commands are done
				CL_ParseServerData( msg );
			}
			else
			{
				return; // ignore rest of the packet (serverdata is always sent alone)
			}
			break;

		case svc_spawnbaseline:
			CL_ParseBaseline( msg );
			break;

		case svc_download:
			CL_ParseDownload( msg );
			break;

		case svc_clcack:
			if( cls.reliable )
			{
				Com_Error( ERR_DROP, "CL_ParseServerMessage: clack message for reliable client\n" );
				return;
			}
			cls.reliableAcknowledge = (unsigned)MSG_ReadLong( msg );
			cls.ucmdAcknowledged = (unsigned)MSG_ReadLong( msg );
			if( cl_debug_serverCmd->integer & 4 )
				Com_Printf( "svc_clcack:reliable cmd ack:%i ucmdack:%i\n", cls.reliableAcknowledge, cls.ucmdAcknowledged );
			break;

		case svc_frame:
			CL_ParseFrame( msg );
			break;

		case svc_demoinfo:
			assert( cls.demo.playing );
			{
				size_t meta_data_maxsize;

				MSG_ReadLong( msg );
				MSG_ReadLong( msg );
				cls.demo.meta_data_realsize = (size_t)MSG_ReadLong( msg );
				meta_data_maxsize = (size_t)MSG_ReadLong( msg );

				// sanity check
				if( cls.demo.meta_data_realsize > meta_data_maxsize ) {
					cls.demo.meta_data_realsize = meta_data_maxsize;
				}
				if( cls.demo.meta_data_realsize > sizeof( cls.demo.meta_data ) ) {
					cls.demo.meta_data_realsize = sizeof( cls.demo.meta_data );
				}

				MSG_ReadData( msg, cls.demo.meta_data, cls.demo.meta_data_realsize );
				MSG_SkipData( msg, meta_data_maxsize - cls.demo.meta_data_realsize );
			}
			break;

		case svc_playerinfo:
		case svc_packetentities:
		case svc_match:
			Com_Error( ERR_DROP, "Out of place frame data" );
			break;

		case svc_extension:
			if( 1 )
			{
				int ext, len;

				ext = MSG_ReadByte( msg );		// extension id
				MSG_ReadByte( msg );			// version number
				len = MSG_ReadShort( msg );		// command length

				switch( ext )
				{
				default:
					// unsupported
					MSG_SkipData( msg, len );
					break;
				}
			}
			break;
		}
	}

	CL_AddNetgraph();

	//
	// if recording demos, copy the message out
	//
	//
	// we don't know if it is ok to save a demo message until
	// after we have parsed the frame
	//
	if( cls.demo.recording && !cls.demo.waiting )
		CL_WriteDemoMessage( msg );
}
Esempio n. 4
0
/*
* SV_ParseClientMessage
* The current message is parsed for the given client
*/
void SV_ParseClientMessage( client_t *client, msg_t *msg )
{
	int c;
	char *s;
	qboolean move_issued;
	unsigned int cmdNum;

	if( !msg )
		return;

	SV_UpdateActivity();

	// only allow one move command
	move_issued = qfalse;
	while( 1 )
	{
		if( msg->readcount > msg->cursize )
		{
			Com_Printf( "SV_ParseClientMessage: badread\n" );
			SV_DropClient( client, DROP_TYPE_GENERAL, "Error: Bad message" );
			return;
		}

		c = MSG_ReadByte( msg );
		if( c == -1 )
			break;

		switch( c )
		{
		default:
			Com_Printf( "SV_ParseClientMessage: unknown command char\n" );
			SV_DropClient( client, DROP_TYPE_GENERAL, "Error: Unknown command char" );
			return;

		case clc_nop:
			break;

		case clc_move:
			{
				if( move_issued )
					return; // someone is trying to cheat...

				move_issued = qtrue;
				SV_ParseMoveCommand( client, msg );
			}
			break;

		case clc_svcack:
			{
				if( client->reliable )
				{
					Com_Printf( "SV_ParseClientMessage: svack from reliable client\n" );
					SV_DropClient( client, DROP_TYPE_GENERAL, "Error: svack from reliable client" );
					return;
				}
				cmdNum = MSG_ReadLong( msg );
				if( cmdNum < client->reliableAcknowledge || cmdNum > client->reliableSent )
				{
					//SV_DropClient( client, DROP_TYPE_GENERAL, "Error: bad server command acknowledged" );
					return;
				}
				client->reliableAcknowledge = cmdNum;
			}
			break;

		case clc_clientcommand:
			if( !client->reliable )
			{
				cmdNum = MSG_ReadLong( msg );
				if( cmdNum <= client->clientCommandExecuted )
				{
					s = MSG_ReadString( msg ); // read but ignore
					continue;
				}
				client->clientCommandExecuted = cmdNum;
			}
			s = MSG_ReadString( msg );
			SV_ExecuteUserCommand( client, s );
			if( client->state == CS_ZOMBIE )
				return; // disconnect command
			break;

		case clc_extension:
			if( 1 )
			{
				int ext, len;

				ext = MSG_ReadByte( msg );		// extension id
				MSG_ReadByte( msg );			// version number
				len = MSG_ReadShort( msg );		// command length

				switch( ext )
				{
				default:
					// unsupported
					MSG_SkipData( msg, len );
					break;
				}
			}
			break;
		}
	}
}
Esempio n. 5
0
/*
* TV_Upstream_ParseServerMessage
*/
void TV_Upstream_ParseServerMessage( upstream_t *upstream, msg_t *msg )
{
	int cmd;

	assert( upstream && upstream->state >= CA_HANDSHAKE );
	assert( msg );

	// parse the message
	while( upstream->state >= CA_HANDSHAKE )
	{
		if( msg->readcount > msg->cursize )
			TV_Upstream_Error( upstream, "Bad server message" );

		cmd = MSG_ReadByte( msg );

		if( cmd == -1 )
			break;

		// other commands
		switch( cmd )
		{
		default:
			TV_Upstream_Error( upstream, "Illegible server message" );

		case svc_nop:
			break;

		case svc_servercmd:
			if( !upstream->reliable )
			{
				int cmdNum = MSG_ReadLong( msg );
				if( cmdNum < 0 )
					TV_Upstream_Error( upstream, "Invalid cmdNum value" );
				if( cmdNum <= upstream->lastExecutedServerCommand )
				{
					MSG_ReadString( msg ); // read but ignore
					break;
				}
				upstream->lastExecutedServerCommand = cmdNum;
			}
			// fall trough
		case svc_servercs: // configstrings from demo files. they don't have acknowledge
			TV_Upstream_ParseServerCommand( upstream, msg );
			break;

		case svc_serverdata:
			if( upstream->state == CA_HANDSHAKE )
			{
				Cbuf_Execute(); // make sure any stuffed commands are done

				FS_Rescan();	// FIXME?

				TV_Upstream_ParseServerData( upstream, msg );
			}
			else
			{
				return; // ignore rest of the packet (serverdata is always sent alone)
			}
			break;

		case svc_spawnbaseline:
			TV_Upstream_ParseBaseline( upstream, msg );
			break;

		case svc_download:
			//CL_ParseDownload( msg );
			break;

		case svc_clcack:
			if( upstream->reliable )
				TV_Upstream_Error( upstream, "clack message while reliable" );
			upstream->reliableAcknowledge = (unsigned)MSG_ReadLong( msg );
			MSG_ReadLong( msg ); // ucmdAcknowledged
			break;

		case svc_frame:
			TV_Upstream_ParseFrame( upstream, msg );
			break;

		case svc_demoinfo:
			{
				int length;

				assert( upstream->demo.playing );

				length = MSG_ReadLong( msg );
				MSG_SkipData( msg, length );
			}
			break;

		case svc_playerinfo:
		case svc_packetentities:
		case svc_match:
			TV_Upstream_Error( upstream, "Out of place frame data" );
			break;

		case svc_extension:
			if( 1 )
			{
				int len;

				MSG_ReadByte( msg );			// extension id
				MSG_ReadByte( msg );			// version number
				len = MSG_ReadShort( msg );		// command length
				MSG_SkipData( msg, len );		// command data
			}
			break;
		}
	}

	// if recording demos, copy the message out
	if( upstream->demo.recording && !upstream->demo.waiting )
		TV_Upstream_WriteDemoMessage( upstream, msg );
}