Merge pull request #16659 from glassez/backport

Backport changes to v4.4.x branch
This commit is contained in:
Vladimir Golovnev 2022-03-18 16:16:07 +03:00 committed by GitHub
commit 0ab10ef2b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 76 additions and 46 deletions

View file

@ -4422,54 +4422,62 @@ void Session::startUpTorrents()
const lt::info_hash_t infoHash = (resumeData.ltAddTorrentParams.ti
? resumeData.ltAddTorrentParams.ti->info_hashes()
: resumeData.ltAddTorrentParams.info_hashes);
if (infoHash.has_v1() && infoHash.has_v2())
const bool isHybrid = infoHash.has_v1() && infoHash.has_v2();
const auto torrentIDv2 = TorrentID::fromInfoHash(infoHash);
const auto torrentIDv1 = TorrentID::fromInfoHash(lt::info_hash_t(infoHash.v1));
if (torrentID == torrentIDv1)
{
const auto torrentIDv1 = TorrentID::fromInfoHash(lt::info_hash_t(infoHash.v1));
const auto torrentIDv2 = TorrentID::fromInfoHash(infoHash);
if (torrentID == torrentIDv1)
if (isHybrid && indexedTorrents.contains(torrentIDv2))
{
if (indexedTorrents.contains(torrentIDv2))
// if we don't have metadata, try to find it in alternative "resume data"
if (!resumeData.ltAddTorrentParams.ti)
{
// if we has no metadata trying to find it in alternative "resume data"
if (!resumeData.ltAddTorrentParams.ti)
{
const std::optional<LoadTorrentParams> loadAltResumeDataResult = startupStorage->load(torrentIDv2);
if (loadAltResumeDataResult)
{
LoadTorrentParams altResumeData = *loadAltResumeDataResult;
resumeData.ltAddTorrentParams.ti = altResumeData.ltAddTorrentParams.ti;
}
}
// remove alternative "resume data" and skip the attempt to load it
m_resumeDataStorage->remove(torrentIDv2);
skippedIDs.insert(torrentIDv2);
const std::optional<LoadTorrentParams> loadAltResumeDataResult = startupStorage->load(torrentIDv2);
if (loadAltResumeDataResult)
resumeData.ltAddTorrentParams.ti = loadAltResumeDataResult->ltAddTorrentParams.ti;
}
}
else
{
torrentID = torrentIDv1;
needStore = true;
// remove alternative "resume data" and skip the attempt to load it
m_resumeDataStorage->remove(torrentIDv2);
skippedIDs.insert(torrentIDv2);
}
}
else if (torrentID == torrentIDv2)
{
torrentID = torrentIDv1;
needStore = true;
m_resumeDataStorage->remove(torrentIDv2);
if (indexedTorrents.contains(torrentID))
if (indexedTorrents.contains(torrentID))
{
skippedIDs.insert(torrentID);
const std::optional<LoadTorrentParams> loadPreferredResumeDataResult = startupStorage->load(torrentID);
if (loadPreferredResumeDataResult)
{
skippedIDs.insert(torrentID);
const std::optional<LoadTorrentParams> loadPreferredResumeDataResult = startupStorage->load(torrentID);
if (loadPreferredResumeDataResult)
{
LoadTorrentParams preferredResumeData = *loadPreferredResumeDataResult;
std::shared_ptr<lt::torrent_info> ti = resumeData.ltAddTorrentParams.ti;
if (!preferredResumeData.ltAddTorrentParams.ti)
preferredResumeData.ltAddTorrentParams.ti = ti;
resumeData = preferredResumeData;
}
std::shared_ptr<lt::torrent_info> ti = resumeData.ltAddTorrentParams.ti;
resumeData = *loadPreferredResumeDataResult;
if (!resumeData.ltAddTorrentParams.ti)
resumeData.ltAddTorrentParams.ti = ti;
}
}
}
else
{
LogMsg(tr("Failed to resume torrent: inconsistent torrent ID is detected. Torrent: \"%1\"")
.arg(torrentID.toString()), Log::WARNING);
continue;
}
#else
const lt::sha1_hash infoHash = (resumeData.ltAddTorrentParams.ti
? resumeData.ltAddTorrentParams.ti->info_hash()
: resumeData.ltAddTorrentParams.info_hash);
if (torrentID != TorrentID::fromInfoHash(infoHash))
{
LogMsg(tr("Failed to resume torrent: inconsistent torrent ID is detected. Torrent: \"%1\"")
.arg(torrentID.toString()), Log::WARNING);
continue;
}
#endif
if (m_resumeDataStorage != startupStorage)

