コード例 #1
0
void Transfer::getParams(const UserConnection& aSource, StringMap& params) {
	params["userNI"] = aSource.getUser()->getNick();
	params["userI4"] = aSource.getRemoteIp();
	params["hub"] = aSource.getUser()->getClientName();
	params["hubURL"] = aSource.getUser()->getClientUrl();
	params["fileSI"] = Util::toString(getSize());
	params["fileSIshort"] = Util::formatBytes(getSize());
	params["fileSIchunk"] = Util::toString(getTotal());
	params["fileSIchunkshort"] = Util::formatBytes(getTotal());
	params["fileSIactual"] = Util::toString(getActual());
	params["fileSIactualshort"] = Util::formatBytes(getActual());
	params["speed"] = Util::formatBytes(getAverageSpeed()) + "/s";
	params["time"] = Util::formatSeconds((GET_TICK() - getStart()) / 1000);
	params["fileTR"] = getTTH().toBase32();
}
コード例 #2
0
ファイル: Transfer.cpp プロジェクト: eiskaltdcpp/eiskaltdcpp
void Transfer::getParams(const UserConnection& aSource, StringMap& params) {
    params["userCID"] = aSource.getUser()->getCID().toBase32();
    params["userNI"] = Util::toString(ClientManager::getInstance()->getNicks(aSource.getUser()->getCID(), aSource.getHubUrl()));
    params["userI4"] = aSource.getRemoteIp();
    StringList hubNames = ClientManager::getInstance()->getHubNames(aSource.getUser()->getCID(), aSource.getHubUrl());
    if(hubNames.empty())
        hubNames.push_back(_("Offline"));
    params["hub"] = Util::toString(hubNames);
    StringList hubs = ClientManager::getInstance()->getHubs(aSource.getUser()->getCID(), aSource.getHubUrl());
    if(hubs.empty())
        hubs.push_back(_("Offline"));
    params["hubURL"] = Util::toString(hubs);
    params["fileSI"] = Util::toString(getSize());
    params["fileSIshort"] = Util::formatBytes(getSize());
    params["fileSIactual"] = Util::toString(getActual());
    params["fileSIactualshort"] = Util::formatBytes(getActual());
    params["speed"] = str(F_("%1%/s") % Util::formatBytes(getAverageSpeed()));
    params["time"] = Util::formatSeconds((GET_TICK() - getStart()) / 1000);
    params["fileTR"] = getTTH().toBase32();
}
コード例 #3
0
ファイル: Display.cpp プロジェクト: rxk8345/Cyclometer
void displaySpeed(){
	int a,b,c,d;

	double currSpeed = getCurrentSpeed();
	double averSpeed = getAverageSpeed();
	//current speed in left most
	if(currSpeed >= 100){
		// only allow display two digits, display 99
		a = 9;
		b = 9;
	}else if(currSpeed > 10 ){
		// no decimal pt
		a = currSpeed / 10;
		setDecimalAnode0(false);
		b = (currSpeed - a * 10);
	}else{
		//1 digit + decimal
		a = currSpeed;
		setDecimalAnode0(true);
		b = (currSpeed * 10 ) - (a * 10);
	}

	if(averSpeed >= 100){
		// only allow display two digits, display 99
		c = 9;
		d = 9;
	}else if(averSpeed > 10 ){
		// no decimal pt
		c = averSpeed / 10;
		setDecimalAnode2(false);
		d = (averSpeed - c * 10);
	} else{
		//1 digit + decimal
		c = averSpeed;
		setDecimalAnode2(true);
		d = (averSpeed * 10 ) - (c * 10);
	}

	displayNumbers(a,b,c,d);
}
コード例 #4
0
ファイル: Transfer.cpp プロジェクト: strogo/StrongDC
void Transfer::getParams(const UserConnection& aSource, StringMap& params) const {
	params["userCID"] = aSource.getUser()->getCID().toBase32();
	params["userNI"] = Util::toString(ClientManager::getInstance()->getNicks(aSource.getUser()->getCID(), aSource.getHubUrl()));
	params["userI4"] = aSource.getRemoteIp();
	StringList hubNames = ClientManager::getInstance()->getHubNames(aSource.getUser()->getCID(), aSource.getHubUrl());
	if(hubNames.empty())
		hubNames.push_back(STRING(OFFLINE));
	params["hub"] = Util::toString(hubNames);
	StringList hubs = ClientManager::getInstance()->getHubs(aSource.getUser()->getCID(), aSource.getHubUrl());
	if(hubs.empty())
		hubs.push_back(STRING(OFFLINE));
	params["hubURL"] = Util::toString(hubs);
	params["fileSI"] = Util::toString(getSize());
	params["fileSIshort"] = Util::formatBytes(getSize());
	params["fileSIchunk"] = Util::toString(getPos());
	params["fileSIchunkshort"] = Util::formatBytes(getPos());
	params["fileSIactual"] = Util::toString(getActual());
	params["fileSIactualshort"] = Util::formatBytes(getActual());
	params["speed"] = Util::formatBytes(static_cast<int64_t>(getAverageSpeed())) + "/s";
	params["time"] = Text::fromT(Util::formatSeconds((GET_TICK() - getStart()) / 1000));
	params["fileTR"] = getTTH().toBase32();
}
コード例 #5
0
void Transfer::updateRunningAverage() {
	time_t tick = GET_TICK();
	// Update 4 times/sec at most
	if(tick > (lastTick + 250)) {
		time_t diff = tick - lastTick;
		int64_t tot = getTotal();
		if( ((tick - getStart()) < AVG_PERIOD) ) {
			runningAverage = getAverageSpeed();
		} else {
			int64_t bdiff = tot - last;
			int64_t avg = bdiff * (int64_t)1000 / diff;
			if(diff > AVG_PERIOD) {
				runningAverage = avg;
			} else {
				// Weighted average...
				runningAverage = ((avg * diff) + (runningAverage*(AVG_PERIOD-diff)))/AVG_PERIOD;
			}
		}
		last = tot;
	}
	lastTick = tick;
}
コード例 #6
0
ファイル: Transfer.cpp プロジェクト: strogo/StrongDC
int64_t Transfer::getSecondsLeft(bool wholeFile) const {
	double avg = getAverageSpeed();
	int64_t bytesLeft =  (wholeFile ? ((Upload*)this)->getFileSize() : getSize()) - getPos();
	return (avg > 0) ? static_cast<int64_t>(bytesLeft / avg) : 0;
}
コード例 #7
0
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());
		}
	}
}
コード例 #8
0
Segment QueueItem::getNextSegment(int64_t  blockSize, int64_t wantedSize, int64_t lastSpeed, const PartialSource::Ptr partialSource) const {
	if(getSize() == -1 || blockSize == 0) {
		return Segment(0, -1);
	}
	
	if(!BOOLSETTING(MULTI_CHUNK)) {
		if(!downloads.empty()) {
			return Segment(-1, 0);
		}

		int64_t start = 0;
		int64_t end = getSize();

		if(!done.empty()) {
			const Segment& first = *done.begin();

			if(first.getStart() > 0) {
				end = Util::roundUp(first.getStart(), blockSize);
			} else {
				start = Util::roundDown(first.getEnd(), blockSize);

				if(done.size() > 1) {
					const Segment& second = *(++done.begin());
					end = Util::roundUp(second.getStart(), blockSize);
				}
			}
		}

		return Segment(start, std::min(getSize(), end) - start);
	}
	
	if(downloads.size() >= maxSegments ||
		(BOOLSETTING(DONT_BEGIN_SEGMENT) && (size_t)(SETTING(DONT_BEGIN_SEGMENT_SPEED) * 1024) < getAverageSpeed()))
	{
		// no other segments if we have reached the speed or segment limit
		return Segment(-1, 0);
	}

	/* added for PFS */
	vector<int64_t> posArray;
	vector<Segment> neededParts;

	if(partialSource) {
		posArray.reserve(partialSource->getPartialInfo().size());

		// Convert block index to file position
		for(PartsInfo::const_iterator i = partialSource->getPartialInfo().begin(); i != partialSource->getPartialInfo().end(); i++)
			posArray.push_back(min(getSize(), (int64_t)(*i) * blockSize));
	}

	/***************************/

	double donePart = static_cast<double>(getDownloadedBytes()) / getSize();
		
	// We want smaller blocks at the end of the transfer, squaring gives a nice curve...
	int64_t targetSize = static_cast<int64_t>(static_cast<double>(wantedSize) * std::max(0.25, (1. - (donePart * donePart))));
		
	if(targetSize > blockSize) {
		// Round off to nearest block size
		targetSize = Util::roundDown(targetSize, blockSize);
	} else {
		targetSize = blockSize;
	}		

	int64_t start = 0;
	int64_t curSize = targetSize;

	while(start < getSize()) {
		int64_t end = std::min(getSize(), start + curSize);
		Segment block(start, end - start);
		bool overlaps = false;
		for(SegmentConstIter i = done.begin(); !overlaps && i != done.end(); ++i) {
			if(curSize <= blockSize) {
				int64_t dstart = i->getStart();
				int64_t dend = i->getEnd();
				// We accept partial overlaps, only consider the block done if it is fully consumed by the done block
				if(dstart <= start && dend >= end) {
					overlaps = true;
				}
			} else {
				overlaps = block.overlaps(*i);
			}
		}
		
		for(auto i = downloads.begin(); !overlaps && i != downloads.end(); ++i) {
			overlaps = block.overlaps((*i)->getSegment());
		}
		
		if(!overlaps) {
			if(partialSource) {
				// store all chunks we could need
				for(vector<int64_t>::const_iterator j = posArray.begin(); j < posArray.end(); j += 2){
					if( (*j <= start && start < *(j+1)) || (start <= *j && *j < end) ) {
						int64_t b = max(start, *j);
						int64_t e = min(end, *(j+1));

						// segment must be blockSize aligned
						dcassert(b % blockSize == 0);
						dcassert(e % blockSize == 0 || e == getSize());

						neededParts.push_back(Segment(b, e - b));
					}
				}
			} else {
				return block;
			}
		}
		
		if(overlaps && (curSize > blockSize)) {
			curSize -= blockSize;
		} else {
			start = end;
			curSize = targetSize;
		}
	}

	if(!neededParts.empty()) {
		// select random chunk for download
		dcdebug("Found chunks: %d\n", neededParts.size());
		
		Segment& selected = neededParts[Util::rand(0, neededParts.size())];
		selected.setSize(std::min(selected.getSize(), targetSize));	// request only wanted size
		
		return selected;
	}
	
	if(partialSource == NULL && BOOLSETTING(OVERLAP_CHUNKS) && lastSpeed > 0) {
		// overlap slow running chunk

		for(auto i = downloads.begin(); i != downloads.end(); ++i) {
			Download* d = *i;
			
			// current chunk mustn't be already overlapped
			if(d->getOverlapped())
				continue;

			// current chunk must be running at least for 4 seconds
			if(d->getStart() == 0 || GET_TICK() - d->getStart() < 4000) 
				continue;

			// current chunk mustn't be finished in next 20 seconds
			if(d->getSecondsLeft() < 20)
				continue;

			// overlap current chunk at last block boundary
			int64_t pos = d->getPos() - (d->getPos() % blockSize);
			int64_t size = d->getSize() - pos;

			// new user should finish this chunk more than 2x faster
			int64_t newChunkLeft = size / lastSpeed;
			if(2 * newChunkLeft < d->getSecondsLeft()) {
				dcdebug("Overlapping... old user: %I64d s, new user: %I64d s\n", d->getSecondsLeft(), newChunkLeft);
				return Segment(d->getStartPos() + pos, size, true);
			}
		}
	}

	return Segment(0, 0);
}