⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 evauhmanager.cpp

📁 linux下的eva源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************** *   Copyright (C) 2004-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 "evauhmanager.h"#include "evauhpacket.h"#include "evauhprotocols.h"#include <qfile.h>#include <qdatastream.h>#include <qtextstream.h>#include <qsocketdevice.h>#include <qdns.h>#include <qstringlist.h>#include <qapplication.h>#include <string.h>#define MaxBlockSize      800#define CFACE_SERVER      "cface_tms.qq.com"#define CFACE_PORT        4000#define UH_PROFILE_NAME   "evauh.profile"#define UH_TIME_OUT       30// UH represents User Head which is used in Tencent QQ, sounds pretty @!#~*!$@# :)class EvaUHFile {public:	EvaUHFile(unsigned int id);	~EvaUHFile();	const bool setFileInfo(const char *md5, unsigned int sid);	const bool setFileBlock(const unsigned int numPackets, const unsigned int packetNum, 			const unsigned int fileSize, const unsigned int partStart, 			const unsigned int partSize, const unsigned char *buf);		const QString getMd5String() const;	const unsigned int getQQ() const { return mId; }	const int getSessionId() const { return mSessionId; }		// is this file downloaded sucessfully?	const bool isFinished();	// return session id, and assign the start and size, return 0 means md5 wrong, 	// need redownloading this file again, or no session available	const unsigned int nextBlock(unsigned int *start, unsigned int *size);		const bool isMD5Correct();	void save(QString &dir);	void initSettings();private:	unsigned int mId;	char md5[16];	bool *flags;	unsigned int mFileSize;  // total size of this file	unsigned int mNumPackets;   // number of blocks this file needs	unsigned int mSessionId;   // the session id used in downloading	unsigned char *mBuffer;  // the file data};EvaUHFile::EvaUHFile(unsigned int id)	: mId(id), flags(NULL), mFileSize(0), mNumPackets(0), mSessionId(0), mBuffer(NULL){}EvaUHFile::~EvaUHFile(){	if(flags) delete flags;	if(mBuffer) delete mBuffer;}const bool EvaUHFile::setFileInfo(const char *_md5, unsigned int sid){	if(mSessionId) return false;	memcpy(md5, _md5, 16);	mSessionId = sid;	return true;}const bool EvaUHFile::setFileBlock(const unsigned int numPackets, const unsigned int /*packetNum*/, 			const unsigned int fileSize, const unsigned int partStart, 			const unsigned int partSize, const unsigned char *buf){	//if(packetNum >= numPackets) return false; // impossible	if(mFileSize && fileSize != mFileSize) return false;  // different file size	//if(mNumPackets && numPackets != mNumPackets) return false; // num of blocks wrong	//if(flags && flags[packetNum] ) return false; // got this block already		if(!mFileSize) mFileSize = fileSize;	if(!mNumPackets) mNumPackets = numPackets;	if(!flags){ 		flags = new bool[mNumPackets];		for(unsigned int i=0; i<mNumPackets; i++)			flags[i] = false;	}		if(!mBuffer){ 		mBuffer = new unsigned char[mFileSize];		memset(mBuffer, 0, mFileSize);	}	memcpy(mBuffer+partStart, buf, partSize);	//flags[packetNum] = true;	flags[partStart/MaxBlockSize] = true;	return true;}const QString EvaUHFile::getMd5String() const{	return EvaHelper::md5ToString(md5);}const bool EvaUHFile::isFinished(){	if(!flags) return false;	bool result = true;	for(unsigned int i=0; i< mNumPackets; i++){		if(!flags[i]) {			result = false;			break;		}	}	return result;}// return session id, and assign the start and size, return 0 means md5 wrong, // need redownloading this file again, no session availableconst unsigned int EvaUHFile::nextBlock(unsigned int *start, unsigned int *size){	if(!flags){		*start = 0xffffffff;		*size = 0;		return mSessionId;	}	unsigned int index;	for(index=0; index<mNumPackets; index++)		if(!flags[index]) break;			if(index==0 || index== mNumPackets){		*start = 0xffffffff;		*size = 0;	}else{		*start = (index * MaxBlockSize);		if(index == mNumPackets-1)			*size = mFileSize - (*start);		else			*size = MaxBlockSize;	}		return mSessionId;}const bool EvaUHFile::isMD5Correct(){	if(!mBuffer)		return false;		char *gMd5 = new char[16];	memcpy(gMd5, EvaUtil::doMd5((char *)mBuffer, mFileSize), 16);	if(memcmp(gMd5, md5, 16) != 0){  // which means not equal		delete [] gMd5;		return false;	}	delete []gMd5;	return true;}// Given a directory, that's enoughvoid EvaUHFile::save(QString &dir){	if(!mBuffer){		fprintf(stderr, "EvaUHFile::save -- NULL file buffer, failed\n");		return;	}		/* we don't check md5, leave the job to calling function to do, save tiem :)	// we check md5 first	if(!isMD5Correct()){		fprintf(stderr, "EvaUHFile::save -- MD5 checking, failed\n");		initSettings(); // if md5 wrong, the data is useless, we clear all		return;	}	*/	QString filePrefix = dir + "/" + getMd5String();	QFile file(filePrefix + ".bmp");	if(!file.open(IO_WriteOnly | IO_Raw )){		fprintf(stderr, "EvaUHFile::save -- file creating, failed\n");		return;	}  	QDataStream stream(&file);	stream.writeRawBytes((char *)mBuffer, mFileSize);	file.flush();	file.close();	QImage grayPic;	grayPic.loadFromData(mBuffer, mFileSize);	EvaQtUtils::convertToGrayscale(&grayPic);	grayPic.save(filePrefix +"_off.bmp", "BMP");}// we only re-set the details not the basic information like id, session id and md5 valuevoid EvaUHFile::initSettings(){	if(flags) delete []flags;	flags = NULL;	if(mBuffer) delete []mBuffer;	mBuffer = NULL;	mNumPackets = 0;	mFileSize = 0;}/************************************************************************************************/ class EvaUHProfile {public:	QString dir;            // note must set the UH directory first	QMap<unsigned int, UHInfoItem> list;	bool loadProfile();	void saveProfile();	void updateInfo(UHInfoItem item);	void updateInfo(const unsigned int id, char *md5, unsigned int sid);	void remove(const unsigned int id);	void fileFinished(const unsigned int id);	char *strMd5ToChar(const QString &strMd5);	char *getMd5(const unsigned int id); // if not exists, NULL return	// cuz session id only used within one session and will not be saved as well	// but it does help to download the new file :)	unsigned int getSession(const unsigned int id); 	UHInfoItem nextDownload(); // if id is 0, means no file downloading needed	QString getStrMd5(const unsigned int id);};bool EvaUHProfile::loadProfile(){	QString filename = dir + "/" + UH_PROFILE_NAME;	QFile file(filename);	if(!file.open(IO_ReadOnly)){		fprintf(stderr, "EvaUHProfile::loadProfile -- file not exists\n");		return false;	}	QTextStream stream(&file);	while(!stream.atEnd()){		QString line = stream.readLine();		QStringList lines = QStringList::split(":", line);		if(lines.size() != 2) continue;		bool ok;		int id = lines[0].stripWhiteSpace().toInt(&ok);		if(!ok) continue;		char *md5 = strMd5ToChar(lines[1].stripWhiteSpace());		if(!md5) continue;		UHInfoItem item;		item.id = id;		item.sessionId = 0;		memcpy(item.md5, md5, 16);		delete [] md5; 		item.isUpdated = false;		list[id] = item;	}	file.close();	return true;}void EvaUHProfile::updateInfo(UHInfoItem item){	QMap<unsigned int, UHInfoItem>::Iterator it = list.find(item.id);	if(it != list.end()){		if(memcmp(it.data().md5, item.md5, 16)!=0){			memcpy(it.data().md5, item.md5, 16);			it.data().sessionId = item.sessionId;			it.data().isUpdated = true;		}	} else {		item.isUpdated = true;		list[item.id] = item;	}}void EvaUHProfile::updateInfo(const unsigned int id, char *md5, unsigned int sid){	QMap<unsigned int, UHInfoItem>::Iterator it = list.find(id);	if(it != list.end()){		if(memcmp(it.data().md5, md5, 16)!=0){			memcpy(it.data().md5, md5, 16);			it.data().sessionId = sid;			it.data().isUpdated = true;		}	} else {		UHInfoItem item;		item.id = id;		memcpy(item.md5, md5, 16);		item.sessionId = sid;		item.isUpdated = true;		list[id] = item;	}}void EvaUHProfile::remove(const unsigned int id){	list.erase(id);}void EvaUHProfile::fileFinished(const unsigned int id){	QMap<unsigned int, UHInfoItem>::Iterator it = list.find(id);	if(it != list.end())		it.data().isUpdated = false;}void EvaUHProfile::saveProfile(){	QString filename = dir + "/" + UH_PROFILE_NAME;	QFile file(filename);	if(!file.open(IO_WriteOnly)){		fprintf(stderr, "EvaUHProfile::saveProfile -- cannot open file to write\n");		return;	}	QTextStream stream(&file);	QMap<unsigned int, UHInfoItem>::Iterator it;	for(it = list.begin(); it!=list.end(); ++it){		if(it.data().isUpdated) continue;     // only save the downloaded ones		QString strId = QString::number(it.key());		QString strMd5 = EvaHelper::md5ToString(it.data().md5);		stream<<strId << ":" << strMd5 << "\n";	}	file.flush();	file.close();}// we new a char[], so calling function should delete the memorychar *EvaUHProfile::strMd5ToChar(const QString &strMd5){	QString ch;	bool ok;	int tmp;	if(strMd5.length() != 32) return NULL;	char *md5 = new char[16];		for(uint i=0; i<strMd5.length(); i+=2){		ch = strMd5.mid(i, 2);		tmp = ch.toInt(&ok, 16);		if(!ok)			return NULL;		md5[i/2] = tmp & 0xff;	}	return md5;}// calling function shouldn't delete the memorychar *EvaUHProfile::getMd5(const unsigned int id){	QMap<unsigned int, UHInfoItem>::Iterator it = list.find(id);	if(it != list.end())		return it.data().md5;	else		return NULL;}// 0 means no session id avalibleunsigned int EvaUHProfile::getSession(const unsigned int id){	QMap<unsigned int, UHInfoItem>::Iterator it = list.find(id);	if(it != list.end())		return it.data().sessionId;	else		return 0;}// return item.id == 0 means all finished, no more downloading neededUHInfoItem EvaUHProfile::nextDownload(){	QMap<unsigned int, UHInfoItem>::Iterator it = list.begin();	while(it != list.end()){		if(it.data().isUpdated)			return list[it.key()];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -