void UTIL_DecodeICE( unsigned char * buffer, int size, const unsigned char *key) { if ( !key ) return; IceKey ice( 0 ); // level 0 = 64bit key ice.set( key ); // set key int blockSize = ice.blockSize(); unsigned char *temp = (unsigned char *)_alloca( PAD_NUMBER( size, blockSize ) ); unsigned char *p1 = buffer; unsigned char *p2 = temp; // encrypt data in 8 byte blocks int bytesLeft = size; while ( bytesLeft >= blockSize ) { ice.decrypt( p1, p2 ); bytesLeft -= blockSize; p1+=blockSize; p2+=blockSize; } // copy encrypted data back to original buffer Q_memcpy( buffer, temp, size-bytesLeft ); }
bool CHLTVClientState::ProcessVoiceData( SVC_VoiceData *msg ) { int size = PAD_NUMBER( Bits2Bytes(msg->m_nLength), 4); byte *buffer = (byte*) stackalloc( size ); msg->m_DataIn.ReadBits( buffer, msg->m_nLength ); msg->m_DataOut = buffer; return m_pHLTV->SendNetMsg( *msg ); // relay to server }
bool PackedEntity::AllocAndCopyPadded( const void *pData, unsigned long size, PackedDataAllocator *pAllocator ) { m_Data.Free(); unsigned long nBytes = PAD_NUMBER( size, 4 ); if ( pAllocator->Alloc( nBytes, m_Data ) ) { void *pDest = m_Data.Lock(); if ( pDest ) { memcpy( pDest, pData, size ); m_Data.Unlock(); SetNumBits( nBytes * 8 ); return true; } } return false; }
//----------------------------------------------------------------------------- // Writes the compressed packet of entities to all clients //----------------------------------------------------------------------------- void SV_ComputeClientPacks( int clientCount, client_t** clients, CFrameSnapshot *snapshot, client_frame_t **pPack ) { VPROF( "SV_ComputeClientPacks" ); ClientPackInfo_t info[MAX_CLIENTS]; // Do some setup for each client int iClient; for (iClient = 0; iClient < clientCount; ++iClient) { ClientPackInfo_t *pInfo = &info[iClient]; // This helps handle it if they turn cl_LocalNetworkBackdoor on and off (which is useful to do for profiling). SV_HandleLocalNetworkBackdoorChange( clients[iClient] ); // This will force network string table updates for local client to go through the backdoor if it's active SV_CheckDirectUpdate( clients[iClient] ); SV_ComputeClientPackInfo( clients[iClient], pInfo ); // This is the frame we are creating, i.e., the next // frame after the last one that the client acknowledged client_frame_t& frame = clients[iClient]->frames[clients[iClient]->netchan.outgoing_sequence & SV_UPDATE_MASK]; pPack[iClient] = &frame; SV_SetupPack( pPack[iClient], snapshot ); // Clear the 'transmit edict' bits for this ent for this client. memset( pInfo->m_EdictBits, 0, PAD_NUMBER( sv.num_edicts, 8 ) / 8 ); pInfo->m_pPVS = pInfo->m_PVS; pInfo->m_pEdictBits = pInfo->m_EdictBits; // Since area to area visibility is determined by each player's PVS, copy // the area network lookups into the ClientPackInfo_t pInfo->m_AreasNetworked.RemoveAll(); int areaCount = g_AreasNetworked.Count(); for ( int i = 0; i < areaCount; i++ ) { pInfo->m_AreasNetworked.AddToTail( g_AreasNetworked[ i ] ); } } // Figure out which entities should be sent. int validEdicts[MAX_EDICTS]; int nValidEdicts = 0; for ( int iEdict=0; iEdict < sv.num_edicts; iEdict++ ) { edict_t* ent = SV_GetEdictToTransmit( iEdict, snapshot ); if ( !ent || !ent->m_pEnt ) continue; // Get the edict send table SendTable* pSendTable = GetEntSendTable( ent ); assert( pSendTable ); if ( !pSendTable ) continue; validEdicts[nValidEdicts++] = iEdict; for ( int iClient=0; iClient < clientCount; iClient++ ) { ClientPackInfo_t *pInfo = &info[iClient]; Assert( pInfo ); int areaCount = pInfo->m_AreasNetworked.Count(); for ( int iArea=0; iArea < areaCount; iArea++ ) { // If the edict is already marked to send to this client, we don't need to call CheckTransmit on it. if ( pInfo->WillTransmit( iEdict ) ) break; pInfo->m_iArea = pInfo->m_AreasNetworked[ iArea ]; CServerDTITimer timer( pSendTable, SERVERDTI_SHOULDTRANSMIT ); ent->m_pEnt->CheckTransmit( pInfo ); } } } #ifndef SWDS int saveTicks = cl.tickcount; #endif if ( g_pLocalNetworkBackdoor ) { g_pLocalNetworkBackdoor->StartEntityStateUpdate(); #ifndef SWDS cl.tickcount = sv.tickcount; g_ClientGlobalVariables.tickcount = cl.tickcount; g_ClientGlobalVariables.curtime = cl.gettime(); #endif } // Send client all active entities in the pvs for ( int iValidEdict=0; iValidEdict < nValidEdicts; iValidEdict++ ) { int e = validEdicts[iValidEdict]; edict_t* ent = SV_GetEdictToTransmit(e, snapshot); SendTable* pSendTable = GetEntSendTable( ent ); // Check to see if the entity changed this frame... EntityChange_t changeType = ent->m_pEnt->DetectNetworkStateChanges(); ServerDTI_RegisterNetworkStateChange( pSendTable, changeType ); // Have we packed this entity this frame? bool packedThisEntity = false; IServerEntity *serverEntity = ent->GetIServerEntity(); if ( serverEntity ) { serverEntity->SetSentLastFrame( false ); } // Compute the entity bit + byte for the entity_in_pvs bitfield int entityByte = e >> 3; byte entityBit = ( 1 << ( e & 7 ) ); for (int i = 0; i < clientCount; ++i ) { ClientPackInfo_t *pInfo = &info[i]; if ( g_pLocalNetworkBackdoor ) { // this is a bit of a hack to ensure that we get a "preview" of the // packet timstamp that the server will send so that things that // are encoded relative to packet time will be correct int serialNum = ent->m_pEnt->GetRefEHandle().GetSerialNumber() & (1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS) - 1; if( pInfo->WillTransmit( e ) ) { CServerDTITimer timer( pSendTable, SERVERDTI_ENCODE ); // If we're using the fast path for a single-player game, just pass the entity // directly over to the client. ServerClass *pClass = ent->m_pEnt->GetServerClass(); g_pLocalNetworkBackdoor->EntState( e, serialNum, pClass->m_ClassID, pSendTable, ent->m_pEnt, changeType != ENTITY_CHANGE_NONE ); // Indicate we've actually put the changes into the pack ent->m_pEnt->ResetNetworkStateChanges(); } else { // Notify the client that the ent is still alive, but its ShouldTransmit returned false. g_pLocalNetworkBackdoor->EntityDormant( e, serialNum ); } } else { if( !pInfo->WillTransmit( e ) ) continue; // Mark that this player will have seen this entity created // (i.e., sent, at least once) ent->entity_created |= info[i].m_ClientBit; pPack[i]->entity_in_pvs[ entityByte ] |= entityBit; // Check to see if it's already been packed this frame... // If it hasn't, then pack it in, baby! if ( !packedThisEntity ) { packedThisEntity = true; SV_PackEntity( e, ent, pSendTable, changeType, snapshot ); ent->m_pEnt->ResetNetworkStateChanges(); } } // We've got one more entity in this pack. ++pPack[i]->entities.num_entities; // Now this is our biggest ent index in the pack pPack[i]->entities.max_entities = e; } } if ( g_pLocalNetworkBackdoor ) { g_pLocalNetworkBackdoor->EndEntityStateUpdate(); #ifndef SWDS cl.tickcount = saveTicks; g_ClientGlobalVariables.tickcount = cl.tickcount; g_ClientGlobalVariables.curtime = cl.gettime(); #endif } }