mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-30 00:14:57 +00:00
Save torrents queue in separate file
This commit is contained in:
parent
e146c2f227
commit
68508ba657
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2015, 2018 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -39,18 +39,23 @@ ResumeDataSavingManager::ResumeDataSavingManager(const QString &resumeFolderPath
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResumeDataSavingManager::saveResumeData(QString infoHash, QByteArray data) const
|
void ResumeDataSavingManager::save(const QString &filename, const QByteArray &data) const
|
||||||
{
|
{
|
||||||
QString filename = QString("%1.fastresume").arg(infoHash);
|
const QString filepath = m_resumeDataDir.absoluteFilePath(filename);
|
||||||
QString filepath = m_resumeDataDir.absoluteFilePath(filename);
|
|
||||||
|
|
||||||
qDebug() << "Saving resume data in" << filepath;
|
QSaveFile file {filepath};
|
||||||
QSaveFile resumeFile(filepath);
|
if (file.open(QIODevice::WriteOnly)) {
|
||||||
if (resumeFile.open(QIODevice::WriteOnly)) {
|
file.write(data);
|
||||||
resumeFile.write(data);
|
if (!file.commit()) {
|
||||||
if (!resumeFile.commit()) {
|
Logger::instance()->addMessage(QString("Couldn't save data in '%1'. Error: %2")
|
||||||
Logger::instance()->addMessage(QString("Couldn't save resume data in %1. Error: %2")
|
.arg(filepath, file.errorString()), Log::WARNING);
|
||||||
.arg(filepath, resumeFile.errorString()), Log::WARNING);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResumeDataSavingManager::remove(const QString &filename) const
|
||||||
|
{
|
||||||
|
const QString filepath = m_resumeDataDir.absoluteFilePath(filename);
|
||||||
|
|
||||||
|
Utils::Fs::forceRemove(filepath);
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2015, 2018 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -26,8 +26,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef RESUMEDATASAVINGMANAGER_H
|
#pragma once
|
||||||
#define RESUMEDATASAVINGMANAGER_H
|
|
||||||
|
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
@ -36,15 +35,15 @@
|
|||||||
class ResumeDataSavingManager : public QObject
|
class ResumeDataSavingManager : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(ResumeDataSavingManager)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ResumeDataSavingManager(const QString &resumeFolderPath);
|
explicit ResumeDataSavingManager(const QString &resumeFolderPath);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void saveResumeData(QString infoHash, QByteArray data) const;
|
void save(const QString &filename, const QByteArray &data) const;
|
||||||
|
void remove(const QString &filename) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QDir m_resumeDataDir;
|
QDir m_resumeDataDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RESUMEDATASAVINGMANAGER_H
|
|
||||||
|
@ -69,6 +69,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "base/algorithm.h"
|
#include "base/algorithm.h"
|
||||||
|
#include "base/global.h"
|
||||||
#include "base/logger.h"
|
#include "base/logger.h"
|
||||||
#include "base/net/downloadhandler.h"
|
#include "base/net/downloadhandler.h"
|
||||||
#include "base/net/downloadmanager.h"
|
#include "base/net/downloadmanager.h"
|
||||||
@ -532,7 +533,7 @@ Session::Session(QObject *parent)
|
|||||||
connect(&m_networkManager, &QNetworkConfigurationManager::configurationChanged, this, &Session::networkConfigurationChange);
|
connect(&m_networkManager, &QNetworkConfigurationManager::configurationChanged, this, &Session::networkConfigurationChange);
|
||||||
|
|
||||||
m_ioThread = new QThread(this);
|
m_ioThread = new QThread(this);
|
||||||
m_resumeDataSavingManager = new ResumeDataSavingManager(m_resumeFolderPath);
|
m_resumeDataSavingManager = new ResumeDataSavingManager {m_resumeFolderPath};
|
||||||
m_resumeDataSavingManager->moveToThread(m_ioThread);
|
m_resumeDataSavingManager->moveToThread(m_ioThread);
|
||||||
connect(m_ioThread, &QThread::finished, m_resumeDataSavingManager, &QObject::deleteLater);
|
connect(m_ioThread, &QThread::finished, m_resumeDataSavingManager, &QObject::deleteLater);
|
||||||
m_ioThread->start();
|
m_ioThread->start();
|
||||||
@ -1978,8 +1979,8 @@ bool Session::cancelLoadMetadata(const InfoHash &hash)
|
|||||||
void Session::increaseTorrentsPriority(const QStringList &hashes)
|
void Session::increaseTorrentsPriority(const QStringList &hashes)
|
||||||
{
|
{
|
||||||
std::priority_queue<QPair<int, TorrentHandle *>,
|
std::priority_queue<QPair<int, TorrentHandle *>,
|
||||||
std::vector<QPair<int, TorrentHandle *> >,
|
std::vector<QPair<int, TorrentHandle *>>,
|
||||||
std::greater<QPair<int, TorrentHandle *> > > torrentQueue;
|
std::greater<QPair<int, TorrentHandle *>>> torrentQueue;
|
||||||
|
|
||||||
// Sort torrents by priority
|
// Sort torrents by priority
|
||||||
foreach (const InfoHash &hash, hashes) {
|
foreach (const InfoHash &hash, hashes) {
|
||||||
@ -1995,14 +1996,14 @@ void Session::increaseTorrentsPriority(const QStringList &hashes)
|
|||||||
torrentQueue.pop();
|
torrentQueue.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleTorrentsPrioritiesChanged();
|
saveTorrentsQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::decreaseTorrentsPriority(const QStringList &hashes)
|
void Session::decreaseTorrentsPriority(const QStringList &hashes)
|
||||||
{
|
{
|
||||||
std::priority_queue<QPair<int, TorrentHandle *>,
|
std::priority_queue<QPair<int, TorrentHandle *>,
|
||||||
std::vector<QPair<int, TorrentHandle *> >,
|
std::vector<QPair<int, TorrentHandle *>>,
|
||||||
std::less<QPair<int, TorrentHandle *> > > torrentQueue;
|
std::less<QPair<int, TorrentHandle *>>> torrentQueue;
|
||||||
|
|
||||||
// Sort torrents by priority
|
// Sort torrents by priority
|
||||||
foreach (const InfoHash &hash, hashes) {
|
foreach (const InfoHash &hash, hashes) {
|
||||||
@ -2021,14 +2022,14 @@ void Session::decreaseTorrentsPriority(const QStringList &hashes)
|
|||||||
for (auto i = m_loadedMetadata.cbegin(); i != m_loadedMetadata.cend(); ++i)
|
for (auto i = m_loadedMetadata.cbegin(); i != m_loadedMetadata.cend(); ++i)
|
||||||
torrentQueuePositionBottom(m_nativeSession->find_torrent(i.key()));
|
torrentQueuePositionBottom(m_nativeSession->find_torrent(i.key()));
|
||||||
|
|
||||||
handleTorrentsPrioritiesChanged();
|
saveTorrentsQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::topTorrentsPriority(const QStringList &hashes)
|
void Session::topTorrentsPriority(const QStringList &hashes)
|
||||||
{
|
{
|
||||||
std::priority_queue<QPair<int, TorrentHandle *>,
|
std::priority_queue<QPair<int, TorrentHandle *>,
|
||||||
std::vector<QPair<int, TorrentHandle *> >,
|
std::vector<QPair<int, TorrentHandle *>>,
|
||||||
std::greater<QPair<int, TorrentHandle *> > > torrentQueue;
|
std::greater<QPair<int, TorrentHandle *>>> torrentQueue;
|
||||||
|
|
||||||
// Sort torrents by priority
|
// Sort torrents by priority
|
||||||
foreach (const InfoHash &hash, hashes) {
|
foreach (const InfoHash &hash, hashes) {
|
||||||
@ -2044,14 +2045,14 @@ void Session::topTorrentsPriority(const QStringList &hashes)
|
|||||||
torrentQueue.pop();
|
torrentQueue.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleTorrentsPrioritiesChanged();
|
saveTorrentsQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::bottomTorrentsPriority(const QStringList &hashes)
|
void Session::bottomTorrentsPriority(const QStringList &hashes)
|
||||||
{
|
{
|
||||||
std::priority_queue<QPair<int, TorrentHandle *>,
|
std::priority_queue<QPair<int, TorrentHandle *>,
|
||||||
std::vector<QPair<int, TorrentHandle *> >,
|
std::vector<QPair<int, TorrentHandle *>>,
|
||||||
std::less<QPair<int, TorrentHandle *> > > torrentQueue;
|
std::less<QPair<int, TorrentHandle *>>> torrentQueue;
|
||||||
|
|
||||||
// Sort torrents by priority
|
// Sort torrents by priority
|
||||||
foreach (const InfoHash &hash, hashes) {
|
foreach (const InfoHash &hash, hashes) {
|
||||||
@ -2070,7 +2071,7 @@ void Session::bottomTorrentsPriority(const QStringList &hashes)
|
|||||||
for (auto i = m_loadedMetadata.cbegin(); i != m_loadedMetadata.cend(); ++i)
|
for (auto i = m_loadedMetadata.cbegin(); i != m_loadedMetadata.cend(); ++i)
|
||||||
torrentQueuePositionBottom(m_nativeSession->find_torrent(i.key()));
|
torrentQueuePositionBottom(m_nativeSession->find_torrent(i.key()));
|
||||||
|
|
||||||
handleTorrentsPrioritiesChanged();
|
saveTorrentsQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<InfoHash, TorrentHandle *> Session::torrents() const
|
QHash<InfoHash, TorrentHandle *> Session::torrents() const
|
||||||
@ -2379,11 +2380,13 @@ void Session::generateResumeData(bool final)
|
|||||||
// Called on exit
|
// Called on exit
|
||||||
void Session::saveResumeData()
|
void Session::saveResumeData()
|
||||||
{
|
{
|
||||||
qDebug("Saving fast resume data...");
|
qDebug("Saving resume data...");
|
||||||
|
|
||||||
// Pause session
|
// Pause session
|
||||||
m_nativeSession->pause();
|
m_nativeSession->pause();
|
||||||
|
|
||||||
|
if (isQueueingSystemEnabled())
|
||||||
|
saveTorrentsQueue();
|
||||||
generateResumeData(true);
|
generateResumeData(true);
|
||||||
|
|
||||||
while (m_numResumeData > 0) {
|
while (m_numResumeData > 0) {
|
||||||
@ -2408,6 +2411,31 @@ void Session::saveResumeData()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Session::saveTorrentsQueue()
|
||||||
|
{
|
||||||
|
QMap<int, QString> queue; // Use QMap since it should be ordered by key
|
||||||
|
for (const TorrentHandle *torrent : copyAsConst(torrents())) {
|
||||||
|
// We require actual (non-cached) queue position here!
|
||||||
|
const int queuePos = torrent->nativeHandle().queue_position();
|
||||||
|
if (queuePos >= 0)
|
||||||
|
queue[queuePos] = torrent->hash();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray data;
|
||||||
|
for (const QString &hash : qAsConst(queue))
|
||||||
|
data += (hash.toLatin1() + '\n');
|
||||||
|
|
||||||
|
const QString filename = QLatin1String {"queue"};
|
||||||
|
QMetaObject::invokeMethod(m_resumeDataSavingManager, "save"
|
||||||
|
, Q_ARG(QString, filename), Q_ARG(QByteArray, data));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Session::removeTorrentsQueue()
|
||||||
|
{
|
||||||
|
const QString filename = QLatin1String {"queue"};
|
||||||
|
QMetaObject::invokeMethod(m_resumeDataSavingManager, "remove", Q_ARG(QString, filename));
|
||||||
|
}
|
||||||
|
|
||||||
void Session::setDefaultSavePath(QString path)
|
void Session::setDefaultSavePath(QString path)
|
||||||
{
|
{
|
||||||
path = normalizeSavePath(path);
|
path = normalizeSavePath(path);
|
||||||
@ -3213,6 +3241,11 @@ void Session::setQueueingSystemEnabled(bool enabled)
|
|||||||
if (enabled != m_isQueueingEnabled) {
|
if (enabled != m_isQueueingEnabled) {
|
||||||
m_isQueueingEnabled = enabled;
|
m_isQueueingEnabled = enabled;
|
||||||
configureDeferred();
|
configureDeferred();
|
||||||
|
|
||||||
|
if (enabled)
|
||||||
|
saveTorrentsQueue();
|
||||||
|
else
|
||||||
|
removeTorrentsQueue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3543,18 +3576,6 @@ void Session::handleTorrentShareLimitChanged(TorrentHandle *const torrent)
|
|||||||
updateSeedingLimitTimer();
|
updateSeedingLimitTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentsPrioritiesChanged()
|
|
||||||
{
|
|
||||||
// Save fastresume for the torrents that changed queue position
|
|
||||||
for (TorrentHandle *const torrent : torrents()) {
|
|
||||||
if (!torrent->isSeed()) {
|
|
||||||
// cached vs actual queue position, qBt starts queue at 1
|
|
||||||
if (torrent->queuePosition() != (torrent->nativeHandle().queue_position() + 1))
|
|
||||||
saveTorrentResumeData(torrent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Session::saveTorrentResumeData(TorrentHandle *const torrent)
|
void Session::saveTorrentResumeData(TorrentHandle *const torrent)
|
||||||
{
|
{
|
||||||
qDebug("Saving fastresume data for %s", qUtf8Printable(torrent->name()));
|
qDebug("Saving fastresume data for %s", qUtf8Printable(torrent->name()));
|
||||||
@ -3677,11 +3698,8 @@ void Session::handleTorrentChecked(TorrentHandle *const torrent)
|
|||||||
|
|
||||||
void Session::handleTorrentFinished(TorrentHandle *const torrent)
|
void Session::handleTorrentFinished(TorrentHandle *const torrent)
|
||||||
{
|
{
|
||||||
if (!torrent->hasError() && !torrent->hasMissingFiles()) {
|
if (!torrent->hasError() && !torrent->hasMissingFiles())
|
||||||
saveTorrentResumeData(torrent);
|
saveTorrentResumeData(torrent);
|
||||||
if (isQueueingSystemEnabled())
|
|
||||||
handleTorrentsPrioritiesChanged();
|
|
||||||
}
|
|
||||||
emit torrentFinished(torrent);
|
emit torrentFinished(torrent);
|
||||||
|
|
||||||
qDebug("Checking if the torrent contains torrent files to download");
|
qDebug("Checking if the torrent contains torrent files to download");
|
||||||
@ -3724,8 +3742,9 @@ void Session::handleTorrentResumeDataReady(TorrentHandle *const torrent, const l
|
|||||||
QByteArray out;
|
QByteArray out;
|
||||||
libt::bencode(std::back_inserter(out), data);
|
libt::bencode(std::back_inserter(out), data);
|
||||||
|
|
||||||
QMetaObject::invokeMethod(m_resumeDataSavingManager, "saveResumeData",
|
const QString filename = QString("%1.fastresume").arg(torrent->hash());
|
||||||
Q_ARG(QString, torrent->hash()), Q_ARG(QByteArray, out));
|
QMetaObject::invokeMethod(m_resumeDataSavingManager, "save",
|
||||||
|
Q_ARG(QString, filename), Q_ARG(QByteArray, out));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentResumeDataFailed(TorrentHandle *const torrent)
|
void Session::handleTorrentResumeDataFailed(TorrentHandle *const torrent)
|
||||||
@ -3894,56 +3913,97 @@ void Session::startUpTorrents()
|
|||||||
++resumedTorrentsCount;
|
++resumedTorrentsCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
qDebug("Starting up torrents");
|
qDebug("Starting up torrents...");
|
||||||
qDebug("Queue size: %d", fastresumes.size());
|
qDebug("Queue size: %d", fastresumes.size());
|
||||||
// Resume downloads
|
|
||||||
QMap<int, TorrentResumeData> queuedResumeData;
|
|
||||||
int nextQueuePosition = 1;
|
|
||||||
int numOfRemappedFiles = 0;
|
|
||||||
const QRegularExpression rx(QLatin1String("^([A-Fa-f0-9]{40})\\.fastresume$"));
|
const QRegularExpression rx(QLatin1String("^([A-Fa-f0-9]{40})\\.fastresume$"));
|
||||||
foreach (const QString &fastresumeName, fastresumes) {
|
|
||||||
|
if (isQueueingSystemEnabled()) {
|
||||||
|
QFile queueFile {resumeDataDir.absoluteFilePath(QLatin1String {"queue"})};
|
||||||
|
|
||||||
|
// TODO: The following code is deprecated in 4.1.5. Remove after several releases in 4.2.x.
|
||||||
|
// === BEGIN DEPRECATED CODE === //
|
||||||
|
if (!queueFile.exists()) {
|
||||||
|
// Resume downloads in a legacy manner
|
||||||
|
QMap<int, TorrentResumeData> queuedResumeData;
|
||||||
|
int nextQueuePosition = 1;
|
||||||
|
int numOfRemappedFiles = 0;
|
||||||
|
foreach (const QString &fastresumeName, fastresumes) {
|
||||||
|
const QRegularExpressionMatch rxMatch = rx.match(fastresumeName);
|
||||||
|
if (!rxMatch.hasMatch()) continue;
|
||||||
|
|
||||||
|
QString hash = rxMatch.captured(1);
|
||||||
|
QString fastresumePath = resumeDataDir.absoluteFilePath(fastresumeName);
|
||||||
|
QByteArray data;
|
||||||
|
CreateTorrentParams torrentParams;
|
||||||
|
MagnetUri magnetUri;
|
||||||
|
int queuePosition;
|
||||||
|
if (readFile(fastresumePath, data) && loadTorrentResumeData(data, torrentParams, queuePosition, magnetUri)) {
|
||||||
|
if (queuePosition <= nextQueuePosition) {
|
||||||
|
startupTorrent({ hash, magnetUri, torrentParams, data });
|
||||||
|
|
||||||
|
if (queuePosition == nextQueuePosition) {
|
||||||
|
++nextQueuePosition;
|
||||||
|
while (queuedResumeData.contains(nextQueuePosition)) {
|
||||||
|
startupTorrent(queuedResumeData.take(nextQueuePosition));
|
||||||
|
++nextQueuePosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int q = queuePosition;
|
||||||
|
for (; queuedResumeData.contains(q); ++q) {}
|
||||||
|
if (q != queuePosition)
|
||||||
|
++numOfRemappedFiles;
|
||||||
|
queuedResumeData[q] = {hash, magnetUri, torrentParams, data};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numOfRemappedFiles > 0) {
|
||||||
|
logger->addMessage(
|
||||||
|
QString(tr("Queue positions were corrected in %1 resume files")).arg(numOfRemappedFiles),
|
||||||
|
Log::CRITICAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// starting up downloading torrents (queue position > 0)
|
||||||
|
foreach (const TorrentResumeData &torrentResumeData, queuedResumeData)
|
||||||
|
startupTorrent(torrentResumeData);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// === END DEPRECATED CODE === //
|
||||||
|
|
||||||
|
QStringList queue;
|
||||||
|
if (queueFile.open(QFile::ReadOnly)) {
|
||||||
|
QByteArray line;
|
||||||
|
while (!(line = queueFile.readLine()).isEmpty())
|
||||||
|
queue.append(QString::fromLatin1(line.trimmed()) + QLatin1String {".fastresume"});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LogMsg(tr("Couldn't load torrents queue from '%1'. Error: %2")
|
||||||
|
.arg(queueFile.fileName(), queueFile.errorString()), Log::WARNING);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!queue.empty())
|
||||||
|
fastresumes = queue + fastresumes.toSet().subtract(queue.toSet()).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const QString &fastresumeName : qAsConst(fastresumes)) {
|
||||||
const QRegularExpressionMatch rxMatch = rx.match(fastresumeName);
|
const QRegularExpressionMatch rxMatch = rx.match(fastresumeName);
|
||||||
if (!rxMatch.hasMatch()) continue;
|
if (!rxMatch.hasMatch()) continue;
|
||||||
|
|
||||||
QString hash = rxMatch.captured(1);
|
const QString hash = rxMatch.captured(1);
|
||||||
QString fastresumePath = resumeDataDir.absoluteFilePath(fastresumeName);
|
const QString fastresumePath = resumeDataDir.absoluteFilePath(fastresumeName);
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
CreateTorrentParams torrentParams;
|
CreateTorrentParams torrentParams;
|
||||||
MagnetUri magnetUri;
|
MagnetUri magnetUri;
|
||||||
int queuePosition;
|
int queuePosition;
|
||||||
if (readFile(fastresumePath, data) && loadTorrentResumeData(data, torrentParams, queuePosition, magnetUri)) {
|
if (readFile(fastresumePath, data)
|
||||||
if (queuePosition <= nextQueuePosition) {
|
&& loadTorrentResumeData(data, torrentParams, queuePosition, magnetUri)) {
|
||||||
startupTorrent({ hash, magnetUri, torrentParams, data });
|
startupTorrent({hash, magnetUri, torrentParams, data});
|
||||||
|
|
||||||
if (queuePosition == nextQueuePosition) {
|
|
||||||
++nextQueuePosition;
|
|
||||||
while (queuedResumeData.contains(nextQueuePosition)) {
|
|
||||||
startupTorrent(queuedResumeData.take(nextQueuePosition));
|
|
||||||
++nextQueuePosition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int q = queuePosition;
|
|
||||||
for (; queuedResumeData.contains(q); ++q) {
|
|
||||||
}
|
|
||||||
if (q != queuePosition) {
|
|
||||||
++numOfRemappedFiles;
|
|
||||||
}
|
|
||||||
queuedResumeData[q] = {hash, magnetUri, torrentParams, data};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numOfRemappedFiles > 0) {
|
|
||||||
logger->addMessage(
|
|
||||||
QString(tr("Queue positions were corrected in %1 resume files")).arg(numOfRemappedFiles),
|
|
||||||
Log::CRITICAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// starting up downloading torrents (queue position > 0)
|
|
||||||
foreach (const TorrentResumeData &torrentResumeData, queuedResumeData)
|
|
||||||
startupTorrent(torrentResumeData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
quint64 Session::getAlltimeDL() const
|
quint64 Session::getAlltimeDL() const
|
||||||
|
@ -481,7 +481,6 @@ namespace BitTorrent
|
|||||||
|
|
||||||
// TorrentHandle interface
|
// TorrentHandle interface
|
||||||
void handleTorrentShareLimitChanged(TorrentHandle *const torrent);
|
void handleTorrentShareLimitChanged(TorrentHandle *const torrent);
|
||||||
void handleTorrentsPrioritiesChanged();
|
|
||||||
void handleTorrentNameChanged(TorrentHandle *const torrent);
|
void handleTorrentNameChanged(TorrentHandle *const torrent);
|
||||||
void handleTorrentSavePathChanged(TorrentHandle *const torrent);
|
void handleTorrentSavePathChanged(TorrentHandle *const torrent);
|
||||||
void handleTorrentCategoryChanged(TorrentHandle *const torrent, const QString &oldCategory);
|
void handleTorrentCategoryChanged(TorrentHandle *const torrent, const QString &oldCategory);
|
||||||
@ -633,6 +632,8 @@ namespace BitTorrent
|
|||||||
void createTorrentHandle(const libtorrent::torrent_handle &nativeHandle);
|
void createTorrentHandle(const libtorrent::torrent_handle &nativeHandle);
|
||||||
|
|
||||||
void saveResumeData();
|
void saveResumeData();
|
||||||
|
void saveTorrentsQueue();
|
||||||
|
void removeTorrentsQueue();
|
||||||
|
|
||||||
#if LIBTORRENT_VERSION_NUM < 10100
|
#if LIBTORRENT_VERSION_NUM < 10100
|
||||||
void dispatchAlerts(libtorrent::alert *alertPtr);
|
void dispatchAlerts(libtorrent::alert *alertPtr);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user