// 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 ); } } }
int EXT_FUNC MSG_ReadBuf_api(int iSize, void *pbuf) { return MSG_ReadBuf(iSize, pbuf); }
/* <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); }