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

📄 queuemanager.cpp

📁 p2p技术C源代码.rar
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		}

		q->removeSource(aUser, reason);
		
		fire(QueueManagerListener::SOURCES_UPDATED, q);
		setDirty();
	}
	if(!x.empty()) {
		DownloadManager::getInstance()->abortDownload(x);
	}
}

void QueueManager::removeSources(User::Ptr& aUser, int reason) throw() {
	string x;
	{
		Lock l(cs);
		QueueItem* qi = NULL;
		while( (qi = userQueue.getNext(aUser, QueueItem::PAUSED)) != NULL) {
			if(qi->isSet(QueueItem::FLAG_USER_LIST)) {
				remove(qi->getTarget());
			} else {
				userQueue.remove(qi, aUser);
				qi->removeSource(aUser, reason);
				fire(QueueManagerListener::SOURCES_UPDATED, qi);
				setDirty();
			}
		}
		
		qi = userQueue.getRunning(aUser);
		if(qi != NULL) {
			if(qi->isSet(QueueItem::FLAG_USER_LIST)) {
				remove(qi->getTarget());
			} else {
				userQueue.setWaiting(qi);
				userQueue.remove(qi, aUser);
				x = qi->getTarget();
				qi->removeSource(aUser, reason);
				fire(QueueManagerListener::SOURCES_UPDATED, qi);
				setDirty();
			}
		}
	}
	if(!x.empty()) {
		DownloadManager::getInstance()->abortDownload(x);
	}
}

void QueueManager::setPriority(const string& aTarget, QueueItem::Priority p) throw() {
	User::List ul;

	{
		Lock l(cs);
	
		QueueItem* q = findByTarget(aTarget);
		if( (q != NULL) && (q->getPriority() != p) ) {
			if( q->getStatus() != QueueItem::STATUS_RUNNING ) {
				if(q->getPriority() == QueueItem::PAUSED) {
					// Problem, we have to request connections to all these users...
					userQueue.getUserList(ul, QueueItem::PAUSED);
				}

				userQueue.remove(q);
				q->setPriority(p);
				userQueue.add(q);
			} else {
				q->setPriority(p);
			}
			setDirty();
			fire(QueueManagerListener::STATUS_UPDATED, q);
		}
	}
	for(User::Iter i = ul.begin(); i != ul.end(); ++i) {
		ConnectionManager::getInstance()->getDownloadConnection(*i);
	}
}

QueueItem* QueueManager::findByTarget(const string& aTarget) {
	// The hash is (hopefully...) case-insensitive...
	QueueItem::StringIter i = queue.find(aTarget);
	return (i == queue.end()) ? NULL : i->second;
}

void QueueManager::saveQueue() throw() {
	if(!dirty)
		return;

	Lock l(cs);

	try {
		
#define STRINGLEN(n) n, sizeof(n)-1
#define CHECKESCAPE(n) SimpleXML::needsEscape(n, true) ? SimpleXML::escape(n, true) : n
		
		BufferedFile f(getQueueFile() + ".tmp", File::WRITE, File::CREATE | File::TRUNCATE);
		f.write(STRINGLEN("<?xml version=\"1.0\" encoding=\"windows-1252\"?>\r\n"));
		f.write(STRINGLEN("<Downloads>\r\n"));

		for(QueueItem::StringIter i = queue.begin(); i != queue.end(); ++i) {
			const QueueItem::Ptr& d = i->second;
			if(!d->isSet(QueueItem::FLAG_USER_LIST)) {
				f.write(STRINGLEN("\t<Download Target=\""));
				f.write(CHECKESCAPE(d->getTarget()));
				f.write(STRINGLEN("\" Resume=\""));
				f.write(Util::toString(d->isSet(QueueItem::FLAG_RESUME)));
				f.write(STRINGLEN("\" Size=\""));
				f.write(Util::toString(d->getSize()));
				f.write(STRINGLEN("\" Priority=\""));
				f.write(Util::toString((int)d->getPriority()));
				f.write(STRINGLEN("\" TempTarget=\""));
				f.write(CHECKESCAPE(d->getTempTarget()));
				f.write(STRINGLEN("\">\r\n"));

				for(QueueItem::Source::List::const_iterator j = d->sources.begin(); j != d->sources.end(); ++j) {
					QueueItem::Source* s = *j;
					f.write(STRINGLEN("\t\t<Source Nick=\""));
					f.write(CHECKESCAPE(s->getUser()->getNick()));
					f.write(STRINGLEN("\" Path=\""));
					f.write(CHECKESCAPE(s->getPath()));
					f.write(STRINGLEN("\"/>\r\n"));
				}

				f.write(STRINGLEN("\t</Download>\r\n"));
			}
		}

		for(DirectoryItem::DirectoryIter j = directories.begin(); j != directories.end(); ++j) {
			DirectoryItem::Ptr d = j->second;
			f.write(STRINGLEN("\t<Directory Target=\""));
			f.write(CHECKESCAPE(d->getTarget()));
			f.write(STRINGLEN("\" Nick=\""));
			f.write(CHECKESCAPE(d->getUser()->getNick()));
			f.write(STRINGLEN("\" Priority=\""));
			f.write(Util::toString((int)d->getPriority()));
			f.write(STRINGLEN("\" Source=\""));
			f.write(CHECKESCAPE(d->getName()));
			f.write(STRINGLEN("\"/>\r\n"));
		}
		
		f.write("</Downloads>\r\n");
		f.close();
		File::deleteFile(getQueueFile());
		File::renameFile(getQueueFile() + ".tmp", getQueueFile());

		dirty = false;
		lastSave = GET_TICK();
	} catch(const FileException&) {
		// ...
	}
}

