Initial MSVC 2008 projects workspace
This commit is contained in:
31
l2packets/AionPackets.h
Normal file
31
l2packets/AionPackets.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef AIONPACKETS_H_
|
||||
#define AIONPACKETS_H_
|
||||
|
||||
/** \file AionPackets.h
|
||||
* Main include file to include all library files related to Aion.
|
||||
*/
|
||||
|
||||
// detect OS
|
||||
#if defined(_WIN32) || defined(WIN32) || defined(WINVER) || defined(_WIN32_WINNT)
|
||||
#undef L2PACKETS_WINDOWS
|
||||
#define L2PACKETS_WINDOWS
|
||||
#else
|
||||
#undef L2PACKETS_LINUX
|
||||
#define L2PACKETS_LINUX
|
||||
#endif
|
||||
|
||||
// base of library
|
||||
#include "L2_versions.h"
|
||||
#include "xcpt/L2Packets_xcpt.h"
|
||||
#include "base/ByteArray.h"
|
||||
#include "base/L2BasePacket.h"
|
||||
|
||||
// network
|
||||
#include "net_io/L2Packet_NetLayer.h"
|
||||
#include "net_io/L2PacketReceiver.h"
|
||||
#include "net_io/L2PacketSender.h"
|
||||
|
||||
//#include "login/AionLoginPacket.h"
|
||||
#include "game/AionGamePacket.h"
|
||||
|
||||
#endif /* AIONPACKETS_H_ */
|
97
l2packets/L2Packets.h
Normal file
97
l2packets/L2Packets.h
Normal file
@@ -0,0 +1,97 @@
|
||||
#ifndef L2PACKETS_H_
|
||||
#define L2PACKETS_H_
|
||||
|
||||
/** \file L2Packets.h
|
||||
* Main include file to include all other library files related to Lineage II.
|
||||
*/
|
||||
|
||||
// detect OS
|
||||
#if defined(_WIN32) || defined(WIN32) || defined(WINVER) || defined(_WIN32_WINNT)
|
||||
#undef L2PACKETS_WINDOWS
|
||||
#define L2PACKETS_WINDOWS
|
||||
#else
|
||||
#undef L2PACKETS_LINUX
|
||||
#define L2PACKETS_LINUX
|
||||
#endif
|
||||
|
||||
/* some #defines come here
|
||||
* they determine some behaviour of L2Packets library
|
||||
*
|
||||
* L2LOGINP_DEBUGOUT_BLOWFISH - if defined, library reports to stdout errors/successes
|
||||
* about Blowfish encoding/decoding process of login server packets
|
||||
* L2LOGINP_DEBUGOUT_XOR - if defined, library reports to stdout errors/successes about
|
||||
* Init packet XOR decoding process
|
||||
* L2LOGINP_DEBUGOUT_CHKSUM - if defined, library reports to stdout about process of
|
||||
* appending checksum to login server packets
|
||||
* L2LOGINP_DEBUGOUT_PADDING - if defined, library reports to stdout about process of
|
||||
* padding login server packets to 8-byte boundary
|
||||
*
|
||||
* L2P_NETWORK_DEBUGOUT - debug messages about sending/receiving packets process
|
||||
*/
|
||||
|
||||
// those should be defined in login/L2LoginPacket.h:
|
||||
//#define L2LOGINP_DEBUGOUT_BLOWFISH
|
||||
//#define L2LOGINP_DEBUGOUT_XOR
|
||||
//#define L2LOGINP_DEBUGOUT_CHKSUM
|
||||
//#define L2LOGINP_DEBUGOUT_PADDING
|
||||
|
||||
// these should be defined in net_io headers (in both)
|
||||
//#define L2P_NETWORK_DEBUGOUT
|
||||
|
||||
#include "L2_versions.h"
|
||||
|
||||
#include "base/ByteArray.h"
|
||||
#include "base/L2BasePacket.h"
|
||||
|
||||
#include "net_io/L2Packet_NetLayer.h"
|
||||
#include "net_io/L2PacketReceiver.h"
|
||||
#include "net_io/L2PacketSender.h"
|
||||
|
||||
#include "login/L2LoginPacket.h"
|
||||
#include "login/server/L2Login_Init.h"
|
||||
#include "login/client/L2Login_RequestGGAuth.h"
|
||||
#include "login/server/L2Login_GGAuthResponse.h"
|
||||
#include "login/client/L2Login_RequestAuthLogin.h"
|
||||
#include "login/server/L2Login_LoginOK.h"
|
||||
#include "login/server/L2Login_LoginFail.h"
|
||||
#include "login/server/L2Login_AccountKicked.h"
|
||||
#include "login/client/L2Login_RequestServerList.h"
|
||||
#include "login/server/L2Login_ServerList.h"
|
||||
#include "login/client/L2Login_RequestServerLogin.h"
|
||||
#include "login/server/L2Login_PlayOK.h"
|
||||
#include "login/server/L2Login_PlayFail.h"
|
||||
|
||||
#include "game/L2GamePacket.h"
|
||||
// game: from server
|
||||
#include "game/server/L2Game_AuthLoginFail.h"
|
||||
#include "game/server/L2Game_CharCreateFail.h"
|
||||
#include "game/server/L2Game_CharCreateSuccess.h"
|
||||
#include "game/server/L2Game_CharDeleteFail.h"
|
||||
#include "game/server/L2Game_CharDeleteSuccess.h"
|
||||
#include "game/server/L2Game_CharSelected.h"
|
||||
#include "game/server/L2Game_CharSelectionInfo.h"
|
||||
#include "game/server/L2Game_KeyPacket.h"
|
||||
#include "game/server/L2Game_NewCharacterSuccess.h"
|
||||
#include "game/server/L2Game_SSQInfo.h"
|
||||
// game: from client
|
||||
#include "game/client/L2Game_Action.h"
|
||||
#include "game/client/L2Game_AuthLogin.h"
|
||||
#include "game/client/L2Game_CharacterCreate.h"
|
||||
#include "game/client/L2Game_CharacterDelete.h"
|
||||
#include "game/client/L2Game_CharacterRestore.h"
|
||||
#include "game/client/L2Game_CharacterSelect.h"
|
||||
#include "game/client/L2Game_EnterWorld.h"
|
||||
#include "game/client/L2Game_NewCharacter.h"
|
||||
#include "game/client/L2Game_ProtocolVersion.h"
|
||||
#include "game/client/L2Game_RequestJoinParty.h"
|
||||
#include "game/client/L2Game_RequestGotoLobby.h"
|
||||
#include "game/client/L2Game_RequestUserCommand.h"
|
||||
#include "game/client/L2Game_UseItem.h"
|
||||
|
||||
#include "pcode_obfuscator/L2PCodeObfuscator.h"
|
||||
#include "l2data/L2Data.h"
|
||||
#include "l2world/L2World.h"
|
||||
#include "packetNames/L2PacketNames.h"
|
||||
#include "xcpt/L2Packets_xcpt.h"
|
||||
|
||||
#endif /*L2PACKETS_H_*/
|
20
l2packets/L2_versions.h
Normal file
20
l2packets/L2_versions.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef H_L2_VERSIONS
|
||||
#define H_L2_VERSIONS
|
||||
|
||||
typedef enum eL2_VERSION
|
||||
{
|
||||
/** constant to set protocol version as Kamael */
|
||||
L2_VERSION_T1 = 0,
|
||||
/** constant to set protocol version as Hellbound */
|
||||
L2_VERSION_T15 = 1,
|
||||
/** constant to set protocol version as Gracia Part 1 */
|
||||
L2_VERSION_T2 = 2,
|
||||
/** constant to set protocol version as Gracia Part 2 */
|
||||
L2_VERSION_T22 = 3,
|
||||
/** constant to set protocol version as Gracia Final */
|
||||
L2_VERSION_T23 = 4,
|
||||
/** constant to set protocol version as Gracia Epilogue */
|
||||
L2_VERSION_T24 = 5
|
||||
} L2_VERSION;
|
||||
|
||||
#endif
|
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
|
181
l2packets/game/AionGamePacket.cpp
Normal file
181
l2packets/game/AionGamePacket.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
#include "stdafx.h"
|
||||
#include "AionGamePacket.h"
|
||||
|
||||
unsigned char *AionGamePacket::STATIC_XOR_KEY = NULL;
|
||||
|
||||
void AionGamePacket::_checkInitStaticXorKey()
|
||||
{
|
||||
if( !AionGamePacket::STATIC_XOR_KEY )
|
||||
AionGamePacket::STATIC_XOR_KEY = (unsigned char *)"nKO/WctQ0AVLbpzfBkS6NevDYT8ourG5CRlmdjyJ72aswx4EPq1UgZhFMXH?3iI9";
|
||||
}
|
||||
|
||||
AionGamePacket::AionGamePacket()
|
||||
{
|
||||
this->_initNull();
|
||||
this->_checkInitStaticXorKey();
|
||||
}
|
||||
|
||||
AionGamePacket::AionGamePacket( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->_checkInitStaticXorKey();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool AionGamePacket::decodeXOR( unsigned char *key )
|
||||
{
|
||||
if( !key ) return false;
|
||||
bool r = AionGamePacket::decodeXOR_buffer( b.getBytesPtr(), getPacketSize(), key );
|
||||
return r;
|
||||
}
|
||||
|
||||
bool AionGamePacket::encodeXOR( unsigned char *key )
|
||||
{
|
||||
if( !key ) return false;
|
||||
bool r = AionGamePacket::encodeXOR_buffer( b.getBytesPtr(), getPacketSize(), key );
|
||||
return r;
|
||||
}
|
||||
|
||||
bool AionGamePacket::decodeXOR_buffer( unsigned char *decodeBytes, unsigned int bytesLen, unsigned char *key )
|
||||
{
|
||||
if( !key ) return false;
|
||||
const int data_offset = 2; // do not touch 1st 2 bytes - with packet length; pass them
|
||||
unsigned int i = 0;
|
||||
unsigned char cur = 0; // current byte
|
||||
unsigned char prev = decodeBytes[data_offset]; // prev. encrypted byte
|
||||
decodeBytes[data_offset] ^= key[0]; // decrypt 1st byte
|
||||
// decrypt loop
|
||||
for( i=(data_offset + 1); i<bytesLen; i++ )
|
||||
{
|
||||
cur = decodeBytes[i];
|
||||
decodeBytes[i] ^= AionGamePacket::STATIC_XOR_KEY[(i-data_offset) & 63] ^ key[(i-data_offset) & 7] ^ prev;
|
||||
prev = cur;
|
||||
}
|
||||
// old key value as 64-bit unsigned int
|
||||
unsigned long long oldKey = (unsigned long long)key[0] | ((unsigned long long)key[1] << 8) |
|
||||
((unsigned long long)key[2] << 16) | ((unsigned long long)key[3] << 24) |
|
||||
((unsigned long long)key[4] << 32) | ((unsigned long long)key[5] << 40) |
|
||||
((unsigned long long)key[6] << 48) | ((unsigned long long)key[7] << 56);
|
||||
// packet size is added to old key value
|
||||
oldKey += (bytesLen - 2); // data size = whole packet length - 2
|
||||
// update key
|
||||
key[0] = (unsigned char)(oldKey & 0xFF);
|
||||
key[1] = (unsigned char)((oldKey >> 8) & 0xFF);
|
||||
key[2] = (unsigned char)((oldKey >> 16) & 0xFF);
|
||||
key[3] = (unsigned char)((oldKey >> 24) & 0xFF);
|
||||
key[4] = (unsigned char)((oldKey >> 32) & 0xFF);
|
||||
key[5] = (unsigned char)((oldKey >> 40) & 0xFF);
|
||||
key[6] = (unsigned char)((oldKey >> 48) & 0xFF);
|
||||
key[7] = (unsigned char)((oldKey >> 56) & 0xFF);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AionGamePacket::encodeXOR_buffer( unsigned char *encodeBytes, unsigned int bytesLen, unsigned char *key )
|
||||
{
|
||||
if( !key ) return false;
|
||||
unsigned int i = 0;
|
||||
unsigned char prev = 0; // prev. encoded byte
|
||||
const int data_offset = 2; // do not touch 1st 2 bytes - with packet length; pass them
|
||||
// encrypt 1st byte
|
||||
encodeBytes[data_offset] ^= key[0];
|
||||
prev = encodeBytes[data_offset];
|
||||
// encrypt loop
|
||||
for( i=(data_offset+1); i<bytesLen; i++ )
|
||||
{
|
||||
encodeBytes[i] ^= AionGamePacket::STATIC_XOR_KEY[(i-data_offset) & 63] ^ key[(i-data_offset) & 7] ^ prev;
|
||||
prev = encodeBytes[i];
|
||||
}
|
||||
// old key value as 64-bit unsigned int
|
||||
unsigned long long oldKey = (unsigned long long)key[0] | ((unsigned long long)key[1] << 8) |
|
||||
((unsigned long long)key[2] << 16) | ((unsigned long long)key[3] << 24) |
|
||||
((unsigned long long)key[4] << 32) | ((unsigned long long)key[5] << 40) |
|
||||
((unsigned long long)key[6] << 48) | ((unsigned long long)key[7] << 56);
|
||||
// packet size is added to old key value
|
||||
oldKey += (bytesLen - 2); // data size = whole packet length - 2
|
||||
// update key
|
||||
key[0] = (unsigned char)(oldKey & 0xFF);
|
||||
key[1] = (unsigned char)((oldKey >> 8) & 0xFF);
|
||||
key[2] = (unsigned char)((oldKey >> 16) & 0xFF);
|
||||
key[3] = (unsigned char)((oldKey >> 24) & 0xFF);
|
||||
key[4] = (unsigned char)((oldKey >> 32) & 0xFF);
|
||||
key[5] = (unsigned char)((oldKey >> 40) & 0xFF);
|
||||
key[6] = (unsigned char)((oldKey >> 48) & 0xFF);
|
||||
key[7] = (unsigned char)((oldKey >> 56) & 0xFF);
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned char AionGamePacket::obfuscateServerOpcode( unsigned char opcode )
|
||||
{
|
||||
return ((opcode + 0xAE) ^ 0xEE);
|
||||
}
|
||||
|
||||
unsigned char AionGamePacket::deobfuscateServerOpcode( unsigned char opcode )
|
||||
{
|
||||
return ((opcode ^ 0xEE) - 0xAE);
|
||||
}
|
||||
|
||||
bool AionGamePacket::writeServerOpcode( unsigned char opcode )
|
||||
{
|
||||
writeReset();
|
||||
unsigned char scrambled_opcode = obfuscateServerOpcode( opcode );
|
||||
writeUChar( scrambled_opcode );
|
||||
writeUChar( AionGamePacket::STATIC_SERVER_OPCODE );
|
||||
writeUChar( ~scrambled_opcode );
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: verify this
|
||||
bool AionGamePacket::writeClientOpcode( unsigned char opcode )
|
||||
{
|
||||
writeReset();
|
||||
unsigned char scrambled_opcode = obfuscateServerOpcode( opcode ); // REALLYY??????????
|
||||
writeUChar( scrambled_opcode ); // ARE YOU SURE??
|
||||
writeUChar( AionGamePacket::STATIC_CLIENT_OPCODE );
|
||||
writeUChar( ~scrambled_opcode );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AionGamePacket::validateClientOpcode() const
|
||||
{
|
||||
if( getDataSize() >= 3 )
|
||||
{
|
||||
unsigned char o1 = b[2];
|
||||
unsigned char o2 = b[3];
|
||||
unsigned char o3 = b[4];
|
||||
if( (o1 == (unsigned char)(~o3)) && (o2 == AionGamePacket::STATIC_CLIENT_OPCODE) ) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AionGamePacket::validateServerOpcode() const
|
||||
{
|
||||
if( getDataSize() >= 3 )
|
||||
{
|
||||
unsigned char o1 = b[2];
|
||||
unsigned char o2 = b[3];
|
||||
unsigned char o3 = b[4];
|
||||
if( (o1 == (unsigned char)(~o3)) && (o2 == AionGamePacket::STATIC_SERVER_OPCODE) ) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AionGamePacket::initStaticXORKey( unsigned char *key )
|
||||
{
|
||||
key[4] = 0xA1;
|
||||
key[5] = 0x6C;
|
||||
key[6] = 0x54;
|
||||
key[7] = 0x87;
|
||||
}
|
||||
|
||||
unsigned char AionGamePacket::readOpcode()
|
||||
{
|
||||
unsigned char opcode = 0;
|
||||
readReset();
|
||||
if( canReadBytes( 3 ) )
|
||||
{
|
||||
opcode = readUChar();
|
||||
readUChar(); // static opcode
|
||||
readUChar(); // ~opcode
|
||||
}
|
||||
return opcode;
|
||||
}
|
58
l2packets/game/AionGamePacket.h
Normal file
58
l2packets/game/AionGamePacket.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#ifndef AIONGAMEPACKET_H_
|
||||
#define AIONGAMEPACKET_H_
|
||||
|
||||
#include "../base/L2BasePacket.h"
|
||||
|
||||
class AionGamePacket : public L2BasePacket
|
||||
{
|
||||
public:
|
||||
static const unsigned char STATIC_SERVER_OPCODE = 0x54;
|
||||
static const unsigned char STATIC_CLIENT_OPCODE = 0x5D;
|
||||
static unsigned char *STATIC_XOR_KEY;
|
||||
//(const unsigned char *)"nKO/WctQ0AVLbpzfBkS6NevDYT8ourG5CRlmdjyJ72aswx4EPq1UgZhFMXH?3iI9";
|
||||
|
||||
public:
|
||||
AionGamePacket();
|
||||
AionGamePacket( const unsigned char *bytes, unsigned int length );
|
||||
|
||||
public:
|
||||
/* Decodes this packet data with Aion XORgame encryption. key is updated at every dec/enc call
|
||||
* \param key - 8-byte lenght key buffer */
|
||||
bool decodeXOR( unsigned char *key );
|
||||
|
||||
/* Encodes this packet data with Aion XORgame encryption. key is updated at every dec/enc call
|
||||
* \param key - 8-byte lenght key buffer */
|
||||
bool encodeXOR( unsigned char *key );
|
||||
|
||||
/* Decodes buffer contents with Aion XOR game encryption. key is updated at every dec/enc call
|
||||
* \param decodeBytes pointer to data to be decrypted
|
||||
* \param bytesLen data length in bytes
|
||||
* \param key - 8-byte lenght key buffer */
|
||||
static bool decodeXOR_buffer( unsigned char *decodeBytes, unsigned int bytesLen, unsigned char *key );
|
||||
|
||||
/* Encodes buffer contents with Aion XOR game encryption. key is updated at every dec/enc call
|
||||
* \param decodeBytes pointer to data to be decrypted
|
||||
* \param bytesLen data length in bytes
|
||||
* \param key - 8-byte lenght key buffer */
|
||||
static bool encodeXOR_buffer( unsigned char *encodeBytes, unsigned int bytesLen, unsigned char *key );
|
||||
|
||||
public:
|
||||
static unsigned char obfuscateServerOpcode( unsigned char opcode );
|
||||
static unsigned char deobfuscateServerOpcode( unsigned char opcode );
|
||||
bool writeServerOpcode( unsigned char opcode );
|
||||
bool writeClientOpcode( unsigned char opcode );
|
||||
bool validateServerOpcode() const;
|
||||
bool validateClientOpcode() const;
|
||||
unsigned char readOpcode();
|
||||
|
||||
public:
|
||||
/** Creates initial XOR key - sets last 4 bytes of key. First 4 bytes are dynamic, last 4 bytes are const.\n
|
||||
* key must point to 8-byte buffer.
|
||||
* \param key 8-byte buffer; function updates last 4 of them. */
|
||||
static void initStaticXORKey( unsigned char *key );
|
||||
|
||||
protected:
|
||||
void _checkInitStaticXorKey();
|
||||
};
|
||||
|
||||
#endif /* AIONGAMEPACKET_H_ */
|
153
l2packets/game/L2GamePacket.cpp
Normal file
153
l2packets/game/L2GamePacket.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2GamePacket.h"
|
||||
|
||||
L2GamePacket::L2GamePacket()
|
||||
{
|
||||
this->_initNull();
|
||||
}
|
||||
|
||||
L2GamePacket::L2GamePacket( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
// in Hellbound key must be 16-byte array
|
||||
// key is changed after enc/dec procedure
|
||||
bool L2GamePacket::decodeXOR( unsigned char *key )
|
||||
{
|
||||
if( !key ) return false;
|
||||
unsigned int sz = this->getPacketSize();
|
||||
unsigned int dsz = this->getDataSize();
|
||||
if( sz < 3 ) return false;
|
||||
unsigned char temp = 0, temp2 = 0;
|
||||
unsigned int i = 0;
|
||||
unsigned char *data = (unsigned char *)this->getBytesPtr();
|
||||
// xor enc/dec from index 2 (pass 2 bytes - packet size)
|
||||
data += 2;
|
||||
for( i = 0; i < dsz; i++ )
|
||||
{
|
||||
temp2 = data[i];
|
||||
data[i] = (temp2 ^ (key[i & 15]) ^ temp);
|
||||
temp = temp2;
|
||||
}
|
||||
|
||||
unsigned int old = 0;
|
||||
old |= key[8] & 0x000000ff;
|
||||
old |= (key[9] << 0x08) & 0x0000ff00;
|
||||
old |= (key[10] << 0x10) & 0x00ff0000;
|
||||
old |= (key[11] << 0x18) & 0xff000000;
|
||||
|
||||
//old += sz;
|
||||
old += dsz; // key increases by data size
|
||||
|
||||
key[8] = (unsigned char)((old) & 0xff);
|
||||
key[9] = (unsigned char)((old >> 0x08) & 0xff);
|
||||
key[10] = (unsigned char)((old >> 0x10) & 0xff);
|
||||
key[11] = (unsigned char)((old >> 0x18) & 0xff);
|
||||
return true;
|
||||
}
|
||||
|
||||
// in Hellbound key must be 16-byte array
|
||||
// key is changed after enc/dec procedure
|
||||
bool L2GamePacket::encodeXOR( unsigned char *key )
|
||||
{
|
||||
if( !key ) return false;
|
||||
unsigned int sz = this->getPacketSize();
|
||||
unsigned int dsz = this->getDataSize();
|
||||
if( sz < 3 ) return false;
|
||||
unsigned char temp = 0, temp2 = 0;
|
||||
unsigned int i = 0;
|
||||
unsigned char *data = (unsigned char *)this->getBytesPtr();
|
||||
// xor enc/dec from index 2 (pass 2 bytes - packet size)
|
||||
data += 2;
|
||||
for( i = 0; i < dsz; i++ )
|
||||
{
|
||||
temp2 = data[i];
|
||||
data[i] = (temp2 ^ (key[i & 15]) ^ temp );
|
||||
temp = data[i];
|
||||
}
|
||||
|
||||
unsigned int old = 0;
|
||||
old |= key[8] & 0x000000ff;
|
||||
old |= (key[9] << 0x08) & 0x0000ff00;
|
||||
old |= (key[10] << 0x10) & 0x00ff0000;
|
||||
old |= (key[11] << 0x18) & 0xff000000;
|
||||
|
||||
//old += sz;
|
||||
old += dsz; // key increases by data size
|
||||
|
||||
key[8] = (unsigned char)((old) & 0xff);
|
||||
key[9] = (unsigned char)((old >> 0x08) & 0xff);
|
||||
key[10] = (unsigned char)((old >> 0x10) & 0xff);
|
||||
key[11] = (unsigned char)((old >> 0x18) & 0xff);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2GamePacket::decodeXOR_buffer( unsigned char *decodeBytes, unsigned int bytesLen,
|
||||
unsigned char *key )
|
||||
{
|
||||
//if( !key ) return false;
|
||||
unsigned int dsz = bytesLen - 2;
|
||||
//if( sz < 3 ) return false;
|
||||
unsigned char temp = 0, temp2 = 0;
|
||||
unsigned int i = 0;
|
||||
unsigned char *data = decodeBytes;
|
||||
// xor enc/dec from index 2 (pass 2 bytes - packet size)
|
||||
data += 2;
|
||||
for( i = 0; i < dsz; i++ )
|
||||
{
|
||||
temp2 = data[i];
|
||||
data[i] = (temp2 ^ (key[i & 15]) ^ temp);
|
||||
temp = temp2;
|
||||
}
|
||||
|
||||
unsigned int old = 0;
|
||||
old |= key[8] & 0x000000ff;
|
||||
old |= (key[9] << 0x08) & 0x0000ff00;
|
||||
old |= (key[10] << 0x10) & 0x00ff0000;
|
||||
old |= (key[11] << 0x18) & 0xff000000;
|
||||
|
||||
//old += sz;
|
||||
old += dsz; // key increases by data size
|
||||
|
||||
key[8] = (unsigned char)((old) & 0xff);
|
||||
key[9] = (unsigned char)((old >> 0x08) & 0xff);
|
||||
key[10] = (unsigned char)((old >> 0x10) & 0xff);
|
||||
key[11] = (unsigned char)((old >> 0x18) & 0xff);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2GamePacket::encodeXOR_buffer( unsigned char *encodeBytes, unsigned int bytesLen,
|
||||
unsigned char *key )
|
||||
{
|
||||
//if( !key ) return false;
|
||||
unsigned int dsz = bytesLen - 2;
|
||||
//if( sz < 3 ) return false;
|
||||
unsigned char temp = 0, temp2 = 0;
|
||||
unsigned int i = 0;
|
||||
unsigned char *data = encodeBytes;
|
||||
// xor enc/dec from index 2 (pass 2 bytes - packet size)
|
||||
data += 2;
|
||||
for( i = 0; i < dsz; i++ )
|
||||
{
|
||||
temp2 = data[i];
|
||||
data[i] = (temp2 ^ (key[i & 15]) ^ temp );
|
||||
temp = data[i];
|
||||
}
|
||||
|
||||
unsigned int old = 0;
|
||||
old |= key[8] & 0x000000ff;
|
||||
old |= (key[9] << 0x08) & 0x0000ff00;
|
||||
old |= (key[10] << 0x10) & 0x00ff0000;
|
||||
old |= (key[11] << 0x18) & 0xff000000;
|
||||
|
||||
//old += sz;
|
||||
old += dsz; // key increases by data size
|
||||
|
||||
key[8] = (unsigned char)((old) & 0xff);
|
||||
key[9] = (unsigned char)((old >> 0x08) & 0xff);
|
||||
key[10] = (unsigned char)((old >> 0x10) & 0xff);
|
||||
key[11] = (unsigned char)((old >> 0x18) & 0xff);
|
||||
return true;
|
||||
}
|
24
l2packets/game/L2GamePacket.h
Normal file
24
l2packets/game/L2GamePacket.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef L2GAMEPACKET_H_
|
||||
#define L2GAMEPACKET_H_
|
||||
|
||||
#include "../base/L2BasePacket.h"
|
||||
|
||||
class L2GamePacket : public L2BasePacket
|
||||
{
|
||||
public:
|
||||
L2GamePacket();
|
||||
L2GamePacket( const unsigned char *bytes, unsigned int length );
|
||||
//virtual ~L2GamePacket();
|
||||
public:
|
||||
// in Hellbound key must be 16-byte array
|
||||
// key is changed after enc/dec procedure
|
||||
bool decodeXOR( unsigned char *key );
|
||||
// in Hellbound key must be 16-byte array
|
||||
// key is changed after enc/dec procedure
|
||||
bool encodeXOR( unsigned char *key );
|
||||
public:
|
||||
static bool decodeXOR_buffer( unsigned char *decodeBytes, unsigned int bytesLen, unsigned char *key );
|
||||
static bool encodeXOR_buffer( unsigned char *encodeBytes, unsigned int bytesLen, unsigned char *key );
|
||||
};
|
||||
|
||||
#endif /*L2GAMEPACKET_H_*/
|
63
l2packets/game/client/L2Game_Action.cpp
Normal file
63
l2packets/game/client/L2Game_Action.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_Action.h"
|
||||
|
||||
/* L2J:
|
||||
private int _objectId;
|
||||
@SuppressWarnings("unused")
|
||||
private int _originX;
|
||||
@SuppressWarnings("unused")
|
||||
private int _originY;
|
||||
@SuppressWarnings("unused")
|
||||
private int _originZ;
|
||||
private int _actionId;
|
||||
|
||||
@Override
|
||||
protected void readImpl()
|
||||
{
|
||||
_objectId = readD(); // Target object Identifier
|
||||
_originX = readD();
|
||||
_originY = readD();
|
||||
_originZ = readD();
|
||||
_actionId = readC(); // Action identifier : 0-Simple click, 1-Shift click
|
||||
}
|
||||
*/
|
||||
|
||||
L2Game_Action::L2Game_Action()
|
||||
{
|
||||
this->_initNull();
|
||||
}
|
||||
|
||||
L2Game_Action::L2Game_Action( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Game_Action::create( unsigned int objectID,
|
||||
unsigned int originX,
|
||||
unsigned int originY,
|
||||
unsigned int originZ,
|
||||
unsigned char bUseShift )
|
||||
{
|
||||
this->writeReset();
|
||||
this->writeUChar( 0x1f ); // packet type - Action
|
||||
this->writeUInt( objectID );
|
||||
this->writeUInt( originX );
|
||||
this->writeUInt( originY );
|
||||
this->writeUInt( originZ );
|
||||
this->writeUChar( bUseShift );
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int L2Game_Action::read_objectID()
|
||||
{
|
||||
if( !(this->canReadBytes(5)) ) return 0;
|
||||
this->readReset();
|
||||
this->readUChar(); // pcode
|
||||
return this->readUInt();
|
||||
}
|
||||
|
||||
int L2Game_Action::read_originX() { return this->readInt(); }
|
||||
int L2Game_Action::read_originY() { return this->readInt(); }
|
||||
int L2Game_Action::read_originZ() { return this->readInt(); }
|
||||
char L2Game_Action::read_useShift() { return this->readChar(); }
|
24
l2packets/game/client/L2Game_Action.h
Normal file
24
l2packets/game/client/L2Game_Action.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef L2GAME_ACTION_H_
|
||||
#define L2GAME_ACTION_H_
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
class L2Game_Action : public L2GamePacket
|
||||
{
|
||||
public:
|
||||
L2Game_Action();
|
||||
L2Game_Action( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
bool create( unsigned int objectID,
|
||||
unsigned int originX,
|
||||
unsigned int originY,
|
||||
unsigned int originZ,
|
||||
unsigned char bUseShift );
|
||||
unsigned int read_objectID();
|
||||
int read_originX();
|
||||
int read_originY();
|
||||
int read_originZ();
|
||||
char read_useShift();
|
||||
};
|
||||
|
||||
#endif /*L2GAME_CHARACTERSELECT_H_*/
|
96
l2packets/game/client/L2Game_AuthLogin.cpp
Normal file
96
l2packets/game/client/L2Game_AuthLogin.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_AuthLogin.h"
|
||||
|
||||
/* interlude pcode is 08
|
||||
hellbound pcode is 2b
|
||||
L2J:
|
||||
protected void readImpl()
|
||||
{
|
||||
_loginName = readS().toLowerCase();
|
||||
_playKey2 = readD();
|
||||
_playKey1 = readD();
|
||||
_loginKey1 = readD();
|
||||
_loginKey2 = readD();
|
||||
}
|
||||
*/
|
||||
|
||||
L2Game_AuthLogin::L2Game_AuthLogin()
|
||||
{
|
||||
this->_initNull();
|
||||
}
|
||||
|
||||
L2Game_AuthLogin::L2Game_AuthLogin( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
// session keys must point to 8-byte arrays
|
||||
bool L2Game_AuthLogin::create( char *loginName,
|
||||
unsigned char *sessionKey1,
|
||||
unsigned char *sessionKey2 )
|
||||
{
|
||||
if( !loginName || !sessionKey1 || !sessionKey2 ) return false;
|
||||
wchar_t loginU[32];
|
||||
memset( loginU, 0, sizeof(loginU) );
|
||||
#ifdef L2PACKETS_WINDOWS
|
||||
_snwprintf( loginU, 32, L"%S", loginName );
|
||||
#endif
|
||||
#ifdef L2PACKETS_LINUX
|
||||
swprintf( loginU, 32, L"%ls", loginName );
|
||||
#endif
|
||||
loginU[31] = 0;
|
||||
return this->create( loginU, sessionKey1, sessionKey2 );
|
||||
}
|
||||
|
||||
bool L2Game_AuthLogin::create( wchar_t *loginName,
|
||||
unsigned char *sessionKey1,
|
||||
unsigned char *sessionKey2 )
|
||||
{
|
||||
if( !loginName || !sessionKey1 || !sessionKey2 ) return false;
|
||||
this->writeReset();
|
||||
// write packet code
|
||||
//this->writeUChar( 0x08 ); // interlude
|
||||
this->writeUChar( 0x2b ); // hellbound
|
||||
this->writeUnicodeString( loginName );
|
||||
this->writeBytes( sessionKey2+4, 4 );
|
||||
this->writeBytes( sessionKey2, 4 );
|
||||
this->writeBytes( sessionKey1, 8 );
|
||||
this->writeUInt( 1 );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Game_AuthLogin::read_login( wchar_t *loginOut )
|
||||
{
|
||||
if( !loginOut ) return false;
|
||||
this->readReset();
|
||||
this->readUChar();
|
||||
loginOut[0] = 0;
|
||||
wchar_t *login = this->readUnicodeString();
|
||||
if( !login ) return false;
|
||||
wcscpy( loginOut, login );
|
||||
free( login );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Game_AuthLogin::read_login( char *loginOut )
|
||||
{
|
||||
if( !loginOut ) return false;
|
||||
loginOut[0] = 0;
|
||||
wchar_t loginU[32] = {0};
|
||||
if( this->read_login(loginU) )
|
||||
{
|
||||
if( loginU[0] == 0 ) return true;
|
||||
#ifdef L2PACKETS_WINDOWS
|
||||
sprintf( loginOut, "%S", loginU );
|
||||
#else
|
||||
#ifdef L2PACKETS_LINUX
|
||||
sprintf( loginOut, "%ls", loginU );
|
||||
#else
|
||||
#error Unknown OS? O_o
|
||||
#endif
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
27
l2packets/game/client/L2Game_AuthLogin.h
Normal file
27
l2packets/game/client/L2Game_AuthLogin.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef L2GAME_AUTHLOGIN_H_
|
||||
#define L2GAME_AUTHLOGIN_H_
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
class L2Game_AuthLogin : public L2GamePacket
|
||||
{
|
||||
public:
|
||||
L2Game_AuthLogin();
|
||||
L2Game_AuthLogin( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
// session keys must point to 8-byte arrays
|
||||
bool create( char *loginName,
|
||||
unsigned char *sessionKey1,
|
||||
unsigned char *sessionKey2 );
|
||||
// unicode version of upper function
|
||||
// session keys must point to 8-byte arrays
|
||||
bool create( wchar_t *loginName,
|
||||
unsigned char *sessionKey1,
|
||||
unsigned char *sessionKey2 );
|
||||
public:
|
||||
bool read_login( char *loginOut );
|
||||
bool read_login( wchar_t *loginOut );
|
||||
//bool read_session_keys( unsigned char *skey1, unsigned char *skey2 );
|
||||
};
|
||||
|
||||
#endif /*L2GAME_AUTHLOGIN_H_*/
|
53
l2packets/game/client/L2Game_CharacterCreate.cpp
Normal file
53
l2packets/game/client/L2Game_CharacterCreate.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_CharacterCreate.h"
|
||||
|
||||
/*
|
||||
Client: Len 63 [CharacterCreate]
|
||||
3F 00
|
||||
0C // opcode
|
||||
41 00 65 00 72 00 69 00 6E 00 00 00 // name
|
||||
01 00 00 00 // race
|
||||
01 00 00 00 // sex
|
||||
19 00 00 00 // class id
|
||||
1C 00 00 00 // INT
|
||||
27 00 00 00 // STR
|
||||
1E 00 00 00 // CON
|
||||
1B 00 00 00 // MEN
|
||||
23 00 00 00 // DEX
|
||||
0B 00 00 00 // WIT
|
||||
00 00 00 00 // hair style
|
||||
00 00 00 00 // hair color
|
||||
00 00 00 00 // face
|
||||
*/
|
||||
|
||||
L2Game_CharacterCreate::L2Game_CharacterCreate()
|
||||
{
|
||||
_initNull();
|
||||
}
|
||||
|
||||
L2Game_CharacterCreate::L2Game_CharacterCreate( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
_initNull();
|
||||
setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Game_CharacterCreate::create( const L2Game_NewCharacterTemplate *tmpl, const wchar_t *name,
|
||||
int hairStyle, int hairColor, int face, int gender )
|
||||
{
|
||||
if( !tmpl ) return false;
|
||||
setPacketType( 0x0C ); // CharacterCreate
|
||||
writeS( name );
|
||||
writeD( tmpl->race );
|
||||
writeD( gender );
|
||||
writeD( tmpl->classID );
|
||||
writeD( tmpl->base_INT );
|
||||
writeD( tmpl->base_STR );
|
||||
writeD( tmpl->base_CON );
|
||||
writeD( tmpl->base_MEN );
|
||||
writeD( tmpl->base_DEX );
|
||||
writeD( tmpl->base_WIT );
|
||||
writeD( hairStyle );
|
||||
writeD( hairColor );
|
||||
writeD( face );
|
||||
return true;
|
||||
}
|
17
l2packets/game/client/L2Game_CharacterCreate.h
Normal file
17
l2packets/game/client/L2Game_CharacterCreate.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef H_L2GAME_CHARACTERCREATE
|
||||
#define H_L2GAME_CHARACTERCREATE
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
#include "../server/L2Game_NewCharacterSuccess.h"
|
||||
|
||||
class L2Game_CharacterCreate: public L2GamePacket
|
||||
{
|
||||
public:
|
||||
L2Game_CharacterCreate();
|
||||
L2Game_CharacterCreate( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
bool create( const L2Game_NewCharacterTemplate *tmpl, const wchar_t *name,
|
||||
int hairStyle, int hairColor, int face, int gender );
|
||||
};
|
||||
|
||||
#endif
|
29
l2packets/game/client/L2Game_CharacterDelete.cpp
Normal file
29
l2packets/game/client/L2Game_CharacterDelete.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_CharacterDelete.h"
|
||||
|
||||
L2Game_CharacterDelete::L2Game_CharacterDelete()
|
||||
{
|
||||
_initNull();
|
||||
}
|
||||
|
||||
L2Game_CharacterDelete::L2Game_CharacterDelete( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
_initNull();
|
||||
setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Game_CharacterDelete::create( L2_VERSION ver )
|
||||
{
|
||||
ver = L2_VERSION_T1;
|
||||
setPacketType( 0x0D ); // CharacterDelete
|
||||
writeD( p_charSlot );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Game_CharacterDelete::parse( L2_VERSION ver )
|
||||
{
|
||||
ver = L2_VERSION_T1;
|
||||
if( getPacketType() != 0x0D ) return false;
|
||||
p_charSlot = readD();
|
||||
return true;
|
||||
}
|
18
l2packets/game/client/L2Game_CharacterDelete.h
Normal file
18
l2packets/game/client/L2Game_CharacterDelete.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef H_L2GAME_CHARACTERDELETE
|
||||
#define H_L2GAME_CHARACTERDELETE
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
class L2Game_CharacterDelete: public L2GamePacket
|
||||
{
|
||||
public:
|
||||
L2Game_CharacterDelete();
|
||||
L2Game_CharacterDelete( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
bool parse( L2_VERSION ver = L2_VERSION_T1 );
|
||||
public:
|
||||
int p_charSlot;
|
||||
};
|
||||
|
||||
#endif
|
30
l2packets/game/client/L2Game_CharacterRestore.cpp
Normal file
30
l2packets/game/client/L2Game_CharacterRestore.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_CharacterRestore.h"
|
||||
|
||||
L2Game_CharacterRestore::L2Game_CharacterRestore()
|
||||
{
|
||||
_initNull();
|
||||
}
|
||||
|
||||
L2Game_CharacterRestore::L2Game_CharacterRestore( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
_initNull();
|
||||
setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Game_CharacterRestore::create( L2_VERSION ver )
|
||||
{
|
||||
ver = L2_VERSION_T1;
|
||||
setPacketType( 0x7B ); // CharacterDelete
|
||||
writeD( p_charSlot );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Game_CharacterRestore::parse( L2_VERSION ver )
|
||||
{
|
||||
ver = L2_VERSION_T1;
|
||||
if( getPacketType() != 0x7B ) return false;
|
||||
p_charSlot = readD();
|
||||
return true;
|
||||
}
|
||||
|
18
l2packets/game/client/L2Game_CharacterRestore.h
Normal file
18
l2packets/game/client/L2Game_CharacterRestore.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef H_L2GAME_CHARACTERRESTORE
|
||||
#define H_L2GAME_CHARACTERRESTORE
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
class L2Game_CharacterRestore: public L2GamePacket
|
||||
{
|
||||
public:
|
||||
L2Game_CharacterRestore();
|
||||
L2Game_CharacterRestore( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
bool parse( L2_VERSION ver = L2_VERSION_T1 );
|
||||
public:
|
||||
int p_charSlot;
|
||||
};
|
||||
|
||||
#endif
|
46
l2packets/game/client/L2Game_CharacterSelect.cpp
Normal file
46
l2packets/game/client/L2Game_CharacterSelect.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_CharacterSelect.h"
|
||||
|
||||
/* L2J:
|
||||
protected void readImpl()
|
||||
{
|
||||
_charSlot = readD();
|
||||
_unk1 = readH();
|
||||
_unk2 = readD();
|
||||
_unk3 = readD();
|
||||
_unk4 = readD();
|
||||
}
|
||||
*/
|
||||
|
||||
L2Game_CharacterSelect::L2Game_CharacterSelect()
|
||||
{
|
||||
this->_initNull();
|
||||
}
|
||||
|
||||
L2Game_CharacterSelect::L2Game_CharacterSelect( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Game_CharacterSelect::create( unsigned int charSlot )
|
||||
{
|
||||
this->writeReset();
|
||||
this->writeUChar( 0x12 ); // packet type
|
||||
this->writeUInt( charSlot );
|
||||
this->writeUShort( 0x0000 );
|
||||
this->writeUInt( 0x00000000 );
|
||||
this->writeUInt( 0x00000000 );
|
||||
this->writeUInt( 0x00000000 );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Game_CharacterSelect::read_charSlot( unsigned int *charSlot )
|
||||
{
|
||||
if( !charSlot || !(this->canReadBytes(5)) ) return false;
|
||||
(*charSlot) = 0;
|
||||
this->readReset();
|
||||
this->readUChar(); // pcode
|
||||
(*charSlot) = this->readUInt();
|
||||
return true;
|
||||
}
|
16
l2packets/game/client/L2Game_CharacterSelect.h
Normal file
16
l2packets/game/client/L2Game_CharacterSelect.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef L2GAME_CHARACTERSELECT_H_
|
||||
#define L2GAME_CHARACTERSELECT_H_
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
class L2Game_CharacterSelect : public L2GamePacket
|
||||
{
|
||||
public:
|
||||
L2Game_CharacterSelect();
|
||||
L2Game_CharacterSelect( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
bool create( unsigned int charSlot );
|
||||
bool read_charSlot( unsigned int *charSlot );
|
||||
};
|
||||
|
||||
#endif /*L2GAME_CHARACTERSELECT_H_*/
|
54
l2packets/game/client/L2Game_EnterWorld.cpp
Normal file
54
l2packets/game/client/L2Game_EnterWorld.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_EnterWorld.h"
|
||||
|
||||
/*
|
||||
Client: Len 107
|
||||
6B 00
|
||||
11
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
C9 BC F2 A7 66 5A 0B 98 36 A5 BD 89 ED 7F E4 D7
|
||||
6B 49 E2 9F EF 76 EB CE A3 FA F4 BF 0C 64 A3 B4
|
||||
A4 CE DC C6 08 3E 6E EA 45 CA D3 FE 88 13 87 B8
|
||||
06 2C 96 F0 9B 1E 8E BC C6 9B 98 C8 63 16 CF D0
|
||||
29 00 00 00 0A E1 74 17 0A 08 00 08 5C 32 BD E1
|
||||
5C 32 BE 22 5E 19 03 41
|
||||
|
||||
last 2 D's are different, depend on char
|
||||
|
||||
unsigned char array = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xC9, 0xBC, 0xF2, 0xA7, 0x66, 0x5A, 0x0B, 0x98, 0x36, 0xA5, 0xBD, 0x89, 0xED, 0x7F, 0xE4, 0xD7,
|
||||
0x6B, 0x49, 0xE2, 0x9F, 0xEF, 0x76, 0xEB, 0xCE, 0xA3, 0xFA, 0xF4, 0xBF, 0x0C, 0x64, 0xA3, 0xB4,
|
||||
0xA4, 0xCE, 0xDC, 0xC6, 0x08, 0x3E, 0x6E, 0xEA, 0x45, 0xCA, 0xD3, 0xFE, 0x88, 0x13, 0x87, 0xB8,
|
||||
0x06, 0x2C, 0x96, 0xF0, 0x9B, 0x1E, 0x8E, 0xBC, 0xC6, 0x9B, 0x98, 0xC8, 0x63, 0x16, 0xCF, 0xD0,
|
||||
0x29, 0x00, 0x00, 0x00, 0x0A, 0xE1, 0x74, 0x17, 0x0A, 0x08, 0x00, 0x08, 0x5C, 0x32, 0xBD, 0xE1,
|
||||
0x5C, 0x32, 0xBE, 0x22, 0x5E, 0x19, 0x03, 0x41, };
|
||||
*/
|
||||
|
||||
L2Game_EnterWorld::L2Game_EnterWorld()
|
||||
{
|
||||
_initNull();
|
||||
}
|
||||
|
||||
L2Game_EnterWorld::L2Game_EnterWorld( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
_initNull();
|
||||
setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Game_EnterWorld::create( L2_VERSION ver /*= L2_VERSION_T1*/ )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
unsigned char ew_array[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xC9, 0xBC, 0xF2, 0xA7, 0x66, 0x5A, 0x0B, 0x98, 0x36, 0xA5, 0xBD, 0x89, 0xED, 0x7F, 0xE4, 0xD7,
|
||||
0x6B, 0x49, 0xE2, 0x9F, 0xEF, 0x76, 0xEB, 0xCE, 0xA3, 0xFA, 0xF4, 0xBF, 0x0C, 0x64, 0xA3, 0xB4,
|
||||
0xA4, 0xCE, 0xDC, 0xC6, 0x08, 0x3E, 0x6E, 0xEA, 0x45, 0xCA, 0xD3, 0xFE, 0x88, 0x13, 0x87, 0xB8,
|
||||
0x06, 0x2C, 0x96, 0xF0, 0x9B, 0x1E, 0x8E, 0xBC, 0xC6, 0x9B, 0x98, 0xC8, 0x63, 0x16, 0xCF, 0xD0,
|
||||
0x29, 0x00, 0x00, 0x00, 0x0A, 0xE1, 0x74, 0x17, 0x0A, 0x08, 0x00, 0x08, 0x5C, 0x32, 0xBD, 0xE1,
|
||||
0x5C, 0x32, 0xBE, 0x22, 0x5E, 0x19, 0x03, 0x41 };
|
||||
this->writeReset();
|
||||
this->writeUChar( 0x11 ); // EnterWorld
|
||||
this->writeBytes( ew_array, sizeof(ew_array) );
|
||||
return true;
|
||||
}
|
16
l2packets/game/client/L2Game_EnterWorld.h
Normal file
16
l2packets/game/client/L2Game_EnterWorld.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef L2GAME_ENTERWORLD_H_
|
||||
#define L2GAME_ENTERWORLD_H_
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
class L2Game_EnterWorld : public L2GamePacket
|
||||
{
|
||||
public:
|
||||
L2Game_EnterWorld();
|
||||
L2Game_EnterWorld( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
virtual bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
//void read() {} // L2J Server ignores its contents, parsing is unknown :)
|
||||
};
|
||||
|
||||
#endif
|
33
l2packets/game/client/L2Game_NewCharacter.cpp
Normal file
33
l2packets/game/client/L2Game_NewCharacter.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_NewCharacter.h"
|
||||
|
||||
/**
|
||||
Client: Len 3 [NewCharacter]
|
||||
03 00
|
||||
13 // opcode
|
||||
*/
|
||||
|
||||
L2Game_NewCharacter::L2Game_NewCharacter()
|
||||
{
|
||||
_initNull();
|
||||
}
|
||||
|
||||
L2Game_NewCharacter::L2Game_NewCharacter( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
_initNull();
|
||||
setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Game_NewCharacter::create( L2_VERSION ver )
|
||||
{
|
||||
ver = L2_VERSION_T1;
|
||||
setPacketType( 0x13 );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Game_NewCharacter::parse( L2_VERSION ver )
|
||||
{
|
||||
ver = L2_VERSION_T1;
|
||||
// just trugger
|
||||
return true;
|
||||
}
|
16
l2packets/game/client/L2Game_NewCharacter.h
Normal file
16
l2packets/game/client/L2Game_NewCharacter.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef H_L2GAME_NEWCHARACTER
|
||||
#define H_L2GAME_NEWCHARACTER
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
class L2Game_NewCharacter: public L2GamePacket
|
||||
{
|
||||
public:
|
||||
L2Game_NewCharacter();
|
||||
L2Game_NewCharacter( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
bool parse( L2_VERSION ver = L2_VERSION_T1 );
|
||||
};
|
||||
|
||||
#endif
|
274
l2packets/game/client/L2Game_ProtocolVersion.cpp
Normal file
274
l2packets/game/client/L2Game_ProtocolVersion.cpp
Normal file
@@ -0,0 +1,274 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_ProtocolVersion.h"
|
||||
|
||||
/* L2J:
|
||||
// "[C] 00 ProtocolVersion";
|
||||
* pcode 0c00 is in interlude
|
||||
* pcode 0x0e is in hellbound
|
||||
protected void readImpl()
|
||||
{
|
||||
_version = readD();
|
||||
}
|
||||
*/
|
||||
|
||||
L2Game_ProtocolVersion::L2Game_ProtocolVersion()
|
||||
{
|
||||
this->_initNull();
|
||||
}
|
||||
|
||||
L2Game_ProtocolVersion::L2Game_ProtocolVersion( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Game_ProtocolVersion::create( L2_VERSION ver )
|
||||
{
|
||||
switch( ver )
|
||||
{
|
||||
case L2_VERSION_T1: this->createDefaultKamael(); break;
|
||||
case L2_VERSION_T15: this->createDefaultHellbound(); break;
|
||||
case L2_VERSION_T2: this->createDefaultGracia1(); break;
|
||||
case L2_VERSION_T22: this->createDefaultGracia2(); break;
|
||||
case L2_VERSION_T23: this->createDefaultGracia3(); break;
|
||||
case L2_VERSION_T24: this->createDefaultGracia4(); break;
|
||||
default: return false; break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Kamael
|
||||
C->S
|
||||
0B 01 // len
|
||||
0E // p.code ProtocolVersion
|
||||
3C 03 00 00 // protocol - 828
|
||||
09 07 54 56 03 09 0B 01 07 02 54 54 56 07 00 02
|
||||
55 56 00 51 00 53 57 04 07 55 08 54 01 07 01 53
|
||||
00 56 55 56 01 06 05 04 51 03 08 51 08 51 56 04
|
||||
54 06 55 08 02 09 51 56 01 53 06 55 04 53 00 56
|
||||
56 53 01 09 02 09 01 51 54 51 09 55 56 09 03 04
|
||||
07 05 55 04 06 55 04 06 09 04 51 01 08 08 06 05
|
||||
52 06 04 01 07 54 03 06 52 55 06 55 55 51 01 02
|
||||
04 54 03 55 54 01 57 51 55 05 52 05 54 07 51 51
|
||||
55 07 02 53 53 00 52 05 52 07 01 54 00 03 05 05
|
||||
08 06 05 05 06 03 00 0D 08 01 07 09 03 51 03 07
|
||||
53 09 51 06 07 54 0A 50 56 02 52 04 05 55 51 02
|
||||
53 00 08 54 04 52 56 06 02 09 00 08 03 53 56 01
|
||||
05 00 55 06 08 56 04 0D 06 07 52 06 07 04 0A 06
|
||||
01 04 54 04 00 05 02 04 54 00 09 52 53 05 04 01
|
||||
04 05 05 01 52 51 52 0D 06 51 08 09 54 53 00 0D
|
||||
01 02 03 54 53 01 05 03 08 56 54 07 02 54 0B 06
|
||||
8D 71 5F 08
|
||||
*/
|
||||
|
||||
bool L2Game_ProtocolVersion::createDefaultKamael( unsigned int gameProtoVer /*= 828*/ )
|
||||
{
|
||||
this->writeReset();
|
||||
// packet code 0x00 was in Interlude!!!!
|
||||
// this->writeUChar( 0x00 ); // packet type - ProtocolVersion
|
||||
// in Hellbound this code is 0x0e
|
||||
this->writeUChar( 0x0e ); // packet type - ProtocolVersion
|
||||
this->writeUInt( gameProtoVer );
|
||||
unsigned char pv_array[] = {
|
||||
0x09, 0x07, 0x54, 0x56, 0x03, 0x09, 0x0B, 0x01, 0x07, 0x02, 0x54, 0x54, 0x56, 0x07, 0x00, 0x02,
|
||||
0x55, 0x56, 0x00, 0x51, 0x00, 0x53, 0x57, 0x04, 0x07, 0x55, 0x08, 0x54, 0x01, 0x07, 0x01, 0x53,
|
||||
0x00, 0x56, 0x55, 0x56, 0x01, 0x06, 0x05, 0x04, 0x51, 0x03, 0x08, 0x51, 0x08, 0x51, 0x56, 0x04,
|
||||
0x54, 0x06, 0x55, 0x08, 0x02, 0x09, 0x51, 0x56, 0x01, 0x53, 0x06, 0x55, 0x04, 0x53, 0x00, 0x56,
|
||||
0x56, 0x53, 0x01, 0x09, 0x02, 0x09, 0x01, 0x51, 0x54, 0x51, 0x09, 0x55, 0x56, 0x09, 0x03, 0x04,
|
||||
0x07, 0x05, 0x55, 0x04, 0x06, 0x55, 0x04, 0x06, 0x09, 0x04, 0x51, 0x01, 0x08, 0x08, 0x06, 0x05,
|
||||
0x52, 0x06, 0x04, 0x01, 0x07, 0x54, 0x03, 0x06, 0x52, 0x55, 0x06, 0x55, 0x55, 0x51, 0x01, 0x02,
|
||||
0x04, 0x54, 0x03, 0x55, 0x54, 0x01, 0x57, 0x51, 0x55, 0x05, 0x52, 0x05, 0x54, 0x07, 0x51, 0x51,
|
||||
0x55, 0x07, 0x02, 0x53, 0x53, 0x00, 0x52, 0x05, 0x52, 0x07, 0x01, 0x54, 0x00, 0x03, 0x05, 0x05,
|
||||
0x08, 0x06, 0x05, 0x05, 0x06, 0x03, 0x00, 0x0D, 0x08, 0x01, 0x07, 0x09, 0x03, 0x51, 0x03, 0x07,
|
||||
0x53, 0x09, 0x51, 0x06, 0x07, 0x54, 0x0A, 0x50, 0x56, 0x02, 0x52, 0x04, 0x05, 0x55, 0x51, 0x02,
|
||||
0x53, 0x00, 0x08, 0x54, 0x04, 0x52, 0x56, 0x06, 0x02, 0x09, 0x00, 0x08, 0x03, 0x53, 0x56, 0x01,
|
||||
0x05, 0x00, 0x55, 0x06, 0x08, 0x56, 0x04, 0x0D, 0x06, 0x07, 0x52, 0x06, 0x07, 0x04, 0x0A, 0x06,
|
||||
0x01, 0x04, 0x54, 0x04, 0x00, 0x05, 0x02, 0x04, 0x54, 0x00, 0x09, 0x52, 0x53, 0x05, 0x04, 0x01,
|
||||
0x04, 0x05, 0x05, 0x01, 0x52, 0x51, 0x52, 0x0D, 0x06, 0x51, 0x08, 0x09, 0x54, 0x53, 0x00, 0x0D,
|
||||
0x01, 0x02, 0x03, 0x54, 0x53, 0x01, 0x05, 0x03, 0x08, 0x56, 0x54, 0x07, 0x02, 0x54, 0x0B, 0x06,
|
||||
0x8D, 0x71, 0x5F, 0x08 };
|
||||
writeBytes( pv_array, sizeof(pv_array) );
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Hellbound
|
||||
C->S Len 267
|
||||
0B 01 // len
|
||||
0E // p. code
|
||||
3F 03 00 00 // protocol - 831 (Hellbound?)
|
||||
09 07 54 56 03 09 0B 01 07 02 54 54 56 07 00 02
|
||||
55 56 00 51 00 53 57 04 07 55 08 54 01 07 01 53
|
||||
00 56 55 56 01 06 05 04 51 03 08 51 08 51 56 04
|
||||
54 06 55 08 02 09 51 56 01 53 06 55 04 53 00 56
|
||||
56 53 01 09 02 09 01 51 54 51 09 55 56 09 03 04
|
||||
07 05 55 04 06 55 04 06 09 04 51 01 08 08 06 05
|
||||
52 06 04 01 07 54 03 06 52 55 06 55 55 51 01 02
|
||||
04 54 03 55 54 01 57 51 55 05 52 05 54 07 51 51
|
||||
55 07 02 53 53 00 52 05 52 07 01 54 00 03 05 05
|
||||
08 06 05 05 06 03 00 0D 08 01 07 09 03 51 03 07
|
||||
53 09 51 06 07 54 0A 50 56 02 52 04 05 55 51 02
|
||||
53 00 08 54 04 52 56 06 02 09 00 08 03 53 56 01
|
||||
05 00 55 06 08 56 04 0D 06 07 52 06 07 04 0A 06
|
||||
01 04 54 04 00 05 02 04 54 00 09 52 53 05 04 01
|
||||
04 05 05 01 52 51 52 0D 06 51 08 09 54 53 00 0D
|
||||
01 02 03 54 53 01 05 03 08 56 54 07 02 54 0B 06
|
||||
FB 87 B9 4A
|
||||
*/
|
||||
|
||||
bool L2Game_ProtocolVersion::createDefaultHellbound( unsigned int gameProtoVer /*= 851*/ )
|
||||
{
|
||||
this->writeReset();
|
||||
// packet code 0x00 was in Interlude!!!!
|
||||
// this->writeUChar( 0x00 ); // packet type - ProtocolVersion
|
||||
// in Hellbound this code is 0x0e
|
||||
this->writeUChar( 0x0e ); // packet type - ProtocolVersion
|
||||
this->writeUInt( gameProtoVer );
|
||||
unsigned char pv_array[] = {
|
||||
0x09, 0x07, 0x54, 0x56, 0x03, 0x09, 0x0B, 0x01, 0x07, 0x02, 0x54, 0x54, 0x56, 0x07, 0x00, 0x02,
|
||||
0x55, 0x56, 0x00, 0x51, 0x00, 0x53, 0x57, 0x04, 0x07, 0x55, 0x08, 0x54, 0x01, 0x07, 0x01, 0x53,
|
||||
0x00, 0x56, 0x55, 0x56, 0x01, 0x06, 0x05, 0x04, 0x51, 0x03, 0x08, 0x51, 0x08, 0x51, 0x56, 0x04,
|
||||
0x54, 0x06, 0x55, 0x08, 0x02, 0x09, 0x51, 0x56, 0x01, 0x53, 0x06, 0x55, 0x04, 0x53, 0x00, 0x56,
|
||||
0x56, 0x53, 0x01, 0x09, 0x02, 0x09, 0x01, 0x51, 0x54, 0x51, 0x09, 0x55, 0x56, 0x09, 0x03, 0x04,
|
||||
0x07, 0x05, 0x55, 0x04, 0x06, 0x55, 0x04, 0x06, 0x09, 0x04, 0x51, 0x01, 0x08, 0x08, 0x06, 0x05,
|
||||
0x52, 0x06, 0x04, 0x01, 0x07, 0x54, 0x03, 0x06, 0x52, 0x55, 0x06, 0x55, 0x55, 0x51, 0x01, 0x02,
|
||||
0x04, 0x54, 0x03, 0x55, 0x54, 0x01, 0x57, 0x51, 0x55, 0x05, 0x52, 0x05, 0x54, 0x07, 0x51, 0x51,
|
||||
0x55, 0x07, 0x02, 0x53, 0x53, 0x00, 0x52, 0x05, 0x52, 0x07, 0x01, 0x54, 0x00, 0x03, 0x05, 0x05,
|
||||
0x08, 0x06, 0x05, 0x05, 0x06, 0x03, 0x00, 0x0D, 0x08, 0x01, 0x07, 0x09, 0x03, 0x51, 0x03, 0x07,
|
||||
0x53, 0x09, 0x51, 0x06, 0x07, 0x54, 0x0A, 0x50, 0x56, 0x02, 0x52, 0x04, 0x05, 0x55, 0x51, 0x02,
|
||||
0x53, 0x00, 0x08, 0x54, 0x04, 0x52, 0x56, 0x06, 0x02, 0x09, 0x00, 0x08, 0x03, 0x53, 0x56, 0x01,
|
||||
0x05, 0x00, 0x55, 0x06, 0x08, 0x56, 0x04, 0x0D, 0x06, 0x07, 0x52, 0x06, 0x07, 0x04, 0x0A, 0x06,
|
||||
0x01, 0x04, 0x54, 0x04, 0x00, 0x05, 0x02, 0x04, 0x54, 0x00, 0x09, 0x52, 0x53, 0x05, 0x04, 0x01,
|
||||
0x04, 0x05, 0x05, 0x01, 0x52, 0x51, 0x52, 0x0D, 0x06, 0x51, 0x08, 0x09, 0x54, 0x53, 0x00, 0x0D,
|
||||
0x01, 0x02, 0x03, 0x54, 0x53, 0x01, 0x05, 0x03, 0x08, 0x56, 0x54, 0x07, 0x02, 0x54, 0x0B, 0x06,
|
||||
0xFB, 0x87, 0xB9, 0x4A };
|
||||
writeBytes( pv_array, sizeof(pv_array) );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Game_ProtocolVersion::createDefaultGracia1( unsigned int gameProtoVer /*= 12*/ )
|
||||
{
|
||||
this->writeReset();
|
||||
// packet code 0x00 was in Interlude!!!!
|
||||
// this->writeUChar( 0x00 ); // packet type - ProtocolVersion
|
||||
// in Hellbound this code is 0x0e
|
||||
this->writeUChar( 0x0e ); // packet type - ProtocolVersion
|
||||
this->writeUInt( gameProtoVer );
|
||||
unsigned char pv_array[] = {
|
||||
0x09, 0x07, 0x54, 0x56, 0x03, 0x09, 0x0b, 0x01, 0x07, 0x02, 0x54, 0x54, 0x56, 0x07, 0x00, 0x02,
|
||||
0x55, 0x56, 0x00, 0x51, 0x00, 0x53, 0x57, 0x04, 0x07, 0x55, 0x08, 0x54, 0x01, 0x07, 0x01, 0x53,
|
||||
0x00, 0x56, 0x55, 0x56, 0x01, 0x06, 0x05, 0x04, 0x51, 0x03, 0x08, 0x51, 0x08, 0x51, 0x56, 0x04,
|
||||
0x54, 0x06, 0x55, 0x08, 0x02, 0x09, 0x51, 0x56, 0x01, 0x53, 0x06, 0x55, 0x04, 0x53, 0x00, 0x56,
|
||||
0x56, 0x53, 0x01, 0x09, 0x02, 0x09, 0x01, 0x51, 0x54, 0x51, 0x09, 0x55, 0x56, 0x09, 0x03, 0x04,
|
||||
0x07, 0x05, 0x55, 0x04, 0x06, 0x55, 0x04, 0x06, 0x09, 0x04, 0x51, 0x01, 0x08, 0x08, 0x06, 0x05,
|
||||
0x52, 0x06, 0x04, 0x01, 0x07, 0x54, 0x03, 0x06, 0x52, 0x55, 0x06, 0x55, 0x55, 0x51, 0x01, 0x02,
|
||||
0x04, 0x54, 0x03, 0x55, 0x54, 0x01, 0x57, 0x51, 0x55, 0x05, 0x52, 0x05, 0x54, 0x07, 0x51, 0x51,
|
||||
0x55, 0x07, 0x02, 0x53, 0x53, 0x00, 0x52, 0x05, 0x52, 0x07, 0x01, 0x54, 0x00, 0x03, 0x05, 0x05,
|
||||
0x08, 0x06, 0x05, 0x05, 0x06, 0x03, 0x00, 0x0d, 0x08, 0x01, 0x07, 0x09, 0x03, 0x51, 0x03, 0x07,
|
||||
0x53, 0x09, 0x51, 0x06, 0x07, 0x54, 0x0a, 0x50, 0x56, 0x02, 0x52, 0x04, 0x05, 0x55, 0x51, 0x02,
|
||||
0x53, 0x00, 0x08, 0x54, 0x04, 0x52, 0x56, 0x06, 0x02, 0x09, 0x00, 0x08, 0x03, 0x53, 0x56, 0x01,
|
||||
0x05, 0x00, 0x55, 0x06, 0x08, 0x56, 0x04, 0x0d, 0x06, 0x07, 0x52, 0x06, 0x07, 0x04, 0x0a, 0x06,
|
||||
0x01, 0x04, 0x54, 0x04, 0x00, 0x05, 0x02, 0x04, 0x54, 0x00, 0x09, 0x52, 0x53, 0x05, 0x04, 0x01,
|
||||
0x04, 0x05, 0x05, 0x01, 0x52, 0x51, 0x52, 0x0d, 0x06, 0x51, 0x08, 0x09, 0x54, 0x53, 0x00, 0x0d,
|
||||
0x01, 0x02, 0x03, 0x54, 0x53, 0x01, 0x05, 0x03, 0x08, 0x56, 0x54, 0x07, 0x02, 0x54, 0x0b, 0x06,
|
||||
0xdf, 0xb8, 0x3b, 0x54 };
|
||||
writeBytes( pv_array, sizeof(pv_array) );
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: validate
|
||||
bool L2Game_ProtocolVersion::createDefaultGracia2( unsigned int gameProtoVer /*= 17*/ )
|
||||
{
|
||||
this->writeReset();
|
||||
// packet code 0x00 was in Interlude!!!!
|
||||
// this->writeUChar( 0x00 ); // packet type - ProtocolVersion
|
||||
// in Hellbound this code is 0x0e
|
||||
this->writeUChar( 0x0e ); // packet type - ProtocolVersion
|
||||
this->writeUInt( gameProtoVer );
|
||||
unsigned char pv_array[] = {
|
||||
0x09, 0x07, 0x54, 0x56, 0x03, 0x09, 0x0B, 0x01, 0x07, 0x02, 0x54, 0x54, 0x56, 0x07, 0x00, 0x02,
|
||||
0x55, 0x56, 0x00, 0x51, 0x00, 0x53, 0x57, 0x04, 0x07, 0x55, 0x08, 0x54, 0x01, 0x07, 0x01, 0x53,
|
||||
0x00, 0x56, 0x55, 0x56, 0x01, 0x06, 0x05, 0x04, 0x51, 0x03, 0x08, 0x51, 0x08, 0x51, 0x56, 0x04,
|
||||
0x54, 0x06, 0x55, 0x08, 0x02, 0x09, 0x51, 0x56, 0x01, 0x53, 0x06, 0x55, 0x04, 0x53, 0x00, 0x56,
|
||||
0x56, 0x53, 0x01, 0x09, 0x02, 0x09, 0x01, 0x51, 0x54, 0x51, 0x09, 0x55, 0x56, 0x09, 0x03, 0x04,
|
||||
0x07, 0x05, 0x55, 0x04, 0x06, 0x55, 0x04, 0x06, 0x09, 0x04, 0x51, 0x01, 0x08, 0x08, 0x06, 0x05,
|
||||
0x52, 0x06, 0x04, 0x01, 0x07, 0x54, 0x03, 0x06, 0x52, 0x55, 0x06, 0x55, 0x55, 0x51, 0x01, 0x02,
|
||||
0x04, 0x54, 0x03, 0x55, 0x54, 0x01, 0x57, 0x51, 0x55, 0x05, 0x52, 0x05, 0x54, 0x07, 0x51, 0x51,
|
||||
0x55, 0x07, 0x02, 0x53, 0x53, 0x00, 0x52, 0x05, 0x52, 0x07, 0x01, 0x54, 0x00, 0x03, 0x05, 0x05,
|
||||
0x08, 0x06, 0x05, 0x05, 0x06, 0x03, 0x00, 0x0D, 0x08, 0x01, 0x07, 0x09, 0x03, 0x51, 0x03, 0x07,
|
||||
0x53, 0x09, 0x51, 0x06, 0x07, 0x54, 0x0A, 0x50, 0x56, 0x02, 0x52, 0x04, 0x05, 0x55, 0x51, 0x02,
|
||||
0x53, 0x00, 0x08, 0x54, 0x04, 0x52, 0x56, 0x06, 0x02, 0x09, 0x00, 0x08, 0x03, 0x53, 0x56, 0x01,
|
||||
0x05, 0x00, 0x55, 0x06, 0x08, 0x56, 0x04, 0x0D, 0x06, 0x07, 0x52, 0x06, 0x07, 0x04, 0x0A, 0x06,
|
||||
0x01, 0x04, 0x54, 0x04, 0x00, 0x05, 0x02, 0x04, 0x54, 0x00, 0x09, 0x52, 0x53, 0x05, 0x04, 0x01,
|
||||
0x04, 0x05, 0x05, 0x01, 0x52, 0x51, 0x52, 0x0D, 0x06, 0x51, 0x08, 0x09, 0x54, 0x53, 0x00, 0x0D,
|
||||
0x01, 0x02, 0x03, 0x54, 0x53, 0x01, 0x05, 0x03, 0x08, 0x56, 0x54, 0x07, 0x02, 0x54, 0x0B, 0x06,
|
||||
0xEB, 0xEF, 0x3D, 0xE6 };
|
||||
writeBytes( pv_array, sizeof(pv_array) );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Game_ProtocolVersion::createDefaultGracia3( unsigned int gameProtoVer /*= 83*/ )
|
||||
{
|
||||
this->writeReset();
|
||||
// packet code 0x00 was in Interlude!!!!
|
||||
// this->writeUChar( 0x00 ); // packet type - ProtocolVersion
|
||||
// in Hellbound this code is 0x0e
|
||||
this->writeUChar( 0x0e ); // packet type - ProtocolVersion
|
||||
this->writeUInt( gameProtoVer );
|
||||
unsigned char pv_array[] = {
|
||||
0x09, 0x07, 0x54, 0x56, 0x03, 0x09, 0x0B, 0x01, 0x07, 0x02, 0x54, 0x54, 0x56, 0x07, 0x00, 0x02,
|
||||
0x55, 0x56, 0x00, 0x51, 0x00, 0x53, 0x57, 0x04, 0x07, 0x55, 0x08, 0x54, 0x01, 0x07, 0x01, 0x53,
|
||||
0x00, 0x56, 0x55, 0x56, 0x01, 0x06, 0x05, 0x04, 0x51, 0x03, 0x08, 0x51, 0x08, 0x51, 0x56, 0x04,
|
||||
0x54, 0x06, 0x55, 0x08, 0x02, 0x09, 0x51, 0x56, 0x01, 0x53, 0x06, 0x55, 0x04, 0x53, 0x00, 0x56,
|
||||
0x56, 0x53, 0x01, 0x09, 0x02, 0x09, 0x01, 0x51, 0x54, 0x51, 0x09, 0x55, 0x56, 0x09, 0x03, 0x04,
|
||||
0x07, 0x05, 0x55, 0x04, 0x06, 0x55, 0x04, 0x06, 0x09, 0x04, 0x51, 0x01, 0x08, 0x08, 0x06, 0x05,
|
||||
0x52, 0x06, 0x04, 0x01, 0x07, 0x54, 0x03, 0x06, 0x52, 0x55, 0x06, 0x55, 0x55, 0x51, 0x01, 0x02,
|
||||
0x04, 0x54, 0x03, 0x55, 0x54, 0x01, 0x57, 0x51, 0x55, 0x05, 0x52, 0x05, 0x54, 0x07, 0x51, 0x51,
|
||||
0x55, 0x07, 0x02, 0x53, 0x53, 0x00, 0x52, 0x05, 0x52, 0x07, 0x01, 0x54, 0x00, 0x03, 0x05, 0x05,
|
||||
0x08, 0x06, 0x05, 0x05, 0x06, 0x03, 0x00, 0x0D, 0x08, 0x01, 0x07, 0x09, 0x03, 0x51, 0x03, 0x07,
|
||||
0x53, 0x09, 0x51, 0x06, 0x07, 0x54, 0x0A, 0x50, 0x56, 0x02, 0x52, 0x04, 0x05, 0x55, 0x51, 0x02,
|
||||
0x53, 0x00, 0x08, 0x54, 0x04, 0x52, 0x56, 0x06, 0x02, 0x09, 0x00, 0x08, 0x03, 0x53, 0x56, 0x01,
|
||||
0x05, 0x00, 0x55, 0x06, 0x08, 0x56, 0x04, 0x0D, 0x06, 0x07, 0x52, 0x06, 0x07, 0x04, 0x0A, 0x06,
|
||||
0x01, 0x04, 0x54, 0x04, 0x00, 0x05, 0x02, 0x04, 0x54, 0x00, 0x09, 0x52, 0x53, 0x05, 0x04, 0x01,
|
||||
0x04, 0x05, 0x05, 0x01, 0x52, 0x51, 0x52, 0x0D, 0x06, 0x51, 0x08, 0x09, 0x54, 0x53, 0x00, 0x0D,
|
||||
0x01, 0x02, 0x03, 0x54, 0x53, 0x01, 0x05, 0x03, 0x08, 0x56, 0x54, 0x07, 0x02, 0x54, 0x0B, 0x06,
|
||||
0x11, 0x5D, 0x1F, 0x60 }; // these last 4 bytes always differ :)
|
||||
writeBytes( pv_array, sizeof(pv_array) );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Game_ProtocolVersion::createDefaultGracia4( unsigned int gameProtoVer /*= 146*/ )
|
||||
{
|
||||
this->writeReset();
|
||||
this->writeUChar( 0x0e ); // packet type - ProtocolVersion
|
||||
this->writeUInt( gameProtoVer );
|
||||
unsigned char pv_array[] = {
|
||||
0x09, 0x07, 0x54, 0x56, 0x03, 0x09, 0x0B, 0x01, 0x07, 0x02, 0x54, 0x54, 0x56, 0x07, 0x00, 0x02,
|
||||
0x55, 0x56, 0x00, 0x51, 0x00, 0x53, 0x57, 0x04, 0x07, 0x55, 0x08, 0x54, 0x01, 0x07, 0x01, 0x53,
|
||||
0x00, 0x56, 0x55, 0x56, 0x01, 0x06, 0x05, 0x04, 0x51, 0x03, 0x08, 0x51, 0x08, 0x51, 0x56, 0x04,
|
||||
0x54, 0x06, 0x55, 0x08, 0x02, 0x09, 0x51, 0x56, 0x01, 0x53, 0x06, 0x55, 0x04, 0x53, 0x00, 0x56,
|
||||
0x56, 0x53, 0x01, 0x09, 0x02, 0x09, 0x01, 0x51, 0x54, 0x51, 0x09, 0x55, 0x56, 0x09, 0x03, 0x04,
|
||||
0x07, 0x05, 0x55, 0x04, 0x06, 0x55, 0x04, 0x06, 0x09, 0x04, 0x51, 0x01, 0x08, 0x08, 0x06, 0x05,
|
||||
0x52, 0x06, 0x04, 0x01, 0x07, 0x54, 0x03, 0x06, 0x52, 0x55, 0x06, 0x55, 0x55, 0x51, 0x01, 0x02,
|
||||
0x04, 0x54, 0x03, 0x55, 0x54, 0x01, 0x57, 0x51, 0x55, 0x05, 0x52, 0x05, 0x54, 0x07, 0x51, 0x51,
|
||||
0x55, 0x07, 0x02, 0x53, 0x53, 0x00, 0x52, 0x05, 0x52, 0x07, 0x01, 0x54, 0x00, 0x03, 0x05, 0x05,
|
||||
0x08, 0x06, 0x05, 0x05, 0x06, 0x03, 0x00, 0x0D, 0x08, 0x01, 0x07, 0x09, 0x03, 0x51, 0x03, 0x07,
|
||||
0x53, 0x09, 0x51, 0x06, 0x07, 0x54, 0x0A, 0x50, 0x56, 0x02, 0x52, 0x04, 0x05, 0x55, 0x51, 0x02,
|
||||
0x53, 0x00, 0x08, 0x54, 0x04, 0x52, 0x56, 0x06, 0x02, 0x09, 0x00, 0x08, 0x03, 0x53, 0x56, 0x01,
|
||||
0x05, 0x00, 0x55, 0x06, 0x08, 0x56, 0x04, 0x0D, 0x06, 0x07, 0x52, 0x06, 0x07, 0x04, 0x0A, 0x06,
|
||||
0x01, 0x04, 0x54, 0x04, 0x00, 0x05, 0x02, 0x04, 0x54, 0x00, 0x09, 0x52, 0x53, 0x05, 0x04, 0x01,
|
||||
0x04, 0x05, 0x05, 0x01, 0x52, 0x51, 0x52, 0x0D, 0x06, 0x51, 0x08, 0x09, 0x54, 0x53, 0x00, 0x0D,
|
||||
0x01, 0x02, 0x03, 0x54, 0x53, 0x01, 0x05, 0x03, 0x08, 0x56, 0x54, 0x07, 0x02, 0x54, 0x0B, 0x06,
|
||||
0xA6, 0x23, 0xF4, 0xFE }; // these last 4 bytes always differ :)
|
||||
writeBytes( pv_array, sizeof(pv_array) );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Game_ProtocolVersion::read_protoVer( unsigned int *pver )
|
||||
{
|
||||
if( !pver || !(this->canReadBytes(5)) ) return false;
|
||||
(*pver) = 0;
|
||||
this->readReset();
|
||||
this->readUChar();
|
||||
(*pver) = this->readUInt();
|
||||
return true;
|
||||
}
|
22
l2packets/game/client/L2Game_ProtocolVersion.h
Normal file
22
l2packets/game/client/L2Game_ProtocolVersion.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef L2GAME_PROTOCOLVERSION_H_
|
||||
#define L2GAME_PROTOCOLVERSION_H_
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
class L2Game_ProtocolVersion : public L2GamePacket
|
||||
{
|
||||
public:
|
||||
L2Game_ProtocolVersion();
|
||||
L2Game_ProtocolVersion( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
bool createDefaultKamael( unsigned int gameProtoVer = 828 );
|
||||
bool createDefaultHellbound( unsigned int gameProtoVer = 851 );
|
||||
bool createDefaultGracia1( unsigned int gameProtoVer = 12 );
|
||||
bool createDefaultGracia2( unsigned int gameProtoVer = 17 );
|
||||
bool createDefaultGracia3( unsigned int gameProtoVer = 83 );
|
||||
bool createDefaultGracia4( unsigned int gameProtoVer = 146 );
|
||||
bool read_protoVer( unsigned int *pver );
|
||||
};
|
||||
|
||||
#endif /*L2GAME_PROTOCOLVERSION_H_*/
|
30
l2packets/game/client/L2Game_RequestGotoLobby.cpp
Normal file
30
l2packets/game/client/L2Game_RequestGotoLobby.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_RequestGotoLobby.h"
|
||||
|
||||
L2Game_RequestGotoLobby::L2Game_RequestGotoLobby()
|
||||
{
|
||||
this->_initNull();
|
||||
}
|
||||
|
||||
L2Game_RequestGotoLobby::L2Game_RequestGotoLobby( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Game_RequestGotoLobby::create( L2_VERSION ver )
|
||||
{
|
||||
if( ver <= L2_VERSION_T22 ) setPacketType2( 0xD0, 0x0039 );
|
||||
if( ver >= L2_VERSION_T23 ) setPacketType2( 0xD0, 0x0036 );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Game_RequestGotoLobby::parse( L2_VERSION ver )
|
||||
{
|
||||
if( getPacketType() != 0xD0 ) return false;
|
||||
if( ver <= L2_VERSION_T22 )
|
||||
if( readUShort() != 0x0039 ) return false;
|
||||
if( ver >= L2_VERSION_T23 )
|
||||
if( readUShort() != 0x0036 ) return false;
|
||||
return true;
|
||||
}
|
16
l2packets/game/client/L2Game_RequestGotoLobby.h
Normal file
16
l2packets/game/client/L2Game_RequestGotoLobby.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef L2GAME_REQEUSTGOTOLOBBY_H_
|
||||
#define L2GAME_REQUESTGOTOLOBBY_H_
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
class L2Game_RequestGotoLobby : public L2GamePacket
|
||||
{
|
||||
public:
|
||||
L2Game_RequestGotoLobby();
|
||||
L2Game_RequestGotoLobby( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
bool parse( L2_VERSION ver = L2_VERSION_T1 );
|
||||
};
|
||||
|
||||
#endif /*L2GAME_CHARACTERSELECT_H_*/
|
44
l2packets/game/client/L2Game_RequestJoinParty.cpp
Normal file
44
l2packets/game/client/L2Game_RequestJoinParty.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_RequestJoinParty.h"
|
||||
|
||||
/* L2J:
|
||||
Client: Len 15
|
||||
0F 00
|
||||
42
|
||||
6C 00 6F 00 6C 00 00 00 // target char name
|
||||
00 00 00 00 // loot type, item distribution
|
||||
*/
|
||||
|
||||
L2Game_RequestJoinParty::L2Game_RequestJoinParty()
|
||||
{
|
||||
this->_initNull();
|
||||
}
|
||||
|
||||
L2Game_RequestJoinParty::L2Game_RequestJoinParty( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Game_RequestJoinParty::create( const wchar_t *invitePlayer, unsigned int lootRule )
|
||||
{
|
||||
if( !invitePlayer ) return false;
|
||||
writeReset();
|
||||
writeUChar( 0x42 );
|
||||
writeUnicodeString( invitePlayer );
|
||||
writeUInt( lootRule );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Game_RequestJoinParty::read_invitePlayer( wchar_t *out )
|
||||
{
|
||||
if( !out ) return false;
|
||||
readReset();
|
||||
wcscpy( out, readUnicodeStringPtr() );
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int L2Game_RequestJoinParty::read_lootRule()
|
||||
{
|
||||
return readUInt();
|
||||
}
|
30
l2packets/game/client/L2Game_RequestJoinParty.h
Normal file
30
l2packets/game/client/L2Game_RequestJoinParty.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef L2GAME_REQUESTJOINPARY_H_
|
||||
#define L2GAME_REQUESTJOINPARY_H_
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
#define L2_PARTY_LOOT_ITEM_LOOTER 0
|
||||
#define L2_PARTY_LOOT_ITEM_RANDOM 1
|
||||
#define L2_PARTY_LOOT_ITEM_RANDOM_SPOIL 2
|
||||
#define L2_PARTY_LOOT_ITEM_ORDER 3
|
||||
#define L2_PARTY_LOOT_ITEM_ORDER_SPOIL 4
|
||||
|
||||
class L2Game_RequestJoinParty: public L2GamePacket
|
||||
{
|
||||
public:
|
||||
static const unsigned int ITEM_LOOTER = 0;
|
||||
static const unsigned int ITEM_RANDOM = 1;
|
||||
static const unsigned int ITEM_RANDOM_SPOIL = 2;
|
||||
static const unsigned int ITEM_ORDER = 3;
|
||||
static const unsigned int ITEM_ORDER_SPOIL = 4;
|
||||
public:
|
||||
L2Game_RequestJoinParty();
|
||||
L2Game_RequestJoinParty( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
bool create( const wchar_t *invitePlayer, unsigned int lootRule );
|
||||
public:
|
||||
bool read_invitePlayer( wchar_t *out );
|
||||
unsigned int read_lootRule();
|
||||
};
|
||||
|
||||
#endif
|
56
l2packets/game/client/L2Game_RequestUserCommand.cpp
Normal file
56
l2packets/game/client/L2Game_RequestUserCommand.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_RequestUserCommand.h"
|
||||
|
||||
/* L2J:
|
||||
Client Len 7 [ RequestUserCommand]
|
||||
07 00
|
||||
B3
|
||||
00 00 00 00 // command ID
|
||||
|
||||
================================
|
||||
|
||||
Decimal command numbers:
|
||||
|
||||
0 - /loc
|
||||
52 - /unstuck (Escape)
|
||||
61 - /Mount
|
||||
62 - /DisMount
|
||||
77 - /time
|
||||
81 - /partyinfo
|
||||
88 - /AttackList
|
||||
89 - /underattacklist
|
||||
90 - /warlist
|
||||
93 - /ChannelDelete
|
||||
96 - /ChannelLeave
|
||||
97 - /ChannelListUpdate
|
||||
100 - /ClanPenalty
|
||||
109 - /OlympiadStat
|
||||
114 - /InstanceZone
|
||||
*/
|
||||
|
||||
L2Game_RequestUserCommand::L2Game_RequestUserCommand()
|
||||
{
|
||||
this->_initNull();
|
||||
}
|
||||
|
||||
L2Game_RequestUserCommand::L2Game_RequestUserCommand( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Game_RequestUserCommand::create( unsigned int commandID )
|
||||
{
|
||||
writeReset();
|
||||
writeUChar( 0xB3 );
|
||||
writeUInt( commandID );
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int L2Game_RequestUserCommand::read_commandID()
|
||||
{
|
||||
readReset();
|
||||
getPacketType();
|
||||
return readUInt();
|
||||
}
|
||||
|
33
l2packets/game/client/L2Game_RequestUserCommand.h
Normal file
33
l2packets/game/client/L2Game_RequestUserCommand.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef L2GAME_REQUESTUSERCOMMAND_H_
|
||||
#define L2GAME_REQUESTUSERCOMMAND_H_
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
class L2Game_RequestUserCommand: public L2GamePacket
|
||||
{
|
||||
public:
|
||||
static const unsigned int CMD_LOC = 0;
|
||||
static const unsigned int CMD_UNSTUCK = 52;
|
||||
static const unsigned int CMD_MOUNT = 61;
|
||||
static const unsigned int CMD_DISMOUNT = 62;
|
||||
static const unsigned int CMD_TIME = 77;
|
||||
static const unsigned int CMD_PARTYINFO = 81;
|
||||
static const unsigned int CMD_ATTACKLIST = 88;
|
||||
static const unsigned int CMD_UNDERATTACKLIST = 89;
|
||||
static const unsigned int CMD_WARLIST = 90;
|
||||
static const unsigned int CMD_CHANNELDELETE = 93;
|
||||
static const unsigned int CMD_CHANNELLEAVE = 96;
|
||||
static const unsigned int CMD_CHANNELLISTUPDATE = 97;
|
||||
static const unsigned int CMD_CLANPENALTY = 100;
|
||||
static const unsigned int CMD_OLYMPIADSTAT = 109;
|
||||
static const unsigned int CMD_INSTANCEZONE = 114;
|
||||
public:
|
||||
L2Game_RequestUserCommand();
|
||||
L2Game_RequestUserCommand( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
bool create( unsigned int commandID );
|
||||
public:
|
||||
unsigned int read_commandID();
|
||||
};
|
||||
|
||||
#endif
|
37
l2packets/game/client/L2Game_UseItem.cpp
Normal file
37
l2packets/game/client/L2Game_UseItem.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_UseItem.h"
|
||||
|
||||
/*
|
||||
0B 00 // len 11
|
||||
19 // ptype - UseItem
|
||||
57 EA 03 10 // objectID? 268692055
|
||||
00 00 00 00 // wtf nulls?
|
||||
*/
|
||||
|
||||
L2Game_UseItem::L2Game_UseItem()
|
||||
{
|
||||
this->_initNull();
|
||||
}
|
||||
|
||||
L2Game_UseItem::L2Game_UseItem( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Game_UseItem::create( unsigned int oid )
|
||||
{
|
||||
this->writeReset();
|
||||
this->writeUChar( 0x19 ); // packet type - UseItem
|
||||
this->writeUInt( oid );
|
||||
this->writeUInt( 0x00000000 );
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int L2Game_UseItem::read_objectID()
|
||||
{
|
||||
if( !(this->canReadBytes(5)) ) return 0;
|
||||
this->readReset();
|
||||
this->readUChar(); // pcode
|
||||
return this->readUInt();
|
||||
}
|
17
l2packets/game/client/L2Game_UseItem.h
Normal file
17
l2packets/game/client/L2Game_UseItem.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef L2GAME_USEITEM_H_
|
||||
#define L2GAME_USEITEM_H_
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
class L2Game_UseItem: public L2GamePacket
|
||||
{
|
||||
public:
|
||||
L2Game_UseItem();
|
||||
L2Game_UseItem( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
bool create( unsigned int oid );
|
||||
public:
|
||||
unsigned int read_objectID();
|
||||
};
|
||||
|
||||
#endif
|
49
l2packets/game/server/L2Game_AuthLoginFail.cpp
Normal file
49
l2packets/game/server/L2Game_AuthLoginFail.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_AuthLoginFail.h"
|
||||
|
||||
L2Game_AuthLoginFail::L2Game_AuthLoginFail()
|
||||
{
|
||||
_initNull();
|
||||
}
|
||||
|
||||
L2Game_AuthLoginFail::L2Game_AuthLoginFail( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
_initNull();
|
||||
setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Game_AuthLoginFail::parse( L2_VERSION ver )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
if( getPacketType() != 0x0A ) return false;
|
||||
p_reasonCode = readUInt();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Game_AuthLoginFail::create( L2_VERSION ver )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
setPacketType( 0x0A );
|
||||
writeUInt( p_reasonCode );
|
||||
return true;
|
||||
}
|
||||
|
||||
void L2Game_AuthLoginFail::reasonCodeToString( int code, char *outString )
|
||||
{
|
||||
switch( code )
|
||||
{
|
||||
case REASON_NO_TEXT: strcpy( outString, "REASON_NO_TEXT" ); break;
|
||||
case REASON_SYSTEM_ERROR_LOGIN_LATER: strcpy( outString, "REASON_SYSTEM_ERROR_LOGIN_LATER" ); break;
|
||||
case REASON_PASSWORD_DOES_NOT_MATCH_THIS_ACCOUNT: strcpy( outString, "REASON_PASSWORD_DOES_NOT_MATCH_THIS_ACCOUNT" ); break;
|
||||
case REASON_PASSWORD_DOES_NOT_MATCH_THIS_ACCOUNT2: strcpy( outString, "REASON_PASSWORD_DOES_NOT_MATCH_THIS_ACCOUNT2" ); break;
|
||||
case REASON_ACCESS_FAILED_TRY_LATER: strcpy( outString, "REASON_ACCESS_FAILED_TRY_LATER" ); break;
|
||||
case REASON_INCORRECT_ACCOUNT_INFO_CONTACT_CUSTOMER_SUPPORT: strcpy( outString, "REASON_INCORRECT_ACCOUNT_INFO_CONTACT_CUSTOMER_SUPPORT" ); break;
|
||||
case REASON_ACCESS_FAILED_TRY_LATER2: strcpy( outString, "REASON_ACCESS_FAILED_TRY_LATER2" ); break;
|
||||
case REASON_ACOUNT_ALREADY_IN_USE: strcpy( outString, "REASON_ACOUNT_ALREADY_IN_USE" ); break;
|
||||
case REASON_ACCESS_FAILED_TRY_LATER3: strcpy( outString, "REASON_ACCESS_FAILED_TRY_LATER3" ); break;
|
||||
case REASON_ACCESS_FAILED_TRY_LATER4: strcpy( outString, "REASON_ACCESS_FAILED_TRY_LATER4" ); break;
|
||||
case REASON_ACCESS_FAILED_TRY_LATER5: strcpy( outString, "REASON_ACCESS_FAILED_TRY_LATER5" ); break;
|
||||
default: strcpy( outString, "REASON_UNKNOWN" ); break;
|
||||
}
|
||||
}
|
||||
|
32
l2packets/game/server/L2Game_AuthLoginFail.h
Normal file
32
l2packets/game/server/L2Game_AuthLoginFail.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef L2GAME_AUTHLOGINFAIL_H_
|
||||
#define L2GAME_AUTHLOGINFAIL_H_
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
class L2Game_AuthLoginFail: public L2GamePacket
|
||||
{
|
||||
public:
|
||||
static const int REASON_NO_TEXT = 0;
|
||||
static const int REASON_SYSTEM_ERROR_LOGIN_LATER = 1;
|
||||
static const int REASON_PASSWORD_DOES_NOT_MATCH_THIS_ACCOUNT = 2;
|
||||
static const int REASON_PASSWORD_DOES_NOT_MATCH_THIS_ACCOUNT2 = 3;
|
||||
static const int REASON_ACCESS_FAILED_TRY_LATER = 4;
|
||||
static const int REASON_INCORRECT_ACCOUNT_INFO_CONTACT_CUSTOMER_SUPPORT = 5;
|
||||
static const int REASON_ACCESS_FAILED_TRY_LATER2 = 6;
|
||||
static const int REASON_ACOUNT_ALREADY_IN_USE = 7;
|
||||
static const int REASON_ACCESS_FAILED_TRY_LATER3 = 8;
|
||||
static const int REASON_ACCESS_FAILED_TRY_LATER4 = 9;
|
||||
static const int REASON_ACCESS_FAILED_TRY_LATER5 = 10;
|
||||
public:
|
||||
L2Game_AuthLoginFail();
|
||||
L2Game_AuthLoginFail( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
virtual bool parse( L2_VERSION ver = L2_VERSION_T1 );
|
||||
virtual bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
public:
|
||||
static void reasonCodeToString( int code, char *outString );
|
||||
public:
|
||||
unsigned int p_reasonCode;
|
||||
};
|
||||
|
||||
#endif
|
42
l2packets/game/server/L2Game_CharCreateFail.cpp
Normal file
42
l2packets/game/server/L2Game_CharCreateFail.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_CharCreateFail.h"
|
||||
|
||||
L2Game_CharCreateFail::L2Game_CharCreateFail()
|
||||
{
|
||||
_initNull();
|
||||
}
|
||||
|
||||
L2Game_CharCreateFail::L2Game_CharCreateFail( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
_initNull();
|
||||
setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Game_CharCreateFail::parse( L2_VERSION ver )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
if( getPacketType() != 0x10 ) return false;
|
||||
p_reasonCode = readUInt();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Game_CharCreateFail::create( L2_VERSION ver )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
setPacketType( 0x10 );
|
||||
writeUInt( p_reasonCode );
|
||||
return true;
|
||||
}
|
||||
|
||||
void L2Game_CharCreateFail::reasonCodeToString( int code, char *outString )
|
||||
{
|
||||
switch( code )
|
||||
{
|
||||
case REASON_CREATION_FAILED: strcpy( outString, "REASON_CREATION_FAILED" ); break;
|
||||
case REASON_TOO_MANY_CHARACTERS: strcpy( outString, "REASON_TOO_MANY_CHARACTERS" ); break;
|
||||
case REASON_NAME_ALREADY_EXISTS: strcpy( outString, "REASON_NAME_ALREADY_EXISTS" ); break;
|
||||
case REASON_16_ENG_CHARS: strcpy( outString, "REASON_16_ENG_CHARS" ); break;
|
||||
default: strcpy( outString, "REASON_UNKNOWN" ); break;
|
||||
}
|
||||
}
|
||||
|
28
l2packets/game/server/L2Game_CharCreateFail.h
Normal file
28
l2packets/game/server/L2Game_CharCreateFail.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef L2GAME_CHARCREATEFAIL_H_
|
||||
#define L2GAME_CHARCREATEFAIL_H_
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
class L2Game_CharCreateFail: public L2GamePacket
|
||||
{
|
||||
public:
|
||||
static const int REASON_CREATION_FAILED = 0x00;
|
||||
static const int REASON_TOO_MANY_CHARACTERS = 0x01;
|
||||
static const int REASON_NAME_ALREADY_EXISTS = 0x02;
|
||||
static const int REASON_16_ENG_CHARS = 0x03;
|
||||
static const int REASON_INCORRECT_NAME = 0x04;
|
||||
static const int REASON_CREATE_NOT_ALLOWED = 0x05;
|
||||
static const int REASON_CHOOSE_ANOTHER_SVR = 0x06;
|
||||
public:
|
||||
L2Game_CharCreateFail();
|
||||
L2Game_CharCreateFail( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
virtual bool parse( L2_VERSION ver = L2_VERSION_T1 );
|
||||
virtual bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
public:
|
||||
static void reasonCodeToString( int code, char *outString );
|
||||
public:
|
||||
unsigned int p_reasonCode;
|
||||
};
|
||||
|
||||
#endif
|
30
l2packets/game/server/L2Game_CharCreateSuccess.cpp
Normal file
30
l2packets/game/server/L2Game_CharCreateSuccess.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_CharCreateSuccess.h"
|
||||
|
||||
L2Game_CharCreateSuccess::L2Game_CharCreateSuccess()
|
||||
{
|
||||
_initNull();
|
||||
}
|
||||
|
||||
L2Game_CharCreateSuccess::L2Game_CharCreateSuccess( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
_initNull();
|
||||
setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Game_CharCreateSuccess::parse( L2_VERSION ver )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
if( getPacketType() != 0x0F ) return false;
|
||||
if( readUInt() != 0x01 ) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Game_CharCreateSuccess::create( L2_VERSION ver )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
setPacketType( 0x0F );
|
||||
writeUInt( 0x01 );
|
||||
return true;
|
||||
}
|
||||
|
16
l2packets/game/server/L2Game_CharCreateSuccess.h
Normal file
16
l2packets/game/server/L2Game_CharCreateSuccess.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef L2GAME_CHARCREATEOK_H_
|
||||
#define L2GAME_CHARCREATEOK_H_
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
class L2Game_CharCreateSuccess: public L2GamePacket
|
||||
{
|
||||
public:
|
||||
L2Game_CharCreateSuccess();
|
||||
L2Game_CharCreateSuccess( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
virtual bool parse( L2_VERSION ver = L2_VERSION_T1 );
|
||||
virtual bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
};
|
||||
|
||||
#endif
|
41
l2packets/game/server/L2Game_CharDeleteFail.cpp
Normal file
41
l2packets/game/server/L2Game_CharDeleteFail.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_CharDeleteFail.h"
|
||||
|
||||
L2Game_CharDeleteFail::L2Game_CharDeleteFail()
|
||||
{
|
||||
_initNull();
|
||||
}
|
||||
|
||||
L2Game_CharDeleteFail::L2Game_CharDeleteFail( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
_initNull();
|
||||
setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Game_CharDeleteFail::parse( L2_VERSION ver )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
if( getPacketType() != 0x1E ) return false;
|
||||
p_reasonCode = readUInt();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Game_CharDeleteFail::create( L2_VERSION ver )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
setPacketType( 0x1E );
|
||||
writeUInt( p_reasonCode );
|
||||
return true;
|
||||
}
|
||||
|
||||
void L2Game_CharDeleteFail::reasonCodeToString( int code, char *outString )
|
||||
{
|
||||
switch( code )
|
||||
{
|
||||
case REASON_DELETION_FAILED: strcpy( outString, "REASON_DELETION_FAILED" ); break;
|
||||
case REASON_YOU_MAY_NOT_DELETE_CLAN_MEMBER: strcpy( outString, "REASON_YOU_MAY_NOT_DELETE_CLAN_MEMBER" ); break;
|
||||
case REASON_CLAN_LEADERS_MAY_NOT_BE_DELETED: strcpy( outString, "REASON_CLAN_LEADERS_MAY_NOT_BE_DELETED" ); break;
|
||||
default: strcpy( outString, "REASON_UNKNOWN" ); break;
|
||||
}
|
||||
}
|
||||
|
24
l2packets/game/server/L2Game_CharDeleteFail.h
Normal file
24
l2packets/game/server/L2Game_CharDeleteFail.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef L2GAME_CHARDELETEFAIL_H_
|
||||
#define L2GAME_CHARDELETEFAIL_H_
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
class L2Game_CharDeleteFail: public L2GamePacket
|
||||
{
|
||||
public:
|
||||
static const int REASON_DELETION_FAILED = 0x01;
|
||||
static const int REASON_YOU_MAY_NOT_DELETE_CLAN_MEMBER = 0x02;
|
||||
static const int REASON_CLAN_LEADERS_MAY_NOT_BE_DELETED = 0x03;
|
||||
public:
|
||||
L2Game_CharDeleteFail();
|
||||
L2Game_CharDeleteFail( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
virtual bool parse( L2_VERSION ver = L2_VERSION_T1 );
|
||||
virtual bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
public:
|
||||
static void reasonCodeToString( int code, char *outString );
|
||||
public:
|
||||
unsigned int p_reasonCode;
|
||||
};
|
||||
|
||||
#endif
|
16
l2packets/game/server/L2Game_CharDeleteSuccess.cpp
Normal file
16
l2packets/game/server/L2Game_CharDeleteSuccess.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_CharDeleteSuccess.h"
|
||||
|
||||
L2Game_CharDeleteSuccess::L2Game_CharDeleteSuccess()
|
||||
{
|
||||
_initNull();
|
||||
}
|
||||
|
||||
L2Game_CharDeleteSuccess::L2Game_CharDeleteSuccess( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
_initNull();
|
||||
setBytes( bytes, length );
|
||||
}
|
||||
|
||||
|
||||
|
14
l2packets/game/server/L2Game_CharDeleteSuccess.h
Normal file
14
l2packets/game/server/L2Game_CharDeleteSuccess.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef L2GAME_CHARDELETESUCCESS_H_
|
||||
#define L2GAME_CHARDELETESUCCESS_H_
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
class L2Game_CharDeleteSuccess: public L2GamePacket
|
||||
{
|
||||
public:
|
||||
L2Game_CharDeleteSuccess();
|
||||
L2Game_CharDeleteSuccess( const unsigned char *bytes, unsigned int length );
|
||||
// nothing to parse - just trigger
|
||||
};
|
||||
|
||||
#endif
|
124
l2packets/game/server/L2Game_CharSelected.cpp
Normal file
124
l2packets/game/server/L2Game_CharSelected.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_CharSelected.h"
|
||||
|
||||
L2Game_CharSelected::L2Game_CharSelected()
|
||||
{
|
||||
_initNull();
|
||||
}
|
||||
|
||||
L2Game_CharSelected::L2Game_CharSelected( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
_initNull();
|
||||
setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Game_CharSelected::parse( L2_VERSION ver /*= L2_VERSION_T1*/ )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
if( !this->canReadBytes( 200 ) ) return false; // must be at least 200 bytes
|
||||
|
||||
readReset();
|
||||
readUChar(); // 0x0b CharSelected
|
||||
|
||||
wcscpy( p_char_name, readUnicodeStringPtr() ); // char name
|
||||
p_charId = readUInt(); // char id (objectId)
|
||||
wcscpy( p_title, readUnicodeStringPtr() ); // title
|
||||
p_sessionId = readUInt(); // sessionId
|
||||
p_clanId = readUInt(); // clanId
|
||||
readD(); // 0x00 (maybe allyId?)
|
||||
p_sex = readD();
|
||||
p_race = readD();
|
||||
p_classId = readUInt();
|
||||
p_isActive = readD();
|
||||
|
||||
p_x = readD();
|
||||
p_y = readD();
|
||||
p_z = readD();
|
||||
|
||||
p_curHp = readF();
|
||||
p_curMp = readF();
|
||||
p_sp = readUInt();
|
||||
p_exp = readUInt64();
|
||||
p_level = readD();
|
||||
p_karma = readD();
|
||||
p_PK_kills = readD();
|
||||
|
||||
p_INT = readD();
|
||||
p_STR = readD();
|
||||
p_CON = readD();
|
||||
p_MEN = readD();
|
||||
p_DEX = readD();
|
||||
p_WIT = readD();
|
||||
|
||||
readD(); // writeD( 0x0451 ); // game time?
|
||||
readD(); // writeD( 0x00 ); // 0x00
|
||||
|
||||
readD(); // writeD( classId ); // classId already read?
|
||||
|
||||
//writeD(0x00); // 4 x 0x00
|
||||
//writeD(0x00);
|
||||
//writeD(0x00);
|
||||
//writeD(0x00);
|
||||
readD(); readD(); readD(); readD();
|
||||
|
||||
//writeB(new byte[64]); // some 64 bytes
|
||||
int i;
|
||||
for( i=0; i<16; i++ ) readD(); // read 4 x 16 = 64 bytes
|
||||
|
||||
p_opcodeObfuscatorSeed = readUInt();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Game_CharSelected::create( L2_VERSION ver /*= L2_VERSION_T1*/ )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
writeReset();
|
||||
writeC(0x0b);
|
||||
|
||||
writeS( p_char_name );
|
||||
writeD( p_charId );
|
||||
writeS( p_title );
|
||||
writeD( p_sessionId ); // playOkID1
|
||||
writeD( p_clanId );
|
||||
writeD( 0x00 ); // maybe allyId?
|
||||
writeD( p_sex );
|
||||
writeD( p_race );
|
||||
writeD( p_classId );
|
||||
writeD( p_isActive ); // active ??
|
||||
|
||||
writeD( p_x );
|
||||
writeD( p_y );
|
||||
writeD( p_z );
|
||||
|
||||
writeF( p_curHp );
|
||||
writeF( p_curMp );
|
||||
writeD( p_sp );
|
||||
writeQ( p_exp );
|
||||
writeD( p_level );
|
||||
writeD( p_karma );
|
||||
writeD( p_PK_kills );
|
||||
writeD( p_INT );
|
||||
writeD( p_STR );
|
||||
writeD( p_CON );
|
||||
writeD( p_MEN );
|
||||
writeD( p_DEX );
|
||||
writeD( p_WIT );
|
||||
|
||||
writeD( 0x0451 ); //?
|
||||
writeD( 0x00 ); // some constants
|
||||
|
||||
writeD( p_classId );
|
||||
|
||||
writeD(0x00); // 4 x 0x00
|
||||
writeD(0x00);
|
||||
writeD(0x00);
|
||||
writeD(0x00);
|
||||
|
||||
//writeB(new byte[64]); // some 64 bytes
|
||||
unsigned char *rndbuf = (unsigned char *)malloc( 64 );
|
||||
writeBytes( rndbuf, 64 );
|
||||
free( rndbuf );
|
||||
|
||||
writeD( p_opcodeObfuscatorSeed ); // writeD(0x00);
|
||||
return true;
|
||||
}
|
43
l2packets/game/server/L2Game_CharSelected.h
Normal file
43
l2packets/game/server/L2Game_CharSelected.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef L2GAME_CHARSELECTED_H_
|
||||
#define L2GAME_CHARSELECTED_H_
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
class L2Game_CharSelected : public L2GamePacket
|
||||
{
|
||||
public:
|
||||
L2Game_CharSelected();
|
||||
L2Game_CharSelected( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
virtual bool parse( L2_VERSION ver = L2_VERSION_T1 );
|
||||
virtual bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
public:
|
||||
wchar_t p_char_name[128]; // char name
|
||||
unsigned int p_charId; // char id (objectId)
|
||||
wchar_t p_title[128]; // title (empty here)
|
||||
unsigned int p_sessionId; // sessionId
|
||||
unsigned int p_clanId; // clan id
|
||||
int p_sex; // sex
|
||||
int p_race; // race 0x01 - elf
|
||||
unsigned int p_classId; // class Id
|
||||
int p_isActive; // is Active
|
||||
int p_x;
|
||||
int p_y;
|
||||
int p_z;
|
||||
double p_curHp; // currentHp
|
||||
double p_curMp; // currentMp
|
||||
unsigned int p_sp; // sp
|
||||
unsigned long long int p_exp; // exp
|
||||
int p_level; // level (64)
|
||||
int p_karma; // karma
|
||||
int p_PK_kills; // PK kills
|
||||
int p_INT; // INT
|
||||
int p_STR; // STR
|
||||
int p_CON; // CON
|
||||
int p_MEN; // MEN
|
||||
int p_DEX; // DEX
|
||||
int p_WIT; // WIT
|
||||
unsigned int p_opcodeObfuscatorSeed; // opcode obfuscator seed
|
||||
};
|
||||
|
||||
#endif
|
109
l2packets/game/server/L2Game_CharSelectionInfo.cpp
Normal file
109
l2packets/game/server/L2Game_CharSelectionInfo.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_CharSelectionInfo.h"
|
||||
|
||||
L2Game_CharSelectionInfo::L2Game_CharSelectionInfo()
|
||||
{
|
||||
this->_initNull();
|
||||
}
|
||||
|
||||
L2Game_CharSelectionInfo::L2Game_CharSelectionInfo( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Game_CharSelectionInfo::read_nChars( unsigned int *ret )
|
||||
{
|
||||
if( !ret ) return false;
|
||||
this->readReset();
|
||||
if( !this->canReadBytes(10) ) return false;
|
||||
this->readUChar(); // pcode
|
||||
(*ret) = this->readUInt();
|
||||
return true;
|
||||
}
|
||||
|
||||
// ret can be NULL
|
||||
bool L2Game_CharSelectionInfo::read_server_maxChars( unsigned int *ret )
|
||||
{
|
||||
if( !ret ) return false;
|
||||
this->readReset();
|
||||
if( !this->canReadBytes(10) ) return false;
|
||||
this->readUChar(); // pcode
|
||||
this->readUInt(); // nChars
|
||||
if( ret ) (*ret) = this->readUInt();
|
||||
this->readUChar(); // read 0x00
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Game_CharSelectionInfo::read_next_charSelectInfoBlock( L2_VERSION l2_version,
|
||||
struct L2Game_CharSelectionInfoBlock *c )
|
||||
{
|
||||
if( !c ) return false;
|
||||
memset( c, 0, sizeof(L2Game_CharSelectionInfoBlock) );
|
||||
// TODO: how to detect that packet may be incorrect?
|
||||
// char info must be AT LEAST 280 bytes long (Hellbound)
|
||||
if( !this->canReadBytes(280) ) return false;
|
||||
const wchar_t *wstr = NULL;
|
||||
int i = 0;
|
||||
wstr = this->readUnicodeStringPtr();
|
||||
if( !wstr ) return false;
|
||||
wcsncpy( c->charName, wstr, 31 );
|
||||
c->charID = this->readUInt();
|
||||
wstr = this->readUnicodeStringPtr();
|
||||
if( !wstr ) return false;
|
||||
wcsncpy( c->accountName, wstr, 31 );
|
||||
c->sessionID = readUInt();
|
||||
c->clanID = readUInt();
|
||||
readUInt(); // 0x00
|
||||
c->sex = readUInt();
|
||||
c->race = readUInt();
|
||||
c->baseClassID = readUInt();
|
||||
c->isActive = readUInt();
|
||||
c->x = readInt();
|
||||
c->y = readInt();
|
||||
c->z = readInt();
|
||||
c->HP_cur = readDouble();
|
||||
c->MP_cur = readDouble();
|
||||
c->SP = readUInt();
|
||||
c->Exp = readUInt64();
|
||||
c->level = readUInt();
|
||||
c->karma = readUInt();
|
||||
c->PK_kills = readUInt();
|
||||
c->PVP_kills = readUInt();
|
||||
for( i=0; i<7; i++ ) readUInt(); // 7 0x00
|
||||
c->iid_hair_all = readUInt();
|
||||
c->iid_R_ear = readUInt();
|
||||
c->iid_L_ear = readUInt();
|
||||
c->iid_neck = readUInt();
|
||||
c->iid_R_finger = readUInt();
|
||||
c->iid_L_finger = readUInt();
|
||||
c->iid_head = readUInt();
|
||||
c->iid_R_hand = readUInt();
|
||||
c->iid_L_hand = readUInt();
|
||||
c->iid_gloves = readUInt();
|
||||
c->iid_chest = readUInt();
|
||||
c->iid_legs = readUInt();
|
||||
c->iid_feet = readUInt();
|
||||
c->iid_back = readUInt();
|
||||
c->iid_LR_hand = readUInt();
|
||||
c->iid_hair = readUInt();
|
||||
c->iid_hair_2 = readUInt();
|
||||
c->iid_R_bracelet = readUInt();
|
||||
c->iid_L_bracelet = readUInt();
|
||||
for( i=0; i<6; i++ ) readUInt(); // DECO1 .. DECO6
|
||||
if( l2_version >= L2_VERSION_T23 )
|
||||
c->iid_belt = readUInt(); // Gracia Final T2.3
|
||||
c->hairStyle = readUInt();
|
||||
c->hairColor = readUInt();
|
||||
c->face = readUInt();
|
||||
c->HP_max = readDouble();
|
||||
c->MP_max = readDouble();
|
||||
c->deleteSeconds = readUInt();
|
||||
c->classID = readUInt();
|
||||
c->lastUsedChar = readUInt();
|
||||
c->enchantEffect = readUChar();
|
||||
c->augmentID = readUShort();
|
||||
c->augmentSmth = readUShort();
|
||||
c->transformID = readUInt();
|
||||
return true;
|
||||
}
|
74
l2packets/game/server/L2Game_CharSelectionInfo.h
Normal file
74
l2packets/game/server/L2Game_CharSelectionInfo.h
Normal file
@@ -0,0 +1,74 @@
|
||||
#ifndef L2GAME_CHARSELECTIONINFO_H_
|
||||
#define L2GAME_CHARSELECTIONINFO_H_
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
struct L2Game_CharSelectionInfoBlock
|
||||
{
|
||||
wchar_t charName[32];
|
||||
unsigned int charID;
|
||||
wchar_t accountName[32];
|
||||
unsigned int sessionID;
|
||||
unsigned int clanID;
|
||||
unsigned int sex;
|
||||
unsigned int race;
|
||||
unsigned int baseClassID;
|
||||
unsigned int isActive;
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
double HP_cur;
|
||||
double MP_cur;
|
||||
unsigned int SP;
|
||||
unsigned long long Exp;
|
||||
unsigned int level;
|
||||
unsigned int karma;
|
||||
unsigned int PK_kills;
|
||||
unsigned int PVP_kills;
|
||||
unsigned int iid_hair_all;
|
||||
unsigned int iid_R_ear;
|
||||
unsigned int iid_L_ear;
|
||||
unsigned int iid_neck;
|
||||
unsigned int iid_R_finger;
|
||||
unsigned int iid_L_finger;
|
||||
unsigned int iid_head;
|
||||
unsigned int iid_R_hand;
|
||||
unsigned int iid_L_hand;
|
||||
unsigned int iid_gloves;
|
||||
unsigned int iid_chest;
|
||||
unsigned int iid_legs;
|
||||
unsigned int iid_feet;
|
||||
unsigned int iid_back;
|
||||
unsigned int iid_LR_hand;
|
||||
unsigned int iid_hair;
|
||||
unsigned int iid_hair_2;
|
||||
unsigned int iid_R_bracelet;
|
||||
unsigned int iid_L_bracelet;
|
||||
unsigned int iid_belt; // T2.3
|
||||
unsigned int hairStyle;
|
||||
unsigned int hairColor;
|
||||
unsigned int face;
|
||||
double HP_max;
|
||||
double MP_max;
|
||||
unsigned int deleteSeconds; ///< seconds left before char will be deleted, or 0 if char is not marked to deletion
|
||||
unsigned int classID;
|
||||
unsigned int lastUsedChar;
|
||||
unsigned char enchantEffect;
|
||||
unsigned short int augmentID;
|
||||
unsigned short int augmentSmth;
|
||||
unsigned int transformID;
|
||||
};
|
||||
|
||||
class L2Game_CharSelectionInfo : public L2GamePacket
|
||||
{
|
||||
public:
|
||||
L2Game_CharSelectionInfo();
|
||||
L2Game_CharSelectionInfo( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
bool read_nChars( unsigned int *ret );
|
||||
bool read_server_maxChars( unsigned int *ret ); // ret can be NULL
|
||||
bool read_next_charSelectInfoBlock( L2_VERSION l2_version,
|
||||
struct L2Game_CharSelectionInfoBlock *c );
|
||||
};
|
||||
|
||||
#endif /*L2GAME_CHARSELECTIONINFO_H_*/
|
122
l2packets/game/server/L2Game_KeyPacket.cpp
Normal file
122
l2packets/game/server/L2Game_KeyPacket.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_KeyPacket.h"
|
||||
|
||||
/**
|
||||
* ==========================================
|
||||
Retail NCSoft
|
||||
19 00 // p.len 25
|
||||
2E // pcode
|
||||
01 // always const
|
||||
42 55 77 8F C3 05 69 87 // xorkey first part
|
||||
01 00 00 00 // always const
|
||||
01 // possible Game Server ID - depends on game server ID
|
||||
00 00 00 00 // always NULLs
|
||||
XX XX XX XX // always different, non-nulls: opcode obfuscator
|
||||
*/
|
||||
|
||||
L2Game_KeyPacket::L2Game_KeyPacket()
|
||||
{
|
||||
this->_initNull();
|
||||
}
|
||||
|
||||
L2Game_KeyPacket::L2Game_KeyPacket( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
// key must point to buffer large enough to hold 8 bytes
|
||||
bool L2Game_KeyPacket::read_key( unsigned char *key )
|
||||
{
|
||||
if( !key ) return false;
|
||||
this->readReset();
|
||||
if( this->canReadBytes(10) )
|
||||
{
|
||||
this->readUChar(); // packet type (0x0e in hellbound, 0x00 - interlude)
|
||||
this->readUChar(); // 0x01 ?
|
||||
return this->readBytes( key, 8 );
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
unsigned char L2Game_KeyPacket::read_GameServerID()
|
||||
{
|
||||
if( !this->canReadBytes(5) ) return 0x00;
|
||||
this->readUInt(); // 01 00 00 00 // always const
|
||||
return this->readUChar(); // 01 // possible Game Server ID
|
||||
}
|
||||
|
||||
unsigned int L2Game_KeyPacket::read_OpcodeObfuscator()
|
||||
{
|
||||
if( !this->canReadBytes(4) ) return 0x00000000;
|
||||
this->readUInt(); // 00 00 00 00 // always 0x00000000, read 4 NULLs
|
||||
return this->readUInt(); // XX XX XX XX // always different, opcode obfuscator
|
||||
}
|
||||
|
||||
// keyPacket array points to key bytes received from KeyPacket (8 bytes)
|
||||
// keyResult will hold resultig key (16 bytes)
|
||||
void L2Game_KeyPacket::createInitialHellboundKey(
|
||||
const unsigned char *keyPacket,
|
||||
unsigned char *keyResult )
|
||||
{
|
||||
if( !keyPacket || !keyResult ) return;
|
||||
// first 8 bytes of key are from KeyPacket
|
||||
keyResult[0] = keyPacket[0];
|
||||
keyResult[1] = keyPacket[1];
|
||||
keyResult[2] = keyPacket[2];
|
||||
keyResult[3] = keyPacket[3];
|
||||
keyResult[4] = keyPacket[4];
|
||||
keyResult[5] = keyPacket[5];
|
||||
keyResult[6] = keyPacket[6];
|
||||
keyResult[7] = keyPacket[7];
|
||||
// last 8 bytes are constant in T1/T1.5/T2/T2.2/T2.3...
|
||||
keyResult[8] = (unsigned char)0xc8;
|
||||
keyResult[9] = (unsigned char)0x27;
|
||||
keyResult[10] = (unsigned char)0x93;
|
||||
keyResult[11] = (unsigned char)0x01;
|
||||
keyResult[12] = (unsigned char)0xa1;
|
||||
keyResult[13] = (unsigned char)0x6c;
|
||||
keyResult[14] = (unsigned char)0x31;
|
||||
keyResult[15] = (unsigned char)0x97;
|
||||
}
|
||||
|
||||
/*** Format:
|
||||
19 00 // plen = 25
|
||||
2E // pcode
|
||||
01 // 00 - wrong proto, 01 - proto OK
|
||||
B6 4D 20 15 CE 0E BC 7A // 1st 8 bytes of crypto key
|
||||
01 00 00 00 // 0x01
|
||||
09 // game serverID
|
||||
00 00 00 00 // wtf?
|
||||
E3 D1 10 2F // obfuscation key ***/
|
||||
bool L2Game_KeyPacket::parse( L2_VERSION ver /*= L2_VERSION_T1*/ )
|
||||
{
|
||||
UNREFERENCED_PARAMETER( ver );
|
||||
readReset();
|
||||
if( !canReadBytes( 19 ) ) return false; // packet size is at least 19 bytes O_o
|
||||
getPacketType();
|
||||
this->p_protocolIsOK = readUChar(); // 0x01 - proto OK, 0x00 - proto not supported
|
||||
readBytes( this->p_initialKey, 8 ); // first 8 bytes of XOR key
|
||||
readD(); // 0x00000001
|
||||
this->p_serverId = readUChar(); // server ID
|
||||
readD(); // 0x00000000;
|
||||
this->p_obfuscatorSeed = readUInt(); // obfuscator seed
|
||||
// add last 8 bytes of XOR key - they are constant
|
||||
createInitialHellboundKey( p_initialKey, p_initialKey );
|
||||
//
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Game_KeyPacket::create( L2_VERSION ver )
|
||||
{
|
||||
UNREFERENCED_PARAMETER( ver );
|
||||
writeReset();
|
||||
setPacketType( 0x2E );
|
||||
writeUChar( p_protocolIsOK );
|
||||
writeBytes( p_initialKey, 8 );
|
||||
writeD( 1 );
|
||||
writeUChar( p_serverId );
|
||||
writeD( 0 );
|
||||
writeUInt( p_obfuscatorSeed );
|
||||
return true;
|
||||
}
|
32
l2packets/game/server/L2Game_KeyPacket.h
Normal file
32
l2packets/game/server/L2Game_KeyPacket.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef L2GAME_KEYPACKET_H_
|
||||
#define L2GAME_KEYPACKET_H_
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
class L2Game_KeyPacket : public L2GamePacket
|
||||
{
|
||||
public:
|
||||
L2Game_KeyPacket();
|
||||
L2Game_KeyPacket( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
// key must point to buffer large enough to hold 8 bytes
|
||||
bool read_key( unsigned char *key );
|
||||
unsigned char read_GameServerID();
|
||||
unsigned int read_OpcodeObfuscator();
|
||||
public:
|
||||
// keyPacket array points to key bytes received from KeyPacket (8 bytes)
|
||||
// keyResult will hold resultig key (16 bytes)
|
||||
static void createInitialHellboundKey(
|
||||
const unsigned char *keyPacket,
|
||||
unsigned char *keyResult );
|
||||
public:
|
||||
virtual bool parse( L2_VERSION ver = L2_VERSION_T1 );
|
||||
virtual bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
public:
|
||||
unsigned char p_protocolIsOK;
|
||||
unsigned char p_initialKey[16];
|
||||
unsigned char p_serverId;
|
||||
unsigned int p_obfuscatorSeed;
|
||||
};
|
||||
|
||||
#endif /*L2GAME_KEYPACKET_H_*/
|
80
l2packets/game/server/L2Game_NewCharacterSuccess.cpp
Normal file
80
l2packets/game/server/L2Game_NewCharacterSuccess.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_NewCharacterSuccess.h"
|
||||
|
||||
/*
|
||||
Server: Len 967 [NewCharacterSuccess]
|
||||
C7 03
|
||||
0D // opcode
|
||||
0C 00 00 00 // number of templates
|
||||
|
||||
// [ for each template ]
|
||||
|
||||
00 00 00 00 // race
|
||||
00 00 00 00 // class id
|
||||
46 00 00 00 // 0x46
|
||||
28 00 00 00 // base STR
|
||||
0A 00 00 00 // 0x0A
|
||||
46 00 00 00 // 0x46
|
||||
1E 00 00 00 // base DEX
|
||||
0A 00 00 00
|
||||
46 00 00 00
|
||||
2B 00 00 00 // base CON
|
||||
0A 00 00 00
|
||||
46 00 00 00
|
||||
15 00 00 00 // base INT
|
||||
0A 00 00 00
|
||||
46 00 00 00
|
||||
0B 00 00 00 // base WIT
|
||||
0A 00 00 00
|
||||
46 00 00 00
|
||||
19 00 00 00 // base MEN
|
||||
0A 00 00 00
|
||||
*/
|
||||
|
||||
L2Game_NewCharacterSuccess::L2Game_NewCharacterSuccess()
|
||||
{
|
||||
_initNull();
|
||||
}
|
||||
|
||||
L2Game_NewCharacterSuccess::L2Game_NewCharacterSuccess( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
_initNull();
|
||||
setBytes( bytes, length );
|
||||
}
|
||||
|
||||
int L2Game_NewCharacterSuccess::read_templatesCount()
|
||||
{
|
||||
readReset();
|
||||
getPacketType();
|
||||
return readInt();
|
||||
}
|
||||
|
||||
bool L2Game_NewCharacterSuccess::read_nextCharacterTemplate( struct L2Game_NewCharacterTemplate *t )
|
||||
{
|
||||
if( !t ) return false;
|
||||
// each template is 80 bytes length (20Ds)
|
||||
if( !canReadBytes( 80 ) ) return false;
|
||||
// read
|
||||
t->race = readD();
|
||||
t->classID = readD();
|
||||
readD(); // 0x46
|
||||
t->base_STR = readD();
|
||||
readD(); // 0x0A
|
||||
readD(); // 0x46
|
||||
t->base_DEX = readD();
|
||||
readD(); // 0x0A
|
||||
readD(); // 0x46
|
||||
t->base_CON = readD();
|
||||
readD(); // 0x0A
|
||||
readD(); // 0x46
|
||||
t->base_INT = readD();
|
||||
readD(); // 0x0A
|
||||
readD(); // 0x46
|
||||
t->base_WIT = readD();
|
||||
readD(); // 0x0A
|
||||
readD(); // 0x46
|
||||
t->base_MEN = readD();
|
||||
readD(); // 0x0A
|
||||
return true;
|
||||
}
|
||||
|
28
l2packets/game/server/L2Game_NewCharacterSuccess.h
Normal file
28
l2packets/game/server/L2Game_NewCharacterSuccess.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef H_L2GAME_NEWCHARACTERSUCCESS
|
||||
#define H_L2GAME_NEWCHARACTERSUCCESS
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
struct L2Game_NewCharacterTemplate
|
||||
{
|
||||
int race;
|
||||
int classID;
|
||||
int base_STR;
|
||||
int base_DEX;
|
||||
int base_CON;
|
||||
int base_INT;
|
||||
int base_WIT;
|
||||
int base_MEN;
|
||||
};
|
||||
|
||||
class L2Game_NewCharacterSuccess: public L2GamePacket
|
||||
{
|
||||
public:
|
||||
L2Game_NewCharacterSuccess();
|
||||
L2Game_NewCharacterSuccess( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
int read_templatesCount();
|
||||
bool read_nextCharacterTemplate( struct L2Game_NewCharacterTemplate *t );
|
||||
};
|
||||
|
||||
#endif
|
43
l2packets/game/server/L2Game_SSQInfo.cpp
Normal file
43
l2packets/game/server/L2Game_SSQInfo.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Game_SSQInfo.h"
|
||||
|
||||
L2Game_SSQInfo::L2Game_SSQInfo()
|
||||
{
|
||||
_initNull();
|
||||
}
|
||||
|
||||
L2Game_SSQInfo::L2Game_SSQInfo( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
_initNull();
|
||||
setBytes( bytes, length );
|
||||
}
|
||||
|
||||
/**
|
||||
protected final void writeImpl()
|
||||
{
|
||||
writeC(0x73);
|
||||
|
||||
if (_state == 2) // Dawn Sky
|
||||
{
|
||||
writeH(258);
|
||||
}
|
||||
else if (_state == 1) // Dusk Sky
|
||||
{
|
||||
writeH(257);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeH(256);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
unsigned short int L2Game_SSQInfo::read_SSQ_SkySatus()
|
||||
{
|
||||
if( this->canReadBytes( 3 ) )
|
||||
{
|
||||
this->getPacketType();
|
||||
return this->readUShort();
|
||||
}
|
||||
else return SSQ_NORMAL_SKY;
|
||||
}
|
19
l2packets/game/server/L2Game_SSQInfo.h
Normal file
19
l2packets/game/server/L2Game_SSQInfo.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef L2GAME_SSQINFO_H_
|
||||
#define L2GAME_SSQINFO_H_
|
||||
|
||||
#include "../L2GamePacket.h"
|
||||
|
||||
class L2Game_SSQInfo : public L2GamePacket
|
||||
{
|
||||
public:
|
||||
static const unsigned short int SSQ_DAWN_SKY = 258;
|
||||
static const unsigned short int SSQ_DUSK_SKY = 257;
|
||||
static const unsigned short int SSQ_NORMAL_SKY = 256;
|
||||
public:
|
||||
L2Game_SSQInfo();
|
||||
L2Game_SSQInfo( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
unsigned short int read_SSQ_SkySatus();
|
||||
};
|
||||
|
||||
#endif /* L2GAME_SSQINFO_H_*/
|
207
l2packets/l2data/L2Data.cpp
Normal file
207
l2packets/l2data/L2Data.cpp
Normal file
@@ -0,0 +1,207 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Data.h"
|
||||
|
||||
// Lineage II races
|
||||
char *L2Race[L2MaxRaces];
|
||||
// Lineage II classes
|
||||
char *L2Class[L2MaxClasses];
|
||||
// Sex :)
|
||||
char *L2Sex[L2MaxSexes];
|
||||
// Races pictures depending on sex
|
||||
// L2MaxRacePics = L2MaxRaces * L2MaxSexes;
|
||||
char *L2RacePic[L2MaxRacePics];
|
||||
// NPC races/classes
|
||||
// index is level of skill id = 4416
|
||||
char *L2NPCRace[L2MaxNPCRaces];
|
||||
|
||||
void L2Data_init()
|
||||
{
|
||||
// (char *) conversion because gcc4 thinks that string constants like "Human" are (const char *)
|
||||
// but really all these strings are used like (const char *) pointers, so it must be OK
|
||||
L2Race[0] = (char *)"Human";
|
||||
L2Race[1] = (char *)"Elf";
|
||||
L2Race[2] = (char *)"Dark Elf";
|
||||
L2Race[3] = (char *)"Orc";
|
||||
L2Race[4] = (char *)"Dwarf";
|
||||
L2Race[5] = (char *)"Kamael";
|
||||
|
||||
memset( L2Class, 0, sizeof(L2Class) );
|
||||
L2Class[0] = (char *)"Human Fighter";
|
||||
L2Class[1] = (char *)"Warrior";
|
||||
L2Class[2] = (char *)"Gladiator";
|
||||
L2Class[3] = (char *)"Warlord";
|
||||
L2Class[4] = (char *)"Knight";
|
||||
L2Class[5] = (char *)"Paladin";
|
||||
L2Class[6] = (char *)"Dark Avenger";
|
||||
L2Class[7] = (char *)"Rogue";
|
||||
L2Class[8] = (char *)"Treasure Hunter";
|
||||
L2Class[9] = (char *)"Hawkeye";
|
||||
L2Class[10] = (char *)"Human Mystic";
|
||||
L2Class[11] = (char *)"Human Wizard";
|
||||
L2Class[12] = (char *)"Sorceror";
|
||||
L2Class[13] = (char *)"Necromancer";
|
||||
L2Class[14] = (char *)"Warlock";
|
||||
L2Class[15] = (char *)"Cleric";
|
||||
L2Class[16] = (char *)"Bishop";
|
||||
L2Class[17] = (char *)"Prophet";
|
||||
L2Class[18] = (char *)"Elven Fighter";
|
||||
L2Class[19] = (char *)"Elven Knight";
|
||||
L2Class[20] = (char *)"Temple Knight";
|
||||
L2Class[21] = (char *)"Sword Singer";
|
||||
L2Class[22] = (char *)"Elven Scout";
|
||||
L2Class[23] = (char *)"Plains Walker";
|
||||
L2Class[24] = (char *)"Silver Ranger";
|
||||
L2Class[25] = (char *)"Elven Mystic";
|
||||
L2Class[26] = (char *)"Elven Wizard";
|
||||
L2Class[27] = (char *)"SpellSinger";
|
||||
L2Class[28] = (char *)"Elemental Summoner";
|
||||
L2Class[29] = (char *)"Elven Oracle";
|
||||
L2Class[30] = (char *)"Elven Elder";
|
||||
L2Class[31] = (char *)"Dark Fighter";
|
||||
L2Class[32] = (char *)"Paulus Knight";
|
||||
L2Class[33] = (char *)"Shillien Knight";
|
||||
L2Class[34] = (char *)"BladeDancer";
|
||||
L2Class[35] = (char *)"Assassin";
|
||||
L2Class[36] = (char *)"Abyss Walker";
|
||||
L2Class[37] = (char *)"Phantom Ranger";
|
||||
L2Class[38] = (char *)"Dark Mystic";
|
||||
L2Class[39] = (char *)"Dark Wizard";
|
||||
L2Class[40] = (char *)"Spellhowler";
|
||||
L2Class[41] = (char *)"Phantom Summoner";
|
||||
L2Class[42] = (char *)"Shillien Oracle";
|
||||
L2Class[43] = (char *)"Shillien Elder";
|
||||
L2Class[44] = (char *)"Orc Fighter";
|
||||
L2Class[45] = (char *)"Orc Raider";
|
||||
L2Class[46] = (char *)"Destroyer";
|
||||
L2Class[47] = (char *)"Orc Monk";
|
||||
L2Class[48] = (char *)"Tyrant";
|
||||
L2Class[49] = (char *)"Orc Mystic";
|
||||
L2Class[50] = (char *)"Orc Shaman";
|
||||
L2Class[51] = (char *)"Overlord";
|
||||
L2Class[52] = (char *)"Warcryer";
|
||||
L2Class[53] = (char *)"Dwarven Fighter";
|
||||
L2Class[54] = (char *)"Scavenger";
|
||||
L2Class[55] = (char *)"Bounty Hunter";
|
||||
L2Class[56] = (char *)"Artisan";
|
||||
L2Class[57] = (char *)"Warsmith";
|
||||
//
|
||||
// indexes [ 58 .. 87 ] unused
|
||||
//
|
||||
L2Class[88] = (char *)"Duelist";
|
||||
L2Class[89] = (char *)"Dreadnought";
|
||||
L2Class[90] = (char *)"Phoenix Knight";
|
||||
L2Class[91] = (char *)"HellKnight";
|
||||
L2Class[92] = (char *)"Sagittarius";
|
||||
L2Class[93] = (char *)"Adventurer";
|
||||
L2Class[94] = (char *)"Archmage";
|
||||
L2Class[95] = (char *)"Soultaker";
|
||||
L2Class[96] = (char *)"Arcana Lord";
|
||||
L2Class[97] = (char *)"Cardinal";
|
||||
L2Class[98] = (char *)"Hierophant";
|
||||
L2Class[99] = (char *)"Eva's Templar";
|
||||
L2Class[100] = (char *)"Sword Muse";
|
||||
L2Class[101] = (char *)"Wind Rider";
|
||||
L2Class[102] = (char *)"Moonlight Sentinel";
|
||||
L2Class[103] = (char *)"Mystic Muse";
|
||||
L2Class[104] = (char *)"Elemental Master";
|
||||
L2Class[105] = (char *)"Eva's Saint";
|
||||
L2Class[106] = (char *)"Shillien Templar";
|
||||
L2Class[107] = (char *)"Spectral Dancer";
|
||||
L2Class[108] = (char *)"Ghost Hunter";
|
||||
L2Class[109] = (char *)"Ghost Sentinel";
|
||||
L2Class[110] = (char *)"Storm Screamer";
|
||||
L2Class[111] = (char *)"Spectral Master";
|
||||
L2Class[112] = (char *)"Shillien Saint";
|
||||
L2Class[113] = (char *)"Titan";
|
||||
L2Class[114] = (char *)"Grand Khauatari";
|
||||
L2Class[115] = (char *)"Dominator";
|
||||
L2Class[116] = (char *)"Doomcryer";
|
||||
L2Class[117] = (char *)"Fortune Seeker";
|
||||
L2Class[118] = (char *)"Maestro";
|
||||
//
|
||||
// indexes [ 119 .. 122 ] unused
|
||||
//
|
||||
L2Class[123] = (char *)"Kamael Male Soldier";
|
||||
L2Class[124] = (char *)"Kamael Female Soldier";
|
||||
L2Class[125] = (char *)"Trooper";
|
||||
L2Class[126] = (char *)"Warder";
|
||||
L2Class[127] = (char *)"Berserker";
|
||||
L2Class[128] = (char *)"Soulbreaker (Male)"; //"Male Soulbreaker";
|
||||
L2Class[129] = (char *)"Soulbreaker (Female)"; //"Female Soulbreaker";
|
||||
L2Class[130] = (char *)"Arbalester";
|
||||
L2Class[131] = (char *)"Doombringer";
|
||||
L2Class[132] = (char *)"Soulhound (Male)"; // male
|
||||
L2Class[133] = (char *)"Soulhound (Female)"; // female
|
||||
L2Class[134] = (char *)"Trickster"; // female
|
||||
L2Class[135] = (char *)"Inspector";
|
||||
L2Class[136] = (char *)"Judicator";
|
||||
|
||||
L2Sex[0] = (char *)"Male";
|
||||
L2Sex[1] = (char *)"Female";
|
||||
|
||||
L2RacePic[0] = (char *)"human_male";
|
||||
L2RacePic[1] = (char *)"human_female";
|
||||
L2RacePic[2] = (char *)"elf_male";
|
||||
L2RacePic[3] = (char *)"elf_female";
|
||||
L2RacePic[4] = (char *)"darkelf_male";
|
||||
L2RacePic[5] = (char *)"darkelf_female";
|
||||
L2RacePic[6] = (char *)"orc_male";
|
||||
L2RacePic[7] = (char *)"orc_female";
|
||||
L2RacePic[8] = (char *)"dwarf_male";
|
||||
L2RacePic[9] = (char *)"dwarf_female";
|
||||
L2RacePic[10] = (char *)"kamael_male";
|
||||
L2RacePic[11] = (char *)"kamael_female";
|
||||
|
||||
L2NPCRace[0] = (char *)"NPC race index 0 not used";
|
||||
L2NPCRace[1] = (char *)"Undead";
|
||||
L2NPCRace[2] = (char *)"Magic Creatures";
|
||||
L2NPCRace[3] = (char *)"Beasts";
|
||||
L2NPCRace[4] = (char *)"Animals";
|
||||
L2NPCRace[5] = (char *)"Plants";
|
||||
L2NPCRace[6] = (char *)"Humanoids";
|
||||
L2NPCRace[7] = (char *)"Spirits";
|
||||
L2NPCRace[8] = (char *)"Angels";
|
||||
L2NPCRace[9] = (char *)"Demons";
|
||||
L2NPCRace[10] = (char *)"Dragons";
|
||||
L2NPCRace[11] = (char *)"Giants";
|
||||
L2NPCRace[12] = (char *)"Bugs";
|
||||
L2NPCRace[13] = (char *)"Fairies";
|
||||
L2NPCRace[14] = (char *)"Humans";
|
||||
L2NPCRace[15] = (char *)"Elves";
|
||||
L2NPCRace[16] = (char *)"Dark Elves";
|
||||
L2NPCRace[17] = (char *)"Orcs";
|
||||
L2NPCRace[18] = (char *)"Dwarves";
|
||||
L2NPCRace[19] = (char *)"Others";
|
||||
L2NPCRace[20] = (char *)"Non-living Beings";
|
||||
L2NPCRace[21] = (char *)"Siege Weapons";
|
||||
L2NPCRace[22] = (char *)"Defending Army";
|
||||
L2NPCRace[23] = (char *)"Mercenaries";
|
||||
L2NPCRace[24] = (char *)"Unknown Creature";
|
||||
}
|
||||
|
||||
const char *L2Data_getRace( int raceID )
|
||||
{
|
||||
if( (raceID<0) || (raceID>=L2MaxRaces) ) return NULL;
|
||||
return L2Race[raceID];
|
||||
}
|
||||
const char *L2Data_getClass( int classID )
|
||||
{
|
||||
if( (classID<0) || (classID>=L2MaxClasses) ) return NULL;
|
||||
return L2Class[classID];
|
||||
}
|
||||
const char *L2Data_getSex( int sexID )
|
||||
{
|
||||
if( (sexID<0) || (sexID>=L2MaxSexes) ) return NULL;
|
||||
return L2Sex[sexID];
|
||||
}
|
||||
const char *L2Data_getRacePic( int raceID, int sexID )
|
||||
{
|
||||
int picID = raceID*2 + sexID;
|
||||
if( (picID<0) || (picID>=L2MaxRacePics) ) return NULL;
|
||||
return L2RacePic[picID];
|
||||
}
|
||||
const char *L2Data_getNPCRace( int npcRaceID )
|
||||
{
|
||||
if( (npcRaceID<0) || (npcRaceID>=L2MaxNPCRaces) ) return NULL;
|
||||
return L2NPCRace[npcRaceID];
|
||||
}
|
51
l2packets/l2data/L2Data.h
Normal file
51
l2packets/l2data/L2Data.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef L2DATA_H_
|
||||
#define L2DATA_H_
|
||||
|
||||
#include "L2Data_Recipes.h"
|
||||
|
||||
#define L2MaxRaces 6
|
||||
#define L2MaxClasses 137
|
||||
#define L2MaxSexes 2
|
||||
#define L2MaxRacePics 12
|
||||
#define L2MaxNPCRaces 25
|
||||
|
||||
void L2Data_init();
|
||||
|
||||
const char *L2Data_getRace( int raceID );
|
||||
const char *L2Data_getClass( int classID );
|
||||
const char *L2Data_getSex( int sexID );
|
||||
const char *L2Data_getRacePic( int raceID, int sexID );
|
||||
const char *L2Data_getNPCRace( int npcRaceID );
|
||||
|
||||
void L2Data_SM_init();
|
||||
void L2Data_SM_free();
|
||||
const char *L2Data_SM_get( unsigned int systemMessageID );
|
||||
|
||||
bool L2Data_DB_Init( char *outErrMsg,
|
||||
const char *items_db_filename,
|
||||
const char *mobs_db_filename,
|
||||
const char *skills_db_filename );
|
||||
void L2Data_DB_Free();
|
||||
|
||||
// title can be NULL
|
||||
bool L2Data_DB_GetNPCNameTitleByID( unsigned int npcID, char *name, char *title );
|
||||
// pic can be NULL
|
||||
bool L2Data_DB_GetItemNamePicByID( unsigned int itemID, char *name, char *pic );
|
||||
bool L2Data_DB_GetSkillNameByID( unsigned int skillID, char *name );
|
||||
|
||||
typedef struct st_L2Data_DB_Result
|
||||
{
|
||||
int rowCount; // row count in result set
|
||||
int colCount; // columns count in result set
|
||||
char ***rows; // row data: row[0] is 1st row; row[0][0] is 1st column; row[0][0][0] is 1st char in string
|
||||
// input parameter
|
||||
int inMaxRowsToGet; // queries do not change this parameter.
|
||||
} L2Data_DB_Result, *PL2Data_DB_Result;
|
||||
|
||||
void L2Data_DB_Free_Result( L2Data_DB_Result *pResult );
|
||||
|
||||
bool L2Data_DB_Query_NPCs_ByName( const char *request, L2Data_DB_Result *pResult );
|
||||
bool L2Data_DB_Query_Items_ByName( const char *request, L2Data_DB_Result *pResult );
|
||||
bool L2Data_DB_Query_Skills_ByName( const char *request, L2Data_DB_Result *pResult );
|
||||
|
||||
#endif /* L2DATA_H_ */
|
8225
l2packets/l2data/L2Data_Recipes.cpp
Normal file
8225
l2packets/l2data/L2Data_Recipes.cpp
Normal file
File diff suppressed because it is too large
Load Diff
23
l2packets/l2data/L2Data_Recipes.h
Normal file
23
l2packets/l2data/L2Data_Recipes.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef H_RECIPEDATA
|
||||
#define H_RECIPEDATA
|
||||
|
||||
class L2Data_RecipeInfo
|
||||
{
|
||||
public:
|
||||
L2Data_RecipeInfo() { name[0] = 0; itemID = rec_itemID = 0; level = resultCount = mpCost = successRate; }
|
||||
public:
|
||||
char name[128];
|
||||
unsigned int itemID;
|
||||
unsigned int rec_itemID;
|
||||
int level;
|
||||
int resultCount;
|
||||
int mpCost;
|
||||
int successRate;
|
||||
};
|
||||
|
||||
#define MAX_RECIPE_ID 910
|
||||
|
||||
void L2Data_InitRecipes();
|
||||
bool L2Data_GetRecipeInfoForRecID( int recID, L2Data_RecipeInfo *pInfo );
|
||||
|
||||
#endif
|
377
l2packets/l2data/L2Data_db.cpp
Normal file
377
l2packets/l2data/L2Data_db.cpp
Normal file
@@ -0,0 +1,377 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Data.h"
|
||||
#include "sqlite3.h"
|
||||
|
||||
//char l2data_db_filename
|
||||
int l2data_sqlite3_was_init = 0;
|
||||
sqlite3 *l2data_sqlite3_conn_items = NULL;
|
||||
sqlite3 *l2data_sqlite3_conn_npcs = NULL;
|
||||
sqlite3 *l2data_sqlite3_conn_skills = NULL;
|
||||
|
||||
// synchronisation
|
||||
#ifdef L2PACKETS_WINDOWS
|
||||
CRITICAL_SECTION l2data_db_cs;
|
||||
#endif
|
||||
|
||||
|
||||
bool L2Data_DB_Init( char *outErrMsg,
|
||||
const char *items_db_filename,
|
||||
const char *mobs_db_filename,
|
||||
const char *skills_db_filename )
|
||||
{
|
||||
if( outErrMsg ) outErrMsg[0] = 0;
|
||||
if( !l2data_sqlite3_was_init )
|
||||
{
|
||||
// test for threadsafe
|
||||
if( sqlite3_threadsafe() == 0 )
|
||||
{
|
||||
fprintf( stderr, "WARNING: sqlite3 is not configured to use thread-safe operations!\n" );
|
||||
if( outErrMsg ) strcat( outErrMsg, "sqlite3 is not configured threadsafe! " );
|
||||
}
|
||||
//
|
||||
int r = 0;
|
||||
const char *errmsg = NULL;
|
||||
// items
|
||||
r = sqlite3_open( items_db_filename, &l2data_sqlite3_conn_items );
|
||||
if( r != SQLITE_OK )
|
||||
{
|
||||
errmsg = sqlite3_errmsg( l2data_sqlite3_conn_items );
|
||||
if( outErrMsg && errmsg ) strcat( outErrMsg, errmsg );
|
||||
sqlite3_close( l2data_sqlite3_conn_items );
|
||||
l2data_sqlite3_conn_items = NULL;
|
||||
return false;
|
||||
}
|
||||
// npcs
|
||||
r = sqlite3_open( mobs_db_filename, &l2data_sqlite3_conn_npcs );
|
||||
if( r != SQLITE_OK )
|
||||
{
|
||||
errmsg = sqlite3_errmsg( l2data_sqlite3_conn_npcs );
|
||||
if( outErrMsg && errmsg ) strcat( outErrMsg, errmsg );
|
||||
sqlite3_close( l2data_sqlite3_conn_items );
|
||||
l2data_sqlite3_conn_items = NULL;
|
||||
sqlite3_close( l2data_sqlite3_conn_npcs );
|
||||
l2data_sqlite3_conn_npcs = NULL;
|
||||
return false;
|
||||
}
|
||||
// skills
|
||||
r = sqlite3_open( skills_db_filename, &l2data_sqlite3_conn_skills );
|
||||
if( r != SQLITE_OK )
|
||||
{
|
||||
errmsg = sqlite3_errmsg( l2data_sqlite3_conn_skills );
|
||||
if( outErrMsg && errmsg ) strcat( outErrMsg, errmsg );
|
||||
sqlite3_close( l2data_sqlite3_conn_items );
|
||||
l2data_sqlite3_conn_items = NULL;
|
||||
sqlite3_close( l2data_sqlite3_conn_npcs );
|
||||
l2data_sqlite3_conn_npcs = NULL;
|
||||
sqlite3_close( l2data_sqlite3_conn_skills );
|
||||
l2data_sqlite3_conn_skills = NULL;
|
||||
return false;
|
||||
}
|
||||
//
|
||||
l2data_sqlite3_was_init = 1;
|
||||
#ifdef L2PACKETS_WINDOWS
|
||||
InitializeCriticalSection( &l2data_db_cs );
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef L2PACKETS_WINDOWS
|
||||
void L2Data_DB_Lock() { EnterCriticalSection( &l2data_db_cs ); }
|
||||
void L2Data_DB_UnLock() { LeaveCriticalSection( &l2data_db_cs ); }
|
||||
#endif
|
||||
|
||||
#ifdef L2PACKETS_LINUX
|
||||
// TODO: lock/unlock semaphore (mutex?)
|
||||
// FIXED: (?) uses SQLITE_THREADSAFE definition to sqlite3 library
|
||||
void L2Data_DB_Lock()
|
||||
{
|
||||
}
|
||||
|
||||
void L2Data_DB_UnLock()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void L2Data_DB_Free()
|
||||
{
|
||||
if( l2data_sqlite3_was_init )
|
||||
{
|
||||
L2Data_DB_Lock();
|
||||
sqlite3_close( l2data_sqlite3_conn_items );
|
||||
l2data_sqlite3_conn_items = NULL;
|
||||
sqlite3_close( l2data_sqlite3_conn_npcs );
|
||||
l2data_sqlite3_conn_npcs = NULL;
|
||||
sqlite3_close( l2data_sqlite3_conn_skills );
|
||||
l2data_sqlite3_conn_skills = NULL;
|
||||
l2data_sqlite3_was_init = 0;
|
||||
L2Data_DB_UnLock();
|
||||
#ifdef L2PACKETS_WINDOWS
|
||||
DeleteCriticalSection( &l2data_db_cs );
|
||||
#endif
|
||||
#ifdef L2PACKETS_LINUX
|
||||
// TODO: linux: delete sync object
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct st_L2DATA_2PARAM
|
||||
{
|
||||
char *param1;
|
||||
char *param2;
|
||||
} L2DATA_2PARAM, *PL2DATA_2PARAM;
|
||||
|
||||
int L2Data_sqlite_callback_2param( void *arg, int argc, char **argv, char **argvCol )
|
||||
{
|
||||
argvCol = NULL; // unreferenced formal parameter
|
||||
PL2DATA_2PARAM pst = (PL2DATA_2PARAM)arg;
|
||||
if( !pst ) return 0;
|
||||
if( !argv ) return 0;
|
||||
if( argc == 1 )
|
||||
{
|
||||
if( pst->param1 ) pst->param1[0] = 0;
|
||||
if( argv[0] && pst->param1 ) strcpy( pst->param1, argv[0] );
|
||||
}
|
||||
else if( argc == 2 )
|
||||
{
|
||||
if( pst->param1 ) pst->param1[0] = 0;
|
||||
if( pst->param2 ) pst->param2[0] = 0;
|
||||
if( argv[0] && pst->param1 ) strcpy( pst->param1, argv[0] );
|
||||
if( argv[1] && pst->param2 ) strcpy( pst->param2, argv[1] );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// title can be NULL
|
||||
bool L2Data_DB_GetNPCNameTitleByID( unsigned int npcID, char *name, char *title )
|
||||
{
|
||||
if( !l2data_sqlite3_conn_npcs ) return false;
|
||||
L2Data_DB_Lock(); // lock
|
||||
char *errmsg = NULL;
|
||||
char query[128];
|
||||
L2DATA_2PARAM st;
|
||||
st.param1 = name;
|
||||
st.param2 = title;
|
||||
sprintf( query, "SELECT name,title FROM mobs WHERE id=%u", npcID );
|
||||
int r = sqlite3_exec( l2data_sqlite3_conn_npcs, query, L2Data_sqlite_callback_2param, (void *)&st, &errmsg );
|
||||
if( errmsg )
|
||||
{
|
||||
#if defined(_DEBUG) && defined(L2PACKETS_WINDOWS)
|
||||
MessageBoxA( NULL, errmsg, "sqlite3 error (get NPC by ID)", MB_ICONSTOP );
|
||||
#endif
|
||||
#if defined(_DEBUG) && defined(L2PACKETS_LINUX)
|
||||
fprintf( stderr, "sqlite3 error (get NPC by ID): %s\n", errmsg );
|
||||
#endif
|
||||
sqlite3_free( errmsg );
|
||||
}
|
||||
L2Data_DB_UnLock(); // unlock
|
||||
return (r == SQLITE_OK);
|
||||
}
|
||||
|
||||
// desc can be NULL
|
||||
bool L2Data_DB_GetItemNamePicByID( unsigned int itemID, char *name, char *pic )
|
||||
{
|
||||
if( !l2data_sqlite3_conn_items ) return false;
|
||||
L2Data_DB_Lock(); // lock
|
||||
char *errmsg = NULL;
|
||||
char query[128];
|
||||
L2DATA_2PARAM st;
|
||||
st.param1 = name;
|
||||
st.param2 = pic;
|
||||
sprintf( query, "SELECT name,pic FROM items WHERE id=%u", itemID );
|
||||
int r = sqlite3_exec( l2data_sqlite3_conn_items, query, L2Data_sqlite_callback_2param, (void *)&st, &errmsg );
|
||||
if( errmsg )
|
||||
{
|
||||
#if defined(_DEBUG) && defined(L2PACKETS_WINDOWS)
|
||||
MessageBoxA( NULL, errmsg, "sqlite3 error (get item by id)", MB_ICONSTOP );
|
||||
#endif
|
||||
#if defined(_DEBUG) && defined(L2PACKETS_LINUX)
|
||||
fprintf( stderr, "sqlite3 error (get item by ID): %s\n", errmsg );
|
||||
#endif
|
||||
sqlite3_free( errmsg );
|
||||
}
|
||||
L2Data_DB_UnLock(); // unlock
|
||||
return (r == SQLITE_OK);
|
||||
}
|
||||
|
||||
bool L2Data_DB_GetSkillNameByID( unsigned int skillID, char *name )
|
||||
{
|
||||
if( !l2data_sqlite3_conn_skills ) return false;
|
||||
L2Data_DB_Lock(); // lock
|
||||
char *errmsg = NULL;
|
||||
char query[128];
|
||||
L2DATA_2PARAM st;
|
||||
st.param1 = name;
|
||||
st.param2 = NULL;
|
||||
sprintf( query, "SELECT name FROM skills WHERE id=%u", skillID );
|
||||
int r = sqlite3_exec( l2data_sqlite3_conn_skills, query, L2Data_sqlite_callback_2param, (void *)&st, &errmsg );
|
||||
if( errmsg )
|
||||
{
|
||||
#if defined(_DEBUG) && defined(L2PACKETS_WINDOWS)
|
||||
MessageBoxA( NULL, errmsg, "sqlite3 error (get skill by ID)", MB_ICONSTOP );
|
||||
#endif
|
||||
#if defined(_DEBUG) && defined(L2PACKETS_LINUX)
|
||||
fprintf( stderr, "sqlite3 error (get skill by ID): %s\n", errmsg );
|
||||
#endif
|
||||
sqlite3_free( errmsg );
|
||||
}
|
||||
L2Data_DB_UnLock(); // unlock
|
||||
return (r == SQLITE_OK);
|
||||
}
|
||||
|
||||
|
||||
//#define L2DATA_RESULT_MAX_ROWS 64
|
||||
|
||||
int L2Data_sqlite_result_callback( void *pvResult, int colCount, char **colData, char **colName )
|
||||
{
|
||||
colName = NULL; // unreferenced formal parameter
|
||||
L2Data_DB_Result *pResult = (L2Data_DB_Result *)pvResult;
|
||||
if( !pResult ) return 0;
|
||||
if( pResult->rowCount == 0 ) // current row number is 0, func called first time
|
||||
{
|
||||
pResult->colCount = colCount; // set column count in result set
|
||||
// allocate row pointers array (maximum rows count limited :( )
|
||||
pResult->rows = (char ***)malloc( pResult->inMaxRowsToGet * sizeof(char **) );
|
||||
if( !pResult->rows ) return 0; // malloc() failed!
|
||||
int i;
|
||||
for( i=0; i<pResult->inMaxRowsToGet; i++ ) pResult->rows[i] = NULL;
|
||||
}
|
||||
if( pResult->rowCount >= pResult->inMaxRowsToGet ) return 0; // maximum reached, no more place
|
||||
// allocate space for current row (colCount columns)
|
||||
pResult->rows[ pResult->rowCount ] = (char **)malloc( colCount * sizeof( char* ) );
|
||||
if( !pResult->rows[ pResult->rowCount ] ) return 0; // malloc failed! :(
|
||||
// copy all coumns data to current row
|
||||
int iCol;
|
||||
for( iCol = 0; iCol < colCount; iCol++ )
|
||||
{
|
||||
if( colData[iCol] != NULL )
|
||||
#ifdef L2PACKETS_WINDOWS
|
||||
pResult->rows[ pResult->rowCount ][ iCol ] = _strdup( colData[iCol] ); // copy string to result set
|
||||
#else // write own strdup() :)
|
||||
pResult->rows[ pResult->rowCount ][ iCol ] = (char *)malloc( strlen( colData[iCol] ) + 1 );
|
||||
if( pResult->rows[ pResult->rowCount ][ iCol ] ) strcpy( pResult->rows[ pResult->rowCount ][ iCol ], colData[iCol] );
|
||||
#endif
|
||||
else
|
||||
pResult->rows[ pResult->rowCount ][ iCol ] = NULL; // NULL column value
|
||||
}
|
||||
//
|
||||
pResult->rowCount++; // inc current row count in result set
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool L2Data_DB_Query_NPCs_ByName( const char *request, L2Data_DB_Result *pResult )
|
||||
{
|
||||
if( !request || !pResult ) return false;
|
||||
L2Data_DB_Lock(); // lock
|
||||
char *errmsg = NULL;
|
||||
char query[256];
|
||||
sprintf( query, "SELECT id,name,title,level FROM mobs WHERE name LIKE '%s' ORDER BY name", request );
|
||||
// zero result set
|
||||
pResult->colCount = 0;
|
||||
pResult->rowCount = 0;
|
||||
pResult->rows = NULL;
|
||||
// run query
|
||||
int r = sqlite3_exec( l2data_sqlite3_conn_npcs, query,
|
||||
L2Data_sqlite_result_callback,
|
||||
(void *)pResult, // pass pointer to result set to callback
|
||||
&errmsg );
|
||||
if( errmsg )
|
||||
{
|
||||
#if defined(_DEBUG) && defined(L2PACKETS_WINDOWS)
|
||||
MessageBoxA( NULL, errmsg, "sqlite3 error (L2Data_DB_Query_NPCs_ByName)", MB_ICONSTOP );
|
||||
#endif
|
||||
#if defined(_DEBUG) && defined(L2PACKETS_LINUX)
|
||||
fprintf( stderr, "sqlite3 error (L2Data_DB_Query_NPCs_ByName): %s\n", errmsg );
|
||||
#endif
|
||||
sqlite3_free( errmsg );
|
||||
}
|
||||
L2Data_DB_UnLock(); // unlock
|
||||
return (r == SQLITE_OK);
|
||||
}
|
||||
|
||||
bool L2Data_DB_Query_Items_ByName( const char *request, L2Data_DB_Result *pResult )
|
||||
{
|
||||
if( !request || !pResult ) return false;
|
||||
L2Data_DB_Lock(); // lock
|
||||
char *errmsg = NULL;
|
||||
char query[256];
|
||||
sprintf( query, "SELECT id,name,pic FROM items WHERE name LIKE '%s' ORDER BY name", request );
|
||||
// zero result set
|
||||
pResult->colCount = 0;
|
||||
pResult->rowCount = 0;
|
||||
pResult->rows = NULL;
|
||||
// run query
|
||||
int r = sqlite3_exec( l2data_sqlite3_conn_items, query,
|
||||
L2Data_sqlite_result_callback,
|
||||
(void *)pResult, // pass pointer to result set to callback
|
||||
&errmsg );
|
||||
if( errmsg )
|
||||
{
|
||||
#if defined(_DEBUG) && defined(L2PACKETS_WINDOWS)
|
||||
MessageBoxA( NULL, errmsg, "sqlite3 error (L2Data_DB_Query_Items_ByName)", MB_ICONSTOP );
|
||||
#endif
|
||||
#if defined(_DEBUG) && defined(L2PACKETS_LINUX)
|
||||
fprintf( stderr, "sqlite3 error (L2Data_DB_Query_Items_ByName): %s\n", errmsg );
|
||||
#endif
|
||||
sqlite3_free( errmsg );
|
||||
}
|
||||
L2Data_DB_UnLock(); // unlock
|
||||
return (r == SQLITE_OK);
|
||||
}
|
||||
|
||||
bool L2Data_DB_Query_Skills_ByName( const char *request, L2Data_DB_Result *pResult )
|
||||
{
|
||||
if( !request || !pResult ) return false;
|
||||
L2Data_DB_Lock(); // lock
|
||||
char *errmsg = NULL;
|
||||
char query[256];
|
||||
sprintf( query, "SELECT id,name FROM skills WHERE name LIKE '%s' ORDER BY name", request );
|
||||
// zero result set
|
||||
pResult->colCount = 0;
|
||||
pResult->rowCount = 0;
|
||||
pResult->rows = NULL;
|
||||
// run query
|
||||
int r = sqlite3_exec( l2data_sqlite3_conn_skills, query,
|
||||
L2Data_sqlite_result_callback,
|
||||
(void *)pResult, // pass pointer to result set to callback
|
||||
&errmsg );
|
||||
if( errmsg )
|
||||
{
|
||||
#if defined(_DEBUG) && defined(L2PACKETS_WINDOWS)
|
||||
MessageBoxA( NULL, errmsg, "sqlite3 error (L2Data_DB_Query_Skills_ByName)", MB_ICONSTOP );
|
||||
#endif
|
||||
#if defined(_DEBUG) && defined(L2PACKETS_LINUX)
|
||||
fprintf( stderr, "sqlite3 error (L2Data_DB_Query_Skills_ByName): %s\n", errmsg );
|
||||
#endif
|
||||
sqlite3_free( errmsg );
|
||||
}
|
||||
L2Data_DB_UnLock(); // unlock
|
||||
return (r == SQLITE_OK);
|
||||
}
|
||||
|
||||
void L2Data_DB_Free_Result( L2Data_DB_Result *pResult )
|
||||
{
|
||||
if( !pResult ) return;
|
||||
int rowCount = pResult->rowCount;
|
||||
int colCount = pResult->colCount;
|
||||
int ir, ic;
|
||||
for( ir = 0; ir < rowCount; ir++ )
|
||||
{
|
||||
if( pResult->rows[ir] )
|
||||
{
|
||||
for( ic = 0; ic < colCount; ic++ )
|
||||
{
|
||||
if( pResult->rows[ir][ic] ) free( pResult->rows[ir][ic] );
|
||||
}
|
||||
free( pResult->rows[ir] );
|
||||
}
|
||||
}
|
||||
free( pResult->rows );
|
||||
pResult->rows = NULL;
|
||||
pResult->colCount = 0;
|
||||
pResult->rowCount = 0;
|
||||
pResult->inMaxRowsToGet = 0;
|
||||
}
|
2640
l2packets/l2data/L2Data_sm.cpp
Normal file
2640
l2packets/l2data/L2Data_sm.cpp
Normal file
File diff suppressed because it is too large
Load Diff
215
l2packets/l2world/L2Character.cpp
Normal file
215
l2packets/l2world/L2Character.cpp
Normal file
@@ -0,0 +1,215 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Character.h"
|
||||
#include "../game/L2GamePacket.h"
|
||||
#include "../os/os_abstraction.h"
|
||||
|
||||
L2Character::L2Character()
|
||||
{
|
||||
setUnused();
|
||||
}
|
||||
|
||||
L2Character::~L2Character()
|
||||
{
|
||||
setUnused();
|
||||
}
|
||||
|
||||
L2Character::L2Character( const L2Character& other ): L2Object()
|
||||
{
|
||||
setUnused();
|
||||
this->operator=( other );
|
||||
}
|
||||
|
||||
const L2Character& L2Character::operator=( const L2Character& other )
|
||||
{
|
||||
if( this == &other ) return (*this);
|
||||
L2Object::operator=( other );
|
||||
// copy
|
||||
level = other.level;
|
||||
setName( other.charName );
|
||||
setTitle( other.charTitle );
|
||||
xDst = other.xDst;
|
||||
yDst = other.yDst;
|
||||
zDst = other.zDst;
|
||||
heading = other.heading;
|
||||
runSpeed = other.runSpeed;
|
||||
walkSpeed = other.walkSpeed;
|
||||
isRunning = other.isRunning;
|
||||
isSitting = other.isSitting;
|
||||
isAlikeDead = other.isAlikeDead;
|
||||
isFlying = other.isFlying;
|
||||
lastMoveTickTime = other.lastMoveTickTime;
|
||||
s_STR = other.s_STR;
|
||||
s_DEX = other.s_DEX;
|
||||
s_CON = other.s_CON;
|
||||
s_INT = other.s_INT;
|
||||
s_WIT = other.s_WIT;
|
||||
s_MEN = other.s_MEN;
|
||||
pAtk = other.pAtk;
|
||||
pDef = other.pDef;
|
||||
mAtk = other.mAtk;
|
||||
mDef = other.mDef;
|
||||
pAtkSpd = other.pAtkSpd;
|
||||
mAtkSpd = other.mAtkSpd;
|
||||
accuracy = other.accuracy;
|
||||
evasion = other.evasion;
|
||||
critical = other.critical;
|
||||
curHp = other.curHp;
|
||||
maxHp = other.maxHp;
|
||||
curMp = other.curMp;
|
||||
maxMp = other.maxMp;
|
||||
curCp = other.curCp;
|
||||
maxCp = other.maxCp;
|
||||
abnormalEffect = other.abnormalEffect;
|
||||
targetObjectID = other.targetObjectID;
|
||||
isInCombat = other.isInCombat;
|
||||
collisionRadius = other.collisionRadius;
|
||||
collisionHeight = other.collisionHeight;
|
||||
pvpFlag = other.pvpFlag;
|
||||
karma = other.karma;
|
||||
clanID = other.clanID;
|
||||
clanCrestID = other.clanCrestID;
|
||||
clanCrestLargeID = other.clanCrestLargeID;
|
||||
allyID = other.allyID;
|
||||
allyCrestID = other.allyCrestID;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
void L2Character::setUnused()
|
||||
{
|
||||
L2Object::setUnused();
|
||||
stopMove();
|
||||
charName[0] = charTitle[0] = 0;
|
||||
level = 0;
|
||||
heading = 0;
|
||||
runSpeed = walkSpeed = isRunning = isSitting = isAlikeDead = 0;
|
||||
lastMoveTickTime = 0;
|
||||
s_STR = s_DEX = s_CON = s_INT = s_WIT = s_MEN = 0;
|
||||
pAtk = pDef = mAtk = mDef = pAtkSpd = mAtkSpd = accuracy = evasion = critical = 0;
|
||||
curHp = maxHp = curMp = maxMp = curCp = maxCp = 0.0;
|
||||
abnormalEffect = 0;
|
||||
targetObjectID = 0;
|
||||
isInCombat = 0;
|
||||
collisionRadius = collisionHeight = 1.0;
|
||||
}
|
||||
|
||||
void L2Character::setName( const wchar_t *name )
|
||||
{
|
||||
if( name )
|
||||
{
|
||||
wcsncpy( charName, name, sizeof(charName)/sizeof(charName[0]) - 1 );
|
||||
charName[ sizeof(charName)/sizeof(charName[0]) - 1 ] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void L2Character::setName( const char *name )
|
||||
{
|
||||
if( name )
|
||||
{
|
||||
#ifdef L2PACKETS_WINDOWS
|
||||
_snwprintf( charName, sizeof(charName)/sizeof(charName[0]), L"%S", name );
|
||||
#endif
|
||||
#ifdef L2PACKETS_LINUX
|
||||
swprintf( charName, sizeof(charName)/sizeof(charName[0]), L"%ls", name );
|
||||
#endif
|
||||
charName[ sizeof(charName)/sizeof(charName[0]) - 1 ] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void L2Character::setTitle( const wchar_t *title )
|
||||
{
|
||||
if( title )
|
||||
{
|
||||
wcsncpy( charTitle, title, sizeof(charTitle)/sizeof(charTitle[0]) - 1 );
|
||||
charTitle[ sizeof(charTitle)/sizeof(charTitle[0]) - 1 ] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void L2Character::setTitle( const char *title )
|
||||
{
|
||||
if( title )
|
||||
{
|
||||
#ifdef L2PACKETS_WINDOWS
|
||||
_snwprintf( charTitle, sizeof(charTitle)/sizeof(charTitle[0]), L"%S", title );
|
||||
#endif
|
||||
#ifdef L2PACKETS_LINUX
|
||||
swprintf( charTitle, sizeof(charTitle)/sizeof(charTitle[0]), L"%ls", title );
|
||||
#endif
|
||||
charTitle[ sizeof(charTitle)/sizeof(charTitle[0]) - 1 ] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const wchar_t *L2Character::getName()
|
||||
{
|
||||
this->charName[sizeof(this->charName) - 1] = 0;
|
||||
return (const wchar_t *)(this->charName);
|
||||
}
|
||||
|
||||
const wchar_t *L2Character::getTitle()
|
||||
{
|
||||
this->charTitle[sizeof(this->charTitle) - 1] = 0;
|
||||
return (const wchar_t *)(this->charTitle);
|
||||
}
|
||||
|
||||
bool L2Character::parse_MoveToLocation( void *l2_game_packet )
|
||||
{
|
||||
L2GamePacket *p = (L2GamePacket *)l2_game_packet;
|
||||
p->getPacketType();
|
||||
unsigned int oid = p->readUInt();
|
||||
if( oid != this->objectID ) return false; // not my move
|
||||
xDst = p->readInt();
|
||||
yDst = p->readInt();
|
||||
zDst = p->readInt();
|
||||
x = p->readInt();
|
||||
y = p->readInt();
|
||||
z = p->readInt();
|
||||
this->lastMoveTickTime = OS_GetTickCount(); // last time when x,y,z, xDst,yDst,zDst were known exactly
|
||||
return true;
|
||||
}
|
||||
|
||||
void L2Character::processMoveTick()
|
||||
{
|
||||
unsigned long long int curTick = OS_GetTickCount();
|
||||
unsigned long long int millisecsPassed = curTick - lastMoveTickTime;
|
||||
if( millisecsPassed < 100 ) return;
|
||||
lastMoveTickTime = curTick;
|
||||
const int near_range = 50; // range in which point is reached
|
||||
if( isMoving() )
|
||||
{
|
||||
int dx = xDst - x;
|
||||
int dy = yDst - y;
|
||||
int dz = zDst - z;
|
||||
if( ((dx > -near_range)&&(dx < near_range)) &&
|
||||
((dy > -near_range)&&(dy < near_range)) &&
|
||||
((dz > -near_range)&&(dz < near_range)) ) // target ~~ reached?
|
||||
{
|
||||
stopMove();
|
||||
return;
|
||||
}
|
||||
float useSpeed = (float)runSpeed;
|
||||
if( isRunning ) useSpeed = (float)walkSpeed;
|
||||
float secs = ((float)millisecsPassed) / 1000;
|
||||
float movedDist = useSpeed * secs;
|
||||
float totalDist = sqrtf( (float)(dx*dx + dy*dy) );
|
||||
float k = totalDist / movedDist;
|
||||
if( k < 1.1 ) // cannot be < 1
|
||||
{
|
||||
stopMove();
|
||||
return;
|
||||
}
|
||||
float xDelta = (float)dx / k;
|
||||
float yDelta = (float)dy / k;
|
||||
x += (int)xDelta;
|
||||
y += (int)yDelta;
|
||||
}
|
||||
}
|
||||
|
||||
void L2Character::startMoveTo( int mxd, int myd, int mzd, int mx, int my, int mz )
|
||||
{
|
||||
x = mx;
|
||||
y = my;
|
||||
z = mz;
|
||||
xDst = mxd;
|
||||
yDst = myd;
|
||||
zDst = mzd;
|
||||
lastMoveTickTime = OS_GetTickCount();
|
||||
}
|
162
l2packets/l2world/L2Character.h
Normal file
162
l2packets/l2world/L2Character.h
Normal file
@@ -0,0 +1,162 @@
|
||||
#ifndef H_L2CHARACTER
|
||||
#define H_L2CHARACTER
|
||||
#include "L2Object.h"
|
||||
|
||||
/** \class L2Character
|
||||
|
||||
L2Character represents common properties for all moving objects in game:\n
|
||||
treasure chests, doors, chairs, mobs, npcs, players...\n
|
||||
\n
|
||||
Every character is L2Object:\n
|
||||
Every L2Object has its objectID and can also have its coordinates in L2World)\n
|
||||
\n
|
||||
Additionally:\n
|
||||
Every L2Character has LEVEL!\n
|
||||
Every L2Character has its charName and charTitle\n
|
||||
Every L2Character has its heading\n
|
||||
Every L2Character has moving speed in states: running, walking\n
|
||||
Every L2Character has its move destination: xDst, yDst, zDst\n
|
||||
Every L2Character can calc its position based on destnation point and time passed since last calc\n
|
||||
Every L2Character has its base stats: INT WIT MEN CON STR DEX\n
|
||||
Every L2Character has its stats: pAtk, mAtk, ..., curHp, maxHp, ...\n
|
||||
Every L2Character has abnormalEffect\n
|
||||
Every L2Character has its target\n
|
||||
Every L2Character can be in combat\n
|
||||
Every L2Character has its collision radius and height\n
|
||||
Every L2Character has its pvpFlag, karma\n
|
||||
Every L2Character has its clan, ally IDs and clan/ally crest IDs\n
|
||||
*/
|
||||
|
||||
class L2Character : public L2Object
|
||||
{
|
||||
public:
|
||||
/** Default constructor, just calls setUnused() (zeroes all members) */
|
||||
L2Character();
|
||||
|
||||
/** Copy constructor
|
||||
* \param other source to copy from */
|
||||
L2Character( const L2Character& other );
|
||||
|
||||
/** Operator =
|
||||
* \param other source to copy from
|
||||
* \return reference to this object
|
||||
*/
|
||||
virtual const L2Character& operator=( const L2Character& other );
|
||||
|
||||
/** Default destructor, just calls setUnused() (zeroes all members) */
|
||||
virtual ~L2Character();
|
||||
|
||||
public:
|
||||
/** Initializes object's state (zeroes all members)
|
||||
* \return none
|
||||
*/
|
||||
virtual void setUnused();
|
||||
|
||||
public:
|
||||
/** MoveToLocation packet parser.
|
||||
* MoveToLocation packet is sent when some object starts moving to some point.
|
||||
* Updates x,y,z, xDst,yDst,zDst.
|
||||
* Updates lastMoveTickTime (sets to current time).
|
||||
* \param l2_game_packet pointer to L2GamePacket object to parse
|
||||
* \return none
|
||||
* \see lastMoveTickTime
|
||||
*/
|
||||
virtual bool parse_MoveToLocation( void *l2_game_packet );
|
||||
|
||||
/** Calculates current character position based on x, y, z, xDst, yDst, zDst,
|
||||
* runSpeed / walkSpeed, isRunning, current time and last time when character coords were
|
||||
* known exactly (from some packet or after previous calculation).
|
||||
* Updates x,y,z and lastMoveTickTime (sets to current time).
|
||||
* \return none
|
||||
* \see lastMoveTickTime
|
||||
*/
|
||||
virtual void processMoveTick();
|
||||
|
||||
/** Starts 'moving' character: sets destination coords and current coords.
|
||||
* Updates x,y,z,xDst,yDst,zDst,lastMoveTickTime.
|
||||
* \param mxd,myd,mzd destination point coords
|
||||
* \param mx,my,mz current char coords
|
||||
* \return none
|
||||
* \see lastMoveTickTime
|
||||
*/
|
||||
virtual void startMoveTo( int mxd, int myd, int mzd, int mx, int my, int mz );
|
||||
|
||||
/** sets xDst,yDst,zDst to 0x7FFFFFFF, indicating that character is not moving.
|
||||
* \return none
|
||||
* \see xDst,yDst,zDst
|
||||
*/
|
||||
virtual void stopMove() { xDst = 0x7FFFFFFF; yDst = 0x7FFFFFFF; zDst = 0x7FFFFFFF; }
|
||||
|
||||
/** moving test
|
||||
* \return 1 if char is moving, 0 if not
|
||||
* \see xDst,yDst,zDst
|
||||
*/
|
||||
virtual int isMoving() { return ((xDst != 0x7FFFFFFF) && (yDst != 0x7FFFFFFF) && (zDst!=0x7FFFFFFF)); }
|
||||
|
||||
public:
|
||||
/** Sets char name.
|
||||
* \param name new char name to set.
|
||||
*/
|
||||
virtual void setName( const wchar_t *name );
|
||||
virtual void setName( const char *name );
|
||||
|
||||
/** Sets char title.
|
||||
* \param title new char title to set.
|
||||
*/
|
||||
virtual void setTitle( const wchar_t *title );
|
||||
virtual void setTitle( const char *title );
|
||||
|
||||
virtual const wchar_t *getName(); //< not really used
|
||||
virtual const wchar_t *getTitle(); //< not really used
|
||||
|
||||
public:
|
||||
int level; ///< character level
|
||||
wchar_t charName[128]; ///< character name
|
||||
wchar_t charTitle[128]; ///< character title (displayed above name in client ^^)
|
||||
int xDst; ///< x-destination move coord (=0x7FFFFFFF if char is not moving)
|
||||
int yDst; ///< y-destination move coord (=0x7FFFFFFF if char is not moving)
|
||||
int zDst; ///< z-destination move coord (=0x7FFFFFFF if char is not moving)
|
||||
unsigned int heading; ///< heading... not really used
|
||||
int runSpeed; ///< run speed
|
||||
int walkSpeed; ///< walk speed
|
||||
int isRunning; ///< 1, if char is runing, 0 if walking
|
||||
int isSitting; ///< 1, if char is sitting, 0 if standing
|
||||
int isAlikeDead; ///< 1, if characted is dead or looks like dead (fake death)
|
||||
int isFlying; ///< 1, if character is flying (?) T2.3
|
||||
unsigned long long int lastMoveTickTime; ///< timer used to store last time when character coords were known exactly
|
||||
int s_STR; ///< STR base stat
|
||||
int s_DEX; ///< DEX base stat
|
||||
int s_CON; ///< CON base stat
|
||||
int s_INT; ///< INT base stat
|
||||
int s_WIT; ///< WIT base stat
|
||||
int s_MEN; ///< MEN base stat
|
||||
int pAtk;
|
||||
int pDef;
|
||||
int mAtk;
|
||||
int mDef;
|
||||
int pAtkSpd;
|
||||
int mAtkSpd;
|
||||
int accuracy;
|
||||
int evasion;
|
||||
int critical;
|
||||
double curHp; ///< current HP value
|
||||
double maxHp; ///< maximum HP value
|
||||
double curMp; ///< current MP value
|
||||
double maxMp; ///< maximum MP value
|
||||
double curCp; ///< current CP value
|
||||
double maxCp; ///< maximum CP value
|
||||
unsigned int abnormalEffect; ///< flags for visible buffs/defuffs: poison, medusa, bleed, ...
|
||||
unsigned int targetObjectID; ///< objectID of object which is targeted by this character
|
||||
int isInCombat; ///< 1, if char is in combat state, 0 if not
|
||||
double collisionRadius;
|
||||
double collisionHeight;
|
||||
int pvpFlag;
|
||||
int karma;
|
||||
unsigned int clanID;
|
||||
unsigned int clanCrestID;
|
||||
unsigned int clanCrestLargeID;
|
||||
unsigned int allyID;
|
||||
unsigned int allyCrestID;
|
||||
};
|
||||
|
||||
#endif
|
30
l2packets/l2world/L2ChatMessageTypes.h
Normal file
30
l2packets/l2world/L2ChatMessageTypes.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef H_L2_CHAT_MESSAGE_TYPES
|
||||
#define H_L2_CHAT_MESSAGE_TYPES
|
||||
|
||||
/** \class L2_CHAT_MESSAGE
|
||||
* Defines constants used in S->C CreatureSay and C->S Say2 packets.\n
|
||||
* Chat message type.
|
||||
*/
|
||||
|
||||
class L2_CHAT_MESSAGE
|
||||
{
|
||||
public:
|
||||
static const unsigned int ALL = 0;
|
||||
static const unsigned int SHOUT = 1; //!
|
||||
static const unsigned int TELL = 2;
|
||||
static const unsigned int PARTY = 3; //#
|
||||
static const unsigned int CLAN = 4; //@
|
||||
static const unsigned int GM = 5;
|
||||
static const unsigned int PETITION_PLAYER = 6; // used for petition
|
||||
static const unsigned int PETITION_GM = 7; //* used for petition
|
||||
static const unsigned int TRADE = 8; //+
|
||||
static const unsigned int ALLIANCE = 9; //$
|
||||
static const unsigned int ANNOUNCEMENT = 10;
|
||||
static const unsigned int PARTYROOM_ALL = 16; //(Red)
|
||||
static const unsigned int PARTYROOM_COMMANDER = 15; //(Yellow)
|
||||
static const unsigned int HERO_VOICE = 17;
|
||||
static const unsigned int L2_CHAT_MESSAGE_LAST = HERO_VOICE;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
39
l2packets/l2world/L2ElementalInfo.cpp
Normal file
39
l2packets/l2world/L2ElementalInfo.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2ElementalInfo.h"
|
||||
|
||||
L2ElementalInfo::L2ElementalInfo()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
L2ElementalInfo::L2ElementalInfo( const L2ElementalInfo& other )
|
||||
{
|
||||
clear();
|
||||
this->operator=( other );
|
||||
}
|
||||
|
||||
const L2ElementalInfo& L2ElementalInfo::operator=( const L2ElementalInfo& other )
|
||||
{
|
||||
if( this == &other ) return (*this);
|
||||
attackElementType = other.attackElementType;
|
||||
attackElementValue = other.attackElementValue;
|
||||
defAttrFire = other.defAttrFire;
|
||||
defAttrWater = other.defAttrWater;
|
||||
defAttrWind = other.defAttrWind;
|
||||
defAttrEarth = other.defAttrEarth;
|
||||
defAttrHoly = other.defAttrHoly;
|
||||
defAttrUnholy = other.defAttrUnholy;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
void L2ElementalInfo::clear()
|
||||
{
|
||||
attackElementType = 0;
|
||||
attackElementValue = 0;
|
||||
defAttrFire = 0;
|
||||
defAttrWater = 0;
|
||||
defAttrWind = 0;
|
||||
defAttrEarth = 0;
|
||||
defAttrHoly = 0;
|
||||
defAttrUnholy = 0;
|
||||
}
|
23
l2packets/l2world/L2ElementalInfo.h
Normal file
23
l2packets/l2world/L2ElementalInfo.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef H_L2_ELEMENTAL_INFO
|
||||
#define H_L2_ELEMENTAL_INFO
|
||||
|
||||
class L2ElementalInfo
|
||||
{
|
||||
public:
|
||||
L2ElementalInfo();
|
||||
L2ElementalInfo( const L2ElementalInfo& other );
|
||||
const L2ElementalInfo& operator=( const L2ElementalInfo& other );
|
||||
public:
|
||||
void clear();
|
||||
public:
|
||||
int attackElementType;
|
||||
int attackElementValue;
|
||||
int defAttrFire;
|
||||
int defAttrWater;
|
||||
int defAttrWind;
|
||||
int defAttrEarth;
|
||||
int defAttrHoly;
|
||||
int defAttrUnholy;
|
||||
};
|
||||
|
||||
#endif
|
118
l2packets/l2world/L2Experience.cpp
Normal file
118
l2packets/l2world/L2Experience.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Experience.h"
|
||||
|
||||
double L2Experience::getExpPercent( long long exp )
|
||||
{
|
||||
double ret = 0.0;
|
||||
#ifndef __GNUC__
|
||||
const long long int exp_at_level[] =
|
||||
#else
|
||||
const double exp_at_level[] =
|
||||
#endif
|
||||
{
|
||||
-1, // level 0 (unreachable)
|
||||
0,
|
||||
68,
|
||||
363,
|
||||
1168,
|
||||
2884,
|
||||
6038,
|
||||
11287,
|
||||
19423,
|
||||
31378,
|
||||
48229, //level 10
|
||||
71201,
|
||||
101676,
|
||||
141192,
|
||||
191452,
|
||||
254327,
|
||||
331864,
|
||||
426284,
|
||||
539995,
|
||||
675590,
|
||||
835854, //level 20
|
||||
1023775,
|
||||
1242536,
|
||||
1495531,
|
||||
1786365,
|
||||
2118860,
|
||||
2497059,
|
||||
2925229,
|
||||
3407873,
|
||||
3949727,
|
||||
4555766, //level 30
|
||||
5231213,
|
||||
5981539,
|
||||
6812472,
|
||||
7729999,
|
||||
8740372,
|
||||
9850111,
|
||||
11066012,
|
||||
12395149,
|
||||
13844879,
|
||||
15422851, //level 40
|
||||
17137002,
|
||||
18995573,
|
||||
21007103,
|
||||
23180442,
|
||||
25524751,
|
||||
28049509,
|
||||
30764519,
|
||||
33679907,
|
||||
36806133,
|
||||
40153995, //level 50
|
||||
45524865,
|
||||
51262204,
|
||||
57383682,
|
||||
63907585,
|
||||
70852742,
|
||||
80700339,
|
||||
91162131,
|
||||
102265326,
|
||||
114038008,
|
||||
126509030, //level 60
|
||||
146307211,
|
||||
167243291,
|
||||
189363788,
|
||||
212716741,
|
||||
237351413,
|
||||
271973532,
|
||||
308441375,
|
||||
346825235,
|
||||
387197529,
|
||||
429632402, //level 70
|
||||
474205751,
|
||||
532692055,
|
||||
606319094,
|
||||
696376867,
|
||||
804219972,
|
||||
931275828,
|
||||
1151275834,
|
||||
1511275834,
|
||||
#ifdef __GNUC__
|
||||
2099275834.0,
|
||||
4200000000.0, //level 80
|
||||
6300000000.0, //level 81
|
||||
8820000000.0, //level 82
|
||||
11844000000.0, //level 83
|
||||
15472800000.0, //level 84
|
||||
19827360000.0, //level 85
|
||||
25314000000.0
|
||||
#else
|
||||
2099275834,
|
||||
4200000000, //level 80
|
||||
6300000000, //level 81
|
||||
8820000000, //level 82
|
||||
11844000000, //level 83
|
||||
15472800000, //level 84
|
||||
19827360000, //level 85
|
||||
25314000000
|
||||
#endif
|
||||
};
|
||||
int i = 0;
|
||||
//int cur_level = 0;
|
||||
for( i=0; i<86; i++ ) if( exp_at_level[i+1] > exp ) break;
|
||||
//cur_level = i;
|
||||
ret = 100.0 * (exp - exp_at_level[i]) / (exp_at_level[i+1] - exp_at_level[i]);
|
||||
return ret;
|
||||
}
|
28
l2packets/l2world/L2Experience.h
Normal file
28
l2packets/l2world/L2Experience.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef H_L2_EXPERIENCE_
|
||||
#define H_L2_EXPERIENCE_
|
||||
|
||||
/** \class L2Experience
|
||||
* Some functions and constants to work with player exp values.
|
||||
*/
|
||||
|
||||
class L2Experience
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Converts exp value to current exp percent.
|
||||
* \param exp current experience value
|
||||
* \return precent value in current level
|
||||
*/
|
||||
static double getExpPercent( long long exp );
|
||||
|
||||
public:
|
||||
/**
|
||||
* This is the first UNREACHABLE level.<BR>
|
||||
* ex: If you want a max at 85 & 100.00%, you have to put 86.<BR><BR>
|
||||
*/
|
||||
static const int MAX_LEVEL = 86;
|
||||
static const int MIN_NEWBIE_LEVEL = 6;
|
||||
static const int MAX_NEWBIE_LEVEL = 39;
|
||||
};
|
||||
|
||||
#endif
|
139
l2packets/l2world/L2Npc.cpp
Normal file
139
l2packets/l2world/L2Npc.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Npc.h"
|
||||
#include "../l2data/L2Data.h"
|
||||
#include "../game/L2GamePacket.h"
|
||||
#include "../os/os_abstraction.h"
|
||||
|
||||
L2Npc::L2Npc()
|
||||
{
|
||||
setUnused();
|
||||
}
|
||||
|
||||
L2Npc::~L2Npc()
|
||||
{
|
||||
setUnused();
|
||||
}
|
||||
|
||||
L2Npc::L2Npc( const L2Npc& other ): L2Character()
|
||||
{
|
||||
setUnused();
|
||||
operator=( other );
|
||||
}
|
||||
|
||||
const L2Npc& L2Npc::operator=( const L2Npc& other )
|
||||
{
|
||||
if( this == &other ) return (*this);
|
||||
L2Character::operator=( other );
|
||||
templateID = other.templateID;
|
||||
isAttackable = other.isAttackable;
|
||||
iid_left_hand = other.iid_left_hand;
|
||||
iid_right_hand = other.iid_right_hand;
|
||||
iid_chest = other.iid_chest;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
void L2Npc::setUnused()
|
||||
{
|
||||
L2Character::setUnused();
|
||||
templateID = 0;
|
||||
isAttackable = 0;
|
||||
// weapon
|
||||
iid_left_hand = iid_right_hand = iid_chest = 0;
|
||||
}
|
||||
|
||||
void L2Npc::setNpcNameTitleByTemplate()
|
||||
{
|
||||
char db_name[256], db_title[256];
|
||||
db_name[0] = db_title[0] = 0;
|
||||
if( L2Data_DB_GetNPCNameTitleByID( templateID, db_name, db_title ) )
|
||||
{
|
||||
setName( db_name );
|
||||
setTitle( db_title );
|
||||
}
|
||||
}
|
||||
|
||||
bool L2Npc::parse_NpcInfo( void *l2_game_packet, L2_VERSION l2_version )
|
||||
{
|
||||
if( !l2_game_packet ) return false;
|
||||
L2GamePacket *p = (L2GamePacket *)l2_game_packet;
|
||||
// parse
|
||||
unsigned char ptype = p->getPacketType();
|
||||
if( ptype != 0x0C ) return false; // 0x0C NpcInfo
|
||||
//
|
||||
objectID = p->readUInt();
|
||||
templateID = p->readUInt() - 1000000; // ? :) L2J adds 1000000 to this field
|
||||
isAttackable = p->readD(); // _isAttackable
|
||||
x = p->readD();
|
||||
y = p->readD();
|
||||
z = p->readD();
|
||||
heading = p->readUInt();
|
||||
p->readD(); // 0x00
|
||||
|
||||
mAtkSpd = p->readD();
|
||||
pAtkSpd = p->readD();
|
||||
runSpeed = p->readD();
|
||||
walkSpeed = p->readD();
|
||||
p->readD(); // swim run speed
|
||||
p->readD(); // swim walk speed
|
||||
p->readD(); // fl run speed (?)
|
||||
p->readD(); // fl walk speed (?)
|
||||
p->readD(); // fly run speed (?) same as fl
|
||||
p->readD(); // fly walk speed (?)
|
||||
|
||||
double moveSpeedMultiplier = p->readF();
|
||||
double attackSpeedMultiplier = p->readF();
|
||||
if( moveSpeedMultiplier > 0 )
|
||||
{
|
||||
runSpeed = (int)( ((double)runSpeed) * moveSpeedMultiplier );
|
||||
walkSpeed = (int)( ((double)walkSpeed) * moveSpeedMultiplier );
|
||||
}
|
||||
if( attackSpeedMultiplier > 0 ) pAtkSpd = (int)( ((double)pAtkSpd) * attackSpeedMultiplier );
|
||||
|
||||
collisionRadius = p->readF();
|
||||
collisionHeight = p->readF();
|
||||
|
||||
iid_right_hand = p->readUInt();
|
||||
iid_chest = p->readUInt();
|
||||
iid_left_hand = p->readUInt();
|
||||
|
||||
p->readC(); // has title
|
||||
isRunning = p->readC();
|
||||
isInCombat = p->readC();
|
||||
isAlikeDead = p->readC();
|
||||
p->readC(); // is summoned
|
||||
|
||||
setName( p->readUnicodeStringPtr() );
|
||||
setTitle( p->readUnicodeStringPtr() );
|
||||
|
||||
p->readD(); // title color
|
||||
p->readD(); // 0x00
|
||||
pvpFlag = p->readD(); // pvp flag
|
||||
|
||||
abnormalEffect = p->readUInt();
|
||||
clanID = p->readUInt(); // Gracia Final
|
||||
clanCrestID = p->readUInt(); // Gracia Final
|
||||
|
||||
isFlying = p->readC(); // Gracia Final
|
||||
p->readC(); // 0x00
|
||||
|
||||
p->readF(); // collisionRadius (again?)
|
||||
p->readF(); // collisionHeight (again?)
|
||||
|
||||
p->readD(); // 0x00
|
||||
p->readD(); // isFlying? (again?) Gracia Final
|
||||
p->readD(); // 0x00
|
||||
p->readD(); // pet form and skills (?)
|
||||
|
||||
// Gracia Final has some more to read
|
||||
if( l2_version >= L2_VERSION_T23 )
|
||||
{
|
||||
p->readC(); // 0x01
|
||||
p->readC(); // 0x01
|
||||
p->readD(); // 0x00000000
|
||||
}
|
||||
|
||||
// set last time when npc coordinates were known exactly
|
||||
lastMoveTickTime = OS_GetTickCount();
|
||||
|
||||
return true;
|
||||
}
|
67
l2packets/l2world/L2Npc.h
Normal file
67
l2packets/l2world/L2Npc.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#ifndef H_L2NPC
|
||||
#define H_L2NPC
|
||||
#include "L2Character.h"
|
||||
|
||||
/** \class L2Npc
|
||||
Every L2Npc is L2Character:\n
|
||||
Every L2Character is L2Object (has objectID, x, y, z)\n
|
||||
Every L2Character has LEVEL!\n
|
||||
Every L2Character has its charName and charTitle\n
|
||||
Every L2Character has its heading\n
|
||||
Every L2Character has moving speed in states: running, walking\n
|
||||
Every L2Character has its move destination: xDst, yDst, zDst\n
|
||||
Every l2Character can calc its position based on destnation point and time passed since last calc\n
|
||||
Every L2Character has its base stats: INT WIT MEN CON STR DEX\n
|
||||
Every L2Character has its stats: pAtk, mAtk, ..., curHp, maxHp, ...\n
|
||||
Every L2Character has abnormalEffect\n
|
||||
Every L2Character has its target\n
|
||||
Every L2Character can be in combat\n
|
||||
Every L2Character has its collision radius and height\n
|
||||
\n
|
||||
Additionally:\n
|
||||
Every L2Npc has its NPC templateID\n
|
||||
Every L2Npc can be attackable or not (attackable is mob, other is NPC. chooses default action on click)\n
|
||||
Every L2Npc has weapon/shield or bow/arrow in left/right hand\n
|
||||
*/
|
||||
|
||||
class L2Npc : public L2Character
|
||||
{
|
||||
public:
|
||||
/** Default constructor calls setUnused() (zeroes all members) */
|
||||
L2Npc();
|
||||
|
||||
/** Copy constructor
|
||||
* \param other source to copy from
|
||||
*/
|
||||
L2Npc( const L2Npc& other );
|
||||
|
||||
/* Assigns all members of L2Npc class instance to other
|
||||
* \param other source to copy from
|
||||
* \return reference to this object */
|
||||
virtual const L2Npc& operator=( const L2Npc& other );
|
||||
|
||||
/** Default destructor calls setUnused() (zeroes all members) */
|
||||
virtual ~L2Npc();
|
||||
|
||||
public:
|
||||
/** Initializes object's state (zeroes all members)
|
||||
* \return none
|
||||
*/
|
||||
virtual void setUnused();
|
||||
|
||||
public:
|
||||
/** Query database for name and title, using this object's templateID, and set them */
|
||||
virtual void setNpcNameTitleByTemplate();
|
||||
|
||||
public:
|
||||
bool parse_NpcInfo( void *l2_game_packet, L2_VERSION l2_version );
|
||||
|
||||
public:
|
||||
unsigned int templateID; ///< NPC template ID
|
||||
int isAttackable; ///< =1, if npc is auto attackable on double click (mob); 0 if double click begins chat with NPC (NPC)
|
||||
unsigned int iid_left_hand; ///< item ID of left hand weapon item
|
||||
unsigned int iid_chest; ///< item ID of chest (?)
|
||||
unsigned int iid_right_hand; ///< item ID of right hand weapon item
|
||||
};
|
||||
|
||||
#endif
|
27
l2packets/l2world/L2Object.cpp
Normal file
27
l2packets/l2world/L2Object.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Object.h"
|
||||
|
||||
L2Object::~L2Object()
|
||||
{
|
||||
setUnused();
|
||||
}
|
||||
|
||||
L2Object::L2Object( const L2Object& other )
|
||||
{
|
||||
this->operator=( other );
|
||||
}
|
||||
|
||||
const L2Object& L2Object::operator=( const L2Object& other )
|
||||
{
|
||||
if( this == &other ) return (*this);
|
||||
this->x = other.x;
|
||||
this->y = other.y;
|
||||
this->z = other.z;
|
||||
this->objectID = other.objectID;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
bool L2Object::operator==( const L2Object& other )
|
||||
{
|
||||
return this->objectID == other.objectID;
|
||||
}
|
64
l2packets/l2world/L2Object.h
Normal file
64
l2packets/l2world/L2Object.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#ifndef H_L2OBJECT
|
||||
#define H_L2OBJECT
|
||||
|
||||
#include "../L2_versions.h"
|
||||
|
||||
/** \class L2Object
|
||||
Every object has its objectID and can also have its coordinates in L2World
|
||||
*/
|
||||
|
||||
class L2Object
|
||||
{
|
||||
public:
|
||||
/** L2Object default constructor
|
||||
*/
|
||||
L2Object(): x(0), y(0), z(0), objectID(0) {}
|
||||
|
||||
/** L2Object copy constructor
|
||||
* \param other copy source
|
||||
*/
|
||||
L2Object( const L2Object& other );
|
||||
|
||||
/** Assigns this->x,y,z,objectID to other's x,y,z,objectID
|
||||
* \param other copy source
|
||||
* \return reference to this object
|
||||
*/
|
||||
virtual const L2Object& operator=( const L2Object& other );
|
||||
|
||||
/** Compares objectIDs
|
||||
* \param other object to compare with
|
||||
* \return true, if objects are equal (equal objectIDs)
|
||||
*/
|
||||
virtual bool operator==( const L2Object& other );
|
||||
|
||||
/** Destructor calls setUnused()
|
||||
* \see setUnused
|
||||
*/
|
||||
virtual ~L2Object();
|
||||
public:
|
||||
/** Sets object coordinates in world
|
||||
* \param sx, sy, sz - new coordinates
|
||||
* \return none
|
||||
*/
|
||||
virtual void setXYZ( int sx, int sy, int sz ) { x = sx; y = sy; z = sz; }
|
||||
public:
|
||||
/** Test objectID
|
||||
* \return 1, if objectID == 0; 0 if objectID is nonzero.
|
||||
*/
|
||||
virtual int isUnused() const { return (objectID == 0); }
|
||||
/** Initializes object's state, zeroes all members (sets coords to 0, objectID to 0)
|
||||
* \return none
|
||||
*/
|
||||
virtual void setUnused() { objectID = 0; x = 0; y = 0; z = 0; }
|
||||
public:
|
||||
/** object's X coordinate */
|
||||
int x;
|
||||
/** object's Y coordinate */
|
||||
int y;
|
||||
/** object's Z coordinate */
|
||||
int z;
|
||||
/** objectID is unique in game world */
|
||||
unsigned int objectID;
|
||||
};
|
||||
|
||||
#endif
|
678
l2packets/l2world/L2Player.cpp
Normal file
678
l2packets/l2world/L2Player.cpp
Normal file
@@ -0,0 +1,678 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Player.h"
|
||||
#include "../l2data/L2Data.h"
|
||||
#include "../game/L2GamePacket.h"
|
||||
#include "../os/os_abstraction.h"
|
||||
|
||||
L2Player::L2Player()
|
||||
{
|
||||
setUnused();
|
||||
}
|
||||
|
||||
L2Player::~L2Player()
|
||||
{
|
||||
setUnused();
|
||||
}
|
||||
|
||||
L2Player::L2Player( const L2Player& other ): L2Character()
|
||||
{
|
||||
setUnused();
|
||||
this->operator=( other );
|
||||
}
|
||||
|
||||
const L2Player& L2Player::operator=( const L2Player& other )
|
||||
{
|
||||
if( this == &other ) return (*this); // self-assign
|
||||
L2Character::operator=( other );
|
||||
//
|
||||
int i;
|
||||
//
|
||||
classID = other.classID;
|
||||
baseClassID = other.baseClassID;
|
||||
race = other.race;
|
||||
sex = other.sex;
|
||||
hairStyle = other.hairStyle;
|
||||
hairColor = other.hairColor;
|
||||
face = other.face;
|
||||
experience = other.experience;
|
||||
skill_points = other.skill_points;
|
||||
curLoad = other.curLoad;
|
||||
maxLoad = other.maxLoad;
|
||||
pkKills = other.pkKills;
|
||||
pvpKills = other.pvpKills;
|
||||
enchantEffect = other.enchantEffect;
|
||||
relation = other.relation;
|
||||
autoAttackable = other.autoAttackable;
|
||||
for( i=0; i<32; i++ )
|
||||
{
|
||||
paperdoll_oid[i] = other.paperdoll_oid[i];
|
||||
paperdoll_iid[i] = other.paperdoll_iid[i];
|
||||
paperdoll_augid[i] = other.paperdoll_augid[i];
|
||||
}
|
||||
isFakeDeath = other.isFakeDeath;
|
||||
isFishing = other.isFishing;
|
||||
fishX = other.fishX;
|
||||
fishY = other.fishY;
|
||||
fishZ = other.fishZ;
|
||||
privateStoreType = other.privateStoreType;
|
||||
wcsncpy( privateStoreMsgBuy, other.privateStoreMsgBuy, 64 );
|
||||
privateStoreMsgBuy[63] = 0;
|
||||
wcsncpy( privateStoreMsgSell, other.privateStoreMsgSell, 64 );
|
||||
privateStoreMsgSell[63] = 0;
|
||||
wcsncpy( privateStoreMsgRecipe, other.privateStoreMsgRecipe, 64 );
|
||||
privateStoreMsgRecipe[63] = 0;
|
||||
mountType = other.mountType;
|
||||
mountNpcId = other.mountNpcId;
|
||||
recomLeft = other.recomLeft;
|
||||
recomHave = other.recomHave;
|
||||
isNoble = other.isNoble;
|
||||
isHero = other.isHero;
|
||||
nameColor = other.nameColor;
|
||||
titleColor = other.titleColor;
|
||||
pledgeClass = other.pledgeClass;
|
||||
pledgeType = other.pledgeType;
|
||||
cursedWeaponId = other.cursedWeaponId;
|
||||
clanRepScore = other.clanRepScore;
|
||||
transformId = other.transformId;
|
||||
agathionId = other.agathionId;
|
||||
vehicleObjectId = other.vehicleObjectId;
|
||||
hasDwarvenCraft = other.hasDwarvenCraft;
|
||||
numCubics = other.numCubics;
|
||||
for( i=0; i<4; i++ ) cubicId[i] = other.cubicId[i];
|
||||
clanPrivs = other.clanPrivs;
|
||||
inventoryLimit = other.inventoryLimit;
|
||||
elements = other.elements;
|
||||
fame = other.fame;
|
||||
vitalityLevel = other.vitalityLevel;
|
||||
//
|
||||
return (*this);
|
||||
}
|
||||
|
||||
void L2Player::setUnused()
|
||||
{
|
||||
L2Character::setUnused();
|
||||
classID = baseClassID = 0;
|
||||
clanID = clanCrestID = clanCrestLargeID = allyID = allyCrestID = 0;
|
||||
race = sex = 0;
|
||||
hairStyle = hairColor = face = 0;
|
||||
experience = 0;
|
||||
skill_points = 0;
|
||||
curLoad = maxLoad = 0;
|
||||
pkKills = pvpKills = 0;
|
||||
relation = RELATION_NONE;
|
||||
autoAttackable = 0;
|
||||
int i;
|
||||
for( i=0; i<32; i++ )
|
||||
{
|
||||
paperdoll_oid[i] = 0;
|
||||
paperdoll_iid[i] = 0;
|
||||
paperdoll_augid[i] = 0;
|
||||
}
|
||||
isFishing = 0;
|
||||
fishX = fishY = fishZ = 0;
|
||||
privateStoreType = 0;
|
||||
privateStoreMsgBuy[0] = privateStoreMsgSell[0] = privateStoreMsgRecipe[0] = 0;
|
||||
mountType = mountNpcId = 0;
|
||||
recomLeft = recomHave = 0;
|
||||
isNoble = isHero = 0;
|
||||
nameColor = titleColor = 0;
|
||||
pledgeClass = pledgeType = 0;
|
||||
cursedWeaponId = transformId = agathionId = 0;
|
||||
clanRepScore = 0;
|
||||
vehicleObjectId = 0;
|
||||
hasDwarvenCraft = 0;
|
||||
numCubics = 0;
|
||||
for( i=0; i<4; i++ ) cubicId[i] = 0;
|
||||
clanPrivs = 0;
|
||||
inventoryLimit = 0;
|
||||
elements.clear();
|
||||
}
|
||||
|
||||
void L2Player::getRaceStr( wchar_t *out ) const
|
||||
{
|
||||
if( !out ) return;
|
||||
out[0] = 0;
|
||||
const char *ansi = L2Data_getRace( this->race );
|
||||
#ifdef L2PACKETS_WINDOWS
|
||||
_snwprintf( out, 32, L"%S", ansi );
|
||||
#endif
|
||||
#ifdef L2PACKETS_LINUX
|
||||
swprintf( out, 32, L"%ls", ansi );
|
||||
#endif
|
||||
out[31] = 0;
|
||||
}
|
||||
|
||||
void L2Player::getSexStr( wchar_t *out ) const
|
||||
{
|
||||
if( !out ) return;
|
||||
out[0] = 0;
|
||||
const char *ansi = L2Data_getSex( this->sex );
|
||||
#ifdef L2PACKETS_WINDOWS
|
||||
_snwprintf( out, 32, L"%S", ansi );
|
||||
#endif
|
||||
#ifdef L2PACKETS_LINUX
|
||||
swprintf( out, 32, L"%ls", ansi );
|
||||
#endif
|
||||
out[31] = 0;
|
||||
}
|
||||
|
||||
void L2Player::getClassStr( wchar_t *out ) const
|
||||
{
|
||||
if( !out ) return;
|
||||
out[0] = 0;
|
||||
const char *ansi = L2Data_getClass( this->classID );
|
||||
#ifdef L2PACKETS_WINDOWS
|
||||
_snwprintf( out, 32, L"%S", ansi );
|
||||
#endif
|
||||
#ifdef L2PACKETS_LINUX
|
||||
swprintf( out, 32, L"%ls", ansi );
|
||||
#endif
|
||||
out[31] = 0;
|
||||
}
|
||||
|
||||
void L2Player::getBaseClassStr( wchar_t *out ) const
|
||||
{
|
||||
if( !out ) return;
|
||||
out[0] = 0;
|
||||
const char *ansi = L2Data_getClass( this->baseClassID );
|
||||
#ifdef L2PACKETS_WINDOWS
|
||||
_snwprintf( out, 32, L"%S", ansi );
|
||||
#endif
|
||||
#ifdef L2PACKETS_LINUX
|
||||
swprintf( out, 32, L"%ls", ansi );
|
||||
#endif
|
||||
}
|
||||
|
||||
bool L2Player::parse_CharInfo( void *l2_game_packet, L2_VERSION l2_version )
|
||||
{
|
||||
if( !l2_game_packet ) return false;
|
||||
int i;
|
||||
L2GamePacket *p = (L2GamePacket *)l2_game_packet;
|
||||
|
||||
// parse
|
||||
unsigned char ptype = p->getPacketType(); // 0x31
|
||||
if( ptype != 0x31 ) return false;
|
||||
|
||||
x = p->readInt(); // x
|
||||
y = p->readInt(); // y
|
||||
z = p->readInt(); // z
|
||||
p->readUInt(); // 0x00
|
||||
objectID = p->readUInt(); // objectID
|
||||
|
||||
setName( p->readUnicodeStringPtr() ); // name
|
||||
race = p->readUInt(); // race
|
||||
sex = p->readInt(); // sex (0-male)
|
||||
baseClassID = p->readUInt(); // base class
|
||||
|
||||
// paperdoll item IDs
|
||||
paperdoll_iid[L2_PAPERDOLL_UNDER] = p->readUInt(); // PAPERDOLL_UNDER
|
||||
paperdoll_iid[L2_PAPERDOLL_HEAD] = p->readUInt(); // PAPERDOLL_HEAD
|
||||
paperdoll_iid[L2_PAPERDOLL_RHAND] = p->readUInt(); // PAPERDOLL_RHAND
|
||||
paperdoll_iid[L2_PAPERDOLL_LHAND] = p->readUInt(); // PAPERDOLL_LHAND
|
||||
paperdoll_iid[L2_PAPERDOLL_GLOVES] = p->readUInt(); // PAPERDOLL_GLOVES
|
||||
paperdoll_iid[L2_PAPERDOLL_CHEST] = p->readUInt(); // PAPERDOLL_CHEST
|
||||
paperdoll_iid[L2_PAPERDOLL_LEGS] = p->readUInt(); // PAPERDOLL_LEGS
|
||||
paperdoll_iid[L2_PAPERDOLL_FEET] = p->readUInt(); // PAPERDOLL_FEET
|
||||
paperdoll_iid[L2_PAPERDOLL_BACK] = p->readUInt(); // PAPERDOLL_BACK
|
||||
paperdoll_iid[L2_PAPERDOLL_LRHAND] = p->readUInt(); // PAPERDOLL_LRHAND
|
||||
paperdoll_iid[L2_PAPERDOLL_HAIR] = p->readUInt(); // PAPERDOLL_HAIR
|
||||
paperdoll_iid[L2_PAPERDOLL_HAIR2] = p->readUInt(); // PAPERDOLL_HAIR2
|
||||
// kamael
|
||||
paperdoll_iid[L2_PAPERDOLL_RBRACELET] = p->readUInt(); // PAPERDOLL_RBRACELET
|
||||
paperdoll_iid[L2_PAPERDOLL_LBRACELET] = p->readUInt(); // PAPERDOLL_LBRACELET
|
||||
paperdoll_iid[L2_PAPERDOLL_DECO1] = p->readUInt(); // PAPERDOLL_DECO1
|
||||
paperdoll_iid[L2_PAPERDOLL_DECO2] = p->readUInt(); // PAPERDOLL_DECO2
|
||||
paperdoll_iid[L2_PAPERDOLL_DECO3] = p->readUInt(); // PAPERDOLL_DECO3
|
||||
paperdoll_iid[L2_PAPERDOLL_DECO4] = p->readUInt(); // PAPERDOLL_DECO4
|
||||
paperdoll_iid[L2_PAPERDOLL_DECO5] = p->readUInt(); // PAPERDOLL_DECO5
|
||||
paperdoll_iid[L2_PAPERDOLL_DECO6] = p->readUInt(); // PAPERDOLL_DECO6
|
||||
//
|
||||
if( l2_version >= L2_VERSION_T23 )
|
||||
paperdoll_iid[L2_PAPERDOLL_BELT] = p->readUInt(); // PAPERDOLL_BELT
|
||||
|
||||
// paperdoll augmentation IDs
|
||||
paperdoll_augid[L2_PAPERDOLL_UNDER] = p->readUInt(); // PAPERDOLL_UNDER
|
||||
paperdoll_augid[L2_PAPERDOLL_HEAD] = p->readUInt(); // PAPERDOLL_HEAD
|
||||
paperdoll_augid[L2_PAPERDOLL_RHAND] = p->readUInt(); // PAPERDOLL_RHAND
|
||||
paperdoll_augid[L2_PAPERDOLL_LHAND] = p->readUInt(); // PAPERDOLL_LHAND
|
||||
paperdoll_augid[L2_PAPERDOLL_GLOVES] = p->readUInt(); // PAPERDOLL_GLOVES
|
||||
paperdoll_augid[L2_PAPERDOLL_CHEST] = p->readUInt(); // PAPERDOLL_CHEST
|
||||
paperdoll_augid[L2_PAPERDOLL_LEGS] = p->readUInt(); // PAPERDOLL_LEGS
|
||||
paperdoll_augid[L2_PAPERDOLL_FEET] = p->readUInt(); // PAPERDOLL_FEET
|
||||
paperdoll_augid[L2_PAPERDOLL_BACK] = p->readUInt(); // PAPERDOLL_BACK
|
||||
paperdoll_augid[L2_PAPERDOLL_LRHAND] = p->readUInt(); // PAPERDOLL_LRHAND
|
||||
paperdoll_augid[L2_PAPERDOLL_HAIR] = p->readUInt(); // PAPERDOLL_HAIR
|
||||
paperdoll_augid[L2_PAPERDOLL_HAIR2] = p->readUInt(); // PAPERDOLL_HAIR2
|
||||
// kamael
|
||||
paperdoll_augid[L2_PAPERDOLL_RBRACELET] = p->readUInt(); // PAPERDOLL_RBRACELET
|
||||
paperdoll_augid[L2_PAPERDOLL_LBRACELET] = p->readUInt(); // PAPERDOLL_LBRACELET
|
||||
paperdoll_augid[L2_PAPERDOLL_DECO1] = p->readUInt(); // PAPERDOLL_DECO1
|
||||
paperdoll_augid[L2_PAPERDOLL_DECO2] = p->readUInt(); // PAPERDOLL_DECO2
|
||||
paperdoll_augid[L2_PAPERDOLL_DECO3] = p->readUInt(); // PAPERDOLL_DECO3
|
||||
paperdoll_augid[L2_PAPERDOLL_DECO4] = p->readUInt(); // PAPERDOLL_DECO4
|
||||
paperdoll_augid[L2_PAPERDOLL_DECO5] = p->readUInt(); // PAPERDOLL_DECO5
|
||||
paperdoll_augid[L2_PAPERDOLL_DECO6] = p->readUInt(); // PAPERDOLL_DECO6
|
||||
//
|
||||
if( l2_version >= L2_VERSION_T23 )
|
||||
paperdoll_augid[L2_PAPERDOLL_BELT] = p->readUInt(); // PAPERDOLL_BELT
|
||||
|
||||
// Gracia Final 2.3
|
||||
if( l2_version == L2_VERSION_T23 )
|
||||
{
|
||||
p->readD();
|
||||
p->readD();
|
||||
}
|
||||
|
||||
pvpFlag = p->readUInt(); // pvp flag
|
||||
karma = p->readInt(); // karma
|
||||
|
||||
mAtkSpd = p->readInt(); // cast speed
|
||||
pAtkSpd = p->readInt(); // atk speed
|
||||
|
||||
pvpFlag = p->readUInt(); // pvp flag
|
||||
karma = p->readInt(); // karma
|
||||
|
||||
runSpeed = p->readInt(); // run spd
|
||||
walkSpeed = p->readInt(); // walk spd
|
||||
p->readInt(); // _swimRunSpd (?)
|
||||
p->readInt(); // _swimWalkSpd (?)
|
||||
p->readInt(); // _flRunSpd (?)
|
||||
p->readInt(); // _flWalkSpd (?)
|
||||
p->readInt(); // _flyRunSpd (?)
|
||||
p->readInt(); // _flyWalkSpd (?)
|
||||
double moveMult = p->readDouble(); // move spd mult
|
||||
double atkMult = p->readDouble(); // atk spd mult
|
||||
|
||||
// apply multipliers
|
||||
if( moveMult > 0 )
|
||||
{
|
||||
runSpeed = (int)( ((double)(runSpeed)) * moveMult );
|
||||
walkSpeed = (int)( ((double)(walkSpeed)) * moveMult );
|
||||
}
|
||||
if( atkMult > 0 ) pAtkSpd = (int)( ((double)(pAtkSpd)) * atkMult );
|
||||
|
||||
collisionRadius = p->readF(); // collisionRadius
|
||||
collisionHeight = p->readF(); // collisionHeight
|
||||
|
||||
hairStyle = p->readInt();
|
||||
hairColor = p->readInt();
|
||||
face = p->readInt();
|
||||
|
||||
setTitle( p->readUnicodeStringPtr() ); // title
|
||||
|
||||
clanID = p->readUInt();
|
||||
clanCrestID = p->readInt();
|
||||
allyID = p->readInt();
|
||||
allyCrestID = p->readInt();
|
||||
p->readInt(); // relation(?), which is always 0
|
||||
|
||||
isSitting = (int)(!p->readUChar()); // standing = 1 sitting = 0
|
||||
isRunning = (int)p->readUChar(); // running = 1 walking = 0
|
||||
isInCombat = (int)p->readUChar();
|
||||
isAlikeDead = (int)p->readUChar();
|
||||
|
||||
p->readUChar(); // invisible = 1 visible =0
|
||||
|
||||
this->mountType = p->readUChar(); // 1-on Strider, 2-on Wyvern, 3-on Great Wolf, 0-no mount
|
||||
this->privateStoreType = p->readUChar(); // 1 - sellshop
|
||||
|
||||
// cubics
|
||||
numCubics = (int)p->readUShort(); // cubics count
|
||||
if( numCubics > 4 ) numCubics = 4;
|
||||
for( i=0; i<numCubics; i++ )
|
||||
cubicId[i] = (unsigned int)p->readUShort(); // cubic ID
|
||||
|
||||
p->readUChar(); // find party members
|
||||
abnormalEffect = p->readUInt(); // abnormalEffect
|
||||
|
||||
recomLeft = (int)p->readUChar();
|
||||
recomHave = (int)p->readUShort(); // Blue value for name (0 = white, 255 = pure blue)
|
||||
mountNpcId = p->readUInt() - 1000000; // mountNpcId + 1000000
|
||||
|
||||
classID = p->readUInt(); // class ID
|
||||
p->readUInt(); // 0x00
|
||||
enchantEffect = (unsigned int)p->readUChar();
|
||||
|
||||
p->readUChar(); // team circle around feet 1 = Blue, 2 = red
|
||||
|
||||
clanCrestLargeID = p->readUInt();
|
||||
isNoble = p->readUChar();
|
||||
isHero = p->readUChar(); // hero aura
|
||||
|
||||
isFishing = p->readUChar(); // 0x01: Fishing Mode (Cant be undone by setting back to 0)
|
||||
fishX = p->readInt();
|
||||
fishY = p->readInt();
|
||||
fishZ = p->readInt();
|
||||
|
||||
nameColor = p->readInt();
|
||||
heading = p->readUInt();
|
||||
|
||||
pledgeClass = p->readUInt(); // PledgeClass
|
||||
pledgeType = p->readUInt(); // PledgeType
|
||||
|
||||
titleColor = p->readUInt(); // TitleColor
|
||||
|
||||
cursedWeaponId = p->readUInt(); // CursedWeaponEquippedId
|
||||
|
||||
clanRepScore = p->readInt(); // clan ReputationScore
|
||||
|
||||
// T1
|
||||
transformId = p->readUInt(); // TransformationId
|
||||
agathionId = p->readUInt(); // AgathionId
|
||||
|
||||
// T2
|
||||
//writeD(0x01);
|
||||
|
||||
// T2.3
|
||||
//writeD(0x00);
|
||||
//writeD(0x00);
|
||||
//writeD(0x00);
|
||||
//writeD(0x00);
|
||||
|
||||
// set last time when char coordinates were known exactly
|
||||
lastMoveTickTime = OS_GetTickCount();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Player::parse_UserInfo( void *l2_game_packet, L2_VERSION l2_version )
|
||||
{
|
||||
if( !l2_game_packet ) return false;
|
||||
|
||||
unsigned int tempUINT;
|
||||
int i;
|
||||
L2GamePacket *p = (L2GamePacket *)l2_game_packet;
|
||||
|
||||
unsigned char ptype = p->getPacketType();
|
||||
if( ptype != 0x32 ) return false;
|
||||
|
||||
x = p->readInt();
|
||||
y = p->readInt();
|
||||
z = p->readInt();
|
||||
|
||||
if( l2_version <= L2_VERSION_T22 ) heading = p->readUInt();
|
||||
else if( l2_version >= L2_VERSION_T23 ) vehicleObjectId = p->readUInt();
|
||||
|
||||
objectID = p->readUInt();
|
||||
|
||||
setName( p->readUnicodeStringPtr() );
|
||||
race = p->readInt();
|
||||
sex = p->readInt();
|
||||
|
||||
baseClassID = p->readUInt();
|
||||
|
||||
level = p->readInt();
|
||||
experience = p->readUInt64();
|
||||
|
||||
s_STR = p->readInt(); // writeD(_activeChar.getSTR());
|
||||
s_DEX = p->readInt(); // writeD(_activeChar.getDEX());
|
||||
s_CON = p->readInt(); // writeD(_activeChar.getCON());
|
||||
s_INT = p->readInt(); // writeD(_activeChar.getINT());
|
||||
s_WIT = p->readInt(); // writeD(_activeChar.getWIT());
|
||||
s_MEN = p->readInt(); // writeD(_activeChar.getMEN());
|
||||
|
||||
maxHp = (double)p->readInt(); // writeD(_activeChar.getMaxHp());
|
||||
curHp = (double)p->readInt(); // writeD((int) _activeChar.getCurrentHp());
|
||||
maxMp = (double)p->readInt(); // writeD(_activeChar.getMaxMp());
|
||||
curMp = (double)p->readInt(); //writeD((int) _activeChar.getCurrentMp());
|
||||
skill_points = p->readUInt(); // writeD(_activeChar.getSp());
|
||||
curLoad = p->readUInt(); // writeD(_activeChar.getCurrentLoad());
|
||||
maxLoad = p->readUInt(); // writeD(_activeChar.getMaxLoad());
|
||||
|
||||
//writeD(_activeChar.getActiveWeaponItem() != null ? 0x40 : 0x20); // 0x20 no weapon, 0x40 weapon equipped
|
||||
bool isWeaponEquipped = false; // why?... cannot we check weapon paperdoll objectId/itemId?
|
||||
tempUINT = p->readUInt();
|
||||
if( tempUINT == 0x40 ) isWeaponEquipped = true;
|
||||
|
||||
// paperdoll and its augments
|
||||
// paperdoll objectIDs (25 items)
|
||||
paperdoll_oid[L2_PAPERDOLL_UNDER] = p->readUInt(); // Inventory.PAPERDOLL_UNDER));
|
||||
paperdoll_oid[L2_PAPERDOLL_REAR] = p->readUInt(); // writeD(....PAPERDOLL_REAR));
|
||||
paperdoll_oid[L2_PAPERDOLL_LEAR] = p->readUInt(); // writeD(....PAPERDOLL_LEAR));
|
||||
paperdoll_oid[L2_PAPERDOLL_NECK] = p->readUInt(); // writeD(....PAPERDOLL_NECK));
|
||||
paperdoll_oid[L2_PAPERDOLL_RFINGER] = p->readUInt(); // writeD(....PAPERDOLL_RFINGER));
|
||||
paperdoll_oid[L2_PAPERDOLL_LFINGER] = p->readUInt(); // writeD(....PAPERDOLL_LFINGER));
|
||||
paperdoll_oid[L2_PAPERDOLL_HEAD] = p->readUInt(); // writeD(....PAPERDOLL_HEAD));
|
||||
paperdoll_oid[L2_PAPERDOLL_RHAND] = p->readUInt(); // writeD(....PAPERDOLL_RHAND));
|
||||
paperdoll_oid[L2_PAPERDOLL_LHAND] = p->readUInt(); // writeD(....PAPERDOLL_LHAND));
|
||||
paperdoll_oid[L2_PAPERDOLL_GLOVES] = p->readUInt(); // writeD(....PAPERDOLL_GLOVES));
|
||||
paperdoll_oid[L2_PAPERDOLL_CHEST] = p->readUInt(); // writeD(....PAPERDOLL_CHEST));
|
||||
paperdoll_oid[L2_PAPERDOLL_LEGS] = p->readUInt(); // writeD(....PAPERDOLL_LEGS));
|
||||
paperdoll_oid[L2_PAPERDOLL_FEET] = p->readUInt(); // writeD(....PAPERDOLL_FEET));
|
||||
paperdoll_oid[L2_PAPERDOLL_BACK] = p->readUInt(); // writeD(....PAPERDOLL_BACK));
|
||||
paperdoll_oid[L2_PAPERDOLL_LRHAND] = p->readUInt(); // writeD(....PAPERDOLL_LRHAND));
|
||||
paperdoll_oid[L2_PAPERDOLL_HAIR] = p->readUInt(); // writeD(....PAPERDOLL_HAIR));
|
||||
paperdoll_oid[L2_PAPERDOLL_HAIR2] = p->readUInt(); // writeD(....PAPERDOLL_HAIR2));
|
||||
// T1 new D's
|
||||
paperdoll_oid[L2_PAPERDOLL_RBRACELET] = p->readUInt(); // writeD(....PAPERDOLL_RBRACELET));
|
||||
paperdoll_oid[L2_PAPERDOLL_LBRACELET] = p->readUInt(); // writeD(....PAPERDOLL_LBRACELET));
|
||||
paperdoll_oid[L2_PAPERDOLL_DECO1] = p->readUInt(); // writeD(....PAPERDOLL_DECO1));
|
||||
paperdoll_oid[L2_PAPERDOLL_DECO2] = p->readUInt(); // writeD(....PAPERDOLL_DECO2));
|
||||
paperdoll_oid[L2_PAPERDOLL_DECO3] = p->readUInt(); // writeD(....PAPERDOLL_DECO3));
|
||||
paperdoll_oid[L2_PAPERDOLL_DECO4] = p->readUInt(); // writeD(....PAPERDOLL_DECO4));
|
||||
paperdoll_oid[L2_PAPERDOLL_DECO5] = p->readUInt(); // writeD(....PAPERDOLL_DECO5));
|
||||
paperdoll_oid[L2_PAPERDOLL_DECO6] = p->readUInt(); // writeD(....PAPERDOLL_DECO6));
|
||||
if( l2_version >= L2_VERSION_T23 )
|
||||
paperdoll_oid[L2_PAPERDOLL_BELT] = p->readUInt(); // PAPERDOLL_BELT
|
||||
|
||||
// paperdoll itemIDs (25 items)
|
||||
paperdoll_iid[L2_PAPERDOLL_UNDER] = p->readUInt(); // Inventory.PAPERDOLL_UNDER));
|
||||
paperdoll_iid[L2_PAPERDOLL_REAR] = p->readUInt(); // writeD(....PAPERDOLL_REAR));
|
||||
paperdoll_iid[L2_PAPERDOLL_LEAR] = p->readUInt(); // writeD(....PAPERDOLL_LEAR));
|
||||
paperdoll_iid[L2_PAPERDOLL_NECK] = p->readUInt(); // writeD(....PAPERDOLL_NECK));
|
||||
paperdoll_iid[L2_PAPERDOLL_RFINGER] = p->readUInt(); // writeD(....PAPERDOLL_RFINGER));
|
||||
paperdoll_iid[L2_PAPERDOLL_LFINGER] = p->readUInt(); // writeD(....PAPERDOLL_LFINGER));
|
||||
paperdoll_iid[L2_PAPERDOLL_HEAD] = p->readUInt(); // writeD(....PAPERDOLL_HEAD));
|
||||
paperdoll_iid[L2_PAPERDOLL_RHAND] = p->readUInt(); // writeD(....PAPERDOLL_RHAND));
|
||||
paperdoll_iid[L2_PAPERDOLL_LHAND] = p->readUInt(); // writeD(....PAPERDOLL_LHAND));
|
||||
paperdoll_iid[L2_PAPERDOLL_GLOVES] = p->readUInt(); // writeD(....PAPERDOLL_GLOVES));
|
||||
paperdoll_iid[L2_PAPERDOLL_CHEST] = p->readUInt(); // writeD(....PAPERDOLL_CHEST));
|
||||
paperdoll_iid[L2_PAPERDOLL_LEGS] = p->readUInt(); // writeD(....PAPERDOLL_LEGS));
|
||||
paperdoll_iid[L2_PAPERDOLL_FEET] = p->readUInt(); // writeD(....PAPERDOLL_FEET));
|
||||
paperdoll_iid[L2_PAPERDOLL_BACK] = p->readUInt(); // writeD(....PAPERDOLL_BACK));
|
||||
paperdoll_iid[L2_PAPERDOLL_LRHAND] = p->readUInt(); // writeD(....PAPERDOLL_LRHAND));
|
||||
paperdoll_iid[L2_PAPERDOLL_HAIR] = p->readUInt(); // writeD(....PAPERDOLL_HAIR));
|
||||
paperdoll_iid[L2_PAPERDOLL_HAIR2] = p->readUInt(); // writeD(....PAPERDOLL_HAIR2));
|
||||
// T1 new D's
|
||||
paperdoll_iid[L2_PAPERDOLL_RBRACELET] = p->readUInt(); // writeD(....PAPERDOLL_RBRACELET));
|
||||
paperdoll_iid[L2_PAPERDOLL_LBRACELET] = p->readUInt(); // writeD(....PAPERDOLL_LBRACELET));
|
||||
paperdoll_iid[L2_PAPERDOLL_DECO1] = p->readUInt(); // writeD(....PAPERDOLL_DECO1));
|
||||
paperdoll_iid[L2_PAPERDOLL_DECO2] = p->readUInt(); // writeD(....PAPERDOLL_DECO2));
|
||||
paperdoll_iid[L2_PAPERDOLL_DECO3] = p->readUInt(); // writeD(....PAPERDOLL_DECO3));
|
||||
paperdoll_iid[L2_PAPERDOLL_DECO4] = p->readUInt(); // writeD(....PAPERDOLL_DECO4));
|
||||
paperdoll_iid[L2_PAPERDOLL_DECO5] = p->readUInt(); // writeD(....PAPERDOLL_DECO5));
|
||||
paperdoll_iid[L2_PAPERDOLL_DECO6] = p->readUInt(); // writeD(....PAPERDOLL_DECO6));
|
||||
if( l2_version >= L2_VERSION_T23 )
|
||||
paperdoll_iid[L2_PAPERDOLL_BELT] = p->readUInt(); // PAPERDOLL_BELT
|
||||
|
||||
// paperdoll augmentation IDs (25 items)
|
||||
//for( i=0; i<25; i++ ) p->readUInt();
|
||||
paperdoll_augid[L2_PAPERDOLL_UNDER] = p->readUInt(); // Inventory.PAPERDOLL_UNDER));
|
||||
paperdoll_augid[L2_PAPERDOLL_REAR] = p->readUInt(); // writeD(....PAPERDOLL_REAR));
|
||||
paperdoll_augid[L2_PAPERDOLL_LEAR] = p->readUInt(); // writeD(....PAPERDOLL_LEAR));
|
||||
paperdoll_augid[L2_PAPERDOLL_NECK] = p->readUInt(); // writeD(....PAPERDOLL_NECK));
|
||||
paperdoll_augid[L2_PAPERDOLL_RFINGER] = p->readUInt(); // writeD(....PAPERDOLL_RFINGER));
|
||||
paperdoll_augid[L2_PAPERDOLL_LFINGER] = p->readUInt(); // writeD(....PAPERDOLL_LFINGER));
|
||||
paperdoll_augid[L2_PAPERDOLL_HEAD] = p->readUInt(); // writeD(....PAPERDOLL_HEAD));
|
||||
paperdoll_augid[L2_PAPERDOLL_RHAND] = p->readUInt(); // writeD(....PAPERDOLL_RHAND));
|
||||
paperdoll_augid[L2_PAPERDOLL_LHAND] = p->readUInt(); // writeD(....PAPERDOLL_LHAND));
|
||||
paperdoll_augid[L2_PAPERDOLL_GLOVES] = p->readUInt(); // writeD(....PAPERDOLL_GLOVES));
|
||||
paperdoll_augid[L2_PAPERDOLL_CHEST] = p->readUInt(); // writeD(....PAPERDOLL_CHEST));
|
||||
paperdoll_augid[L2_PAPERDOLL_LEGS] = p->readUInt(); // writeD(....PAPERDOLL_LEGS));
|
||||
paperdoll_augid[L2_PAPERDOLL_FEET] = p->readUInt(); // writeD(....PAPERDOLL_FEET));
|
||||
paperdoll_augid[L2_PAPERDOLL_BACK] = p->readUInt(); // writeD(....PAPERDOLL_BACK));
|
||||
paperdoll_augid[L2_PAPERDOLL_LRHAND] = p->readUInt(); // writeD(....PAPERDOLL_LRHAND));
|
||||
paperdoll_augid[L2_PAPERDOLL_HAIR] = p->readUInt(); // writeD(....PAPERDOLL_HAIR));
|
||||
paperdoll_augid[L2_PAPERDOLL_HAIR2] = p->readUInt(); // writeD(....PAPERDOLL_HAIR2));
|
||||
// T1 new D's
|
||||
paperdoll_augid[L2_PAPERDOLL_RBRACELET] = p->readUInt(); // writeD(....PAPERDOLL_RBRACELET));
|
||||
paperdoll_augid[L2_PAPERDOLL_LBRACELET] = p->readUInt(); // writeD(....PAPERDOLL_LBRACELET));
|
||||
paperdoll_augid[L2_PAPERDOLL_DECO1] = p->readUInt(); // writeD(....PAPERDOLL_DECO1));
|
||||
paperdoll_augid[L2_PAPERDOLL_DECO2] = p->readUInt(); // writeD(....PAPERDOLL_DECO2));
|
||||
paperdoll_augid[L2_PAPERDOLL_DECO3] = p->readUInt(); // writeD(....PAPERDOLL_DECO3));
|
||||
paperdoll_augid[L2_PAPERDOLL_DECO4] = p->readUInt(); // writeD(....PAPERDOLL_DECO4));
|
||||
paperdoll_augid[L2_PAPERDOLL_DECO5] = p->readUInt(); // writeD(....PAPERDOLL_DECO5));
|
||||
paperdoll_augid[L2_PAPERDOLL_DECO6] = p->readUInt(); // writeD(....PAPERDOLL_DECO6));
|
||||
if( l2_version >= L2_VERSION_T23 )
|
||||
paperdoll_augid[L2_PAPERDOLL_BELT] = p->readUInt(); // PAPERDOLL_BELT
|
||||
|
||||
// T2.3 some 2 Ds
|
||||
if( l2_version >= L2_VERSION_T23 )
|
||||
{
|
||||
p->readD();
|
||||
p->readD();
|
||||
}
|
||||
|
||||
pAtk = p->readInt(); // writeD(_activeChar.getPAtk(null));
|
||||
pAtkSpd = p->readInt(); // writeD(_activeChar.getPAtkSpd());
|
||||
pDef = p->readInt(); // writeD(_activeChar.getPDef(null));
|
||||
evasion = p->readInt(); // writeD(_activeChar.getEvasionRate(null));
|
||||
accuracy = p->readInt(); // writeD(_activeChar.getAccuracy());
|
||||
critical = p->readInt(); // writeD(_activeChar.getCriticalHit(null, null));
|
||||
mAtk = p->readInt(); // writeD(_activeChar.getMAtk(null, null));
|
||||
mAtkSpd = p->readInt(); // writeD(_activeChar.getMAtkSpd());
|
||||
pAtkSpd = p->readInt(); // writeD(_activeChar.getPAtkSpd());
|
||||
mDef = p->readInt(); // writeD(_activeChar.getMDef(null, null));
|
||||
|
||||
pvpFlag = p->readInt(); // writeD(_activeChar.getPvpFlag()); // 0-non-pvp 1-pvp = violett name
|
||||
karma = p->readInt(); // writeD(_activeChar.getKarma());
|
||||
|
||||
runSpeed = p->readInt(); // writeD(_runSpd);
|
||||
walkSpeed = p->readInt(); // writeD(_walkSpd);
|
||||
p->readInt(); // writeD(_swimRunSpd); // swimspeed
|
||||
p->readInt(); // writeD(_swimWalkSpd); // swimspeed
|
||||
p->readInt(); // writeD(_flRunSpd);
|
||||
p->readInt(); // writeD(_flWalkSpd);
|
||||
p->readInt(); // writeD(_flyRunSpd);
|
||||
p->readInt(); // writeD(_flyWalkSpd);
|
||||
double moveMultiplier = p->readDouble(); // writeF(_moveMultiplier);
|
||||
double attackSpeedMultiplier = p->readDouble(); // writeF(_activeChar.getAttackSpeedMultiplier());
|
||||
if( moveMultiplier > 0.0 )
|
||||
{
|
||||
runSpeed = (int)( ((double)(runSpeed)) * moveMultiplier + 0.5 );
|
||||
walkSpeed = (int)( ((double)(walkSpeed)) * moveMultiplier + 0.5 );
|
||||
}
|
||||
if( attackSpeedMultiplier > 0.0 )
|
||||
{
|
||||
pAtkSpd = (int)( ((double)(pAtkSpd)) * attackSpeedMultiplier);
|
||||
}
|
||||
|
||||
collisionRadius = p->readDouble(); // writeF(_activeChar.getBaseTemplate().collisionRadius);
|
||||
collisionHeight = p->readDouble(); // writeF(_activeChar.getBaseTemplate().collisionHeight);
|
||||
|
||||
hairStyle = p->readInt(); // writeD(_activeChar.getAppearance().getHairStyle());
|
||||
hairColor = p->readInt(); // writeD(_activeChar.getAppearance().getHairColor());
|
||||
face = p->readInt(); // writeD(_activeChar.getAppearance().getFace());
|
||||
/*isGm =*/ p->readInt(); // writeD(_activeChar.isGM() ? 1 : 0); // builder level
|
||||
|
||||
setTitle( p->readS() ); // writeS(title);
|
||||
|
||||
clanID = p->readUInt(); // writeD(_activeChar.getClanId());
|
||||
clanCrestID = p->readUInt(); // writeD(_activeChar.getClanCrestId());
|
||||
allyID = p->readUInt(); // writeD(_activeChar.getAllyId());
|
||||
allyCrestID = p->readUInt(); // writeD(_activeChar.getAllyCrestId()); // ally crest id
|
||||
// 0x40 leader rights
|
||||
// siege flags: attacker - 0x180 sword over name, defender - 0x80 shield, 0xC0 crown (|leader), 0x1C0 flag (|leader)
|
||||
relation = p->readUInt(); // writeD(_relation);
|
||||
mountType = p->readUChar(); // writeC(_activeChar.getMountType()); // mount type
|
||||
privateStoreType = (int)p->readUChar(); // writeC(_activeChar.getPrivateStoreType());
|
||||
hasDwarvenCraft = p->readUChar(); // writeC(_activeChar.hasDwarvenCraft() ? 1 : 0);
|
||||
pkKills = p->readInt(); // writeD(_activeChar.getPkKills());
|
||||
pvpKills = p->readInt(); // writeD(_activeChar.getPvpKills());
|
||||
|
||||
numCubics = p->readUShort(); // writeH(_activeChar.getCubics().size());
|
||||
if( numCubics > 4 ) numCubics = 4; // safe
|
||||
for( i=0; i<numCubics; i++ )
|
||||
cubicId[i] = p->readUShort(); //for (int id : _activeChar.getCubics().keySet()) writeH(id);
|
||||
|
||||
p->readUChar(); // writeC(0x00); //1-find party members
|
||||
|
||||
abnormalEffect = p->readUInt(); // writeD(_activeChar.getAbnormalEffect());
|
||||
p->readChar(); // writeC(0x00);
|
||||
|
||||
clanPrivs = p->readUInt(); // writeD(_activeChar.getClanPrivileges());
|
||||
|
||||
recomLeft = p->readUShort(); // writeH(_activeChar.getRecomLeft());
|
||||
recomHave = p->readUShort(); // writeH(_activeChar.getRecomHave());
|
||||
mountNpcId = p->readUInt(); // writeD(_activeChar.getMountNpcId() + 1000000);
|
||||
inventoryLimit = p->readUShort(); // writeH(_activeChar.getInventoryLimit());
|
||||
|
||||
classID = p->readUInt(); // writeD(_activeChar.getClassId().getId());
|
||||
p->readUInt(); // writeD(0x00); // special effects? circles around player...
|
||||
maxCp = (double)p->readInt(); // writeD(_activeChar.getMaxCp());
|
||||
curCp = (double)p->readInt(); // writeD((int) _activeChar.getCurrentCp());
|
||||
enchantEffect = p->readUChar(); // writeC(_activeChar.getEnchantEffect());
|
||||
|
||||
p->readUChar(); // writeC(0x00); //team circle around feet 1= Blue, 2 = red
|
||||
|
||||
clanCrestLargeID = p->readUInt(); // writeD(_activeChar.getClanCrestLargeId());
|
||||
isNoble = p->readUChar(); // writeC(_activeChar.isNoble() ? 1 : 0);
|
||||
isHero = p->readUChar(); // writeC(_activeChar.isHero()
|
||||
|
||||
isFishing = p->readUChar(); // writeC(_activeChar.isFishing() ? 1 : 0); //Fishing Mode
|
||||
fishX = p->readUInt(); // writeD(_activeChar.getFishx()); //fishing x
|
||||
fishY = p->readUInt(); // writeD(_activeChar.getFishy()); //fishing y
|
||||
fishZ = p->readUInt(); // writeD(_activeChar.getFishz()); //fishing z
|
||||
nameColor = p->readUInt(); // writeD(_activeChar.getAppearance().getNameColor());
|
||||
|
||||
//new c5
|
||||
isRunning = (int)p->readUChar(); // writeC(_activeChar.isRunning() ? 0x01 : 0x00); //changes the Speed display on Status Window
|
||||
|
||||
pledgeClass = p->readUInt(); // writeD(_activeChar.getPledgeClass()); //changes the text above CP on Status Window
|
||||
pledgeType = p->readUInt(); // writeD(_activeChar.getPledgeType());
|
||||
|
||||
titleColor = p->readUInt(); // writeD(_activeChar.getAppearance().getTitleColor());
|
||||
|
||||
// writeD(CursedWeaponsManager.getInstance().getLevel(_activeChar.getCursedWeaponEquippedId()));
|
||||
cursedWeaponId = p->readUInt(); // cursedWeapon
|
||||
|
||||
// T1 Starts
|
||||
transformId = p->readUInt(); // writeD(_activeChar.getTransformationId());
|
||||
|
||||
if( l2_version < L2_VERSION_T23 )
|
||||
{
|
||||
elements.attackElementType = p->readD(); // writeD(_activeChar.getAttackElement());
|
||||
elements.attackElementValue = p->readD(); // writeD(_activeChar.getAttackElementValue());
|
||||
elements.defAttrFire = p->readD(); // writeD(_activeChar.getDefAttrFire());
|
||||
elements.defAttrWater = p->readD(); // writeD(_activeChar.getDefAttrWater());
|
||||
elements.defAttrWind = p->readD(); // writeD(_activeChar.getDefAttrWind());
|
||||
elements.defAttrEarth = p->readD(); // writeD(_activeChar.getDefAttrEarth());
|
||||
elements.defAttrHoly = p->readD(); // writeD(_activeChar.getDefAttrHoly());
|
||||
elements.defAttrUnholy = p->readD(); // writeD(_activeChar.getDefAttrUnholy());
|
||||
}
|
||||
else
|
||||
{
|
||||
elements.attackElementType = p->readH(); // writeH(attackAttribute);
|
||||
elements.attackElementValue = p->readH(); // writeH(_activeChar.getAttackElementValue(attackAttribute));
|
||||
elements.defAttrFire = p->readH(); // writeH(_activeChar.getDefenseElementValue(Elementals.FIRE));
|
||||
elements.defAttrWater = p->readH(); // writeH(_activeChar.getDefenseElementValue(Elementals.WATER));
|
||||
elements.defAttrWind = p->readH(); // writeH(_activeChar.getDefenseElementValue(Elementals.WIND));
|
||||
elements.defAttrEarth = p->readH(); // writeH(_activeChar.getDefenseElementValue(Elementals.EARTH));
|
||||
elements.defAttrHoly = p->readH(); // writeH(_activeChar.getDefenseElementValue(Elementals.HOLY));
|
||||
elements.defAttrUnholy = p->readH(); // writeH(_activeChar.getDefenseElementValue(Elementals.DARK));
|
||||
}
|
||||
|
||||
agathionId = p->readUInt(); // writeD(_activeChar.getAgathionId());
|
||||
|
||||
// T2
|
||||
if( l2_version >= L2_VERSION_T2 )
|
||||
{
|
||||
fame = p->readUInt(); // writeD(_activeChar.getFame()); // Fame
|
||||
p->readUInt(); // writeD(0x00); // Unknown // 0x01 in CT2.3
|
||||
vitalityLevel = p->readUInt(); // writeD(_activeChar.getVitalityLevel()); // Vitality Level
|
||||
}
|
||||
|
||||
// T2.3
|
||||
//if( l2_version >= L2_VERSION_T23 )
|
||||
//{
|
||||
//writeD(0x00); // CT2.3
|
||||
//writeD(0x00); // CT2.3
|
||||
//writeD(0x00); // CT2.3
|
||||
//writeD(0x00); // CT2.3
|
||||
//}
|
||||
|
||||
// set last time when char coordinates were known exactly
|
||||
lastMoveTickTime = OS_GetTickCount();
|
||||
|
||||
return true;
|
||||
}
|
170
l2packets/l2world/L2Player.h
Normal file
170
l2packets/l2world/L2Player.h
Normal file
@@ -0,0 +1,170 @@
|
||||
#ifndef H_L2PLAYER
|
||||
#define H_L2PLAYER
|
||||
#include "L2Character.h"
|
||||
#include "L2PlayerPaperDoll.h"
|
||||
#include "L2ElementalInfo.h"
|
||||
|
||||
/** \class L2Player
|
||||
Every L2Npc is L2Character:\n
|
||||
Every L2Character is L2Object (has objectID, x, y, z)\n
|
||||
Every L2Character has LEVEL!\n
|
||||
Every L2Character has its charName and charTitle\n
|
||||
Every L2Character has its heading\n
|
||||
Every L2Character has its hairStyle, hairColor and face\n
|
||||
Every L2Character has moving speed in states: running, walking\n
|
||||
Every L2Character has its move destination: xDst, yDst, zDst\n
|
||||
Every L2Character can calc its position based on destnation point and time passed since last calc\n
|
||||
Every L2Character has its base stats: INT WIT MEN CON STR DEX\n
|
||||
Every L2Character has its stats: pAtk, mAtk, ..., curHp, maxHp, ...\n
|
||||
Every L2Character has abnormalEffect\n
|
||||
Every L2Character has its target\n
|
||||
Every L2Character can be in combat\n
|
||||
Every L2Character has its collision radius and height\n
|
||||
\n
|
||||
Additionally:\n
|
||||
Every L2Player has classID, baseClassID\n
|
||||
Every L2Player has its appearance (Race, Sex, Face, Hair style, Hair color)\n
|
||||
Every L2Player has enchantEffect\n
|
||||
Every L2Player has its paperdoll: items equipped on it. Every paperdoll item can have augment ID\n
|
||||
Every L2Player can fish: has isFishing, fishX, fishY, fishZ\n
|
||||
Every L2Player can create sell shop: sell, buy, package sale, craft shop (has shop type and shop message)\n
|
||||
Every L2Player can ride animals (mount NPC)\n
|
||||
Every L2Player can give and receive recommendations\n
|
||||
Every L2Player can be noble and hero\n
|
||||
\n
|
||||
Additionally, some values come from RelationChanged packet, not in CharInfo\n
|
||||
Every L2Player has relation to current user\n
|
||||
Every L2Player can be autoAttackable\n
|
||||
\n
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class L2Player : public L2Character
|
||||
{
|
||||
public:
|
||||
/** Default constructor, just calls setUnused() (zeroes all members) */
|
||||
L2Player();
|
||||
|
||||
/** Copy constructor.
|
||||
* \param other source to copy from
|
||||
*/
|
||||
L2Player( const L2Player& other );
|
||||
|
||||
/** Operator=
|
||||
* \param other source to copy from
|
||||
* \return reference to this object
|
||||
*/
|
||||
virtual const L2Player& operator=( const L2Player& other );
|
||||
|
||||
/** Just calls setUnused() (zeroes all members) */
|
||||
virtual ~L2Player();
|
||||
public:
|
||||
/** Initializes object state (zeroes all members) */
|
||||
virtual void setUnused();
|
||||
public:
|
||||
/** Converts player's race ID to displayable string
|
||||
* \param out pointer to unicode string buffer to receive string
|
||||
* \return out
|
||||
*/
|
||||
virtual void getRaceStr( wchar_t *out ) const;
|
||||
|
||||
/** Converts player's sex number to displayable string
|
||||
* \param out pointer to unicode string buffer to receive string
|
||||
* \return out
|
||||
*/
|
||||
virtual void getSexStr( wchar_t *out ) const;
|
||||
|
||||
/** Converts player's class ID to displayable string.\n
|
||||
* This is current selected subclass (not base class).
|
||||
* \param out pointer to unicode string buffer to receive string
|
||||
* \return out
|
||||
*/
|
||||
virtual void getClassStr( wchar_t *out ) const;
|
||||
|
||||
/** Converts player's base class ID to displayable string.\n
|
||||
* This is always player's base class.
|
||||
* \param out pointer to unicode string buffer to receive string
|
||||
* \return out
|
||||
*/
|
||||
virtual void getBaseClassStr( wchar_t *out ) const;
|
||||
|
||||
public:
|
||||
// relation to current user constants
|
||||
static const int RELATION_NONE = 0; ///< default value, no mean
|
||||
static const int RELATION_PVP_FLAG = 0x00002; ///< pvp ???
|
||||
static const int RELATION_HAS_KARMA = 0x00004; ///< karma ???
|
||||
static const int RELATION_LEADER = 0x00080; ///< leader
|
||||
static const int RELATION_INSIEGE = 0x00200; ///< true if in siege
|
||||
static const int RELATION_ATTACKER = 0x00400; ///< true when attacker
|
||||
static const int RELATION_ALLY = 0x00800; ///< blue siege icon, cannot have if red
|
||||
static const int RELATION_ENEMY = 0x01000; ///< true when red icon, doesn't matter with blue
|
||||
static const int RELATION_MUTUAL_WAR = 0x08000; ///< double fist (war)
|
||||
static const int RELATION_1SIDED_WAR = 0x10000; ///< single fist (war)
|
||||
// private store type constants
|
||||
static const int PRIVATE_STORE_NONE = 0; ///< player has no private store
|
||||
static const int PRIVATE_STORE_SELL = 1; ///< player is selling
|
||||
static const int PRIVATE_STORE_BUY = 3; ///< player is buying
|
||||
static const int PRIVATE_STORE_CRAFT = 5; ///< player is sitting in recipe shop mode
|
||||
static const int PRIVATE_STORE_PACKAGESALE = 8; ///< player is in package sale mode
|
||||
|
||||
public:
|
||||
bool parse_CharInfo( void *l2_game_packet, L2_VERSION l2_version );
|
||||
bool parse_UserInfo( void *l2_game_packet, L2_VERSION l2_version );
|
||||
|
||||
public:
|
||||
unsigned int classID; ///< current class ID, which may be subclass and may differ from base class ID
|
||||
unsigned int baseClassID; ///< player's base class ID
|
||||
int race; ///< race number
|
||||
int sex; ///< 1 - female, 0 - male
|
||||
int hairStyle;
|
||||
int hairColor;
|
||||
int face;
|
||||
unsigned long long experience; // only from UserInfo
|
||||
unsigned int skill_points; // only from UserInfo
|
||||
int curLoad; // only from UserInfo
|
||||
int maxLoad; // only from UserInfo
|
||||
int pkKills; // only from UserInfo
|
||||
int pvpKills; // only from UserInfo
|
||||
unsigned int enchantEffect; ///< player's weapon enchant value
|
||||
// from RelationChanged
|
||||
unsigned int relation; ///< relation (siege flags and clan war flags,fists)
|
||||
int autoAttackable; ///< 1, if player is auto attackable (2-sided war, for example)
|
||||
unsigned int paperdoll_oid[32]; ///< array of paperdoll objectIDs (only from UserInfo)
|
||||
unsigned int paperdoll_iid[32]; ///< array of paperdoll itemIDs
|
||||
unsigned int paperdoll_augid[32]; ///< array of paperdoll augmentationIDs
|
||||
int isFakeDeath;
|
||||
int isFishing;
|
||||
int fishX;
|
||||
int fishY;
|
||||
int fishZ;
|
||||
int privateStoreType; ///< player's private store type. See PRIVATE_STORE_* constants (1 - sellshop, ...)
|
||||
wchar_t privateStoreMsgBuy[64]; ///< buy shop message
|
||||
wchar_t privateStoreMsgSell[64]; ///< sell shop message
|
||||
wchar_t privateStoreMsgRecipe[64]; ///< recipe shop message
|
||||
unsigned int mountType; ///< 1-on Strider, 2-on Wyvern, 3-on Great Wolf, 0-no mount
|
||||
unsigned int mountNpcId; ///< mount NPC template ID
|
||||
int recomLeft; ///< number of recommendations this player can give to others
|
||||
int recomHave; ///< number of received recommendations
|
||||
int isNoble; ///< 1 if is noblesse
|
||||
int isHero; ///< 1 if is hero
|
||||
unsigned int nameColor;
|
||||
unsigned int titleColor;
|
||||
unsigned int pledgeClass; ///< pledge class (TODO)
|
||||
unsigned int pledgeType; ///< pledge type (TODO)
|
||||
unsigned int cursedWeaponId;
|
||||
int clanRepScore; ///< clan reputation score or 0, if no clan
|
||||
unsigned int transformId;
|
||||
unsigned int agathionId;
|
||||
unsigned int vehicleObjectId; // O_o Gracia Final
|
||||
int hasDwarvenCraft; // only for UserInfo
|
||||
int numCubics;
|
||||
unsigned int cubicId[4];
|
||||
unsigned int clanPrivs; // only for UserInfo
|
||||
int inventoryLimit; // only for UserInfo
|
||||
L2ElementalInfo elements; // only for UserInfo
|
||||
int fame; // only for UserInfo
|
||||
int vitalityLevel; // only for UserInfo
|
||||
};
|
||||
|
||||
#endif
|
42
l2packets/l2world/L2PlayerPaperDoll.h
Normal file
42
l2packets/l2world/L2PlayerPaperDoll.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef H_L2PLAYER_PAPERDOLL_
|
||||
#define H_L2PLAYER_PAPERDOLL_
|
||||
|
||||
/** \file L2PlayerPaperDoll.h
|
||||
* Defines paperdoll items indexes in arrays:
|
||||
* unsigned int L2Player::paperdoll_iid[32];
|
||||
* unsigned int L2Player::paperdoll_augid[32];
|
||||
*/
|
||||
|
||||
#define L2_PAPERDOLL_UNDER 0
|
||||
#define L2_PAPERDOLL_REAR 1
|
||||
#define L2_PAPERDOLL_LEAR 2
|
||||
#define L2_PAPERDOLL_LREAR 3
|
||||
#define L2_PAPERDOLL_NECK 4
|
||||
#define L2_PAPERDOLL_LFINGER 5
|
||||
#define L2_PAPERDOLL_RFINGER 6
|
||||
#define L2_PAPERDOLL_LRFINGER 7
|
||||
#define L2_PAPERDOLL_HEAD 8
|
||||
#define L2_PAPERDOLL_RHAND 9
|
||||
#define L2_PAPERDOLL_LHAND 10
|
||||
#define L2_PAPERDOLL_GLOVES 11
|
||||
#define L2_PAPERDOLL_CHEST 12
|
||||
#define L2_PAPERDOLL_LEGS 13
|
||||
#define L2_PAPERDOLL_FEET 14
|
||||
#define L2_PAPERDOLL_BACK 15
|
||||
#define L2_PAPERDOLL_LRHAND 16
|
||||
#define L2_PAPERDOLL_FULLARMOR 17
|
||||
#define L2_PAPERDOLL_HAIR 18
|
||||
#define L2_PAPERDOLL_ALLDRESS 19
|
||||
#define L2_PAPERDOLL_HAIR2 20
|
||||
#define L2_PAPERDOLL_HAIRALL 21
|
||||
#define L2_PAPERDOLL_RBRACELET 22
|
||||
#define L2_PAPERDOLL_LBRACELET 23
|
||||
#define L2_PAPERDOLL_DECO1 24
|
||||
#define L2_PAPERDOLL_DECO2 25
|
||||
#define L2_PAPERDOLL_DECO3 26
|
||||
#define L2_PAPERDOLL_DECO4 27
|
||||
#define L2_PAPERDOLL_DECO5 28
|
||||
#define L2_PAPERDOLL_DECO6 29
|
||||
#define L2_PAPERDOLL_BELT 30
|
||||
|
||||
#endif
|
19
l2packets/l2world/L2Skill.h
Normal file
19
l2packets/l2world/L2Skill.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef L2SKILL_H_
|
||||
#define L2SKILL_H_
|
||||
|
||||
/** \class L2Skill
|
||||
* Information about skill: skill ID, skill level and active/passive type.
|
||||
*/
|
||||
|
||||
class L2Skill
|
||||
{
|
||||
public:
|
||||
L2Skill(): isPassive(1), id(0), level(0) {}
|
||||
~L2Skill() {}
|
||||
public:
|
||||
int isPassive; ///< 1, if is passive; 0 otherwise
|
||||
unsigned int id; ///< skill ID
|
||||
unsigned int level; ///< skill level
|
||||
};
|
||||
|
||||
#endif
|
21
l2packets/l2world/L2World.h
Normal file
21
l2packets/l2world/L2World.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef H_L2WORLD
|
||||
#define H_L2WORLD
|
||||
|
||||
/** \file L2World.h
|
||||
* Just a header to include all information about Lineage2 world...
|
||||
*/
|
||||
|
||||
#include "L2Object.h"
|
||||
#include "L2Character.h"
|
||||
#include "L2Npc.h"
|
||||
#include "L2Player.h"
|
||||
|
||||
#include "L2Skill.h"
|
||||
|
||||
#include "L2ChatMessageTypes.h"
|
||||
#include "L2PlayerPaperDoll.h"
|
||||
#include "L2Experience.h"
|
||||
|
||||
#include "L2ElementalInfo.h"
|
||||
|
||||
#endif
|
387
l2packets/login/L2LoginPacket.cpp
Normal file
387
l2packets/login/L2LoginPacket.cpp
Normal file
@@ -0,0 +1,387 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2LoginPacket.h"
|
||||
|
||||
//#define L2LOGINP_DEBUGOUT_BLOWFISH // can be defined in L2Packets.h
|
||||
|
||||
L2LoginPacket::L2LoginPacket()
|
||||
{
|
||||
_initNull(); // static BF key is initialized there
|
||||
NEW_BLOWFISH_KEY_LEN = 0;
|
||||
memset( (void *)NEW_BLOWFISH_KEY, 0, sizeof(NEW_BLOWFISH_KEY) );
|
||||
}
|
||||
|
||||
L2LoginPacket::L2LoginPacket( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
_initNull(); // static BF key is initialized there
|
||||
NEW_BLOWFISH_KEY_LEN = 0;
|
||||
memset( (void *)NEW_BLOWFISH_KEY, 0, sizeof(NEW_BLOWFISH_KEY) );
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
L2LoginPacket::~L2LoginPacket()
|
||||
{
|
||||
_freeSelf();
|
||||
}
|
||||
|
||||
void L2LoginPacket::_initNull()
|
||||
{
|
||||
L2BasePacket::_initNull();
|
||||
memset( (void *)STATIC_BLOWFISH_KEY, 0, sizeof(STATIC_BLOWFISH_KEY) );
|
||||
STATIC_BLOWFISH_KEY[0] = 0x6B;
|
||||
STATIC_BLOWFISH_KEY[1] = 0x60;
|
||||
STATIC_BLOWFISH_KEY[2] = 0xCB;
|
||||
STATIC_BLOWFISH_KEY[3] = 0x5B;
|
||||
STATIC_BLOWFISH_KEY[4] = 0x82;
|
||||
STATIC_BLOWFISH_KEY[5] = 0xCE;
|
||||
STATIC_BLOWFISH_KEY[6] = 0x90;
|
||||
STATIC_BLOWFISH_KEY[7] = 0xB1;
|
||||
STATIC_BLOWFISH_KEY[8] = 0xCC;
|
||||
STATIC_BLOWFISH_KEY[9] = 0x2B;
|
||||
STATIC_BLOWFISH_KEY[10] = 0x6C;
|
||||
STATIC_BLOWFISH_KEY[11] = 0x55;
|
||||
STATIC_BLOWFISH_KEY[12] = 0x6C;
|
||||
STATIC_BLOWFISH_KEY[13] = 0x6C;
|
||||
STATIC_BLOWFISH_KEY[14] = 0x6C;
|
||||
STATIC_BLOWFISH_KEY[15] = 0x6C;
|
||||
STATIC_BLOWFISH_KEY_LEN = 16;
|
||||
xor_key = 0;
|
||||
}
|
||||
|
||||
bool L2LoginPacket::decodeBlowfish( bool bUseStaticBFKey )
|
||||
{
|
||||
int blen = (int)getPacketSize(); // all array length
|
||||
int datalen = blen - 2; // only data len, w/o 1st 2 bytes - packet size
|
||||
int n8bc = datalen / 8; // 8-byte blocks count
|
||||
int rest = datalen - n8bc*8; // bytes left
|
||||
if( rest > 0 ) rest = 8; // do we need addition?
|
||||
int newdatalen = datalen + rest; // dlina novogo u4astka dannih
|
||||
int newbuflen = newdatalen + 2; // dlina novogo paketa
|
||||
if( blen < 1 ) return false; // TODO: throw?
|
||||
|
||||
unsigned char *buf = b.getBytesPtr();
|
||||
if( !buf ) return false; // TODO: throw?
|
||||
|
||||
// initialize Blowfish key
|
||||
BF_KEY bfkey;
|
||||
if( bUseStaticBFKey )
|
||||
BF_set_key( &bfkey, (int)this->STATIC_BLOWFISH_KEY_LEN,
|
||||
this->STATIC_BLOWFISH_KEY );
|
||||
else
|
||||
BF_set_key( &bfkey, (int)this->NEW_BLOWFISH_KEY_LEN,
|
||||
this->NEW_BLOWFISH_KEY );
|
||||
|
||||
int offset = 0;
|
||||
int nPasses = 0;
|
||||
unsigned char *outbuf = NULL;
|
||||
|
||||
// we will decode to this buffer
|
||||
outbuf = (unsigned char *)malloc( newbuflen );
|
||||
if( !outbuf )
|
||||
{
|
||||
#ifdef L2LOGINP_DEBUGOUT_BLOWFISH
|
||||
printf( "L2LoginPacket::decodeBlowfish(): memory error!\n" );
|
||||
#endif // L2LOGINP_DEBUGOUT_BLOWFISH
|
||||
return false;
|
||||
}
|
||||
memset( outbuf, 0, newbuflen );
|
||||
outbuf[0] = buf[0]; // copy packet len
|
||||
outbuf[1] = buf[1];
|
||||
|
||||
nPasses = 0;
|
||||
#ifdef L2LOGINP_DEBUGOUT_BLOWFISH
|
||||
if( bUseStaticBFKey ) printf( "L2LoginPacket::decodeBlowfish(): using STATIC BF KEY\n" );
|
||||
else printf( "L2LoginPacket::decodeBlowfish(): using DYNAMIC BF KEY\n" );
|
||||
#endif // L2LOGINP_DEBUGOUT_BLOWFISH
|
||||
for( offset=2; offset<newdatalen; offset+=8 )
|
||||
{
|
||||
unsigned char data[8] = {0,0,0,0,0,0,0,0};
|
||||
memcpy( data, buf+offset, 8 );
|
||||
BF_decrypt( (BF_LONG *)data, &bfkey );
|
||||
memcpy( outbuf+offset, data, 8 );
|
||||
nPasses++;
|
||||
}
|
||||
#ifdef L2LOGINP_DEBUGOUT_BLOWFISH
|
||||
printf( "L2LoginPacket::decodeBlowfish(): Decode2: %d passes, %d 8-byte blocks\n", nPasses, n8bc );
|
||||
//L2LoginPacket *dec2 = new L2LoginPacket( outbuf, blen );
|
||||
//dec2->dumpToFile( stdout );
|
||||
//dec2->saveToFileRaw( "pdecodedbf.dat" );
|
||||
//delete dec2;
|
||||
#endif // L2LOGINP_DEBUGOUT_BLOWFISH
|
||||
|
||||
this->setBytes( outbuf, blen );
|
||||
free( outbuf );
|
||||
|
||||
#ifdef L2LOGINP_DEBUGOUT_BLOWFISH
|
||||
printf( "L2LoginPacket::decodeBlowfish(): decode complete\n" );
|
||||
#endif // L2LOGINP_DEBUGOUT_BLOWFISH
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2LoginPacket::setDynamicBFKey( unsigned char *newKey, unsigned int newKeyLen )
|
||||
{
|
||||
if( !newKey ) return false;
|
||||
if( newKeyLen < 1 ) return false;
|
||||
memcpy( this->NEW_BLOWFISH_KEY, newKey, newKeyLen );
|
||||
this->NEW_BLOWFISH_KEY_LEN = newKeyLen;
|
||||
#ifdef L2LOGINP_DEBUGOUT_BLOWFISH
|
||||
printf( "L2LoginPacket::setDynamicBFKey(): set dynamic BF key of len = %u\n",
|
||||
newKeyLen );
|
||||
#endif // L2LOGINP_DEBUGOUT_BLOWFISH
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2LoginPacket::decodeBlowfish( unsigned char *blowfishKey )
|
||||
{
|
||||
setDynamicBFKey( blowfishKey, 16 );
|
||||
return decodeBlowfish( false );
|
||||
}
|
||||
|
||||
/*bool L2LoginPacket::appendChecksum()
|
||||
{
|
||||
// save packet len bytes
|
||||
//unsigned char plenbytes[2] = {0,0}
|
||||
//plenbytes[0] = b.getByteAt( 0 );
|
||||
//plenbytes[1] = b.getByteAt( 1 );
|
||||
// get packet length
|
||||
unsigned int count = this->getPacketSize();
|
||||
if( count > 2 )
|
||||
{
|
||||
unsigned char *rawbytes = b.getBytesPtr();
|
||||
unsigned int chksum = 0;
|
||||
unsigned int i = 0;
|
||||
for( i=2; i<count; i += 4 ) chksum ^= *( (unsigned int *)&rawbytes[i] );
|
||||
this->writeUInt( chksum );
|
||||
// restore plen bytes
|
||||
//b.setByteAt( 0, plenbytes[0] );
|
||||
//b.setByteAt( 1, plenbytes[1] );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}*/
|
||||
|
||||
bool L2LoginPacket::appendChecksum( bool append4bytes )
|
||||
{
|
||||
unsigned char *raw = b.getBytesPtr();
|
||||
int size = (int)this->real_size;
|
||||
unsigned int chksum = 0;
|
||||
int count = size; // size-4; // we do not reserve space for checksum
|
||||
unsigned int ecx = 0;
|
||||
int i = 0;
|
||||
int offset = 2;
|
||||
#ifdef L2LOGINP_DEBUGOUT_CHKSUM
|
||||
printf( "L2LoginPacket::appendChecksum(): for( i=%d; i<%d; i+=4)\n",
|
||||
offset, count );
|
||||
#endif // L2LOGINP_DEBUGOUT_CHKSUM
|
||||
for( i = offset; i<count; i+=4 )
|
||||
{
|
||||
ecx = (raw[i]) & 0x000000ff;
|
||||
ecx |= (raw[i+1] << 0x08) & 0x0000ff00;
|
||||
ecx |= (raw[i+2] << 0x10) & 0x00ff0000;
|
||||
ecx |= (raw[i+3] << 0x18) & 0xff000000;
|
||||
|
||||
chksum ^= ecx;
|
||||
}
|
||||
|
||||
ecx = raw[i] & 0x000000ff;
|
||||
ecx |= raw[i+1] << 0x08 & 0x0000ff00;
|
||||
ecx |= raw[i+2] << 0x10 & 0x00ff0000;
|
||||
ecx |= raw[i+3] << 0x18 & 0xff000000;
|
||||
|
||||
// write chksum to end of packet
|
||||
/*/// L2J style :)
|
||||
raw[i] = (unsigned char)((chksum) & 0xff);
|
||||
raw[i+1] = (unsigned char)((chksum >> 0x08) & 0xff);
|
||||
raw[i+2] = (unsigned char)((chksum >> 0x10) & 0xff);
|
||||
raw[i+3] = (unsigned char)((chksum >> 0x18) & 0xff);
|
||||
*/
|
||||
//this->write_ptr = i+4;
|
||||
|
||||
#ifdef L2LOGINP_DEBUGOUT_CHKSUM
|
||||
printf( "L2LoginPacket::appendChecksum(): writing chksum [%04X] at indexes [%d..%d]\n",
|
||||
chksum, this->write_ptr, this->write_ptr+3 );
|
||||
#endif // L2LOGINP_DEBUGOUT_CHKSUM
|
||||
|
||||
writeUChar( (unsigned char)((chksum) & 0xff) );
|
||||
writeUChar( (unsigned char)((chksum >> 0x08) & 0xff) );
|
||||
writeUChar( (unsigned char)((chksum >> 0x10) & 0xff) );
|
||||
writeUChar( (unsigned char)((chksum >> 0x18) & 0xff) );
|
||||
// Should we also automatically append 4 0x00 symbols to packet?
|
||||
// Before calling appendChecksum(), packet is considered to be
|
||||
// aligned at 8-byte border, so adding 4 bytes of checksum
|
||||
// breaks this alignment. And adding more 4 zero bytes will
|
||||
// resore 8-byte border alignment.
|
||||
// But sometimes this adding is not necessary, for example,
|
||||
// when encoding packet from Login Server to Client.
|
||||
if( append4bytes )
|
||||
{
|
||||
writeUChar( 0x00 );
|
||||
writeUChar( 0x00 );
|
||||
writeUChar( 0x00 );
|
||||
writeUChar( 0x00 );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2LoginPacket::verifyBytesChecksum( const unsigned char *bytes, unsigned int offset, unsigned int size )
|
||||
{
|
||||
if( !bytes || (size<8) ) return false;
|
||||
if( size % 4 != 0 ) return false; // data size should be a multiple of 4
|
||||
//
|
||||
unsigned int chksum = 0;
|
||||
unsigned int count = size-4;
|
||||
unsigned int check = 0xFFFFFFFF;
|
||||
unsigned int i = 0;
|
||||
//
|
||||
for( i=offset; i<count; i+=4 )
|
||||
{
|
||||
check = bytes[i] & 0xFF;
|
||||
check |= (bytes[i+1] << 8) & 0xFF00;
|
||||
check |= (bytes[i+2] << 16) & 0xFF0000;
|
||||
check |= (bytes[i+3] << 24) & 0xFF000000;
|
||||
chksum ^= check;
|
||||
}
|
||||
check = bytes[i] & 0xFF;
|
||||
check |= (bytes[i+1] << 8) & 0xFF00;
|
||||
check |= (bytes[i+2] << 16) & 0xFF0000;
|
||||
check |= (bytes[i+3] << 24) & 0xFF000000;
|
||||
//
|
||||
return (check == chksum);
|
||||
}
|
||||
|
||||
bool L2LoginPacket::verifyChecksum() const
|
||||
{
|
||||
const unsigned char *bytes = getBytesPtr();
|
||||
unsigned int data_len = getDataSize();
|
||||
return L2LoginPacket::verifyBytesChecksum( bytes, 2, data_len );
|
||||
}
|
||||
|
||||
bool L2LoginPacket::padPacketTo8ByteLen()
|
||||
{
|
||||
unsigned char *packet = b.getBytesPtr();
|
||||
unsigned int plen = getPacketSize();
|
||||
if( !packet || plen<3 ) return false;
|
||||
unsigned int datalen = plen-2;
|
||||
|
||||
#ifdef L2LOGINP_DEBUGOUT_PADDING
|
||||
printf( "L2LoginPacket::padPacketTo8ByteLen(): len = %u (data len = %d)\n",
|
||||
plen, datalen );
|
||||
#endif // L2LOGINP_DEBUGOUT_PADDING
|
||||
|
||||
unsigned int rest = datalen % 8;
|
||||
unsigned int addsize = 0;
|
||||
if( rest > 0 ) addsize = 8 - rest;
|
||||
|
||||
#ifdef L2LOGINP_DEBUGOUT_PADDING
|
||||
printf( "L2LoginPacket::padPacketTo8ByteLen(): We should add %u bytes (rest is %u)\n",
|
||||
addsize, rest );
|
||||
#endif // L2LOGINP_DEBUGOUT_PADDING
|
||||
|
||||
// save packet len bytes
|
||||
//unsigned char plenbytes[2] = {0,0};
|
||||
//plenbytes[0] = b.getByteAt( 0 );
|
||||
//plenbytes[1] = b.getByteAt( 1 );
|
||||
|
||||
// append by NULLs if we must append something
|
||||
if( addsize > 0 )
|
||||
{
|
||||
unsigned int i;
|
||||
for( i=0; i<addsize; i++ ) this->writeUChar( 0x00 );
|
||||
// restore plen bytes
|
||||
//b.setByteAt( 0, plenbytes[0] );
|
||||
//b.setByteAt( 1, plenbytes[1] );
|
||||
#ifdef L2LOGINP_DEBUGOUT_PADDING
|
||||
printf( "L2LoginPacket::padPacketTo8ByteLen(): "
|
||||
"after padding real_size = [%u] ==== \n", this->real_size );
|
||||
//this->dumpToFile( stdout );
|
||||
#endif // L2LOGINP_DEBUGOUT_PADDING
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2LoginPacket::appendMore8Bytes()
|
||||
{
|
||||
int i;
|
||||
for( i=0; i<8; i++ ) writeUChar( 0x00 );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2LoginPacket::encodeBlowfish( bool bUseStaticBFKey )
|
||||
{
|
||||
unsigned char *buf = this->b.getBytesPtr();
|
||||
if( !buf ) return false; // TODO: throw
|
||||
unsigned int blen = getPacketSize();
|
||||
if( blen < 1 ) return false; // TODO: throw
|
||||
//unsigned int datalen = blen - 2; // C4189: local variable is initialized but not referenced
|
||||
//this->padPacketTo8ByteLen(); // manually
|
||||
|
||||
// initialize Blowfish key
|
||||
BF_KEY bfkey;
|
||||
if( bUseStaticBFKey )
|
||||
BF_set_key( &bfkey, (int)this->STATIC_BLOWFISH_KEY_LEN,
|
||||
this->STATIC_BLOWFISH_KEY );
|
||||
else
|
||||
BF_set_key( &bfkey, (int)this->NEW_BLOWFISH_KEY_LEN,
|
||||
this->NEW_BLOWFISH_KEY );
|
||||
|
||||
unsigned int offset = 0;
|
||||
int nPasses = 0;
|
||||
unsigned char *outbuf = NULL;
|
||||
|
||||
// we will decode to this buffer
|
||||
outbuf = (unsigned char *)malloc( blen );
|
||||
if( !outbuf )
|
||||
{
|
||||
#ifdef L2LOGINP_DEBUGOUT_BLOWFISH
|
||||
printf( "L2LoginPacket::encodeBlowfish(): memory error!\n" );
|
||||
#endif // L2LOGINP_DEBUGOUT_BLOWFISH
|
||||
return false;
|
||||
}
|
||||
memset( outbuf, 0, blen );
|
||||
outbuf[0] = buf[0]; // copy packet len
|
||||
outbuf[1] = buf[1];
|
||||
|
||||
#ifdef L2LOGINP_DEBUGOUT_BLOWFISH
|
||||
if( bUseStaticBFKey ) printf( "L2LoginPacket::encodeBlowfish(): using STATIC BF KEY\n" );
|
||||
else printf( "L2LoginPacket::encodeBlowfish(): using DYNAMIC BF KEY\n" );
|
||||
printf( "L2LoginPacket::encodeBlowfish(): blen = %u, datalen = %u\n",
|
||||
blen, datalen );
|
||||
#endif // L2LOGINP_DEBUGOUT_BLOWFISH
|
||||
for( offset=2; offset<real_size-2; offset+=8 )
|
||||
{
|
||||
unsigned char data[8] = {0,0,0,0,0,0,0,0};
|
||||
memcpy( data, buf+offset, 8 );
|
||||
BF_encrypt( (BF_LONG *)data, &bfkey );
|
||||
memcpy( outbuf+offset, data, 8 );
|
||||
nPasses++;
|
||||
}
|
||||
#ifdef L2LOGINP_DEBUGOUT_BLOWFISH
|
||||
int n8bc = datalen / 8;
|
||||
printf( "L2LoginPacket::encodeBlowfish(): %d passes, %d 8-byte blocks ==\n",
|
||||
nPasses, n8bc );
|
||||
//L2LoginPacket dec2; // = new L2LoginPacket();
|
||||
//printf( "here\n" );
|
||||
//bool bret = dec2.setBytes( outbuf, real_size );
|
||||
//if( bret ) printf( "true\n" ); else printf( "false\n" );
|
||||
//dec2.dumpToFile( stdout );
|
||||
//delete dec2;
|
||||
#endif // L2LOGINP_DEBUGOUT_BLOWFISH
|
||||
|
||||
this->setBytes( outbuf, blen );
|
||||
free( outbuf );
|
||||
|
||||
#ifdef L2LOGINP_DEBUGOUT_BLOWFISH
|
||||
printf( "L2LoginPacket::encodeBlowfish(): encode complete\n" );
|
||||
#endif // L2LOGINP_DEBUGOUT_BLOWFISH
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2LoginPacket::encodeAndPrepareToSend( unsigned char *blowfishKey, unsigned int bfKeyLen /*= 16*/ )
|
||||
{
|
||||
if( !setDynamicBFKey( blowfishKey, bfKeyLen ) ) return false;
|
||||
if( !padPacketTo8ByteLen() ) return false;
|
||||
appendChecksum( true );
|
||||
appendMore8Bytes();
|
||||
return encodeBlowfish( false );
|
||||
}
|
76
l2packets/login/L2LoginPacket.h
Normal file
76
l2packets/login/L2LoginPacket.h
Normal file
@@ -0,0 +1,76 @@
|
||||
#ifndef H_L2LOGINPACKET
|
||||
#define H_L2LOGINPACKET
|
||||
|
||||
#include "../base/L2BasePacket.h"
|
||||
|
||||
/** \class L2LoginPacket
|
||||
* A base class for all login server communication packets.
|
||||
* Includes functions to handle Blowfish encryption/decryption and checksum calculations. */
|
||||
|
||||
class L2LoginPacket: public L2BasePacket
|
||||
{
|
||||
public:
|
||||
/** Default constructor */
|
||||
L2LoginPacket();
|
||||
/** Constructs object and calls setBytes() with parameters bytes, length
|
||||
* \param bytes data to set
|
||||
* \param length data size */
|
||||
L2LoginPacket( const unsigned char *bytes, unsigned int length );
|
||||
virtual ~L2LoginPacket();
|
||||
public:
|
||||
/** Does Blowfish decryption of packet data.
|
||||
* \param bUseStaticBFKey set to true to use static BF key, or false to dynamic.
|
||||
Dynamic BF key must be set before by setDynamicBFKey()
|
||||
* \return success status */
|
||||
virtual bool decodeBlowfish( bool bUseStaticBFKey );
|
||||
|
||||
/** Does Blowfish decryption of packet data.
|
||||
* \param blowfishKey - 16 bytes array, blowfish key to use to decrypt packet data
|
||||
* \return success status */
|
||||
virtual bool decodeBlowfish( unsigned char *blowfishKey );
|
||||
public:
|
||||
/** Appends checksum to packet
|
||||
* \param append4bytes in Hellbound, set to true to keep packet data length 8-byte aligned */
|
||||
virtual bool appendChecksum( bool append4bytes = true );
|
||||
/** Verifies data checksum, XORing count bytes starting from offset.\n
|
||||
* Checksum must be written at last 4 bytes of data, so data size must be >= 8 at least.
|
||||
* \param bytes data array
|
||||
* \param offset starting position
|
||||
* \param size data size in bytes (should be a multiple of 4)
|
||||
* \return true, if checksum is ok */
|
||||
static bool verifyBytesChecksum( const unsigned char *bytes, unsigned int offset, unsigned int size );
|
||||
/** Verifies this packet checksum. */
|
||||
virtual bool verifyChecksum() const;
|
||||
/** Does padding of packet data by zeroes to 8-byte border (before BF encryption) */
|
||||
virtual bool padPacketTo8ByteLen();
|
||||
/** In Hellbound, packets are padded by more 8 zero bytes after adding checksum & 4 bytes */
|
||||
virtual bool appendMore8Bytes();
|
||||
/** Sets dynamic Blowfish key (which is taken from Init packet)
|
||||
* \param newKey must point at 16 bytes buffer
|
||||
* \param newKeyLen currently must be = 16 */
|
||||
virtual bool setDynamicBFKey( unsigned char *newKey, unsigned int newKeyLen );
|
||||
/** Does Blowfish encryption.
|
||||
* \param bUseStaticBFKey set to true to use static BF key, or false to dynamic.
|
||||
Dynamic BF key must be set before by setDynamicBFKey()
|
||||
* \return success status */
|
||||
virtual bool encodeBlowfish( bool bUseStaticBFKey );
|
||||
|
||||
public:
|
||||
/** Encrypts packet with Blowfish, does all padding, appends checksum - after that packet may be sent
|
||||
* \param blowfishKey - Blowfish key to use for encryption (16 bytes)
|
||||
* \param bfKeyLen - length of Blowfish key (default is 16)
|
||||
* \return success status */
|
||||
virtual bool encodeAndPrepareToSend( unsigned char *blowfishKey, unsigned int bfKeyLen = 16 );
|
||||
|
||||
protected:
|
||||
/** Also initializes STATIC_BF_KEY, which is constant. */
|
||||
virtual void _initNull();
|
||||
protected:
|
||||
unsigned char STATIC_BLOWFISH_KEY[32]; ///< Static Blowfish key (First packet from login server is encrypted by this)
|
||||
unsigned int STATIC_BLOWFISH_KEY_LEN; ///< length of static BF key
|
||||
unsigned char NEW_BLOWFISH_KEY[64]; ///< Buffer to hold dynamic blowfish key
|
||||
unsigned int NEW_BLOWFISH_KEY_LEN; ///< Dynamic BF key size
|
||||
unsigned int xor_key; ///< current XOR key (for Init packet)
|
||||
};
|
||||
|
||||
#endif /* H_L2LOGINPACKET */
|
134
l2packets/login/client/L2Login_RequestAuthLogin.cpp
Normal file
134
l2packets/login/client/L2Login_RequestAuthLogin.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Login_RequestAuthLogin.h"
|
||||
|
||||
L2Login_RequestAuthLogin::L2Login_RequestAuthLogin()
|
||||
{
|
||||
_initNull();
|
||||
}
|
||||
|
||||
L2Login_RequestAuthLogin::L2Login_RequestAuthLogin( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
_initNull();
|
||||
setBytes( bytes, length );
|
||||
}
|
||||
|
||||
|
||||
// RSA_pubKeyMod must point to 128-bytes length buffer
|
||||
bool L2Login_RequestAuthLogin::create( const char *szL2Login, const char *szL2Password,
|
||||
unsigned int ggAuthResponse, const unsigned char *RSA_pubKeyMod )
|
||||
{
|
||||
// assert
|
||||
if( !szL2Login || !szL2Password ) return false;
|
||||
// vars
|
||||
size_t l2l_len = strlen( szL2Login );
|
||||
size_t l2p_len = strlen( szL2Password );
|
||||
char l2login[L2_LOGIN_MAXLEN];
|
||||
char l2password[L2_PASSWORD_MAXLEN];
|
||||
unsigned char block128[128];
|
||||
int i = 0;
|
||||
const int l2l_offset = 94;
|
||||
const int l2p_offset = 108;
|
||||
// memsets
|
||||
memset( l2login, 0, sizeof(l2login) );
|
||||
memset( l2password, 0, sizeof(l2password) );
|
||||
memset( block128, 0, sizeof(block128) );
|
||||
// check strings length
|
||||
if( (l2l_len<1) || (l2l_len>L2_LOGIN_MAXLEN) )
|
||||
{
|
||||
printf( "L2Login_RequestAuthLogin::create(): L2 Login length must be [1..%d] chars\n",
|
||||
L2_LOGIN_MAXLEN );
|
||||
return false;
|
||||
}
|
||||
if( (l2p_len<1) || (l2p_len>L2_PASSWORD_MAXLEN) )
|
||||
{
|
||||
printf( "L2Login_RequestAuthLogin::create(): L2 Password length must be [1..%d] chars\n",
|
||||
L2_PASSWORD_MAXLEN );
|
||||
return false;
|
||||
}
|
||||
// copy strings
|
||||
for( i=0; i<(int)l2l_len; i++ ) l2login[i] = szL2Login[i];
|
||||
for( i=0; i<(int)l2p_len; i++ ) l2password[i] = szL2Password[i];
|
||||
// copy login/pass to 128-byte block
|
||||
memcpy( (void *)(block128 + l2l_offset), l2login, L2_LOGIN_MAXLEN );
|
||||
memcpy( (void *)(block128 + l2p_offset), l2password, L2_PASSWORD_MAXLEN );
|
||||
// RSA encode block...
|
||||
if( !this->block_encode_RSA( block128, sizeof(block128), RSA_pubKeyMod ) ) return false;
|
||||
// construct packet
|
||||
this->writeReset();
|
||||
this->setPacketType( 0x00 ); // RequestAuthLogin code
|
||||
this->writeBytes( block128, sizeof(block128) ); // block with login/password
|
||||
this->writeUInt( ggAuthResponse ); // from GGAuthResponse
|
||||
for( i=0; i<16; i++ ) this->writeUChar( 0x00 ); // 16 NULLs
|
||||
this->writeUChar( 0x08 );
|
||||
for( i=0; i<10; i++ ) this->writeUChar( 0x00 ); // some 11 bytes
|
||||
// now packet must be padded to 8-byte border
|
||||
// next caller must add checksum, and so on...
|
||||
return true;
|
||||
}
|
||||
|
||||
// for internal use only
|
||||
// encode block with login/password
|
||||
// RSA_pubKeyMod must point to 128-bytes length buffer
|
||||
bool L2Login_RequestAuthLogin::block_encode_RSA( unsigned char *block , unsigned int blockSize,
|
||||
const unsigned char *RSA_pubKeyMod )
|
||||
{
|
||||
if( !block || (blockSize<1) || !RSA_pubKeyMod ) return false;
|
||||
bool retVal = true;
|
||||
unsigned char blockE[128];
|
||||
memset( blockE, 0, sizeof(blockE) );
|
||||
// allocate & initialize RSA struct
|
||||
RSA *rsa = RSA_new();
|
||||
// set exponent and n
|
||||
rsa->e = BN_new();
|
||||
BN_dec2bn( &(rsa->e), "65537" ); // exponent is constant, 65537
|
||||
rsa->n = BN_bin2bn( RSA_pubKeyMod, 128, NULL ); // n is taken from unscrambled RSA public key modulus from Init packet
|
||||
//printf( "RSA_size: %d\n", RSA_size( rsa ) );
|
||||
int res = RSA_public_encrypt( 128, block, blockE, rsa, RSA_NO_PADDING );
|
||||
if( res == -1 )
|
||||
{
|
||||
retVal = false;
|
||||
fprintf( stderr, "RSA_public_encrypt res: %d\n", res );
|
||||
ERR_print_errors_fp( stderr );
|
||||
}
|
||||
// store result...
|
||||
memcpy( block, blockE, 128 );
|
||||
// free RSA struct
|
||||
RSA_free( rsa );
|
||||
rsa = NULL;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool L2Login_RequestAuthLogin::block_decode_RSA( unsigned char *block , unsigned int blockSize,
|
||||
const unsigned char *RSA_pubKeyMod )
|
||||
{
|
||||
if( !block || (blockSize<1) || !RSA_pubKeyMod ) return false;
|
||||
bool retVal = true;
|
||||
unsigned char blockE[128];
|
||||
memset( blockE, 0, sizeof(blockE) );
|
||||
// allocate & initialize RSA struct
|
||||
RSA *rsa = RSA_new();
|
||||
// set exponent and n
|
||||
rsa->e = BN_new();
|
||||
BN_dec2bn( &(rsa->e), "65537" ); // exponent is constant, 65537
|
||||
rsa->n = BN_bin2bn( RSA_pubKeyMod, 128, NULL ); // n is taken from unscrambled RSA public key modulus from Init packet
|
||||
int res = RSA_private_decrypt( 128, block, blockE, rsa, RSA_NO_PADDING );
|
||||
if( res == -1 )
|
||||
{
|
||||
retVal = false;
|
||||
fprintf( stderr, "RSA_private_decrypt res: %d\n", res );
|
||||
ERR_print_errors_fp( stderr );
|
||||
}
|
||||
// store result...
|
||||
memcpy( block, blockE, 128 );
|
||||
// free RSA struct
|
||||
RSA_free( rsa );
|
||||
rsa = NULL;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool L2Login_RequestAuthLogin::parse( L2_VERSION ver /*= L2_VERSION_T1*/ )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
fprintf( stderr, "L2Login_RequestAuthLogin::parse() not implemented!\n" );
|
||||
return false;
|
||||
}
|
36
l2packets/login/client/L2Login_RequestAuthLogin.h
Normal file
36
l2packets/login/client/L2Login_RequestAuthLogin.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef L2LOGIN_REQUESTAUTHLOGIN_H_
|
||||
#define L2LOGIN_REQUESTAUTHLOGIN_H_
|
||||
|
||||
#include "../L2LoginPacket.h"
|
||||
|
||||
#define L2_LOGIN_MAXLEN 14
|
||||
#define L2_PASSWORD_MAXLEN 16
|
||||
|
||||
class L2Login_RequestAuthLogin: public L2LoginPacket
|
||||
{
|
||||
public:
|
||||
L2Login_RequestAuthLogin();
|
||||
L2Login_RequestAuthLogin( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
// RSA_pubKeyMod must point to 128-bytes length buffer
|
||||
bool create( const char *szL2Login, const char *szL2Password,
|
||||
unsigned int ggAuthResponse, const unsigned char *RSA_pubKeyMod );
|
||||
//virtual bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
virtual bool parse( L2_VERSION ver = L2_VERSION_T1 );
|
||||
|
||||
public:
|
||||
char strLogin[32];
|
||||
char strPassword[32];
|
||||
unsigned int uGGAuthResponse;
|
||||
|
||||
protected:
|
||||
// for internal use only
|
||||
// encode block with login/password
|
||||
// RSA_pubKeyMod must point to 128-bytes length buffer
|
||||
bool block_encode_RSA( unsigned char *block , unsigned int blockSize,
|
||||
const unsigned char *RSA_pubKeyMod );
|
||||
bool block_decode_RSA( unsigned char *block , unsigned int blockSize,
|
||||
const unsigned char *RSA_pubKeyMod );
|
||||
};
|
||||
|
||||
#endif /*L2LOGIN_REQUESTAUTHLOGIN_H_*/
|
43
l2packets/login/client/L2Login_RequestGGAuth.cpp
Normal file
43
l2packets/login/client/L2Login_RequestGGAuth.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Login_RequestGGAuth.h"
|
||||
|
||||
L2Login_RequestGGAuth::L2Login_RequestGGAuth()
|
||||
{
|
||||
this->_initNull();
|
||||
sessionId[0] = sessionId[1] = sessionId[2] = sessionId[3] = 0;
|
||||
}
|
||||
|
||||
L2Login_RequestGGAuth::L2Login_RequestGGAuth( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
sessionId[0] = sessionId[1] = sessionId[2] = sessionId[3] = 0;
|
||||
}
|
||||
|
||||
// sesionID - 4 bytes array
|
||||
bool L2Login_RequestGGAuth::create( L2_VERSION ver )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
// set packet type
|
||||
this->setPacketType( 0x07 );
|
||||
// write sessionID
|
||||
this->writeUChar( sessionId[0] );
|
||||
this->writeUChar( sessionId[1] );
|
||||
this->writeUChar( sessionId[2] );
|
||||
this->writeUChar( sessionId[3] );
|
||||
// write 16 0x00
|
||||
int i;
|
||||
for( i=0; i<16; i++ ) this->writeUChar( 0x00 );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Login_RequestGGAuth::parse( L2_VERSION ver )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
if( getPacketType() != 0x07 ) return false;
|
||||
sessionId[0] = readUChar();
|
||||
sessionId[1] = readUChar();
|
||||
sessionId[2] = readUChar();
|
||||
sessionId[3] = readUChar();
|
||||
return true;
|
||||
}
|
19
l2packets/login/client/L2Login_RequestGGAuth.h
Normal file
19
l2packets/login/client/L2Login_RequestGGAuth.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef LOGIN_REQUESTGGAUTH_H_
|
||||
#define LOGIN_REQUESTGGAUTH_H_
|
||||
|
||||
#include "../L2LoginPacket.h"
|
||||
|
||||
class L2Login_RequestGGAuth: public L2LoginPacket
|
||||
{
|
||||
public:
|
||||
L2Login_RequestGGAuth();
|
||||
L2Login_RequestGGAuth( const unsigned char *bytes, unsigned int length );
|
||||
|
||||
public:
|
||||
virtual bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
virtual bool parse( L2_VERSION ver = L2_VERSION_T1 );
|
||||
public:
|
||||
unsigned char sessionId[4];
|
||||
};
|
||||
|
||||
#endif /*LOGIN_REQUESTGGAUTH_H_*/
|
34
l2packets/login/client/L2Login_RequestServerList.cpp
Normal file
34
l2packets/login/client/L2Login_RequestServerList.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Login_RequestServerList.h"
|
||||
|
||||
/*
|
||||
22 00 // packet size - 34 bytes
|
||||
05 // packet type - RequestServerList
|
||||
e0 43 ef 46 8e dc 83 f2 // sessionKey #1
|
||||
04 00 00 00 00 00 00 // some 7 bytes
|
||||
b1 6a 9f 6c 00 00 00 00 // checksum and 4 0x00 bytes of checksum padding
|
||||
00 00 00 00 00 00 00 00 // 8 0x00 bytes padding
|
||||
*/
|
||||
|
||||
L2Login_RequestServerList::L2Login_RequestServerList()
|
||||
{
|
||||
this->_initNull();
|
||||
}
|
||||
|
||||
L2Login_RequestServerList::L2Login_RequestServerList( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Login_RequestServerList::create( const unsigned char *sessionKey1 )
|
||||
{
|
||||
if( !sessionKey1 ) return false;
|
||||
this->writeReset();
|
||||
this->setPacketType( 0x05 );
|
||||
this->writeBytes( sessionKey1, 8 );
|
||||
unsigned char somebytes[7] = { 4,0,0,0, 0,0,0 };
|
||||
this->writeBytes( somebytes, sizeof(somebytes) );
|
||||
// now packet is padded at 8-byte border. all left to is add checksum
|
||||
return true;
|
||||
}
|
25
l2packets/login/client/L2Login_RequestServerList.h
Normal file
25
l2packets/login/client/L2Login_RequestServerList.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef L2LOGIN_REQUESTSERVERLIST_H_
|
||||
#define L2LOGIN_REQUESTSERVERLIST_H_
|
||||
|
||||
#include "../L2LoginPacket.h"
|
||||
|
||||
/*
|
||||
22 00 // packet size - 34 bytes
|
||||
05 // packet type - RequestServerList
|
||||
e0 43 ef 46 8e dc 83 f2 // sessionKey #1
|
||||
04 00 00 00 00 00 00 // some 7 bytes
|
||||
b1 6a 9f 6c 00 00 00 00 // checksum and 4 0x00 bytes of checksum padding
|
||||
00 00 00 00 00 00 00 00 // 8 0x00 bytes padding
|
||||
*/
|
||||
|
||||
class L2Login_RequestServerList : public L2LoginPacket
|
||||
{
|
||||
public:
|
||||
L2Login_RequestServerList();
|
||||
L2Login_RequestServerList( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
// sessionKey1 - 8-byte array (from LoginOK packet)
|
||||
bool create( const unsigned char *sessionKey1 );
|
||||
};
|
||||
|
||||
#endif /*L2LOGIN_REQUESTSERVERLIST_H_*/
|
70
l2packets/login/client/L2Login_RequestServerLogin.cpp
Normal file
70
l2packets/login/client/L2Login_RequestServerLogin.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Login_RequestServerLogin.h"
|
||||
|
||||
/**
|
||||
* Format is ddc
|
||||
* d: first part of session id
|
||||
* d: second part of session id
|
||||
* c: server ID
|
||||
*/
|
||||
|
||||
L2Login_RequestServerLogin::L2Login_RequestServerLogin()
|
||||
{
|
||||
this->_initNull();
|
||||
}
|
||||
|
||||
L2Login_RequestServerLogin::L2Login_RequestServerLogin( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
// sessionKey1 must point to 8-byte array
|
||||
// this is Session Key #1 from LoginOK packet
|
||||
bool L2Login_RequestServerLogin::create( const unsigned char *sessionKey1,
|
||||
unsigned char GameServerID )
|
||||
{
|
||||
if( !sessionKey1 || (GameServerID == 0x00) ) return false;
|
||||
// construct packet
|
||||
this->writeReset();
|
||||
this->setPacketType( 0x02 ); // RequestServerLogin
|
||||
this->writeBytes( sessionKey1, 8 );
|
||||
this->writeUChar( GameServerID );
|
||||
// pad to 8-byte border
|
||||
int i;
|
||||
for( i=0; i<6; i++ ) this->writeUChar( 0x00 );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Login_RequestServerLogin::read_sessionKey1( unsigned char *bytes )
|
||||
{
|
||||
if( !this->canReadBytes(8) ) return false;
|
||||
return this->readBytes( bytes, 8 );
|
||||
}
|
||||
|
||||
unsigned char L2Login_RequestServerLogin::read_GameServerID()
|
||||
{
|
||||
return this->readUChar();
|
||||
}
|
||||
|
||||
bool L2Login_RequestServerLogin::parse( L2_VERSION ver /*= L2_VERSION_T1*/ )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
if( getPacketType() != 0x02 ) return false;
|
||||
if( !canReadBytes( 9 ) ) return false;
|
||||
readBytes( p_sessionKey1, 8 );
|
||||
p_gameServerId = readUChar();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Login_RequestServerLogin::create( L2_VERSION ver /*= L2_VERSION_T1*/ )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
setPacketType( 0x02 ); // RequestServerLogin
|
||||
writeBytes( p_sessionKey1, 8 );
|
||||
writeUChar( p_gameServerId );
|
||||
// pad to 8-byte border
|
||||
int i;
|
||||
for( i=0; i<6; i++ ) writeUChar( 0x00 );
|
||||
return true;
|
||||
}
|
26
l2packets/login/client/L2Login_RequestServerLogin.h
Normal file
26
l2packets/login/client/L2Login_RequestServerLogin.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef L2LOGIN_REQUESTSERVERLOGIN_H_
|
||||
#define L2LOGIN_REQUESTSERVERLOGIN_H_
|
||||
|
||||
#include "../L2LoginPacket.h"
|
||||
|
||||
class L2Login_RequestServerLogin : public L2LoginPacket
|
||||
{
|
||||
public:
|
||||
L2Login_RequestServerLogin();
|
||||
L2Login_RequestServerLogin( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
// sessionKey1 must point to 8-byte array
|
||||
// this is Session Key #1 from LoginOK packet
|
||||
bool create( const unsigned char *sessionKey1, unsigned char GameServerID );
|
||||
public:
|
||||
bool read_sessionKey1( unsigned char *bytes );
|
||||
unsigned char read_GameServerID();
|
||||
public:
|
||||
bool parse( L2_VERSION ver = L2_VERSION_T1 );
|
||||
bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
public:
|
||||
unsigned char p_gameServerId;
|
||||
unsigned char p_sessionKey1[8];
|
||||
};
|
||||
|
||||
#endif /*L2LOGIN_REQUESTSERVERLOGIN_H_*/
|
62
l2packets/login/server/L2Login_AccountKicked.cpp
Normal file
62
l2packets/login/server/L2Login_AccountKicked.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Login_AccountKicked.h"
|
||||
|
||||
/*
|
||||
writeC(0x02);
|
||||
writeD(_reason.getCode());
|
||||
*/
|
||||
|
||||
L2Login_AccountKicked::L2Login_AccountKicked()
|
||||
{
|
||||
this->_initNull();
|
||||
p_reasonCode = 0;
|
||||
}
|
||||
|
||||
L2Login_AccountKicked::L2Login_AccountKicked( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
p_reasonCode = 0;
|
||||
}
|
||||
|
||||
unsigned int L2Login_AccountKicked::read_reason()
|
||||
{
|
||||
if( !this->canReadBytes(5) ) return 0;
|
||||
this->readReset();
|
||||
this->readUChar();
|
||||
return this->readUInt();
|
||||
}
|
||||
|
||||
void L2Login_AccountKicked::getReasonStr( unsigned int code, char *str )
|
||||
{
|
||||
if( !str ) return;
|
||||
strcpy( str, "REASON_UNKNOWN" );
|
||||
switch( code )
|
||||
{
|
||||
case REASON_DATA_STEALER: strcpy( str, "REASON_DATA_STEALER" ); break;
|
||||
case REASON_GENERIC_VIOLATION: strcpy( str, "REASON_GENERIC_VIOLATION" ); break;
|
||||
case REASON_7_DAYS_SUSPENDED: strcpy( str, "REASON_7_DAYS_SUSPENDED" ); break;
|
||||
case REASON_PERMANENTLY_BANNED: strcpy( str, "REASON_PERMANENTLY_BANNED" ); break;
|
||||
}
|
||||
}
|
||||
|
||||
void L2Login_AccountKicked::getReasonStr( char *str )
|
||||
{
|
||||
L2Login_AccountKicked::getReasonStr( p_reasonCode, str );
|
||||
}
|
||||
|
||||
bool L2Login_AccountKicked::parse( L2_VERSION ver )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
if( this->getPacketType() != 0x02 ) return false;
|
||||
p_reasonCode = readUInt();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Login_AccountKicked::create( L2_VERSION ver )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
setPacketType( 0x02 );
|
||||
writeUInt( p_reasonCode );
|
||||
return true;
|
||||
}
|
28
l2packets/login/server/L2Login_AccountKicked.h
Normal file
28
l2packets/login/server/L2Login_AccountKicked.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef L2LOGIN_ACCOUNTKICKED_H_
|
||||
#define L2LOGIN_ACCOUNTKICKED_H_
|
||||
|
||||
#include "../L2LoginPacket.h"
|
||||
|
||||
class L2Login_AccountKicked : public L2LoginPacket
|
||||
{
|
||||
public:
|
||||
static const unsigned int REASON_DATA_STEALER = 0x01;
|
||||
static const unsigned int REASON_GENERIC_VIOLATION = 0x08;
|
||||
static const unsigned int REASON_7_DAYS_SUSPENDED = 0x10;
|
||||
static const unsigned int REASON_PERMANENTLY_BANNED = 0x20;
|
||||
public:
|
||||
L2Login_AccountKicked();
|
||||
L2Login_AccountKicked( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
unsigned int read_reason();
|
||||
// str must point to buffer at 32 bytes long
|
||||
static void getReasonStr( unsigned int code, char *str );
|
||||
void getReasonStr( char *str );
|
||||
public:
|
||||
virtual bool parse( L2_VERSION ver = L2_VERSION_T1 );
|
||||
virtual bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
public:
|
||||
unsigned int p_reasonCode;
|
||||
};
|
||||
|
||||
#endif /*L2LOGIN_ACCOUNTKICKED_H_*/
|
52
l2packets/login/server/L2Login_GGAuthResponse.cpp
Normal file
52
l2packets/login/server/L2Login_GGAuthResponse.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Login_GGAuthResponse.h"
|
||||
|
||||
/* // L2J
|
||||
protected void write()
|
||||
{
|
||||
writeC(0x0b); // packet code
|
||||
writeD(_response);
|
||||
writeD(0x00);
|
||||
writeD(0x00);
|
||||
writeD(0x00);
|
||||
writeD(0x00);
|
||||
}*/
|
||||
|
||||
L2Login_GGAuthResponse::L2Login_GGAuthResponse()
|
||||
{
|
||||
this->_initNull();
|
||||
}
|
||||
|
||||
L2Login_GGAuthResponse::L2Login_GGAuthResponse( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
unsigned int L2Login_GGAuthResponse::read_Response()
|
||||
{
|
||||
if( !this->canReadBytes(21) ) return 0;
|
||||
this->readReset();
|
||||
this->getPacketType();
|
||||
return this->readUInt();
|
||||
}
|
||||
|
||||
bool L2Login_GGAuthResponse::parse( L2_VERSION ver )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
p_ggAuthResponse = read_Response();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Login_GGAuthResponse::create( L2_VERSION ver )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
this->writeReset();
|
||||
writeC( 0x0b ); // packet code
|
||||
writeD( p_ggAuthResponse );
|
||||
writeD( 0x00 );
|
||||
writeD( 0x00 );
|
||||
writeD( 0x00 );
|
||||
writeD( 0x00 );
|
||||
return true;
|
||||
}
|
20
l2packets/login/server/L2Login_GGAuthResponse.h
Normal file
20
l2packets/login/server/L2Login_GGAuthResponse.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef LOGIN_GGAUTHRESPONSE_H_
|
||||
#define LOGIN_GGAUTHRESPONSE_H_
|
||||
|
||||
#include "../L2LoginPacket.h"
|
||||
|
||||
class L2Login_GGAuthResponse : public L2LoginPacket
|
||||
{
|
||||
public:
|
||||
L2Login_GGAuthResponse();
|
||||
L2Login_GGAuthResponse( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
unsigned int read_Response();
|
||||
public:
|
||||
virtual bool parse( L2_VERSION ver = L2_VERSION_T1 );
|
||||
virtual bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
public:
|
||||
unsigned int p_ggAuthResponse;
|
||||
};
|
||||
|
||||
#endif /*LOGIN_GGAUTHRESPONSE_H_*/
|
300
l2packets/login/server/L2Login_Init.cpp
Normal file
300
l2packets/login/server/L2Login_Init.cpp
Normal file
@@ -0,0 +1,300 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Login_Init.h"
|
||||
|
||||
L2Login_Init::L2Login_Init()
|
||||
{
|
||||
_initNull();
|
||||
_initPublicMembers();
|
||||
}
|
||||
|
||||
L2Login_Init::L2Login_Init( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
_initNull();
|
||||
_initPublicMembers();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
bool L2Login_Init::decodeXOR()
|
||||
{
|
||||
unsigned int blen = getPacketSize();
|
||||
unsigned char *packet = b.getBytesPtr();
|
||||
if( blen < 1 || !packet ) return false; // TODO: throw?
|
||||
if( blen < 186 ) return false; // TODO: throw?
|
||||
// get xor key
|
||||
// XOR key position to the left from End-of-packet
|
||||
unsigned int xor_offset = 8;
|
||||
xor_key = 0;
|
||||
unsigned char b = 0;
|
||||
b = packet[ blen - xor_offset ];
|
||||
xor_key |= (unsigned int)b;
|
||||
b = packet[ blen - xor_offset + 1 ];
|
||||
xor_key |= ( (unsigned int)b << 8 );
|
||||
b = packet[ blen - xor_offset + 2 ];
|
||||
xor_key |= ( (unsigned int)b << 16 );
|
||||
b = packet[ blen - xor_offset + 3 ];
|
||||
xor_key |= ( (unsigned int)b << 24 );
|
||||
|
||||
// enc xor?
|
||||
unsigned int offset = 2;
|
||||
unsigned int edx = 0;
|
||||
unsigned int ecx = xor_key;
|
||||
|
||||
offset = blen - xor_offset - 4;
|
||||
while( offset > 2 ) // offset > 3 ?
|
||||
{
|
||||
edx = (packet[offset+0] & 0xFF);
|
||||
edx |= (packet[offset+1] & 0xFF) << 8;
|
||||
edx |= (packet[offset+2] & 0xFF) << 16;
|
||||
edx |= (packet[offset+3] & 0xFF) << 24;
|
||||
|
||||
edx ^= ecx;
|
||||
ecx -= edx;
|
||||
|
||||
packet[offset+0] = (unsigned char)((edx) & 0xFF);
|
||||
packet[offset+1] = (unsigned char)((edx >> 8) & 0xFF);
|
||||
packet[offset+2] = (unsigned char)((edx >> 16) & 0xFF);
|
||||
packet[offset+3] = (unsigned char)((edx >> 24) & 0xFF);
|
||||
offset -= 4;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// static function used to decrypt RSA public key modulus from Init packet
|
||||
// data must be 128-byte long array
|
||||
bool L2Login_Init::unscramble_RSA_PubKeyMod( unsigned char *data )
|
||||
{
|
||||
int i;
|
||||
// step 4 xor last 0x40 bytes with first 0x40 bytes
|
||||
for( i=0; i<0x40; i++ )
|
||||
data[0x40 + i] = (unsigned char)(data[0x40 + i] ^ data[i]);
|
||||
// step 3 xor bytes 0x0d-0x10 with bytes 0x34-0x38
|
||||
for( i=0; i<4; i++ )
|
||||
data[0x0d + i] = (unsigned char)(data[0x0d + i] ^ data[0x34 + i]);
|
||||
// step 2 xor first 0x40 bytes with last 0x40 bytes
|
||||
for( i=0; i<0x40; i++ )
|
||||
data[i] = (unsigned char)(data[i] ^ data[0x40 + i]);
|
||||
// step 1
|
||||
for( i=0; i<4; i++ )
|
||||
{
|
||||
unsigned char temp = data[0x00 + i];
|
||||
data[0x00 + i] = data[0x4d + i];
|
||||
data[0x4d + i] = temp;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Login_Init::scramble_RSA_PubKeyMod( unsigned char *data )
|
||||
{
|
||||
int i;
|
||||
for( i=0; i<4; i++ )
|
||||
{
|
||||
unsigned char temp = data[0x00 + i];
|
||||
data[0x00 + i] = data[0x4d + i];
|
||||
data[0x4d + i] = temp;
|
||||
}
|
||||
// step 2 xor first 0x40 bytes with last 0x40 bytes
|
||||
for( i=0; i<0x40; i++ )
|
||||
data[i] = (unsigned char)(data[i] ^ data[0x40 + i]);
|
||||
// step 3 xor bytes 0x0d-0x10 with bytes 0x34-0x38
|
||||
for( i=0; i<4; i++ )
|
||||
data[0x0d + i] = (unsigned char)(data[0x0d + i] ^ data[0x34 + i]);
|
||||
// step 4 xor last 0x40 bytes with first 0x40 bytes
|
||||
for( i=0; i<0x40; i++ )
|
||||
data[0x40 + i] = (unsigned char)(data[0x40 + i] ^ data[i]);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Login_Init::read_SessionID( unsigned char *sidBytes )
|
||||
{
|
||||
if( !sidBytes ) return false;
|
||||
if( !canReadBytes( 4 ) ) return false;
|
||||
this->readReset();
|
||||
this->readChar(); // pass packet type
|
||||
sidBytes[0] = this->readUChar();
|
||||
sidBytes[1] = this->readUChar();
|
||||
sidBytes[2] = this->readUChar();
|
||||
sidBytes[3] = this->readUChar();
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int L2Login_Init::read_ProtoVer()
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
ret = this->readUInt();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// RSApublicKeyMod must point to buffer 128 bytes len
|
||||
bool L2Login_Init::read_RSA_pubKeyMod( unsigned char *RSApublicKeyMod )
|
||||
{
|
||||
if( !RSApublicKeyMod ) return false;
|
||||
if( !canReadBytes(128) ) return false;
|
||||
int i = 0;
|
||||
while( i < 128 ) RSApublicKeyMod[i++] = readUChar();
|
||||
return true;
|
||||
}
|
||||
|
||||
// ggShit - 16 bytes buffer; can be NULL
|
||||
bool L2Login_Init::read_GGShit( unsigned char *ggShit )
|
||||
{
|
||||
if( !canReadBytes( 16 ) ) return false;
|
||||
int i = 0;
|
||||
char c = 0;
|
||||
while( i < 16 )
|
||||
{
|
||||
c = this->readUChar();
|
||||
if( ggShit ) ggShit[i] = c;
|
||||
i++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// newBFKey - 16 bytes buffer; can NOT be NULL
|
||||
bool L2Login_Init::read_DynamicBFKey( unsigned char *newBFKey )
|
||||
{
|
||||
if( !newBFKey ) return false;
|
||||
if( !canReadBytes(16) ) return false;
|
||||
int i = 0;
|
||||
while( i < 16 ) newBFKey[i++] = this->readUChar();
|
||||
return true;
|
||||
}
|
||||
|
||||
void L2Login_Init::displaySelfNice( FILE *f )
|
||||
{
|
||||
fprintf( f, "L2Login_Init: displaying self\n" );
|
||||
if( this->getPacketSize() != 186 )
|
||||
{
|
||||
fprintf( f, "L2Login_Init: this is not standard Interlude Init packet! (wrong size)\n" );
|
||||
this->dumpToFile( stdout );
|
||||
return;
|
||||
}
|
||||
char ptype = this->getPacketType();
|
||||
if( ptype != 0 )
|
||||
{
|
||||
fprintf( f, "L2Login_Init: this is not standard Interlude Init packet! (wrong packet type)\n" );
|
||||
this->dumpToFile( stdout );
|
||||
}
|
||||
|
||||
// vars
|
||||
unsigned char sidBytes[4] = {0,0,0,0};
|
||||
unsigned int protoRev = 0;
|
||||
unsigned char RSA_pubKeyMod[128];
|
||||
unsigned char GG_Shit[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
|
||||
unsigned char dyn_BF_key[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
|
||||
unsigned char nullTerm = 0;
|
||||
|
||||
// memsets
|
||||
memset( RSA_pubKeyMod, 0, sizeof(RSA_pubKeyMod) );
|
||||
|
||||
// read ...
|
||||
this->read_SessionID( sidBytes );
|
||||
protoRev = this->read_ProtoVer();
|
||||
this->read_RSA_pubKeyMod( RSA_pubKeyMod );
|
||||
this->read_GGShit( GG_Shit );
|
||||
this->read_DynamicBFKey( dyn_BF_key );
|
||||
nullTerm = this->readUChar();
|
||||
|
||||
// print
|
||||
int i = 0;
|
||||
fprintf( f, "Packet type : Init (0)\n" );
|
||||
fprintf( f, "Session ID : %02X %02X %02X %02X\n",
|
||||
sidBytes[0], sidBytes[1], sidBytes[2], sidBytes[3] );
|
||||
fprintf( f, "Protocol Rev : %04X\n", protoRev );
|
||||
fprintf( f, "RSA pub key mod :\n" );
|
||||
for( i=0; i<128; i++ ) fprintf( f, "%02X ", (unsigned int)RSA_pubKeyMod[i] );
|
||||
fprintf( f, "\n" );
|
||||
fprintf( f, "GG Shit : " );
|
||||
for( i=0; i<16; i++ ) fprintf( f, "%02X ", (unsigned int)GG_Shit[i] );
|
||||
fprintf( f, "\n" );
|
||||
fprintf( f, "Dynamic BF Key : " );
|
||||
for( i=0; i<16; i++ ) fprintf( f, "%02X ", (unsigned int)dyn_BF_key[i] );
|
||||
fprintf( f, "\n" );
|
||||
fprintf( f, "NULL terminator : %u (0x%02X)\n",
|
||||
(unsigned int)nullTerm, (unsigned int)nullTerm );
|
||||
fprintf( f, "Init packet dump end ;)\n\n" );
|
||||
}
|
||||
|
||||
void L2Login_Init::_initPublicMembers()
|
||||
{
|
||||
p_sessionId[0] = p_sessionId[1] = p_sessionId[2] = p_sessionId[3] = 0x00;
|
||||
p_protoVer = 0x00000000;
|
||||
memset( p_RSA_pubKeyMod, 0, sizeof(p_RSA_pubKeyMod) );
|
||||
memset( p_GG_shit, 0, sizeof(p_GG_shit) );
|
||||
memset( p_BF_dyn_key, 0, sizeof(p_BF_dyn_key) );
|
||||
}
|
||||
|
||||
bool L2Login_Init::create( L2_VERSION ver )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver); // login server packets may ignore this
|
||||
//int i;
|
||||
scramble_RSA_PubKeyMod( p_RSA_pubKeyMod );
|
||||
// write data
|
||||
writeReset();
|
||||
setPacketType( 0x00 );
|
||||
writeBytes( p_sessionId, 4 );
|
||||
writeUInt( p_protoVer );
|
||||
writeBytes( p_RSA_pubKeyMod, 128 );
|
||||
writeUInt( 0x29dd954e ); // 4e 95 dd 29 // GGshit? O_o
|
||||
writeUInt( 0x77c39cfc ); // fc 9c c3 77
|
||||
writeUInt( 0x97adb620 ); // 20 b6 ad 97
|
||||
writeUInt( 0x07bde0f7 ); // f7 e0 bd 07
|
||||
writeBytes( p_BF_dyn_key, 16 );
|
||||
writeChar( 0x00 );
|
||||
// Init packet has no checksum or padding, but it has XOR encryption
|
||||
// fill packet up to xor key position
|
||||
writeD( 0x00000000 ); // write some 6 bytes, they are ignored? trash?
|
||||
writeH( 0x0000 ); // tested, works OK
|
||||
// now, XOR all previous bytes except first 2 bytes with packet len
|
||||
// and next 4 bytes with login session id?
|
||||
unsigned int xor_key = rand(); // O_o generate random XOR "key"
|
||||
unsigned char *raw_bytes = b.getBytesPtr(); // we need to modify almost all bytes...
|
||||
int psize = getPacketSize();
|
||||
int xor_offset = 6; //2; // should we XOR login session id also?
|
||||
while( xor_offset < psize )
|
||||
{
|
||||
// read current dword
|
||||
unsigned int xoring_dword =
|
||||
(unsigned int)raw_bytes[xor_offset] |
|
||||
((unsigned int)raw_bytes[xor_offset+1]) << 8 |
|
||||
((unsigned int)raw_bytes[xor_offset+2]) << 16 |
|
||||
((unsigned int)raw_bytes[xor_offset+3]) << 24;
|
||||
xor_key += xoring_dword; // increase xor key by xoring dword before XOR
|
||||
xoring_dword ^= xor_key; // XOR
|
||||
// decodeXOR() first XORs, then substracts :) and it goes from end of packet to beginning
|
||||
// update dword inside packet
|
||||
raw_bytes[xor_offset] = (unsigned char)(xoring_dword & 0xFF);
|
||||
raw_bytes[xor_offset+1] = (unsigned char)(xoring_dword >> 8 & 0xFF);
|
||||
raw_bytes[xor_offset+2] = (unsigned char)(xoring_dword >> 16 & 0xFF);
|
||||
raw_bytes[xor_offset+3] = (unsigned char)(xoring_dword >> 24 & 0xFF);
|
||||
// move to next dword
|
||||
xor_offset += 4;
|
||||
}
|
||||
// append resulting xor key to packet
|
||||
writeUInt( xor_key );
|
||||
// add some 4 (trash?) bytes up to size 186
|
||||
writeUInt( 0x00001234 );
|
||||
// now Init packet size is 186 bytes long, all OK
|
||||
// next step before sending packet to client is to encrypt Init packet
|
||||
// by STATIC blowfish key (can be done by calling L2LoginPacket::encodeBlowfish( true );)
|
||||
// NO need to call padPacketTo8ByteLen(), appendChecksum(), appendMore8Bytes().
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Login_Init::parse( L2_VERSION ver )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver); // login server packets may ignore this
|
||||
if( getPacketSize() != 186 ) return false;
|
||||
// first remove blowfish using static BF key (hardcoded)
|
||||
if( !decodeBlowfish( true ) ) return false;
|
||||
if( !decodeXOR() ) return false;
|
||||
// read data
|
||||
_initPublicMembers();
|
||||
if( getPacketType() != 0x00 ) return false;
|
||||
if( !read_SessionID( p_sessionId ) ) return false;
|
||||
p_protoVer = read_ProtoVer();
|
||||
if( !read_RSA_pubKeyMod( p_RSA_pubKeyMod ) ) return false;
|
||||
if( !read_GGShit( p_GG_shit ) ) return false;
|
||||
if( !read_DynamicBFKey( p_BF_dyn_key ) ) return false;
|
||||
unscramble_RSA_PubKeyMod( p_RSA_pubKeyMod );
|
||||
return true;
|
||||
}
|
73
l2packets/login/server/L2Login_Init.h
Normal file
73
l2packets/login/server/L2Login_Init.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#ifndef LOGIN_INIT_H_
|
||||
#define LOGIN_INIT_H_
|
||||
|
||||
#include "../L2LoginPacket.h"
|
||||
|
||||
/**
|
||||
* \class L2Login_Init
|
||||
* Handles Init packet XOR encryption/decryption, RSA public key modulus scrambling/unscrambling,
|
||||
* general Init packet parsing and creation.
|
||||
*/
|
||||
|
||||
class L2Login_Init: public L2LoginPacket
|
||||
{
|
||||
public:
|
||||
/** Default constructor */
|
||||
L2Login_Init();
|
||||
/** Constructs object and calls setBytes() with parameters bytes, length
|
||||
* \param bytes data to set
|
||||
* \param length data size */
|
||||
L2Login_Init( const unsigned char *bytes, unsigned int length );
|
||||
|
||||
protected:
|
||||
void _initPublicMembers();
|
||||
|
||||
public: // Init packet related encoding/decoding functions
|
||||
/** Used only immediately after BF decoding */
|
||||
virtual bool decodeXOR();
|
||||
/** Static function used to decrypt RSA public key modulus from Init packet
|
||||
* \param data must be 128-bytes array */
|
||||
static bool unscramble_RSA_PubKeyMod( unsigned char *data );
|
||||
/** Static function used to encrypt RSA public key modulus from Init packet
|
||||
* \param data must be 128-bytes array */
|
||||
static bool scramble_RSA_PubKeyMod( unsigned char *data );
|
||||
public:
|
||||
/** Called after decoding Init packet (removing Blowfish, XOR)
|
||||
* \param sidBytes must point to array 4 bytes long */
|
||||
virtual bool read_SessionID( unsigned char *sidBytes );
|
||||
/** Read login protocol version (after reading sessionID) */
|
||||
virtual unsigned int read_ProtoVer();
|
||||
/** Read RSA public key modulus after reading login protocol version
|
||||
* \param RSApublicKeyMod must point to buffer 128 bytes len */
|
||||
virtual bool read_RSA_pubKeyMod( unsigned char *RSApublicKeyMod );
|
||||
/** Read some 16 bytes, possibly related to GameGuard (contents and meaning unknown).
|
||||
* Called after reading scrambled RSA public key modulus
|
||||
* \param ggShit - 16 bytes buffer; can be NULL */
|
||||
virtual bool read_GGShit( unsigned char *ggShit );
|
||||
/** Read dynamic Blowfish key, which is used to encrypt/decrypt all following packets in session.
|
||||
* Called after reading 16 bytes GGshit.
|
||||
* \param newBFKey - 16 bytes buffer; must NOT be NULL. */
|
||||
virtual bool read_DynamicBFKey( unsigned char *newBFKey );
|
||||
|
||||
public: // for debugging
|
||||
/** Dumps Init packet to FILE line by line..
|
||||
* \param f - FILE * pointer to opened file. */
|
||||
virtual void displaySelfNice( FILE *f );
|
||||
|
||||
public: // easily create/parse Init packet using public class data members
|
||||
/** Creates Init packet using public data members: p_sessionId, p_protoVer, p_RSA_pubKeyMod, p_GG_shit, p_BF_dyn_key.
|
||||
* Can be used by server app. */
|
||||
virtual bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
/** Parses Init packet, received from server. Result will be in public data members:
|
||||
* p_sessionId, p_protoVer, p_RSA_pubKeyMod, p_GG_shit, p_BF_dyn_key.\n
|
||||
* Performs BF & XOR decryption, reading data, unscrambles RSA public key modulus. */
|
||||
virtual bool parse( L2_VERSION ver = L2_VERSION_T1 );
|
||||
public:
|
||||
unsigned char p_sessionId[4]; ///< session ID, used in some packets later in session.
|
||||
unsigned int p_protoVer; ///< login server protocol version. For >= Interlude it must be 0x0000c621
|
||||
unsigned char p_RSA_pubKeyMod[128]; ///< RSA public key modulus
|
||||
unsigned char p_GG_shit[16]; ///< some bytes
|
||||
unsigned char p_BF_dyn_key[16]; ///< dynamic Blowfish key
|
||||
};
|
||||
|
||||
#endif /* LOGIN_INIT_H_ */
|
77
l2packets/login/server/L2Login_LoginFail.cpp
Normal file
77
l2packets/login/server/L2Login_LoginFail.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Login_LoginFail.h"
|
||||
|
||||
/*
|
||||
L2J:
|
||||
protected void write()
|
||||
{
|
||||
writeC(0x01);
|
||||
writeD(_reason.getCode());
|
||||
}
|
||||
|
||||
REASON_SYSTEM_ERROR (0x01),
|
||||
REASON_PASS_WRONG (0x02),
|
||||
REASON_USER_OR_PASS_WRONG (0x03),
|
||||
REASON_ACCESS_FAILED (0x04),
|
||||
REASON_ACCOUNT_IN_USE (0x07),
|
||||
REASON_SERVER_OVERLOADED (0x0f),
|
||||
REASON_SERVER_MAINTENANCE (0x10),
|
||||
REASON_TEMP_PASS_EXPIRED (0x11),
|
||||
REASON_DUAL_BOX (0x23);
|
||||
*/
|
||||
|
||||
L2Login_LoginFail::L2Login_LoginFail()
|
||||
{
|
||||
this->_initNull();
|
||||
}
|
||||
|
||||
L2Login_LoginFail::L2Login_LoginFail( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
unsigned int L2Login_LoginFail::read_reason()
|
||||
{
|
||||
if( !this->canReadBytes(5) ) return 0;
|
||||
this->readReset();
|
||||
this->readUChar(); // pass packet type byte
|
||||
return this->readUInt();
|
||||
}
|
||||
|
||||
// converts login fail code to human-readable error string :)
|
||||
// s must point to buffer at least 32 bytes long
|
||||
void L2Login_LoginFail::getReasonStr( unsigned int code, char *s )
|
||||
{
|
||||
if( !s ) return;
|
||||
strcpy( s, "REASON_UNKNOWN" );
|
||||
switch( code )
|
||||
{
|
||||
case REASON_SYSTEM_ERROR : strcpy( s, "REASON_SYSTEM_ERROR" ); break;
|
||||
case REASON_PASS_WRONG : strcpy( s, "REASON_PASS_WRONG" ); break;
|
||||
case REASON_USER_OR_PASS_WRONG : strcpy( s, "REASON_USER_OR_PASS_WRONG" ); break;
|
||||
case REASON_ACCESS_FAILED : strcpy( s, "REASON_ACCESS_FAILED" ); break;
|
||||
case REASON_ACCOUNT_IN_USE : strcpy( s, "REASON_ACCOUNT_IN_USE" ); break;
|
||||
case REASON_SERVER_OVERLOADED : strcpy( s, "REASON_SERVER_OVERLOADED" ); break;
|
||||
case REASON_SERVER_MAINTENANCE : strcpy( s, "REASON_SERVER_MAINTENANCE" ); break;
|
||||
case REASON_TEMP_PASS_EXPIRED : strcpy( s, "REASON_TEMP_PASS_EXPIRED" ); break;
|
||||
case REASON_DUAL_BOX : strcpy( s, "REASON_DUAL_BOX" ); break;
|
||||
}
|
||||
}
|
||||
|
||||
bool L2Login_LoginFail::create( L2_VERSION ver /*= L2_VERSION_T1*/ )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
setPacketType( 0x01 );
|
||||
writeUChar( p_reasonCode & 0xFF );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Login_LoginFail::parse( L2_VERSION ver /*= L2_VERSION_T1*/ )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
if( !canReadBytes( 2 ) ) return false;
|
||||
if( getPacketType() != 0x01 ) return false;
|
||||
p_reasonCode = (unsigned int)readUChar();
|
||||
return true;
|
||||
}
|
33
l2packets/login/server/L2Login_LoginFail.h
Normal file
33
l2packets/login/server/L2Login_LoginFail.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef L2LOGIN_LOGINFAIL_H_
|
||||
#define L2LOGIN_LOGINFAIL_H_
|
||||
|
||||
#include "../L2LoginPacket.h"
|
||||
|
||||
class L2Login_LoginFail : public L2LoginPacket
|
||||
{
|
||||
public:
|
||||
static const unsigned int REASON_SYSTEM_ERROR = 0x01;
|
||||
static const unsigned int REASON_PASS_WRONG = 0x02;
|
||||
static const unsigned int REASON_USER_OR_PASS_WRONG = 0x03;
|
||||
static const unsigned int REASON_ACCESS_FAILED = 0x04;
|
||||
static const unsigned int REASON_ACCOUNT_IN_USE = 0x07;
|
||||
static const unsigned int REASON_SERVER_OVERLOADED = 0x0f;
|
||||
static const unsigned int REASON_SERVER_MAINTENANCE = 0x10;
|
||||
static const unsigned int REASON_TEMP_PASS_EXPIRED = 0x11;
|
||||
static const unsigned int REASON_DUAL_BOX = 0x23;
|
||||
public:
|
||||
L2Login_LoginFail();
|
||||
L2Login_LoginFail( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
unsigned int read_reason();
|
||||
// converts login fail code to human-readable error string :)
|
||||
// s must point to buffer at least 32 bytes long
|
||||
static void getReasonStr( unsigned int code, char *s );
|
||||
public:
|
||||
bool create( L2_VERSION ver = L2_VERSION_T1 );
|
||||
bool parse( L2_VERSION ver = L2_VERSION_T1 );
|
||||
public:
|
||||
unsigned int p_reasonCode;
|
||||
};
|
||||
|
||||
#endif /*L2LOGIN_LOGINFAIL_H_*/
|
56
l2packets/login/server/L2Login_LoginOK.cpp
Normal file
56
l2packets/login/server/L2Login_LoginOK.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Login_LoginOK.h"
|
||||
|
||||
L2Login_LoginOK::L2Login_LoginOK()
|
||||
{
|
||||
this->_initNull();
|
||||
}
|
||||
|
||||
L2Login_LoginOK::L2Login_LoginOK( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
// read SessionKey #1 from packet
|
||||
// sessionKey1 must point to 8-byte array
|
||||
bool L2Login_LoginOK::read_sessionKey1( unsigned char *sessionKey1 )
|
||||
{
|
||||
if( !sessionKey1 ) return false;
|
||||
// check packet size
|
||||
if( this->real_size < 9 ) return false;
|
||||
this->readReset();
|
||||
this->readUChar(); // pass packet code byte
|
||||
this->readBytes( sessionKey1, 8 ); // read 8 bytes of sessionKey1
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Login_LoginOK::create( L2_VERSION ver /*= L2_VERSION_T23*/ )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
setPacketType( 0x03 );
|
||||
writeBytes( p_sessionKey1, 8 );
|
||||
writeD( 0x00 );
|
||||
writeD( 0x00 );
|
||||
writeD( 0x000003ea ); // wtf?
|
||||
writeD( 0x00 );
|
||||
writeD( 0x00 );
|
||||
writeD( 0x00 );
|
||||
//writeB(new byte[16]); // 4 Ds
|
||||
writeD( 0x00 );
|
||||
writeD( 0x00 );
|
||||
writeD( 0x00 );
|
||||
writeD( 0x00 );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Login_LoginOK::parse( L2_VERSION ver /*= L2_VERSION_T23*/ )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
if( getPacketType() != 0x03 ) return false;
|
||||
if( !canReadBytes( 8 ) ) return false; // we need at least 8 bytes of sessionKey1
|
||||
readBytes( p_sessionKey1, 8 );
|
||||
// ignore the rest
|
||||
return true;
|
||||
}
|
||||
|
22
l2packets/login/server/L2Login_LoginOK.h
Normal file
22
l2packets/login/server/L2Login_LoginOK.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef L2LOGIN_LOGINOK_H_
|
||||
#define L2LOGIN_LOGINOK_H_
|
||||
|
||||
#include "../L2LoginPacket.h"
|
||||
|
||||
class L2Login_LoginOK : public L2LoginPacket
|
||||
{
|
||||
public:
|
||||
L2Login_LoginOK();
|
||||
L2Login_LoginOK( const unsigned char *bytes, unsigned int length );
|
||||
public:
|
||||
// read SessionKey #1 from packet
|
||||
// SessionKey is 8-byte array
|
||||
bool read_sessionKey1( unsigned char *sessionKey1 );
|
||||
public:
|
||||
bool create( L2_VERSION ver = L2_VERSION_T23 );
|
||||
bool parse( L2_VERSION ver = L2_VERSION_T23 );
|
||||
public:
|
||||
unsigned char p_sessionKey1[8];
|
||||
};
|
||||
|
||||
#endif /*L2LOGIN_LOGINOK_H_*/
|
64
l2packets/login/server/L2Login_PlayFail.cpp
Normal file
64
l2packets/login/server/L2Login_PlayFail.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Login_PlayFail.h"
|
||||
|
||||
/*
|
||||
writeC(0x06);
|
||||
writeC(_reason.getCode());
|
||||
*/
|
||||
|
||||
L2Login_PlayFail::L2Login_PlayFail()
|
||||
{
|
||||
this->_initNull();
|
||||
}
|
||||
|
||||
L2Login_PlayFail::L2Login_PlayFail( const unsigned char *bytes, unsigned int length )
|
||||
{
|
||||
this->_initNull();
|
||||
this->setBytes( bytes, length );
|
||||
}
|
||||
|
||||
unsigned char L2Login_PlayFail::read_reason()
|
||||
{
|
||||
if( this->canReadBytes(2) )
|
||||
{
|
||||
this->readReset();
|
||||
this->readUChar();
|
||||
return this->readUChar();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// str must point to buffer at least 32 bytes long
|
||||
bool L2Login_PlayFail::getReasonStr( unsigned char code, char *str )
|
||||
{
|
||||
if( !str ) return false;
|
||||
strcpy( str, "REASON_UNKNOWN" );
|
||||
switch( code )
|
||||
{
|
||||
case REASON_SYSTEM_ERROR: strcpy( str, "REASON_SYSTEM_ERROR" ); break;
|
||||
case REASON_USER_OR_PASS_WRONG: strcpy( str, "REASON_USER_OR_PASS_WRONG" ); break;
|
||||
case REASON3: strcpy( str, "REASON3" ); break;
|
||||
case REASON_ACCESS_FAILED: strcpy( str, "REASON_ACCESS_FAILED" ); break;
|
||||
case REASON_ACCOUNT_INFORMATION_INCORRECT: strcpy( str, "REASON_ACCOUNT_INFORMATION_INCORRECT" ); break;
|
||||
case REASON_TOO_MANY_PLAYERS: strcpy( str, "REASON_TOO_MANY_PLAYERS" ); break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Login_PlayFail::create( L2_VERSION ver /*= L2_VERSION_T1*/ )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
setPacketType( 0x06 );
|
||||
writeUChar( p_reasonCode );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool L2Login_PlayFail::parse( L2_VERSION ver /*= L2_VERSION_T1*/ )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ver);
|
||||
if( getPacketType() != 0x06 ) return false;
|
||||
if( !canReadBytes(1) ) return false;
|
||||
p_reasonCode = readUChar();
|
||||
return true;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user