📄 evaimreceive.cpp
字号:
/*************************************************************************** * Copyright (C) 2004- 2006 by yunfan * * yunfan_zg@163.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/#include "evaimreceive.h"#include "evadefines.h"#include "evautil.h"#include <string.h>#ifdef _WIN32#include <winsock.h>#else#include <arpa/inet.h>#endifReceiveIMPacket::ReceiveIMPacket(unsigned char *buf, const int len) : InPacket(buf, len), bodyOffset(0){} ReceiveIMPacket::ReceiveIMPacket(const ReceiveIMPacket &rhs) : InPacket(rhs){ memcpy(replyKey, rhs.getReplyKey(), REPLY_KEY_LENGTH); sender = rhs.getSender(); receiver = rhs.getReceiver(); sequence = rhs.getSequence(); senderIP = rhs.getSenderIP(); senderPort = rhs.getSenderPort(); type = rhs.getIMType(); bodyOffset = rhs.getLength() - rhs.getBodyLength();}std::string ReceiveIMPacket::convertToShow(const std::string &src, const unsigned char type){ std::string converted = ""; unsigned int start = 0; char *uuid = NULL; // uuid format: {12345678-1234-1234-1234-123456789ABC} if(type == QQ_IM_IMAGE_REPLY){ uuid = new char[39]; // 38 + 1 memcpy(uuid, src.c_str(), 38); uuid[38] = 0x00; // just make it as a string start+=38; start+=2; // 2 unknown bytes: 0x13 0x4c (always) } for(uint i=start; i<src.length(); i++){ if(src[i]==0x14){ converted+=EvaUtil::smileyToText(src[++i]); converted+=' '; }else if(src[i]==0x15){ int t=0; char *tmp = new char[src.length()+1]; strcpy(tmp, src.c_str()); converted+=EvaUtil::customSmileyToText(tmp + i, &t, uuid); i+=(t-1); // get rid of 0x15 delete tmp; } else converted+=src[i]; } if(uuid) delete []uuid; return converted;}ReceiveIMPacket &ReceiveIMPacket::operator=(const ReceiveIMPacket &rhs){ *((InPacket *)this) = (InPacket)rhs; memcpy(replyKey, rhs.getReplyKey(), REPLY_KEY_LENGTH); sender = rhs.getSender(); receiver = rhs.getReceiver(); sequence = rhs.getSequence(); senderIP = rhs.getSenderIP(); senderPort = rhs.getSenderPort(); type = rhs.getIMType(); bodyOffset = rhs.getLength() - rhs.getBodyLength(); return *this;}void ReceiveIMPacket::parseBody(){ if(bodyLength < 16){ printf("message too short, just chuck it\n"); bodyOffset = -1; // means error occurred return; } memcpy(replyKey, decryptedBuf, REPLY_KEY_LENGTH); printf("you got it!!!!!!!!!!!!!111\n"); bodyOffset = readHeader(decryptedBuf);}int ReceiveIMPacket::readHeader(const unsigned char *buf){ int pos=0; sender = READ32(buf); pos+=4; receiver = READ32(buf+pos); pos+=4; intSequence = READ32(buf+pos); pos+=4; senderIP = READ32(buf+pos); pos+=4; senderPort = READ16(buf+pos); pos+=2; type = READ16(buf+pos); pos+=2; return pos;}/* =========================================================== */NormalIMBase::NormalIMBase(const unsigned char *buf, const int len){ bodyBuf = (unsigned char *)malloc(len * sizeof(unsigned char)); bodyLength = len; memcpy(bodyBuf, buf, len);}NormalIMBase::NormalIMBase(const NormalIMBase &rhs){ *this = rhs;}NormalIMBase::~NormalIMBase(){ free(bodyBuf);}void NormalIMBase::setNormalIMBase(const NormalIMBase *base){ *this = *base; }void NormalIMBase::parseData(){ int len = readHeader(bodyBuf); parseContents(bodyBuf + len, bodyLength - len);}NormalIMBase &NormalIMBase::operator=(const NormalIMBase &rhs){ bodyLength = rhs.getBodyLength(); bodyBuf = (unsigned char *)malloc(bodyLength * sizeof(unsigned char)); memcpy(bodyBuf, rhs.getBodyData(), bodyLength); senderVersion = rhs.getSenderVersion(); sender = rhs.getSender(); receiver = rhs.getReceiver(); memcpy(fileSessionKey, rhs.getBuddyFileSessionKey(), 16); type = rhs.getNormalIMType(); sequence = rhs.getSequence(); sendTime = rhs.getSendTime(); unknown1 = rhs.getUnknown1(); senderFace = rhs.getSenderFace(); return *this;}void NormalIMBase::parseContents(const unsigned char *, const int ){ //fprintf(stderr, "In NormalIMBase: buf[0]=0x%2x, len=%d\n",buf[0], len); }int NormalIMBase::readHeader(const unsigned char *buf){ int pos=0; senderVersion = READ16(buf+pos); pos+=2; sender = READ32(buf+pos); pos+=4; receiver = READ32(buf+pos); pos+=4; memcpy(fileSessionKey, buf+pos, 16); pos+=16; type = READ16(buf+pos); pos+=2; sequence = READ16(buf+pos); pos+=2; sendTime = READ32(buf+pos); pos+=4; senderFace = READ16(buf+pos); pos+=2; return pos;}/* =========================================================== */ReceivedNormalIM::ReceivedNormalIM(const unsigned char *buf, const int len) : NormalIMBase(buf, len){}ReceivedNormalIM::ReceivedNormalIM(const ReceivedNormalIM &rhs) : NormalIMBase(rhs){ memcpy(unknown2, rhs.getUnknown2(), 3); numFragments = rhs.getNumFragments(); seqFragments = rhs.getSeqOfFragments(); messageID = rhs.getMessageID(); replyType = rhs.getReplyType(); message = rhs.getMessage(); mHasFontAttribute = rhs.hasFontAttribute(); encoding = rhs.getEncoding(); red = rhs.getRed(); green = rhs.getGreen(); blue = rhs.getBlue(); fontSize = rhs.getFontSize(); fontName = rhs.getFontName(); bold = rhs.isBold(); italic = rhs.isItalic(); underline = rhs.isUnderline();}const bool ReceivedNormalIM::isNormalReply() const{ return replyType == QQ_IM_NORMAL_REPLY;}ReceivedNormalIM &ReceivedNormalIM::operator=(const ReceivedNormalIM &rhs){ *((NormalIMBase *)this) = (NormalIMBase)rhs; memcpy(unknown2, rhs.getUnknown2(), 3); numFragments = rhs.getNumFragments(); seqFragments = rhs.getSeqOfFragments(); messageID = rhs.getMessageID(); replyType = rhs.getReplyType(); message = rhs.getMessage(); mHasFontAttribute = rhs.hasFontAttribute(); encoding = rhs.getEncoding(); red = rhs.getRed(); green = rhs.getGreen(); blue = rhs.getBlue(); fontSize = rhs.getFontSize(); fontName = rhs.getFontName(); bold = rhs.isBold(); italic = rhs.isItalic(); underline = rhs.isUnderline(); return *this;}void ReceivedNormalIM::parseContents(const unsigned char *buf, const int len){ int pos=0; memcpy(unknown2, buf, 3); pos+=3; mHasFontAttribute = (buf[pos++] != 0); pos+=8; /// unknown 8 bytes, all 0x00s numFragments = buf[pos++]; seqFragments = buf[pos++]; memcpy(&messageID, buf+pos, 2); pos+=2; replyType = buf[pos++]; int i=0; while( (buf[pos++]) != 0x00){ i++; }#ifdef WIN32 char* str; str=(char*)_alloca(i+2);#else char str[i+2];#endif memcpy(str, buf+(pos-i-1), i+1); str[i+1]= 0x00; message = ReceiveIMPacket::convertToShow(str, replyType); if(mHasFontAttribute) { if(pos<len) {#ifdef WIN32 char* fa; fa=(char*)_alloca(len-pos);#else char fa[len-pos];#endif memcpy(fa, buf+pos, len-pos); fontSize = fa[0] & 0x1F; bold = ((fa[0] & 0x20) != 0); italic = ((fa[0] & 0x40) != 0); underline = ((fa[0] & 0x80) != 0); red = fa[1] & 0xFF; green = fa[2] & 0xFF; blue = fa[3] & 0xFF; short tmp2; memcpy(&tmp2, fa+5, 2); encoding = ntohs(tmp2);#ifdef WIN32 char* fn; fn=(char*)_alloca(len-pos-7);#else char fn[len-pos-7];#endif memcpy(fn, fa+7, len-pos-7-1); fn[len-pos-7-1]=0x00; //fn[len-pos-7]=0x00; fontName.assign(fn); } else mHasFontAttribute = false; }}/* =========================================================== */ReceivedSystemIM::ReceivedSystemIM(const unsigned char *buf, const int len){ parseData(buf, len);}ReceivedSystemIM::ReceivedSystemIM( const ReceivedSystemIM &rhs){ *this = rhs;}ReceivedSystemIM &ReceivedSystemIM::operator=(const ReceivedSystemIM &rhs){ systemIMType = rhs.getSystemIMType(); message = rhs.getMessage(); return *this;}void ReceivedSystemIM::parseData(const unsigned char *buf, const int /*len*/){ int pos = 0; systemIMType = buf[pos++]; char msgLen = buf[pos++];#ifdef WIN32 char* msg; msg=(char*)_alloca(msgLen+1);#else char msg[msgLen+1];#endif memcpy(msg, buf+pos, msgLen); msg[0xff & msgLen]=0x00; message.assign(msg);}/* =========================================================== */ReceiveIMReplyPacket::ReceiveIMReplyPacket(const char *key) : OutPacket(QQ_CMD_RECV_IM, false){ memcpy(replyKey, key, 16);}ReceiveIMReplyPacket::ReceiveIMReplyPacket(const ReceiveIMReplyPacket &rhs) : OutPacket(rhs){ memcpy(replyKey, rhs.getReplyKey(), REPLY_KEY_LENGTH);}ReceiveIMReplyPacket &ReceiveIMReplyPacket::operator=(const ReceiveIMReplyPacket &rhs){ *((OutPacket *)this) = (OutPacket)rhs; memcpy(replyKey, rhs.getReplyKey(), REPLY_KEY_LENGTH); return *this;}int ReceiveIMReplyPacket::putBody(unsigned char *buf) { memcpy(buf, replyKey, REPLY_KEY_LENGTH); return REPLY_KEY_LENGTH;}/* =========================================================== */ReceivedQunIM::ReceivedQunIM(const unsigned short src, const unsigned char * buf, const int len ) : source(src){ parseData(buf, len);}ReceivedQunIM::ReceivedQunIM( const ReceivedQunIM & rhs ){ (*this) = rhs;}ReceivedQunIM & ReceivedQunIM::operator =( const ReceivedQunIM & rhs ){ source = rhs.getSource(); // this is to mention, permenent, temporary qun externalID = rhs.getExtID(); qunID = rhs.getQunID(); type = rhs.getType(); sender = rhs.getSenderQQ(); unknown1 = rhs.getUnknown1(); numFragments = rhs.getNumFragments(); seqFragments = rhs.getSeqOfFragments(); messageID = rhs.getMessageID(); sequence = rhs.getSequence(); sentTime = rhs.getSentTime(); versionID = rhs.getVersionID(); message = rhs.getMessage(); mHasFontAttribute = rhs.hasFontAttribute(); encoding = rhs.getEncoding(); red = rhs.getRed(); green = rhs.getGreen(); blue = rhs.getBlue(); fontSize = rhs.getFontSize(); fontName = rhs.getFontName(); bold = rhs.isBold(); italic = rhs.isItalic(); underline = rhs.isUnderline(); return *this;}void ReceivedQunIM::parseData( const unsigned char * buf, const int len ){ printf("ReceivedQunIM::parseData\n"); for(int i=0; i<len; i++){ if(!(i%8)) printf("\n%d: ",i); char t = buf[i]; printf("%2x ", (uint8_t)t); } printf("\n"); int pos=0; externalID = ntohl(*(int*)buf); // the external Qun ID pos+=4; type = buf[pos++]; // type of the Qun if(source == QQ_RECV_IM_TEMP_QUN_IM){ // internal ID of temporary Qun qunID = ntohl( *(int*)(buf+pos) ); pos+=4; } sender = ntohl(*(int*)(buf+pos) ); // the sender pos+=4; memcpy(&unknown1, buf+pos, 2); pos+=2; sequence = ntohs(*(short*)(buf+pos) ); // message sequence number pos+=2; sentTime = ntohl(*(int*)(buf+pos) ); // the sending time pos+=4; versionID = ntohl(*(int*)(buf+pos) ); // version ID is to tell if something like memebers, or rules of this Qun were changed pos+=4; pos+=2; // ignore 2 bytes; Luma QQ says it's the length for the following data. // 10 unknown bytes if(source != QQ_RECV_IM_UNKNOWN_QUN_IM) { pos+=2; numFragments = buf[pos++]; seqFragments = buf[pos++]; memcpy(&messageID, buf+pos, 2); pos+=6; } int i=0; // not scan \0 but to extract the length from the packet if (numFragments != (seqFragments + 1)) { i = len - pos - 1; pos = len; } else { i = buf[len-1]; i = len - i - pos; pos = pos + i + 1; }#ifdef WIN32 char* str; str=(char*)_alloca(i+2);#else char str[i+2];#endif memcpy(str, buf+(pos-i-1), i+1); str[i+1]= 0x00; message = ReceiveIMPacket::convertToShow(str, QQ_IM_NORMAL_REPLY); mHasFontAttribute = (len > pos); if(mHasFontAttribute) {#ifdef WIN32
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -