📄 evapacketmanager.cpp
字号:
/*************************************************************************** * Copyright (C) 2004 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 "evapacketmanager.h"#include "evausersetting.h"#include "evaconnecter.h"#include <qapplication.h>#include <qdatetime.h>#include <qtimer.h>#include <qtextcodec.h>#include <stdlib.h>#include <map>EvaPacketManager::EvaPacketManager(EvaUser *user, EvaConnecter *connecter){ codec = QTextCodec::codecForName("GB18030"); this->user = user; addingBuddyQQ = 0; deletingBuddyQQ = 0; processQunID = 0; qunMemberInfoFinished = false; OutPacket::setQQ(user->getQQ()); Packet::setPasswordKey((unsigned char *)(user->getMd5Password())); this->connecter = connecter; Packet::setUDP(connecter->getConnectionType() == EvaNetwork::UDP); QObject::connect(connecter, SIGNAL(newPacket()), this, SLOT(newPacketSlot())); QObject::connect(connecter, SIGNAL(networkException(int)), this, SLOT(networkExceptionSlot(int))); QObject::connect(connecter, SIGNAL(packetException(int)), this, SLOT(packetExceptionSlot(int))); QObject::connect(connecter, SIGNAL(clientNotReady()), this, SLOT(slotClientNotReady())); timer = new QTimer(this); QObject::connect(timer, SIGNAL(timeout()), SLOT(timerSlot()) );}EvaPacketManager::~EvaPacketManager(){ if(timer->isActive()){ timer->stop(); } delete timer; if(user) delete user; if(connecter) delete connecter;}void EvaPacketManager::newPacketSlot(){ InPacket *packet = connecter->getInPacket(); if(packet==NULL){ fprintf(stderr, "grab packet error: NULL pointer!\n"); return; } parsePacket(packet);}void EvaPacketManager::networkExceptionSlot(int exp){ printf("network exception: %d\n", exp); emit networkException(exp);}void EvaPacketManager::packetExceptionSlot(int cmd){ printf("packet exception: (cmd)0x%4x\n",cmd); emit packetException(cmd);}void EvaPacketManager::timerSlot(){ connecter->append(new KeepAlivePacket()); receivedPacketList.clear(); receivedCacheList.clear();}void EvaPacketManager::redirectTo(const unsigned int ip, const short port){ connecter->redirectTo(ip, port);}void EvaPacketManager::saveBuddyQQ(const unsigned int id, const short seq){ std::map<short, int>::iterator iter = sendRemoveCacheList.find(seq); if( iter != sendRemoveCacheList.end()) return ; sendRemoveCacheList[seq] = id;}void EvaPacketManager::removeSequence(const short seq){ std::map<short, int>::iterator iter = sendRemoveCacheList.find(seq); if( iter == sendRemoveCacheList.end()) return; sendRemoveCacheList.erase(iter);}const int EvaPacketManager::getSavedBuddyQQ(const short seq){ std::map<short, int>::iterator iter = sendRemoveCacheList.find(seq); if(iter == sendRemoveCacheList.end()) return -1; return sendRemoveCacheList[seq];}void EvaPacketManager::parsePacket(InPacket *packet){ int index = receivedPacketList.findIndex(packet->hashCode()); if(index != -1 && packet->getCommand() != QQ_CMD_RECV_IM) { delete packet; return; } receivedPacketList.append(packet->hashCode()); switch(packet->getCommand()){ case QQ_CMD_LOGIN: processLoginReply(packet); break; case QQ_CMD_KEEP_ALIVE: processKeepAliveReply(packet); break; case QQ_CMD_GET_USER_INFO: printf("user info\n"); processGetUserInfoReply(packet); break; case QQ_CMD_CHANGE_STATUS: printf("change status reply\n"); processChangeStatusReply(packet); break; case QQ_CMD_GET_FRIEND_LIST: printf("friend list\n"); processGetFriendListReply(packet); break; case QQ_CMD_GET_FRIEND_ONLINE: //printf("online-friend list\n"); processGetOnlineFriendReply(packet); break; case QQ_CMD_SEND_IM: printf("send im reply\n"); processSendIMReply(packet); break; case QQ_CMD_RECV_IM: printf("received new message\n"); processReceiveIM(packet); break; case QQ_CMD_RECV_MSG_FRIEND_CHANGE_STATUS: printf("friend change status\n"); processFriendChangeStatus(packet); break; case QQ_CMD_GROUP_NAME_OP: printf("upload/download group names reply\n"); processGroupNameOp(packet); break; case QQ_CMD_DOWNLOAD_GROUP_FRIEND: printf("grouped friends reply\n"); processDownloadGroupFriendReply(packet); break; case QQ_CMD_UPLOAD_GROUP_FRIEND: printf("upload grouped friend reply\n"); processUploadGroupFriendReply(packet); break; case QQ_CMD_DELETE_FRIEND: printf("delete friend reply\n"); processDeleteFriendReply(packet); break; case QQ_CMD_ADD_FRIEND: printf("add friend reply\n"); processAddFriendReply(packet); break; case QQ_CMD_ADD_FRIEND_AUTH: printf("add friend auth reply\n"); processAddFriendAuthReply(packet); break; case QQ_CMD_RECV_MSG_SYS: printf("system message\n"); processSystemNotification(packet); break; case QQ_CMD_MODIFY_INFO: printf("received modify info\n"); processModifyInfoReply(packet); break; case QQ_CMD_SEARCH_USER: printf("search reply\n"); processSearchUserReply(packet); break; case QQ_CMD_DELETE_ME: printf("delete me reply\n"); processDeleteMeReply(packet); break; case QQ_CMD_REQUEST_LOGIN_TOKEN: printf("got login token\n"); processRequestLoginTokenReply(packet); break; case QQ_CMD_REQUEST_LOGIN_TOKEN_EX: printf("got login token ex\n"); processRequestLoginTokenExReply(packet); break; case QQ_CMD_QUN_CMD: printf("got Qun operation reply\n"); processQunReply(packet); break; case QQ_CMD_GET_LEVEL: printf("got level reply\n"); processGetLevelReply(packet); break; case QQ_CMD_REQUEST_KEY: printf("got keys reply\n"); processRequestKeyReply(packet); break; case QQ_CMD_REQUEST_EXTRA_INFORMATION: printf("got extra info reply\n"); processRequestExtraInfoReply(packet); break; case QQ_CMD_SIGNATURE_OP: printf("got signature op reply\n"); processSignatureReply(packet); break; case QQ_CMD_MEMO_OP: printf("got memo op reply\n"); processMemoReply(packet); break; case QQ_CMD_ADVANCED_SEARCH: printf("advanced search reply\n"); processAdvancedSearchReply(packet); break; case QQ_CMD_ADD_FRIEND_EX: printf("add friend ex reply\n"); processAddFriendExReply(packet); break; case QQ_CMD_ADD_FRIEND_AUTH_EX: printf("add friend auth ex reply\n"); processAddFriendAuthExReply(packet); break; case QQ_CMD_ADD_FRIEND_AUTH_INFO: printf("auth info reply\n"); processAddFrendAuthInfoReply(packet); break; case QQ_CMD_ADD_FRIEND_AUTH_QUESTION: printf("auth question reply\n"); processAddFriendAuthQuestionReply(packet); break; case QQ_CMD_VERIFY_ADDING_MSG: printf("verify adding message reply\n"); processVerifyAddingMsgReply(packet); break; } delete packet;}void EvaPacketManager::doRequestLoginToken(){ connecter->append(new RequestLoginTokenPacket());}void EvaPacketManager::doLogin(){ if(! Packet::isLoginTokenSet()){ //doRequestLoginToken(); doRequestLoginTokenEx(); return; } unsigned char mode = QQ_LOGIN_MODE_INVISIBLE; if(user->getStatus() == EvaUser::Eva_Online) mode = QQ_LOGIN_MODE_NORMAL; Packet::setPasswordKey((unsigned char *)(user->getMd5Password())); LoginPacket *packet = new LoginPacket(mode); packet->setNumProcess(1); // we simple set it to 1 for now packet->setComputerUUID(Computer_UUID); // use hard-coded UUID, might change it to follow QQ's logic connecter->append(packet);}void EvaPacketManager::processRequestLoginTokenReply(const InPacket *in){ if(Packet::isLoginTokenSet()) return; RequestLoginTokenReplyPacket *packet = new RequestLoginTokenReplyPacket(); packet->setInPacket(in); bool isWrong = packet->parse(); delete packet; if(!isWrong){ emit serverBusy(); return; } user->loginManager()->finishedCommand(QQ_CMD_REQUEST_LOGIN_TOKEN); // here, we've got login token, therefore, try to log in doLogin();}void EvaPacketManager::processLoginReply(const InPacket *in){ // if client key is set, the user has logged in. if(Packet::isClientKeySet()) return; if(user->loginManager()->isCommandFinished(QQ_CMD_LOGIN)) return; LoginReplyPacket *packet = new LoginReplyPacket(); packet->setInPacket(in); if(!packet->parse()) { printf("parse error\n"); delete packet; emit serverBusy(); // if parse error, we just emit a serverBusy signal so that we can have another try return; } switch(packet->getReplyCode()) { case QQ_LOGIN_REPLY_OK: { printf("user \"%d\" logged in!\n", user->getQQ());// printf("My Ip: %s\tMy Port: %d\n", QHostAddress(packet->getMyIP()).toString().ascii(),// 0xffff & packet->getMyPort());// printf("EvaPacketManager::processLoginReply -- \n");// for(int i=0; i<packet->getLength(); i++){// if(!(i%8)) printf("\n%d: ",i);// char t = packet->getBody()[i];// printf("%2x ", (uint8_t)t);// }// printf("\n----====== Login Successfully ======----\n\n"); user->setLoginWanIp(packet->getMyIP()); user->setLoginWanPort(packet->getMyPort()); user->setLastLoginIp(packet->getLastLoginIP()); user->setLastLoginTime(packet->getLastLoginTime()); user->setLoginLanIp(connecter->getSocketIp().toIPv4Address()); user->setLoginLanPort(connecter->getSocketPort()); user->loginManager()->finishedCommand(QQ_CMD_LOGIN); connecter->append(new ChangeStatusPacket(EvaUser::getStatusCode(user->getStatus()))); connecter->append(new EvaRequestKeyPacket(QQ_REQUEST_FILE_AGENT_KEY)); //connecter->append(new EvaRequestKeyPacket(QQ_REQUEST_UNKNOWN_KEY)); if(user->isBuddiesLoaded()) connecter->append(new GetOnlineFriendsPacket()); if(!timer->isActive()){ timer->start(60000, false); }else printf("impossible! \n"); emit loginOK(); } break; case QQ_LOGIN_REPLY_REDIRECT: case QQ_LOGIN_REPLY_REDIRECT_EX: printf("EVA redirect to: %8x, %d\n", packet->getRedirectedIP(), packet->getRedirectedPort()); if(packet->getRedirectedIP() == 0) { emit serverBusy(); }else{ ServerDetectorPacket::nextStep(); ServerDetectorPacket::setFromIP(connecter->getHostAddress().toIPv4Address()); redirectTo(packet->getRedirectedIP(),packet->getRedirectedPort()); } break; case QQ_LOGIN_REPLY_PWD_ERROR: case QQ_LOGIN_REPLY_NEED_REACTIVATE: printf("something wrong:%s\n",codec->toUnicode(packet->getReplyMessage().c_str()).local8Bit().data()); emit wrongPassword(codec->toUnicode(packet->getReplyMessage().c_str())); break; case QQ_LOGIN_REPLY_MISC_ERROR: printf("some unknown error:%s\nhaving another try ...\n",packet->getReplyMessage().c_str()); emit serverBusy(); break; default: printf("unknown reply code\n"); } delete packet;}void EvaPacketManager::doLogout( ){ if(user->getStatus() != EvaUser::Eva_Offline){ if(connecter->isConnectionReady()){ for(int i=0; i<4; i++) { connecter->append(new LogoutPacket()); } } user->setStatus(EvaUser::Eva_Offline); } if(timer->isActive()) timer->stop(); connecter->stop(); longMsgPacketQueue.clear(); Packet::clearAllKeys(); emit logoutOK();}void EvaPacketManager::doGetUserInfo( const unsigned int id ){ connecter->append(new GetUserInfoPacket(id));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -