void DownloadManager::checkDownloads(UserConnection* aConn) { Download* d = aConn->getDownload(); bool firstTry = false; if(d == NULL) { firstTry = true; bool slotsFull = (SETTING(DOWNLOAD_SLOTS) != 0) && (getDownloads() >= (size_t)SETTING(DOWNLOAD_SLOTS)); bool speedFull = (SETTING(MAX_DOWNLOAD_SPEED) != 0) && (getAverageSpeed() >= (SETTING(MAX_DOWNLOAD_SPEED)*1024)); if( slotsFull || speedFull ) { bool extraFull = (SETTING(DOWNLOAD_SLOTS) != 0) && (getDownloads() >= (size_t)(SETTING(DOWNLOAD_SLOTS)+3)); if(extraFull || !QueueManager::getInstance()->hasDownload(aConn->getUser(), QueueItem::HIGHEST)) { removeConnection(aConn); return; } } d = QueueManager::getInstance()->getDownload(aConn->getUser()); if(d == NULL) { removeConnection(aConn, true); return; } { Lock l(cs); downloads.push_back(d); } d->setUserConnection(aConn); aConn->setDownload(d); } if(firstTry && !d->getTreeValid() && !d->isSet(Download::FLAG_USER_LIST) && d->getTTH() != NULL) { if(HashManager::getInstance()->getTree(d->getTarget(), d->getTTH(), d->getTigerTree())) { d->setTreeValid(true); } else if(!d->isSet(Download::FLAG_TREE_TRIED) && aConn->isSet(UserConnection::FLAG_SUPPORTS_TTHL)) { // So, we need to download the tree... Download* tthd = new Download(); tthd->setOldDownload(d); tthd->setFlag(Download::FLAG_TREE_DOWNLOAD); tthd->setTarget(d->getTarget()); tthd->setSource(d->getSource()); tthd->setUserConnection(aConn); aConn->setDownload(tthd); aConn->setState(UserConnection::STATE_TREE); // Hack to get by TTH if possible tthd->setTTH(d->getTTH()); aConn->send(tthd->getCommand(false, aConn->isSet(UserConnection::FLAG_SUPPORTS_TTHF))); tthd->setTTH(NULL); return; } } aConn->setState(UserConnection::STATE_FILELENGTH); if(d->isSet(Download::FLAG_RESUME)) { dcassert(d->getSize() != -1); const string& target = (d->getTempTarget().empty() ? d->getTarget() : d->getTempTarget()); int64_t start = File::getSize(target); // Only use antifrag if we don't have a previous non-antifrag part if( BOOLSETTING(ANTI_FRAG) && (start == -1) && (d->getSize() != -1) ) { int64_t aSize = File::getSize(target + Download::ANTI_FRAG_EXT); if(aSize == d->getSize()) start = d->getPos(); else start = 0; d->setFlag(Download::FLAG_ANTI_FRAG); } int rollback = SETTING(ROLLBACK); if(rollback > start) { d->setStartPos(0); } else { d->setStartPos(start - rollback); d->setFlag(Download::FLAG_ROLLBACK); } } else { d->setStartPos(0); } if(d->isSet(Download::FLAG_USER_LIST)) { if(aConn->isSet(UserConnection::FLAG_SUPPORTS_XML_BZLIST)) { d->setSource("files.xml.bz2"); } } if(aConn->isSet(UserConnection::FLAG_SUPPORTS_ADCGET) && d->isSet(Download::FLAG_UTF8)) { aConn->send(d->getCommand( aConn->isSet(UserConnection::FLAG_SUPPORTS_ZLIB_GET), aConn->isSet(UserConnection::FLAG_SUPPORTS_TTHF) )); } else { if(BOOLSETTING(COMPRESS_TRANSFERS) && aConn->isSet(UserConnection::FLAG_SUPPORTS_GETZBLOCK) && d->getSize() != -1 ) { // This one, we'll download with a zblock download instead... d->setFlag(Download::FLAG_ZDOWNLOAD); aConn->getZBlock(d->getSource(), d->getPos(), d->getBytesLeft(), d->isSet(Download::FLAG_UTF8)); } else if(d->isSet(Download::FLAG_UTF8)) { aConn->getBlock(d->getSource(), d->getPos(), d->getBytesLeft(), true); } else { aConn->get(d->getSource(), d->getPos()); } } }