Initial MSVC 2008 projects workspace
This commit is contained in:
239
l2packets/base/ByteArray.cpp
Normal file
239
l2packets/base/ByteArray.cpp
Normal file
@@ -0,0 +1,239 @@
|
||||
#include "stdafx.h"
|
||||
#include "ByteArray.h"
|
||||
#include "../xcpt/L2Packets_xcpt.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
int ByteArray::_debugPrintf( const char *_Format, ... )
|
||||
{
|
||||
if( !this->bDebugMode ) return 0;
|
||||
if( !_Format ) return 0;
|
||||
if( !this->fLogFile ) return 0;
|
||||
va_list args;
|
||||
int ret = 0;
|
||||
va_start( args, _Format );
|
||||
ret = vfprintf( this->fLogFile, _Format, args );
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ByteArray::setDebugMode( bool bDebug, FILE *flog )
|
||||
{
|
||||
if( bDebug && flog )
|
||||
{
|
||||
this->bDebugMode = bDebug;
|
||||
this->fLogFile = flog;
|
||||
return;
|
||||
}
|
||||
if( !bDebug )
|
||||
{
|
||||
this->bDebugMode = false;
|
||||
this->fLogFile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void ByteArray::dumpArrayInfo( FILE * fOut )
|
||||
{
|
||||
if( !fOut ) return;
|
||||
fprintf( fOut, "==== Dump of Array info ====\n" );
|
||||
fprintf( fOut, " Size: %u\n", this->byteCount );
|
||||
if( this->byteCount > 0 )
|
||||
{
|
||||
unsigned i = 0;
|
||||
while( i < this->byteCount )
|
||||
{
|
||||
fprintf( fOut, "%c:%02X ", this->bytes[i], this->bytes[i] );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
fprintf( fOut, "\n==== end dump ====\n" );
|
||||
}
|
||||
#endif
|
||||
|
||||
void ByteArray::_initNull()
|
||||
{
|
||||
// data
|
||||
this->byteCount = 0;
|
||||
this->bytes = NULL;
|
||||
// debug mode vars
|
||||
#ifdef _DEBUG
|
||||
this->bDebugMode = false;
|
||||
this->fLogFile = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ByteArray::_freeSelf()
|
||||
{
|
||||
if( (this->byteCount > 0) && (this->bytes) )
|
||||
{
|
||||
free( this->bytes );
|
||||
this->bytes = NULL;
|
||||
this->byteCount = 0;
|
||||
#ifdef _DEBUG
|
||||
_debugPrintf( "ByteArray::_freeSelf() freeed\n" );
|
||||
#endif
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
else _debugPrintf( "ByteArray::_freeSelf() nothing to free\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
ByteArray::ByteArray()
|
||||
{
|
||||
this->_initNull();
|
||||
}
|
||||
|
||||
ByteArray::ByteArray( unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
if( length > 0 ) this->setSize( length );
|
||||
}
|
||||
|
||||
ByteArray::ByteArray( const char *string )
|
||||
{
|
||||
this->_initNull();
|
||||
if( string ) this->setBytesFromString( string );
|
||||
}
|
||||
|
||||
ByteArray::ByteArray( const unsigned char *newBytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( newBytes, length );
|
||||
}
|
||||
|
||||
ByteArray::ByteArray( const ByteArray& ba )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( ba.bytes, ba.byteCount );
|
||||
}
|
||||
|
||||
ByteArray::~ByteArray()
|
||||
{
|
||||
this->_freeSelf();
|
||||
#ifdef _DEBUG
|
||||
_debugPrintf( "ByteArray::~ByteArray() worked\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ByteArray::setSize( unsigned int newSize )
|
||||
{
|
||||
if( newSize == 0 )
|
||||
{
|
||||
this->_freeSelf();
|
||||
return true;
|
||||
}
|
||||
if( newSize == this->byteCount ) return true; // already have that size
|
||||
if( newSize > 0 )
|
||||
{
|
||||
unsigned char *newPtr = (unsigned char *)realloc( this->bytes, newSize );
|
||||
if( newPtr )
|
||||
{
|
||||
this->bytes = newPtr;
|
||||
this->byteCount = newSize;
|
||||
return true;
|
||||
}
|
||||
#ifdef L2P_THROW
|
||||
else throw L2P_MemoryError( "ByteArray::setSize()", newSize );
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
unsigned char ByteArray::getByteAt( unsigned int index ) const
|
||||
{
|
||||
if( (this->byteCount > 0) && (this->bytes) )
|
||||
{
|
||||
if( index < (this->byteCount) ) return this->bytes[index];
|
||||
return 0;
|
||||
}
|
||||
#ifdef L2P_THROW
|
||||
throw L2P_ReadException( "ByteArray::getByteAt()", 1, (int)index, (int)byteCount );
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned char ByteArray::setByteAt( unsigned int index, unsigned char byteSet )
|
||||
{
|
||||
if( (this->byteCount > 0) && (this->bytes) )
|
||||
{
|
||||
unsigned char retVal = 0;
|
||||
if( index < (this->byteCount) )
|
||||
{
|
||||
retVal = this->bytes[index];
|
||||
this->bytes[index] = byteSet;
|
||||
}
|
||||
#ifdef L2P_THROW
|
||||
else throw L2P_WriteException( "ByteArray::setByteAt()", 1, (int)index, (int)byteCount );
|
||||
#endif
|
||||
return retVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef L2P_THROW
|
||||
throw L2P_WriteException( "ByteArray::setByteAt()", 1, (int)index, (int)byteCount );
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void ByteArray::memset( unsigned char c )
|
||||
{
|
||||
if( (this->byteCount > 0) && (this->bytes) )
|
||||
{
|
||||
/*unsigned int i = 0;
|
||||
while( i < this->byteCount )
|
||||
this->bytes[i++] = c;*/
|
||||
::memset( this->bytes, c, this->byteCount );
|
||||
}
|
||||
}
|
||||
|
||||
bool ByteArray::setBytes( const unsigned char *newBytes, unsigned int length )
|
||||
{
|
||||
if( length < 1 ) return false;
|
||||
//unsigned int i = 0;
|
||||
//
|
||||
//printf( "ByteArray::setBytes( 0x%p, %u )\n", newBytes, length );
|
||||
//printf( "ByteArray::setBytes(): %u < %u?\n", this->byteCount, length );
|
||||
//
|
||||
// check if it is enough space in 'bytes' now
|
||||
if( this->byteCount < length ) // not enough
|
||||
{
|
||||
// we should try to grow to required size
|
||||
if( !this->setSize( length ) ) return false; // growing failed :(
|
||||
}
|
||||
// if we're here, space in 'bytes' buffer is enough to hold 'length' bytes
|
||||
this->memset( 0x00 );
|
||||
//while( i < length ) this->bytes[i] = newBytes[i++];
|
||||
memcpy( this->bytes, newBytes, length );
|
||||
//printf( "ByteArray::setBytes(): %u bytes set OK (buffer len %u)\n", length, this->byteCount );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ByteArray::setBytesFromString( const char *string )
|
||||
{
|
||||
if( !string ) return false;
|
||||
unsigned int str_len = strlen( string );
|
||||
if( str_len < 1 ) return false;
|
||||
return this->setBytes( (const unsigned char *)string, str_len );
|
||||
}
|
||||
|
||||
bool ByteArray::setBytesFromPtrNoMemcpy( unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
if( !bytes || (length<1) ) return false;
|
||||
this->byteCount = length;
|
||||
this->bytes = bytes;
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned char ByteArray::operator[]( int index ) const
|
||||
{
|
||||
if( (this->byteCount > 0) && (this->bytes) )
|
||||
{
|
||||
if( (index>=0) && (index<((int)(this->byteCount))) ) return this->bytes[index];
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
111
l2packets/base/ByteArray.h
Normal file
111
l2packets/base/ByteArray.h
Normal file
@@ -0,0 +1,111 @@
|
||||
#ifndef H_BYTEARRAY
|
||||
#define H_BYTEARRAY
|
||||
|
||||
/** \class ByteArray
|
||||
* Represents array of bytes with variable size.\n
|
||||
* L2Packets programmer does not work with ByteArray directly.
|
||||
* This object is used inside L2BasePacket to hold raw packet data bytes.
|
||||
*/
|
||||
|
||||
class ByteArray
|
||||
{
|
||||
public: // constructors/destructors
|
||||
/** Default constructor with zero array length */
|
||||
ByteArray();
|
||||
/** Constructs ByteArray object with specified array length
|
||||
* \param length - size in bytes to reserve space
|
||||
*/
|
||||
ByteArray( unsigned int length );
|
||||
/** Constructs ByteArray object with length equal to length of string \n
|
||||
* and with contents of this string. \n
|
||||
* Calls setBytesFromString( string );
|
||||
* \param string - string from which to set contents of created ByteArray
|
||||
*/
|
||||
ByteArray( const char *string );
|
||||
/** Copy constructor */
|
||||
ByteArray( const ByteArray& ba );
|
||||
/** Constructs ByteArray object and sets its size and contents.
|
||||
* \param newBytes pointer to data to set contents
|
||||
* \param length data size
|
||||
*/
|
||||
ByteArray( const unsigned char *newBytes, unsigned int length );
|
||||
~ByteArray();
|
||||
|
||||
public: // size funcs
|
||||
/** \return Current array size. */
|
||||
inline unsigned int getSize() const { return this->byteCount; }
|
||||
/** sets new size of buffer. Contents remain unchanged (but may be truncated). \n
|
||||
* In general, calls C runtime realloc()\n
|
||||
* May throw L2P_MemoryError exception, if enabled.
|
||||
* \param newSize new size of buffer. Must be >= 0
|
||||
*/
|
||||
bool setSize( unsigned int newSize );
|
||||
|
||||
public: // data functions
|
||||
/** \return pointer to internal data buffer */
|
||||
inline unsigned char *getBytesPtr() const { return this->bytes; }
|
||||
|
||||
/** Get byte value at specified index.\n
|
||||
* May throw L2P_ReadException, if enabled.
|
||||
* \param index Index of byte to retreive. If index is out of array bounds, function returns zero.
|
||||
* \return byte alue at index, or 0 if index does not belong to array.
|
||||
*/
|
||||
unsigned char getByteAt( unsigned int index ) const;
|
||||
/** Sets byte at specified index.\n
|
||||
* May throw L2P_WriteException, if enabled.
|
||||
* \param index Byte index to set. If index does not belong to array, function does nothing.
|
||||
* \param byteSet new byte value
|
||||
* \return previous byte value */
|
||||
unsigned char setByteAt( unsigned int index, unsigned char byteSet );
|
||||
|
||||
/** Fills array with specified byte value.
|
||||
* \param c value to assign to all bytes. */
|
||||
void memset( unsigned char c );
|
||||
/** Sets all array contents. Data is copied to internal storage
|
||||
* \param newBytes data to set.
|
||||
* \param length length of data. If length is > current array length, function resizes array to fit contents.
|
||||
* \return true, if set was ok. false, if there were errors (memory failure?)
|
||||
*/
|
||||
bool setBytes( const unsigned char *newBytes, unsigned int length );
|
||||
/** Sets array data from string data. Terminating zero is not appended.
|
||||
* \param string string from which to copy bytes.
|
||||
* \return true/false */
|
||||
bool setBytesFromString( const char *string );
|
||||
/** Sets internal pointer to data buffer and internal bytes counter from specified pointer to data and size.\n
|
||||
* Data is not copied (works much faster)\n
|
||||
* This function is not recommended to use, because:\n
|
||||
* WARNING! buffer must be allocated by the same C runtime as library uses - malloc(), realloc(), calloc(). \n
|
||||
* WARNING! object frees its buffer when destructor executes, so, free() will be called for source buffer.
|
||||
* \param bytes data to set.
|
||||
* \param length length of data. If length is > current array length, function resizes array to fit contents.
|
||||
* \return true, if set was ok.*/
|
||||
bool setBytesFromPtrNoMemcpy( unsigned char *bytes, unsigned int length );
|
||||
|
||||
public: // operators
|
||||
/** Calls getByteAt( index ) */
|
||||
unsigned char operator[]( int index ) const;
|
||||
|
||||
protected: // internal functions
|
||||
void _initNull();
|
||||
void _freeSelf();
|
||||
|
||||
// debug functions
|
||||
#ifdef _DEBUG
|
||||
public:
|
||||
void setDebugMode( bool bDebug, FILE *flog );
|
||||
int _debugPrintf( const char *_Format, ... );
|
||||
void dumpArrayInfo( FILE * fOut );
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// data
|
||||
unsigned int byteCount; ///< internal array size counter
|
||||
unsigned char *bytes; ///< internal pointer to allocated buffer
|
||||
// debug mode vars
|
||||
#ifdef _DEBUG
|
||||
bool bDebugMode;
|
||||
FILE *fLogFile;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
650
l2packets/base/L2BasePacket.cpp
Normal file
650
l2packets/base/L2BasePacket.cpp
Normal file
@@ -0,0 +1,650 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2BasePacket.h"
|
||||
#include "../xcpt/L2Packets_xcpt.h"
|
||||
|
||||
L2BasePacket::L2BasePacket()
|
||||
{
|
||||
this->_initNull();
|
||||
}
|
||||
|
||||
L2BasePacket::L2BasePacket( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
L2BasePacket::~L2BasePacket()
|
||||
{
|
||||
_freeSelf();
|
||||
}
|
||||
|
||||
bool L2BasePacket::setBytes( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
_initNull();
|
||||
if( !bytes || (length < 2) ) return false;
|
||||
//
|
||||
//printf( "L2BasePacket::setBytes( 0x%p, %u )\n", bytes, length );
|
||||
//
|
||||
this->ensureCanWriteBytes( length );
|
||||
bool ret = this->b.setBytes( bytes, length );
|
||||
if( ret )
|
||||
{
|
||||
this->buffer_size = b.getSize();
|
||||
this->real_size = length;
|
||||
this->datasize = length - 2; // length always >= 2 here
|
||||
this->write_ptr = length;
|
||||
this->read_ptr = 2;
|
||||
// should we update packet size field in packet (0,1 bytes) here?, YES, imo
|
||||
this->b.setByteAt( 0, (unsigned char)((length) & 0xff) );
|
||||
this->b.setByteAt( 1, (unsigned char)((length >> 8) & 0xff) );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool L2BasePacket::setBytesPtr( unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
if( !bytes || (length < 2) ) return false;
|
||||
if( this->b.setBytesFromPtrNoMemcpy( bytes, length ) )
|
||||
{
|
||||
this->buffer_size = b.getSize();
|
||||
this->real_size = length;
|
||||
this->datasize = length - 2;
|
||||
this->write_ptr = length;
|
||||
this->read_ptr = 2;
|
||||
// should we update packet size field in packet (0,1 bytes) here?, YES, imo
|
||||
this->b.setByteAt( 0, (unsigned char)((length) & 0xff) );
|
||||
this->b.setByteAt( 1, (unsigned char)((length >> 8) & 0xff) );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void L2BasePacket::setPacketType( unsigned char type )
|
||||
{
|
||||
writeReset();
|
||||
writeUChar( type );
|
||||
}
|
||||
|
||||
void L2BasePacket::setPacketType2( unsigned char opcode, unsigned short opcode2 )
|
||||
{
|
||||
writeReset();
|
||||
writeUChar( opcode );
|
||||
writeUShort( opcode2 );
|
||||
}
|
||||
|
||||
void L2BasePacket::setPacketType3( unsigned char opcode, unsigned short opcode2, unsigned short opcode3 )
|
||||
{
|
||||
writeReset();
|
||||
writeUChar( opcode );
|
||||
writeUShort( opcode2 );
|
||||
writeUShort( opcode3 );
|
||||
}
|
||||
|
||||
/*unsigned char L2BasePacket::getPacketType()
|
||||
{
|
||||
readReset();
|
||||
return readUChar();
|
||||
}*/
|
||||
|
||||
/*unsigned short L2BasePacket::getPacketSize() const
|
||||
{
|
||||
return (unsigned short)(this->real_size);
|
||||
}*/
|
||||
/*unsigned short L2BasePacket::getDataSize() const// number of DATA bytes in packet
|
||||
{
|
||||
return (unsigned short)(this->datasize);
|
||||
}*/
|
||||
|
||||
bool L2BasePacket::ensureCanWriteBytes( unsigned int nBytes )
|
||||
{
|
||||
if( nBytes == 0 ) return true;
|
||||
unsigned int end_ptr = write_ptr + nBytes - 1; // calc write end pointer
|
||||
// loop until end_ptr fits in buffer size
|
||||
while( end_ptr >= buffer_size ) // not enough place in buffer
|
||||
{
|
||||
if( !this->_growBuffer() ) return false; // _growBuffer() increases buffer_size
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void L2BasePacket::writeChar( char c )
|
||||
{
|
||||
if( !this->ensureCanWriteBytes( 1 ) ) return; // TODO: Throw exception??
|
||||
this->b.setByteAt( this->write_ptr, (unsigned char)c );
|
||||
this->write_ptr++;
|
||||
this->real_size++;
|
||||
this->datasize++;
|
||||
// update packet size
|
||||
// 1st 2 bytes contain only DATA size? no IMO
|
||||
unsigned short psize = (unsigned short)real_size;
|
||||
//unsigned short psize = (unsigned short)datasize;
|
||||
unsigned char *psaddr = (unsigned char *)&psize;
|
||||
b.setByteAt( 0, psaddr[0] );
|
||||
b.setByteAt( 1, psaddr[1] );
|
||||
}
|
||||
|
||||
void L2BasePacket::writeUChar( unsigned char c )
|
||||
{
|
||||
if( !this->ensureCanWriteBytes( 1 ) ) return; // TODO: Throw exception??
|
||||
//printf( "L2BasePacket::writeUChar(): writing [0x%02X] at idx [%d]\n",
|
||||
// (unsigned int)c, this->write_ptr );
|
||||
this->b.setByteAt( this->write_ptr, c );
|
||||
this->write_ptr++;
|
||||
this->real_size++;
|
||||
this->datasize++;
|
||||
// update packet size
|
||||
unsigned short psize = (unsigned short)real_size;
|
||||
unsigned char *psaddr = (unsigned char *)&psize;
|
||||
b.setByteAt( 0, psaddr[0] );
|
||||
b.setByteAt( 1, psaddr[1] );
|
||||
}
|
||||
|
||||
void L2BasePacket::writeBytes( const unsigned char *bytes, unsigned int len )
|
||||
{
|
||||
if( !bytes || (len<1) ) return;
|
||||
unsigned int i;
|
||||
for( i=0; i<len; i++ ) this->writeUChar( bytes[i] );
|
||||
}
|
||||
|
||||
void L2BasePacket::writeShort( short int s )
|
||||
{
|
||||
char leftByte = (char)(s & 0x00FF);
|
||||
char rightByte = (char)( (s & 0xFF00) >> 8 );
|
||||
this->writeChar( leftByte );
|
||||
this->writeChar( rightByte );
|
||||
}
|
||||
|
||||
void L2BasePacket::writeUShort( unsigned short int s )
|
||||
{
|
||||
unsigned char leftByte = (unsigned char)( s & (unsigned short)0x00FF);
|
||||
unsigned char rightByte = (unsigned char)( (s & (unsigned short)0xFF00) >> 8 );
|
||||
this->writeUChar( leftByte );
|
||||
this->writeUChar( rightByte );
|
||||
}
|
||||
|
||||
void L2BasePacket::writeInt( int i )
|
||||
{
|
||||
char b1 = (char)( i & (int)0x000000FF);
|
||||
char b2 = (char)( (i & (int)0x0000FF00) >> 8 );
|
||||
char b3 = (char)( (i & (int)0x00FF0000) >> 16 );
|
||||
char b4 = (char)( (i & (int)0xFF000000) >> 24 );
|
||||
this->writeChar( b1 );
|
||||
this->writeChar( b2 );
|
||||
this->writeChar( b3 );
|
||||
this->writeChar( b4 );
|
||||
}
|
||||
|
||||
void L2BasePacket::writeUInt( unsigned int i )
|
||||
{
|
||||
unsigned char b1 = (unsigned char)( i & (unsigned int)0x000000FF);
|
||||
unsigned char b2 = (unsigned char)( (i & (unsigned int)0x0000FF00) >> 8 );
|
||||
unsigned char b3 = (unsigned char)( (i & (unsigned int)0x00FF0000) >> 16 );
|
||||
unsigned char b4 = (unsigned char)( (i & (unsigned int)0xFF000000) >> 24 );
|
||||
this->writeUChar( b1 );
|
||||
this->writeUChar( b2 );
|
||||
this->writeUChar( b3 );
|
||||
this->writeUChar( b4 );
|
||||
}
|
||||
|
||||
void L2BasePacket::writeInt64( long long int i64 )
|
||||
{
|
||||
char *i64b = (char *)(&i64);
|
||||
unsigned int i;
|
||||
for( i=0; i<sizeof(long long int); i++ ) this->writeChar( i64b[i] );
|
||||
}
|
||||
|
||||
void L2BasePacket::writeUInt64( unsigned long long int i64 )
|
||||
{
|
||||
unsigned char *i64b = (unsigned char *)(&i64);
|
||||
unsigned int i;
|
||||
for( i=0; i<sizeof(unsigned long long int); i++ ) this->writeUChar( i64b[i] );
|
||||
}
|
||||
|
||||
void L2BasePacket::writeDouble( double d )
|
||||
{
|
||||
char *pd = (char *)(&d);
|
||||
unsigned int i;
|
||||
for( i=0; i<sizeof(double); i++ ) this->writeChar( pd[i] );
|
||||
}
|
||||
|
||||
void L2BasePacket::writeString( const char *str )
|
||||
{
|
||||
if( !str ) return;
|
||||
char *p = (char *)str;
|
||||
while( (*p) )
|
||||
{
|
||||
this->writeChar( (*p) );
|
||||
p++;
|
||||
}
|
||||
this->writeChar( 0 );
|
||||
}
|
||||
|
||||
void L2BasePacket::writeUnicodeString( const wchar_t *ustr )
|
||||
{
|
||||
if( !ustr ) return;
|
||||
wchar_t *p = (wchar_t *)ustr;
|
||||
while( (*p) )
|
||||
{
|
||||
this->writeShort( (*p) );
|
||||
p++;
|
||||
}
|
||||
this->writeShort( 0x0000 );
|
||||
}
|
||||
|
||||
bool L2BasePacket::canReadBytes( unsigned int nBytes )
|
||||
{
|
||||
if( nBytes == 0 ) return true;
|
||||
unsigned int end_ptr = read_ptr + nBytes;
|
||||
if( end_ptr <= real_size ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
char L2BasePacket::readChar()
|
||||
{
|
||||
if( !canReadBytes( 1 ) )
|
||||
#ifdef L2P_THROW
|
||||
throw L2P_ReadException( "L2BasePacket::readChar()", 1, (int)read_ptr, (int)real_size );
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
char ret = b.getByteAt( read_ptr );
|
||||
read_ptr++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned char L2BasePacket::readUChar()
|
||||
{
|
||||
if( !canReadBytes( 1 ) )
|
||||
#ifdef L2P_THROW
|
||||
throw L2P_ReadException( "L2BasePacket::readUChar()", 1, (int)read_ptr, (int)real_size );
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
unsigned char ret = b.getByteAt( read_ptr );
|
||||
read_ptr++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool L2BasePacket::readBytes( unsigned char *bytes, unsigned int num )
|
||||
{
|
||||
if( !bytes || (num<1) ) return false;
|
||||
unsigned int i;
|
||||
for( i=0; i<num; i++ ) bytes[i] = this->readUChar();
|
||||
return true;
|
||||
}
|
||||
|
||||
short int L2BasePacket::readShort()
|
||||
{
|
||||
if( canReadBytes( 2 ) )
|
||||
{
|
||||
unsigned char c1 = readChar();
|
||||
unsigned char c2 = readChar();
|
||||
unsigned short int ret = ((unsigned short int)c1) | ((unsigned short int)c2 << 8);
|
||||
return ret;
|
||||
}
|
||||
#ifdef L2P_THROW
|
||||
throw L2P_ReadException( "L2BasePacket::readShort()", 2, (int)read_ptr, (int)real_size );
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned short int L2BasePacket::readUShort()
|
||||
{
|
||||
if( canReadBytes( 2 ) )
|
||||
{
|
||||
unsigned char c1 = readUChar();
|
||||
unsigned char c2 = readUChar();
|
||||
unsigned short int ret = ((unsigned short int)c1) | ((unsigned short int)c2 << 8);
|
||||
return ret;
|
||||
}
|
||||
#ifdef L2P_THROW
|
||||
throw L2P_ReadException( "L2BasePacket::readUShort()", 2, (int)read_ptr, (int)real_size );
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int L2BasePacket::readInt()
|
||||
{
|
||||
if( canReadBytes( 4 ) )
|
||||
{
|
||||
unsigned char c1 = readChar();
|
||||
unsigned char c2 = readChar();
|
||||
unsigned char c3 = readChar();
|
||||
unsigned char c4 = readChar();
|
||||
unsigned int ret = (unsigned int)c1;
|
||||
ret |= ( (unsigned int)c2 << 8 );
|
||||
ret |= ( (unsigned int)c3 << 16 );
|
||||
ret |= ( (unsigned int)c4 << 24 );
|
||||
return ret;
|
||||
}
|
||||
#ifdef L2P_THROW
|
||||
throw L2P_ReadException( "L2BasePacket::readInt()", 4, (int)read_ptr, (int)real_size );
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int L2BasePacket::readUInt()
|
||||
{
|
||||
if( canReadBytes( 4 ) )
|
||||
{
|
||||
unsigned char c1 = readChar();
|
||||
unsigned char c2 = readChar();
|
||||
unsigned char c3 = readChar();
|
||||
unsigned char c4 = readChar();
|
||||
unsigned int ret = (unsigned int)c1;
|
||||
ret |= ( (unsigned int)c2 << 8 );
|
||||
ret |= ( (unsigned int)c3 << 16 );
|
||||
ret |= ( (unsigned int)c4 << 24 );
|
||||
return ret;
|
||||
}
|
||||
#ifdef L2P_THROW
|
||||
throw L2P_ReadException( "L2BasePacket::readUInt()", 4, (int)read_ptr, (int)real_size );
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
long long int L2BasePacket::readInt64()
|
||||
{
|
||||
long long int ret = 0;
|
||||
if( this->canReadBytes( 8 ) )
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned char c = 0;
|
||||
unsigned char *retaddr = (unsigned char *)&ret;
|
||||
for( i=0; i<sizeof(long long int); i++ )
|
||||
{
|
||||
c = readChar();
|
||||
(*retaddr) = c;
|
||||
retaddr++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#ifdef L2P_THROW
|
||||
throw L2P_ReadException( "L2BasePacket::readInt64()", 8, (int)read_ptr, (int)real_size );
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned long long int L2BasePacket::readUInt64()
|
||||
{
|
||||
unsigned long long int ret = 0;
|
||||
if( this->canReadBytes( 8 ) )
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned char c = 0;
|
||||
unsigned char *retaddr = (unsigned char *)&ret;
|
||||
for( i=0; i<sizeof(unsigned long long int); i++ )
|
||||
{
|
||||
c = readUChar();
|
||||
(*retaddr) = c;
|
||||
retaddr++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#ifdef L2P_THROW
|
||||
throw L2P_ReadException( "L2BasePacket::readUInt64()", 8, (int)read_ptr, (int)real_size );
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
double L2BasePacket::readDouble()
|
||||
{
|
||||
double ret = 0.0;
|
||||
if( canReadBytes( 8 ) )
|
||||
{
|
||||
unsigned int i = 0;
|
||||
unsigned char c = 0;
|
||||
unsigned char *retaddr = (unsigned char *)&ret;
|
||||
for( i=0; i<sizeof(double); i++ )
|
||||
{
|
||||
c = readChar();
|
||||
(*retaddr) = c;
|
||||
retaddr++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#ifdef L2P_THROW
|
||||
throw L2P_ReadException( "L2BasePacket::readDouble()", 8, (int)read_ptr, (int)real_size );
|
||||
#else
|
||||
return 0.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
char *L2BasePacket::readString()
|
||||
{
|
||||
unsigned int save_read_ptr = this->read_ptr;
|
||||
unsigned int str_len = 0;
|
||||
char c = 0;
|
||||
char *str = NULL;
|
||||
// count string length (including terminating 0x00 byte)
|
||||
while( this->canReadBytes(1) )
|
||||
{
|
||||
c = this->readChar();
|
||||
str_len++;
|
||||
if( c == 0 ) break;
|
||||
}
|
||||
// restore read_ptr
|
||||
this->read_ptr = save_read_ptr;
|
||||
// assert
|
||||
if( str_len == 0 ) return NULL;
|
||||
// allocate buffer
|
||||
str = (char *)malloc( str_len+1 ); // +1 for additional safety
|
||||
if( !str ) return NULL;
|
||||
str[str_len] = 0x00;
|
||||
// read bytes to buffer
|
||||
if( this->readBytes( (unsigned char *)str, str_len ) ) return str;
|
||||
// some error? O_o
|
||||
free( str );
|
||||
str = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// returns allocated by malloc() buffer. must be freed later by caller!
|
||||
wchar_t *L2BasePacket::readUnicodeString()
|
||||
{
|
||||
unsigned int save_read_ptr = this->read_ptr;
|
||||
unsigned int str_len = 0;
|
||||
unsigned int buffer_len = 0;
|
||||
unsigned short int c = 0;
|
||||
wchar_t *wstr = NULL;
|
||||
// count string length (including terminating 0x0000 word)
|
||||
while( this->canReadBytes(2) )
|
||||
{
|
||||
c = this->readUShort();
|
||||
str_len++;
|
||||
buffer_len += 2;
|
||||
if( c == 0x0000 ) break;
|
||||
}
|
||||
// restore read_ptr
|
||||
this->read_ptr = save_read_ptr;
|
||||
// assert
|
||||
if( str_len == 0 ) return NULL;
|
||||
// allocate buffer
|
||||
wstr = (wchar_t *)malloc( buffer_len+2 ); // +2 for more safety
|
||||
if( !wstr ) return NULL;
|
||||
wstr[str_len] = 0x0000;
|
||||
// read bytes to buffer
|
||||
if( this->readBytes( (unsigned char *)wstr, buffer_len ) ) return wstr;
|
||||
// some error? O_o
|
||||
free( wstr );
|
||||
wstr = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// returns read-only pointer to wchar_t inside packet.
|
||||
const wchar_t *L2BasePacket::readUnicodeStringPtr()
|
||||
{
|
||||
//unsigned int str_len = 0;
|
||||
unsigned short int ch = 0;
|
||||
// we return poiter to internal buffer
|
||||
wchar_t *wstr = (wchar_t *)( this->getBytesPtr() + this->read_ptr );
|
||||
// count string length (including terminating 0x0000 word), also moving current read_ptr
|
||||
while( this->canReadBytes(2) )
|
||||
{
|
||||
ch = this->readUShort();
|
||||
//str_len++;
|
||||
//buffer_len += 2;
|
||||
if( ch == 0x0000 ) break;
|
||||
}
|
||||
//wstr += str_len; // add counted string length to returned ptr
|
||||
return wstr;
|
||||
}
|
||||
|
||||
|
||||
void L2BasePacket::writeReset()
|
||||
{
|
||||
write_ptr = 2; // pass 1st 2 bytes - packet size
|
||||
real_size = 2; // think that only 2 bytes written
|
||||
read_ptr = 2; // cannot read more than written :)
|
||||
datasize = 0;
|
||||
_preAllocateBuffer();
|
||||
// update packet size field
|
||||
b.setByteAt( 0, 2 );
|
||||
b.setByteAt( 1, 0 );
|
||||
}
|
||||
|
||||
void L2BasePacket::readReset()
|
||||
{
|
||||
read_ptr = 2; // pass 1st 2 bytes - packet size
|
||||
}
|
||||
|
||||
bool L2BasePacket::_preAllocateBuffer()
|
||||
{
|
||||
if( !b.setSize( buffer_size ) ) return false; // TODO: or throw exception?
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2BasePacket::_growBuffer()
|
||||
{
|
||||
buffer_size *= 2;
|
||||
return _preAllocateBuffer();
|
||||
}
|
||||
|
||||
void L2BasePacket::_initNull()
|
||||
{
|
||||
buffer_size = 256;
|
||||
datasize = 0;
|
||||
writeReset();
|
||||
readReset();
|
||||
}
|
||||
|
||||
void L2BasePacket::_freeSelf()
|
||||
{
|
||||
buffer_size = 256;
|
||||
writeReset();
|
||||
readReset();
|
||||
}
|
||||
|
||||
void L2BasePacket::dumpToFile( FILE *f )
|
||||
{
|
||||
if( !f ) return;
|
||||
fprintf( f, "L2BasePacket::dumpToFile() begin\n" );
|
||||
fprintf( f, "-- read_ptr : %u\n", this->read_ptr );
|
||||
fprintf( f, "-- write_ptr : %u\n", this->write_ptr );
|
||||
fprintf( f, "-- buffer_size : %u\n", this->buffer_size );
|
||||
fprintf( f, "-- real_size : %u\n", this->real_size );
|
||||
unsigned int psize = (unsigned int)(this->b[0]) |
|
||||
( ((unsigned int)this->b[1]) << 8 );
|
||||
fprintf( f, "-- Packet size : %u (%02X %02X)\n", psize, this->b[0], this->b[1] );
|
||||
if( this->real_size > 2 )
|
||||
{
|
||||
fprintf( f, "-- Packet type : %u (%02X)\n", this->b.getByteAt( 2 ), this->b[2] );
|
||||
fprintf( f, "-- ByteArray b :\n" );
|
||||
unsigned int i = 0;
|
||||
for( i=0; i<this->real_size; i++ )
|
||||
fprintf( f, "%02X ", this->b[i] );
|
||||
fprintf( f, "\n" );
|
||||
}
|
||||
fprintf( f, "L2BasePacket::dumpToFile() end\n\n" );
|
||||
}
|
||||
|
||||
void L2BasePacket::saveToFileRaw( const char *filename )
|
||||
{
|
||||
if( !filename ) return;
|
||||
FILE *f = fopen( filename, "wb" );
|
||||
if( !f ) return;
|
||||
fprintf( f, "L2BasePacket::dumpToFile() begin\r\n" );
|
||||
fprintf( f, "-- read_ptr : %u\r\n", this->read_ptr );
|
||||
fprintf( f, "-- write_ptr : %u\r\n", this->write_ptr );
|
||||
fprintf( f, "-- buffer_size : %u\r\n", this->buffer_size );
|
||||
fprintf( f, "-- real_size : %u\r\n", this->real_size );
|
||||
unsigned int psize = this->b[0] + (this->b[1] << 8);
|
||||
fprintf( f, "-- Packet size : %u (%02X %02X)\r\n", psize, this->b[0], this->b[1] );
|
||||
if( this->real_size > 2 )
|
||||
{
|
||||
unsigned char *bytes = b.getBytesPtr();
|
||||
unsigned int count = b.getSize();
|
||||
fwrite( bytes, 1, count, f );
|
||||
}
|
||||
fprintf( f, "L2BasePacket::dumpToFile() end\n\n" );
|
||||
fclose( f );
|
||||
}
|
||||
|
||||
void L2BasePacket::displaySelfNice( FILE *f )
|
||||
{
|
||||
this->dumpToFile( f );
|
||||
}
|
||||
|
||||
unsigned char L2BasePacket::getByteAt( unsigned int index )
|
||||
{
|
||||
if( index >= real_size )
|
||||
#ifdef L2P_THROW
|
||||
throw L2P_ReadException( "L2BasePacket::getByteAt()", 1, (int)index, (int)real_size );
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
char c = b.getByteAt( index );
|
||||
return c;
|
||||
}
|
||||
unsigned char L2BasePacket::setByteAt( unsigned int index, unsigned char byte )
|
||||
{
|
||||
// checks are inside of ByteArray::setByteAt() (throwing exceptions if enabled)
|
||||
return b.setByteAt( index, byte );
|
||||
}
|
||||
|
||||
inline const unsigned char *L2BasePacket::getBytesPtr() const
|
||||
{
|
||||
return b.getBytesPtr();
|
||||
}
|
||||
|
||||
/*L2BasePacket::operator const unsigned char *() const
|
||||
{
|
||||
return this->getBytesPtr();
|
||||
}*/
|
||||
|
||||
ByteArray *L2BasePacket::readB( unsigned int count )
|
||||
{
|
||||
ByteArray *pByteArray = new ByteArray();
|
||||
if( !pByteArray ) return NULL;
|
||||
pByteArray->setSize( count );
|
||||
if( this->readBytes( pByteArray->getBytesPtr(), count ) ) return pByteArray;
|
||||
delete pByteArray;
|
||||
#ifdef L2P_THROW
|
||||
throw L2P_ReadException( "L2BasePacket::readB()", (int)count, (int)read_ptr, (int)real_size );
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
// must be overrided in child classes
|
||||
bool L2BasePacket::parse( L2_VERSION ver )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
this->readReset();
|
||||
this->readUChar();
|
||||
return true;
|
||||
}
|
||||
|
||||
// must be overrided in child classes
|
||||
bool L2BasePacket::create( L2_VERSION ver )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
this->writeReset();
|
||||
return true;
|
||||
}
|
284
l2packets/base/L2BasePacket.h
Normal file
284
l2packets/base/L2BasePacket.h
Normal file
@@ -0,0 +1,284 @@
|
||||
#ifndef H_L2BASEPACKET
|
||||
#define H_L2BASEPACKET
|
||||
|
||||
#include "ByteArray.h"
|
||||
#include "../L2_versions.h"
|
||||
|
||||
#ifndef UNREFERENCED_PARAMETER
|
||||
#define UNREFERENCED_PARAMETER(x) // will produce compiler warnings, anyway
|
||||
#endif
|
||||
|
||||
/** \class L2BasePacket
|
||||
* Represents base class for all L2 packets. Provides way to create packets,
|
||||
* write data to packets, read data from them.\n
|
||||
* Internally uses ByteArray object to hold raw packet data bytes.
|
||||
* Allows writing data/reading data from packet, using readXXXX or writeXXXX functions.\n
|
||||
* \n
|
||||
* In Lineage protocol, all packets start with 2 bytes, which hold all packet length (including these first 2 bytes).
|
||||
* These 2 bytes are never encrypted, so client application receives first 2 bytes,
|
||||
* treates them as packet length and then reads the rest length-2 bytes.\n
|
||||
* \n
|
||||
* L2BasePacket internally uses ByteArray object to hold packet data. Initially created L2BasePacket object
|
||||
* has preallocated space for 256 bytes in its internal storage (ByteArray::setSize(256)), so most write
|
||||
* operations do not cause packet to grow. If 256 bytes is not enough, L2BasePacket automatically doubles
|
||||
* size of its internal buffer, and so on.\n
|
||||
* \n
|
||||
* \n
|
||||
*<pre>
|
||||
* Lineage II packet structure:\n
|
||||
* Size field packet data
|
||||
* |----------------------|--------------------------|
|
||||
* | low byte | high byte | opcode | ... ... ... ... |
|
||||
* |----------------------|--------------------------|
|
||||
* 0 1 2 3 .......... << byte ordinal numbers
|
||||
* </pre>
|
||||
* \n
|
||||
* Size field is 16-bit integer, defines size of ALL packet, including size field itself. So,
|
||||
* maximum length of L2 packet is 65536 bytes (maximum data size is 65534).
|
||||
*/
|
||||
|
||||
class L2BasePacket
|
||||
{
|
||||
public:
|
||||
/** Default constructor for empty packet. Preallocates buffer size for 256 bytes. */
|
||||
L2BasePacket();
|
||||
/** Copies length bytes to packet */
|
||||
L2BasePacket( const unsigned char *bytes, unsigned int length ); // does memcpy()
|
||||
/** Frees object memory */
|
||||
virtual ~L2BasePacket();
|
||||
|
||||
public:
|
||||
/** Reads byte at index from internal storage. Calls ByteArray::getByteAt()\n
|
||||
* May throw L2P_ReadException in case of range error.
|
||||
\param index - byte index to read
|
||||
\return byte value, or 0 if index is out of range.
|
||||
*/
|
||||
virtual unsigned char getByteAt( unsigned int index );
|
||||
/** Sets byte at specified index to value. Does nothing if index out of bounds. Calls ByteArray::setByteAt()\n
|
||||
* May throw L2P_WriteException in case of range error.
|
||||
* \param index byte index
|
||||
* \param byte byte value to set
|
||||
* \return previous byte value
|
||||
*/
|
||||
virtual unsigned char setByteAt( unsigned int index, unsigned char byte );
|
||||
/** Copies bytes to internal storage buffer. Resizes internal buffer if needed. Calls ByteArray::setBytes()
|
||||
* \param bytes pointer to source data buffer to copy from
|
||||
* \param length source buffer size
|
||||
* \return success state
|
||||
*/
|
||||
virtual bool setBytes( const unsigned char *bytes, unsigned int length );
|
||||
/** Sets internal ByteArray's buffer pointer to [bytes], and length to [length]. Does no memcpy()\n
|
||||
* Do not use this function!
|
||||
* \param bytes pointer to new data buffer
|
||||
* \param length source buffer size
|
||||
* \return success state
|
||||
* \see ByteArray::setBytesFromPtrNoMemcpy() */
|
||||
virtual bool setBytesPtr( unsigned char *bytes, unsigned int length );
|
||||
/** Sets 3rd byte of packet (which holds packet opcode).
|
||||
* Equivalent to call writeReset() and writeUChar() with parameter type.
|
||||
* Moves write pointer to byte #3 (next after opcode)
|
||||
* \param type new packet opcode. */
|
||||
virtual void setPacketType( unsigned char type );
|
||||
/** Sets 3rd,4th,5th bytes of packet (which holds packet opcode and extended opcode).
|
||||
* Equivalent to call writeReset(); writeUChar(); writeUShort() with parameter type.
|
||||
* Moves write pointer!
|
||||
* \param opcode new packet opcode.
|
||||
* \param opcode2 extended opcode. */
|
||||
virtual void setPacketType2( unsigned char opcode, unsigned short opcode2 );
|
||||
/** Sets 3rd,4th,5th,6th,7th bytes of packet (which holds packet opcode, ext opcode, ext opcode 2).
|
||||
* Equivalent to call writeReset(); writeUChar(); writeUShort() writeUShort() with parameter type.
|
||||
* Moves write pointer!
|
||||
* \param opcode new packet opcode.
|
||||
* \param opcode2 extended opcode.
|
||||
* \param opcode3 extended opcode 2.
|
||||
*/
|
||||
virtual void setPacketType3( unsigned char opcode, unsigned short opcode2, unsigned short opcode3 );
|
||||
/** Reads packet opcode. Moves read pointer to byte #3 (next after opcode). Equivalent calls: readReset(); readUChar()
|
||||
* \return read packet opcode. */
|
||||
virtual unsigned char getPacketType() { readReset(); return readUChar(); }
|
||||
/** Gets packet length in bytes (not size of internal data buffer, which is larger)
|
||||
* \return packet lentgh */
|
||||
virtual unsigned short getPacketSize() const { return (unsigned short)(this->real_size); }
|
||||
/** Gets number of data bytes in packet (excluding 1st 2 bytes, which hold all packet size).
|
||||
* Equivalent to getPacketSize()-2.
|
||||
* \return number of <b>data</b> bytes in buffer. */
|
||||
virtual unsigned short getDataSize() const { return (unsigned short)(this->datasize); }
|
||||
|
||||
public: // write funcs
|
||||
// All of read/write funcs can throw subclasses of L2P_Exception in case of read/write errors.
|
||||
/** Checks if it is possible to write nBytes bytes to packet; if no, tries to increase buffer size.
|
||||
* Called automatically from write-functions.
|
||||
* \param nBytes checked size
|
||||
* \return false on memory error */
|
||||
virtual bool ensureCanWriteBytes( unsigned int nBytes );
|
||||
/** Moves write pointer to the beginning of the packet, to byte #2, where starts opcode.
|
||||
* First 2 bytes (byte #0, byte #1 - packet size) are always updated automatically, and
|
||||
* they cannot be accessed by read/write-functions, only by setByteAt() / getByteAt().
|
||||
* Pre-allocates internal buffer, sets packet size to 2. */
|
||||
virtual void writeReset();
|
||||
/** Writes single byte to packet. Moves write pointer one char right
|
||||
* \param c byte to write to packet. */
|
||||
virtual void writeChar( char c );
|
||||
/** Writes single byte to packet. Moves write pointer one char right
|
||||
* \param c byte to write to packet. */
|
||||
virtual void writeUChar( unsigned char c );
|
||||
/** Writes short integer to packet. Moves write pointer two chars right
|
||||
* \param s value to write to packet. */
|
||||
virtual void writeShort( short int s );
|
||||
/** Writes short integer to packet. Moves write pointer two chars right
|
||||
* \param s value to write to packet. */
|
||||
virtual void writeUShort( unsigned short int s );
|
||||
/** Writes 32-bit integer to packet. Moves write pointer 4 chars right
|
||||
* \param i value to write to packet. */
|
||||
virtual void writeInt( int i );
|
||||
/** Writes 32-bit integer to packet. Moves write pointer 4 chars right
|
||||
* \param i value to write to packet. */
|
||||
virtual void writeUInt( unsigned int i );
|
||||
/** Writes 64-bit integer to packet. Moves write pointer 8 chars right
|
||||
* \param i64 value to write to packet. */
|
||||
virtual void writeInt64( long long int i64 );
|
||||
/** Writes 64-bit integer to packet. Moves write pointer 8 chars right
|
||||
* \param i64 value to write to packet. */
|
||||
virtual void writeUInt64( unsigned long long int i64 );
|
||||
/** Writes double value to packet. Moves write pointer 8 chars right
|
||||
* \param d value to write to packet. */
|
||||
virtual void writeDouble( double d );
|
||||
/** Writes ANSI string to packet, also NULL terminator. Moves write pointer right by string length
|
||||
* \param str string to write to packet. */
|
||||
virtual void writeString( const char *str );
|
||||
/** Writes Unicode string to packet, also Unicode NULL terminator. Moves write pointer right by string length*2
|
||||
* \param ustr string to write to packet. */
|
||||
virtual void writeUnicodeString( const wchar_t *ustr );
|
||||
/** Writes bytes array to packet (len bytes). Moves write pointer right by len bytes
|
||||
* \param bytes pointer to data to write to packet.
|
||||
* \param len data length. */
|
||||
virtual void writeBytes( const unsigned char *bytes, unsigned int len );
|
||||
public: // read funcs
|
||||
// All of read/write funcs can throw subclasses of L2P_Exception in case of read/write errors.
|
||||
/** Checks if there are some bytes left to read form current read position in packet.
|
||||
* \param nBytes number of bytes to test to readability.
|
||||
* \return true, if nBytes bytes can be read form current read position; false if there are less than
|
||||
* nBytes left in buffer. */
|
||||
virtual bool canReadBytes( unsigned int nBytes );
|
||||
/** Moves read pointer to byte #2 (opcode will be read next). */
|
||||
virtual void readReset();
|
||||
/** Reads one byte from packet. Moves read pointer to next position
|
||||
* \return byte */
|
||||
virtual char readChar();
|
||||
/** Reads one byte from packet. Moves read pointer to next position
|
||||
* \return byte */
|
||||
virtual unsigned char readUChar();
|
||||
/** Reads 16-bit integer from packet. Moves read pointer to next position
|
||||
* \return short int */
|
||||
virtual short int readShort();
|
||||
/** Reads 16-bit integer from packet. Moves read pointer to next position
|
||||
* \return short int */
|
||||
virtual unsigned short int readUShort();
|
||||
/** Reads 32-bit integer from packet. Moves read pointer to next position
|
||||
* \return int */
|
||||
virtual int readInt();
|
||||
/** Reads 32-bit integer from packet. Moves read pointer to next position
|
||||
* \return int */
|
||||
virtual unsigned int readUInt();
|
||||
/** Reads 64-bit integer from packet. Moves read pointer to next position
|
||||
* \return long long int */
|
||||
virtual long long int readInt64();
|
||||
/** Reads 64-bit integer from packet. Moves read pointer to next position
|
||||
* \return long long int */
|
||||
virtual unsigned long long int readUInt64();
|
||||
/** Reads double value from packet. Moves read pointer to next position
|
||||
* \return double */
|
||||
virtual double readDouble();
|
||||
/** Reads ANSI string from packet. Moves read pointer to next read position
|
||||
* \return pointer to allocated string */
|
||||
virtual char *readString();
|
||||
/** Reads Unicode string from packet. Moves read pointer to next read position. Allocates buffer.
|
||||
* \return pointer to allocated string. Calling function must free() this buffer. */
|
||||
virtual wchar_t *readUnicodeString();
|
||||
/** Reads Unicode string from packet. Moves read pointer to next read position.\n
|
||||
* Function does not allocate buffer,
|
||||
* it just returns casted to (wchar_t *) pointer to internal data buffer as read-only.\n
|
||||
* Warning! Returning pointer will be invalid, because internal data buffer is freed when object is destroyed.\n
|
||||
* Warning! Data is read-only.\n
|
||||
* This function may be faster than readUnicodeString() because it does not do
|
||||
* memory allocation.
|
||||
* \return pointer to allocated string */
|
||||
virtual const wchar_t *readUnicodeStringPtr();
|
||||
/** Reads num bytes from packet
|
||||
* \param bytes pointer to buffer to store data
|
||||
* \param num number of bytes to read
|
||||
* \returns success state */
|
||||
virtual bool readBytes( unsigned char *bytes, unsigned int num );
|
||||
public: // L2J aliases
|
||||
// writers
|
||||
/** Alias to writeChar() */
|
||||
virtual inline void writeC( char c ) { writeChar( c ); }
|
||||
/** Alias to writeShort() */
|
||||
virtual inline void writeH( short h ) { writeShort( h ); }
|
||||
/** Alias to writeInt() */
|
||||
virtual inline void writeD( int d ) { writeInt( d ); }
|
||||
/** Alias to writeInt64() */
|
||||
virtual inline void writeQ( long long int Q ) { writeInt64( Q ); }
|
||||
/** Alias to writeDouble() */
|
||||
virtual inline void writeF( double f ) { writeDouble( f ); }
|
||||
/** Alias to writeUnicodeString() */
|
||||
virtual inline void writeS( const wchar_t *string ) { writeUnicodeString( string ); }
|
||||
/** Alias to writeBytes() */
|
||||
virtual inline void writeB( const ByteArray& bytes ) { writeBytes( bytes.getBytesPtr(), bytes.getSize() ); }
|
||||
// readers
|
||||
/** Alias to readChar() */
|
||||
virtual inline char readC() { return readChar(); }
|
||||
/** Alias to readShort() */
|
||||
virtual inline short readH() { return readShort(); }
|
||||
/** Alias to readInt() */
|
||||
virtual inline int readD() { return readInt(); }
|
||||
/** Alias to readDouble() */
|
||||
virtual inline double readF() { return readDouble(); }
|
||||
/** Alias to readInt64() */
|
||||
virtual inline long long int readQ() { return readInt64(); }
|
||||
/** Alias to readUnicodeString() */
|
||||
virtual inline wchar_t *readS() { return readUnicodeString(); }
|
||||
/** Alias to readBytes() */
|
||||
virtual ByteArray *readB( unsigned int count ); // not inline :)
|
||||
public: // parsers/creators
|
||||
/** Parses packet. Must be overriden in child classes */
|
||||
virtual bool parse( L2_VERSION ver = L2_VERSION_T1 );
|
||||
/** Default method to create packet. Must be overriden in subclasses */
|
||||
virtual bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
|
||||
// DEBUG funcs
|
||||
public:
|
||||
/** Writes packet dump to file f n HEX
|
||||
* \param f - file to write to */
|
||||
virtual void dumpToFile( FILE *f );
|
||||
/** Saves all packet to file as binary data
|
||||
* \param filename - file name to save to */
|
||||
virtual void saveToFileRaw( const char *filename );
|
||||
/** here calls dumpToFile(). Must be overriden in child classes
|
||||
* \param f - file to write to */
|
||||
virtual void displaySelfNice( FILE *f );
|
||||
public: // typeconv
|
||||
//virtual operator const unsigned char *() const;
|
||||
/** Returns pointer to all internal data buffer. Calls ByteArray::getBytesPtr()
|
||||
* \return pointer to all internal data buffer */
|
||||
virtual const unsigned char *getBytesPtr() const;
|
||||
protected:
|
||||
/** Internal function - called from constuctors. Initializes object state:
|
||||
* Sets buffer_size to 256, calls readReset(), writeReset() */
|
||||
virtual void _initNull();
|
||||
/** Internal function. Pre-allocates internal buffer to buffer_size */
|
||||
virtual bool _preAllocateBuffer();
|
||||
/** Internal function. Tries to increase buffer size twice */
|
||||
virtual bool _growBuffer();
|
||||
/** almost the same as _initNull()... */
|
||||
virtual void _freeSelf();
|
||||
protected:
|
||||
unsigned int buffer_size; ///< current buffer size
|
||||
unsigned int real_size; ///< number of used bytes in buffer
|
||||
unsigned int write_ptr; ///< index of next byte that will be written to buffer
|
||||
unsigned int read_ptr; ///< index of next byte that will be read from buffer
|
||||
unsigned int datasize; ///< number of data bytes in packet (excluding first 2 bytes that hold packet size)
|
||||
ByteArray b; ///< internal buffer to hold raw packet data
|
||||
};
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user