void QueueManager::loadQueue() throw() {
	try {
		SimpleXML xml(5);
		xml.fromXML(File(getQueueFile(), File::READ, File::OPEN).read());

		load(&xml);
	} catch(const Exception&) {
		// ...
	}
}

void QueueManager::load(SimpleXML* aXml) {
	Lock l(cs);

	aXml->resetCurrentChild();
	if(aXml->findChild("Downloads")) {

		const string sDownload = "Download";
		const string sTempTarget = "TempTarget";
		const string sTarget = "Target";
		const string sResume = "Resume";
		const string sSize = "Size";
		const string sPriority = "Priority";
		const string sSource = "Source";
		const string sNick = "Nick";
		const string sPath = "Path";
		const string sDirectory = "Directory";
		
		aXml->stepIn();
		
		while(aXml->findChild(sDownload)) {
			const string& tempTarget = aXml->getChildAttrib(sTempTarget);
			const string& target = aXml->getChildAttrib(sTarget);
			bool resume = aXml->getBoolChildAttrib(sResume);
			int64_t size = aXml->getLongLongChildAttrib(sSize);
			QueueItem::Priority p = (QueueItem::Priority)aXml->getIntChildAttrib(sPriority);
			aXml->stepIn();
			if(aXml->findChild(sSource)) {
				do {
					const string& nick = aXml->getChildAttrib(sNick);
					const string& path = aXml->getChildAttrib(sPath);

					try {
						add(path, size, ClientManager::getInstance()->getUser(nick), target, resume, p, tempTarget);
					} catch(const Exception&) {
						// ...
					}
				} while(aXml->findChild(sSource));
			} else {
				// Sourceless file!
				Lock l(cs);
				bool newItem = false;
				if(target.find('\\') == string::npos)
					continue;

				QueueItem* qi = getQueueItem(target, size, resume, newItem);
				if(newItem) {
					qi->setPriority(p);
					qi->setTempTarget(tempTarget);
					
					if(lastInsert == queue.end()) {
						lastInsert = queue.insert(make_pair(qi->getTarget(), qi)).first;
					} else {
						lastInsert = queue.insert(lastInsert, make_pair(qi->getTarget(), qi));
					}
					fire(QueueManagerListener::ADDED, qi);
				}
			}
			aXml->stepOut();
		}
		aXml->resetCurrentChild();
		while(aXml->findChild(sDirectory)) {
			const string& name = aXml->getChildAttrib(sSource);
			const string& target = aXml->getChildAttrib(sTarget);
			const string& nick = aXml->getChildAttrib(sNick);
			QueueItem::Priority p = (QueueItem::Priority)aXml->getIntChildAttrib(sPriority);
			
			addDirectory(name, ClientManager::getInstance()->getUser(nick), target, p);
		}

		aXml->stepOut();
	}

	// We don't need to save the queue when we've just loaded it...
	dirty = false;
}

