Store hybrid torrents using legacy filenames

* Make Digest32 implicitly shared class
* Store hybrid torrents using legacy filenames

PR #16237.
This commit is contained in:
Vladimir Golovnev
2022-01-25 08:22:35 +03:00
committed by GitHub
parent 270e2023cd
commit e93c360db6
4 changed files with 152 additions and 56 deletions

View File

@@ -291,6 +291,20 @@ namespace
return {};
}
#endif
TorrentID resumeDataID(const BitTorrent::Torrent *torrent)
{
#ifdef QBT_USES_LIBTORRENT2
// use legacy ID to store hybrid torrent
const InfoHash infoHash = torrent->infoHash();
const TorrentID id = ((infoHash.v1().isValid() && infoHash.v2().isValid())
? InfoHash(infoHash.v1(), SHA256Hash()).toTorrentID()
: torrent->id());
#else
const TorrentID id = torrent->id();
#endif
return id;
}
}
const int addTorrentParamsId = qRegisterMetaType<AddTorrentParams>();
@@ -1841,7 +1855,7 @@ bool Session::deleteTorrent(const TorrentID &id, const DeleteOption deleteOption
}
// Remove it from torrent resume directory
m_resumeDataStorage->remove(torrent->id());
m_resumeDataStorage->remove(resumeDataID(torrent));
delete torrent;
return true;
@@ -4011,7 +4025,7 @@ void Session::handleTorrentResumeDataReady(TorrentImpl *const torrent, const Loa
{
--m_numResumeData;
m_resumeDataStorage->store(torrent->id(), data);
m_resumeDataStorage->store(resumeDataID(torrent), data);
}
void Session::handleTorrentTrackerReply(TorrentImpl *const torrent, const QString &trackerUrl)
@@ -4346,53 +4360,115 @@ void Session::startUpTorrents()
const QVector<TorrentID> torrents = startupStorage->registeredTorrents();
int resumedTorrentsCount = 0;
QVector<TorrentID> queue;
for (const TorrentID &torrentID : torrents)
#ifdef QBT_USES_LIBTORRENT2
const QSet<TorrentID> indexedTorrents {torrents.cbegin(), torrents.cend()};
QSet<TorrentID> skippedIDs;
#endif
for (TorrentID torrentID : torrents)
{
#ifdef QBT_USES_LIBTORRENT2
if (skippedIDs.contains(torrentID))
continue;
#endif
const std::optional<LoadTorrentParams> loadResumeDataResult = startupStorage->load(torrentID);
if (loadResumeDataResult)
{
LoadTorrentParams resumeData = *loadResumeDataResult;
bool needStore = false;
if (m_resumeDataStorage != startupStorage)
{
needStore = true;
if (isQueueingSystemEnabled() && !resumeData.hasSeedStatus)
queue.append(torrentID);
}
// TODO: Remove the following upgrade code in v4.5
// == BEGIN UPGRADE CODE ==
if (m_needUpgradeDownloadPath && isDownloadPathEnabled())
{
if (!resumeData.useAutoTMM)
{
resumeData.downloadPath = downloadPath();
needStore = true;
}
}
// == END UPGRADE CODE ==
if (needStore)
m_resumeDataStorage->store(torrentID, resumeData);
qDebug() << "Starting up torrent" << torrentID.toString() << "...";
if (!loadTorrent(resumeData))
{
LogMsg(tr("Unable to resume torrent '%1'.", "e.g: Unable to resume torrent 'hash'.")
.arg(torrentID.toString()), Log::CRITICAL);
}
// process add torrent messages before message queue overflow
if ((resumedTorrentsCount % 100) == 0) readAlerts();
++resumedTorrentsCount;
}
else
if (!loadResumeDataResult)
{
LogMsg(tr("Unable to resume torrent '%1'.", "e.g: Unable to resume torrent 'hash'.")
.arg(torrentID.toString()), Log::CRITICAL);
continue;
}
LoadTorrentParams resumeData = *loadResumeDataResult;
bool needStore = false;
#ifdef QBT_USES_LIBTORRENT2
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 auto torrentIDv1 = TorrentID::fromInfoHash(lt::info_hash_t(infoHash.v1));
const auto torrentIDv2 = TorrentID::fromInfoHash(infoHash);
if (torrentID == torrentIDv1)
{
if (indexedTorrents.contains(torrentIDv2))
{
// 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);
}
}
else
{
torrentID = torrentIDv1;
needStore = true;
m_resumeDataStorage->remove(torrentIDv2);
if (indexedTorrents.contains(torrentID))
{
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;
}
}
}
}
#endif
if (m_resumeDataStorage != startupStorage)
{
needStore = true;
if (isQueueingSystemEnabled() && !resumeData.hasSeedStatus)
queue.append(torrentID);
}
// TODO: Remove the following upgrade code in v4.5
// == BEGIN UPGRADE CODE ==
if (m_needUpgradeDownloadPath && isDownloadPathEnabled())
{
if (!resumeData.useAutoTMM)
{
resumeData.downloadPath = downloadPath();
needStore = true;
}
}
// == END UPGRADE CODE ==
if (needStore)
m_resumeDataStorage->store(torrentID, resumeData);
qDebug() << "Starting up torrent" << torrentID.toString() << "...";
if (!loadTorrent(resumeData))
{
LogMsg(tr("Unable to resume torrent '%1'.", "e.g: Unable to resume torrent 'hash'.")
.arg(torrentID.toString()), Log::CRITICAL);
}
// process add torrent messages before message queue overflow
if ((resumedTorrentsCount % 100) == 0) readAlerts();
++resumedTorrentsCount;
}
if (m_resumeDataStorage != startupStorage)
@@ -4610,7 +4686,7 @@ void Session::createTorrent(const lt::torrent_handle &nativeHandle)
}
else
{
m_resumeDataStorage->store(torrent->id(), params);
m_resumeDataStorage->store(resumeDataID(torrent), params);
// The following is useless for newly added magnet
if (hasMetadata)