Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

evaqun.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005 by yunfan                                          *
00003  *   yunfan_zg@163.com                                                     *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020  
00021 #include "evaqun.h" 
00022 #include "evadefines.h"
00023 #include "evautil.h"
00024 #include <string.h>
00025 #ifdef _WIN32
00026 #include <winsock.h>
00027 #else
00028 #include <arpa/inet.h>
00029 #endif
00030 
00031 QunInfo::QunInfo()
00032         : qunID(0), externalID(0), type(QQ_QUN_TYPE_PERMANENT),
00033         creator(0), authType(QQ_QUN_NEED_AUTH), category(0),
00034         versionID(0), name(""), description(""), notice("")
00035 {
00036 }
00037 
00038 QunInfo &QunInfo::operator=(const QunInfo &rhs)
00039 {
00040         qunID = rhs.getQunID();
00041         externalID = rhs.getExtID();
00042         type = rhs.getType();
00043         creator = rhs.getCreator();
00044         authType = rhs.getAuthType();
00045         unknown1 = rhs.getUnknown1();
00046         category = rhs.getCategory();
00047         versionID = rhs.getVersionID();
00048         name = rhs.getName();
00049         unknown2 = rhs.getUnknown2();
00050         description = rhs.getDescription();
00051         notice = rhs.getNotice();
00052         return *this;
00053 }
00054 
00055 const bool QunInfo::operator==(const QunInfo &rhs)
00056 {
00057         return (qunID == rhs.getQunID())       && (externalID == rhs.getExtID()) &&
00058                 (type == rhs.getType())         && (authType == rhs.getAuthType()) &&
00059                 (category == rhs.getCategory()) && (name == rhs.getName()) &&
00060                 (notice == rhs.getNotice())     && (notice == rhs.getNotice()) ;
00061 }
00062 
00063 int QunInfo::readTempQunInfo(unsigned char *buf)
00064 {
00065         int pos=0;
00066         type = buf[pos++];
00067         
00068         int tmp4;
00069         memcpy(&tmp4, buf+pos, 4);
00070         externalID = ntohl(tmp4);
00071         pos+=4;
00072         
00073         memcpy(&tmp4, buf+pos, 4);
00074         qunID = ntohl(tmp4);
00075         pos+=4;
00076         
00077         memcpy(&tmp4, buf+pos, 4);
00078         creator = ntohl(tmp4);
00079         pos+=4;
00080 
00081         authType = buf[pos++];
00082         unknown1 = buf[pos++];
00083         
00084         short tmp2;
00085         memcpy(&tmp2, buf+pos, 2);
00086         category = ntohs(tmp2);
00087         pos+=2;
00088         
00089         // length of group name
00090         int len = buf[pos++];
00091         char *nameChar = (char *)malloc((len + 1)* sizeof(char));
00092         memcpy(nameChar, buf + pos, len);
00093         nameChar[len]=0x00;
00094         name.assign(nameChar);
00095         free(nameChar);
00096         pos+=len;
00097         
00098         return pos;
00099 }
00100 
00101 int QunInfo::readQunInfo(unsigned char *buf)
00102 {
00103         int pos=0;
00104         
00105         int tmp4;
00106         memcpy(&tmp4, buf+pos, 4);
00107         qunID = ntohl(tmp4);
00108         pos+=4;
00109 
00110         memcpy(&tmp4, buf+pos, 4);
00111         externalID = ntohl(tmp4);
00112         pos+=4;
00113         
00114         type = buf[pos++];
00115         
00116         pos+=4; // here we ignore 4 unknown bytes;
00117         
00118         memcpy(&tmp4, buf+pos, 4);
00119         creator = ntohl(tmp4);
00120         pos+=4;
00121 
00122         authType = buf[pos++];
00123         
00124         pos+=6; // here we ignore 6 unknown bytes;
00125         
00126         short tmp2;
00127         category = EvaUtil::read32( buf + pos); pos+=4;
00128         
00129         memcpy(&tmp2, buf+pos, 2);
00130         unknown1 = ntohs(tmp2);
00131         pos+=2;
00132 
00133         pos++;
00134 
00135         memcpy(&tmp4, buf+pos, 4);
00136         versionID = ntohl(tmp4);
00137         pos+=4;
00138         
00139         // length of group name
00140         int len = buf[pos++];
00141         char *nameChar = (char *)malloc((len + 1)* sizeof(char));
00142         memcpy(nameChar, buf + pos, len);
00143         nameChar[len]=0x00;
00144         name.assign(nameChar);
00145         free(nameChar);
00146         pos+=len;
00147         
00148         memcpy(&tmp2, buf+pos, 2);
00149         unknown2 = ntohs(tmp2);
00150         pos+=2;
00151 
00152         // length of group notice
00153         len = buf[pos++];
00154         char *noticeChar = (char *)malloc((len + 1)* sizeof(char));
00155         memcpy(noticeChar, buf + pos, len);
00156         noticeChar[len]=0x00;
00157         notice.assign(noticeChar);
00158         free(noticeChar);
00159         pos+=len;
00160 
00161         // length of group description
00162         len = buf[pos++];
00163         char *descriptionChar = (char *)malloc((len + 1)* sizeof(char));
00164         memcpy(descriptionChar, buf + pos, len);
00165         descriptionChar[len]=0x00;
00166         description.assign(descriptionChar);
00167         free(descriptionChar);
00168         pos+=len;
00169         
00170         return pos;
00171 }
00172 
00173 int QunInfo::readQunInfoFromSearchReply(unsigned char *buf)
00174 {
00175         int pos=0;
00176         
00177         int tmp4;
00178         memcpy(&tmp4, buf+pos, 4);
00179         qunID = ntohl(tmp4);
00180         pos+=4;
00181 
00182         memcpy(&tmp4, buf+pos, 4);
00183         externalID = ntohl(tmp4);
00184         pos+=4;
00185         
00186         type = buf[pos++];
00187         
00188         if (QQ_CLIENT_VERSION>=QQ_CLIENT_0D51)
00189                 pos+=4;
00190 
00191         memcpy(&tmp4, buf+pos, 4);
00192         creator = ntohl(tmp4);
00193         pos+=4;
00194 
00195         short tmp2;
00196         memcpy(&tmp2, buf+pos, 2);
00197         unknown1 = ntohs(tmp2);
00198         pos+=4; // qun category for QQ 2004, should be a int
00199         
00200         category = EvaUtil::read32( buf+pos); pos+=4;
00201 
00202         pos+=2; // unkonwn 2 bytes
00203         
00204         // length of group name
00205         int len = buf[pos++];
00206         char *nameChar = (char *)malloc((len + 1)* sizeof(char));
00207         memcpy(nameChar, buf + pos, len);
00208         nameChar[len]=0x00;
00209         name.assign(nameChar);
00210         free(nameChar);
00211         pos+=len;
00212         
00213         memcpy(&tmp2, buf+pos, 2);
00214         unknown2 = ntohs(tmp2);
00215         pos+=2;
00216 
00217         authType = buf[pos++];
00218 
00219         // length of group description
00220         len = buf[pos++];
00221         char *descriptionChar = (char *)malloc((len + 1)* sizeof(char));
00222         memcpy(descriptionChar, buf + pos, len);
00223         descriptionChar[len]=0x00;
00224         description.assign(descriptionChar);
00225         free(descriptionChar);
00226         pos+=len;
00227         
00228         return pos;
00229 }
00230 
00231 /**********************************************************************************************************************/
00232 
00233 QunPacket::QunPacket(const char qunCmd)
00234         : OutPacket(QQ_CMD_QUN_CMD, true)
00235 {
00236         qunCommand = qunCmd;
00237 }
00238 
00239 QunPacket::QunPacket(const char qunCmd, const int id)
00240         : OutPacket(QQ_CMD_QUN_CMD, true)
00241 {
00242         qunCommand = qunCmd;
00243         qunID = id;
00244 }
00245 
00246 QunPacket::QunPacket(const QunPacket &rhs)
00247         : OutPacket(rhs)
00248 {
00249         *this = rhs;
00250 }
00251 
00252 QunPacket::~QunPacket()
00253 {
00254 }
00255 
00256 QunPacket &QunPacket::operator=(const QunPacket &rhs)
00257 {
00258         *((OutPacket *)this) = (OutPacket)rhs;
00259         qunCommand = rhs.getQunCommand();
00260         qunID = rhs.getQunID();
00261         return *this;
00262 }
00263 
00264 
00265 
00266 
00267 /***************************************************************************************************************/
00268 
00269 QunReplyPacket::QunReplyPacket(unsigned char *buf, int len)
00270         : InPacket(buf, len)
00271 {
00272 }
00273 
00274 QunReplyPacket::QunReplyPacket(const QunReplyPacket &rhs)
00275         : InPacket(rhs)
00276 {
00277         *this = rhs;
00278 }
00279 
00280 QunReplyPacket::~QunReplyPacket()
00281 {
00282 }
00283         
00284 QunReplyPacket &QunReplyPacket::operator=(const QunReplyPacket &rhs)
00285 {
00286         *((InPacket *)this) = (InPacket)rhs;
00287         qunCommand = rhs.getQunCommand();
00288         replyCode = rhs.getReplyCode();
00289         qunID = rhs.getQunID();
00290         externalID = rhs.getExtID();
00291         type = rhs.getType();
00292         parentQunID = rhs.getParentQunID();
00293         errorMessage = rhs.getErrorMessage();
00294         
00295         searchType = rhs.getSearchType();
00296         info = rhs.getQunInfo();
00297         qunInfoList = rhs.getQunInfoList();
00298         qunQQNumberList = rhs.getQQNumberList();
00299         memberList = rhs.getMemberList();
00300         memberInfoList = rhs.getMemberInfoList();
00301         joinReply = rhs.getJoinReply();
00302         targetQQ = rhs.getTargetQQ();
00303         opCode = rhs.getOpCode();
00304         versionID = rhs.getQunVersionID();
00305         realName = rhs.getRealName();
00306         gender = rhs.getGender();
00307         phone = rhs.getPhone();
00308         email = rhs.getEmail();
00309         memo = rhs.getMemo();
00310         return *this;
00311 }
00312 
00313 void QunReplyPacket::parseBody()
00314 {
00315         int pos = 0;
00316         qunCommand = decryptedBuf[pos++];
00317         replyCode = decryptedBuf[pos++];
00318         switch(qunCommand){
00319         case QQ_QUN_CMD_SEND_IM:
00320         case QQ_QUN_CMD_SEND_IM_EX:
00321                 pos += parseSendIMReply(decryptedBuf + pos, bodyLength - pos);
00322                 break;
00323         case QQ_QUN_CMD_SEND_TEMP_QUN_IM:
00324                 pos += parseSendTempQunIMReply(decryptedBuf + pos, bodyLength - pos);
00325                 break;
00326         case QQ_QUN_CMD_CREATE_QUN:
00327                 pos += parseCreateReply(decryptedBuf + pos, bodyLength - pos);
00328                 break;
00329         case QQ_QUN_CMD_CREATE_TEMP_QUN:
00330                 pos += parseCreateTempQun(decryptedBuf + pos, bodyLength - pos);
00331                 break;
00332         case QQ_QUN_CMD_ACTIVATE_QUN:
00333                 pos += parseActivateReply(decryptedBuf + pos, bodyLength - pos);
00334                 break;
00335         case QQ_QUN_CMD_MODIFY_MEMBER:
00336                 pos += parseModifyMemberReply(decryptedBuf + pos, bodyLength - pos);
00337                 break;
00338         case QQ_QUN_CMD_GET_QUN_INFO:
00339                 pos += parseGetInfoReply(decryptedBuf + pos, bodyLength - pos);
00340                 break;
00341         case QQ_QUN_CMD_EXIT_QUN:
00342                 pos += parseExitReply(decryptedBuf + pos, bodyLength - pos);
00343                 break;
00344         case QQ_QUN_CMD_GET_MEMBER_INFO:
00345                 pos += parseGetMemberInfoReply(decryptedBuf + pos, bodyLength - pos);
00346                 break;
00347         case QQ_QUN_CMD_GET_ONLINE_MEMBER:
00348                 pos += parseGetOnlineMemberReply(decryptedBuf + pos, bodyLength - pos);
00349                 break;
00350         case QQ_QUN_CMD_JOIN_QUN:
00351                 pos += parseJoinReply(decryptedBuf + pos, bodyLength - pos);
00352                 break;
00353         case QQ_QUN_CMD_JOIN_QUN_AUTH:
00354                 pos += parseJoinAuthReply(decryptedBuf + pos, bodyLength - pos);
00355                 break;
00356         case QQ_QUN_CMD_MODIFY_QUN_INFO:
00357                 pos += parseModifyInfoReply(decryptedBuf + pos, bodyLength - pos);
00358                 break;
00359         case QQ_QUN_CMD_SEARCH_QUN:
00360                 pos += parseSearchReply(decryptedBuf + pos, bodyLength - pos);
00361                 break;
00362         case QQ_QUN_CMD_GET_TEMP_QUN_INFO:
00363                 pos += parseGetTempQunInfoReply(decryptedBuf + pos, bodyLength - pos);
00364                 break;
00365         case QQ_QUN_CMD_EXIT_TEMP_QUN:
00366                 pos += parseExitTempQunReply(decryptedBuf + pos, bodyLength - pos);
00367                 break;
00368         case QQ_QUN_CMD_GET_TEMP_QUN_MEMBERS:
00369                 pos += parseGetTempQunMembers(decryptedBuf + pos, bodyLength - pos);
00370                 break;
00371         case QQ_QUN_CMD_MODIFY_CARD:
00372                 pos += parseModifyQunCard(decryptedBuf + pos, bodyLength - pos);
00373                 break;
00374         case QQ_QUN_CMD_REQUEST_ALL_REALNAMES:
00375                 pos += parseRequestAllRealNames(decryptedBuf + pos, bodyLength - pos);
00376                 break;
00377         case QQ_QUN_CMD_REQUEST_CARD:
00378                 pos += parseRequestQunCard(decryptedBuf + pos, bodyLength - pos);
00379                 break;
00380         case QQ_QUN_CMD_ADMIN:
00381                 pos += parseQunAdminOperation(decryptedBuf + pos, bodyLength - pos);
00382                 break;
00383         case QQ_QUN_CMD_TRANSFER:
00384                 pos += parseQunTransfer(decryptedBuf + pos, bodyLength - pos);
00385                 break;
00386         default:
00387                 printf("unknown Qun command:0x%2x\n", (char)qunCommand);
00388         }
00389         
00390         if(replyCode != QQ_QUN_CMD_REPLY_OK) {
00391                 /* operation failed */
00392                 char * errorChar = (char *)malloc((bodyLength-pos+1) * sizeof(char));
00393                 errorChar[bodyLength-pos] = 0x00;
00394                 memcpy(errorChar, decryptedBuf + pos, bodyLength - pos);printf("error:%s\n", errorChar);
00395                 errorMessage.assign(errorChar);
00396                 free(errorChar);
00397                 pos = bodyLength;
00398         }
00399 }
00400 
00401 const bool QunReplyPacket::isReplyOK() const
00402 {
00403         return replyCode == QQ_QUN_CMD_REPLY_OK;
00404 }
00405 
00406 // useful variable: qunID
00407 int QunReplyPacket::parseSendIMReply(unsigned char *buf, int)
00408 {
00409         int pos = 0;
00410         if(replyCode == QQ_QUN_CMD_REPLY_OK){
00411                 int tmp4;
00412                 memcpy(&tmp4, buf + pos, 4);
00413                 qunID = ntohl(tmp4);
00414                 pos+=4;
00415         }
00416         return pos;
00417 }
00418 
00419 // useful variables: type, parentQunID and qunID
00420 int QunReplyPacket::parseSendTempQunIMReply(unsigned char *buf, int)
00421 {
00422         int pos = 0;
00423         if(replyCode == QQ_QUN_CMD_REPLY_OK) {    
00424                 type = buf[pos++];    
00425                 int tmp4;
00426                 memcpy(&tmp4, buf + pos, 4);
00427                 parentQunID = ntohl(tmp4);
00428                 pos+=4;
00429                 memcpy(&tmp4, buf + pos, 4);
00430                 qunID = ntohl(tmp4);
00431                 pos+=4;
00432         }
00433         return pos;
00434 }
00435 
00436 // useful variables: qunID and externalID
00437 int QunReplyPacket::parseCreateReply(unsigned char *buf, int)
00438 {
00439         int pos = 0;
00440         if(replyCode == QQ_QUN_CMD_REPLY_OK){
00441                 int tmp4;
00442                 memcpy(&tmp4, buf + pos, 4);
00443                 qunID = ntohl(tmp4);
00444                 pos+=4;
00445                 
00446                 memcpy(&tmp4, buf + pos, 4);
00447                 externalID = ntohl(tmp4);
00448                 pos+=4;
00449         }
00450         return pos;
00451 }
00452 
00453 // useful variables:  qunID, parentQunID and type
00454 int QunReplyPacket::parseCreateTempQun(unsigned char *buf, int)
00455 {
00456         int pos = 0;
00457         if(replyCode == QQ_QUN_CMD_REPLY_OK) {              
00458                 type = buf[pos++];    
00459                 int tmp4;
00460                 memcpy(&tmp4, buf + pos, 4);
00461                 parentQunID = ntohl(tmp4);
00462                 pos+=4;
00463                 memcpy(&tmp4, buf + pos, 4);
00464                 qunID = ntohl(tmp4);
00465                 pos+=4;
00466         }
00467         return pos;
00468 }
00469 
00470 // useful variable: qunID
00471 int QunReplyPacket::parseActivateReply(unsigned char *buf, int)
00472 {
00473         int pos = 0;
00474         if(replyCode == QQ_QUN_CMD_REPLY_OK){
00475                 int tmp4;
00476                 memcpy(&tmp4, buf + pos, 4);
00477                 qunID = ntohl(tmp4);
00478                 pos+=4;
00479         }
00480         return pos;
00481 }
00482 
00483 // useful variable: qunID
00484 int QunReplyPacket::parseModifyMemberReply(unsigned char *buf, int )
00485 {
00486         int pos = 0;
00487         if(replyCode == QQ_QUN_CMD_REPLY_OK){
00488                 int tmp4;
00489                 memcpy(&tmp4, buf + pos, 4);
00490                 qunID = ntohl(tmp4);
00491                 pos+=4;
00492         }
00493         return pos;
00494 }
00495 
00496 /*
00497          for this part, the useful variables are:
00498          qunID,  externalID and
00499          info,  memberList (actually these two contain all information)
00500 */
00501 int QunReplyPacket::parseGetInfoReply(unsigned char *buf, int len)
00502 {
00503                         printf("Qun info reply --- \n");
00504                         for(int i=0; i<len; i++){
00505                                 if(!(i%8)) printf("\n%d: ",i);
00506                                 char t = buf[i];
00507                                 printf("%2x ", (uint8_t)t);
00508                         }
00509                         printf("\n");
00510         int pos=0;
00511         if(replyCode == QQ_QUN_CMD_REPLY_OK) {
00512                 int pos = info.readQunInfo(buf);
00513                 qunID = info.getQunID();
00514                 externalID = info.getExtID();
00515                 
00516                 int tmp4;
00517                 while(pos < len ) {
00518                         QunMember member;
00519                         memcpy(&tmp4, buf+pos, 4);
00520                         member.qqNum = ntohl(tmp4);
00521                         pos+=4;
00522                         
00523                         member.groupIndex = buf[pos++];
00524                         member.admin = buf[pos++];
00525                         memberList[member.qqNum] = member;
00526                 }
00527         }
00528         return pos;
00529 }
00530 
00531 // useful variable: qunID
00532 int QunReplyPacket::parseExitReply(unsigned char *buf, int )
00533 {
00534         int pos = 0;
00535         if(replyCode == QQ_QUN_CMD_REPLY_OK){
00536                 int tmp4;
00537                 memcpy(&tmp4, buf + pos, 4);
00538                 qunID = ntohl(tmp4);
00539                 pos+=4;
00540         }
00541         return pos;
00542 }
00543 
00544 // useful variables:  qunID and memberInfoList;
00545 int QunReplyPacket::parseGetMemberInfoReply(unsigned char *buf, int len)
00546 {
00547         int pos=0;
00548         if(replyCode == QQ_QUN_CMD_REPLY_OK) {
00549                 int tmp4;
00550                 memcpy(&tmp4, buf+pos, 4);
00551                 qunID = ntohl(tmp4);
00552                 pos+=4;
00553                 // member information now
00554                 int tmpLen=0;
00555                 while(pos < len) {
00556                         FriendItem *info = new FriendItem(buf + pos, &tmpLen);
00557                         memberInfoList.push_back(*info);
00558                         delete info;
00559                         pos+=tmpLen;
00560                 }
00561         }
00562         return pos;
00563 }
00564 
00565 // useful variables: qunID and qunQQNumberList
00566 int QunReplyPacket::parseGetOnlineMemberReply(unsigned char *buf, int len)
00567 {
00568         int pos=0;
00569         if(replyCode == QQ_QUN_CMD_REPLY_OK) {
00570                 int tmp4;
00571                 memcpy(&tmp4, buf + pos, 4);
00572                 qunID = ntohl(tmp4);
00573                 pos+=4;
00574                 pos++; // ignore one unknow byte, always be 0x3c;
00575                 while(pos < len ) {
00576                         memcpy(&tmp4, buf+pos, 4);
00577                         qunQQNumberList.push_back(ntohl(tmp4));
00578                         pos+=4;
00579                 }
00580         }
00581         return pos;
00582 }
00583 
00584 // useful variables: qunID and joinReply
00585 int QunReplyPacket::parseJoinReply(unsigned char *buf, int )
00586 {
00587         int pos = 0;
00588         if(replyCode == QQ_QUN_CMD_REPLY_OK){
00589                 int tmp4;
00590                 memcpy(&tmp4, buf + pos, 4);
00591                 qunID = ntohl(tmp4);
00592                 pos+=4;
00593                 joinReply = buf[pos++];
00594         }
00595         return pos;
00596 }
00597 
00598 // useful varible: qunID    ** note that this is only a reply from server for your request and dose not mean anything
00599 int QunReplyPacket::parseJoinAuthReply(unsigned char *buf, int )
00600 {
00601         int pos = 0;
00602         if(replyCode == QQ_QUN_CMD_REPLY_OK){
00603                 int tmp4;
00604                 memcpy(&tmp4, buf + pos, 4);
00605                 qunID = ntohl(tmp4);
00606                 pos+=4;
00607         }
00608         return pos;
00609 }
00610 
00611 // useful variable: qunID
00612 int QunReplyPacket::parseModifyInfoReply(unsigned char *buf, int )
00613 {
00614         int pos = 0;
00615         //if(replyCode == QQ_QUN_CMD_REPLY_OK){
00616         int tmp4;
00617         memcpy(&tmp4, buf + pos, 4);
00618         qunID = ntohl(tmp4);
00619         pos+=4;
00620         //}
00621         return pos;
00622 }
00623 
00624 // useful variables: searchType and qunInfoList
00625 int QunReplyPacket::parseSearchReply(unsigned char *buf, int len)
00626 {
00627         int pos=0;
00628         if(replyCode == QQ_QUN_CMD_REPLY_OK) {
00629                 searchType = buf[pos++]; // actually, In new QQ, all types except QQ_SEARCH_QUN_BY_ID are searched by Web Explorer
00630                 while(pos < len ) {
00631                         QunInfo info;
00632                         pos+=info.readQunInfoFromSearchReply(buf+pos);
00633                         qunInfoList.push_back(info);
00634                 }
00635         }
00636         return pos;
00637 }
00638 
00639 /*
00640          for this part, the useful variables are:
00641          type, qunID,  parentID and
00642          info,  qunQQNumberList (actually these two contain all information)
00643 */
00644 int QunReplyPacket::parseGetTempQunInfoReply(unsigned char *buf, int len)
00645 {
00646         int pos=0;
00647         if(replyCode == QQ_QUN_CMD_REPLY_OK) {
00648                 pos = info.readTempQunInfo(buf);
00649                 type = info.getType();
00650                 qunID = info.getQunID();
00651                 parentQunID = info.getExtID();
00652                 
00653                 int tmp4;
00654                 while(pos < len ) {
00655                         memcpy(&tmp4, buf+pos, 4);
00656                         qunQQNumberList.push_back(ntohl(tmp4));
00657                         pos+=5; // note that we ignore one unknow byte, maybe just the seperator byte
00658                 }
00659         }
00660         return pos;
00661 }
00662 
00663 int QunReplyPacket::parseExitTempQunReply(unsigned char *buf, int )
00664 {
00665         int pos = 0;
00666         if(replyCode == QQ_QUN_CMD_REPLY_OK) {              
00667                 type = buf[pos++];  
00668                   
00669                 int tmp4;
00670                 memcpy(&tmp4, buf + pos, 4);
00671                 parentQunID = ntohl(tmp4);
00672                 pos+=4;
00673                 
00674                 memcpy(&tmp4, buf + pos, 4);
00675                 qunID = ntohl(tmp4);
00676                 pos+=4;
00677         }
00678         return pos;
00679 }
00680 
00681 // useful variables: type, parentQunID, qunID and qunQQNumberList
00682 int QunReplyPacket::parseGetTempQunMembers(unsigned char *buf, int len)
00683 {
00684         int pos=0;
00685         if(replyCode == QQ_QUN_CMD_REPLY_OK) {
00686                 type = buf[pos++];
00687                 
00688                 int tmp4;
00689                 memcpy(&tmp4, buf+pos, 4);
00690                 parentQunID = ntohl(tmp4);
00691                 pos+=4;
00692                 
00693                 memcpy(&tmp4, buf + pos, 4);
00694                 qunID = ntohl(tmp4);
00695                 pos+=4;
00696                 
00697                 while(pos < len ) {
00698                         memcpy(&tmp4, buf+pos, 4);
00699                         qunQQNumberList.push_back(ntohl(tmp4));
00700                         pos+=4; 
00701                 }
00702         }
00703         return pos;
00704 }
00705 
00706 // useful variables:  qunID,  targetQQ
00707 int QunReplyPacket::parseModifyQunCard(unsigned char *buf, int len)
00708 {
00709         int pos=0;
00710         //if(replyCode == QQ_QUN_CMD_REPLY_OK) {
00711         int tmp4;
00712         memcpy(&tmp4, buf+pos, 4);
00713         qunID = ntohl(tmp4);
00714         pos+=4;
00715         
00716         memcpy(&tmp4, buf + pos, 4);
00717         targetQQ = ntohl(tmp4);
00718         pos+=4;
00719         //}
00720         return pos;
00721 }
00722 
00723 int QunReplyPacket::parseRequestAllRealNames(unsigned char *buf, int len)
00724 {
00725         int pos = 0;
00726         qunID = EvaUtil::read32( buf + pos); pos+=4;
00727         m_CardVersion = EvaUtil::read32( buf + pos); pos+=4; 
00728         m_NextStart = EvaUtil::read32( buf + pos); pos+=4;
00729         m_RealNameList.clear();
00730         int tmpId;
00731         char strName[257];
00732         unsigned char nameLen = 0;
00733         while(pos<len){
00734                 tmpId = EvaUtil::read32( buf + pos); pos+=4;
00735                 nameLen = buf[pos++];
00736                 memcpy(strName, buf + pos, nameLen); pos+=nameLen;
00737                 strName[nameLen] = 0x0;
00738                 std::string name;
00739                 name.assign(strName);
00740                 m_RealNameList[tmpId] = name;
00741         }
00742         return pos;
00743 }
00744 
00745 // useful variables: qunID, targetQQ
00746 int QunReplyPacket::parseRequestQunCard(unsigned char *buf, int len)
00747 {
00748         int pos = 0;
00749         
00750         int tmp4;
00751         memcpy(&tmp4, buf + pos, 4); pos+=4;
00752         qunID = ntohl(tmp4);
00753         
00754         memcpy(&tmp4, buf + pos, 4);
00755         targetQQ = ntohl(tmp4);
00756         pos+=4;
00757         
00758         if(replyCode == QQ_QUN_CMD_REPLY_OK) {
00759                 unsigned char strLen;
00760                 char *str;
00761                 strLen = buf[pos++];
00762                 str = new char[strLen + 1];
00763                 memcpy(str, buf+pos, strLen); pos+=strLen;
00764                 str[strLen] = 0x00;
00765                 realName.assign(str);
00766                 delete str;
00767 
00768                 gender = buf[pos++];
00769                 
00770                 strLen = buf[pos++];
00771                 str = new char[strLen + 1];
00772                 memcpy(str, buf+pos, strLen); pos+=strLen;
00773                 str[strLen] = 0x00;
00774                 phone.assign(str);
00775                 delete str;
00776                 
00777                 strLen = buf[pos++];
00778                 str = new char[strLen + 1];
00779                 memcpy(str, buf+pos, strLen); pos+=strLen;
00780                 str[strLen] = 0x00;
00781                 email.assign(str);
00782                 delete str;
00783                 
00784                 strLen = buf[pos++];
00785                 str = new char[strLen + 1];
00786                 memcpy(str, buf+pos, strLen); pos+=strLen;
00787                 str[strLen] = 0x00;
00788                 memo.assign(str);
00789                 delete str;
00790         }else
00791                 pos++;
00792         return pos;
00793 }
00794 
00795 int QunReplyPacket::parseQunAdminOperation(unsigned char *buf, int len)
00796 {
00797         int pos=0;
00798 
00799         int tmp4;
00800         memcpy(&tmp4, buf+pos, 4);
00801         qunID = ntohl(tmp4);
00802         pos+=4;
00803                 
00804         if(replyCode == QQ_QUN_CMD_REPLY_OK) {
00805                 memcpy(&tmp4, buf + pos, 4);
00806                 versionID = ntohl(tmp4);
00807                 pos+=4; 
00808                 
00809                 memcpy(&tmp4, buf + pos, 4);
00810                 targetQQ = ntohl(tmp4);
00811                 pos+=4;
00812                 
00813                 opCode = buf[pos++];
00814         }
00815         
00816         return pos;
00817 }
00818 
00819 int QunReplyPacket::parseQunTransfer(unsigned char *buf, int len)
00820 {
00821         int pos=0;
00822         int tmp4;
00823         memcpy(&tmp4, buf+pos, 4);
00824         qunID = ntohl(tmp4);
00825         pos+=4;
00826         
00827         memcpy(&tmp4, buf + pos, 4);
00828         targetQQ = ntohl(tmp4);
00829         pos+=4;
00830         
00831         if(replyCode == QQ_QUN_CMD_REPLY_OK) {
00832                 memcpy(&tmp4, buf + pos, 4);
00833                 versionID = ntohl(tmp4);
00834                 pos+=4;
00835         }
00836         return pos;
00837 }
00838 
00839 /***************************************************************************************************************/
00840  
00841 
00842 QunGetInfoPacket::QunGetInfoPacket(const int id)
00843         : QunPacket(QQ_QUN_CMD_GET_QUN_INFO, id)
00844 {
00845 }
00846 
00847 QunGetInfoPacket::QunGetInfoPacket(const QunGetInfoPacket &rhs)
00848         : QunPacket(rhs)
00849 {
00850 }
00851 
00852 QunGetInfoPacket::~QunGetInfoPacket()
00853 {
00854 }
00855 
00856 int QunGetInfoPacket::putBody(unsigned char *buf)
00857 {
00858         buf[0] = qunCommand;
00859         int tmp4 = htonl(qunID);
00860         memcpy(buf + 1, &tmp4, 4);
00861         return 5;
00862 }
00863 
00864 
00865 /***************************************************************************************************************/
00866  
00867 
00868 
00869 QunGetMemberInfoPacket::QunGetMemberInfoPacket(const int id)
00870         : QunPacket(QQ_QUN_CMD_GET_MEMBER_INFO, id)
00871 {
00872 }
00873 
00874 QunGetMemberInfoPacket::QunGetMemberInfoPacket( const QunGetMemberInfoPacket & rhs )
00875         : QunPacket(rhs)
00876 {
00877         memberList = rhs.getMemberList();
00878 }
00879 
00880 QunGetMemberInfoPacket::~ QunGetMemberInfoPacket( )
00881 {
00882 }
00883 
00884 QunGetMemberInfoPacket & QunGetMemberInfoPacket::operator =( const QunGetMemberInfoPacket & rhs )
00885 {
00886         *(QunPacket*)this = (QunPacket)rhs;
00887         memberList = rhs.getMemberList();
00888         return *this;
00889 }
00890 
00891 void QunGetMemberInfoPacket::addMember( const int id )
00892 {
00893         memberList.push_back(id);
00894 }
00895 
00896 int QunGetMemberInfoPacket::putBody( unsigned char * buf )
00897 {
00898         int pos=0;
00899         buf[pos++] = qunCommand;
00900         int tmp4 = htonl(qunID);
00901         memcpy(buf + pos, &tmp4, 4);
00902         pos+=4;
00903         
00904         std::list<int>::iterator itr;
00905         for(itr=memberList.begin(); itr!= memberList.end(); ++itr){
00906                 tmp4 = htonl(*itr);
00907                 memcpy(buf + pos, &tmp4, 4);
00908                 pos+=4;
00909                 
00910         }
00911         return pos;
00912 }
00913 
00914 
00915 
00916 /***************************************************************************************************************/
00917  
00918 QunGetOnlineMemberPacket::QunGetOnlineMemberPacket(const int id)
00919         : QunPacket(QQ_QUN_CMD_GET_ONLINE_MEMBER, id)
00920 {
00921 }
00922 
00923 QunGetOnlineMemberPacket::QunGetOnlineMemberPacket(const QunGetOnlineMemberPacket &rhs)
00924         : QunPacket(rhs)
00925 {
00926 }
00927 
00928 QunGetOnlineMemberPacket::~QunGetOnlineMemberPacket()
00929 {
00930 }
00931 
00932 int QunGetOnlineMemberPacket::putBody(unsigned char *buf)
00933 {
00934         buf[0] = qunCommand;
00935         int tmp4 = htonl(qunID);
00936         memcpy(buf + 1, &tmp4, 4);
00937         return 5;
00938 }
00939 
00940 
00941 
00942 /***************************************************************************************************************/
00943  
00944 QunActivatePacket::QunActivatePacket(const int id)
00945         : QunPacket(QQ_QUN_CMD_ACTIVATE_QUN, id)
00946 {
00947 }
00948 
00949 QunActivatePacket::QunActivatePacket(const QunActivatePacket &rhs)
00950         : QunPacket(rhs)
00951 {
00952 }
00953 
00954 QunActivatePacket::~QunActivatePacket()
00955 {
00956 }
00957 
00958 int QunActivatePacket::putBody(unsigned char *buf)
00959 {
00960         buf[0] = qunCommand;
00961         int tmp4 = htonl(qunID);
00962         memcpy(buf + 1, &tmp4, 4);
00963         return 5;
00964 }
00965 
00966 
00967 
00968 /***************************************************************************************************************/
00969  
00970 QunAuthPacket::QunAuthPacket( const int id, int authType )
00971         : QunPacket(QQ_QUN_CMD_JOIN_QUN_AUTH, id),
00972         type(authType), receiver(0), message("")
00973 {
00974 }
00975 
00976 QunAuthPacket::QunAuthPacket( const QunAuthPacket & rhs )
00977         : QunPacket(rhs)
00978 {
00979         *this = rhs;
00980 }
00981 
00982 QunAuthPacket::~ QunAuthPacket( )
00983 {
00984 }
00985 
00986 QunAuthPacket & QunAuthPacket::operator =( const QunAuthPacket & rhs )
00987 {
00988         *(QunPacket *)this = (QunPacket)rhs;
00989         type = rhs.getAuthType();
00990         receiver = rhs.getReceiver();
00991         message = rhs.getMessage();
00992         return *this;
00993 }
00994 
00995 int QunAuthPacket::putBody( unsigned char * buf )
00996 {
00997         int pos=0;
00998         buf[pos++] = qunCommand;
00999         
01000         int tmp4 = htonl(qunID);
01001         memcpy(buf + pos, &tmp4, 4);
01002         pos+=4;
01003         
01004         buf[pos++]=type;
01005         
01006         tmp4 = htonl(receiver);
01007         memcpy(buf + pos, &tmp4, 4);
01008         pos+=4;
01009         
01010         int len = message.length();
01011         buf[pos++] = (char)(len & 0xFF);
01012         
01013         memcpy(buf+pos, message.c_str(), len);
01014         pos+=len;
01015         
01016         return pos;
01017 }
01018 
01019 
01020 
01021 /***************************************************************************************************************/
01022 
01023 QunSendIMPacket::QunSendIMPacket( const int id )
01024         : QunPacket(QQ_QUN_CMD_SEND_IM, id),
01025         encoding(QQ_IM_ENCODING_GB),
01026         red(0),green(0),blue(0),
01027         bold(false),italic(false),underline(false),
01028         fontSize(0x09),
01029         fontFlag(0x09),
01030         message("Hello, I am using Eva.")
01031 {
01032         char *fname = (char *)malloc(5);
01033         fname[0] = 0xcb;
01034         fname[1] = 0xce;
01035         fname[2] = 0xcc;
01036         fname[3] = 0xe5;
01037         fname[4] = 0x00;
01038         fontName = fname; // just set font name to "Song Ti" in Chinese
01039         free(fname);
01040 }
01041 
01042 QunSendIMPacket::QunSendIMPacket( const QunSendIMPacket & rhs )
01043         : QunPacket(rhs)
01044 {
01045         encoding = rhs.getEncoding();  
01046         fontName = rhs.getFontName();
01047         
01048         red = rhs.getRed();
01049         green = rhs.getGreen();
01050         blue = rhs.getBlue();
01051                 
01052         fontFlag = 0x00;
01053         bold = rhs.isBold(); 
01054         fontFlag |= bold ? 0x20 : 0x00; 
01055         
01056         italic = rhs.isItalic(); 
01057         fontFlag |= italic ? 0x40 : 0x00;
01058         
01059         underline = rhs.isUnderline();
01060         fontFlag |= underline ? 0x80 : 0x00;
01061         
01062         fontSize = rhs.getFontSize();
01063         fontFlag |= fontSize;
01064         
01065         message = rhs.getMessage();
01066 }
01067 
01068 QunSendIMPacket::~ QunSendIMPacket( )
01069 {
01070 }
01071 
01072 QunSendIMPacket & QunSendIMPacket::operator =( const QunSendIMPacket & rhs )
01073 {
01074         *((QunPacket *)this) = (QunPacket)rhs;
01075         encoding = rhs.getEncoding();  
01076         fontName = rhs.getFontName();
01077         
01078         red = rhs.getRed();
01079         green = rhs.getGreen();
01080         blue = rhs.getBlue();
01081                 
01082         fontFlag = 0x00;
01083         bold = rhs.isBold(); 
01084         fontFlag |= bold ? 0x20 : 0x00; 
01085         
01086         italic = rhs.isItalic(); 
01087         fontFlag |= italic ? 0x40 : 0x00;
01088         
01089         underline = rhs.isUnderline();
01090         fontFlag |= underline ? 0x80 : 0x00;
01091         
01092         fontSize = rhs.getFontSize();
01093         fontFlag |= fontSize;
01094         
01095         message = rhs.getMessage();     
01096         return *this;
01097 }
01098 
01099 void QunSendIMPacket::setFontSize( char fontSize )
01100 {
01101         this->fontSize = fontSize;
01102         fontSize &= 0x1F;
01103         fontFlag &= 0xE0;
01104         fontFlag |= fontSize;
01105 }
01106 
01107 void QunSendIMPacket::setUnderline( bool underline )
01108 {
01109         this->underline = underline;
01110         fontFlag &= 0x7F;
01111         fontFlag |= underline ? 0x80 : 0x00;
01112 }
01113 
01114 void QunSendIMPacket::setItalic( bool italic )
01115 {
01116         this->italic = italic;
01117         fontFlag &= 0xBF;
01118         fontFlag |= italic ? 0x40 : 0x00;
01119 }
01120 
01121 void QunSendIMPacket::setBold( bool bold )
01122 {
01123         this->bold = bold;
01124         fontFlag &= 0xDF;
01125         fontFlag |= bold ? 0x20 : 0x00;
01126 }
01127 
01128 int QunSendIMPacket::putBody( unsigned char * buf )
01129 {
01130         int pos=0;
01131         buf[pos++] = qunCommand; // qun command
01132         
01133         int tmp4 = htonl(qunID);
01134         memcpy(buf+pos, &tmp4, 4); // qun internal ID
01135         pos+=4;
01136         
01137         int lenPos = pos;  // we record the index of the length of following contents, it takes 2 bytes
01138         pos+=2; 
01139         
01140         std::string str2send = EvaUtil::convertToSend(message);
01141         memcpy(buf+pos, str2send.c_str(), str2send.length());
01142         pos += str2send.length();
01143         
01144         //now we can set the length of message and font name;
01145         short tmp2 = htons((short)(str2send.length() + fontName.length() + 10));
01146         memcpy(buf + lenPos, &tmp2, 2);
01147         
01148         buf[pos++] = 0x20; //  a space
01149         buf[pos++] = 0x00;    //  C style string terminator
01150         
01151         buf[pos++] = fontFlag;
01152         buf[pos++] = red;
01153         buf[pos++] = green;
01154         buf[pos++] = blue;
01155         
01156         buf[pos++] = 0;
01157         
01158         short tmpEncoding = htons(encoding);  // encoding for text
01159         memcpy(buf+pos,&tmpEncoding, 2);
01160         pos+=2;
01161         
01162         int len = fontName.length();     // font name
01163         memcpy(buf+pos, fontName.c_str(), len);
01164         pos+=len;
01165         
01166         buf[pos++] = 0x0D;   // an Enter
01167         
01168         return pos;
01169 }
01170 
01171 
01172 
01173 
01174 /***************************************************************************************************************/
01175 
01176 QunSearchPacket::QunSearchPacket()
01177         : QunPacket(QQ_QUN_CMD_SEARCH_QUN), 
01178         type(QQ_SEARCH_QUN_BY_ID)
01179 {
01180 }
01181 
01182 QunSearchPacket::QunSearchPacket( int type )
01183         : QunPacket(QQ_QUN_CMD_SEARCH_QUN)
01184 {
01185         this->type = type;
01186 }
01187 
01188 QunSearchPacket::QunSearchPacket( const QunSearchPacket & rhs )
01189         : QunPacket(rhs)
01190 {
01191         *this = rhs;
01192 }
01193 
01194 QunSearchPacket & QunSearchPacket::operator =( const QunSearchPacket & rhs )
01195 {
01196         *((QunPacket *)this) = (QunPacket)rhs;
01197         type = rhs.getSearchType();
01198         externalID = rhs.getExtID();
01199         return *this;
01200 }
01201 
01202 int QunSearchPacket::putBody( unsigned char * buf )
01203 {
01204         int pos=0;
01205         buf[pos++] = qunCommand; // qun command
01206         buf[pos++] = type;       // qun type
01207         
01208         int tmp4;
01209         if(type == QQ_SEARCH_DEMO_QUN){
01210                 memset(buf+pos, 0, 4);
01211         }else{
01212                 tmp4 = htonl(externalID);
01213                 memcpy(buf+pos, &tmp4, 4);
01214         }
01215         pos+=4;
01216         return pos;
01217         
01218 }
01219 
01220 
01221 
01222 /***************************************************************************************************************/
01223  
01224 QunJoinPacket::QunJoinPacket(const int id)
01225         : QunPacket(QQ_QUN_CMD_JOIN_QUN, id)
01226 {
01227 }
01228 
01229 QunJoinPacket::QunJoinPacket(const QunJoinPacket &rhs)
01230         : QunPacket(rhs)
01231 {
01232 }
01233 
01234 QunJoinPacket::~QunJoinPacket()
01235 {
01236 }
01237 
01238 int QunJoinPacket::putBody(unsigned char *buf)
01239 {
01240         buf[0] = qunCommand;
01241         int tmp4 = htonl(qunID);
01242         memcpy(buf + 1, &tmp4, 4);
01243         return 5;
01244 }
01245 
01246 
01247 
01248 /***************************************************************************************************************/
01249  
01250 QunModifyPacket::QunModifyPacket( const QunInfo & inf )
01251         : QunPacket( QQ_QUN_CMD_MODIFY_QUN_INFO, inf.getQunID())
01252 {
01253         info = inf;
01254 }
01255 
01256 QunModifyPacket::QunModifyPacket( const QunModifyPacket & rhs )
01257         : QunPacket(rhs)
01258 {
01259         info = rhs.getQunInfo();
01260 }
01261 
01262 QunModifyPacket & QunModifyPacket::operator =( const QunModifyPacket & rhs )
01263 {
01264         *( (QunPacket*)this) = (QunPacket)rhs;
01265         info = rhs.getQunInfo();
01266         return *this;
01267 }
01268 
01269 int QunModifyPacket::putBody( unsigned char * buf )
01270 {
01271         int pos=0;
01272         
01273         buf[pos++] = qunCommand;
01274         
01275         int tmp4 = htonl(info.getQunID());
01276         memcpy(buf + pos, &tmp4, 4);
01277         pos+=4;
01278         
01279         buf[pos++] = 0x01;  // dose this byte means permenant Qun or some thing?
01280         
01281         buf[pos++] = info.getAuthType();
01282         
01283         memset(buf+pos, 0, 6);  // 6 bytes 0x00 s
01284         pos+=6;
01285         
01286         unsigned short tmp2;