582 lines
20 KiB
C++
582 lines
20 KiB
C++
#include "stdafx.h"
|
|
#include "ConfigIni.h"
|
|
#include "Logger.h"
|
|
#include "GameClient.h"
|
|
#include "GameListener.h"
|
|
#include "L2PacketTypes.h"
|
|
#include "accountBind.h"
|
|
|
|
extern class CConfig g_cfg;
|
|
|
|
// Parameters:
|
|
//
|
|
// returns true if packet was modified
|
|
// if packet was not modified:
|
|
// sets (*newLen) to len;
|
|
// sets (*newBytes) to bytes
|
|
// - caller can ignore newLen and newBytes content in this case
|
|
// - caller can use newLen and newBytes instead of original values (they are the same)
|
|
// - caller should send original packet
|
|
// - caller should free original packet buffer
|
|
// if packet was modified:
|
|
// sets (*newLen) to new length of packet
|
|
// sets (*newBytes) to point to new bytes buffer
|
|
// - newBytes are properly encoded if needed,
|
|
// - caller just should send newBytes and free them after sending
|
|
// - caller should also free original packet buffer
|
|
// if packet should be dropped:
|
|
// sets (*newLen) to -1
|
|
// - caller should ignore newLen and newBytes content
|
|
// - caller should not send any packet :)
|
|
// - caller should free original packet buffer
|
|
//
|
|
bool GameClient::PP_full_fromClient( unsigned char *bytes, unsigned int len,
|
|
unsigned char **newBytes, unsigned int *newLen )
|
|
{
|
|
// assume packet was not modified
|
|
(*newLen) = len;
|
|
(*newBytes) = bytes;
|
|
//
|
|
//int i = 0;
|
|
bool bPacketWasModified = false; // initially packet is not modified
|
|
if( !bytes || len<1 ) return bPacketWasModified;
|
|
if( len<3 )
|
|
{
|
|
log_error( LOG_WARNING, "PP_full_fromClient(): packet len < 3!\n" );
|
|
return bPacketWasModified;
|
|
}
|
|
|
|
// should we decrypt it?
|
|
if( this->xor_enabled ) L2GamePacket::decodeXOR_buffer( bytes, len, this->key_client_cs );
|
|
|
|
// parse it
|
|
unsigned char ptype = bytes[2];
|
|
unsigned short int ptype2 = 0x0000;
|
|
unsigned short int ptype3 = 0x0000;
|
|
if( len >= 5 )
|
|
{
|
|
ptype2 |= (unsigned short int)(bytes[3] & 0xFFFF);
|
|
ptype2 |= (unsigned short int)(bytes[4] << 8 & 0xFFFF);
|
|
}
|
|
if( len >= 7 )
|
|
{
|
|
ptype3 |= (unsigned short int)(bytes[5] & 0xFFFF);
|
|
ptype3 |= (unsigned short int)(bytes[6] << 8 & 0xFFFF);
|
|
}
|
|
|
|
// obfuscator
|
|
class L2PCodeObfuscator *lpco;
|
|
lpco = (class L2PCodeObfuscator *)this->clsObfuscator;
|
|
|
|
if( lpco )
|
|
{
|
|
if( lpco->isEnabled() )
|
|
{
|
|
unsigned char pcode_prev = ptype;
|
|
unsigned short pcode2_prev = ptype2;
|
|
bool decode_res = false;
|
|
try
|
|
{
|
|
decode_res = lpco->decodeOpcode( ptype, ptype2 );
|
|
}
|
|
catch( L2P_DeObfuscateException& e )
|
|
{
|
|
log_error( LOG_ERROR, "PP_full_fromClient(): L2P_DeObfuscateException: %s\n", e.what() );
|
|
}
|
|
if( decode_res )
|
|
{
|
|
if( pcode2_prev == ptype2 ) // 2nd opcode not changed, not double-opcode packet
|
|
log_error( LOG_DEBUG, " **** de-obfuscated %02X -> %02X ****\n", pcode_prev, ptype );
|
|
else
|
|
log_error( LOG_DEBUG, " **** de-obfuscated %02X:%02X -> %02X:%02X ****\n",
|
|
pcode_prev, pcode2_prev, ptype, ptype2 );
|
|
}
|
|
else
|
|
log_error( LOG_ERROR, "PP_full_fromClient(): ERROR de-obfuscating %02X\n", pcode_prev );
|
|
}
|
|
}
|
|
|
|
// log packet here, when it is decrypted, and opcode is deobfuscated, if log game packets is enabled
|
|
if( this->logfile )
|
|
{
|
|
unsigned char prev_1 = bytes[2];
|
|
unsigned short prev_2 = bytes[3] | (bytes[4] << 8);
|
|
unsigned short prev_3 = bytes[5] | (bytes[6] << 8);
|
|
if( this->clsObfuscator )
|
|
{
|
|
// replace opcode byte in bytes array to de-obfuscated opcode
|
|
// to make log readable
|
|
bytes[2] = ptype;
|
|
if( len >= 5 )
|
|
{
|
|
bytes[3] = ptype2 & 0xFF;
|
|
bytes[4] = (ptype2 >> 8) & 0xFF;
|
|
if( len >= 7 )
|
|
{
|
|
bytes[5] = ptype3 & 0xFF;
|
|
bytes[6] = (ptype3 >> 8) & 0xFF;
|
|
}
|
|
}
|
|
}
|
|
logPacket( bytes, len, false ); // false - from client
|
|
if( this->clsObfuscator )
|
|
{
|
|
// restore opcode byte in bytes array to original
|
|
// to keep packet 'as is'
|
|
bytes[2] = prev_1;
|
|
if( len >= 5 )
|
|
{
|
|
bytes[3] = prev_2 & 0xFF;
|
|
bytes[4] = (prev_2 >> 8) & 0xFF;
|
|
if( len >= 7 )
|
|
{
|
|
bytes[5] = prev_3 & 0xFF;
|
|
bytes[6] = (prev_3 >> 8) & 0xFF;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
L2PacketTypes_LogClient( (L2_VERSION)g_cfg.L2_client_version, this->state, ptype, ptype2, ptype3 );
|
|
|
|
// special handling packet sequential number
|
|
if( this->counters.ullPacketsSent == 0 )
|
|
{
|
|
// client sends first packet - ProtocolVersion
|
|
if( g_cfg.OverrideGameProtocolVersion > 0 )
|
|
{
|
|
// we can replace ProtocolVersion now...
|
|
int cur_pv = bytes[3] | (bytes[4]<<8) | (bytes[5]<<16) | (bytes[6]<<24);
|
|
// check for client pings server (usually: pv == -2 or 0xFFFFFFFE)
|
|
if( (cur_pv >= 0xFFFFFFF0) || (cur_pv < 0) )
|
|
{
|
|
log_error( LOG_PACKETNAME, "Received client ping server... no process\n" );
|
|
this->thisWasJustServerPing = true; // received client ping (full)
|
|
return false; // flag: packet was not modified, and no need to re-encode it
|
|
}
|
|
//
|
|
log_error( LOG_PACKETNAME, "Client: 0e ProtocolVersion: Overriding ProtocolVersion from %d to %d\n",
|
|
cur_pv, g_cfg.OverrideGameProtocolVersion );
|
|
bytes[3] = (unsigned char)( (g_cfg.OverrideGameProtocolVersion & 0x000000FF) );
|
|
bytes[4] = (unsigned char)( (g_cfg.OverrideGameProtocolVersion & 0x0000FF00) >> 8 );
|
|
if( g_cfg.OverrideGameProtocolVersion == 828 )
|
|
{
|
|
/* Overriding to Kamael T1. we must replace also last 4 bytes */
|
|
bytes[263] = 0x8D;
|
|
bytes[264] = 0x71;
|
|
bytes[265] = 0x5F;
|
|
bytes[266] = 0x08;
|
|
log_error( LOG_PACKETNAME, "Client: 0e ProtocolVersion: Overriding ProtocolVersion to T1: Kamael\n" );
|
|
}
|
|
if( g_cfg.OverrideGameProtocolVersion == 831 )
|
|
{
|
|
/* Overriding to Hellbound T1.5. we must replace also last 4 bytes */
|
|
bytes[263] = 0xFB;
|
|
bytes[264] = 0x87;
|
|
bytes[265] = 0xB9;
|
|
bytes[266] = 0x4A;
|
|
log_error( LOG_PACKETNAME, "Client: 0e ProtocolVersion: Overriding ProtocolVersion to T1.5: Hellbound\n" );
|
|
}
|
|
if( g_cfg.OverrideGameProtocolVersion == 851 )
|
|
{
|
|
/* Overriding to Gracia T2. we must replace also last 4 bytes */
|
|
bytes[263] = 0xDF;
|
|
bytes[264] = 0xB8;
|
|
bytes[265] = 0x3B;
|
|
bytes[266] = 0x54;
|
|
log_error( LOG_PACKETNAME, "Client: 0e ProtocolVersion: Overriding ProtocolVersion to T2: Gracia Part 1\n" );
|
|
}
|
|
if( g_cfg.OverrideGameProtocolVersion >= 12 && g_cfg.OverrideGameProtocolVersion <= 17 )
|
|
{
|
|
/* Overriding to Gracia T2.2. we must replace also last 4 bytes */
|
|
bytes[263] = 0xEB;
|
|
bytes[264] = 0xEF;
|
|
bytes[265] = 0x3D;
|
|
bytes[266] = 0xE6;
|
|
log_error( LOG_PACKETNAME, "Client: 0e ProtocolVersion: Overriding ProtocolVersion to T2.2: Gracia Part 2\n" );
|
|
}
|
|
if( g_cfg.OverrideGameProtocolVersion >= 83 && g_cfg.OverrideGameProtocolVersion <= 87 )
|
|
{
|
|
/* Overriding to Gracia T2.3. we must replace also last 4 bytes */
|
|
bytes[263] = 0x11;
|
|
bytes[264] = 0x5D;
|
|
bytes[265] = 0x1F;
|
|
bytes[266] = 0x60;
|
|
log_error( LOG_PACKETNAME, "Client: 0e ProtocolVersion: Overriding ProtocolVersion to T2.3: Gracia Final\n" );
|
|
}
|
|
if( g_cfg.OverrideGameProtocolVersion >= 146 && g_cfg.OverrideGameProtocolVersion <= 148 )
|
|
{
|
|
/* Overriding to Gracia T2.4. we must replace also last 4 bytes */
|
|
bytes[263] = 0xA6;
|
|
bytes[264] = 0x23;
|
|
bytes[265] = 0xF4;
|
|
bytes[266] = 0xFE;
|
|
log_error( LOG_PACKETNAME, "Client: 0e ProtocolVersion: Overriding ProtocolVersion to T2.4: Gracia Epilogue\n" );
|
|
}
|
|
return true; // flag that packet was modified :)
|
|
// we can use return here, because encoding is not required for this packet
|
|
// packet will be sent to server as is, without encoding
|
|
}
|
|
}
|
|
// special handling packet sequential number end
|
|
|
|
switch( this->state )
|
|
{
|
|
case GCST_CONNECTED:
|
|
{
|
|
switch( ptype )
|
|
{
|
|
//case 0x00: // ProtocolVersion // Interlude
|
|
case 0x0e: // ProtocolVersion // Hellbound
|
|
{
|
|
L2Game_ProtocolVersion *p = new L2Game_ProtocolVersion( bytes, len );
|
|
p->read_protoVer( &(this->gameProtoVer) );
|
|
delete p;
|
|
log_error( LOG_PACKETNAME, "Client: 0e ProtocolVersion %u\n", this->gameProtoVer );
|
|
if( this->gameProtoVer >= 0xFFFFFFF0 ) // < 0
|
|
{
|
|
this->thisWasJustServerPing = true; // received client ping (full)
|
|
log_error( LOG_PACKETNAME, "Received client ping server... no process\n" );
|
|
}
|
|
} break; // ProtocolVersion
|
|
// case 0x08: // AuthLogin // Interlude
|
|
case 0x2b: // AuthLogin // Hellbound
|
|
{
|
|
L2Game_AuthLogin *p = new L2Game_AuthLogin( bytes, len );
|
|
char login[32] = {0};
|
|
p->read_login( login );
|
|
delete p;
|
|
log_error( LOG_DEBUG, "Client: 2b AuthLogin: Login: \"%s\"\n", login );
|
|
#ifdef _ACCOUNT_BIND
|
|
if( !isValidAccount( login ) )
|
|
{
|
|
log_error( LOG_ERROR, "Client: invalid account name (not bound to this). Exiting.\n" );
|
|
ErrorLogger_FlushLogFile();
|
|
L2PNet_shutdown( this->sock_client );
|
|
L2PNet_shutdown( this->sock_server );
|
|
Sleep( 2000 );
|
|
L2PNet_closesocket( this->sock_client );
|
|
L2PNet_closesocket( this->sock_server );
|
|
ExitProcess( 123 );
|
|
}
|
|
#endif
|
|
} break; // AuthLogin
|
|
//default:
|
|
// {
|
|
// log_error( LOG_DEBUGDUMP, "Client: Unknown packet %02X in state: CONNECTED\n",
|
|
// (unsigned int)ptype );
|
|
// if( g_cfg.DumpUnknownToStdout )
|
|
// {
|
|
// printf( "============================================\n" );
|
|
// L2GamePacket *p = new L2GamePacket( bytes, len );
|
|
// p->dumpToFile( stdout );
|
|
// delete p;
|
|
// printf( "============================================\n" );
|
|
// }
|
|
// } break;
|
|
} // switch( ptype )
|
|
} break; // CONNECTED
|
|
|
|
|
|
//case GCST_AUTHED:
|
|
//{
|
|
// switch( ptype )
|
|
// {
|
|
//case 0x00: // LogoutRequest
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: 00 LogoutRequest\n" );
|
|
// } break;
|
|
//case 0x12: // CharacterSelect // Hellbound
|
|
// {
|
|
// int charSlot = bytes[3];
|
|
// //L2Game_CharacterSelect *p = new L2Game_CharacterSelect( bytes, len );
|
|
// log_error( LOG_PACKETNAME, "Client: 12 CharacterSelect: #%d\n", charSlot );
|
|
// //this->state = GCST_IN_GAME;
|
|
// //log_error( LOG_DEBUG, "Client: 12 CharacterSelect: switch state to IN_GAME\n" );
|
|
// } break; // CharacterSelect
|
|
//case 0x13: // NewCharacter
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: 13 NewCharacter\n" );
|
|
// } break; // NewCharacter
|
|
//case 0x0c: // CharacterCreate
|
|
// {
|
|
// wchar_t charNameU[64] = {0};
|
|
// char charName[64] = {0};
|
|
// wcscpy( charNameU, (const wchar_t *)(bytes+3) );
|
|
// sprintf( charName, "%S", charNameU );
|
|
// log_error( LOG_PACKETNAME, "Client: 0c CharacterCreate [%s]\n", charName );
|
|
// } break; // CharacterCreate
|
|
//case 0xd0:
|
|
// {
|
|
// ptype2 = 0x0000;
|
|
// if( len >= 5 )
|
|
// {
|
|
// ptype2 |= (unsigned short int)(bytes[3] & 0xFFFF);
|
|
// ptype2 |= (unsigned short int)(bytes[4] << 8 & 0xFFFF);
|
|
// if( ptype2 == 0x0039 )
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: D0:39 RequestGotoLobby\n" );
|
|
// }
|
|
// else
|
|
// {
|
|
// log_error( LOG_WARNING, "Client: Unknown opcode2 %04X for state AUTHED packet 0xD0\n",
|
|
// (unsigned int)ptype2 );
|
|
// }
|
|
// }
|
|
// else
|
|
// log_error( LOG_WARNING, "Client: (AUTHED) sent 0xd0 without second opcode!\n" );
|
|
// } break; // double opcode packet
|
|
//default:
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: Unknown packet %02X in state: AUTHED\n",
|
|
// (unsigned int)ptype );
|
|
// if( g_cfg.DumpUnknownToStdout )
|
|
// {
|
|
// printf( "============================================\n" );
|
|
// L2GamePacket *p = new L2GamePacket( bytes, len );
|
|
// p->dumpToFile( stdout );
|
|
// delete p;
|
|
// printf( "============================================\n" );
|
|
// }
|
|
// } break;
|
|
//} // switch( ptype )
|
|
//} break; // AUTHED
|
|
|
|
|
|
case GCST_IN_GAME:
|
|
{
|
|
switch( ptype )
|
|
{
|
|
//case 0x00: // LogoutRequest
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: 00 LogoutRequest\n" );
|
|
// } break;
|
|
case 0x0f: // MoveBackwardToLocation
|
|
{
|
|
//log_error( LOG_PACKETNAME, "Client: 0f MoveBackwardToLocation\n" );
|
|
if( g_cfg.L2Walker_FixMoveBackwardToLocation )
|
|
{
|
|
//log_error( LOG_OK, "Fixing L2Walker's MoveBackwardToLocation\n" );
|
|
if( len == 27 )
|
|
{
|
|
//log_error( LOG_OK, "It is L2Walker's packet\n" );
|
|
unsigned char *np = (unsigned char *)malloc( len + 4 );
|
|
if( np )
|
|
{
|
|
(*newBytes) = np;
|
|
(*newLen) = len + 4;
|
|
memcpy( np, bytes, len );
|
|
np[0] = ((unsigned char)31); // length of correct packet must be 31
|
|
np[1] = 0;
|
|
np[len + 0] = 0x01;
|
|
np[len + 1] = 0x00;
|
|
np[len + 2] = 0x00;
|
|
np[len + 3] = 0x00;
|
|
//
|
|
bPacketWasModified = true; // so it will be encoded in the end of this function
|
|
}
|
|
//else log_error( LOG_ERROR, "malloc() error!\n" );
|
|
}
|
|
//else if( len == 31 )
|
|
//{
|
|
// log_error( LOG_OK, "It is normal client's packet. No need to change\n" );
|
|
//}
|
|
//else log_error( LOG_ERROR, "Unknown MoveBackwardToLocation packet!\n" );
|
|
}
|
|
} break;
|
|
//case 0x11: // EnterWorld
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: 11 EnterWorld\n" );
|
|
// } break;
|
|
//case 0x14: // RequestItemList
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: 14 RequestItemList\n" );
|
|
// } break;
|
|
//case 0x19: // UseItem
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: 19 UseItem\n" );
|
|
// } break;
|
|
case 0x1F: // Action
|
|
{
|
|
//log_error( LOG_PACKETNAME, "Client: 1F Action\n" );
|
|
L2Game_Action *p = new L2Game_Action( bytes, len );
|
|
unsigned int actionObjectId = p->read_objectID();
|
|
p->read_originX();
|
|
p->read_originY();
|
|
p->read_originZ();
|
|
//char useShift = p->read_useShift();
|
|
delete p;
|
|
// notify LockTarget manager
|
|
ai.lockTargetMgr.onUserRequestAction( actionObjectId );
|
|
//
|
|
//if( useShift /* && g_cfg.altGameViewNpc */ )
|
|
//{
|
|
// L2OBJECT_TYPE objType = L2OT_NONE;
|
|
// int index = -1;
|
|
// if( WorldObjectTree_GetInfoByObjectID( oid, &objType, &index ) )
|
|
// {
|
|
// // disable Shift + click on NPC
|
|
// /*if( objType == L2OT_NPC )
|
|
// {
|
|
// L2Npc *npc = npc_array[index];
|
|
// char filename[256];
|
|
// sprintf( filename, "npc_%d_stats.txt", npc->templateID );
|
|
// FILE *f = fopen( filename, "wt" );
|
|
// fprintf( f, "x,y,z,heading: (%d,%d,%d) %u\n", npc->x, npc->y, npc->z, npc->heading );
|
|
// fprintf( f, "mAtkSpd, pAtkSpd: %d, %d\n", npc->mAtkSpd, npc->pAtkSpd );
|
|
// fprintf( f, "runSpeed, walkSpeed: %d, %d\n", npc->runSpeed, npc->walkSpeed );
|
|
// fprintf( f, "colR, colH: %0.2f, %0.2f\n", npc->collisionRadius, npc->collisionHeight );
|
|
// fprintf( f, "rhand, chest, lhand: %u, %u, %u\n", npc->iid_right_hand, npc->iid_chest, npc->iid_left_hand );
|
|
// fclose( f );
|
|
// }*/
|
|
// // maybe add Shift + click on player action? :)
|
|
// }
|
|
//}
|
|
} break;
|
|
case 0x22: // RequestLinkHtml
|
|
{
|
|
// this packet requires handling... it may be dropped if AI decides to
|
|
this->ai.UAI_process_RequestBypassToServer( bytes, len, newBytes, newLen );
|
|
} break;
|
|
case 0x23: // RequestBypassToServer
|
|
{
|
|
// this packet requires handling... it may be dropped if AI decides to
|
|
this->ai.UAI_process_RequestBypassToServer( bytes, len, newBytes, newLen );
|
|
} break;
|
|
case 0x36: // ChangeWaitType2
|
|
{
|
|
if( g_cfg.L2Walker_FixChangeWaitType2 )
|
|
{
|
|
log_error( LOG_OK, "Client: Fixing 36 ChangeWaitType2\n" );
|
|
// ChangeWaitType2 format:
|
|
// * Client: Len 7 | 07 00 / 36 / 00 00 00 00 - sit
|
|
// * Client: Len 7 | 07 00 / 36 / 01 00 00 00 - stand
|
|
// Instead of ChangeWaitType2 send RequestActionUse, so does client!
|
|
// only L2Walker sends ChangeWaitType2 :\
|
|
// RequestActionUse sit/stand format:
|
|
// * Client: Len 12 | 0C 00 / 56 / 00 00 00 00 00 00 00 00 00
|
|
// TODO: opcode obfuscate
|
|
unsigned char opcode_RequestActionUse = 0x56; // RequestActionUse
|
|
unsigned short doubleOpcode = 0x00;
|
|
if( this->clsObfuscator )
|
|
{
|
|
L2PCodeObfuscator *lpco = (L2PCodeObfuscator *)(this->clsObfuscator);
|
|
if( lpco->isEnabled() )
|
|
{
|
|
lpco->encodeOpcode( opcode_RequestActionUse, doubleOpcode );
|
|
log_error( LOG_DEBUG, "Fix ChangeWaitType2: obfuscated 56 -> %02X\n", opcode_RequestActionUse );
|
|
}
|
|
}
|
|
// create packet
|
|
L2GamePacket *gp = new L2GamePacket();
|
|
gp->setPacketType( opcode_RequestActionUse ); //gp->setPacketType( 0x56 ); // opcode :)
|
|
gp->writeUInt( 0 ); // actionID
|
|
gp->writeUInt( 0 ); // ctrlPressed
|
|
gp->writeUChar( 0 ); // shiftPressed
|
|
(*newLen) = gp->getPacketSize();
|
|
if( (*newLen) == 0x0C ) // new length must be = 12 bytes
|
|
{
|
|
log_error( LOG_OK, "Client: Fixed 36 ChangeWaitType2 OK\n" );
|
|
bPacketWasModified = true;
|
|
(*newBytes) = (unsigned char *)malloc( (*newLen) );
|
|
memcpy( (*newBytes), gp->getBytesPtr(), (*newLen) );
|
|
}
|
|
delete gp;
|
|
}
|
|
} break;
|
|
//case 0x39: // RequestMagicSkillUse
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: 39 RequestMagicSkillUse\n" );
|
|
// } break;
|
|
//case 0x3d: // RequestMagicSkillUse
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: 3D RequestShortCutReg\n" );
|
|
// } break;
|
|
case 0x48: // RequestTargetCanceld
|
|
{
|
|
//log_error( LOG_PACKETNAME, "Client: 48 RequestTargetCanceld\n" );
|
|
ai.lockTargetMgr.onUserRequestUnselectTarget();
|
|
} break;
|
|
//case 0x57: // RequestRestart
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: 57 RequestRestart\n" );
|
|
// //this->state = GCST_AUTHED;
|
|
// } break;
|
|
//case 0x59: // ValidatePosition
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: 59 ValidatePosition\n" );
|
|
// } break;
|
|
//case 0x65: // RequestPledgeInfo
|
|
// {
|
|
// // TODO: parse RequestPledgeInfo?
|
|
// log_error( LOG_OK, "Client: 65 RequestPledgeInfo\n" );
|
|
// } break;
|
|
case 0x8B: // RequestGmList
|
|
{
|
|
// RequestGmList kill packet?
|
|
//log_error( LOG_PACKETNAME, "Client: 8B RequestGmList\n" );
|
|
if( g_cfg.L2Walker_DropRequestGMList )
|
|
{
|
|
log_error( LOG_WARNING, "Client: Droppped RequestGMList!\n" );
|
|
(*newLen) = (unsigned int)-1; // mark to drop
|
|
}
|
|
} break;
|
|
//case 0xA6: // RequestSkillCoolTime
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: A6 RequestSkillCoolTime\n" );
|
|
// } break;
|
|
//case 0xCB: // GameGuardReply
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: CB GameGuardReply\n" );
|
|
// } break;
|
|
//case 0xd0:
|
|
// {
|
|
// ptype2 = 0x00;
|
|
// if( len >= 5 )
|
|
// {
|
|
// ptype2 |= (unsigned short int)(bytes[3] & 0xFFFF);
|
|
// ptype2 |= (unsigned short int)(bytes[4] << 8 & 0xFFFF);
|
|
// switch( ptype2 )
|
|
// {
|
|
// case 0x0065: // drop :)
|
|
// log_error( LOG_WARNING, "Client: Droppped D0:65 (RequestPostItemList in Epilogue)!\n" );
|
|
// (*newLen) = (unsigned int)-1; // mark to drop
|
|
// break;
|
|
// }
|
|
// }
|
|
// else
|
|
// log_error( LOG_WARNING, "Client: (IN_GAME) sent 0xD0 without second opcode!\n" );
|
|
// } break; // double opcode packet
|
|
//default:
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: Unknown packet %02X in state: IN_GAME\n",
|
|
// (unsigned int)ptype );
|
|
// if( g_cfg.DumpUnknownToStdout )
|
|
// {
|
|
// printf( "============================================\n" );
|
|
// L2GamePacket *p = new L2GamePacket( bytes, len );
|
|
// p->dumpToFile( stdout );
|
|
// delete p;
|
|
// printf( "============================================\n" );
|
|
// }
|
|
// } break;
|
|
} // switch( ptype )
|
|
} break; // IN_GAME
|
|
|
|
} // switch( state )
|
|
|
|
// all encoding takes place ONLY IF PACKET IS NOT SET TO DROP!!!!
|
|
if( (*newLen) != -1 )
|
|
{
|
|
// re-encode packet again =] olny encode original packetif it was not modified
|
|
//PP_full_reencode_packet( bytes, len, this->key_server_cs );
|
|
//log_error( LOG_ERROR, "PP_full_reencode_packet() C->S FAILED\n" );
|
|
if( !bPacketWasModified && this->xor_enabled ) L2GamePacket::encodeXOR_buffer( bytes, len, this->key_server_cs );
|
|
// if packet was modified, encode only modified packet (encode only that will be sent)
|
|
if( bPacketWasModified ) L2GamePacket::encodeXOR_buffer( (*newBytes), (*newLen), this->key_server_cs );
|
|
}
|
|
else log_error( LOG_PACKETNAME, "Client: No encode - DROP packet!\n" );
|
|
|
|
return bPacketWasModified;
|
|
}
|