Improve "info hash" handling

Define "torrent ID" concept, which is either a SHA1 hash for torrents of version 1,
or a SHA256 hash (truncated to SHA1 hash length) for torrents of version 2.
Add support for native libtorrent2 info hashes.
This commit is contained in:
Vladimir Golovnev (Glassez) 2021-03-05 12:43:58 +03:00 committed by sledgehammer999
parent c2ccc9dfa4
commit 437b51b3a5
No known key found for this signature in database
GPG key ID: 6E4A2D025B7CC9A2
34 changed files with 463 additions and 320 deletions

View file

@ -1616,7 +1616,7 @@ void Session::processShareLimits()
// We shouldn't iterate over `m_torrents` in the loop below
// since `deleteTorrent()` modifies it indirectly
const QHash<InfoHash, TorrentImpl *> torrents {m_torrents};
const QHash<TorrentID, TorrentImpl *> torrents {m_torrents};
for (TorrentImpl *const torrent : torrents)
{
if (torrent->isSeed() && !torrent->isForced())
@ -1638,12 +1638,12 @@ void Session::processShareLimits()
if (m_maxRatioAction == Remove)
{
LogMsg(tr("'%1' reached the maximum ratio you set. Removed.").arg(torrent->name()));
deleteTorrent(torrent->hash());
deleteTorrent(torrent->id());
}
else if (m_maxRatioAction == DeleteFiles)
{
LogMsg(tr("'%1' reached the maximum ratio you set. Removed torrent and its files.").arg(torrent->name()));
deleteTorrent(torrent->hash(), DeleteTorrentAndFiles);
deleteTorrent(torrent->id(), DeleteTorrentAndFiles);
}
else if ((m_maxRatioAction == Pause) && !torrent->isPaused())
{
@ -1677,12 +1677,12 @@ void Session::processShareLimits()
if (m_maxRatioAction == Remove)
{
LogMsg(tr("'%1' reached the maximum seeding time you set. Removed.").arg(torrent->name()));
deleteTorrent(torrent->hash());
deleteTorrent(torrent->id());
}
else if (m_maxRatioAction == DeleteFiles)
{
LogMsg(tr("'%1' reached the maximum seeding time you set. Removed torrent and its files.").arg(torrent->name()));
deleteTorrent(torrent->hash(), DeleteTorrentAndFiles);
deleteTorrent(torrent->id(), DeleteTorrentAndFiles);
}
else if ((m_maxRatioAction == Pause) && !torrent->isPaused())
{
@ -1719,7 +1719,7 @@ void Session::handleDownloadFinished(const Net::DownloadResult &result)
}
}
void Session::fileSearchFinished(const InfoHash &id, const QString &savePath, const QStringList &fileNames)
void Session::fileSearchFinished(const TorrentID &id, const QString &savePath, const QStringList &fileNames)
{
TorrentImpl *torrent = m_torrents.value(id);
if (torrent)
@ -1745,9 +1745,9 @@ void Session::fileSearchFinished(const InfoHash &id, const QString &savePath, co
}
// Return the torrent handle, given its hash
Torrent *Session::findTorrent(const InfoHash &hash) const
Torrent *Session::findTorrent(const TorrentID &id) const
{
return m_torrents.value(hash);
return m_torrents.value(id);
}
bool Session::hasActiveTorrents() const
@ -1795,18 +1795,18 @@ void Session::banIP(const QString &ip)
// Delete a torrent from the session, given its hash
// and from the disk, if the corresponding deleteOption is chosen
bool Session::deleteTorrent(const InfoHash &hash, const DeleteOption deleteOption)
bool Session::deleteTorrent(const TorrentID &id, const DeleteOption deleteOption)
{
TorrentImpl *const torrent = m_torrents.take(hash);
TorrentImpl *const torrent = m_torrents.take(id);
if (!torrent) return false;
qDebug("Deleting torrent with hash: %s", qUtf8Printable(torrent->hash().toString()));
qDebug("Deleting torrent with ID: %s", qUtf8Printable(torrent->id().toString()));
emit torrentAboutToBeRemoved(torrent);
// Remove it from session
if (deleteOption == DeleteTorrent)
{
m_removingTorrents[torrent->hash()] = {torrent->name(), "", deleteOption};
m_removingTorrents[torrent->id()] = {torrent->name(), "", deleteOption};
const lt::torrent_handle nativeHandle {torrent->nativeHandle()};
const auto iter = std::find_if(m_moveStorageQueue.begin(), m_moveStorageQueue.end()
@ -1835,7 +1835,7 @@ bool Session::deleteTorrent(const InfoHash &hash, const DeleteOption deleteOptio
rootPath = torrent->actualStorageLocation();
}
m_removingTorrents[torrent->hash()] = {torrent->name(), rootPath, deleteOption};
m_removingTorrents[torrent->id()] = {torrent->name(), rootPath, deleteOption};
if (m_moveStorageQueue.size() > 1)
{
@ -1854,8 +1854,8 @@ bool Session::deleteTorrent(const InfoHash &hash, const DeleteOption deleteOptio
}
// Remove it from torrent resume directory
const QString resumedataFile = QString::fromLatin1("%1.fastresume").arg(torrent->hash().toString());
const QString metadataFile = QString::fromLatin1("%1.torrent").arg(torrent->hash().toString());
const QString resumedataFile = QString::fromLatin1("%1.fastresume").arg(torrent->id().toString());
const QString metadataFile = QString::fromLatin1("%1.torrent").arg(torrent->id().toString());
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
QMetaObject::invokeMethod(m_resumeDataSavingManager, [this, resumedataFile, metadataFile]()
{
@ -1871,19 +1871,19 @@ bool Session::deleteTorrent(const InfoHash &hash, const DeleteOption deleteOptio
return true;
}
bool Session::cancelDownloadMetadata(const InfoHash &hash)
bool Session::cancelDownloadMetadata(const TorrentID &id)
{
const auto downloadedMetadataIter = m_downloadedMetadata.find(hash);
const auto downloadedMetadataIter = m_downloadedMetadata.find(id);
if (downloadedMetadataIter == m_downloadedMetadata.end()) return false;
m_downloadedMetadata.erase(downloadedMetadataIter);
--m_extraLimit;
adjustLimits();
m_nativeSession->remove_torrent(m_nativeSession->find_torrent(hash), lt::session::delete_files);
m_nativeSession->remove_torrent(m_nativeSession->find_torrent(id), lt::session::delete_files);
return true;
}
void Session::increaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
void Session::increaseTorrentsQueuePos(const QVector<TorrentID> &ids)
{
using ElementType = std::pair<int, const TorrentImpl *>;
std::priority_queue<ElementType
@ -1891,9 +1891,9 @@ void Session::increaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
, std::greater<ElementType>> torrentQueue;
// Sort torrents by queue position
for (const InfoHash &infoHash : hashes)
for (const TorrentID &id : ids)
{
const TorrentImpl *torrent = m_torrents.value(infoHash);
const TorrentImpl *torrent = m_torrents.value(id);
if (!torrent) continue;
if (const int position = torrent->queuePosition(); position >= 0)
torrentQueue.emplace(position, torrent);
@ -1910,15 +1910,15 @@ void Session::increaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
saveTorrentsQueue();
}
void Session::decreaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
void Session::decreaseTorrentsQueuePos(const QVector<TorrentID> &ids)
{
using ElementType = std::pair<int, const TorrentImpl *>;
std::priority_queue<ElementType> torrentQueue;
// Sort torrents by queue position
for (const InfoHash &infoHash : hashes)
for (const TorrentID &id : ids)
{
const TorrentImpl *torrent = m_torrents.value(infoHash);
const TorrentImpl *torrent = m_torrents.value(id);
if (!torrent) continue;
if (const int position = torrent->queuePosition(); position >= 0)
torrentQueue.emplace(position, torrent);
@ -1938,15 +1938,15 @@ void Session::decreaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
saveTorrentsQueue();
}
void Session::topTorrentsQueuePos(const QVector<InfoHash> &hashes)
void Session::topTorrentsQueuePos(const QVector<TorrentID> &ids)
{
using ElementType = std::pair<int, const TorrentImpl *>;
std::priority_queue<ElementType> torrentQueue;
// Sort torrents by queue position
for (const InfoHash &infoHash : hashes)
for (const TorrentID &id : ids)
{
const TorrentImpl *torrent = m_torrents.value(infoHash);
const TorrentImpl *torrent = m_torrents.value(id);
if (!torrent) continue;
if (const int position = torrent->queuePosition(); position >= 0)
torrentQueue.emplace(position, torrent);
@ -1963,7 +1963,7 @@ void Session::topTorrentsQueuePos(const QVector<InfoHash> &hashes)
saveTorrentsQueue();
}
void Session::bottomTorrentsQueuePos(const QVector<InfoHash> &hashes)
void Session::bottomTorrentsQueuePos(const QVector<TorrentID> &ids)
{
using ElementType = std::pair<int, const TorrentImpl *>;
std::priority_queue<ElementType
@ -1971,9 +1971,9 @@ void Session::bottomTorrentsQueuePos(const QVector<InfoHash> &hashes)
, std::greater<ElementType>> torrentQueue;
// Sort torrents by queue position
for (const InfoHash &infoHash : hashes)
for (const TorrentID &id : ids)
{
const TorrentImpl *torrent = m_torrents.value(infoHash);
const TorrentImpl *torrent = m_torrents.value(id);
if (!torrent) continue;
if (const int position = torrent->queuePosition(); position >= 0)
torrentQueue.emplace(position, torrent);
@ -2088,20 +2088,20 @@ bool Session::addTorrent_impl(const std::variant<MagnetUri, TorrentInfo> &source
const bool hasMetadata = std::holds_alternative<TorrentInfo>(source);
TorrentInfo metadata = (hasMetadata ? std::get<TorrentInfo>(source) : TorrentInfo {});
const MagnetUri &magnetUri = (hasMetadata ? MagnetUri {} : std::get<MagnetUri>(source));
const InfoHash hash = (hasMetadata ? metadata.hash() : magnetUri.hash());
const auto id = TorrentID::fromInfoHash(hasMetadata ? metadata.infoHash() : magnetUri.infoHash());
// It looks illogical that we don't just use an existing handle,
// but as previous experience has shown, it actually creates unnecessary
// problems and unwanted behavior due to the fact that it was originally
// added with parameters other than those provided by the user.
cancelDownloadMetadata(hash);
cancelDownloadMetadata(id);
// We should not add the torrent if it is already
// processed or is pending to add to session
if (m_loadingTorrents.contains(hash))
if (m_loadingTorrents.contains(id))
return false;
TorrentImpl *const torrent = m_torrents.value(hash);
TorrentImpl *const torrent = m_torrents.value(id);
if (torrent)
{ // a duplicate torrent is added
if (torrent->isPrivate() || (hasMetadata && metadata.isPrivate()))
@ -2192,7 +2192,7 @@ bool Session::addTorrent_impl(const std::variant<MagnetUri, TorrentInfo> &source
if (!isFindingIncompleteFiles)
return loadTorrent(loadTorrentParams);
m_loadingTorrents.insert(hash, loadTorrentParams);
m_loadingTorrents.insert(id, loadTorrentParams);
return true;
}
@ -2209,8 +2209,12 @@ bool Session::loadTorrent(LoadTorrentParams params)
p.max_uploads = maxUploadsPerTorrent();
const bool hasMetadata = (p.ti && p.ti->is_valid());
const InfoHash hash = (hasMetadata ? p.ti->info_hash() : p.info_hash);
m_loadingTorrents.insert(hash, params);
#if (LIBTORRENT_VERSION_NUM >= 20000)
const auto id = TorrentID::fromInfoHash(hasMetadata ? p.ti->info_hashes() : p.info_hashes);
#else
const auto id = TorrentID::fromInfoHash(hasMetadata ? p.ti->info_hash() : p.info_hash);
#endif
m_loadingTorrents.insert(id, params);
// Adding torrent to BitTorrent session
m_nativeSession->async_add_torrent(p);
@ -2220,7 +2224,7 @@ bool Session::loadTorrent(LoadTorrentParams params)
void Session::findIncompleteFiles(const TorrentInfo &torrentInfo, const QString &savePath) const
{
const InfoHash searchId = torrentInfo.hash();
const auto searchId = TorrentID::fromInfoHash(torrentInfo.infoHash());
const QStringList originalFileNames = torrentInfo.filePaths();
const QString completeSavePath = savePath;
const QString incompleteSavePath = (isTempPathEnabled() ? torrentTempPath(torrentInfo) : QString {});
@ -2231,7 +2235,7 @@ void Session::findIncompleteFiles(const TorrentInfo &torrentInfo, const QString
});
#else
QMetaObject::invokeMethod(m_fileSearcher, "search"
, Q_ARG(BitTorrent::InfoHash, searchId), Q_ARG(QStringList, originalFileNames)
, Q_ARG(BitTorrent::TorrentID, searchId), Q_ARG(QStringList, originalFileNames)
, Q_ARG(QString, completeSavePath), Q_ARG(QString, incompleteSavePath));
#endif
}
@ -2242,17 +2246,17 @@ bool Session::downloadMetadata(const MagnetUri &magnetUri)
{
if (!magnetUri.isValid()) return false;
const InfoHash hash = magnetUri.hash();
const auto id = TorrentID::fromInfoHash(magnetUri.infoHash());
const QString name = magnetUri.name();
// We should not add torrent if it's already
// processed or adding to session
if (m_torrents.contains(hash)) return false;
if (m_loadingTorrents.contains(hash)) return false;
if (m_downloadedMetadata.contains(hash)) return false;
if (m_torrents.contains(id)) return false;
if (m_loadingTorrents.contains(id)) return false;
if (m_downloadedMetadata.contains(id)) return false;
qDebug("Adding torrent to preload metadata...");
qDebug(" -> Hash: %s", qUtf8Printable(hash.toString()));
qDebug(" -> Torrent ID: %s", qUtf8Printable(id.toString()));
qDebug(" -> Name: %s", qUtf8Printable(name));
lt::add_torrent_params p = magnetUri.addTorrentParams();
@ -2268,7 +2272,7 @@ bool Session::downloadMetadata(const MagnetUri &magnetUri)
p.max_connections = maxConnectionsPerTorrent();
p.max_uploads = maxUploadsPerTorrent();
const QString savePath = Utils::Fs::tempPath() + hash.toString();
const QString savePath = Utils::Fs::tempPath() + id.toString();
p.save_path = Utils::Fs::toNativePath(savePath).toStdString();
// Forced start
@ -2301,7 +2305,7 @@ void Session::exportTorrentFile(const Torrent *torrent, TorrentExportFolder fold
((folder == TorrentExportFolder::Finished) && !finishedTorrentExportDirectory().isEmpty()));
const QString validName = Utils::Fs::toValidFileSystemName(torrent->name());
const QString torrentFilename = QString::fromLatin1("%1.torrent").arg(torrent->hash().toString());
const QString torrentFilename = QString::fromLatin1("%1.torrent").arg(torrent->id().toString());
QString torrentExportFilename = QString::fromLatin1("%1.torrent").arg(validName);
const QString torrentPath = QDir(m_resumeFolderPath).absoluteFilePath(torrentFilename);
const QDir exportPath(folder == TorrentExportFolder::Regular ? torrentExportDirectory() : finishedTorrentExportDirectory());
@ -2374,13 +2378,13 @@ void Session::saveTorrentsQueue() const
// We require actual (non-cached) queue position here!
const int queuePos = static_cast<LTUnderlyingType<lt::queue_position_t>>(torrent->nativeHandle().queue_position());
if (queuePos >= 0)
queue[queuePos] = torrent->hash().toString();
queue[queuePos] = torrent->id().toString();
}
QByteArray data;
data.reserve(((InfoHash::length() * 2) + 1) * queue.size());
for (const QString &hash : asConst(queue))
data += (hash.toLatin1() + '\n');
data.reserve(((TorrentID::length() * 2) + 1) * queue.size());
for (const QString &torrentID : asConst(queue))
data += (torrentID.toLatin1() + '\n');
const QString filename = QLatin1String {"queue"};
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
@ -3758,11 +3762,11 @@ void Session::setMaxRatioAction(const MaxRatioAction act)
// If this functions returns true, we cannot add torrent to session,
// but it is still possible to merge trackers in some cases
bool Session::isKnownTorrent(const InfoHash &hash) const
bool Session::isKnownTorrent(const TorrentID &id) const
{
return (m_torrents.contains(hash)
|| m_loadingTorrents.contains(hash)
|| m_downloadedMetadata.contains(hash));
return (m_torrents.contains(id)
|| m_loadingTorrents.contains(id)
|| m_downloadedMetadata.contains(id));
}
void Session::updateSeedingLimitTimer()
@ -3868,7 +3872,7 @@ void Session::handleTorrentMetadataReceived(TorrentImpl *const torrent)
{
// Save metadata
const QDir resumeDataDir {m_resumeFolderPath};
const QString torrentFileName {QString {"%1.torrent"}.arg(torrent->hash().toString())};
const QString torrentFileName {QString {"%1.torrent"}.arg(torrent->id().toString())};
try
{
torrent->info().saveToFile(resumeDataDir.absoluteFilePath(torrentFileName));
@ -3948,7 +3952,7 @@ void Session::handleTorrentResumeDataReady(TorrentImpl *const torrent, const std
// Separated thread is used for the blocking IO which results in slow processing of many torrents.
// Copying lt::entry objects around isn't cheap.
const QString filename = QString::fromLatin1("%1.fastresume").arg(torrent->hash().toString());
const QString filename = QString::fromLatin1("%1.fastresume").arg(torrent->id().toString());
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
QMetaObject::invokeMethod(m_resumeDataSavingManager
, [this, filename, data]() { m_resumeDataSavingManager->save(filename, data); });
@ -4024,9 +4028,13 @@ bool Session::addMoveTorrentStorageJob(TorrentImpl *torrent, const QString &newP
void Session::moveTorrentStorage(const MoveStorageJob &job) const
{
const InfoHash infoHash = job.torrentHandle.info_hash();
const TorrentImpl *torrent = m_torrents.value(infoHash);
const QString torrentName = (torrent ? torrent->name() : infoHash.toString());
#if (LIBTORRENT_VERSION_NUM >= 20000)
const auto id = TorrentID::fromInfoHash(job.torrentHandle.info_hashes());
#else
const auto id = TorrentID::fromInfoHash(job.torrentHandle.info_hash());
#endif
const TorrentImpl *torrent = m_torrents.value(id);
const QString torrentName = (torrent ? torrent->name() : id.toString());
LogMsg(tr("Moving \"%1\" to \"%2\"...").arg(torrentName, job.path));
job.torrentHandle.move_storage(job.path.toUtf8().constData()
@ -4157,9 +4165,9 @@ void Session::disableIPFilter()
m_nativeSession->set_ip_filter(filter);
}
void Session::recursiveTorrentDownload(const InfoHash &hash)
void Session::recursiveTorrentDownload(const TorrentID &id)
{
TorrentImpl *const torrent = m_torrents.value(hash);
TorrentImpl *const torrent = m_torrents.value(id);
if (!torrent) return;
for (int i = 0; i < torrent->filesCount(); ++i)
@ -4584,7 +4592,7 @@ void Session::createTorrent(const lt::torrent_handle &nativeHandle)
const LoadTorrentParams params = m_loadingTorrents.take(nativeHandle.info_hash());
auto *const torrent = new TorrentImpl {this, m_nativeSession, nativeHandle, params};
m_torrents.insert(torrent->hash(), torrent);
m_torrents.insert(torrent->id(), torrent);
const bool hasMetadata = torrent->hasMetadata();
@ -4599,7 +4607,7 @@ void Session::createTorrent(const lt::torrent_handle &nativeHandle)
{
// Backup torrent file
const QDir resumeDataDir {m_resumeFolderPath};
const QString torrentFileName {QString::fromLatin1("%1.torrent").arg(torrent->hash().toString())};
const QString torrentFileName {QString::fromLatin1("%1.torrent").arg(torrent->id().toString())};
try
{
torrent->info().saveToFile(resumeDataDir.absoluteFilePath(torrentFileName));
@ -4657,9 +4665,13 @@ void Session::handleAddTorrentAlert(const lt::add_torrent_alert *p)
void Session::handleTorrentRemovedAlert(const lt::torrent_removed_alert *p)
{
const InfoHash infoHash {p->info_hash};
#if (LIBTORRENT_VERSION_NUM >= 20000)
const auto id = TorrentID::fromInfoHash(p->info_hashes);
#else
const auto id = TorrentID::fromInfoHash(p->info_hash);
#endif
const auto removingTorrentDataIter = m_removingTorrents.find(infoHash);
const auto removingTorrentDataIter = m_removingTorrents.find(id);
if (removingTorrentDataIter != m_removingTorrents.end())
{
if (removingTorrentDataIter->deleteOption == DeleteTorrent)
@ -4672,8 +4684,13 @@ void Session::handleTorrentRemovedAlert(const lt::torrent_removed_alert *p)
void Session::handleTorrentDeletedAlert(const lt::torrent_deleted_alert *p)
{
const InfoHash infoHash {p->info_hash};
const auto removingTorrentDataIter = m_removingTorrents.find(infoHash);
#if (LIBTORRENT_VERSION_NUM >= 20000)
const auto id = TorrentID::fromInfoHash(p->info_hashes);
#else
const auto id = TorrentID::fromInfoHash(p->info_hash);
#endif
const auto removingTorrentDataIter = m_removingTorrents.find(id);
if (removingTorrentDataIter == m_removingTorrents.end())
return;
@ -4685,8 +4702,13 @@ void Session::handleTorrentDeletedAlert(const lt::torrent_deleted_alert *p)
void Session::handleTorrentDeleteFailedAlert(const lt::torrent_delete_failed_alert *p)
{
const InfoHash infoHash {p->info_hash};
const auto removingTorrentDataIter = m_removingTorrents.find(infoHash);
#if (LIBTORRENT_VERSION_NUM >= 20000)
const auto id = TorrentID::fromInfoHash(p->info_hashes);
#else
const auto id = TorrentID::fromInfoHash(p->info_hash);
#endif
const auto removingTorrentDataIter = m_removingTorrents.find(id);
if (removingTorrentDataIter == m_removingTorrents.end())
return;
@ -4710,8 +4732,13 @@ void Session::handleTorrentDeleteFailedAlert(const lt::torrent_delete_failed_ale
void Session::handleMetadataReceivedAlert(const lt::metadata_received_alert *p)
{
const InfoHash hash {p->handle.info_hash()};
const auto downloadedMetadataIter = m_downloadedMetadata.find(hash);
#if (LIBTORRENT_VERSION_NUM >= 20000)
const auto id = TorrentID::fromInfoHash(p->handle.info_hashes());
#else
const auto id = TorrentID::fromInfoHash(p->handle.info_hash());
#endif
const auto downloadedMetadataIter = m_downloadedMetadata.find(id);
if (downloadedMetadataIter != m_downloadedMetadata.end())
{
@ -4732,11 +4759,11 @@ void Session::handleFileErrorAlert(const lt::file_error_alert *p)
if (!torrent)
return;
const InfoHash hash = torrent->hash();
const TorrentID id = torrent->id();
if (!m_recentErroredTorrents.contains(hash))
if (!m_recentErroredTorrents.contains(id))
{
m_recentErroredTorrents.insert(hash);
m_recentErroredTorrents.insert(id);
const QString msg = QString::fromStdString(p->message());
LogMsg(tr("File error alert. Torrent: \"%1\". File: \"%2\". Reason: %3")
@ -4935,9 +4962,14 @@ void Session::handleStorageMovedAlert(const lt::storage_moved_alert *p)
const QString newPath {p->storage_path()};
Q_ASSERT(newPath == currentJob.path);
const InfoHash infoHash = currentJob.torrentHandle.info_hash();
TorrentImpl *torrent = m_torrents.value(infoHash);
const QString torrentName = (torrent ? torrent->name() : infoHash.toString());
#if (LIBTORRENT_VERSION_NUM >= 20000)
const auto id = TorrentID::fromInfoHash(currentJob.torrentHandle.info_hashes());
#else
const auto id = TorrentID::fromInfoHash(currentJob.torrentHandle.info_hash());
#endif
TorrentImpl *torrent = m_torrents.value(id);
const QString torrentName = (torrent ? torrent->name() : id.toString());
LogMsg(tr("\"%1\" is successfully moved to \"%2\".").arg(torrentName, newPath));
handleMoveTorrentStorageJobFinished();
@ -4950,9 +4982,14 @@ void Session::handleStorageMovedFailedAlert(const lt::storage_moved_failed_alert
const MoveStorageJob &currentJob = m_moveStorageQueue.first();
Q_ASSERT(currentJob.torrentHandle == p->handle);
const InfoHash infoHash = currentJob.torrentHandle.info_hash();
TorrentImpl *torrent = m_torrents.value(infoHash);
const QString torrentName = (torrent ? torrent->name() : infoHash.toString());
#if (LIBTORRENT_VERSION_NUM >= 20000)
const auto id = TorrentID::fromInfoHash(currentJob.torrentHandle.info_hashes());
#else
const auto id = TorrentID::fromInfoHash(currentJob.torrentHandle.info_hash());
#endif
TorrentImpl *torrent = m_torrents.value(id);
const QString torrentName = (torrent ? torrent->name() : id.toString());
const QString currentLocation = QString::fromStdString(p->handle.status(lt::torrent_handle::query_save_path).save_path);
const QString errorMessage = QString::fromStdString(p->message());
LogMsg(tr("Failed to move \"%1\" from \"%2\" to \"%3\". Reason: %4.")
@ -4968,8 +5005,12 @@ void Session::handleStateUpdateAlert(const lt::state_update_alert *p)
for (const lt::torrent_status &status : p->status)
{
TorrentImpl *const torrent = m_torrents.value(status.info_hash);
#if (LIBTORRENT_VERSION_NUM >= 20000)
const auto id = TorrentID::fromInfoHash(status.info_hashes);
#else
const auto id = TorrentID::fromInfoHash(status.info_hash);
#endif
TorrentImpl *const torrent = m_torrents.value(id);
if (!torrent)
continue;