diff --git a/src/base/CMakeLists.txt b/src/base/CMakeLists.txt index 00fb433e6..cba9ce9c0 100644 --- a/src/base/CMakeLists.txt +++ b/src/base/CMakeLists.txt @@ -4,12 +4,14 @@ add_library(qbt_base STATIC # headers bittorrent/addtorrentparams.h bittorrent/cachestatus.h -bittorrent/filepriority.h +bittorrent/downloadpriority.h bittorrent/infohash.h bittorrent/magneturi.h bittorrent/peerinfo.h bittorrent/private/bandwidthscheduler.h +bittorrent/private/libtorrentfwd.h bittorrent/private/filterparserthread.h +bittorrent/private/portforwarderimpl.h bittorrent/private/resumedatasavingmanager.h bittorrent/private/speedmonitor.h bittorrent/private/statistics.h @@ -77,12 +79,13 @@ types.h unicodestrings.h # sources -bittorrent/filepriority.cpp +bittorrent/downloadpriority.cpp bittorrent/infohash.cpp bittorrent/magneturi.cpp bittorrent/peerinfo.cpp bittorrent/private/bandwidthscheduler.cpp bittorrent/private/filterparserthread.cpp +bittorrent/private/portforwarderimpl.cpp bittorrent/private/resumedatasavingmanager.cpp bittorrent/private/speedmonitor.cpp bittorrent/private/statistics.cpp diff --git a/src/base/base.pri b/src/base/base.pri index 71013cd33..791217f26 100644 --- a/src/base/base.pri +++ b/src/base/base.pri @@ -3,12 +3,14 @@ HEADERS += \ $$PWD/asyncfilestorage.h \ $$PWD/bittorrent/addtorrentparams.h \ $$PWD/bittorrent/cachestatus.h \ - $$PWD/bittorrent/filepriority.h \ + $$PWD/bittorrent/downloadpriority.h \ $$PWD/bittorrent/infohash.h \ $$PWD/bittorrent/magneturi.h \ $$PWD/bittorrent/peerinfo.h \ $$PWD/bittorrent/private/bandwidthscheduler.h \ $$PWD/bittorrent/private/filterparserthread.h \ + $$PWD/bittorrent/private/libtorrentfwd.h \ + $$PWD/bittorrent/private/portforwarderimpl.h \ $$PWD/bittorrent/private/resumedatasavingmanager.h \ $$PWD/bittorrent/private/speedmonitor.h \ $$PWD/bittorrent/private/statistics.h \ @@ -76,12 +78,13 @@ HEADERS += \ SOURCES += \ $$PWD/asyncfilestorage.cpp \ - $$PWD/bittorrent/filepriority.cpp \ + $$PWD/bittorrent/downloadpriority.cpp \ $$PWD/bittorrent/infohash.cpp \ $$PWD/bittorrent/magneturi.cpp \ $$PWD/bittorrent/peerinfo.cpp \ $$PWD/bittorrent/private/bandwidthscheduler.cpp \ $$PWD/bittorrent/private/filterparserthread.cpp \ + $$PWD/bittorrent/private/portforwarderimpl.cpp \ $$PWD/bittorrent/private/resumedatasavingmanager.cpp \ $$PWD/bittorrent/private/speedmonitor.cpp \ $$PWD/bittorrent/private/statistics.cpp \ diff --git a/src/base/bittorrent/addtorrentparams.h b/src/base/bittorrent/addtorrentparams.h index 280849abd..42a837019 100644 --- a/src/base/bittorrent/addtorrentparams.h +++ b/src/base/bittorrent/addtorrentparams.h @@ -33,6 +33,7 @@ #include #include "../tristatebool.h" +#include "downloadpriority.h" namespace BitTorrent { @@ -47,7 +48,7 @@ namespace BitTorrent bool firstLastPiecePriority = false; TriStateBool addForced; TriStateBool addPaused; - QVector filePriorities; // used if TorrentInfo is set + QVector filePriorities; // used if TorrentInfo is set bool ignoreShareLimits = false; bool skipChecking = false; TriStateBool createSubfolder; diff --git a/src/base/bittorrent/filepriority.cpp b/src/base/bittorrent/downloadpriority.cpp similarity index 81% rename from src/base/bittorrent/filepriority.cpp rename to src/base/bittorrent/downloadpriority.cpp index 92c6f6f23..1e83b1cfb 100644 --- a/src/base/bittorrent/filepriority.cpp +++ b/src/base/bittorrent/downloadpriority.cpp @@ -26,18 +26,18 @@ * exception statement from your version. */ -#include "filepriority.h" +#include "downloadpriority.h" namespace BitTorrent { - bool isValidFilePriority(const BitTorrent::FilePriority priority) + bool isValidDownloadPriority(const DownloadPriority priority) { switch (priority) { - case BitTorrent::FilePriority::Ignored: - case BitTorrent::FilePriority::Normal: - case BitTorrent::FilePriority::High: - case BitTorrent::FilePriority::Maximum: - case BitTorrent::FilePriority::Mixed: + case BitTorrent::DownloadPriority::Ignored: + case BitTorrent::DownloadPriority::Normal: + case BitTorrent::DownloadPriority::High: + case BitTorrent::DownloadPriority::Maximum: + case BitTorrent::DownloadPriority::Mixed: return true; default: return false; diff --git a/src/base/bittorrent/filepriority.h b/src/base/bittorrent/downloadpriority.h similarity index 94% rename from src/base/bittorrent/filepriority.h rename to src/base/bittorrent/downloadpriority.h index b5e2fc3aa..8f355d660 100644 --- a/src/base/bittorrent/filepriority.h +++ b/src/base/bittorrent/downloadpriority.h @@ -30,14 +30,15 @@ namespace BitTorrent { - enum class FilePriority : int + enum class DownloadPriority : int { Ignored = 0, Normal = 1, High = 6, Maximum = 7, + Mixed = -1 }; - bool isValidFilePriority(BitTorrent::FilePriority priority); + bool isValidDownloadPriority(DownloadPriority priority); } diff --git a/src/base/bittorrent/infohash.cpp b/src/base/bittorrent/infohash.cpp index d900a4776..9a7f51a74 100644 --- a/src/base/bittorrent/infohash.cpp +++ b/src/base/bittorrent/infohash.cpp @@ -42,18 +42,18 @@ InfoHash::InfoHash(const libtorrent::sha1_hash &nativeHash) : m_valid(true) , m_nativeHash(nativeHash) { - const QByteArray raw = QByteArray::fromRawData(nativeHash.data(), libtorrent::sha1_hash::size); + const QByteArray raw = QByteArray::fromRawData(nativeHash.data(), length()); m_hashString = QString::fromLatin1(raw.toHex()); } InfoHash::InfoHash(const QString &hashString) : m_valid(false) { - if (hashString.size() != (libtorrent::sha1_hash::size * 2)) + if (hashString.size() != (length() * 2)) return; const QByteArray raw = QByteArray::fromHex(hashString.toLatin1()); - if (raw.size() != libtorrent::sha1_hash::size) // QByteArray::fromHex() will skip over invalid characters + if (raw.size() != length()) // QByteArray::fromHex() will skip over invalid characters return; m_valid = true; diff --git a/src/base/bittorrent/infohash.h b/src/base/bittorrent/infohash.h index 7841e8bfc..234549d38 100644 --- a/src/base/bittorrent/infohash.h +++ b/src/base/bittorrent/infohash.h @@ -30,6 +30,8 @@ #define BITTORRENT_INFOHASH_H #include +#include + #include namespace BitTorrent @@ -42,6 +44,15 @@ namespace BitTorrent InfoHash(const QString &hashString); InfoHash(const InfoHash &other) = default; + static constexpr int length() + { +#if (LIBTORRENT_VERSION_NUM < 10200) + return libtorrent::sha1_hash::size; +#else + return libtorrent::sha1_hash::size(); +#endif + } + bool isValid() const; operator libtorrent::sha1_hash() const; diff --git a/src/base/bittorrent/magneturi.cpp b/src/base/bittorrent/magneturi.cpp index cd39e5d3f..52d80b77b 100644 --- a/src/base/bittorrent/magneturi.cpp +++ b/src/base/bittorrent/magneturi.cpp @@ -35,6 +35,8 @@ #include +#include "infohash.h" + namespace { bool isBitTorrentInfoHash(const QString &string) @@ -44,8 +46,8 @@ namespace // == 20 (SHA-1 length in bytes) * 2 (each byte maps to 2 hex characters) // 2. 32 chars Base32 encoded string // == 20 (SHA-1 length in bytes) * 1.6 (the efficiency of Base32 encoding) - const int SHA1_HEX_SIZE = libtorrent::sha1_hash::size * 2; - const int SHA1_BASE32_SIZE = libtorrent::sha1_hash::size * 1.6; + const int SHA1_HEX_SIZE = BitTorrent::InfoHash::length() * 2; + const int SHA1_BASE32_SIZE = BitTorrent::InfoHash::length() * 1.6; return ((((string.size() == SHA1_HEX_SIZE)) && !string.contains(QRegularExpression(QLatin1String("[^0-9A-Fa-f]")))) @@ -75,7 +77,7 @@ MagnetUri::MagnetUri(const QString &source) m_name = QString::fromStdString(m_addTorrentParams.name); for (const std::string &tracker : m_addTorrentParams.trackers) - m_trackers.append(TrackerEntry(tracker)); + m_trackers.append(libtorrent::announce_entry {tracker}); for (const std::string &urlSeed : m_addTorrentParams.url_seeds) m_urlSeeds.append(QUrl(QString::fromStdString(urlSeed))); diff --git a/src/base/bittorrent/peerinfo.cpp b/src/base/bittorrent/peerinfo.cpp index a5a3d8f60..a7ee09e69 100644 --- a/src/base/bittorrent/peerinfo.cpp +++ b/src/base/bittorrent/peerinfo.cpp @@ -60,17 +60,17 @@ PeerInfo::PeerInfo(const TorrentHandle *torrent, const libt::peer_info &nativeIn bool PeerInfo::fromDHT() const { - return (m_nativeInfo.source & libt::peer_info::dht); + return static_cast(m_nativeInfo.source & libt::peer_info::dht); } bool PeerInfo::fromPeX() const { - return (m_nativeInfo.source & libt::peer_info::pex); + return static_cast(m_nativeInfo.source & libt::peer_info::pex); } bool PeerInfo::fromLSD() const { - return (m_nativeInfo.source & libt::peer_info::lsd); + return static_cast(m_nativeInfo.source & libt::peer_info::lsd); } #ifndef DISABLE_COUNTRIES_RESOLUTION @@ -82,102 +82,102 @@ QString PeerInfo::country() const bool PeerInfo::isInteresting() const { - return (m_nativeInfo.flags & libt::peer_info::interesting); + return static_cast(m_nativeInfo.flags & libt::peer_info::interesting); } bool PeerInfo::isChocked() const { - return (m_nativeInfo.flags & libt::peer_info::choked); + return static_cast(m_nativeInfo.flags & libt::peer_info::choked); } bool PeerInfo::isRemoteInterested() const { - return (m_nativeInfo.flags & libt::peer_info::remote_interested); + return static_cast(m_nativeInfo.flags & libt::peer_info::remote_interested); } bool PeerInfo::isRemoteChocked() const { - return (m_nativeInfo.flags & libt::peer_info::remote_choked); + return static_cast(m_nativeInfo.flags & libt::peer_info::remote_choked); } bool PeerInfo::isSupportsExtensions() const { - return (m_nativeInfo.flags & libt::peer_info::supports_extensions); + return static_cast(m_nativeInfo.flags & libt::peer_info::supports_extensions); } bool PeerInfo::isLocalConnection() const { - return (m_nativeInfo.flags & libt::peer_info::local_connection); + return static_cast(m_nativeInfo.flags & libt::peer_info::local_connection); } bool PeerInfo::isHandshake() const { - return (m_nativeInfo.flags & libt::peer_info::handshake); + return static_cast(m_nativeInfo.flags & libt::peer_info::handshake); } bool PeerInfo::isConnecting() const { - return (m_nativeInfo.flags & libt::peer_info::connecting); + return static_cast(m_nativeInfo.flags & libt::peer_info::connecting); } bool PeerInfo::isOnParole() const { - return (m_nativeInfo.flags & libt::peer_info::on_parole); + return static_cast(m_nativeInfo.flags & libt::peer_info::on_parole); } bool PeerInfo::isSeed() const { - return (m_nativeInfo.flags & libt::peer_info::seed); + return static_cast(m_nativeInfo.flags & libt::peer_info::seed); } bool PeerInfo::optimisticUnchoke() const { - return (m_nativeInfo.flags & libt::peer_info::optimistic_unchoke); + return static_cast(m_nativeInfo.flags & libt::peer_info::optimistic_unchoke); } bool PeerInfo::isSnubbed() const { - return (m_nativeInfo.flags & libt::peer_info::snubbed); + return static_cast(m_nativeInfo.flags & libt::peer_info::snubbed); } bool PeerInfo::isUploadOnly() const { - return (m_nativeInfo.flags & libt::peer_info::upload_only); + return static_cast(m_nativeInfo.flags & libt::peer_info::upload_only); } bool PeerInfo::isEndgameMode() const { - return (m_nativeInfo.flags & libt::peer_info::endgame_mode); + return static_cast(m_nativeInfo.flags & libt::peer_info::endgame_mode); } bool PeerInfo::isHolepunched() const { - return (m_nativeInfo.flags & libt::peer_info::holepunched); + return static_cast(m_nativeInfo.flags & libt::peer_info::holepunched); } bool PeerInfo::useI2PSocket() const { - return (m_nativeInfo.flags & libt::peer_info::i2p_socket); + return static_cast(m_nativeInfo.flags & libt::peer_info::i2p_socket); } bool PeerInfo::useUTPSocket() const { - return (m_nativeInfo.flags & libt::peer_info::utp_socket); + return static_cast(m_nativeInfo.flags & libt::peer_info::utp_socket); } bool PeerInfo::useSSLSocket() const { - return (m_nativeInfo.flags & libt::peer_info::ssl_socket); + return static_cast(m_nativeInfo.flags & libt::peer_info::ssl_socket); } bool PeerInfo::isRC4Encrypted() const { - return (m_nativeInfo.flags & libt::peer_info::rc4_encrypted); + return static_cast(m_nativeInfo.flags & libt::peer_info::rc4_encrypted); } bool PeerInfo::isPlaintextEncrypted() const { - return (m_nativeInfo.flags & libt::peer_info::plaintext_encrypted); + return static_cast(m_nativeInfo.flags & libt::peer_info::plaintext_encrypted); } PeerAddress PeerInfo::address() const @@ -220,8 +220,9 @@ QBitArray PeerInfo::pieces() const { QBitArray result(m_nativeInfo.pieces.size()); - for (int i = 0; i < m_nativeInfo.pieces.size(); ++i) - result.setBit(i, m_nativeInfo.pieces.get_bit(i)); + int i = 0; + for (const bool bit : m_nativeInfo.pieces) + result.setBit(i++, bit); return result; } @@ -397,5 +398,5 @@ QString PeerInfo::flagsDescription() const int PeerInfo::downloadingPieceIndex() const { - return m_nativeInfo.downloading_piece_index; + return static_cast(m_nativeInfo.downloading_piece_index); } diff --git a/src/base/bittorrent/private/libtorrentfwd.h b/src/base/bittorrent/private/libtorrentfwd.h new file mode 100644 index 000000000..5bbaf9ff1 --- /dev/null +++ b/src/base/bittorrent/private/libtorrentfwd.h @@ -0,0 +1,81 @@ +/* + * Bittorrent Client using Qt and libtorrent. + * Copyright (C) 2019 Vladimir Golovnev + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + */ + +#pragma once + +#include + +#if (LIBTORRENT_VERSION_NUM < 10200) +namespace libtorrent +{ + class entry; + class session; + struct ip_filter; + struct settings_pack; + struct torrent_handle; + + class alert; + struct add_torrent_alert; + struct external_ip_alert; + struct fastresume_rejected_alert; + struct file_completed_alert; + struct file_error_alert; + struct file_rename_failed_alert; + struct file_renamed_alert; + struct listen_failed_alert; + struct listen_succeeded_alert; + struct metadata_received_alert; + struct peer_ban_alert; + struct peer_blocked_alert; + struct portmap_alert; + struct portmap_error_alert; + struct save_resume_data_alert; + struct save_resume_data_failed_alert; + struct session_stats_alert; + struct state_update_alert; + struct stats_alert; + struct storage_moved_alert; + struct storage_moved_failed_alert; + struct torrent_alert; + struct torrent_checked_alert; + struct torrent_delete_failed_alert; + struct torrent_deleted_alert; + struct torrent_finished_alert; + struct torrent_paused_alert; + struct torrent_removed_alert; + struct torrent_resumed_alert; + struct tracker_error_alert; + struct tracker_reply_alert; + struct tracker_warning_alert; + struct url_seed_alert; +} + +namespace lt = libtorrent; +#else +#include +#endif diff --git a/src/base/bittorrent/private/portforwarderimpl.cpp b/src/base/bittorrent/private/portforwarderimpl.cpp new file mode 100644 index 000000000..e0282bbf7 --- /dev/null +++ b/src/base/bittorrent/private/portforwarderimpl.cpp @@ -0,0 +1,114 @@ +/* + * Bittorrent Client using Qt and libtorrent. + * Copyright (C) 2019 Vladimir Golovnev + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + */ + +#include "portforwarderimpl.h" + +#include + +#include + +#include "base/logger.h" +#include "base/settingsstorage.h" + +const QString KEY_ENABLED = QStringLiteral("Network/PortForwardingEnabled"); + +PortForwarderImpl::PortForwarderImpl(libtorrent::session *provider, QObject *parent) + : Net::PortForwarder {parent} + , m_active {SettingsStorage::instance()->loadValue(KEY_ENABLED, true).toBool()} + , m_provider {provider} +{ + if (m_active) + start(); +} + +PortForwarderImpl::~PortForwarderImpl() +{ + stop(); +} + +bool PortForwarderImpl::isEnabled() const +{ + return m_active; +} + +void PortForwarderImpl::setEnabled(const bool enabled) +{ + if (m_active != enabled) { + if (enabled) + start(); + else + stop(); + + m_active = enabled; + SettingsStorage::instance()->storeValue(KEY_ENABLED, enabled); + } +} + +void PortForwarderImpl::addPort(const quint16 port) +{ + if (!m_mappedPorts.contains(port)) { + m_mappedPorts.insert(port, {}); + if (isEnabled()) + m_mappedPorts[port] = {m_provider->add_port_mapping(lt::session::tcp, port, port)}; + } +} + +void PortForwarderImpl::deletePort(const quint16 port) +{ + if (m_mappedPorts.contains(port)) { + if (isEnabled()) { + for (const LTPortMapping &portMapping : m_mappedPorts[port]) + m_provider->delete_port_mapping(portMapping); + } + m_mappedPorts.remove(port); + } +} + +void PortForwarderImpl::start() +{ + qDebug("Enabling UPnP / NAT-PMP"); + lt::settings_pack settingsPack = m_provider->get_settings(); + settingsPack.set_bool(lt::settings_pack::enable_upnp, true); + settingsPack.set_bool(lt::settings_pack::enable_natpmp, true); + m_provider->apply_settings(settingsPack); + for (auto i = m_mappedPorts.begin(); i != m_mappedPorts.end(); ++i) { + // quint16 port = i.key(); + i.value() = {m_provider->add_port_mapping(lt::session::tcp, i.key(), i.key())}; + } + LogMsg(tr("UPnP / NAT-PMP support [ON]"), Log::INFO); +} + +void PortForwarderImpl::stop() +{ + qDebug("Disabling UPnP / NAT-PMP"); + lt::settings_pack settingsPack = m_provider->get_settings(); + settingsPack.set_bool(lt::settings_pack::enable_upnp, false); + settingsPack.set_bool(lt::settings_pack::enable_natpmp, false); + m_provider->apply_settings(settingsPack); + LogMsg(tr("UPnP / NAT-PMP support [OFF]"), Log::INFO); +} diff --git a/src/base/bittorrent/private/portforwarderimpl.h b/src/base/bittorrent/private/portforwarderimpl.h new file mode 100644 index 000000000..df353c47c --- /dev/null +++ b/src/base/bittorrent/private/portforwarderimpl.h @@ -0,0 +1,65 @@ +/* + * Bittorrent Client using Qt and libtorrent. + * Copyright (C) 2019 Vladimir Golovnev + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + */ + +#pragma once + +#include +#include + +#include "base/net/portforwarder.h" +#include "libtorrentfwd.h" + +#if (LIBTORRENT_VERSION_NUM < 10200) +using LTPortMapping = int; +#else +#include +using LTPortMapping = lt::port_mapping_t; +#endif + +class PortForwarderImpl : public Net::PortForwarder +{ + Q_DISABLE_COPY(PortForwarderImpl) + +public: + explicit PortForwarderImpl(lt::session *provider, QObject *parent = nullptr); + ~PortForwarderImpl() override; + + bool isEnabled() const override; + void setEnabled(bool enabled) override; + + void addPort(quint16 port) override; + void deletePort(quint16 port) override; + +private: + void start(); + void stop(); + + bool m_active; + libtorrent::session *m_provider; + QHash> m_mappedPorts; +}; diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index d02fa3843..2b4f2001b 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -62,13 +62,13 @@ #include #include #include +#include #include "base/algorithm.h" #include "base/exceptions.h" #include "base/global.h" #include "base/logger.h" #include "base/net/downloadmanager.h" -#include "base/net/portforwarder.h" #include "base/net/proxyconfigurationmanager.h" #include "base/profile.h" #include "base/torrentfileguard.h" @@ -82,6 +82,7 @@ #include "magneturi.h" #include "private/bandwidthscheduler.h" #include "private/filterparserthread.h" +#include "private/portforwarderimpl.h" #include "private/resumedatasavingmanager.h" #include "private/statistics.h" #include "torrenthandle.h" @@ -106,6 +107,16 @@ using namespace BitTorrent; namespace { +#if (LIBTORRENT_VERSION_NUM < 10200) + using LTSessionFlags = int; + using LTStatusFlags = int; + using LTString = std::string; +#else + using LTSessionFlags = lt::session_flags_t; + using LTStatusFlags = lt::status_flags_t; + using LTString = lt::string_view; +#endif + bool readFile(const QString &path, QByteArray &buf); bool loadTorrentResumeData(const QByteArray &data, CreateTorrentParams &torrentParams, int &prio, MagnetUri &magnetUri); @@ -134,13 +145,19 @@ namespace return result; } + template + QString fromLTString(const LTStr &str) + { + return QString::fromUtf8(str.data(), static_cast(str.size())); + } + template QSet entryListToSetImpl(const Entry &entry) { Q_ASSERT(entry.type() == Entry::list_t); QSet output; for (int i = 0; i < entry.list_size(); ++i) { - const QString tag = QString::fromStdString(entry.list_string_value_at(i)); + const QString tag = fromLTString(entry.list_string_value_at(i)); if (Session::isValidTag(tag)) output.insert(tag); else @@ -405,7 +422,7 @@ Session::Session(QObject *parent) pack.set_bool(libt::settings_pack::upnp_ignore_nonrouters, true); configure(pack); - m_nativeSession = new libt::session(pack, 0); + m_nativeSession = new lt::session {pack, LTSessionFlags {0}}; m_nativeSession->set_alert_notify([this]() { QMetaObject::invokeMethod(this, "readAlerts", Qt::QueuedConnection); @@ -490,7 +507,7 @@ Session::Session(QObject *parent) } // initialize PortForwarder instance - Net::PortForwarder::initInstance(m_nativeSession); + new PortForwarderImpl {m_nativeSession}; initMetrics(); m_statsUpdateTimer.start(); @@ -936,7 +953,7 @@ Session::~Session() // We must delete PortForwarderImpl before // we delete libtorrent::session - Net::PortForwarder::freeInstance(); + delete Net::PortForwarder::instance(); qDebug("Deleting the session"); delete m_nativeSession; @@ -1665,7 +1682,7 @@ bool Session::cancelLoadMetadata(const InfoHash &hash) const libt::torrent_handle torrent = m_nativeSession->find_torrent(hash); if (!torrent.is_valid()) return false; - if (!torrent.status(0).has_metadata) { + if (!torrent.status(LTStatusFlags {0}).has_metadata) { // if hidden torrent is still loading metadata... --m_extraLimit; adjustLimits(); @@ -1930,11 +1947,21 @@ bool Session::addTorrent_impl(CreateTorrentParams params, const MagnetUri &magne if (!fromMagnetUri) { if (params.restored) { // Set torrent fast resume data - p.resume_data = {fastresumeData.constData(), fastresumeData.constData() + fastresumeData.size()}; + p.resume_data = std::vector {fastresumeData.constData(), fastresumeData.constData() + fastresumeData.size()}; p.flags |= libt::add_torrent_params::flag_use_resume_save_path; } else { - p.file_priorities = {params.filePriorities.begin(), params.filePriorities.end()}; + Q_ASSERT(p.file_priorities.empty()); + std::transform(params.filePriorities.cbegin(), params.filePriorities.cend() + , std::back_inserter(p.file_priorities), [](DownloadPriority priority) + { +#if (LIBTORRENT_VERSION_NUM < 10200) + return static_cast(priority); +#else + return static_cast( + static_cast(priority)); +#endif + }); } } @@ -3966,7 +3993,11 @@ void Session::handlePortmapAlert(const libt::portmap_alert *p) void Session::handlePeerBlockedAlert(const libt::peer_blocked_alert *p) { boost::system::error_code ec; +#if LIBTORRENT_VERSION_NUM < 10200 const std::string ip = p->ip.to_string(ec); +#else + const std::string ip = p->endpoint.address().to_string(ec); +#endif QString reason; switch (p->reason) { case libt::peer_blocked_alert::ip_filter: @@ -4182,31 +4213,31 @@ namespace if (ec || (fast.type() != libt::bdecode_node::dict_t)) return false; torrentParams.savePath = Profile::instance().fromPortablePath( - Utils::Fs::fromNativePath(QString::fromStdString(fast.dict_find_string_value("qBt-savePath")))); + Utils::Fs::fromNativePath(fromLTString(fast.dict_find_string_value("qBt-savePath")))); - std::string ratioLimitString = fast.dict_find_string_value("qBt-ratioLimit"); + LTString ratioLimitString = fast.dict_find_string_value("qBt-ratioLimit"); if (ratioLimitString.empty()) torrentParams.ratioLimit = fast.dict_find_int_value("qBt-ratioLimit", TorrentHandle::USE_GLOBAL_RATIO * 1000) / 1000.0; else - torrentParams.ratioLimit = QString::fromStdString(ratioLimitString).toDouble(); + torrentParams.ratioLimit = fromLTString(ratioLimitString).toDouble(); torrentParams.seedingTimeLimit = fast.dict_find_int_value("qBt-seedingTimeLimit", TorrentHandle::USE_GLOBAL_SEEDING_TIME); // ************************************************************************************** // Workaround to convert legacy label to category // TODO: Should be removed in future - torrentParams.category = QString::fromStdString(fast.dict_find_string_value("qBt-label")); + torrentParams.category = fromLTString(fast.dict_find_string_value("qBt-label")); if (torrentParams.category.isEmpty()) // ************************************************************************************** - torrentParams.category = QString::fromStdString(fast.dict_find_string_value("qBt-category")); + torrentParams.category = fromLTString(fast.dict_find_string_value("qBt-category")); // auto because the return type depends on the #if above. const auto tagsEntry = fast.dict_find_list("qBt-tags"); if (isList(tagsEntry)) torrentParams.tags = entryListToSet(tagsEntry); - torrentParams.name = QString::fromStdString(fast.dict_find_string_value("qBt-name")); + torrentParams.name = fromLTString(fast.dict_find_string_value("qBt-name")); torrentParams.hasSeedStatus = fast.dict_find_int_value("qBt-seedStatus"); torrentParams.disableTempPath = fast.dict_find_int_value("qBt-tempPathDisabled"); torrentParams.hasRootFolder = fast.dict_find_int_value("qBt-hasRootFolder"); - magnetUri = MagnetUri(QString::fromStdString(fast.dict_find_string_value("qBt-magnetUri"))); + magnetUri = MagnetUri(fromLTString(fast.dict_find_string_value("qBt-magnetUri"))); const bool isAutoManaged = fast.dict_find_int_value("auto_managed"); const bool isPaused = fast.dict_find_int_value("paused"); torrentParams.paused = fast.dict_find_int_value("qBt-paused", (isPaused && !isAutoManaged)); diff --git a/src/base/bittorrent/session.h b/src/base/bittorrent/session.h index ce421c593..89d0179a9 100644 --- a/src/base/bittorrent/session.h +++ b/src/base/bittorrent/session.h @@ -47,54 +47,12 @@ #include "base/settingvalue.h" #include "base/tristatebool.h" #include "base/types.h" +#include "private/libtorrentfwd.h" #include "addtorrentparams.h" #include "cachestatus.h" #include "sessionstatus.h" #include "torrentinfo.h" -namespace libtorrent -{ - class session; - struct torrent_handle; - class entry; - struct ip_filter; - struct settings_pack; - - class alert; - struct torrent_alert; - struct state_update_alert; - struct stats_alert; - struct add_torrent_alert; - struct torrent_checked_alert; - struct torrent_finished_alert; - struct torrent_removed_alert; - struct torrent_deleted_alert; - struct torrent_delete_failed_alert; - struct torrent_paused_alert; - struct torrent_resumed_alert; - struct save_resume_data_alert; - struct save_resume_data_failed_alert; - struct file_renamed_alert; - struct storage_moved_alert; - struct storage_moved_failed_alert; - struct metadata_received_alert; - struct file_error_alert; - struct file_completed_alert; - struct tracker_error_alert; - struct tracker_reply_alert; - struct tracker_warning_alert; - struct portmap_error_alert; - struct portmap_alert; - struct peer_blocked_alert; - struct peer_ban_alert; - struct fastresume_rejected_alert; - struct url_seed_alert; - struct listen_succeeded_alert; - struct listen_failed_alert; - struct external_ip_alert; - struct session_stats_alert; -} - class QThread; class QTimer; class QStringList; diff --git a/src/base/bittorrent/torrentcreatorthread.cpp b/src/base/bittorrent/torrentcreatorthread.cpp index 76b92b822..fff8a15ca 100644 --- a/src/base/bittorrent/torrentcreatorthread.cpp +++ b/src/base/bittorrent/torrentcreatorthread.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -47,6 +48,12 @@ namespace { +#if (LIBTORRENT_VERSION_NUM < 10200) + using CreateFlags = int; +#else + using CreateFlags = lt::create_flags_t; +#endif + // do not include files and folders whose // name starts with a . bool fileFilter(const std::string &f) @@ -131,7 +138,7 @@ void TorrentCreatorThread::run() if (isInterruptionRequested()) return; libt::create_torrent newTorrent(fs, m_params.pieceSize, -1 - , (m_params.isAlignmentOptimized ? libt::create_torrent::optimize_alignment : 0)); + , (m_params.isAlignmentOptimized ? libt::create_torrent::optimize_alignment : CreateFlags {})); // Add url seeds for (QString seed : asConst(m_params.urlSeeds)) { @@ -203,5 +210,5 @@ int TorrentCreatorThread::calculateTotalPieces(const QString &inputPath, const i libt::add_files(fs, Utils::Fs::toNativePath(inputPath).toStdString(), fileFilter); return libt::create_torrent(fs, pieceSize, -1 - , (isAlignmentOptimized ? libt::create_torrent::optimize_alignment : 0)).num_pieces(); + , (isAlignmentOptimized ? libt::create_torrent::optimize_alignment : CreateFlags {})).num_pieces(); } diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp index 51c3a2a3f..537525b17 100644 --- a/src/base/bittorrent/torrenthandle.cpp +++ b/src/base/bittorrent/torrenthandle.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -69,6 +70,28 @@ using namespace BitTorrent; namespace { +#if (LIBTORRENT_VERSION_NUM < 10200) + using LTDownloadPriority = int; + using LTDownloadPriorityUnderlyingType = int; + using LTQueuePosition = int; +#else + using LTDownloadPriority = lt::download_priority_t; + using LTDownloadPriorityUnderlyingType = lt::download_priority_t::underlying_type; + using LTQueuePosition = lt::queue_position_t; +#endif + + std::vector toLTDownloadPriorities(const QVector &priorities) + { + std::vector out; + std::transform(priorities.cbegin(), priorities.cend() + , std::back_inserter(out), [](BitTorrent::DownloadPriority priority) + { + return static_cast( + static_cast(priority)); + }); + return out; + } + using ListType = libt::entry::list_type; ListType setToEntryList(const QSet &input) @@ -635,11 +658,21 @@ QStringList TorrentHandle::absoluteFilePathsUnwanted() const return res; } -QVector TorrentHandle::filePriorities() const +QVector TorrentHandle::filePriorities() const { - const std::vector fp = m_nativeHandle.file_priorities(); +#if (LIBTORRENT_VERSION_NUM < 10200) + const std::vector fp = m_nativeHandle.file_priorities(); +#else + const std::vector fp = m_nativeHandle.get_file_priorities(); +#endif - return QVector::fromStdVector(fp); + QVector ret; + std::transform(fp.cbegin(), fp.cend(), std::back_inserter(ret), [](LTDownloadPriority priority) + { + return static_cast( + static_cast::type>(priority)); + }); + return ret; } TorrentInfo TorrentHandle::info() const @@ -838,18 +871,22 @@ bool TorrentHandle::hasError() const bool TorrentHandle::hasFilteredPieces() const { - const std::vector pp = m_nativeHandle.piece_priorities(); - return std::any_of(pp.cbegin(), pp.cend(), [](const int priority) +#if (LIBTORRENT_VERSION_NUM < 10200) + const std::vector pp = m_nativeHandle.piece_priorities(); +#else + const std::vector pp = m_nativeHandle.get_piece_priorities(); +#endif + return std::any_of(pp.cbegin(), pp.cend(), [](const LTDownloadPriority priority) { - return (priority == 0); + return (priority == LTDownloadPriority {0}); }); } int TorrentHandle::queuePosition() const { - if (m_nativeStatus.queue_position < 0) return 0; + if (m_nativeStatus.queue_position < LTQueuePosition {0}) return 0; - return m_nativeStatus.queue_position + 1; + return static_cast(m_nativeStatus.queue_position) + 1; } QString TorrentHandle::error() const @@ -1244,7 +1281,7 @@ void TorrentHandle::setFirstLastPiecePriority(const bool enabled) setFirstLastPiecePriorityImpl(enabled); } -void TorrentHandle::setFirstLastPiecePriorityImpl(const bool enabled, const QVector &updatedFilePrio) +void TorrentHandle::setFirstLastPiecePriorityImpl(const bool enabled, const QVector &updatedFilePrio) { // Download first and last pieces first for every file in the torrent @@ -1253,17 +1290,24 @@ void TorrentHandle::setFirstLastPiecePriorityImpl(const bool enabled, const QVec return; } +#if (LIBTORRENT_VERSION_NUM < 10200) + const std::vector filePriorities = !updatedFilePrio.isEmpty() ? toLTDownloadPriorities(updatedFilePrio) + : nativeHandle().file_priorities(); + std::vector piecePriorities = nativeHandle().piece_priorities(); +#else + const std::vector filePriorities = !updatedFilePrio.isEmpty() ? toLTDownloadPriorities(updatedFilePrio) + : nativeHandle().get_file_priorities(); + std::vector piecePriorities = nativeHandle().get_piece_priorities(); +#endif // Updating file priorities is an async operation in libtorrent, when we just updated it and immediately query it // we might get the old/wrong values, so we rely on `updatedFilePrio` in this case. - const std::vector filePriorities = !updatedFilePrio.isEmpty() ? updatedFilePrio.toStdVector() : nativeHandle().file_priorities(); - std::vector piecePriorities = nativeHandle().piece_priorities(); for (int index = 0; index < static_cast(filePriorities.size()); ++index) { - const int filePrio = filePriorities[index]; - if (filePrio <= 0) + const LTDownloadPriority filePrio = filePriorities[index]; + if (filePrio <= LTDownloadPriority {0}) continue; // Determine the priority to set - const int newPrio = enabled ? 7 : filePrio; + const int newPrio = enabled ? LTDownloadPriority {7} : filePrio; const TorrentInfo::PieceRange extremities = info().filePieces(index); // worst case: AVI index = 1% of total file size (at the end of the file) @@ -1349,8 +1393,11 @@ void TorrentHandle::renameFile(int index, const QString &name) bool TorrentHandle::saveTorrentFile(const QString &path) { if (!m_torrentInfo.isValid()) return false; - +#if (LIBTORRENT_VERSION_NUM < 10200) const libt::create_torrent torrentCreator = libt::create_torrent(*(m_torrentInfo.nativeInfo()), true); +#else + const libt::create_torrent torrentCreator = libt::create_torrent(*(m_torrentInfo.nativeInfo())); +#endif const libt::entry torrentEntry = torrentCreator.generate(); QVector out; @@ -1572,7 +1619,7 @@ void TorrentHandle::handleSaveResumeDataAlert(const libtorrent::save_resume_data resumeData["qBt-name"] = m_name.toStdString(); resumeData["qBt-seedStatus"] = m_hasSeedStatus; resumeData["qBt-tempPathDisabled"] = m_tempPathDisabled; - resumeData["qBt-queuePosition"] = (nativeHandle().queue_position() + 1); // qBt starts queue at 1 + resumeData["qBt-queuePosition"] = (static_cast(nativeHandle().queue_position()) + 1); // qBt starts queue at 1 resumeData["qBt-hasRootFolder"] = m_hasRootFolder; m_session->handleTorrentResumeDataReady(this, resumeData); @@ -1916,7 +1963,7 @@ QString TorrentHandle::toMagnetUri() const return QString::fromStdString(libt::make_magnet_uri(m_nativeHandle)); } -void TorrentHandle::prioritizeFiles(const QVector &priorities) +void TorrentHandle::prioritizeFiles(const QVector &priorities) { if (!hasMetadata()) return; if (priorities.size() != filesCount()) return; @@ -1927,23 +1974,25 @@ void TorrentHandle::prioritizeFiles(const QVector &priorities) // Reset 'm_hasSeedStatus' if needed in order to react again to // 'torrent_finished_alert' and eg show tray notifications const QVector progress = filesProgress(); - const QVector oldPriorities = filePriorities(); + const QVector oldPriorities = filePriorities(); for (int i = 0; i < oldPriorities.size(); ++i) { - if ((oldPriorities[i] == 0) && (priorities[i] > 0) && (progress[i] < 1.0)) { + if ((oldPriorities[i] == DownloadPriority::Ignored) + && (priorities[i] > DownloadPriority::Ignored) + && (progress[i] < 1.0)) { m_hasSeedStatus = false; break; } } qDebug() << Q_FUNC_INFO << "Changing files priorities..."; - m_nativeHandle.prioritize_files(priorities.toStdVector()); + m_nativeHandle.prioritize_files(toLTDownloadPriorities(priorities)); qDebug() << Q_FUNC_INFO << "Moving unwanted files to .unwanted folder and conversely..."; const QString spath = savePath(true); for (int i = 0; i < priorities.size(); ++i) { const QString filepath = filePath(i); // Move unwanted files to a .unwanted subfolder - if (priorities[i] == 0) { + if (priorities[i] == DownloadPriority::Ignored) { const QString oldAbsPath = QDir(spath).absoluteFilePath(filepath); const QString parentAbsPath = Utils::Fs::branchPath(oldAbsPath); // Make sure the file does not already exists @@ -1976,7 +2025,7 @@ void TorrentHandle::prioritizeFiles(const QVector &priorities) } // Move wanted files back to their original folder - if (priorities[i] > 0) { + if (priorities[i] > DownloadPriority::Ignored) { const QString parentRelPath = Utils::Fs::branchPath(filepath); if (QDir(parentRelPath).dirName() == ".unwanted") { const QString oldName = Utils::Fs::fileName(filepath); diff --git a/src/base/bittorrent/torrenthandle.h b/src/base/bittorrent/torrenthandle.h index 96e3c127f..7a0b0d29b 100644 --- a/src/base/bittorrent/torrenthandle.h +++ b/src/base/bittorrent/torrenthandle.h @@ -42,7 +42,9 @@ #include #include +#include "private/libtorrentfwd.h" #include "private/speedmonitor.h" +#include "downloadpriority.h" #include "infohash.h" #include "torrentinfo.h" @@ -53,29 +55,6 @@ class QDateTime; class QStringList; class QUrl; -namespace libtorrent -{ - class alert; - struct fastresume_rejected_alert; - struct file_completed_alert; - struct file_renamed_alert; - struct file_rename_failed_alert; - struct metadata_received_alert; - struct save_resume_data_alert; - struct save_resume_data_failed_alert; - struct stats_alert; - struct storage_moved_alert; - struct storage_moved_failed_alert; - struct torrent_checked_alert; - struct torrent_finished_alert; - struct torrent_paused_alert; - struct torrent_resumed_alert; - struct torrent_status; - struct tracker_error_alert; - struct tracker_reply_alert; - struct tracker_warning_alert; -} - namespace BitTorrent { class PeerInfo; @@ -103,7 +82,7 @@ namespace BitTorrent int uploadLimit; int downloadLimit; // for new torrents - QVector filePriorities; + QVector filePriorities; // for restored torrents qreal ratioLimit; int seedingTimeLimit; @@ -258,7 +237,7 @@ namespace BitTorrent qlonglong fileSize(int index) const; QStringList absoluteFilePaths() const; QStringList absoluteFilePathsUnwanted() const; - QVector filePriorities() const; + QVector filePriorities() const; TorrentInfo info() const; bool isSeed() const; @@ -337,7 +316,7 @@ namespace BitTorrent void forceRecheck(); void renameFile(int index, const QString &name); bool saveTorrentFile(const QString &path); - void prioritizeFiles(const QVector &priorities); + void prioritizeFiles(const QVector &priorities); void setRatioLimit(qreal limit); void setSeedingTimeLimit(int limit); void setUploadLimit(int limit); @@ -410,7 +389,7 @@ namespace BitTorrent bool addTracker(const TrackerEntry &tracker); bool addUrlSeed(const QUrl &urlSeed); bool removeUrlSeed(const QUrl &urlSeed); - void setFirstLastPiecePriorityImpl(bool enabled, const QVector &updatedFilePrio = {}); + void setFirstLastPiecePriorityImpl(bool enabled, const QVector &updatedFilePrio = {}); Session *const m_session; libtorrent::torrent_handle m_nativeHandle; diff --git a/src/base/bittorrent/torrentinfo.cpp b/src/base/bittorrent/torrentinfo.cpp index ef383de80..1f75e44b5 100644 --- a/src/base/bittorrent/torrentinfo.cpp +++ b/src/base/bittorrent/torrentinfo.cpp @@ -28,6 +28,7 @@ #include "torrentinfo.h" +#include #include #include @@ -42,12 +43,27 @@ #include "infohash.h" #include "trackerentry.h" +namespace +{ +#if (LIBTORRENT_VERSION_NUM < 10200) + using LTPieceIndex = int; + using LTFileIndex = int; +#else + using LTPieceIndex = lt::piece_index_t; + using LTFileIndex = lt::file_index_t; +#endif +} + namespace libt = libtorrent; using namespace BitTorrent; TorrentInfo::TorrentInfo(NativeConstPtr nativeInfo) { +#if (LIBTORRENT_VERSION_NUM < 10200) m_nativeInfo = boost::const_pointer_cast(nativeInfo); +#else + m_nativeInfo = std::const_pointer_cast(nativeInfo); +#endif } TorrentInfo::TorrentInfo(const TorrentInfo &other) @@ -190,7 +206,7 @@ int TorrentInfo::pieceLength() const int TorrentInfo::pieceLength(const int index) const { if (!isValid()) return -1; - return m_nativeInfo->piece_size(index); + return m_nativeInfo->piece_size(LTPieceIndex {index}); } int TorrentInfo::piecesCount() const @@ -202,7 +218,8 @@ int TorrentInfo::piecesCount() const QString TorrentInfo::filePath(const int index) const { if (!isValid()) return {}; - return Utils::Fs::fromNativePath(QString::fromStdString(m_nativeInfo->files().file_path(index))); + return Utils::Fs::fromNativePath( + QString::fromStdString(m_nativeInfo->files().file_path(LTFileIndex {index}))); } QStringList TorrentInfo::filePaths() const @@ -222,19 +239,20 @@ QString TorrentInfo::fileName(const int index) const QString TorrentInfo::origFilePath(const int index) const { if (!isValid()) return {}; - return Utils::Fs::fromNativePath(QString::fromStdString(m_nativeInfo->orig_files().file_path(index))); + return Utils::Fs::fromNativePath( + QString::fromStdString(m_nativeInfo->orig_files().file_path(LTFileIndex {index}))); } qlonglong TorrentInfo::fileSize(const int index) const { if (!isValid()) return -1; - return m_nativeInfo->files().file_size(index); + return m_nativeInfo->files().file_size(LTFileIndex {index}); } qlonglong TorrentInfo::fileOffset(const int index) const { if (!isValid()) return -1; - return m_nativeInfo->files().file_offset(index); + return m_nativeInfo->files().file_offset(LTFileIndex {index}); } QList TorrentInfo::trackers() const @@ -285,11 +303,12 @@ QVector TorrentInfo::fileIndicesForPiece(const int pieceIndex) const return {}; const std::vector files( - nativeInfo()->map_block(pieceIndex, 0, nativeInfo()->piece_size(pieceIndex))); + nativeInfo()->map_block(LTPieceIndex {pieceIndex}, 0 + , nativeInfo()->piece_size(LTPieceIndex {pieceIndex}))); QVector res; res.reserve(int(files.size())); std::transform(files.begin(), files.end(), std::back_inserter(res), - [](const libt::file_slice &s) { return s.file_index; }); + [](const libt::file_slice &s) { return static_cast(s.file_index); }); return res; } @@ -304,7 +323,7 @@ QVector TorrentInfo::pieceHashes() const hashes.reserve(count); for (int i = 0; i < count; ++i) - hashes += { m_nativeInfo->hash_for_piece_ptr(i), libtorrent::sha1_hash::size }; + hashes += {m_nativeInfo->hash_for_piece_ptr(LTPieceIndex {i}), InfoHash::length()}; return hashes; } @@ -333,8 +352,8 @@ TorrentInfo::PieceRange TorrentInfo::filePieces(const int fileIndex) const } const libt::file_storage &files = nativeInfo()->files(); - const auto fileSize = files.file_size(fileIndex); - const auto fileOffset = files.file_offset(fileIndex); + const auto fileSize = files.file_size(LTFileIndex {fileIndex}); + const auto fileOffset = files.file_offset(LTFileIndex {fileIndex}); return makeInterval(static_cast(fileOffset / pieceLength()), static_cast((fileOffset + fileSize - 1) / pieceLength())); } diff --git a/src/base/bittorrent/torrentinfo.h b/src/base/bittorrent/torrentinfo.h index cc5d3865a..ea6216abe 100644 --- a/src/base/bittorrent/torrentinfo.h +++ b/src/base/bittorrent/torrentinfo.h @@ -30,12 +30,14 @@ #define BITTORRENT_TORRENTINFO_H #include +#include #include #include #include #include "base/indexrange.h" +#include "private/libtorrentfwd.h" class QByteArray; class QDateTime; @@ -53,8 +55,13 @@ namespace BitTorrent Q_DECLARE_TR_FUNCTIONS(TorrentInfo) public: - typedef boost::shared_ptr NativeConstPtr; - typedef boost::shared_ptr NativePtr; +#if (LIBTORRENT_VERSION_NUM < 10200) + using NativeConstPtr = boost::shared_ptr; + using NativePtr = boost::shared_ptr; +#else + using NativeConstPtr = std::shared_ptr; + using NativePtr = std::shared_ptr; +#endif explicit TorrentInfo(NativeConstPtr nativeInfo = {}); TorrentInfo(const TorrentInfo &other); diff --git a/src/base/bittorrent/trackerentry.cpp b/src/base/bittorrent/trackerentry.cpp index 256149d26..885dd8e72 100644 --- a/src/base/bittorrent/trackerentry.cpp +++ b/src/base/bittorrent/trackerentry.cpp @@ -28,6 +28,10 @@ #include "trackerentry.h" +#include + +#include + #include #include @@ -48,6 +52,19 @@ QString TrackerEntry::url() const return QString::fromStdString(m_nativeEntry.url); } +bool TrackerEntry::isWorking() const +{ +#if (LIBTORRENT_VERSION_NUM < 10200) + return m_nativeEntry.is_working(); +#else + return std::any_of(m_nativeEntry.endpoints.begin(), m_nativeEntry.endpoints.end() + , [](const lt::announce_endpoint &endpoint) + { + return endpoint.is_working(); + }); +#endif +} + int TrackerEntry::tier() const { return m_nativeEntry.tier; @@ -57,7 +74,7 @@ TrackerEntry::Status TrackerEntry::status() const { // libtorrent::announce_entry::is_working() returns // true when the tracker hasn't been tried yet. - if (m_nativeEntry.verified && m_nativeEntry.is_working()) + if (m_nativeEntry.verified && isWorking()) return Working; if ((m_nativeEntry.fails == 0) && m_nativeEntry.updating) return Updating; @@ -72,6 +89,36 @@ void TrackerEntry::setTier(const int value) m_nativeEntry.tier = value; } +int TrackerEntry::numSeeds() const +{ +#if (LIBTORRENT_VERSION_NUM < 10200) + return nativeEntry().scrape_complete; +#else + // FIXME: Handle all possible endpoints. + return nativeEntry().endpoints.empty() ? -1 : nativeEntry().endpoints[0].scrape_complete; +#endif +} + +int TrackerEntry::numLeeches() const +{ +#if (LIBTORRENT_VERSION_NUM < 10200) + return nativeEntry().scrape_incomplete; +#else + // FIXME: Handle all possible endpoints. + return nativeEntry().endpoints.empty() ? -1 : nativeEntry().endpoints[0].scrape_incomplete; +#endif +} + +int TrackerEntry::numDownloaded() const +{ +#if (LIBTORRENT_VERSION_NUM < 10200) + return nativeEntry().scrape_downloaded; +#else + // FIXME: Handle all possible endpoints. + return nativeEntry().endpoints.empty() ? -1 : nativeEntry().endpoints[0].scrape_downloaded; +#endif +} + libtorrent::announce_entry TrackerEntry::nativeEntry() const { return m_nativeEntry; diff --git a/src/base/bittorrent/trackerentry.h b/src/base/bittorrent/trackerentry.h index e0c95b853..8806a1f16 100644 --- a/src/base/bittorrent/trackerentry.h +++ b/src/base/bittorrent/trackerentry.h @@ -53,11 +53,16 @@ namespace BitTorrent TrackerEntry &operator=(const TrackerEntry &other) = default; QString url() const; + bool isWorking() const; Status status() const; int tier() const; void setTier(int value); + int numSeeds() const; + int numLeeches() const; + int numDownloaded() const; + libtorrent::announce_entry nativeEntry() const; private: diff --git a/src/base/net/portforwarder.cpp b/src/base/net/portforwarder.cpp index 15314081e..f1548ba01 100644 --- a/src/base/net/portforwarder.cpp +++ b/src/base/net/portforwarder.cpp @@ -28,110 +28,21 @@ #include "portforwarder.h" -#include - -#include - -#include "base/logger.h" -#include "base/settingsstorage.h" - -static const QString KEY_ENABLED = QStringLiteral("Network/PortForwardingEnabled"); - -namespace libt = libtorrent; -using namespace Net; - -PortForwarder::PortForwarder(libtorrent::session *provider, QObject *parent) - : QObject(parent) - , m_active(false) - , m_provider(provider) -{ - if (SettingsStorage::instance()->loadValue(KEY_ENABLED, true).toBool()) - start(); -} - -PortForwarder::~PortForwarder() +Net::PortForwarder::PortForwarder(QObject *parent) + : QObject {parent} { - stop(); + Q_ASSERT(!m_instance); + m_instance = this; } -void PortForwarder::initInstance(libtorrent::session *const provider) +Net::PortForwarder::~PortForwarder() { - if (!m_instance) - m_instance = new PortForwarder(provider); + m_instance = nullptr; } -void PortForwarder::freeInstance() -{ - if (m_instance) { - delete m_instance; - m_instance = nullptr; - } -} - -PortForwarder *PortForwarder::instance() +Net::PortForwarder *Net::PortForwarder::instance() { return m_instance; } -bool PortForwarder::isEnabled() const -{ - return m_active; -} - -void PortForwarder::setEnabled(const bool enabled) -{ - if (m_active != enabled) { - if (enabled) - start(); - else - stop(); - - SettingsStorage::instance()->storeValue(KEY_ENABLED, enabled); - } -} - -void PortForwarder::addPort(const quint16 port) -{ - if (!m_mappedPorts.contains(port)) { - m_mappedPorts.insert(port, 0); - if (m_active) - m_mappedPorts[port] = m_provider->add_port_mapping(libt::session::tcp, port, port); - } -} - -void PortForwarder::deletePort(const quint16 port) -{ - if (m_mappedPorts.contains(port)) { - if (m_active) - m_provider->delete_port_mapping(m_mappedPorts[port]); - m_mappedPorts.remove(port); - } -} - -void PortForwarder::start() -{ - qDebug("Enabling UPnP / NAT-PMP"); - libt::settings_pack settingsPack = m_provider->get_settings(); - settingsPack.set_bool(libt::settings_pack::enable_upnp, true); - settingsPack.set_bool(libt::settings_pack::enable_natpmp, true); - m_provider->apply_settings(settingsPack); - for (auto i = m_mappedPorts.begin(); i != m_mappedPorts.end(); ++i) { - // quint16 port = i.key(); - i.value() = m_provider->add_port_mapping(libt::session::tcp, i.key(), i.key()); - } - m_active = true; - Logger::instance()->addMessage(tr("UPnP / NAT-PMP support [ON]"), Log::INFO); -} - -void PortForwarder::stop() -{ - qDebug("Disabling UPnP / NAT-PMP"); - libt::settings_pack settingsPack = m_provider->get_settings(); - settingsPack.set_bool(libt::settings_pack::enable_upnp, false); - settingsPack.set_bool(libt::settings_pack::enable_natpmp, false); - m_provider->apply_settings(settingsPack); - m_active = false; - Logger::instance()->addMessage(tr("UPnP / NAT-PMP support [OFF]"), Log::INFO); -} - -PortForwarder *PortForwarder::m_instance = nullptr; +Net::PortForwarder *Net::PortForwarder::m_instance = nullptr; diff --git a/src/base/net/portforwarder.h b/src/base/net/portforwarder.h index 86ce8d028..64b0c09b0 100644 --- a/src/base/net/portforwarder.h +++ b/src/base/net/portforwarder.h @@ -29,43 +29,27 @@ #ifndef NET_PORTFORWARDER_H #define NET_PORTFORWARDER_H -#include #include -namespace libtorrent -{ - class session; -} - namespace Net { class PortForwarder : public QObject { - Q_OBJECT Q_DISABLE_COPY(PortForwarder) public: - static void initInstance(libtorrent::session *const provider); - static void freeInstance(); + explicit PortForwarder(QObject *parent = nullptr); + ~PortForwarder() override; + static PortForwarder *instance(); - bool isEnabled() const; - void setEnabled(bool enabled); + virtual bool isEnabled() const = 0; + virtual void setEnabled(bool enabled) = 0; - void addPort(quint16 port); - void deletePort(quint16 port); + virtual void addPort(quint16 port) = 0; + virtual void deletePort(quint16 port) = 0; private: - explicit PortForwarder(libtorrent::session *const provider, QObject *parent = nullptr); - ~PortForwarder(); - - void start(); - void stop(); - - bool m_active; - libtorrent::session *m_provider; - QHash m_mappedPorts; - static PortForwarder *m_instance; }; } diff --git a/src/gui/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp index a38466c6f..45e39604e 100644 --- a/src/gui/addnewtorrentdialog.cpp +++ b/src/gui/addnewtorrentdialog.cpp @@ -37,7 +37,7 @@ #include #include -#include "base/bittorrent/filepriority.h" +#include "base/bittorrent/downloadpriority.h" #include "base/bittorrent/magneturi.h" #include "base/bittorrent/session.h" #include "base/bittorrent/torrenthandle.h" @@ -420,10 +420,10 @@ void AddNewTorrentDialog::updateDiskSpaceLabel() if (m_hasMetadata) { if (m_contentModel) { - const QVector priorities = m_contentModel->model()->getFilePriorities(); + const QVector priorities = m_contentModel->model()->getFilePriorities(); Q_ASSERT(priorities.size() == m_torrentInfo.filesCount()); for (int i = 0; i < priorities.size(); ++i) - if (priorities[i] > 0) + if (priorities[i] > BitTorrent::DownloadPriority::Ignored) torrentSize += m_torrentInfo.fileSize(i); } else { @@ -612,13 +612,13 @@ void AddNewTorrentDialog::displayContentTreeMenu(const QPoint &) renameSelectedFile(); } else { - BitTorrent::FilePriority prio = BitTorrent::FilePriority::Normal; + BitTorrent::DownloadPriority prio = BitTorrent::DownloadPriority::Normal; if (act == m_ui->actionHigh) - prio = BitTorrent::FilePriority::High; + prio = BitTorrent::DownloadPriority::High; else if (act == m_ui->actionMaximum) - prio = BitTorrent::FilePriority::Maximum; + prio = BitTorrent::DownloadPriority::Maximum; else if (act == m_ui->actionNotDownloaded) - prio = BitTorrent::FilePriority::Ignored; + prio = BitTorrent::DownloadPriority::Ignored; qDebug("Setting files priority"); for (const QModelIndex &index : selectedRows) { diff --git a/src/gui/properties/propertieswidget.cpp b/src/gui/properties/propertieswidget.cpp index 5b9a8fcee..eb10e0d0c 100644 --- a/src/gui/properties/propertieswidget.cpp +++ b/src/gui/properties/propertieswidget.cpp @@ -39,7 +39,7 @@ #include #include -#include "base/bittorrent/filepriority.h" +#include "base/bittorrent/downloadpriority.h" #include "base/bittorrent/session.h" #include "base/preferences.h" #include "base/unicodestrings.h" @@ -621,13 +621,13 @@ void PropertiesWidget::displayFilesListMenu(const QPoint &) renameSelectedFile(); } else { - BitTorrent::FilePriority prio = BitTorrent::FilePriority::Normal; + BitTorrent::DownloadPriority prio = BitTorrent::DownloadPriority::Normal; if (act == m_ui->actionHigh) - prio = BitTorrent::FilePriority::High; + prio = BitTorrent::DownloadPriority::High; else if (act == m_ui->actionMaximum) - prio = BitTorrent::FilePriority::Maximum; + prio = BitTorrent::DownloadPriority::Maximum; else if (act == m_ui->actionNotDownloaded) - prio = BitTorrent::FilePriority::Ignored; + prio = BitTorrent::DownloadPriority::Ignored; qDebug("Setting files priority"); for (const QModelIndex &index : selectedRows) { @@ -894,11 +894,7 @@ void PropertiesWidget::editWebSeed() void PropertiesWidget::applyPriorities() { - qDebug("Saving files priorities"); - const QVector priorities = m_propListModel->model()->getFilePriorities(); - // Prioritize the files - qDebug("prioritize files: %d", priorities[0]); - m_torrent->prioritizeFiles(priorities); + m_torrent->prioritizeFiles(m_propListModel->model()->getFilePriorities()); } void PropertiesWidget::filteredFilesChanged() diff --git a/src/gui/properties/proplistdelegate.cpp b/src/gui/properties/proplistdelegate.cpp index 45b6b3a65..9a1aa401d 100644 --- a/src/gui/properties/proplistdelegate.cpp +++ b/src/gui/properties/proplistdelegate.cpp @@ -40,7 +40,7 @@ #include #endif -#include "base/bittorrent/filepriority.h" +#include "base/bittorrent/downloadpriority.h" #include "base/unicodestrings.h" #include "base/utils/misc.h" #include "base/utils/string.h" @@ -93,7 +93,7 @@ void PropListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti newopt.maximum = 100; newopt.minimum = 0; newopt.textVisible = true; - if (index.sibling(index.row(), PRIORITY).data().toInt() == static_cast(BitTorrent::FilePriority::Ignored)) { + if (index.sibling(index.row(), PRIORITY).data().toInt() == static_cast(BitTorrent::DownloadPriority::Ignored)) { newopt.state &= ~QStyle::State_Enabled; newopt.palette = progressBarDisabledPalette(); } @@ -111,17 +111,17 @@ void PropListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti break; case PRIORITY: { QString text = ""; - switch (static_cast(index.data().toInt())) { - case BitTorrent::FilePriority::Mixed: + switch (static_cast(index.data().toInt())) { + case BitTorrent::DownloadPriority::Mixed: text = tr("Mixed", "Mixed (priorities"); break; - case BitTorrent::FilePriority::Ignored: + case BitTorrent::DownloadPriority::Ignored: text = tr("Not downloaded"); break; - case BitTorrent::FilePriority::High: + case BitTorrent::DownloadPriority::High: text = tr("High", "High (priority)"); break; - case BitTorrent::FilePriority::Maximum: + case BitTorrent::DownloadPriority::Maximum: text = tr("Maximum", "Maximum (priority)"); break; default: @@ -155,14 +155,14 @@ void PropListDelegate::setEditorData(QWidget *editor, const QModelIndex &index) { auto *combobox = static_cast(editor); // Set combobox index - switch (static_cast(index.data().toInt())) { - case BitTorrent::FilePriority::Ignored: + switch (static_cast(index.data().toInt())) { + case BitTorrent::DownloadPriority::Ignored: combobox->setCurrentIndex(0); break; - case BitTorrent::FilePriority::High: + case BitTorrent::DownloadPriority::High: combobox->setCurrentIndex(2); break; - case BitTorrent::FilePriority::Maximum: + case BitTorrent::DownloadPriority::Maximum: combobox->setCurrentIndex(3); break; default: @@ -181,7 +181,7 @@ QWidget *PropListDelegate::createEditor(QWidget *parent, const QStyleOptionViewI return nullptr; } - if (index.data().toInt() == static_cast(BitTorrent::FilePriority::Mixed)) + if (index.data().toInt() == static_cast(BitTorrent::DownloadPriority::Mixed)) return nullptr; auto *editor = new QComboBox(parent); @@ -199,16 +199,16 @@ void PropListDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, int value = combobox->currentIndex(); qDebug("PropListDelegate: setModelData(%d)", value); - BitTorrent::FilePriority prio = BitTorrent::FilePriority::Normal; // NORMAL + BitTorrent::DownloadPriority prio = BitTorrent::DownloadPriority::Normal; // NORMAL switch (value) { case 0: - prio = BitTorrent::FilePriority::Ignored; // IGNORED + prio = BitTorrent::DownloadPriority::Ignored; // IGNORED break; case 2: - prio = BitTorrent::FilePriority::High; // HIGH + prio = BitTorrent::DownloadPriority::High; // HIGH break; case 3: - prio = BitTorrent::FilePriority::Maximum; // MAX + prio = BitTorrent::DownloadPriority::Maximum; // MAX break; } diff --git a/src/gui/properties/trackerlistwidget.cpp b/src/gui/properties/trackerlistwidget.cpp index da83461fe..3ff949bd1 100644 --- a/src/gui/properties/trackerlistwidget.cpp +++ b/src/gui/properties/trackerlistwidget.cpp @@ -367,9 +367,9 @@ void TrackerListWidget::loadTrackers() } item->setText(COL_PEERS, QString::number(data.numPeers)); - item->setText(COL_SEEDS, (entry.nativeEntry().scrape_complete > -1) ? QString::number(entry.nativeEntry().scrape_complete) : tr("N/A")); - item->setText(COL_LEECHES, (entry.nativeEntry().scrape_incomplete > -1) ? QString::number(entry.nativeEntry().scrape_incomplete) : tr("N/A")); - item->setText(COL_DOWNLOADED, (entry.nativeEntry().scrape_downloaded > -1) ? QString::number(entry.nativeEntry().scrape_downloaded) : tr("N/A")); + item->setText(COL_SEEDS, (entry.numSeeds() > -1) ? QString::number(entry.numSeeds()) : tr("N/A")); + item->setText(COL_LEECHES, (entry.numLeeches() > -1) ? QString::number(entry.numLeeches()) : tr("N/A")); + item->setText(COL_DOWNLOADED, (entry.numDownloaded() > -1) ? QString::number(entry.numDownloaded()) : tr("N/A")); item->setTextAlignment(COL_TIER, (Qt::AlignRight | Qt::AlignVCenter)); item->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter)); diff --git a/src/gui/torrentcontentmodel.cpp b/src/gui/torrentcontentmodel.cpp index 9a284c93b..14c52ca54 100644 --- a/src/gui/torrentcontentmodel.cpp +++ b/src/gui/torrentcontentmodel.cpp @@ -50,7 +50,7 @@ #include #endif -#include "base/bittorrent/filepriority.h" +#include "base/bittorrent/downloadpriority.h" #include "base/global.h" #include "base/utils/misc.h" #include "base/utils/fs.h" @@ -239,7 +239,7 @@ void TorrentContentModel::updateFilesProgress(const QVector &fp) emit dataChanged(index(0, 0), index(rowCount(), columnCount())); } -void TorrentContentModel::updateFilesPriorities(const QVector &fprio) +void TorrentContentModel::updateFilesPriorities(const QVector &fprio) { Q_ASSERT(m_filesIndex.size() == fprio.size()); // XXX: Why is this necessary? @@ -248,7 +248,7 @@ void TorrentContentModel::updateFilesPriorities(const QVector &fprio) emit layoutAboutToBeChanged(); for (int i = 0; i < fprio.size(); ++i) - m_filesIndex[i]->setPriority(static_cast(fprio[i])); + m_filesIndex[i]->setPriority(static_cast(fprio[i])); emit dataChanged(index(0, 0), index(rowCount(), columnCount())); } @@ -266,12 +266,12 @@ void TorrentContentModel::updateFilesAvailability(const QVector &fa) emit dataChanged(index(0, 0), index(rowCount(), columnCount())); } -QVector TorrentContentModel::getFilePriorities() const +QVector TorrentContentModel::getFilePriorities() const { - QVector prio; + QVector prio; prio.reserve(m_filesIndex.size()); for (const TorrentContentModelFile *file : asConst(m_filesIndex)) - prio.push_back(static_cast(file->priority())); + prio.push_back(file->priority()); return prio; } @@ -279,7 +279,7 @@ bool TorrentContentModel::allFiltered() const { return std::all_of(m_filesIndex.cbegin(), m_filesIndex.cend(), [](const TorrentContentModelFile *fileItem) { - return (fileItem->priority() == BitTorrent::FilePriority::Ignored); + return (fileItem->priority() == BitTorrent::DownloadPriority::Ignored); }); } @@ -300,11 +300,11 @@ bool TorrentContentModel::setData(const QModelIndex &index, const QVariant &valu auto *item = static_cast(index.internalPointer()); qDebug("setData(%s, %d", qUtf8Printable(item->name()), value.toInt()); if (static_cast(item->priority()) != value.toInt()) { - BitTorrent::FilePriority prio = BitTorrent::FilePriority::Normal; + BitTorrent::DownloadPriority prio = BitTorrent::DownloadPriority::Normal; if (value.toInt() == Qt::PartiallyChecked) - prio = BitTorrent::FilePriority::Mixed; + prio = BitTorrent::DownloadPriority::Mixed; else if (value.toInt() == Qt::Unchecked) - prio = BitTorrent::FilePriority::Ignored; + prio = BitTorrent::DownloadPriority::Ignored; item->setPriority(prio); // Update folders progress in the tree @@ -324,7 +324,7 @@ bool TorrentContentModel::setData(const QModelIndex &index, const QVariant &valu item->setName(value.toString()); break; case TorrentContentModelItem::COL_PRIO: - item->setPriority(static_cast(value.toInt())); + item->setPriority(static_cast(value.toInt())); break; default: return false; @@ -366,9 +366,9 @@ QVariant TorrentContentModel::data(const QModelIndex &index, int role) const } if ((index.column() == TorrentContentModelItem::COL_NAME) && (role == Qt::CheckStateRole)) { - if (item->data(TorrentContentModelItem::COL_PRIO).toInt() == static_cast(BitTorrent::FilePriority::Ignored)) + if (item->data(TorrentContentModelItem::COL_PRIO).toInt() == static_cast(BitTorrent::DownloadPriority::Ignored)) return Qt::Unchecked; - if (item->data(TorrentContentModelItem::COL_PRIO).toInt() == static_cast(BitTorrent::FilePriority::Mixed)) + if (item->data(TorrentContentModelItem::COL_PRIO).toInt() == static_cast(BitTorrent::DownloadPriority::Mixed)) return Qt::PartiallyChecked; return Qt::Checked; } @@ -503,8 +503,8 @@ void TorrentContentModel::selectAll() { for (int i = 0; i < m_rootItem->childCount(); ++i) { TorrentContentModelItem* child = m_rootItem->child(i); - if (child->priority() == BitTorrent::FilePriority::Ignored) - child->setPriority(BitTorrent::FilePriority::Normal); + if (child->priority() == BitTorrent::DownloadPriority::Ignored) + child->setPriority(BitTorrent::DownloadPriority::Normal); } emit dataChanged(index(0, 0), index(rowCount(), columnCount())); } @@ -512,6 +512,6 @@ void TorrentContentModel::selectAll() void TorrentContentModel::selectNone() { for (int i = 0; i < m_rootItem->childCount(); ++i) - m_rootItem->child(i)->setPriority(BitTorrent::FilePriority::Ignored); + m_rootItem->child(i)->setPriority(BitTorrent::DownloadPriority::Ignored); emit dataChanged(index(0, 0), index(rowCount(), columnCount())); } diff --git a/src/gui/torrentcontentmodel.h b/src/gui/torrentcontentmodel.h index 1f6980af2..fda753aad 100644 --- a/src/gui/torrentcontentmodel.h +++ b/src/gui/torrentcontentmodel.h @@ -43,15 +43,16 @@ class TorrentContentModelFile; class TorrentContentModel : public QAbstractItemModel { Q_OBJECT + Q_DISABLE_COPY(TorrentContentModel) public: TorrentContentModel(QObject *parent = nullptr); ~TorrentContentModel() override; void updateFilesProgress(const QVector &fp); - void updateFilesPriorities(const QVector &fprio); + void updateFilesPriorities(const QVector &fprio); void updateFilesAvailability(const QVector &fa); - QVector getFilePriorities() const; + QVector getFilePriorities() const; bool allFiltered() const; int columnCount(const QModelIndex &parent = {}) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; diff --git a/src/gui/torrentcontentmodelfile.cpp b/src/gui/torrentcontentmodelfile.cpp index cb6a8aa0f..ceeccbfc9 100644 --- a/src/gui/torrentcontentmodelfile.cpp +++ b/src/gui/torrentcontentmodelfile.cpp @@ -52,9 +52,9 @@ int TorrentContentModelFile::fileIndex() const return m_fileIndex; } -void TorrentContentModelFile::setPriority(BitTorrent::FilePriority newPriority, bool updateParent) +void TorrentContentModelFile::setPriority(BitTorrent::DownloadPriority newPriority, bool updateParent) { - Q_ASSERT(newPriority != BitTorrent::FilePriority::Mixed); + Q_ASSERT(newPriority != BitTorrent::DownloadPriority::Mixed); if (m_priority == newPriority) return; diff --git a/src/gui/torrentcontentmodelfile.h b/src/gui/torrentcontentmodelfile.h index 00c371a5b..ff972c4b5 100644 --- a/src/gui/torrentcontentmodelfile.h +++ b/src/gui/torrentcontentmodelfile.h @@ -29,7 +29,7 @@ #ifndef TORRENTCONTENTMODELFILE_H #define TORRENTCONTENTMODELFILE_H -#include "base/bittorrent/filepriority.h" +#include "base/bittorrent/downloadpriority.h" #include "torrentcontentmodelitem.h" class TorrentContentModelFile : public TorrentContentModelItem @@ -39,7 +39,7 @@ public: TorrentContentModelFolder *parent, int fileIndex); int fileIndex() const; - void setPriority(BitTorrent::FilePriority newPriority, bool updateParent = true) override; + void setPriority(BitTorrent::DownloadPriority newPriority, bool updateParent = true) override; void setProgress(qreal progress); void setAvailability(qreal availability); ItemType itemType() const override; diff --git a/src/gui/torrentcontentmodelfolder.cpp b/src/gui/torrentcontentmodelfolder.cpp index 3851c4a93..75870a5ce 100644 --- a/src/gui/torrentcontentmodelfolder.cpp +++ b/src/gui/torrentcontentmodelfolder.cpp @@ -109,10 +109,10 @@ void TorrentContentModelFolder::updatePriority() // If all children have the same priority // then the folder should have the same // priority - const BitTorrent::FilePriority prio = m_childItems.first()->priority(); + const BitTorrent::DownloadPriority prio = m_childItems.first()->priority(); for (int i = 1; i < m_childItems.size(); ++i) { if (m_childItems.at(i)->priority() != prio) { - setPriority(BitTorrent::FilePriority::Mixed); + setPriority(BitTorrent::DownloadPriority::Mixed); return; } } @@ -121,7 +121,7 @@ void TorrentContentModelFolder::updatePriority() setPriority(prio); } -void TorrentContentModelFolder::setPriority(BitTorrent::FilePriority newPriority, bool updateParent) +void TorrentContentModelFolder::setPriority(BitTorrent::DownloadPriority newPriority, bool updateParent) { if (m_priority == newPriority) return; @@ -133,7 +133,7 @@ void TorrentContentModelFolder::setPriority(BitTorrent::FilePriority newPriority m_parentItem->updatePriority(); // Update children - if (m_priority != BitTorrent::FilePriority::Mixed) + if (m_priority != BitTorrent::DownloadPriority::Mixed) for (TorrentContentModelItem *child : asConst(m_childItems)) child->setPriority(m_priority, false); } @@ -144,7 +144,7 @@ void TorrentContentModelFolder::recalculateProgress() qulonglong tSize = 0; qulonglong tRemaining = 0; for (TorrentContentModelItem *child : asConst(m_childItems)) { - if (child->priority() == BitTorrent::FilePriority::Ignored) + if (child->priority() == BitTorrent::DownloadPriority::Ignored) continue; if (child->itemType() == FolderType) @@ -167,7 +167,7 @@ void TorrentContentModelFolder::recalculateAvailability() qulonglong tSize = 0; bool foundAnyData = false; for (TorrentContentModelItem *child : asConst(m_childItems)) { - if (child->priority() == BitTorrent::FilePriority::Ignored) + if (child->priority() == BitTorrent::DownloadPriority::Ignored) continue; if (child->itemType() == FolderType) diff --git a/src/gui/torrentcontentmodelfolder.h b/src/gui/torrentcontentmodelfolder.h index 93019c269..6e41ef269 100644 --- a/src/gui/torrentcontentmodelfolder.h +++ b/src/gui/torrentcontentmodelfolder.h @@ -29,7 +29,7 @@ #ifndef TORRENTCONTENTMODELFOLDER_H #define TORRENTCONTENTMODELFOLDER_H -#include "base/bittorrent/filepriority.h" +#include "base/bittorrent/downloadpriority.h" #include "torrentcontentmodelitem.h" class TorrentContentModelFolder : public TorrentContentModelItem @@ -50,7 +50,7 @@ public: void recalculateAvailability(); void updatePriority(); - void setPriority(BitTorrent::FilePriority newPriority, bool updateParent = true) override; + void setPriority(BitTorrent::DownloadPriority newPriority, bool updateParent = true) override; void deleteAllChildren(); const QList &children() const; diff --git a/src/gui/torrentcontentmodelitem.cpp b/src/gui/torrentcontentmodelitem.cpp index 186275448..a6dc0402f 100644 --- a/src/gui/torrentcontentmodelitem.cpp +++ b/src/gui/torrentcontentmodelitem.cpp @@ -38,7 +38,7 @@ TorrentContentModelItem::TorrentContentModelItem(TorrentContentModelFolder *pare : m_parentItem(parent) , m_size(0) , m_remaining(0) - , m_priority(BitTorrent::FilePriority::Normal) + , m_priority(BitTorrent::DownloadPriority::Normal) , m_progress(0) , m_availability(-1.) { @@ -90,7 +90,7 @@ qreal TorrentContentModelItem::availability() const return (m_size > 0) ? m_availability : 0; } -BitTorrent::FilePriority TorrentContentModelItem::priority() const +BitTorrent::DownloadPriority TorrentContentModelItem::priority() const { Q_ASSERT(!isRootItem()); return m_priority; diff --git a/src/gui/torrentcontentmodelitem.h b/src/gui/torrentcontentmodelitem.h index 4b2b50e0a..84e55afb8 100644 --- a/src/gui/torrentcontentmodelitem.h +++ b/src/gui/torrentcontentmodelitem.h @@ -32,7 +32,7 @@ #include #include -#include "base/bittorrent/filepriority.h" +#include "base/bittorrent/downloadpriority.h" class TorrentContentModelFolder; @@ -72,8 +72,8 @@ public: qreal availability() const; - BitTorrent::FilePriority priority() const; - virtual void setPriority(BitTorrent::FilePriority newPriority, bool updateParent = true) = 0; + BitTorrent::DownloadPriority priority() const; + virtual void setPriority(BitTorrent::DownloadPriority newPriority, bool updateParent = true) = 0; int columnCount() const; QVariant data(int column) const; @@ -87,7 +87,7 @@ protected: QString m_name; qulonglong m_size; qulonglong m_remaining; - BitTorrent::FilePriority m_priority; + BitTorrent::DownloadPriority m_priority; qreal m_progress; qreal m_availability; }; diff --git a/src/webui/api/serialize/serialize_torrent.cpp b/src/webui/api/serialize/serialize_torrent.cpp index 225bf8757..621cbb09c 100644 --- a/src/webui/api/serialize/serialize_torrent.cpp +++ b/src/webui/api/serialize/serialize_torrent.cpp @@ -92,7 +92,7 @@ QVariantMap serialize(const BitTorrent::TorrentHandle &torrent) ret[KEY_TORRENT_PROGRESS] = torrent.progress(); ret[KEY_TORRENT_DLSPEED] = torrent.downloadPayloadRate(); ret[KEY_TORRENT_UPSPEED] = torrent.uploadPayloadRate(); - ret[KEY_TORRENT_PRIORITY] = torrent.queuePosition(); + ret[KEY_TORRENT_PRIORITY] = static_cast(torrent.queuePosition()); ret[KEY_TORRENT_SEEDS] = torrent.seedsCount(); ret[KEY_TORRENT_NUM_COMPLETE] = torrent.totalSeedsCount(); ret[KEY_TORRENT_LEECHS] = torrent.leechsCount(); diff --git a/src/webui/api/torrentscontroller.cpp b/src/webui/api/torrentscontroller.cpp index a46afa2a8..f1bf47825 100644 --- a/src/webui/api/torrentscontroller.cpp +++ b/src/webui/api/torrentscontroller.cpp @@ -39,7 +39,7 @@ #include #include -#include "base/bittorrent/filepriority.h" +#include "base/bittorrent/downloadpriority.h" #include "base/bittorrent/peerinfo.h" #include "base/bittorrent/session.h" #include "base/bittorrent/torrenthandle.h" @@ -393,9 +393,9 @@ void TorrentsController::trackersAction() {KEY_TRACKER_STATUS, static_cast(tracker.status())}, {KEY_TRACKER_PEERS_COUNT, data.numPeers}, {KEY_TRACKER_MSG, data.lastMessage.trimmed()}, - {KEY_TRACKER_SEEDS_COUNT, tracker.nativeEntry().scrape_complete}, - {KEY_TRACKER_LEECHES_COUNT, tracker.nativeEntry().scrape_incomplete}, - {KEY_TRACKER_DOWNLOADED_COUNT, tracker.nativeEntry().scrape_downloaded} + {KEY_TRACKER_SEEDS_COUNT, tracker.numSeeds()}, + {KEY_TRACKER_LEECHES_COUNT, tracker.numLeeches()}, + {KEY_TRACKER_DOWNLOADED_COUNT, tracker.numDownloaded()} }; } @@ -446,14 +446,14 @@ void TorrentsController::filesAction() throw APIError(APIErrorType::NotFound); if (torrent->hasMetadata()) { - const QVector priorities = torrent->filePriorities(); + const QVector priorities = torrent->filePriorities(); const QVector fp = torrent->filesProgress(); const QVector fileAvailability = torrent->availableFileFractions(); const BitTorrent::TorrentInfo info = torrent->info(); for (int i = 0; i < torrent->filesCount(); ++i) { QVariantMap fileDict; fileDict[KEY_FILE_PROGRESS] = fp[i]; - fileDict[KEY_FILE_PRIORITY] = priorities[i]; + fileDict[KEY_FILE_PRIORITY] = static_cast(priorities[i]); fileDict[KEY_FILE_SIZE] = torrent->fileSize(i); fileDict[KEY_FILE_AVAILABILITY] = fileAvailability[i]; @@ -701,11 +701,11 @@ void TorrentsController::filePrioAction() const QString hash = params()["hash"]; bool ok = false; - const int priority = params()["priority"].toInt(&ok); + const auto priority = static_cast(params()["priority"].toInt(&ok)); if (!ok) throw APIError(APIErrorType::BadParams, tr("Priority must be an integer")); - if (!BitTorrent::isValidFilePriority(static_cast(priority))) + if (!BitTorrent::isValidDownloadPriority(priority)) throw APIError(APIErrorType::BadParams, tr("Priority is not valid")); BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash); @@ -715,7 +715,7 @@ void TorrentsController::filePrioAction() throw APIError(APIErrorType::Conflict, tr("Torrent's metadata has not yet downloaded")); const int filesCount = torrent->filesCount(); - QVector priorities = torrent->filePriorities(); + QVector priorities = torrent->filePriorities(); bool priorityChanged = false; for (const QString &fileID : params()["id"].split('|')) { const int id = fileID.toInt(&ok);