From b7d524423c23470cd11e720eeb48368c072838cb Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Tue, 7 Feb 2012 20:49:52 +0000 Subject: Rewritten all packets to use buffers instead of direct sockets, for future cSocketThreads compatibility. Moved data sending from cPacket into cSocket git-svn-id: http://mc-server.googlecode.com/svn/trunk@240 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/packets/cPacket.cpp | 325 ++++++++++++++++++++++++++++----------------- 1 file changed, 201 insertions(+), 124 deletions(-) (limited to 'source/packets/cPacket.cpp') diff --git a/source/packets/cPacket.cpp b/source/packets/cPacket.cpp index 06ae24706..284e80903 100644 --- a/source/packets/cPacket.cpp +++ b/source/packets/cPacket.cpp @@ -4,226 +4,303 @@ #include "cPacket.h" #include "../Endianness.h" -#ifdef _WIN32 - #define MSG_NOSIGNAL (0) + + + + +/* +// These checks cannot be done in preprocessor, since sizeof() is evaluated while compiling, so in preprocessing it's unknown. +// Check some basic type assumptions: +#if (sizeof(int) != 4) + #error "Bad size for int, protocol won't work" #endif -#ifdef __MAC_NA - #define MSG_NOSIGNAL (0) +#if (sizeof(float) != 4) + #error "Bad size for float, protocol won't work" #endif +#if (sizeof(double) != 8) + #error "Bad size for double, protocol won't work" +#endif +*/ + -//***************************************************************************** -// Blocking receive all function -//***************************************************************************** -int cPacket::RecvAll( cSocket & a_Socket, char* a_Data, unsigned int a_Size, int a_Options ) +int cPacket::ReadString16(const char * a_Data, int a_Size, AString & a_OutString ) { - unsigned int RequestSize = a_Size; - while(a_Size != 0) + int TotalBytes = 0; + short StrLen; + HANDLE_PACKET_READ(ReadShort, StrLen, TotalBytes); + + if (2 * StrLen > a_Size - TotalBytes) { - int Num = recv(a_Socket, a_Data, a_Size, a_Options); - if( cSocket::IsSocketError( Num ) ) - return Num; - a_Size -= Num; - a_Data += Num; + // The string is not yet complete in the buffer + return PACKET_INCOMPLETE; } - return RequestSize - a_Size; -} -//***************************************************************************** -// Own implementation of send() -//***************************************************************************** -int cPacket::SendData( cSocket & a_Socket, const char* a_Message, unsigned int a_Size, int a_Options ) -{ - return send(a_Socket, a_Message, a_Size, a_Options | MSG_NOSIGNAL ); + // Simple UTF-16 to UTF-8 conversion - discard higher bits, ignore multishort sequences: + a_OutString.clear(); + a_OutString.reserve(StrLen); + short * UTF16 = (short *)(a_Data + TotalBytes); + for ( int i = 0; i < StrLen; ++i ) + { + a_OutString.push_back( (char)ntohs(UTF16[i]) ); + } + + return TotalBytes + StrLen * sizeof(short); } -//***************************************************************************** -// New packets -//***************************************************************************** -bool cPacket::ReadString( std::string & a_OutString ) -{ - short StrLen; - if(!ReadShort( StrLen )) return false; - if( StrLen == 0 ) + +int cPacket::ReadShort(const char * a_Data, int a_Size, short & a_OutShort ) +{ + if (a_Size < 2) { - a_OutString.clear(); - return true; + return PACKET_INCOMPLETE; } + a_OutShort = ntohs(*((short *)a_Data)); + return 2; +} - char* cString = new char[StrLen]; - if( cSocket::IsSocketError( RecvAll( m_Socket, cString, StrLen, 0 ) ) ) return false; - a_OutString.assign( cString, StrLen ); - //printf("Discoved string: %s size: %i\n", a_OutString.c_str(), a_OutString.size() ); - delete [] cString; - return true; -} -bool cPacket::ReadString16( std::string & a_OutString ) -{ - short StrLen; - if(!ReadShort( StrLen )) return false; - a_OutString.clear(); - if( StrLen == 0 ) +int cPacket::ReadInteger(const char * a_Data, int a_Size, int & a_OutInteger ) +{ + if (a_Size < 4) { - return true; + return PACKET_INCOMPLETE; } + a_OutInteger = ntohl(*((int *)a_Data)); + return 4; +} - char* UTF16 = new char[StrLen*sizeof( short )]; - if( cSocket::IsSocketError( RecvAll( m_Socket, UTF16, StrLen * sizeof( short ), 0 ) ) ) return false; - for( int i = 0; i < StrLen; ++i ) - a_OutString.push_back( (char)UTF16[i*sizeof( short )+1] ); - //printf("Discoved string: %s size: %i\n", a_OutString.c_str(), a_OutString.size() ); - delete [] UTF16; - return true; -} -bool cPacket::ReadShort( short & a_OutShort ) -{ - if( cSocket::IsSocketError( RecvAll( m_Socket, (char*)&a_OutShort, sizeof(short), 0 ) ) ) return false; - a_OutShort = ntohs(a_OutShort); - return true; -} -bool cPacket::ReadInteger( int & a_OutInteger ) +int cPacket::ReadInteger(const char * a_Data, int a_Size, unsigned int & a_OutInteger ) { - if( cSocket::IsSocketError( RecvAll( m_Socket, (char*)&a_OutInteger, sizeof(int), 0 ) ) ) return false; - a_OutInteger = ntohl(a_OutInteger); - return true; + if (a_Size < 4) + { + return PACKET_INCOMPLETE; + } + a_OutInteger = ntohl(*((unsigned int *)a_Data)); + return 4; } -bool cPacket::ReadInteger( unsigned int & a_OutInteger ) -{ - if( cSocket::IsSocketError( RecvAll( m_Socket, (char*)&a_OutInteger, sizeof(unsigned int), 0 ) ) ) return false; - a_OutInteger = ntohl(a_OutInteger); - return true; -} -bool cPacket::ReadFloat( float & a_OutFloat ) + + + +int cPacket::ReadFloat(const char * a_Data, int a_Size, float & a_OutFloat ) { - if( cSocket::IsSocketError( RecvAll( m_Socket, (char*)&a_OutFloat, sizeof(float), 0 ) ) ) return false; - a_OutFloat = NetworkToHostFloat4( &a_OutFloat ); - return true; + if (a_Size < sizeof(float)) + { + return PACKET_INCOMPLETE; + } + a_OutFloat = NetworkToHostFloat4(a_Data); + return sizeof(float); } -bool cPacket::ReadDouble( double & a_OutDouble ) + + + + +int cPacket::ReadDouble(const char * a_Data, int a_Size, double & a_OutDouble ) { - if( cSocket::IsSocketError( RecvAll( m_Socket, (char*)&a_OutDouble, sizeof(double), 0 ) ) ) return false; - a_OutDouble = NetworkToHostDouble8( &a_OutDouble ); - return true; + if (a_Size < sizeof(double)) + { + return PACKET_INCOMPLETE; + } + a_OutDouble = NetworkToHostDouble8(a_Data); + return sizeof(double); } -bool cPacket::ReadByte( char & a_OutByte ) + + + + +int cPacket::ReadByte(const char * a_Data, int a_Size, char & a_OutByte ) { - return !cSocket::IsSocketError( RecvAll( m_Socket, (char*)&a_OutByte, sizeof(char), 0 ) ); + if (a_Size < 1) + { + return PACKET_INCOMPLETE; + } + a_OutByte = *a_Data; + return 1; } -bool cPacket::ReadByte( unsigned char & a_OutByte ) + + + + +int cPacket::ReadByte(const char * a_Data, int a_Size, unsigned char & a_OutByte ) { - return !cSocket::IsSocketError(RecvAll( m_Socket, (char*)&a_OutByte, sizeof(char), 0 ) ); + if (a_Size < 1) + { + return PACKET_INCOMPLETE; + } + a_OutByte = *((unsigned char *)a_Data); + return 1; } -bool cPacket::ReadLong( long long & a_OutLong ) + + + + +int cPacket::ReadLong(const char * a_Data, int a_Size, long long & a_OutLong ) { - if( cSocket::IsSocketError( RecvAll( m_Socket, (char*)&a_OutLong, sizeof(long long), 0 ) ) ) return false; - a_OutLong = NetworkToHostLong8( &a_OutLong ); - return true; + if (a_Size < sizeof(a_OutLong)) + { + return PACKET_INCOMPLETE; + } + a_OutLong = NetworkToHostLong8(a_Data); + return sizeof(a_OutLong); } -bool cPacket::ReadBool( bool & a_OutBool ) + + + + +int cPacket::ReadBool(const char * a_Data, int a_Size, bool & a_OutBool ) { - if( cSocket::IsSocketError(RecvAll( m_Socket, (char*)&a_OutBool, sizeof(bool), 0 ) ) ) return false; - return true; + if (a_Size < sizeof(bool)) + { + return PACKET_INCOMPLETE; + } + a_OutBool = (*a_Data != 0); + return sizeof(bool); } -//***************************************************************************** -// Append variables to a c-String -//***************************************************************************** -void cPacket::AppendString( std::string & a_String, char* a_Dst, unsigned int & a_Iterator ) + + + + +void cPacket::AppendString(AString & a_Dst, const AString & a_String) { - AppendShort( (unsigned short)a_String.size(), a_Dst, a_Iterator ); - memcpy( a_Dst + a_Iterator, a_String.c_str(), a_String.size() ); a_Iterator += a_String.size(); + AppendShort(a_Dst, (unsigned short)a_String.size()); + a_Dst.append(a_String); } -void cPacket::AppendString16( std::string & a_String, char* a_Dst, unsigned int & a_Iterator ) + + + + +void cPacket::AppendString16(AString & a_Dst, const AString & a_String) { - AppendShort( (unsigned short)a_String.size(), a_Dst, a_Iterator ); - char* UTF16 = new char[ a_String.size() * sizeof( short ) ]; + AppendShort(a_Dst, (unsigned short)a_String.size()); + std::auto_ptr UTF16(new char[a_String.size() * sizeof( short ) ]); for( unsigned int i = 0; i < a_String.size(); ++i ) { - UTF16[i*sizeof( short )] = 0x00;//a_String[i]; - UTF16[i*sizeof( short )+1] = a_String[i]; + UTF16.get()[i * sizeof( short )] = 0x00; + UTF16.get()[i * sizeof( short ) + 1] = a_String[i]; } - memcpy( a_Dst + a_Iterator, UTF16, a_String.size() * sizeof( short ) ); a_Iterator += a_String.size() * sizeof( short ); - delete [] UTF16; + a_Dst.append(UTF16.get(), a_String.size() * sizeof(short)); } -void cPacket::AppendShort( short a_Short, char *a_Dst, unsigned int &a_Iterator ) + + + + +void cPacket::AppendShort(AString & a_Dst, short a_Short) { short ConvertedShort = htons( a_Short ); - memcpy( a_Dst + a_Iterator, &ConvertedShort, sizeof( short ) ); a_Iterator+=sizeof( short ); + a_Dst.append((const char *)&ConvertedShort, sizeof(short)); } -void cPacket::AppendShort( unsigned short a_Short, char *a_Dst, unsigned int &a_Iterator ) + + + + +void cPacket::AppendShort(AString & a_Dst, unsigned short a_Short) { short ConvertedShort = htons( a_Short ); - memcpy( a_Dst + a_Iterator, &ConvertedShort, sizeof( unsigned short ) ); a_Iterator+=sizeof( unsigned short ); + a_Dst.append((const char *)&ConvertedShort, sizeof(short)); } -void cPacket::AppendInteger( int a_Integer, char* a_Dst, unsigned int & a_Iterator ) + + + +void cPacket::AppendInteger(AString & a_Dst, int a_Integer) { int ConvertedInt = htonl( a_Integer ); - memcpy( a_Dst + a_Iterator, &ConvertedInt, sizeof( int ) ); a_Iterator+=sizeof( int ); + a_Dst.append((const char *)&ConvertedInt, sizeof(int)); } -void cPacket::AppendInteger( unsigned int a_Integer, char* a_Dst, unsigned int & a_Iterator ) + + + + +void cPacket::AppendInteger(AString & a_Dst, unsigned int a_Integer) { unsigned int ConvertedInt = htonl( a_Integer ); - memcpy( a_Dst + a_Iterator, &ConvertedInt, sizeof( unsigned int ) ); a_Iterator+=sizeof( unsigned int ); + a_Dst.append((const char *)&ConvertedInt, sizeof(int)); } -void cPacket::AppendFloat( float a_Float, char* a_Dst, unsigned int & a_Iterator ) + + + + +void cPacket::AppendFloat(AString & a_Dst, float a_Float) { unsigned int ConvertedFloat = HostToNetwork4(&a_Float); - memcpy( a_Dst + a_Iterator, &ConvertedFloat, sizeof(float) ); a_Iterator += sizeof(float); + a_Dst.append((const char *)&ConvertedFloat, sizeof(int)); } -void cPacket::AppendDouble( double & a_Double, char* a_Dst, unsigned int & a_Iterator ) + + + + +void cPacket::AppendDouble(AString & a_Dst, const double & a_Double) { unsigned long long ConvertedDouble = HostToNetwork8(&a_Double); - memcpy( a_Dst + a_Iterator, &ConvertedDouble, sizeof(double) ); a_Iterator += sizeof(double); + a_Dst.append((const char *)&ConvertedDouble, 8); } -void cPacket::AppendByte( char a_Byte, char* a_Dst, unsigned int & a_Iterator ) + + + + +void cPacket::AppendByte(AString & a_Dst, char a_Byte) { - a_Dst[a_Iterator] = a_Byte; a_Iterator+=sizeof(char); + a_Dst.append(&a_Byte, 1); } -void cPacket::AppendLong( long long & a_Long, char* a_Dst, unsigned int & a_Iterator ) + + + + +void cPacket::AppendLong(AString & a_Dst, const long long & a_Long) { unsigned long long ConvertedLong = HostToNetwork8(&a_Long); - memcpy( a_Dst + a_Iterator, &ConvertedLong, sizeof(long long) ); - a_Iterator += sizeof( long long ); + a_Dst.append((const char *)&ConvertedLong, sizeof(a_Long)); } -void cPacket::AppendBool( bool a_Bool, char* a_Dst, unsigned int & a_Iterator ) + + + + +void cPacket::AppendBool(AString & a_Dst, bool a_Bool) { - a_Dst[a_Iterator] = (char)a_Bool; a_Iterator+=sizeof(bool); + a_Dst.append((const char *)&a_Bool, 1); } -void cPacket::AppendData( char* a_Data, unsigned int a_Size, char* a_Dst, unsigned int & a_Iterator ) + + + + +void cPacket::AppendData(AString & a_Dst, const char * a_Data, unsigned int a_Size) { - memcpy( a_Dst + a_Iterator, a_Data, a_Size ); a_Iterator += a_Size; + a_Dst.append(a_Data, a_Size); } + + + + -- cgit v1.2.3