📄 evaqun.cpp
字号:
/*************************************************************************** * Copyright (C) 2005 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 "evaqun.h" #include "evadefines.h"#include "evautil.h"#include <string.h>#ifdef _WIN32#include <winsock.h>#else#include <arpa/inet.h>#endifQunInfo::QunInfo() : qunID(0), externalID(0), type(QQ_QUN_TYPE_PERMANENT), creator(0), authType(QQ_QUN_NEED_AUTH), category(0), versionID(0), name(""), description(""), notice(""), m_UnknownTokenLength(0), m_UnknownToken(0){}QunInfo::QunInfo(const QunInfo &rhs) : qunID(0), externalID(0), type(QQ_QUN_TYPE_PERMANENT), creator(0), authType(QQ_QUN_NEED_AUTH), category(0), versionID(0), name(""), description(""), notice(""), m_UnknownTokenLength(0), m_UnknownToken(0){ *this = rhs;}QunInfo::~QunInfo(){ if(m_UnknownToken) delete [] m_UnknownToken;}QunInfo &QunInfo::operator=(const QunInfo &rhs){ qunID = rhs.getQunID(); externalID = rhs.getExtID(); type = rhs.getType(); creator = rhs.getCreator(); authType = rhs.getAuthType(); unknown1 = rhs.getUnknown1(); category = rhs.getCategory(); versionID = rhs.getVersionID(); name = rhs.getName(); unknown2 = rhs.getUnknown2(); description = rhs.getDescription(); notice = rhs.getNotice(); m_UnknownTokenLength = rhs.getUnknownTokenLength(); if(!m_UnknownTokenLength) return *this; if(m_UnknownToken) delete [] m_UnknownToken; m_UnknownToken = new unsigned char [m_UnknownTokenLength]; memcpy(m_UnknownToken, rhs.getUnknownToken(), m_UnknownTokenLength); return *this;}const bool QunInfo::operator==(const QunInfo &rhs){ return (qunID == rhs.getQunID()) && (externalID == rhs.getExtID()) && (type == rhs.getType()) && (authType == rhs.getAuthType()) && (category == rhs.getCategory()) && (name == rhs.getName()) && (notice == rhs.getNotice()) && (notice == rhs.getNotice()) ;}int QunInfo::readTempQunInfo(unsigned char *buf){ int pos=0; type = buf[pos++]; int tmp4; memcpy(&tmp4, buf+pos, 4); externalID = ntohl(tmp4); pos+=4; memcpy(&tmp4, buf+pos, 4); qunID = ntohl(tmp4); pos+=4; memcpy(&tmp4, buf+pos, 4); creator = ntohl(tmp4); pos+=4; authType = buf[pos++]; unknown1 = buf[pos++]; short tmp2; memcpy(&tmp2, buf+pos, 2); category = ntohs(tmp2); pos+=2; // length of group name int len = buf[pos++]; char *nameChar = (char *)malloc((len + 1)* sizeof(char)); memcpy(nameChar, buf + pos, len); nameChar[len]=0x00; name.assign(nameChar); free(nameChar); pos+=len; return pos;}int QunInfo::readQunInfo(unsigned char *buf){ int pos=0; int tmp4; memcpy(&tmp4, buf+pos, 4); qunID = ntohl(tmp4); pos+=4; memcpy(&tmp4, buf+pos, 4); externalID = ntohl(tmp4); pos+=4; type = buf[pos++]; pos+=4; // here we ignore 4 unknown bytes; memcpy(&tmp4, buf+pos, 4); creator = ntohl(tmp4); pos+=4; authType = buf[pos++]; pos+=6; // here we ignore 6 unknown bytes; short tmp2; category = EvaUtil::read32( buf + pos); pos+=4; memcpy(&tmp2, buf+pos, 2); unknown1 = ntohs(tmp2); pos+=2; pos++; pos+=4; // unknown 4 bytes memcpy(&tmp4, buf+pos, 4); versionID = ntohl(tmp4); pos+=4; //pos+=2; // unknown 2 bytes, 0x00 00 //tmp2 = ntohs(*((unsigned short *)(buf+pos))); // the length of Qun name and Qun notice(max: 0xff ff) //pos+=2; // length of Qun name int len = buf[pos++]; // which means the max length of Qun name is 0xff char *nameChar = (char *)malloc((len + 1)* sizeof(char)); memcpy(nameChar, buf + pos, len); nameChar[len]=0x00; name.assign(nameChar); free(nameChar); pos+=len; pos++; // one byte 0x00, could be the C-stryle string terminator // length of Qun notice len = ntohs(*((unsigned short *)(buf+pos))); // means the max length of Qun notice could be 0xffff pos+=2; char *noticeChar = (char *)malloc((len + 1)* sizeof(char)); memcpy(noticeChar, buf + pos, len); noticeChar[len]=0x00; notice.assign(noticeChar); free(noticeChar); pos+=len; // length of Qun description, max length is 0xff len = buf[pos++]; char *descriptionChar = (char *)malloc((len + 1)* sizeof(char)); memcpy(descriptionChar, buf + pos, len); descriptionChar[len]=0x00; description.assign(descriptionChar); free(descriptionChar); pos+=len; return pos;}int QunInfo::readQunInfoFromSearchReply(unsigned char *buf){ int pos=0; int tmp4; memcpy(&tmp4, buf+pos, 4); qunID = ntohl(tmp4); pos+=4; memcpy(&tmp4, buf+pos, 4); externalID = ntohl(tmp4); pos+=4; type = buf[pos++]; if (QQ_CLIENT_VERSION>=QQ_CLIENT_0D51) pos+=4; memcpy(&tmp4, buf+pos, 4); creator = ntohl(tmp4); pos+=4; short tmp2; memcpy(&tmp2, buf+pos, 2); unknown1 = ntohs(tmp2); pos+=4; // qun category for QQ 2004, should be a int category = EvaUtil::read32( buf+pos); pos+=4; pos+=2; // unkonwn 2 bytes // length of group name int len = buf[pos++]; char *nameChar = (char *)malloc((len + 1)* sizeof(char)); memcpy(nameChar, buf + pos, len); nameChar[len]=0x00; name.assign(nameChar); free(nameChar); pos+=len; memcpy(&tmp2, buf+pos, 2); unknown2 = ntohs(tmp2); pos+=2; authType = buf[pos++]; // length of group description len = buf[pos++]; char *descriptionChar = (char *)malloc((len + 1)* sizeof(char)); memcpy(descriptionChar, buf + pos, len); descriptionChar[len]=0x00; description.assign(descriptionChar); free(descriptionChar); pos+=len; // new stuff in 2006 m_UnknownTokenLength = EvaUtil::read16(buf + pos); pos+=2; m_UnknownToken = new unsigned char[m_UnknownTokenLength]; memcpy(m_UnknownToken, buf + pos, m_UnknownTokenLength); pos+=m_UnknownTokenLength; return pos;}/**********************************************************************************************************************/QunPacket::QunPacket(const char qunCmd) : OutPacket(QQ_CMD_QUN_CMD, true){ qunCommand = qunCmd;}QunPacket::QunPacket(const char qunCmd, const unsigned int id) : OutPacket(QQ_CMD_QUN_CMD, true){ qunCommand = qunCmd; qunID = id;}QunPacket::QunPacket(const QunPacket &rhs) : OutPacket(rhs){ *this = rhs;}QunPacket::~QunPacket(){}QunPacket &QunPacket::operator=(const QunPacket &rhs){ *((OutPacket *)this) = (OutPacket)rhs; qunCommand = rhs.getQunCommand(); qunID = rhs.getQunID(); return *this;}/***************************************************************************************************************/QunReplyPacket::QunReplyPacket(unsigned char *buf, int len) : InPacket(buf, len){}QunReplyPacket::QunReplyPacket(const QunReplyPacket &rhs) : InPacket(rhs){ *this = rhs;}QunReplyPacket::~QunReplyPacket(){} QunReplyPacket &QunReplyPacket::operator=(const QunReplyPacket &rhs){ *((InPacket *)this) = (InPacket)rhs; qunCommand = rhs.getQunCommand(); replyCode = rhs.getReplyCode(); qunID = rhs.getQunID(); externalID = rhs.getExtID(); type = rhs.getType(); parentQunID = rhs.getParentQunID(); errorMessage = rhs.getErrorMessage(); searchType = rhs.getSearchType(); info = rhs.getQunInfo(); qunInfoList = rhs.getQunInfoList(); qunQQNumberList = rhs.getQQNumberList(); memberList = rhs.getMemberList(); memberInfoList = rhs.getMemberInfoList(); joinReply = rhs.getJoinReply(); targetQQ = rhs.getTargetQQ(); opCode = rhs.getOpCode(); versionID = rhs.getQunVersionID(); realName = rhs.getRealName(); gender = rhs.getGender(); phone = rhs.getPhone(); email = rhs.getEmail(); memo = rhs.getMemo(); return *this;}void QunReplyPacket::parseBody(){ printf("QunReplyPacket::parseBody\n"); for(int i=0; i<bodyLength; i++){ if(!(i%8)) printf("\n%d: ",i); char t = decryptedBuf[i]; printf("%2x ", (uint8_t)t); } printf("\n"); int pos = 0; qunCommand = decryptedBuf[pos++]; replyCode = decryptedBuf[pos++]; switch(qunCommand){ case QQ_QUN_CMD_SEND_IM: case QQ_QUN_CMD_SEND_IM_EX: pos += parseSendIMReply(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_SEND_TEMP_QUN_IM: pos += parseSendTempQunIMReply(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_CREATE_QUN: pos += parseCreateReply(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_CREATE_TEMP_QUN: pos += parseCreateTempQun(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_ACTIVATE_QUN: pos += parseActivateReply(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_MODIFY_MEMBER: pos += parseModifyMemberReply(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_GET_QUN_INFO: pos += parseGetInfoReply(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_EXIT_QUN: pos += parseExitReply(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_GET_MEMBER_INFO: pos += parseGetMemberInfoReply(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_GET_ONLINE_MEMBER: pos += parseGetOnlineMemberReply(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_JOIN_QUN: pos += parseJoinReply(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_JOIN_QUN_AUTH: pos += parseJoinAuthReply(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_MODIFY_QUN_INFO: pos += parseModifyInfoReply(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_SEARCH_QUN: pos += parseSearchReply(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_GET_TEMP_QUN_INFO: pos += parseGetTempQunInfoReply(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_EXIT_TEMP_QUN: pos += parseExitTempQunReply(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_GET_TEMP_QUN_MEMBERS: pos += parseGetTempQunMembers(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_MODIFY_CARD: pos += parseModifyQunCard(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_REQUEST_ALL_REALNAMES: pos += parseRequestAllRealNames(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_REQUEST_CARD: pos += parseRequestQunCard(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_ADMIN: pos += parseQunAdminOperation(decryptedBuf + pos, bodyLength - pos); break; case QQ_QUN_CMD_TRANSFER: pos += parseQunTransfer(decryptedBuf + pos, bodyLength - pos); break; default: printf("unknown Qun command:0x%2x\n", (char)qunCommand); } if(replyCode != QQ_QUN_CMD_REPLY_OK) { /* operation failed */ char * errorChar = (char *)malloc((bodyLength-pos+1) * sizeof(char)); errorChar[bodyLength-pos] = 0x00; memcpy(errorChar, decryptedBuf + pos, bodyLength - pos); printf("Qun Reply error(%d):%s\n", qunCommand, errorChar); errorMessage.assign(errorChar); free(errorChar); pos = bodyLength; }}const bool QunReplyPacket::isReplyOK() const{ return replyCode == QQ_QUN_CMD_REPLY_OK;}// useful variable: qunIDint QunReplyPacket::parseSendIMReply(unsigned char *buf, int){ int pos = 0; if(replyCode == QQ_QUN_CMD_REPLY_OK){ int tmp4; memcpy(&tmp4, buf + pos, 4); qunID = ntohl(tmp4); pos+=4; } return pos;}// useful variables: type, parentQunID and qunIDint QunReplyPacket::parseSendTempQunIMReply(unsigned char *buf, int){ int pos = 0; if(replyCode == QQ_QUN_CMD_REPLY_OK) { type = buf[pos++]; int tmp4; memcpy(&tmp4, buf + pos, 4); parentQunID = ntohl(tmp4); pos+=4; memcpy(&tmp4, buf + pos, 4); qunID = ntohl(tmp4); pos+=4; } return pos;}// useful variables: qunID and externalIDint QunReplyPacket::parseCreateReply(unsigned char *buf, int){ int pos = 0; if(replyCode == QQ_QUN_CMD_REPLY_OK){ int tmp4; memcpy(&tmp4, buf + pos, 4); qunID = ntohl(tmp4); pos+=4; memcpy(&tmp4, buf + pos, 4); externalID = ntohl(tmp4); pos+=4; } return pos;}// useful variables: qunID, parentQunID and typeint QunReplyPacket::parseCreateTempQun(unsigned char *buf, int){ int pos = 0; if(replyCode == QQ_QUN_CMD_REPLY_OK) { type = buf[pos++]; int tmp4; memcpy(&tmp4, buf + pos, 4); parentQunID = ntohl(tmp4); pos+=4; memcpy(&tmp4, buf + pos, 4); qunID = ntohl(tmp4); pos+=4; } return pos;}// useful variable: qunIDint QunReplyPacket::parseActivateReply(unsigned char *buf, int){ int pos = 0; if(replyCode == QQ_QUN_CMD_REPLY_OK){ int tmp4; memcpy(&tmp4, buf + pos, 4); qunID = ntohl(tmp4); pos+=4; } return pos;}// useful variable: qunIDint QunReplyPacket::parseModifyMemberReply(unsigned char *buf, int ){ int pos = 0; if(replyCode == QQ_QUN_CMD_REPLY_OK){ int tmp4; memcpy(&tmp4, buf + pos, 4); qunID = ntohl(tmp4); pos+=4; } return pos;}/* for this part, the useful variables are: qunID, externalID and info, memberList (actually these two contain all information)*/int QunReplyPacket::parseGetInfoReply(unsigned char *buf, int len){// printf("Qun info reply --- \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; if(replyCode == QQ_QUN_CMD_REPLY_OK) { int pos = info.readQunInfo(buf); qunID = info.getQunID(); externalID = info.getExtID(); int tmp4; while(pos < len ) { QunMember member; memcpy(&tmp4, buf+pos, 4); member.qqNum = ntohl(tmp4); pos+=4; member.groupIndex = buf[pos++]; member.admin = buf[pos++]; memberList[member.qqNum] = member; printf("\t\tqq:%d, group index:%d, admin:%2x\n", member.qqNum, member.groupIndex, member.admin); } } return pos;}// useful variable: qunIDint QunReplyPacket::parseExitReply(unsigned char *buf, int ){ int pos = 0; if(replyCode == QQ_QUN_CMD_REPLY_OK){ int tmp4; memcpy(&tmp4, buf + pos, 4); qunID = ntohl(tmp4); pos+=4; } return pos;}// useful variables: qunID and memberInfoList;int QunReplyPacket::parseGetMemberInfoReply(unsigned char *buf, int len){ int pos=0; if(replyCode == QQ_QUN_CMD_REPLY_OK) { int tmp4; memcpy(&tmp4, buf+pos, 4); qunID = ntohl(tmp4); pos+=4; // member information now int tmpLen=0; while(pos < len) { FriendItem *info = new FriendItem(buf + pos, &tmpLen); memberInfoList.push_back(*info); delete info; pos+=tmpLen; } } return pos;}// useful variables: qunID and qunQQNumberListint QunReplyPacket::parseGetOnlineMemberReply(unsigned char *buf, int len){ int pos=0; if(replyCode == QQ_QUN_CMD_REPLY_OK) { int tmp4; memcpy(&tmp4, buf + pos, 4); qunID = ntohl(tmp4); pos+=4; pos++; // ignore one unknow byte, always be 0x3c; while(pos < len ) { memcpy(&tmp4, buf+pos, 4); qunQQNumberList.push_back(ntohl(tmp4)); pos+=4; } } return pos;}// useful variables: qunID and joinReplyint QunReplyPacket::parseJoinReply(unsigned char *buf, int ){ int pos = 0; if(replyCode == QQ_QUN_CMD_REPLY_OK){ int tmp4; memcpy(&tmp4, buf + pos, 4); qunID = ntohl(tmp4); pos+=4; joinReply = buf[pos++]; } return pos;}// useful varible: qunID ** note that this is only a reply from server for your request and dose not mean anything
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -