diff --git a/src/d_netsync.cpp b/src/d_netsync.cpp index 755d20f111..793c23f5f7 100644 --- a/src/d_netsync.cpp +++ b/src/d_netsync.cpp @@ -36,112 +36,307 @@ IDList g_NetIDList; //***************************************************************************** // -void NETWORK_AdvanceByteStreamPointer( BYTESTREAM_s *pByteStream, const int NumBytes, const bool OutboundTraffic ) +void BYTESTREAM_s::AdvancePointer( const int NumBytes, const bool OutboundTraffic ) { - pByteStream->pbStream += NumBytes; + this->pbStream += NumBytes; - // [BB] if ( g_MeasuringOutboundTraffic && OutboundTraffic ) g_OutboundBytesMeasured += NumBytes; } //***************************************************************************** // -int NETWORK_ReadByte( BYTESTREAM_s *pByteStream ) +int BYTESTREAM_s::ReadByte() { int Byte = -1; - if (( pByteStream->pbStream + 1 ) <= pByteStream->pbStreamEnd ) - Byte = *pByteStream->pbStream; + if (( this->pbStream + 1 ) <= this->pbStreamEnd ) + Byte = *this->pbStream; // Advance the pointer. - pByteStream->pbStream += 1; + this->pbStream += 1; return ( Byte ); } //***************************************************************************** // -void NETWORK_WriteByte( BYTESTREAM_s *pByteStream, int Byte ) +int BYTESTREAM_s::ReadShort() { - if (( pByteStream->pbStream + 1 ) > pByteStream->pbStreamEnd ) - { - Printf( "NETWORK_WriteByte: Overflow!\n" ); - return; - } + int Short = -1; - *pByteStream->pbStream = Byte; + if (( this->pbStream + 2 ) <= this->pbStreamEnd ) + Short = (short)(( this->pbStream[0] ) + ( this->pbStream[1] << 8 )); // Advance the pointer. - NETWORK_AdvanceByteStreamPointer ( pByteStream, 1, true ); + this->pbStream += 2; + + return ( Short ); } //***************************************************************************** // -void NETWORK_WriteShort( BYTESTREAM_s *pByteStream, int Short ) +int BYTESTREAM_s::ReadLong() { - if (( pByteStream->pbStream + 2 ) > pByteStream->pbStreamEnd ) + int Long = -1; + + if (( this->pbStream + 4 ) <= this->pbStreamEnd ) + { + Long = (( this->pbStream[0] ) + + ( this->pbStream[1] << 8 ) + + ( this->pbStream[2] << 16 ) + + ( this->pbStream[3] << 24 )); + } + + // Advance the pointer. + this->pbStream += 4; + + return ( Long ); +} + +//***************************************************************************** +// +float BYTESTREAM_s::ReadFloat() +{ + union + { + float f; + int i; + } dat; + + dat.i = this->ReadLong(); + return ( dat.f ); +} + +//***************************************************************************** +// +const char *BYTESTREAM_s::ReadString() +{ + int c; + static char s_szString[MAX_NETWORK_STRING]; + + // Read in characters until we've reached the end of the string. + unsigned int ulIdx = 0; + do + { + c = this->ReadByte(); + if ( c <= 0 ) + break; + + // Place this character into our string. + // [BB] Even if we don't have enough space in s_szString, we have to fully + // parse the received string. Otherwise we can't continue parsing the packet. + if ( ulIdx < MAX_NETWORK_STRING - 1 ) + s_szString[ulIdx] = static_cast ( c ); + + ++ulIdx; + + } while ( true ); + + // [BB] We may have read more chars than we can store. + const int endIndex = ( ulIdx < MAX_NETWORK_STRING ) ? ulIdx : MAX_NETWORK_STRING - 1; + s_szString[endIndex] = '\0'; + return ( s_szString ); +} + +//***************************************************************************** +// +bool BYTESTREAM_s::ReadBit() +{ + this->EnsureBitSpace( 1, false ); + + // Use a bit shift to extract a bit from our current byte + bool result = !!( *this->bitBuffer & ( 1 << this->bitShift )); + this->bitShift++; + return result; +} + +//***************************************************************************** +// +int BYTESTREAM_s::ReadVariable() +{ + // Read two bits to form an integer 0...3 + int length = this->ReadBit(); + length |= this->ReadBit() << 1; + + // Use this length to read in an integer of variable length. + switch ( length ) + { + default: + case 0: return 0; + case 1: return this->ReadByte(); + case 2: return this->ReadShort(); + case 3: return this->ReadLong(); + } +} + +//***************************************************************************** +// +int BYTESTREAM_s::ReadShortByte ( int bits ) +{ + if ( bits >= 0 && bits <= 8 ) + { + this->EnsureBitSpace( bits, false ); + int mask = ( 1 << bits ) - 1; // Create a mask to cover the bits we want. + mask <<= this->bitShift; // Shift the mask so that it covers the correct bits. + int result = *this->bitBuffer & mask; // Apply the shifted mask on our byte to remove unwanted bits. + result >>= this->bitShift; // Shift the result back to start from 0. + this->bitShift += bits; // Increase shift to mark these bits as used. + return result; + } + else + { + return 0; + } +} + +//***************************************************************************** +// +void BYTESTREAM_s::ReadBuffer( void *buffer, size_t length ) +{ + if (( this->pbStream + length ) > this->pbStreamEnd ) + { + Printf( "BYTESTREAM_s::ReadBuffer: Overflow!\n" ); + } + else + { + memcpy( buffer, this->pbStream, length ); + this->pbStream += length; + } +} + +//***************************************************************************** +// +void BYTESTREAM_s::WriteByte( int Byte ) +{ + if (( this->pbStream + 1 ) > this->pbStreamEnd ) + { + Printf( "BYTESTREAM_s::WriteByte: Overflow!\n" ); + return; + } + + *this->pbStream = Byte; + + // Advance the pointer. + this->AdvancePointer ( 1, true ); +} + +//***************************************************************************** +// +void BYTESTREAM_s::WriteShort( int Short ) +{ + if (( this->pbStream + 2 ) > this->pbStreamEnd ) { Printf( "NETWORK_WriteShort: Overflow!\n" ); return; } - pByteStream->pbStream[0] = Short & 0xff; - pByteStream->pbStream[1] = Short >> 8; + this->pbStream[0] = Short & 0xff; + this->pbStream[1] = Short >> 8; // Advance the pointer. - NETWORK_AdvanceByteStreamPointer ( pByteStream, 2, true ); + this->AdvancePointer ( 2, true ); } //***************************************************************************** // -void NETWORK_WriteLong( BYTESTREAM_s *pByteStream, int Long ) +void BYTESTREAM_s::WriteLong( int Long ) { - if (( pByteStream->pbStream + 4 ) > pByteStream->pbStreamEnd ) + if (( this->pbStream + 4 ) > this->pbStreamEnd ) { Printf( "NETWORK_WriteLong: Overflow!\n" ); return; } - pByteStream->pbStream[0] = Long & 0xff; - pByteStream->pbStream[1] = ( Long >> 8 ) & 0xff; - pByteStream->pbStream[2] = ( Long >> 16 ) & 0xff; - pByteStream->pbStream[3] = ( Long >> 24 ); + this->pbStream[0] = Long & 0xff; + this->pbStream[1] = ( Long >> 8 ) & 0xff; + this->pbStream[2] = ( Long >> 16 ) & 0xff; + this->pbStream[3] = ( Long >> 24 ); // Advance the pointer. - NETWORK_AdvanceByteStreamPointer ( pByteStream, 4, true ); + this->AdvancePointer ( 4, true ); } //***************************************************************************** // -void NETWORK_WriteBuffer( BYTESTREAM_s *pByteStream, const void *pvBuffer, int nLength ) +void BYTESTREAM_s::WriteFloat( float Float ) { - if (( pByteStream->pbStream + nLength ) > pByteStream->pbStreamEnd ) + union + { + float f; + int l; + } dat; + + dat.f = Float; + + this->WriteLong( dat.l ); +} + +//***************************************************************************** +// +void BYTESTREAM_s::WriteString( const char *pszString ) +{ + if (( pszString ) && ( strlen( pszString ) > MAX_NETWORK_STRING )) + { + Printf( "BYTESTREAM_s::WriteString: String exceeds %d characters!\n", MAX_NETWORK_STRING ); + return; + } + +#ifdef WIN32 + if ( pszString == NULL ) + this->WriteBuffer( "", 1 ); + else + this->WriteBuffer( pszString, (int)( strlen( pszString )) + 1 ); +#else + if ( pszString == NULL ) + this->WriteByte( 0 ); + else + { + this->WriteBuffer( pszString, strlen( pszString )); + this->WriteByte( 0 ); + } +#endif +} + +//***************************************************************************** +// +void BYTESTREAM_s::WriteBuffer( const void *pvBuffer, int nLength ) +{ + if (( this->pbStream + nLength ) > this->pbStreamEnd ) { Printf( "NETWORK_WriteLBuffer: Overflow!\n" ); return; } - memcpy( pByteStream->pbStream, pvBuffer, nLength ); + memcpy( this->pbStream, pvBuffer, nLength ); // Advance the pointer. - NETWORK_AdvanceByteStreamPointer ( pByteStream, nLength, true ); + this->AdvancePointer ( nLength, true ); } //***************************************************************************** // -void NETWORK_WriteBit( BYTESTREAM_s *byteStream, bool bit ) +void BYTESTREAM_s::WriteHeader( int Byte ) +{ + this->WriteByte( Byte ); + this->bitBuffer = NULL; + this->bitShift = -1; +} + +//***************************************************************************** +// +void BYTESTREAM_s::WriteBit( bool bit ) { // Add a bit to this byte - byteStream->EnsureBitSpace( 1, true ); + this->EnsureBitSpace( 1, true ); if ( bit ) - *byteStream->bitBuffer |= 1 << byteStream->bitShift; - ++byteStream->bitShift; + *this->bitBuffer |= 1 << this->bitShift; + ++this->bitShift; } //***************************************************************************** // -void NETWORK_WriteVariable( BYTESTREAM_s *byteStream, int value ) +void BYTESTREAM_s::WriteVariable( int value ) { int length; @@ -156,21 +351,21 @@ void NETWORK_WriteVariable( BYTESTREAM_s *byteStream, int value ) length = 3; // Must be sent as a long // Write this length as two bits - NETWORK_WriteBit( byteStream, !!( length & 1 ) ); - NETWORK_WriteBit( byteStream, !!( length & 2 ) ); + this->WriteBit( !!( length & 1 ) ); + this->WriteBit( !!( length & 2 ) ); // Depending on the required length, write the value. switch ( length ) { - case 1: NETWORK_WriteByte( byteStream, value ); break; - case 2: NETWORK_WriteShort( byteStream, value ); break; - case 3: NETWORK_WriteLong( byteStream, value ); break; + case 1: this->WriteByte( value ); break; + case 2: this->WriteShort( value ); break; + case 3: this->WriteLong( value ); break; } } //***************************************************************************** // -void NETWORK_WriteShortByte( BYTESTREAM_s *byteStream, int value, int bits ) +void BYTESTREAM_s::WriteShortByte( int value, int bits ) { if (( bits < 1 ) || ( bits > 8 )) { @@ -178,11 +373,11 @@ void NETWORK_WriteShortByte( BYTESTREAM_s *byteStream, int value, int bits ) return; } - byteStream->EnsureBitSpace( bits, true ); + this->EnsureBitSpace( bits, true ); value &= (( 1 << bits ) - 1 ); // Form a mask from the bits and trim our value using it. - value <<= byteStream->bitShift; // Shift the value to its proper position. - *byteStream->bitBuffer |= value; // Add it to the byte. - byteStream->bitShift += bits; // Bump the shift value accordingly. + value <<= this->bitShift; // Shift the value to its proper position. + *this->bitBuffer |= value; // Add it to the byte. + this->bitShift += bits; // Bump the shift value accordingly. } //***************************************************************************** @@ -220,13 +415,13 @@ void BYTESTREAM_s::EnsureBitSpace( int bits, bool writing ) if ( writing ) { // Not enough bits left in our current byte, we need a new one. - NETWORK_WriteByte( this, 0 ); + WriteByte( 0 ); bitBuffer = pbStream - 1; } else { // No room for the value in this byte, so we need a new one. - if ( NETWORK_ReadByte( this ) != -1 ) + if ( this->ReadByte() != -1 ) { bitBuffer = pbStream - 1; } @@ -324,7 +519,7 @@ int NETBUFFER_s::WriteTo( BYTESTREAM_s &ByteStream ) const { int bufferSize = CalcSize(); if ( bufferSize > 0 ) - NETWORK_WriteBuffer( &ByteStream, this->pbData, bufferSize ); + ByteStream.WriteBuffer( this->pbData, bufferSize ); return bufferSize; } @@ -400,7 +595,7 @@ void NetCommand::addFloat ( const float FloatValue ) // void NetCommand::addBit( const bool value ) { - NETWORK_WriteBit( &_buffer.ByteStream, value ); + _buffer.ByteStream.WriteBit( value ); _buffer.ulCurrentSize = _buffer.CalcSize(); } @@ -408,7 +603,7 @@ void NetCommand::addBit( const bool value ) // void NetCommand::addVariable( const int value ) { - NETWORK_WriteVariable( &_buffer.ByteStream, value ); + _buffer.ByteStream.WriteVariable( value ); _buffer.ulCurrentSize = _buffer.CalcSize(); } @@ -417,7 +612,7 @@ void NetCommand::addVariable( const int value ) // void NetCommand::addShortByte ( int value, int bits ) { - NETWORK_WriteShortByte( &_buffer.ByteStream, value, bits ); + _buffer.ByteStream.WriteShortByte( value, bits ); _buffer.ulCurrentSize = _buffer.CalcSize(); } diff --git a/src/d_netsync.h b/src/d_netsync.h index e6432db0a8..7dd531a1f9 100644 --- a/src/d_netsync.h +++ b/src/d_netsync.h @@ -49,6 +49,28 @@ struct BYTESTREAM_s BYTESTREAM_s(); void EnsureBitSpace( int bits, bool writing ); + int ReadByte(); + int ReadShort(); + int ReadLong(); + float ReadFloat(); + const char* ReadString(); + bool ReadBit(); + int ReadVariable(); + int ReadShortByte( int bits ); + void ReadBuffer( void* buffer, size_t length ); + + void WriteByte( int Byte ); + void WriteShort( int Short ); + void WriteLong( int Long ); + void WriteFloat( float Float ); + void WriteString( const char *pszString ); + void WriteBit( bool bit ); + void WriteVariable( int value ); + void WriteShortByte( int value, int bits ); + void WriteBuffer( const void *pvBuffer, int nLength ); + + void WriteHeader( int Byte ); + // Pointer to our stream of data. uint8_t *pbStream; @@ -58,6 +80,8 @@ struct BYTESTREAM_s uint8_t *bitBuffer; int bitShift; + + void AdvancePointer( const int NumBytes, const bool OutboundTraffic ); }; //*****************************************************************************