333 lines
10 KiB
C++
333 lines
10 KiB
C++
#include "stdafx.h"
|
|
#include "ConfigIni.h"
|
|
#include "Logger.h"
|
|
#include "GameClient.h"
|
|
#include "GameListener.h"
|
|
#include "L2PacketTypes.h"
|
|
|
|
extern class CConfig g_cfg;
|
|
|
|
void GameClient::PP_sniff_fromClient( unsigned char *bytes, unsigned int len )
|
|
{
|
|
//int i = 0;
|
|
if( !bytes || len<1 ) return;
|
|
if( len<3 )
|
|
{
|
|
log_error( LOG_WARNING, "PP_sniff_fromClient(): packet len < 3!\n" );
|
|
log_error( LOG_WARNING, "PP_sniff_fromClient(): bytes=0x%p, len=%d\n", bytes, len );
|
|
return;
|
|
}
|
|
|
|
// should we decrypt it?
|
|
if( this->xor_enabled ) // yeah :)
|
|
{
|
|
if( !L2GamePacket::decodeXOR_buffer( bytes, len, this->key_client_cs ) )
|
|
log_error( LOG_ERROR, "PP_sniff_fromClient(): decodeXOR_buffer() failed!\n" );
|
|
}
|
|
|
|
// some vars
|
|
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 = lpco->decodeOpcode( ptype, ptype2, ptype3 );
|
|
if( decode_res )
|
|
{
|
|
if( pcode2_prev == ptype2 )
|
|
log_error( LOG_PACKETNAME, " **** de-obfuscated %02X -> %02X\n", pcode_prev, ptype );
|
|
else
|
|
log_error( LOG_PACKETNAME, " **** de-obfuscated %02X:%02X -> %02X:%02X\n",
|
|
pcode_prev, pcode2_prev, ptype, ptype2 );
|
|
}
|
|
else
|
|
log_error( LOG_ERROR, "PP_sniff_fromClient(): ERROR de-obfuscating %02X\n", pcode_prev );
|
|
}
|
|
}
|
|
|
|
L2PacketTypes_LogClient( (L2_VERSION)g_cfg.L2_client_version, this->state, ptype, ptype2, ptype3 );
|
|
|
|
// from client
|
|
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 );
|
|
// client sends protocolVersion = 0xFFFFFFFF when it pings server (not tries to connect really)
|
|
if( this->gameProtoVer >= 0xFFFFFFF0 )
|
|
{
|
|
log_error( LOG_PACKETNAME, "Received client ping server... no process\n" );
|
|
this->thisWasJustServerPing = true; // received client ping (sniff)
|
|
}
|
|
} 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_PACKETNAME, "Client: 2b AuthLogin: Login: \"%s\"\n", login );
|
|
} 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:0039 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" );
|
|
// } 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 oid = p->read_objectID();
|
|
p->read_originX();
|
|
p->read_originY();
|
|
p->read_originZ();
|
|
char useShift = p->read_useShift();
|
|
delete p;
|
|
if( useShift /* && g_cfg.altGameViewNpc */ )
|
|
{
|
|
L2OBJECT_TYPE objType = L2OT_NONE;
|
|
int index = -1;
|
|
if( WorldObjectTree_GetInfoByObjectID( oid, &objType, &index ) )
|
|
{
|
|
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 );
|
|
}
|
|
}
|
|
}
|
|
} break;
|
|
//case 0x23: // RequestBypassToServer
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: 23 RequestBypassToServer\n" );
|
|
// } 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" );
|
|
// } 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_PACKETNAME, "Client: 65 RequestPledgeInfo\n" );
|
|
// } break;
|
|
//case 0x8B: // RequestGmList
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: 8B RequestGmList\n" );
|
|
// } 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);
|
|
// if( ptype2 == 0x01 )
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: D0:01 RequestManorList\n" );
|
|
// }
|
|
// else if( ptype2 == 0x0d )
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: D0:0D RequestAutoSoulShot\n" );
|
|
// }
|
|
// else if( ptype2 == 0x17 )
|
|
// {
|
|
// // TODO: RequestPledgeWarList
|
|
// log_error( LOG_PACKETNAME, "Client: D0:17 RequestPledgeWarList\n" );
|
|
// }
|
|
// else if( ptype2 == 0x21 )
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: D0:21 RequestKeyMapping\n" );
|
|
// }
|
|
// else if( ptype2 == 0x24 )
|
|
// {
|
|
// log_error( LOG_PACKETNAME, "Client: D0:24 RequestSaveInventoryOrder\n" );
|
|
// }
|
|
// else
|
|
// {
|
|
// log_error( LOG_WARNING, "Client: Unknown opcode2 %04X for IN_GAME packet 0xD0\n",
|
|
// (unsigned int)ptype2 );
|
|
// }
|
|
// }
|
|
// 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 )
|
|
} |