View file

@ -236,6 +236,14 @@ namespace
status.pieces = params.have_pieces;
status.verified_pieces = params.verified_pieces;
}
template <typename Vector>
Vector resized(const Vector &inVector, const typename Vector::size_type size, const typename Vector::value_type &defaultValue)
{
Vector outVector = inVector;
outVector.resize(size, defaultValue);
return outVector;
}
}
// TorrentImpl
@ -1504,27 +1512,22 @@ void TorrentImpl::fileSearchFinished(const QString &savePath, const QStringList
void TorrentImpl::endReceivedMetadataHandling(const QString &savePath, const QStringList &fileNames)
{
Q_ASSERT(m_filePaths.isEmpty());
Q_ASSERT(m_indexMap.isEmpty());
lt::add_torrent_params &p = m_ltAddTorrentParams;
const std::shared_ptr<lt::torrent_info> metadata = std::const_pointer_cast<lt::torrent_info>(m_nativeHandle.torrent_file());
m_torrentInfo = TorrentInfo(*metadata);
m_filePaths = fileNames;
m_indexMap.reserve(filesCount());
const auto nativeIndexes = m_torrentInfo.nativeIndexes();
for (int i = 0; i < fileNames.size(); ++i)
{
const auto nativeIndex = nativeIndexes.at(i);
m_indexMap[nativeIndex] = i;
p.renamed_files[nativeIndex] = fileNames[i].toStdString();
}
p.save_path = Utils::Fs::toNativePath(savePath).toStdString();
p.ti = metadata;
const int internalFilesCount = p.ti->files().num_files(); // including .pad files
// Use qBittorrent default priority rather than libtorrent's (4)
p.file_priorities = std::vector(internalFilesCount, LT::toNative(DownloadPriority::Normal));
p.file_priorities = resized(p.file_priorities, metadata->files().num_files()
, LT::toNative(p.file_priorities.empty() ? DownloadPriority::Normal : DownloadPriority::Ignored));
reload();
@ -1566,7 +1569,8 @@ void TorrentImpl::reload()
}
m_nativeHandle = m_nativeSession->add_torrent(p);
m_nativeHandle.queue_position_set(queuePos);
if (queuePos >= lt::queue_position_t {})
m_nativeHandle.queue_position_set(queuePos);
}
void TorrentImpl::pause()
@ -1781,6 +1785,8 @@ void TorrentImpl::handleSaveResumeDataAlert(const lt::save_resume_data_alert *p)
{
if (m_maintenanceJob == MaintenanceJob::HandleMetadata)
{
Q_ASSERT(m_indexMap.isEmpty());
m_ltAddTorrentParams = p->params;
m_ltAddTorrentParams.have_pieces.clear();
@ -1790,6 +1796,19 @@ void TorrentImpl::handleSaveResumeDataAlert(const lt::save_resume_data_alert *p)
QStringList filePaths = metadata.filePaths();
applyContentLayout(filePaths, m_contentLayout);
const auto nativeIndexes = metadata.nativeIndexes();
const auto &renamedFiles = m_ltAddTorrentParams.renamed_files;
m_indexMap.reserve(filePaths.size());
for (int i = 0; i < filePaths.size(); ++i)
{
const auto nativeIndex = nativeIndexes.at(i);
m_indexMap[nativeIndex] = i;
if (const auto it = renamedFiles.find(nativeIndex); it != renamedFiles.cend())
filePaths[i] = QString::fromStdString(it->second);
}
m_session->findIncompleteFiles(metadata, savePath(), downloadPath(), filePaths);
}
else
@ -1929,6 +1948,9 @@ void TorrentImpl::handleFileRenameFailedAlert(const lt::file_rename_failed_alert
void TorrentImpl::handleFileCompletedAlert(const lt::file_completed_alert *p)
{
if (m_maintenanceJob == MaintenanceJob::HandleMetadata)
return;
if (m_session->isAppendExtensionEnabled())
{
const int fileIndex = m_indexMap.value(p->index, -1);