示例#1
0
// Gets voice data from a client and forwards it to anyone who can hear this client.
void SV_ParseVoiceData(client_t *cl)
{
	int i, iClient;
	int	nDataLength;
	char chReceived[4096];
	client_t *pDestClient;
	
	iClient = cl - svs.clients;

	// Read in the data.	
	nDataLength = MSG_ReadShort();
	if( nDataLength > sizeof(chReceived) )
	{
		Host_Error("SV_ParseVoiceData: invalid incoming packet.\n");
		return;
	}

	MSG_ReadBuf( nDataLength, chReceived );


	// Disable voice?
	if( !sv_voiceenable.GetInt() )
		return;

	for(i=0; i < MAX_CLIENTS; i++)
	{
		qboolean bLocal;
		int nSendLength;

		pDestClient = &svs.clients[i];
		bLocal = (pDestClient == cl);

		// Does the game code want cl sending to this client?
		if(!(cl->m_VoiceStreams[i>>5] & (1 << (i & 31))) && !bLocal)
			continue;
		
		// Is this client even on the server?
		if(!pDestClient->active && !pDestClient->connected && !bLocal)
			continue;

		// Is loopback enabled?
		nSendLength = nDataLength;
		if(bLocal && !pDestClient->m_bLoopback)
		{
			nSendLength = 0;	// Still send something, just zero length (this is so the client 
								// can display something that shows knows the server knows it's talking).
		}

		// Is there room to write this data in?
		if( pDestClient->datagram.GetNumBytesLeft() >= (6 + nDataLength) )
		{
			pDestClient->datagram.WriteByte( svc_voicedata );
			pDestClient->datagram.WriteByte( (byte)iClient );
			pDestClient->datagram.WriteShort( nSendLength );
			pDestClient->datagram.WriteBytes( chReceived, nSendLength );
		}
	}
}
示例#2
0
int EXT_FUNC MSG_ReadBuf_api(int iSize, void *pbuf) {
	return MSG_ReadBuf(iSize, pbuf);
}
示例#3
0
/* <ba1d0> ../engine/sv_upld.c:491 */
void SV_ParseResourceList(client_t *pSenderClient)
{
	int i, total;
	int totalsize;
	resource_t *resource;
	resourceinfo_t ri;

	total = MSG_ReadShort();

#ifdef REHLDS_FIXES
	SV_ClearResourceLists( host_client );
#else // REHLDS_FIXES
	SV_ClearResourceList( &host_client->resourcesneeded );
	SV_ClearResourceList( &host_client->resourcesonhand );
#endif // REHLDS_FIXES

#ifdef REHLDS_FIXES
	if (total > 1) // client uses only one custom resource (spray decal)
	{
		SV_DropClient(host_client, false, "Too many resources in client resource list");
		return;
	}
#endif // REHLDS_CHECKS

	for (i = 0; i < total; i++)
	{
		resource = (resource_t *)Mem_ZeroMalloc(sizeof(resource_t));
		Q_strncpy(resource->szFileName, MSG_ReadString(), sizeof(resource->szFileName) - 1);
		resource->szFileName[sizeof(resource->szFileName) - 1] = 0;
		resource->type = (resourcetype_t)MSG_ReadByte();
		resource->nIndex = MSG_ReadShort();
		resource->nDownloadSize = MSG_ReadLong();
		resource->ucFlags = MSG_ReadByte() & (~RES_WASMISSING);
		if (resource->ucFlags & RES_CUSTOM)
			MSG_ReadBuf(16, resource->rgucMD5_hash);
		resource->pNext = NULL;
		resource->pPrev = NULL;

#ifdef REHLDS_FIXES
		SV_AddToResourceList(resource, &host_client->resourcesneeded);	// FIXED: Mem leak. Add to list to free current resource in SV_ClearResourceList if something goes wrong.
#endif // REHLDS_FIXES

		if (msg_badread || resource->type > t_world ||
#ifdef REHLDS_FIXES
			resource->type != t_decal || !(resource->ucFlags & RES_CUSTOM) || Q_strcmp(resource->szFileName, "tempdecal.wad") != 0 || // client uses only tempdecal.wad for customization
			resource->nDownloadSize <= 0 ||		// FIXED: Check that download size is valid
#endif // REHLDS_FIXES
			resource->nDownloadSize > 1024 * 1024 * 1024)	// FIXME: Are they gone crazy??!
		{
#ifdef REHLDS_FIXES
			SV_ClearResourceLists( host_client );
#else // REHLDS_FIXES
			SV_ClearResourceList( &host_client->resourcesneeded );
			SV_ClearResourceList( &host_client->resourcesonhand );
#endif // REHLDS_FIXES		
			return;
		}

#ifndef REHLDS_FIXES
		SV_AddToResourceList(resource, &host_client->resourcesneeded);
#endif // REHLDS_FIXES
	}

	if (sv_allow_upload.value != 0.0f)
	{
		Con_DPrintf("Verifying and uploading resources...\n");
		totalsize = COM_SizeofResourceList(&host_client->resourcesneeded, &ri);
#ifdef REHLDS_FIXES
		if (totalsize > 0)
#else // REHLDS_FIXES
		if (totalsize != 0)
#endif // REHLDS_FIXES
		{
			Con_DPrintf("Custom resources total %.2fK\n", total / 1024.0f);
#ifndef REHLDS_FIXES // because client can send only decals, why there is need to check other types?
			if (ri.info[t_model].size)
			{
				total = ri.info[t_model].size;
				Con_DPrintf("  Models:  %.2fK\n", total / 1024.0f);
			}
			if (ri.info[t_sound].size)
			{
				total = ri.info[t_sound].size;
				Con_DPrintf("  Sounds:  %.2fK\n", total / 1024.0f);
			}
			if (ri.info[t_decal].size) 
			{
#endif // REHLDS_FIXES
			// this check is useless, because presence of decals was checked before.
				total = ri.info[t_decal].size;
				Con_DPrintf("  Decals:  %.2fK\n", total / 1024.0f);
#ifndef REHLDS_FIXES
			}
			if (ri.info[t_skin].size)
			{
				total = ri.info[t_skin].size;
				Con_DPrintf("  Skins :  %.2fK\n", total / 1024.0f);
			}
			if (ri.info[t_generic].size)
			{
				total = ri.info[t_generic].size;
				Con_DPrintf("  Generic :  %.2fK\n", total / 1024.0f);
			}
			if (ri.info[t_eventscript].size)
			{
				total = ri.info[t_eventscript].size;
				Con_DPrintf("  Events  :  %.2fK\n", total / 1024.0f);
			}
#endif // REHLDS_FIXES
			Con_DPrintf("----------------------\n");

			int bytestodownload = SV_EstimateNeededResources();

			if (bytestodownload > sv_max_upload.value * 1024 * 1024)
			{
#ifdef REHLDS_FIXES
				SV_ClearResourceLists( host_client );
#else // REHLDS_FIXES
				SV_ClearResourceList( &host_client->resourcesneeded );
				SV_ClearResourceList( &host_client->resourcesonhand );
#endif //REHLDS_FIXES
				return;
			}

			if (bytestodownload > 1024)
				Con_DPrintf("Resources to request: %.2fK\n", bytestodownload / 1024.0f);
			else
				Con_DPrintf("Resources to request: %i bytes\n", bytestodownload);
		}
	}

	host_client->uploading = TRUE;
	host_client->uploaddoneregistering = FALSE;

	SV_BatchUploadRequest(host_client);
}