if (IncomingPacket) // Server -> client { // Server -> Client = 4 bytes header (2 bytes size - 2 bytes opcode) if (LastPacketFragmented) { ByteBuffer tmp; if (RecvSecondPktFirst) { // Sometimes it gets reversed sniffed, so fix it. tmp.append(*data); tmp.append(PreviousPkt); RecvSecondPktFirst = false; } else // Also, sometimes pkt is split in 2 parts (hdr, data). { tmp.append(PreviousPkt); tmp.append(*data); } PreviousPkt.clear(); data->clear(); data->append(tmp); len = data->size(); LastPacketFragmented = false; } WorldServerPktHdr* hdr = (WorldServerPktHdr*)data->contents(); wowdata->HeaderSize = 4; wowdata->EncryptedDataSize = hdr->size; wowdata->DataSize = len - wowdata->HeaderSize; wowdata->WorldOpcode = hdr->opcode; switch (len) { case 4: // sizeof(WorldServerPktHdr); LastPacketFragmented = true; wowdata->DataSize = 4; wowdata->WorldOpcode = LastRecvOpcode = hdr->opcode; PreviousPkt.append(*data); if (!RecvAuthChallenge) // Full packet = 8 bytes. { // SMSG_AUTH_CHALLENGE is not encrypted. if ((hdr->size == 0xBABE) && (hdr->opcode == 0xDEAD)) RecvSecondPktFirst; // Second part first received. RecvAuthChallenge = true; wowdata->DataSize = 8; wowdata->WorldOpcode = LastRecvOpcode = SMSG_AUTH_CHALLENGE; } else if (!RecvAuthResponse) // Full packet = 10 bytes. { RecvAuthResponse = true; wowdata->DataSize = 8; wowdata->WorldOpcode = LastRecvOpcode = SMSG_AUTH_RESPONSE; } else if (!RecvCharEnum) // Full = 168 for now (1 char on st0rmgaming). { RecvCharEnum = true; wowdata->DataSize = 4; wowdata->WorldOpcode = LastRecvOpcode = SMSG_CHAR_ENUM; } return; case 6: // SMSG_AUTH_RESPONSE = 4 + 6 (if splitted) if (!RecvAuthResponse || (LastRecvOpcode == SMSG_AUTH_RESPONSE)) { RecvAuthResponse = true; wowdata->WorldOpcode = SMSG_AUTH_RESPONSE; RecvSecondPktFirst = true; break; } break; case 8: // Full packet (SMSG_AUTH_CHALLENGE) if (!RecvAuthChallenge || (LastRecvOpcode == SMSG_AUTH_CHALLENGE)) { // SMSG_AUTH_CHALLENGE = not encrypted. RecvAuthChallenge = true; // So no use bruteforcing it. wowdata->WorldOpcode = SMSG_AUTH_CHALLENGE; return; // Just skip it. } break; case 10: // Full packet (SMSG_AUTH_RESPONSE) if (!RecvAuthResponse || (LastRecvOpcode == SMSG_AUTH_RESPONSE)) { // Full packet = 10 bytes RecvAuthResponse = true; wowdata->WorldOpcode = SMSG_AUTH_RESPONSE; break; } break; // char part on st0rmgaming... case 164: if (!RecvCharEnum || (LastRecvOpcode == SMSG_CHAR_ENUM)) { RecvCharEnum = true; wowdata->WorldOpcode = SMSG_CHAR_ENUM; RecvSecondPktFirst = true; break; } break; case 168: if (!RecvCharEnum || (LastRecvOpcode == SMSG_CHAR_ENUM)) { // Full packet = 168 for now (1 char on st0rmgaming). RecvCharEnum = true; wowdata->WorldOpcode = SMSG_CHAR_ENUM; break; } break; } unsigned short op = GetRealServerOpcode(data, wowdata->DecryptedDataSize, LastRecvOpcode); wowdata->WorldOpcode = LastRecvOpcode = (op ? op : wowdata->WorldOpcode); } else // Client -> server { WorldClientPktHdr* hdr = (WorldClientPktHdr*)data->contents(); wowdata->HeaderSize = 6; // sizeof(WorldClientPktHdr); wowdata->DataSize = len - wowdata->HeaderSize; wowdata->EncryptedDataSize = hdr->size; wowdata->WorldOpcode = hdr->opcode; LastSendOpcode = 0; if (!SendAuthSession) // CMSG_AUTH_SESSION { // Its not encrypted the packet. SendAuthSession = true; // So if we send it wowdata->WorldOpcode = LastSendOpcode = CMSG_AUTH_SESSION; return; // dont try to decrypt it (return). } if (!SendCharEnum) { SendCharEnum = true; // CMSG_CHAR_ENUM wowdata->WorldOpcode = LastSendOpcode = CMSG_CHAR_ENUM; } unsigned int op = GetRealClientOpcode(data, wowdata->DecryptedDataSize, LastSendOpcode); wowdata->WorldOpcode = LastSendOpcode = (op ? op : wowdata->WorldOpcode); }