void CHLTVDemoRecorder::WriteMessages( unsigned char cmd, bf_write &message ) { int len = message.GetNumBytesWritten(); if (len <= 0) return; // fill last bits in last byte with NOP if necessary int nRemainingBits = message.GetNumBitsWritten() % 8; if ( nRemainingBits > 0 && nRemainingBits <= (8-NETMSG_TYPE_BITS) ) { message.WriteUBitLong( net_NOP, NETMSG_TYPE_BITS ); } Assert( len < NET_MAX_MESSAGE ); // if signondata read as fast as possible, no rewind // and wait for packet time // byte cmd = (m_pDemoFileHeader != NULL) ? dem_signon : dem_packet; if ( cmd == dem_packet ) { m_nFrameCount++; } // write command & time m_DemoFile.WriteCmdHeader( cmd, GetRecordingTick() ); // write NULL democmdinfo just to keep same format as client demos democmdinfo_t info; Q_memset( &info, 0, sizeof( info ) ); m_DemoFile.WriteCmdInfo( info ); // write continously increasing sequence numbers m_DemoFile.WriteSequenceInfo( m_SequenceInfo, m_SequenceInfo ); m_SequenceInfo++; // Output the buffer. Skip the network packet stuff. m_DemoFile.WriteRawData( (char*)message.GetBasePointer(), len ); if ( tv_debug.GetInt() > 1 ) { Msg( "Writing SourceTV demo message %i bytes at file pos %i\n", len, m_DemoFile.GetCurPos( false ) ); } }
int CNetworkStringTable::WriteUpdate( CBaseClient *client, bf_write &buf, int tick_ack ) { CUtlVector< StringHistoryEntry > history; int entriesUpdated = 0; int lastEntry = -1; int count = m_pItems->Count(); for ( int i = 0; i < count; i++ ) { CNetworkStringTableItem *p = &m_pItems->Element( i ); // Client is up to date if ( p->GetTickChanged() <= tick_ack ) continue; int nStartBit = buf.GetNumBitsWritten(); // Write Entry index if ( (lastEntry+1) == i ) { buf.WriteOneBit( 1 ); } else { buf.WriteOneBit( 0 ); buf.WriteUBitLong( i, m_nEntryBits ); } // check if string can use older string as base eg "models/weapons/gun1" & "models/weapons/gun2" char const *pEntry = m_pItems->String( i ); if ( p->GetTickCreated() > tick_ack ) { // this item has just been created, send string itself buf.WriteOneBit( 1 ); int substringsize = 0; int bestprevious = GetBestPreviousString( history, pEntry, substringsize ); if ( bestprevious != -1 ) { buf.WriteOneBit( 1 ); buf.WriteUBitLong( bestprevious, 5 ); // history never has more than 32 entries buf.WriteUBitLong( substringsize, SUBSTRING_BITS ); buf.WriteString( pEntry + substringsize ); } else { buf.WriteOneBit( 0 ); buf.WriteString( pEntry ); } } else { buf.WriteOneBit( 0 ); } // Write the item's user data. int len; const void *pUserData = GetStringUserData( i, &len ); if ( pUserData && len > 0 ) { buf.WriteOneBit( 1 ); if ( IsUserDataFixedSize() ) { // Don't have to send length, it was sent as part of the table definition buf.WriteBits( pUserData, GetUserDataSizeBits() ); } else { buf.WriteUBitLong( len, CNetworkStringTableItem::MAX_USERDATA_BITS ); buf.WriteBits( pUserData, len*8 ); } } else { buf.WriteOneBit( 0 ); } // limit string history to 32 entries if ( history.Count() > 31 ) { history.Remove( 0 ); } // add string to string history StringHistoryEntry she; Q_strncpy( she.string, pEntry, sizeof( she.string ) ); history.AddToTail( she ); entriesUpdated++; lastEntry = i; if ( client && client->IsTracing() ) { int nBits = buf.GetNumBitsWritten() - nStartBit; client->TraceNetworkMsg( nBits, " [%s] %d:%s ", GetTableName(), i, GetString( i ) ); } } return entriesUpdated; }
inline bool NET_SendDatagram(bool subchans = false) { if (senddata.GetNumBytesWritten() == 0) { return false; } unsigned char flags = 0; netdatagram.WriteLong(netchan->m_nOutSequenceNr); // outgoing sequence netdatagram.WriteLong(netchan->m_nInSequenceNr); // incoming sequence bf_write flagpos = netdatagram; netdatagram.WriteByte(0); // flags netdatagram.WriteWord(0); // crc16 int nCheckSumStart = netdatagram.GetNumBytesWritten(); netdatagram.WriteByte(netchan->m_nInReliableState); if (subchans) { flags |= PACKET_FLAG_RELIABLE; } netdatagram.WriteBits(senddata.GetData(), senddata.GetNumBitsWritten()); // Data int nMinRoutablePayload = MIN_ROUTABLE_PAYLOAD; while ((netdatagram.GetNumBytesWritten() < MIN_ROUTABLE_PAYLOAD&&netdatagram.GetNumBitsWritten() % 8 != 0)) { netdatagram.WriteUBitLong(0, NETMSG_TYPE_BITS); } flagpos.WriteByte(flags); void *pvData = datagram + nCheckSumStart; if (pvData) { int nCheckSumBytes = netdatagram.GetNumBytesWritten() - nCheckSumStart; if (nCheckSumBytes > 0) { unsigned short usCheckSum = BufferToShortChecksum(pvData, nCheckSumBytes); flagpos.WriteUBitLong(usCheckSum, 16); netchan->m_nOutSequenceNr++; net.SendTo(serverip, serverport, datagram, netdatagram.GetNumBytesWritten()); } } NET_ResetDatagram(); return true; }