l2-unlegits/l2packets/game/server/L2Game_KeyPacket.cpp
2012-02-01 05:25:08 +00:00

123 lines
3.9 KiB
C++

#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;
}