void QueueManager::importNMQueue(const string& aFile) throw(FileException) {
	File f(aFile, File::READ, File::OPEN);
	
	u_int32_t size = (u_int32_t)f.getSize();
	
	string tmp;
	if(size > 16) {
		AutoArray<u_int8_t> buf(size);
		f.read(buf, size);
		try {
			CryptoManager::getInstance()->decodeHuffman(buf, tmp);
		} catch(const CryptoException&) {
			return;
		}
	} else {
		tmp = Util::emptyString;
	}
	
	StringTokenizer line(tmp);
	StringList& tokens = line.getTokens();
	
	for(StringIter i = tokens.begin(); i != tokens.end(); i++) {
		const string& tok = *i;
		string::size_type k = tok.find('|');

		if( (k == string::npos) || ((k+1) >= tok.size()) )
			continue;

		string tmp = tok.substr(k+1);
		if( (tmp == "Active") || (tmp == "Paused") ) {
			continue; // ignore first line
		}
		
		StringTokenizer t(tok, '\t');
		StringList& records = t.getTokens();
		
		if(records.size() < 5)
			continue;

		StringIter j = records.begin();
		++j; // filename

		const string& size   = *(++j);
		const string& target = *(++j);
		const string& file   = *(++j);
		const string& nick   = *(++j);

		try {
			add(file, size, ClientManager::getInstance()->getUser(nick), target);
		} catch(const Exception&) {
			// ...
		}
	}
}

// SearchManagerListener
void QueueManager::onAction(SearchManagerListener::Types type, SearchResult* sr) throw() {

	if(type == SearchManagerListener::SEARCH_RESULT && BOOLSETTING(AUTO_SEARCH)) {
		StringList l = getTargetsBySize(sr->getSize(), Util::getExtension(sr->getFile()));
		
		StringTokenizer t(SearchManager::clean(sr->getFileName()), ' ');
		StringList& tok = t.getTokens();

		for(StringIter i = l.begin(); i != l.end(); ++i) {
			bool found = true;

			for(StringIter j = tok.begin(); j != tok.end(); ++j) {
				if(Util::findSubString(*i, *j) == string::npos) {
					found = false;
					break;
				}
			}

			if(found) {
				// Wow! found a new source that seems to match...add it...
				dcdebug("QueueManager::onAction New source %s for target %s found\n", sr->getUser()->getNick().c_str(), i->c_str());
				try {
					add(sr->getFile(), sr->getSize(), sr->getUser(), *i, true, 
						QueueItem::DEFAULT, Util::emptyString, false);
				} catch(const Exception&) {
					// ...
				}
			}
		}
	}
}

// ClientManagerListener
void QueueManager::onAction(ClientManagerListener::Types type, const User::Ptr& aUser) throw() {
	bool hasDown = false;
	switch(type) {
	case ClientManagerListener::USER_UPDATED:
		{
			Lock l(cs);
			for(int i = 0; i < QueueItem::LAST; ++i) {
				QueueItem::UserListIter j = userQueue.getList(i).find(aUser);
				if(j != userQueue.getList(i).end()) {
					for(QueueItem::Iter m = j->second.begin(); m != j->second.end(); ++m)
						fire(QueueManagerListener::SOURCES_UPDATED, *m);
					if(i != QueueItem::PAUSED)
						hasDown = true;
				}
			}
		}
		break;
	}
	if(aUser->isOnline() && hasDown)	
		ConnectionManager::getInstance()->getDownloadConnection(aUser);

}

void QueueManager::onAction(TimerManagerListener::Types type, u_int32_t aTick) throw() {
	switch(type) {
	case TimerManagerListener::MINUTE:
		onTimerMinute(aTick); break;
	case TimerManagerListener::SECOND:
		if(dirty && ((lastSave + 10000) < aTick)) {
			saveQueue();
		}
		break;
	}
}

/**
 * @file
 * $Id: QueueManager.cpp,v 1.42 2003/06/20 10:49:27 arnetheduck Exp $
 */

⌨️ 快捷键说明

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