Ejemplo n.º 1
0
/*
=============================================================================

movevars_t communication

=============================================================================
*/
qboolean MSG_WriteDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *to )
{
	delta_t		*pField;
	delta_info_t	*dt;
	int		i, startBit;
	int		numChanges = 0;

	dt = Delta_FindStruct( "movevars_t" );
	ASSERT( dt && dt->bInitialized );

	pField = dt->pFields;
	ASSERT( pField );

	startBit = msg->iCurBit;

	// activate fields and call custom encode func
	Delta_CustomEncode( dt, from, to );

	BF_WriteByte( msg, svc_deltamovevars );

	// process fields
	for( i = 0; i < dt->numFields; i++, pField++ )
	{
		if( Delta_WriteField( msg, pField, from, to, 0.0f ))
			numChanges++;
	}

	// if we have no changes - kill the message
	if( !numChanges )
	{
		BF_SeekToBit( msg, startBit );
		return false;
	}
	return true;
}
Ejemplo n.º 2
0
/*
==================
MSG_WriteWeaponData

Writes current client data only for local client
Other clients can grab the client state from entity_state_t
==================
*/
void MSG_WriteWeaponData( sizebuf_t *msg, weapon_data_t *from, weapon_data_t *to, float timebase, int index )
{
	delta_t		*pField;
	delta_info_t	*dt;
	int		i, startBit;
	int		numChanges = 0;

	dt = Delta_FindStruct( "weapon_data_t" );
	if( !dt || !dt->bInitialized )
	{
		Host_Error( "MSG_WriteWeaponData: delta not initialized!\n" );
	}

	pField = dt->pFields;
	ASSERT( pField );

	// activate fields and call custom encode func
	Delta_CustomEncode( dt, from, to );

	startBit = msg->iCurBit;

	BF_WriteOneBit( msg, 1 );
	BF_WriteUBitLong( msg, index, MAX_WEAPON_BITS );
               
	// process fields
	for( i = 0; i < dt->numFields; i++, pField++ )
	{
		if( Delta_WriteField( msg, pField, from, to, timebase ))
			numChanges++;
	}

	// if we have no changes - kill the message
	if( !numChanges ) BF_SeekToBit( msg, startBit );
}
Ejemplo n.º 3
0
/*
==================
MSG_WriteDeltaEntity

Writes part of a packetentities message, including the entity number.
Can delta from either a baseline or a previous packet_entity
If to is NULL, a remove entity update will be sent
If force is not set, then nothing at all will be generated if the entity is
identical, under the assumption that the in-order delta code will catch it.
==================
*/
void MSG_WriteDeltaEntity( entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qboolean force, qboolean player, float timebase ) 
{
	delta_info_t	*dt = NULL;
	delta_t		*pField;
	int		i, startBit;
	int		numChanges = 0;

	if( to == NULL )
	{
		int	fRemoveType;

		if( from == NULL ) return;

		// a NULL to is a delta remove message
		BF_WriteWord( msg, from->number );

		// fRemoveType:
		// 0 - keep alive, has delta-update
		// 1 - remove from delta message (but keep states)
		// 2 - completely remove from server
		if( force ) fRemoveType = 2;
		else fRemoveType = 1;

		BF_WriteUBitLong( msg, fRemoveType, 2 );
		return;
	}

	startBit = msg->iCurBit;

	if( to->number < 0 || to->number >= GI->max_edicts )
	{
		MsgDev( D_ERROR, "MSG_WriteDeltaEntity: Bad entity number: %i\n", to->number );
		return;
	}

	BF_WriteWord( msg, to->number );
	BF_WriteUBitLong( msg, 0, 2 ); // alive

	if( to->entityType != from->entityType )
	{
		BF_WriteOneBit( msg, 1 );
		BF_WriteUBitLong( msg, to->entityType, 2 );
	}
	else BF_WriteOneBit( msg, 0 ); 

	if( to->entityType == ENTITY_NORMAL )
	{
		if( player )
		{
			dt = Delta_FindStruct( "entity_state_player_t" );
		}
		else
		{
			dt = Delta_FindStruct( "entity_state_t" );
		}
	}
	else if( to->entityType == ENTITY_BEAM )
	{
		dt = Delta_FindStruct( "custom_entity_state_t" );
	}

	ASSERT( dt && dt->bInitialized );
		
	pField = dt->pFields;
	ASSERT( pField );

	// activate fields and call custom encode func
	Delta_CustomEncode( dt, from, to );

	// process fields
	for( i = 0; i < dt->numFields; i++, pField++ )
	{
		if( Delta_WriteField( msg, pField, from, to, timebase ))
			numChanges++;
	}

	// if we have no changes - kill the message
	if( !numChanges && !force ) BF_SeekToBit( msg, startBit );
}
Ejemplo n.º 4
0
/*
==============================
Netchan_CopyFileFragments

==============================
*/
qboolean Netchan_CopyFileFragments( netchan_t *chan, sizebuf_t *msg )
{
	fragbuf_t	*p, *n;
	char	filename[CS_SIZE];
	int	nsize;
	byte	*buffer;
	int	pos;

	if( !chan->incomingready[FRAG_FILE_STREAM] )
		return false;

	if( !chan->incomingbufs[FRAG_FILE_STREAM] )
	{
		MsgDev( D_WARN, "Netchan_CopyFileFragments:  Called with no fragments readied\n" );
		chan->incomingready[FRAG_FILE_STREAM] = false;
		return false;
	}

	p = chan->incomingbufs[FRAG_FILE_STREAM];

	BF_Init( msg, "NetMessage", net_message_buffer, sizeof( net_message_buffer ));

	// copy in first chunk so we can get filename out
	BF_WriteBits( msg, BF_GetData( &p->frag_message ), BF_GetNumBitsWritten( &p->frag_message ));
	BF_SeekToBit( msg, 0 ); // rewind buffer

	//Q_strncpy( filename, BF_ReadString( msg ), sizeof( filename ));
	Q_snprintf( filename, sizeof( filename ), "downloaded/%s", BF_ReadString( msg ) );

	if( Q_strlen( filename ) <= 0 )
	{
		MsgDev( D_ERROR, "File fragment received with no filename\nFlushing input queue\n" );
		
		// clear out bufs
		Netchan_FlushIncoming( chan, FRAG_FILE_STREAM );
		return false;
	}
	else if( Q_strstr( filename, ".." ))
	{
		MsgDev( D_ERROR, "File fragment received with relative path, ignoring\n" );
		
		// clear out bufs
		Netchan_FlushIncoming( chan, FRAG_FILE_STREAM );
		return false;
	}

	Q_strncpy( chan->incomingfilename, filename, sizeof( chan->incomingfilename ));

	if( FS_FileExists( filename, false ))
	{
		MsgDev( D_ERROR, "Can't download %s, already exists\n", filename );
		
		// clear out bufs
		Netchan_FlushIncoming( chan, FRAG_FILE_STREAM );
		return true;
	}

	// create file from buffers
	nsize = 0;
	while ( p )
	{
		nsize += BF_GetNumBytesWritten( &p->frag_message ); // Size will include a bit of slop, oh well
		if( p == chan->incomingbufs[FRAG_FILE_STREAM] )
		{
			nsize -= BF_GetNumBytesRead( msg );
		}
		p = p->next;
	}

	buffer = Mem_Alloc( net_mempool, nsize + 1 );
	p = chan->incomingbufs[ FRAG_FILE_STREAM ];
	pos = 0;

	while( p )
	{
		int	cursize;

		n = p->next;
		
		cursize = BF_GetNumBytesWritten( &p->frag_message );

		// first message has the file name, don't write that into the data stream,
		// just write the rest of the actual data
		if( p == chan->incomingbufs[FRAG_FILE_STREAM] ) 
		{
			// copy it in
			cursize -= BF_GetNumBytesRead( msg );
			Q_memcpy( &buffer[pos], &p->frag_message.pData[BF_GetNumBytesRead( msg )], cursize );
		}
		else
		{
			Q_memcpy( &buffer[pos], p->frag_message.pData, cursize );
		}

		pos += cursize;

		Mem_Free( p );
		p = n;
	}

	FS_WriteFile( filename, buffer, pos );
	Mem_Free( buffer );

	// clear remnants
	BF_Clear( msg );

	chan->incomingbufs[FRAG_FILE_STREAM] = NULL;

	// reset flag
	chan->incomingready[FRAG_FILE_STREAM] = false;

	return true;
}