From b2cb473b631c2c892b5f67b2967f738b02558a66 Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (Glassez)" Date: Sun, 1 May 2016 11:05:52 +0300 Subject: [PATCH] Don't use Preferences in BitTorrent::Session --- src/app/application.cpp | 3 + src/base/base.pri | 3 + .../bittorrent/private/bandwidthscheduler.cpp | 5 +- src/base/bittorrent/session.cpp | 1994 +++++++++++------ src/base/bittorrent/session.h | 257 ++- src/base/bittorrent/torrenthandle.cpp | 2 +- src/base/net/downloadmanager.cpp | 31 +- src/base/net/proxyconfigurationmanager.cpp | 160 ++ src/base/net/proxyconfigurationmanager.h | 87 + src/base/preferences.cpp | 684 +----- src/base/preferences.h | 145 -- src/base/settingsstorage.cpp | 88 +- src/base/settingvalue.h | 73 + src/gui/advancedsettings.cpp | 82 +- src/gui/mainwindow.cpp | 26 +- src/gui/optionsdlg.cpp | 243 +- src/gui/optionsdlg.h | 7 +- src/gui/properties/trackerlist.cpp | 2 +- src/gui/statusbar.cpp | 73 +- src/gui/transferlistwidget.cpp | 12 +- src/gui/updownratiodlg.cpp | 24 +- src/webui/btjson.cpp | 16 +- src/webui/prefjson.cpp | 212 +- src/webui/webapplication.cpp | 30 +- 24 files changed, 2287 insertions(+), 1972 deletions(-) create mode 100644 src/base/net/proxyconfigurationmanager.cpp create mode 100644 src/base/net/proxyconfigurationmanager.h create mode 100644 src/base/settingvalue.h diff --git a/src/app/application.cpp b/src/app/application.cpp index 622f6b307..cb63433c3 100644 --- a/src/app/application.cpp +++ b/src/app/application.cpp @@ -70,6 +70,7 @@ #include "base/net/smtp.h" #include "base/net/downloadmanager.h" #include "base/net/geoipmanager.h" +#include "base/net/proxyconfigurationmanager.h" #include "base/bittorrent/session.h" #include "base/bittorrent/torrenthandle.h" @@ -393,6 +394,7 @@ void Application::processParams(const QStringList ¶ms) int Application::exec(const QStringList ¶ms) { + Net::ProxyConfigurationManager::initInstance(); Net::DownloadManager::initInstance(); #ifdef DISABLE_GUI IconProvider::initInstance(); @@ -619,6 +621,7 @@ void Application::cleanup() Net::GeoIPManager::freeInstance(); #endif Net::DownloadManager::freeInstance(); + Net::ProxyConfigurationManager::freeInstance(); Preferences::freeInstance(); SettingsStorage::freeInstance(); delete m_fileLogger; diff --git a/src/base/base.pri b/src/base/base.pri index 0c4c4f303..b6310ae4f 100644 --- a/src/base/base.pri +++ b/src/base/base.pri @@ -5,6 +5,7 @@ HEADERS += \ $$PWD/qinisettings.h \ $$PWD/logger.h \ $$PWD/settingsstorage.h \ + $$PWD/settingvalue.h \ $$PWD/preferences.h \ $$PWD/indexrange.h \ $$PWD/iconprovider.h \ @@ -20,6 +21,7 @@ HEADERS += \ $$PWD/net/downloadhandler.h \ $$PWD/net/geoipmanager.h \ $$PWD/net/portforwarder.h \ + $$PWD/net/proxyconfigurationmanager.h \ $$PWD/net/reverseresolution.h \ $$PWD/net/smtp.h \ $$PWD/net/private/geoipdatabase.h \ @@ -74,6 +76,7 @@ SOURCES += \ $$PWD/net/downloadhandler.cpp \ $$PWD/net/geoipmanager.cpp \ $$PWD/net/portforwarder.cpp \ + $$PWD/net/proxyconfigurationmanager.cpp \ $$PWD/net/reverseresolution.cpp \ $$PWD/net/smtp.cpp \ $$PWD/net/private/geoipdatabase.cpp \ diff --git a/src/base/bittorrent/private/bandwidthscheduler.cpp b/src/base/bittorrent/private/bandwidthscheduler.cpp index dcb0097d1..ee009ac55 100644 --- a/src/base/bittorrent/private/bandwidthscheduler.cpp +++ b/src/base/bittorrent/private/bandwidthscheduler.cpp @@ -31,13 +31,13 @@ #include #include +#include "base/bittorrent/session.h" #include "base/preferences.h" #include "bandwidthscheduler.h" BandwidthScheduler::BandwidthScheduler(QObject *parent) : QTimer(parent) { - Q_ASSERT(Preferences::instance()->isSchedulerEnabled()); // Single shot, we call start() again manually setSingleShot(true); // Connect Signals/Slots @@ -47,8 +47,7 @@ BandwidthScheduler::BandwidthScheduler(QObject *parent) void BandwidthScheduler::start() { const Preferences* const pref = Preferences::instance(); - Q_ASSERT(pref->isSchedulerEnabled()); - bool alt_bw_enabled = pref->isAltBandwidthEnabled(); + bool alt_bw_enabled = BitTorrent::Session::instance()->isAltGlobalSpeedLimitEnabled(); QTime start = pref->getSchedulerStartTime(); QTime end = pref->getSchedulerEndTime(); diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index 68d427d7b..a1c020f20 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -41,10 +41,10 @@ #include #include #include -#include #include #include +#include #include #include @@ -66,8 +66,7 @@ #include "base/net/downloadhandler.h" #include "base/net/downloadmanager.h" #include "base/net/portforwarder.h" -#include "base/preferences.h" -#include "base/settingsstorage.h" +#include "base/net/proxyconfigurationmanager.h" #include "base/torrentfileguard.h" #include "base/torrentfilter.h" #include "base/unicodestrings.h" @@ -85,25 +84,19 @@ #include "tracker.h" #include "trackerentry.h" +#if LIBTORRENT_VERSION_NUM >= 10100 +namespace libtorrent +{ + using proxy_settings = aux::proxy_settings; +} +#endif + static const char PEER_ID[] = "qB"; static const char RESUME_FOLDER[] = "BT_backup"; namespace libt = libtorrent; using namespace BitTorrent; -#define SETTINGS_KEY(name) "BitTorrent/Session/" name -const QString KEY_CATEGORIES = SETTINGS_KEY("Categories"); -const QString KEY_MAXRATIOACTION = SETTINGS_KEY("MaxRatioAction"); -const QString KEY_DEFAULTSAVEPATH = SETTINGS_KEY("DefaultSavePath"); -const QString KEY_TEMPPATH = SETTINGS_KEY("TempPath"); -const QString KEY_SUBCATEGORIESENABLED = SETTINGS_KEY("SubcategoriesEnabled"); -const QString KEY_TEMPPATHENABLED = SETTINGS_KEY("TempPathEnabled"); -const QString KEY_DISABLE_AUTOTMM_BYDEFAULT = SETTINGS_KEY("DisableAutoTMMByDefault"); -const QString KEY_DISABLE_AUTOTMM_ONCATEGORYCHANGED = SETTINGS_KEY("DisableAutoTMMTriggers/CategoryChanged"); -const QString KEY_DISABLE_AUTOTMM_ONDEFAULTSAVEPATHCHANGED = SETTINGS_KEY("DisableAutoTMMTriggers/DefaultSavePathChanged"); -const QString KEY_DISABLE_AUTOTMM_ONCATEGORYSAVEPATHCHANGED = SETTINGS_KEY("DisableAutoTMMTriggers/CategorySavePathChanged"); -const QString KEY_ADDTORRENTPAUSED = SETTINGS_KEY("AddTorrentPaused"); - namespace { bool readFile(const QString &path, QByteArray &buf); @@ -114,6 +107,8 @@ namespace void torrentQueuePositionTop(const libt::torrent_handle &handle); void torrentQueuePositionBottom(const libt::torrent_handle &handle); + inline SettingsStorage *settings() { return SettingsStorage::instance(); } + QStringMap map_cast(const QVariantMap &map) { QStringMap result; @@ -130,15 +125,21 @@ namespace return result; } + QString normalizePath(const QString &path) + { + QString tmp = Utils::Fs::fromNativePath(path.trimmed()); + if (!tmp.isEmpty() && !tmp.endsWith('/')) + return tmp + '/'; + return tmp; + } + QString normalizeSavePath(QString path, const QString &defaultPath = Utils::Fs::QDesktopServicesDownloadLocation()) { - path = Utils::Fs::fromNativePath(path.trimmed()); + path = path.trimmed(); if (path.isEmpty()) path = Utils::Fs::fromNativePath(defaultPath.trimmed()); - if (!path.isEmpty() && !path.endsWith('/')) - path += '/'; - return path; + return normalizePath(path); } QStringMap expandCategories(const QStringMap &categories) @@ -164,29 +165,119 @@ namespace return files; } + + template + struct LowerLimited + { + LowerLimited(T limit, T ret) + : m_limit(limit) + , m_ret(ret) + { + } + + explicit LowerLimited(T limit) + : LowerLimited(limit, limit) + { + } + + T operator()(T val) + { + return val <= m_limit ? m_ret : val; + } + + private: + const T m_limit; + const T m_ret; + }; + + template + LowerLimited lowerLimited(T limit) { return LowerLimited(limit); } + + template + LowerLimited lowerLimited(T limit, T ret) { return LowerLimited(limit, ret); } } // Session Session *Session::m_instance = nullptr; +#define BITTORRENT_KEY(name) "BitTorrent/" name +#define BITTORRENT_SESSION_KEY(name) BITTORRENT_KEY("Session/") name + Session::Session(QObject *parent) : QObject(parent) - , m_settings(SettingsStorage::instance()) - , m_LSDEnabled(false) - , m_DHTEnabled(false) - , m_PeXEnabled(false) - , m_queueingEnabled(false) - , m_torrentExportEnabled(false) - , m_finishedTorrentExportEnabled(false) - , m_preAllocateAll(false) - , m_globalMaxRatio(-1) + , m_deferredConfigureScheduled(false) + , m_isDHTEnabled(BITTORRENT_SESSION_KEY("DHTEnabled"), true) + , m_isLSDEnabled(BITTORRENT_SESSION_KEY("LSDEnabled"), true) + , m_isPeXEnabled(BITTORRENT_SESSION_KEY("PeXEnabled"), true) + , m_isTrackerExchangeEnabled(BITTORRENT_SESSION_KEY("TrackerExchangeEnabled"), false) + , m_isFilteringEnabled(BITTORRENT_SESSION_KEY("FilteringEnabled"), false) + , m_isTrackerFilteringEnabled(BITTORRENT_SESSION_KEY("TrackerFilteringEnabled"), false) + , m_IPFilterFile(BITTORRENT_SESSION_KEY("IPFilter")) + , m_announceToAllTrackers(BITTORRENT_SESSION_KEY("AnnounceToAllTrackers"), true) + , m_diskCacheSize(BITTORRENT_SESSION_KEY("DiskCacheSize"), 0) + , m_diskCacheTTL(BITTORRENT_SESSION_KEY("DiskCacheTTL"), 60) + , m_useOSCache(BITTORRENT_SESSION_KEY("UseOSCache"), true) + , m_isAnonymousModeEnabled(BITTORRENT_SESSION_KEY("AnonymousModeEnabled"), false) + , m_isQueueingEnabled(BITTORRENT_SESSION_KEY("QueueingSystemEnabled"), true) + , m_maxActiveDownloads(BITTORRENT_SESSION_KEY("MaxActiveDownloads"), 3, lowerLimited(0)) + , m_maxActiveUploads(BITTORRENT_SESSION_KEY("MaxActiveUploads"), 3, lowerLimited(0)) + , m_maxActiveTorrents(BITTORRENT_SESSION_KEY("MaxActiveTorrents"), 5, lowerLimited(0)) + , m_ignoreSlowTorrentsForQueueing(BITTORRENT_SESSION_KEY("IgnoreSlowTorrentsForQueueing"), false) + , m_outgoingPortsMin(BITTORRENT_SESSION_KEY("OutgoingPortsMin"), 0) + , m_outgoingPortsMax(BITTORRENT_SESSION_KEY("OutgoingPortsMax"), 0) + , m_ignoreLimitsOnLAN(BITTORRENT_SESSION_KEY("IgnoreLimitsOnLAN"), true) + , m_includeOverheadInLimits(BITTORRENT_SESSION_KEY("IncludeOverheadInLimits"), false) + , m_networkAddress(BITTORRENT_SESSION_KEY("NetworkAddress")) + , m_isSuperSeedingEnabled(BITTORRENT_SESSION_KEY("SuperSeedingEnabled"), false) + , m_maxConnections(BITTORRENT_SESSION_KEY("MaxConnections"), 500, lowerLimited(0, -1)) + , m_maxHalfOpenConnections(BITTORRENT_SESSION_KEY("MaxHalfOpenConnections"), 20, lowerLimited(0, -1)) + , m_maxUploads(BITTORRENT_SESSION_KEY("MaxUploads"), -1, lowerLimited(0, -1)) + , m_maxConnectionsPerTorrent(BITTORRENT_SESSION_KEY("MaxConnectionsPerTorrent"), 100, lowerLimited(0, -1)) + , m_maxUploadsPerTorrent(BITTORRENT_SESSION_KEY("MaxUploadsPerTorrent"), -1, lowerLimited(0, -1)) + , m_isUTPEnabled(BITTORRENT_SESSION_KEY("uTPEnabled"), true) + , m_isUTPRateLimited(BITTORRENT_SESSION_KEY("uTPRateLimited"), true) + , m_isAddTrackersEnabled(BITTORRENT_SESSION_KEY("AddTrackersEnabled"), false) + , m_additionalTrackers(BITTORRENT_SESSION_KEY("AdditionalTrackers")) + , m_globalMaxRatio(BITTORRENT_SESSION_KEY("GlobalMaxRatio"), -1, [](qreal r) { return r < 0 ? -1. : r;}) + , m_isAddTorrentPaused(BITTORRENT_SESSION_KEY("AddTorrentPaused"), false) + , m_isAppendExtensionEnabled(BITTORRENT_SESSION_KEY("AddExtensionToIncompleteFiles"), false) + , m_refreshInterval(BITTORRENT_SESSION_KEY("RefreshInterval"), 1500) + , m_isPreallocationEnabled(BITTORRENT_SESSION_KEY("Preallocation"), false) + , m_torrentExportDirectory(BITTORRENT_SESSION_KEY("TorrentExportDirectory")) + , m_finishedTorrentExportDirectory(BITTORRENT_SESSION_KEY("FinishedTorrentExportDirectory")) + , m_globalDownloadSpeedLimit(BITTORRENT_SESSION_KEY("GlobalDLSpeedLimit"), 0, lowerLimited(0)) + , m_globalUploadSpeedLimit(BITTORRENT_SESSION_KEY("GlobalUPSpeedLimit"), 0, lowerLimited(0)) + , m_altGlobalDownloadSpeedLimit(BITTORRENT_SESSION_KEY("AlternativeGlobalDLSpeedLimit"), 10, lowerLimited(0)) + , m_altGlobalUploadSpeedLimit(BITTORRENT_SESSION_KEY("AlternativeGlobalUPSpeedLimit"), 10, lowerLimited(0)) + , m_isAltGlobalSpeedLimitEnabled(BITTORRENT_SESSION_KEY("UseAlternativeGlobalSpeedLimit"), false) + , m_isBandwidthSchedulerEnabled(BITTORRENT_SESSION_KEY("BandwidthSchedulerEnabled"), false) + , m_saveResumeDataInterval(BITTORRENT_SESSION_KEY("SaveResumeDataInterval"), 3) + , m_port(BITTORRENT_SESSION_KEY("Port"), 8999) + , m_useRandomPort(BITTORRENT_SESSION_KEY("UseRandomPort"), false) + , m_networkInterface(BITTORRENT_SESSION_KEY("Interface")) + , m_networkInterfaceAddress(BITTORRENT_SESSION_KEY("InterfaceAddress")) + , m_isIPv6Enabled(BITTORRENT_SESSION_KEY("IPv6Enabled"), false) + , m_encryption(BITTORRENT_SESSION_KEY("Encryption"), 0) + , m_isForceProxyEnabled(BITTORRENT_SESSION_KEY("ForceProxy"), true) + , m_isProxyPeerConnectionsEnabled(BITTORRENT_SESSION_KEY("ProxyPeerConnections"), false) + , m_storedCategories(BITTORRENT_SESSION_KEY("Categories")) + , m_maxRatioAction(BITTORRENT_SESSION_KEY("MaxRatioAction"), Pause) + , m_defaultSavePath(BITTORRENT_SESSION_KEY("DefaultSavePath"), Utils::Fs::QDesktopServicesDownloadLocation(), normalizePath) + , m_tempPath(BITTORRENT_SESSION_KEY("TempPath"), defaultSavePath() + "temp/", normalizePath) + , m_isSubcategoriesEnabled(BITTORRENT_SESSION_KEY("SubcategoriesEnabled"), false) + , m_isTempPathEnabled(BITTORRENT_SESSION_KEY("TempPathEnabled"), false) + , m_isAutoTMMDisabledByDefault(BITTORRENT_SESSION_KEY("DisableAutoTMMByDefault"), true) + , m_isDisableAutoTMMWhenCategoryChanged(BITTORRENT_SESSION_KEY("DisableAutoTMMTriggers/CategoryChanged"), false) + , m_isDisableAutoTMMWhenDefaultSavePathChanged(BITTORRENT_SESSION_KEY("DisableAutoTMMTriggers/DefaultSavePathChanged"), true) + , m_isDisableAutoTMMWhenCategorySavePathChanged(BITTORRENT_SESSION_KEY("DisableAutoTMMTriggers/CategorySavePathChanged"), true) + , m_isTrackerEnabled(BITTORRENT_KEY("TrackerEnabled"), false) + , m_bannedIPs("State/BannedIPs") + , m_numResumeData(0) , m_extraLimit(0) - , m_appendExtension(false) - , m_refreshInterval(0) + , m_useProxy(false) { - Preferences* const pref = Preferences::instance(); Logger* const logger = Logger::instance(); initResumeFolder(); @@ -199,8 +290,8 @@ Session::Session(QObject *parent) // Construct session libt::fingerprint fingerprint(PEER_ID, VERSION_MAJOR, VERSION_MINOR, VERSION_BUGFIX, VERSION_BUILD); - const unsigned short port = pref->getSessionPort(); - std::pair ports(port, port); + const ushort port = this->port(); + std::pair ports(port, port); const QString ip = getListeningIPs().first(); // Set severity level of libtorrent session int alertMask = libt::alert::error_notification @@ -240,38 +331,54 @@ Session::Session(QObject *parent) // Enabling plugins //m_nativeSession->add_extension(&libt::create_metadata_plugin); m_nativeSession->add_extension(&libt::create_ut_metadata_plugin); - if (pref->trackerExchangeEnabled()) + if (isTrackerExchangeEnabled()) m_nativeSession->add_extension(&libt::create_lt_trackers_plugin); - m_PeXEnabled = pref->isPeXEnabled(); - if (m_PeXEnabled) + if (isPeXEnabled()) { m_nativeSession->add_extension(&libt::create_ut_pex_plugin); + logger->addMessage(tr("PeX support [ON]"), Log::INFO); + } + else { + logger->addMessage(tr("PeX support [OFF]"), Log::INFO); + } m_nativeSession->add_extension(&libt::create_smart_ban_plugin); - m_categories = map_cast(m_settings->loadValue(KEY_CATEGORIES).toMap()); + m_categories = map_cast(m_storedCategories); if (isSubcategoriesEnabled()) { // if subcategories support changed manually m_categories = expandCategories(m_categories); - m_settings->storeValue(KEY_CATEGORIES, map_cast(m_categories)); + m_storedCategories = map_cast(m_categories); } m_refreshTimer = new QTimer(this); - m_refreshTimer->setInterval(2000); + m_refreshTimer->setInterval(refreshInterval()); connect(m_refreshTimer, SIGNAL(timeout()), SLOT(refresh())); m_refreshTimer->start(); // Regular saving of fastresume data m_resumeDataTimer = new QTimer(this); + m_resumeDataTimer->setInterval(saveResumeDataInterval() * 60 * 1000); connect(m_resumeDataTimer, SIGNAL(timeout()), SLOT(generateResumeData())); m_statistics = new Statistics(this); - m_maxRatioAction = static_cast(m_settings->loadValue(KEY_MAXRATIOACTION, Pause).toInt()); - m_defaultSavePath = normalizeSavePath(m_settings->loadValue(KEY_DEFAULTSAVEPATH).toString()); - m_tempPath = normalizeSavePath(m_settings->loadValue(KEY_TEMPPATH).toString(), m_defaultSavePath + "temp"); - // Apply user settings to BitTorrent session configure(); - connect(pref, SIGNAL(changed()), SLOT(configure())); + + configureListeningInterface(); + updateRatioTimer(); + populateAdditionalTrackers(); + + enableTracker(isTrackerEnabled()); + if (!torrentExportDirectory().isEmpty()) { + qDebug("Torrent export is enabled, exporting the current torrents"); + foreach (TorrentHandle *const torrent, m_torrents) + exportTorrentFile(torrent); + } + + connect(Net::ProxyConfigurationManager::instance(), SIGNAL(proxyConfigurationChanged()), SLOT(configureDeferred())); + + if (isBandwidthSchedulerEnabled()) + enableBandwidthScheduler(); // Network configuration monitor connect(&m_networkManager, SIGNAL(onlineStateChanged(bool)), SLOT(networkOnlineStateChanged(bool))); @@ -295,39 +402,136 @@ Session::Session(QObject *parent) bool Session::isDHTEnabled() const { - return m_DHTEnabled; + return m_isDHTEnabled; +} + +void Session::setDHTEnabled(bool enabled) +{ + if (enabled != m_isDHTEnabled) { + m_isDHTEnabled = enabled; + configureDeferred(); + } } bool Session::isLSDEnabled() const { - return m_LSDEnabled; + return m_isLSDEnabled; +} + +void Session::setLSDEnabled(bool enabled) +{ + if (enabled != m_isLSDEnabled) { + m_isLSDEnabled = enabled; + configureDeferred(); + } +} + +bool Session::isPeXEnabled() const +{ + return m_isPeXEnabled; +} + +void Session::setPeXEnabled(bool enabled) +{ + if (enabled != isPeXEnabled()) { + m_isPeXEnabled = enabled; + Logger::instance()->addMessage(tr("Restart is required to toggle PeX support"), Log::WARNING); + } } -bool Session::isPexEnabled() const +bool Session::isTrackerExchangeEnabled() const { - return m_PeXEnabled; + return m_isTrackerExchangeEnabled; } -bool Session::isQueueingEnabled() const +void Session::setTrackerExchangeEnabled(bool enabled) { - return m_queueingEnabled; + if (enabled != isTrackerExchangeEnabled()) { + m_isTrackerExchangeEnabled = enabled; + Logger::instance()->addMessage(tr("Restart is required to toggle Tracker Exchange support"), Log::WARNING); + } } bool Session::isTempPathEnabled() const { - return m_settings->loadValue(KEY_TEMPPATHENABLED, false).toBool(); + return m_isTempPathEnabled; } void Session::setTempPathEnabled(bool enabled) { - m_settings->storeValue(KEY_TEMPPATHENABLED, enabled); - foreach (TorrentHandle *const torrent, m_torrents) - torrent->handleTempPathChanged(); + if (enabled != isTempPathEnabled()) { + m_isTempPathEnabled = enabled; + foreach (TorrentHandle *const torrent, m_torrents) + torrent->handleTempPathChanged(); + } } bool Session::isAppendExtensionEnabled() const { - return m_appendExtension; + return m_isAppendExtensionEnabled; +} + +void Session::setAppendExtensionEnabled(bool enabled) +{ + if (isAppendExtensionEnabled() != enabled) { + // append or remove .!qB extension for incomplete files + foreach (TorrentHandle *const torrent, m_torrents) + torrent->handleAppendExtensionToggled(); + + m_isAppendExtensionEnabled = enabled; + } +} + +uint Session::refreshInterval() const +{ + return m_refreshInterval; +} + +void Session::setRefreshInterval(uint value) +{ + if (value != refreshInterval()) { + m_refreshTimer->setInterval(value); + m_refreshInterval = value; + } +} + +bool Session::isPreallocationEnabled() const +{ + return m_isPreallocationEnabled; +} + +void Session::setPreallocationEnabled(bool enabled) +{ + m_isPreallocationEnabled = enabled; +} + +QString Session::torrentExportDirectory() const +{ + return m_torrentExportDirectory; +} + +void Session::setTorrentExportDirectory(const QString &path) +{ + if (path != torrentExportDirectory()) { + const bool wasDisabled = torrentExportDirectory().isEmpty(); + m_torrentExportDirectory = path; + + if (wasDisabled) { + qDebug("Torrent export is enabled, exporting the current torrents"); + foreach (TorrentHandle *const torrent, m_torrents) + exportTorrentFile(torrent); + } + } +} + +QString Session::finishedTorrentExportDirectory() const +{ + return m_finishedTorrentExportDirectory; +} + +void Session::setFinishedTorrentExportDirectory(const QString &path) +{ + m_finishedTorrentExportDirectory = path; } QString Session::defaultSavePath() const @@ -342,7 +546,7 @@ QString Session::tempPath() const QString Session::torrentTempPath(const InfoHash &hash) const { - return m_tempPath + return tempPath() + static_cast(hash).left(7) + "/"; } @@ -410,7 +614,7 @@ bool Session::addCategory(const QString &name, const QString &savePath) } m_categories[name] = savePath; - m_settings->storeValue(KEY_CATEGORIES, map_cast(m_categories)); + m_storedCategories = map_cast(m_categories); emit categoryAdded(name); return true; @@ -460,7 +664,7 @@ bool Session::removeCategory(const QString &name) if (result) { // update stored categories - m_settings->storeValue(KEY_CATEGORIES, map_cast(m_categories)); + m_storedCategories = map_cast(m_categories); emit categoryRemoved(name); } @@ -469,7 +673,7 @@ bool Session::removeCategory(const QString &name) bool Session::isSubcategoriesEnabled() const { - return m_settings->loadValue(KEY_SUBCATEGORIESENABLED, false).toBool(); + return m_isSubcategoriesEnabled; } void Session::setSubcategoriesEnabled(bool value) @@ -480,65 +684,78 @@ void Session::setSubcategoriesEnabled(bool value) // expand categories to include all parent categories m_categories = expandCategories(m_categories); // update stored categories - m_settings->storeValue(KEY_CATEGORIES, map_cast(m_categories)); + m_storedCategories = map_cast(m_categories); } else { // reload categories - m_categories = map_cast(m_settings->loadValue(KEY_CATEGORIES).toMap()); + m_categories = map_cast(m_storedCategories); } - m_settings->storeValue(KEY_SUBCATEGORIESENABLED, value); + m_isSubcategoriesEnabled = value; emit subcategoriesSupportChanged(); } bool Session::isAutoTMMDisabledByDefault() const { - return m_settings->loadValue(KEY_DISABLE_AUTOTMM_BYDEFAULT, true).toBool(); + return m_isAutoTMMDisabledByDefault; } void Session::setAutoTMMDisabledByDefault(bool value) { - m_settings->storeValue(KEY_DISABLE_AUTOTMM_BYDEFAULT, value); + m_isAutoTMMDisabledByDefault = value; } bool Session::isDisableAutoTMMWhenCategoryChanged() const { - return m_settings->loadValue(KEY_DISABLE_AUTOTMM_ONCATEGORYCHANGED, false).toBool(); + return m_isDisableAutoTMMWhenCategoryChanged; } void Session::setDisableAutoTMMWhenCategoryChanged(bool value) { - m_settings->storeValue(KEY_DISABLE_AUTOTMM_ONCATEGORYCHANGED, value); + m_isDisableAutoTMMWhenCategoryChanged = value; } bool Session::isDisableAutoTMMWhenDefaultSavePathChanged() const { - return m_settings->loadValue(KEY_DISABLE_AUTOTMM_ONDEFAULTSAVEPATHCHANGED, true).toBool(); + return m_isDisableAutoTMMWhenDefaultSavePathChanged; } void Session::setDisableAutoTMMWhenDefaultSavePathChanged(bool value) { - m_settings->storeValue(KEY_DISABLE_AUTOTMM_ONDEFAULTSAVEPATHCHANGED, value); + m_isDisableAutoTMMWhenDefaultSavePathChanged = value; } bool Session::isDisableAutoTMMWhenCategorySavePathChanged() const { - return m_settings->loadValue(KEY_DISABLE_AUTOTMM_ONCATEGORYSAVEPATHCHANGED, true).toBool(); + return m_isDisableAutoTMMWhenCategorySavePathChanged; } void Session::setDisableAutoTMMWhenCategorySavePathChanged(bool value) { - m_settings->storeValue(KEY_DISABLE_AUTOTMM_ONCATEGORYSAVEPATHCHANGED, value); + m_isDisableAutoTMMWhenCategorySavePathChanged = value; } bool Session::isAddTorrentPaused() const { - return m_settings->loadValue(KEY_ADDTORRENTPAUSED, false).toBool(); + return m_isAddTorrentPaused; } void Session::setAddTorrentPaused(bool value) { - m_settings->storeValue(KEY_ADDTORRENTPAUSED, value); + m_isAddTorrentPaused = value; +} + +bool Session::isTrackerEnabled() const +{ + return m_isTrackerEnabled; +} + +void Session::setTrackerEnabled(bool enabled) +{ + if (isTrackerEnabled() != enabled) { + enableTracker(enabled); + m_isTrackerEnabled = enabled; + } } qreal Session::globalMaxRatio() const @@ -546,6 +763,19 @@ qreal Session::globalMaxRatio() const return m_globalMaxRatio; } +// Torrents will a ratio superior to the given value will +// be automatically deleted +void Session::setGlobalMaxRatio(qreal ratio) +{ + if (ratio < 0) + ratio = -1.; + + if (ratio != globalMaxRatio()) { + m_globalMaxRatio = ratio; + updateRatioTimer(); + } +} + // Main destructor Session::~Session() { @@ -590,14 +820,42 @@ Session *Session::instance() return m_instance; } -void Session::setSessionSettings() +void Session::adjustLimits() +{ + if (isQueueingSystemEnabled()) { + libt::session_settings sessionSettings(m_nativeSession->settings()); + adjustLimits(sessionSettings); + m_nativeSession->set_settings(sessionSettings); + } +} + +void Session::adjustLimits(libt::session_settings &sessionSettings) +{ + //Internally increase the queue limits to ensure that the magnet is started + int maxDownloading = maxActiveDownloads(); + int maxActive = maxActiveTorrents(); + + if (maxDownloading > -1) + sessionSettings.active_downloads = maxDownloading + m_extraLimit; + else + sessionSettings.active_downloads = maxDownloading; + + if (maxActive > -1) + sessionSettings.active_limit = maxActive + m_extraLimit; + else + sessionSettings.active_limit = maxActive; +} + +// Set BitTorrent session configuration +void Session::configure() { - Preferences* const pref = Preferences::instance(); + qDebug("Configuring session"); Logger* const logger = Logger::instance(); + // * Session settings libt::session_settings sessionSettings = m_nativeSession->settings(); + sessionSettings.user_agent = "qBittorrent " VERSION; - //std::cout << "HTTP User-Agent is " << sessionSettings.user_agent << std::endl; logger->addMessage(tr("HTTP User-Agent is '%1'").arg(Utils::String::fromStdString(sessionSettings.user_agent))); sessionSettings.upnp_ignore_nonrouters = true; @@ -609,33 +867,45 @@ void Session::setSessionSettings() // Speed up exit sessionSettings.stop_tracker_timeout = 1; sessionSettings.auto_scrape_interval = 1200; // 20 minutes - bool announce_to_all = pref->announceToAllTrackers(); - sessionSettings.announce_to_all_trackers = announce_to_all; - sessionSettings.announce_to_all_tiers = announce_to_all; sessionSettings.auto_scrape_min_interval = 900; // 15 minutes - int cache_size = pref->diskCacheSize(); - sessionSettings.cache_size = cache_size ? cache_size * 64 : -1; - sessionSettings.cache_expiry = pref->diskCacheTTL(); - qDebug() << "Using a disk cache size of" << cache_size << "MiB"; - libt::session_settings::io_buffer_mode_t mode = pref->osCache() ? libt::session_settings::enable_os_cache : libt::session_settings::disable_os_cache; + sessionSettings.connection_speed = 20; // default is 10 + sessionSettings.no_connect_privileged_ports = false; + sessionSettings.seed_choking_algorithm = libt::session_settings::fastest_upload; + + const bool altSpeedLimitEnabled = isAltGlobalSpeedLimitEnabled(); + sessionSettings.download_rate_limit = altSpeedLimitEnabled ? altGlobalDownloadSpeedLimit() : globalDownloadSpeedLimit(); + sessionSettings.upload_rate_limit = altSpeedLimitEnabled ? altGlobalUploadSpeedLimit() : globalUploadSpeedLimit(); + + // TODO: Use same settings struct with above + configureEncryption(); + configureProxy(); + + sessionSettings.force_proxy = m_useProxy ? isForceProxyEnabled() : false; + + bool announceToAll = announceToAllTrackers(); + sessionSettings.announce_to_all_trackers = announceToAll; + sessionSettings.announce_to_all_tiers = announceToAll; + int cacheSize = diskCacheSize(); + sessionSettings.cache_size = cacheSize ? cacheSize * 64 : -1; + sessionSettings.cache_expiry = diskCacheTTL(); + qDebug() << "Using a disk cache size of" << cacheSize << "MiB"; + libt::session_settings::io_buffer_mode_t mode = useOSCache() ? libt::session_settings::enable_os_cache + : libt::session_settings::disable_os_cache; sessionSettings.disk_io_read_mode = mode; sessionSettings.disk_io_write_mode = mode; - m_resumeDataTimer->setInterval(pref->saveResumeDataInterval() * 60 * 1000); - - sessionSettings.anonymous_mode = pref->isAnonymousModeEnabled(); + sessionSettings.anonymous_mode = isAnonymousModeEnabled(); if (sessionSettings.anonymous_mode) logger->addMessage(tr("Anonymous mode [ON]"), Log::INFO); else logger->addMessage(tr("Anonymous mode [OFF]"), Log::INFO); // Queueing System - m_queueingEnabled = pref->isQueueingSystemEnabled(); - if (m_queueingEnabled) { + if (isQueueingSystemEnabled()) { adjustLimits(sessionSettings); - sessionSettings.active_seeds = pref->getMaxActiveUploads(); - sessionSettings.dont_count_slow_torrents = pref->ignoreSlowTorrentsForQueueing(); + sessionSettings.active_seeds = maxActiveUploads(); + sessionSettings.dont_count_slow_torrents = ignoreSlowTorrentsForQueueing(); } else { sessionSettings.active_downloads = -1; @@ -648,341 +918,130 @@ void Session::setSessionSettings() // Outgoing ports #if LIBTORRENT_VERSION_NUM < 10100 - sessionSettings.outgoing_ports = std::make_pair(pref->outgoingPortsMin(), pref->outgoingPortsMax()); + sessionSettings.outgoing_ports = std::make_pair(outgoingPortsMin(), outgoingPortsMax()); #else - sessionSettings.outgoing_port = pref->outgoingPortsMin(); - sessionSettings.num_outgoing_ports = pref->outgoingPortsMax() - pref->outgoingPortsMin(); + sessionSettings.outgoing_port = outgoingPortsMin(); + sessionSettings.num_outgoing_ports = outgoingPortsMax() - outgoingPortsMin(); #endif + // Ignore limits on LAN - qDebug() << "Ignore limits on LAN" << pref->getIgnoreLimitsOnLAN(); - sessionSettings.ignore_limits_on_local_network = pref->getIgnoreLimitsOnLAN(); + sessionSettings.ignore_limits_on_local_network = ignoreLimitsOnLAN(); // Include overhead in transfer limits - sessionSettings.rate_limit_ip_overhead = pref->includeOverheadInLimits(); + sessionSettings.rate_limit_ip_overhead = includeOverheadInLimits(); // IP address to announce to trackers - sessionSettings.announce_ip = Utils::String::toStdString(pref->getNetworkAddress()); + sessionSettings.announce_ip = Utils::String::toStdString(networkAddress()); // Super seeding - sessionSettings.strict_super_seeding = pref->isSuperSeedingEnabled(); + sessionSettings.strict_super_seeding = isSuperSeedingEnabled(); // * Max Half-open connections - sessionSettings.half_open_limit = pref->getMaxHalfOpenConnections(); + sessionSettings.half_open_limit = maxHalfOpenConnections(); // * Max connections limit - sessionSettings.connections_limit = pref->getMaxConnecs(); + sessionSettings.connections_limit = maxConnections(); // * Global max upload slots - sessionSettings.unchoke_slots_limit = pref->getMaxUploads(); + sessionSettings.unchoke_slots_limit = maxUploads(); // uTP - sessionSettings.enable_incoming_utp = pref->isuTPEnabled(); - sessionSettings.enable_outgoing_utp = pref->isuTPEnabled(); + sessionSettings.enable_incoming_utp = isUTPEnabled(); + sessionSettings.enable_outgoing_utp = isUTPEnabled(); // uTP rate limiting - sessionSettings.rate_limit_utp = pref->isuTPRateLimited(); + sessionSettings.rate_limit_utp = isUTPRateLimited(); if (sessionSettings.rate_limit_utp) sessionSettings.mixed_mode_algorithm = libt::session_settings::prefer_tcp; else sessionSettings.mixed_mode_algorithm = libt::session_settings::peer_proportional; - sessionSettings.connection_speed = 20; //default is 10 - if (pref->isProxyEnabled()) - sessionSettings.force_proxy = pref->getForceProxy(); - else - sessionSettings.force_proxy = false; - sessionSettings.no_connect_privileged_ports = false; - sessionSettings.seed_choking_algorithm = libt::session_settings::fastest_upload; - - sessionSettings.apply_ip_filter_to_trackers = pref->isFilteringTrackerEnabled(); - qDebug() << "Set session settings"; - m_nativeSession->set_settings(sessionSettings); -} -void Session::adjustLimits() -{ - if (m_queueingEnabled) { - libt::session_settings sessionSettings(m_nativeSession->settings()); - adjustLimits(sessionSettings); - m_nativeSession->set_settings(sessionSettings); - } -} + sessionSettings.apply_ip_filter_to_trackers = isTrackerFilteringEnabled(); -void Session::adjustLimits(libt::session_settings &sessionSettings) -{ - Preferences *const pref = Preferences::instance(); + m_nativeSession->set_settings(sessionSettings); - //Internally increase the queue limits to ensure that the magnet is started - int max_downloading = pref->getMaxActiveDownloads(); - int max_active = pref->getMaxActiveTorrents(); + enableDHT(isDHTEnabled()); + enableLSD(isLSDEnabled()); - if (max_downloading > -1) - sessionSettings.active_downloads = max_downloading + m_extraLimit; + if (isFilteringEnabled()) + enableIPFilter(IPFilterFile()); else - sessionSettings.active_downloads = max_downloading; + disableIPFilter(); - if (max_active > -1) - sessionSettings.active_limit = max_active + m_extraLimit; - else - sessionSettings.active_limit = max_active; + // Add the banned IPs after the possibly disabled IPFilter + // which creates an empty filter and overrides all previously + // applied bans. + FilterParserThread::processFilterList(m_nativeSession, m_bannedIPs); + + m_deferredConfigureScheduled = false; + qDebug("Session configured"); } -// Set BitTorrent session configuration -void Session::configure() +void Session::enableTracker(bool enable) { - qDebug("Configuring session"); - Preferences* const pref = Preferences::instance(); - - const unsigned short oldListenPort = m_nativeSession->listen_port(); - const unsigned short newListenPort = pref->getSessionPort(); - if (oldListenPort != newListenPort) { - qDebug("Session port changes in program preferences: %d -> %d", oldListenPort, newListenPort); - setListeningPort(); - } - - uint newRefreshInterval = pref->getRefreshInterval(); - if (newRefreshInterval != m_refreshInterval) { - m_refreshInterval = newRefreshInterval; - m_refreshTimer->setInterval(m_refreshInterval); - } - - setAppendExtension(pref->useIncompleteFilesExtension()); - preAllocateAllFiles(pref->preAllocateAllFiles()); - - // * Torrent export directory - const bool torrentExportEnabled = pref->isTorrentExportEnabled(); - if (m_torrentExportEnabled != torrentExportEnabled) { - m_torrentExportEnabled = torrentExportEnabled; - if (m_torrentExportEnabled) { - qDebug("Torrent export is enabled, exporting the current torrents"); - for (auto torrent: m_torrents) - exportTorrentFile(torrent); - } - } + Logger *const logger = Logger::instance(); - // * Finished Torrent export directory - const bool finishedTorrentExportEnabled = pref->isFinishedTorrentExportEnabled(); - if (m_finishedTorrentExportEnabled != finishedTorrentExportEnabled) - m_finishedTorrentExportEnabled = finishedTorrentExportEnabled; + if (enable) { + if (!m_tracker) + m_tracker = new Tracker(this); - // Connection - // * Global download limit - const bool alternative_speeds = pref->isAltBandwidthEnabled(); - int down_limit; - if (alternative_speeds) - down_limit = pref->getAltGlobalDownloadLimit(); - else - down_limit = pref->getGlobalDownloadLimit(); - if (down_limit <= 0) { - // Download limit disabled - setDownloadRateLimit(-1); - } - else { - // Enabled - setDownloadRateLimit(down_limit*1024); - } - int up_limit; - if (alternative_speeds) - up_limit = pref->getAltGlobalUploadLimit(); - else - up_limit = pref->getGlobalUploadLimit(); - // * Global Upload limit - if (up_limit <= 0) { - // Upload limit disabled - setUploadRateLimit(-1); + if (m_tracker->start()) + logger->addMessage(tr("Embedded Tracker [ON]"), Log::INFO); + else + logger->addMessage(tr("Failed to start the embedded tracker!"), Log::CRITICAL); } else { - // Enabled - setUploadRateLimit(up_limit*1024); + logger->addMessage(tr("Embedded Tracker [OFF]")); + if (m_tracker) + delete m_tracker; } +} - if (pref->isSchedulerEnabled()) { - if (!m_bwScheduler) { - m_bwScheduler = new BandwidthScheduler(this); - connect(m_bwScheduler.data(), SIGNAL(switchToAlternativeMode(bool)), this, SLOT(switchToAlternativeMode(bool))); - } - m_bwScheduler->start(); - } - else { - delete m_bwScheduler; +void Session::enableBandwidthScheduler() +{ + if (!m_bwScheduler) { + m_bwScheduler = new BandwidthScheduler(this); + connect(m_bwScheduler.data(), SIGNAL(switchToAlternativeMode(bool)), this, SLOT(switchToAlternativeMode(bool))); } + m_bwScheduler->start(); +} - Logger* const logger = Logger::instance(); - - // * Session settings - setSessionSettings(); - - // Bittorrent - // * Max connections per torrent limit - setMaxConnectionsPerTorrent(pref->getMaxConnecsPerTorrent()); - // * Max uploads per torrent limit - setMaxUploadsPerTorrent(pref->getMaxUploadsPerTorrent()); - // * DHT - enableDHT(pref->isDHTEnabled()); - - // * PeX - if (m_PeXEnabled) - logger->addMessage(tr("PeX support [ON]"), Log::INFO); - else - logger->addMessage(tr("PeX support [OFF]"), Log::CRITICAL); - if (m_PeXEnabled != pref->isPeXEnabled()) - logger->addMessage(tr("Restart is required to toggle PeX support"), Log::CRITICAL); - - // * LSD - if (pref->isLSDEnabled()) { - enableLSD(true); - logger->addMessage(tr("Local Peer Discovery support [ON]"), Log::INFO); - } - else { - enableLSD(false); - logger->addMessage(tr("Local Peer Discovery support [OFF]"), Log::INFO); +void Session::populateAdditionalTrackers() +{ + m_additionalTrackerList.clear(); + foreach (QString tracker, additionalTrackers().split("\n")) { + tracker = tracker.trimmed(); + if (!tracker.isEmpty()) + m_additionalTrackerList << tracker; } +} - // * Encryption - const int encryptionState = pref->getEncryptionSetting(); - // The most secure, rc4 only so that all streams and encrypted - libt::pe_settings encryptionSettings; - encryptionSettings.allowed_enc_level = libt::pe_settings::rc4; - encryptionSettings.prefer_rc4 = true; - switch(encryptionState) { - case 0: //Enabled - encryptionSettings.out_enc_policy = libt::pe_settings::enabled; - encryptionSettings.in_enc_policy = libt::pe_settings::enabled; - logger->addMessage(tr("Encryption support [ON]"), Log::INFO); - break; - case 1: // Forced - encryptionSettings.out_enc_policy = libt::pe_settings::forced; - encryptionSettings.in_enc_policy = libt::pe_settings::forced; - logger->addMessage(tr("Encryption support [FORCED]"), Log::INFO); - break; - default: // Disabled - encryptionSettings.out_enc_policy = libt::pe_settings::disabled; - encryptionSettings.in_enc_policy = libt::pe_settings::disabled; - logger->addMessage(tr("Encryption support [OFF]"), Log::INFO); - } +void Session::processBigRatios() +{ + qDebug("Process big ratios..."); - qDebug("Applying encryption settings"); - m_nativeSession->set_pe_settings(encryptionSettings); + qreal globalMaxRatio = this->globalMaxRatio(); + foreach (TorrentHandle *const torrent, m_torrents) { + if (torrent->isSeed() && (torrent->ratioLimit() != TorrentHandle::NO_RATIO_LIMIT)) { + const qreal ratio = torrent->realRatio(); + qreal ratioLimit = torrent->ratioLimit(); + if (ratioLimit == TorrentHandle::USE_GLOBAL_RATIO) { + // If Global Max Ratio is really set... + ratioLimit = globalMaxRatio; + if (ratioLimit < 0) continue; + } + qDebug("Ratio: %f (limit: %f)", ratio, ratioLimit); + Q_ASSERT(ratioLimit >= 0.f); - // * Add trackers - m_additionalTrackers.clear(); - if (pref->isAddTrackersEnabled()) { - foreach (QString tracker, pref->getTrackersList().split("\n")) { - tracker = tracker.trimmed(); - if (!tracker.isEmpty()) - m_additionalTrackers << tracker; + if ((ratio <= TorrentHandle::MAX_RATIO) && (ratio >= ratioLimit)) { + Logger* const logger = Logger::instance(); + if (maxRatioAction() == Remove) { + logger->addMessage(tr("'%1' reached the maximum ratio you set. Removing...").arg(torrent->name())); + deleteTorrent(torrent->hash()); + } + else { + // Pause it + if (!torrent->isPaused()) { + logger->addMessage(tr("'%1' reached the maximum ratio you set. Pausing...").arg(torrent->name())); + torrent->pause(); + } + } + } } } - - // * Maximum ratio - setGlobalMaxRatio(pref->getGlobalMaxRatio()); - - // Ip Filter - if (pref->isFilteringEnabled()) - enableIPFilter(pref->getFilter()); - else - disableIPFilter(); - // Add the banned IPs after the possibly disabled IPFilter - // which creates an empty filter and overrides all previously - // applied bans. - FilterParserThread::processFilterList(m_nativeSession, pref->bannedIPs()); - - // * Proxy settings - libt::proxy_settings proxySettings; - if (pref->isProxyEnabled()) { - qDebug("Enabling P2P proxy"); - proxySettings.hostname = Utils::String::toStdString(pref->getProxyIp()); - qDebug("hostname is %s", proxySettings.hostname.c_str()); - proxySettings.port = pref->getProxyPort(); - qDebug("port is %d", proxySettings.port); - if (pref->isProxyAuthEnabled()) { - proxySettings.username = Utils::String::toStdString(pref->getProxyUsername()); - proxySettings.password = Utils::String::toStdString(pref->getProxyPassword()); - qDebug("username is %s", proxySettings.username.c_str()); - qDebug("password is %s", proxySettings.password.c_str()); - } - } - - switch(pref->getProxyType()) { - case Proxy::HTTP: - qDebug("type: http"); - proxySettings.type = libt::proxy_settings::http; - break; - case Proxy::HTTP_PW: - qDebug("type: http_pw"); - proxySettings.type = libt::proxy_settings::http_pw; - break; - case Proxy::SOCKS4: - proxySettings.type = libt::proxy_settings::socks4; - break; - case Proxy::SOCKS5: - qDebug("type: socks5"); - proxySettings.type = libt::proxy_settings::socks5; - break; - case Proxy::SOCKS5_PW: - qDebug("type: socks5_pw"); - proxySettings.type = libt::proxy_settings::socks5_pw; - break; - default: - proxySettings.type = libt::proxy_settings::none; - } - - setProxySettings(proxySettings); - - // Tracker - if (pref->isTrackerEnabled()) { - if (!m_tracker) - m_tracker = new Tracker(this); - - if (m_tracker->start()) - logger->addMessage(tr("Embedded Tracker [ON]"), Log::INFO); - else - logger->addMessage(tr("Failed to start the embedded tracker!"), Log::CRITICAL); - } - else { - logger->addMessage(tr("Embedded Tracker [OFF]")); - if (m_tracker) - delete m_tracker; - } - - qDebug("Session configured"); -} - -void Session::preAllocateAllFiles(bool b) -{ - const bool change = (m_preAllocateAll != b); - if (change) { - qDebug("PreAllocateAll changed, reloading all torrents!"); - m_preAllocateAll = b; - } -} - -void Session::processBigRatios() -{ - qDebug("Process big ratios..."); - - foreach (TorrentHandle *const torrent, m_torrents) { - if (torrent->isSeed() && (torrent->ratioLimit() != TorrentHandle::NO_RATIO_LIMIT)) { - const qreal ratio = torrent->realRatio(); - qreal ratioLimit = torrent->ratioLimit(); - if (ratioLimit == TorrentHandle::USE_GLOBAL_RATIO) { - // If Global Max Ratio is really set... - if (m_globalMaxRatio >= 0) - ratioLimit = m_globalMaxRatio; - else - continue; - } - qDebug("Ratio: %f (limit: %f)", ratio, ratioLimit); - Q_ASSERT(ratioLimit >= 0.f); - - if ((ratio <= TorrentHandle::MAX_RATIO) && (ratio >= ratioLimit)) { - Logger* const logger = Logger::instance(); - if (m_maxRatioAction == Remove) { - logger->addMessage(tr("'%1' reached the maximum ratio you set. Removing...").arg(torrent->name())); - deleteTorrent(torrent->hash()); - } - else { - // Pause it - if (!torrent->isPaused()) { - logger->addMessage(tr("'%1' reached the maximum ratio you set. Pausing...").arg(torrent->name())); - torrent->pause(); - } - } - } - } - } -} +} void Session::handleDownloadFailed(const QString &url, const QString &reason) { @@ -1007,18 +1066,6 @@ void Session::handleDownloadFinished(const QString &url, const QString &filePath Utils::Fs::forceRemove(filePath); // remove temporary file } -void Session::changeSpeedLimitMode(bool alternative) -{ - Preferences* const pref = Preferences::instance(); - // Stop the scheduler when the user has manually changed the bandwidth mode - if (pref->isSchedulerEnabled()) { - pref->setSchedulerEnabled(false); - delete m_bwScheduler; - } - - changeSpeedLimitMode_impl(alternative); -} - // Return the torrent handle, given its hash TorrentHandle *Session::findTorrent(const InfoHash &hash) const { @@ -1046,7 +1093,11 @@ bool Session::hasUnfinishedTorrents() const void Session::banIP(const QString &ip) { FilterParserThread::processFilterList(m_nativeSession, QStringList(ip)); - Preferences::instance()->banIP(ip); + QStringList bannedIPs = m_bannedIPs; + if (!bannedIPs.contains(ip)) { + bannedIPs << ip; + m_bannedIPs = bannedIPs; + } } // Delete a torrent from the session, given its hash @@ -1259,7 +1310,7 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri { addData.savePath = normalizeSavePath( addData.savePath, - ((!addData.resumed && isAutoTMMDisabledByDefault()) ? m_defaultSavePath : "")); + ((!addData.resumed && isAutoTMMDisabledByDefault()) ? defaultSavePath() : "")); if (!addData.category.isEmpty()) { if (!m_categories.contains(addData.category) && !addCategory(addData.category)) { @@ -1347,7 +1398,7 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri qDebug(" -> Hash: %s", qPrintable(hash)); // Preallocation mode - if (m_preAllocateAll) + if (isPreallocationEnabled()) p.storage_mode = libt::storage_mode_allocate; else p.storage_mode = libt::storage_mode_sparse; @@ -1364,9 +1415,8 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri p.flags &= ~libt::add_torrent_params::flag_seed_mode; // Limits - Preferences *const pref = Preferences::instance(); - p.max_connections = pref->getMaxConnecsPerTorrent(); - p.max_uploads = pref->getMaxUploadsPerTorrent(); + p.max_connections = maxConnectionsPerTorrent(); + p.max_uploads = maxUploadsPerTorrent(); p.save_path = Utils::String::toStdString(Utils::Fs::toNativePath(savePath)); // Check if save path exists, creating it otherwise if (!QDir(savePath).exists()) @@ -1448,15 +1498,14 @@ bool Session::loadMetadata(const MagnetUri &magnetUri) // Flags // Preallocation mode - if (m_preAllocateAll) + if (isPreallocationEnabled()) p.storage_mode = libt::storage_mode_allocate; else p.storage_mode = libt::storage_mode_sparse; - Preferences *const pref = Preferences::instance(); // Limits - p.max_connections = pref->getMaxConnecsPerTorrent(); - p.max_uploads = pref->getMaxUploadsPerTorrent(); + p.max_connections = maxConnectionsPerTorrent(); + p.max_uploads = maxUploadsPerTorrent(); QString savePath = QString("%1/%2").arg(QDir::tempPath()).arg(hash); p.save_path = Utils::String::toStdString(Utils::Fs::toNativePath(savePath)); @@ -1485,14 +1534,14 @@ bool Session::loadMetadata(const MagnetUri &magnetUri) void Session::exportTorrentFile(TorrentHandle *const torrent, TorrentExportFolder folder) { - Q_ASSERT(((folder == TorrentExportFolder::Regular) && m_torrentExportEnabled) || - ((folder == TorrentExportFolder::Finished) && m_finishedTorrentExportEnabled)); + Q_ASSERT(((folder == TorrentExportFolder::Regular) && !torrentExportDirectory().isEmpty()) || + ((folder == TorrentExportFolder::Finished) && !finishedTorrentExportDirectory().isEmpty())); QString validName = Utils::Fs::toValidFileSystemName(torrent->name()); QString torrentFilename = QString("%1.torrent").arg(torrent->hash()); QString torrentExportFilename = QString("%1.torrent").arg(validName); QString torrentPath = QDir(m_resumeFolderPath).absoluteFilePath(torrentFilename); - QDir exportPath(folder == TorrentExportFolder::Regular ? Preferences::instance()->getTorrentExportDir() : Preferences::instance()->getFinishedTorrentExportDir()); + QDir exportPath(folder == TorrentExportFolder::Regular ? torrentExportDirectory() : finishedTorrentExportDirectory()); if (exportPath.exists() || exportPath.mkpath(exportPath.absolutePath())) { QString newTorrentPath = exportPath.absoluteFilePath(torrentExportFilename); int counter = 0; @@ -1507,55 +1556,15 @@ void Session::exportTorrentFile(TorrentHandle *const torrent, TorrentExportFolde } } -void Session::setMaxConnectionsPerTorrent(int max) -{ - qDebug() << Q_FUNC_INFO << max; - - // Apply this to all session torrents - std::vector handles = m_nativeSession->get_torrents(); - std::vector::const_iterator it = handles.begin(); - std::vector::const_iterator itend = handles.end(); - for ( ; it != itend; ++it) { - if (!it->is_valid()) continue; - try { - it->set_max_connections(max); - } - catch(std::exception) {} - } -} - -void Session::setMaxUploadsPerTorrent(int max) -{ - qDebug() << Q_FUNC_INFO << max; - - // Apply this to all session torrents - std::vector handles = m_nativeSession->get_torrents(); - std::vector::const_iterator it = handles.begin(); - std::vector::const_iterator itend = handles.end(); - for ( ; it != itend; ++it) { - if (!it->is_valid()) continue; - try { - it->set_max_uploads(max); - } - catch(std::exception) {} - } -} - void Session::enableLSD(bool enable) { if (enable) { - if (!m_LSDEnabled) { - qDebug("Enabling Local Peer Discovery"); - m_nativeSession->start_lsd(); - m_LSDEnabled = true; - } + m_nativeSession->start_lsd(); + Logger::instance()->addMessage(tr("Local Peer Discovery support [ON]"), Log::INFO); } else { - if (m_LSDEnabled) { - qDebug("Disabling Local Peer Discovery"); - m_nativeSession->stop_lsd(); - m_LSDEnabled = false; - } + m_nativeSession->stop_lsd(); + Logger::instance()->addMessage(tr("Local Peer Discovery support [OFF]"), Log::INFO); } } @@ -1565,31 +1574,25 @@ void Session::enableDHT(bool enable) Logger* const logger = Logger::instance(); if (enable) { - if (!m_DHTEnabled) { + if (!m_nativeSession->is_dht_running()) { try { - qDebug() << "Starting DHT..."; - Q_ASSERT(!m_nativeSession->is_dht_running()); m_nativeSession->start_dht(); m_nativeSession->add_dht_router(std::make_pair(std::string("router.bittorrent.com"), 6881)); m_nativeSession->add_dht_router(std::make_pair(std::string("router.utorrent.com"), 6881)); m_nativeSession->add_dht_router(std::make_pair(std::string("dht.transmissionbt.com"), 6881)); m_nativeSession->add_dht_router(std::make_pair(std::string("dht.aelitis.com"), 6881)); // Vuze - m_DHTEnabled = true; logger->addMessage(tr("DHT support [ON]"), Log::INFO); - qDebug("DHT enabled"); } - catch(std::exception &e) { + catch (std::exception &e) { qDebug("Could not enable DHT, reason: %s", e.what()); - logger->addMessage(tr("DHT support [OFF]. Reason: %1").arg(Utils::String::fromStdString(e.what())), Log::CRITICAL); + logger->addMessage(tr("DHT support [FAILED]. Reason: %1").arg(Utils::String::fromStdString(e.what())), Log::CRITICAL); } } } else { - if (m_DHTEnabled) { - m_DHTEnabled = false; + if (m_nativeSession->is_dht_running()) { m_nativeSession->stop_dht(); logger->addMessage(tr("DHT support [OFF]"), Log::INFO); - qDebug("DHT disabled"); } } } @@ -1597,27 +1600,11 @@ void Session::enableDHT(bool enable) void Session::changeSpeedLimitMode_impl(bool alternative) { qDebug() << Q_FUNC_INFO << alternative; - Preferences* const pref = Preferences::instance(); + if (alternative == isAltGlobalSpeedLimitEnabled()) return; // Save new state to remember it on startup - pref->setAltBandwidthEnabled(alternative); - - // Apply settings to the bittorrent session - int downLimit = alternative ? pref->getAltGlobalDownloadLimit() : pref->getGlobalDownloadLimit(); - if (downLimit <= 0) - downLimit = -1; - else - downLimit *= 1024; - setDownloadRateLimit(downLimit); - - // Upload rate - int upLimit = alternative ? pref->getAltGlobalUploadLimit() : pref->getGlobalUploadLimit(); - if (upLimit <= 0) - upLimit = -1; - else - upLimit *= 1024; - setUploadRateLimit(upLimit); - + m_isAltGlobalSpeedLimitEnabled = alternative; + configureDeferred(); // Notify emit speedLimitModeChanged(alternative); } @@ -1674,10 +1661,9 @@ void Session::saveResumeData() void Session::setDefaultSavePath(QString path) { path = normalizeSavePath(path); - if (m_defaultSavePath == path) return; + if (path == m_defaultSavePath) return; m_defaultSavePath = path; - m_settings->storeValue(KEY_DEFAULTSAVEPATH, m_defaultSavePath); if (isDisableAutoTMMWhenDefaultSavePathChanged()) foreach (TorrentHandle *const torrent, torrents()) @@ -1689,26 +1675,15 @@ void Session::setDefaultSavePath(QString path) void Session::setTempPath(QString path) { - path = normalizeSavePath(path, m_defaultSavePath + "temp"); - if (m_tempPath == path) return; + path = normalizeSavePath(path, defaultSavePath() + "temp/"); + if (path == m_tempPath) return; m_tempPath = path; - m_settings->storeValue(KEY_TEMPPATH, m_tempPath); foreach (TorrentHandle *const torrent, m_torrents) torrent->handleTempPathChanged(); } -void Session::setAppendExtension(bool append) -{ - if (m_appendExtension != append) { - m_appendExtension = append; - // append or remove .!qB extension for incomplete files - foreach (TorrentHandle *const torrent, m_torrents) - torrent->handleAppendExtensionToggled(); - } -} - void Session::networkOnlineStateChanged(const bool online) { Logger::instance()->addMessage(tr("System network status changed to %1", "e.g: System network status changed to ONLINE").arg(online ? tr("ONLINE") : tr("OFFLINE")), Log::INFO); @@ -1716,27 +1691,26 @@ void Session::networkOnlineStateChanged(const bool online) void Session::networkConfigurationChange(const QNetworkConfiguration& cfg) { - const QString configuredInterfaceName = Preferences::instance()->getNetworkInterface(); + const QString configuredInterfaceName = networkInterface(); // Empty means "Any Interface". In this case libtorrent has binded to 0.0.0.0 so any change to any interface will // be automatically picked up. Otherwise we would rebinding here to 0.0.0.0 again. - if (configuredInterfaceName.isEmpty()) - return; + if (configuredInterfaceName.isEmpty()) return; + const QString changedInterface = cfg.name(); if (configuredInterfaceName == changedInterface) { Logger::instance()->addMessage(tr("Network configuration of %1 has changed, refreshing session binding", "e.g: Network configuration of tun0 has changed, refreshing session binding").arg(changedInterface), Log::INFO); - setListeningPort(); + configureListeningInterface(); } } const QStringList Session::getListeningIPs() { - Preferences* const pref = Preferences::instance(); Logger* const logger = Logger::instance(); QStringList IPs; - const QString ifaceName = pref->getNetworkInterface(); - const QString ifaceAddr = pref->getNetworkInterfaceAddress(); - const bool listenIPv6 = pref->getListenIPv6(); + const QString ifaceName = networkInterface(); + const QString ifaceAddr = networkInterfaceAddress(); + const bool listenIPv6 = isIPv6Enabled(); if (!ifaceAddr.isEmpty()) { QHostAddress addr(ifaceAddr); @@ -1779,7 +1753,7 @@ const QStringList Session::getListeningIPs() || (listenIPv6 && (protocol == QAbstractSocket::IPv4Protocol))) continue; - // If an iface address has been defined only allow ip's that match it to go through + //If an iface address has been defined only allow ip's that match it to go through if (!ifaceAddr.isEmpty()) { if (ifaceAddr == ipString) { IPs.append(ipString); @@ -1804,14 +1778,14 @@ const QStringList Session::getListeningIPs() // Set the ports range in which is chosen the port // the BitTorrent session will listen to -void Session::setListeningPort() +void Session::configureListeningInterface() { - Preferences* const pref = Preferences::instance(); - const unsigned short port = pref->getSessionPort(); + const ushort port = this->port(); qDebug() << Q_FUNC_INFO << port; + Logger* const logger = Logger::instance(); - std::pair ports(port, port); + std::pair ports(port, port); libt::error_code ec; const QStringList IPs = getListeningIPs(); @@ -1834,223 +1808,840 @@ void Session::setListeningPort() } } -// Set download rate limit -// -1 to disable -void Session::setDownloadRateLimit(int rate) +int Session::globalDownloadSpeedLimit() const { - qDebug() << Q_FUNC_INFO << rate; - Q_ASSERT((rate == -1) || (rate >= 0)); - libt::session_settings settings = m_nativeSession->settings(); - settings.download_rate_limit = rate; - m_nativeSession->set_settings(settings); + return m_globalDownloadSpeedLimit; } -// Set upload rate limit -// -1 to disable -void Session::setUploadRateLimit(int rate) +void Session::setGlobalDownloadSpeedLimit(int limit) { - qDebug() << Q_FUNC_INFO << rate; - Q_ASSERT((rate == -1) || (rate >= 0)); - libt::session_settings settings = m_nativeSession->settings(); - settings.upload_rate_limit = rate; - m_nativeSession->set_settings(settings); + if (limit < 0) limit = 0; + if (limit == globalDownloadSpeedLimit()) return; + + m_globalDownloadSpeedLimit = limit; + if (!isAltGlobalSpeedLimitEnabled()) + configureDeferred(); } -int Session::downloadRateLimit() const +int Session::globalUploadSpeedLimit() const { - return m_nativeSession->settings().download_rate_limit; + return m_globalUploadSpeedLimit; } -int Session::uploadRateLimit() const +void Session::setGlobalUploadSpeedLimit(int limit) { - return m_nativeSession->settings().upload_rate_limit; + if (limit < 0) limit = 0; + if (limit == globalUploadSpeedLimit()) return; + + m_globalUploadSpeedLimit = limit; + if (!isAltGlobalSpeedLimitEnabled()) + configureDeferred(); } -bool Session::isListening() const +int Session::altGlobalDownloadSpeedLimit() const { - return m_nativeSession->is_listening(); + return m_altGlobalDownloadSpeedLimit; } -MaxRatioAction Session::maxRatioAction() const +void Session::setAltGlobalDownloadSpeedLimit(int limit) { - return m_maxRatioAction; + if (limit < 0) limit = 0; + if (limit == altGlobalDownloadSpeedLimit()) return; + + m_altGlobalDownloadSpeedLimit = limit; + if (isAltGlobalSpeedLimitEnabled()) + configureDeferred(); } -void Session::setMaxRatioAction(MaxRatioAction act) +int Session::altGlobalUploadSpeedLimit() const { - if (m_maxRatioAction != act) { - m_maxRatioAction = act; - m_settings->storeValue(KEY_MAXRATIOACTION, act); - } + return m_altGlobalUploadSpeedLimit; } -// Torrents will a ratio superior to the given value will -// be automatically deleted -void Session::setGlobalMaxRatio(qreal ratio) +void Session::setAltGlobalUploadSpeedLimit(int limit) { - if (ratio < 0) - ratio = -1.; - if (m_globalMaxRatio != ratio) { - m_globalMaxRatio = ratio; - qDebug("* Set globalMaxRatio to %.1f", m_globalMaxRatio); - updateRatioTimer(); - } + if (limit < 0) limit = 0; + if (limit == altGlobalUploadSpeedLimit()) return; + + m_altGlobalUploadSpeedLimit = limit; + if (isAltGlobalSpeedLimitEnabled()) + configureDeferred(); } -// If this functions returns true, we cannot add torrent to session, -// but it is still possible to merge trackers in some case -bool Session::isKnownTorrent(const InfoHash &hash) const +int Session::downloadSpeedLimit() const { - return (m_torrents.contains(hash) - || m_addingTorrents.contains(hash) - || m_loadedMetadata.contains(hash)); + return isAltGlobalSpeedLimitEnabled() + ? altGlobalDownloadSpeedLimit() + : globalDownloadSpeedLimit(); } -void Session::updateRatioTimer() +void Session::setDownloadSpeedLimit(int limit) { - if ((m_globalMaxRatio == -1) && !hasPerTorrentRatioLimit()) { - if (m_bigRatioTimer->isActive()) - m_bigRatioTimer->stop(); - } - else if (!m_bigRatioTimer->isActive()) { - m_bigRatioTimer->start(); - } + if (isAltGlobalSpeedLimitEnabled()) + setAltGlobalDownloadSpeedLimit(limit); + else + setGlobalDownloadSpeedLimit(limit); } -void Session::handleTorrentRatioLimitChanged(TorrentHandle *const torrent) +int Session::uploadSpeedLimit() const { - Q_UNUSED(torrent); - updateRatioTimer(); + return isAltGlobalSpeedLimitEnabled() + ? altGlobalUploadSpeedLimit() + : globalUploadSpeedLimit(); } -void Session::saveTorrentResumeData(TorrentHandle *const torrent) +void Session::setUploadSpeedLimit(int limit) { - torrent->saveResumeData(); - ++m_numResumeData; + if (isAltGlobalSpeedLimitEnabled()) + setAltGlobalUploadSpeedLimit(limit); + else + setGlobalUploadSpeedLimit(limit); } -void Session::handleTorrentSavePathChanged(TorrentHandle *const torrent) +bool Session::isAltGlobalSpeedLimitEnabled() const { - emit torrentSavePathChanged(torrent); + return m_isAltGlobalSpeedLimitEnabled; } -void Session::handleTorrentCategoryChanged(TorrentHandle *const torrent, const QString &oldCategory) +void Session::setAltGlobalSpeedLimitEnabled(bool enabled) { - emit torrentCategoryChanged(torrent, oldCategory); + // Stop the scheduler when the user has manually changed the bandwidth mode + if (isBandwidthSchedulerEnabled()) + setBandwidthSchedulerEnabled(false); + + changeSpeedLimitMode_impl(enabled); } -void Session::handleTorrentSavingModeChanged(TorrentHandle * const torrent) +bool Session::isBandwidthSchedulerEnabled() const { - emit torrentSavingModeChanged(torrent); + return m_isBandwidthSchedulerEnabled; } -void Session::handleTorrentTrackersAdded(TorrentHandle *const torrent, const QList &newTrackers) +void Session::setBandwidthSchedulerEnabled(bool enabled) { - foreach (const TrackerEntry &newTracker, newTrackers) - Logger::instance()->addMessage(tr("Tracker '%1' was added to torrent '%2'").arg(newTracker.url()).arg(torrent->name())); - emit trackersAdded(torrent, newTrackers); - if (torrent->trackers().size() == newTrackers.size()) - emit trackerlessStateChanged(torrent, false); - emit trackersChanged(torrent); + if (enabled != isBandwidthSchedulerEnabled()) { + m_isBandwidthSchedulerEnabled = enabled; + if (enabled) + enableBandwidthScheduler(); + else + delete m_bwScheduler; + } } -void Session::handleTorrentTrackersRemoved(TorrentHandle *const torrent, const QList &deletedTrackers) +uint Session::saveResumeDataInterval() const { - foreach (const TrackerEntry &deletedTracker, deletedTrackers) - Logger::instance()->addMessage(tr("Tracker '%1' was deleted from torrent '%2'").arg(deletedTracker.url()).arg(torrent->name())); - emit trackersRemoved(torrent, deletedTrackers); - if (torrent->trackers().size() == 0) - emit trackerlessStateChanged(torrent, true); - emit trackersChanged(torrent); + return m_saveResumeDataInterval; } -void Session::handleTorrentTrackersChanged(TorrentHandle *const torrent) +void Session::setSaveResumeDataInterval(uint value) { - emit trackersChanged(torrent); + if (value != saveResumeDataInterval()) { + m_saveResumeDataInterval = value; + m_resumeDataTimer->setInterval(value * 60 * 1000); + } } -void Session::handleTorrentUrlSeedsAdded(TorrentHandle *const torrent, const QList &newUrlSeeds) +int Session::port() const { - foreach (const QUrl &newUrlSeed, newUrlSeeds) - Logger::instance()->addMessage(tr("URL seed '%1' was added to torrent '%2'").arg(newUrlSeed.toString()).arg(torrent->name())); + static int randomPort = rand() % 64512 + 1024; + if (useRandomPort()) + return randomPort; + return m_port; } -void Session::handleTorrentUrlSeedsRemoved(TorrentHandle *const torrent, const QList &urlSeeds) +void Session::setPort(int port) { - foreach (const QUrl &urlSeed, urlSeeds) - Logger::instance()->addMessage(tr("URL seed '%1' was removed from torrent '%2'").arg(urlSeed.toString()).arg(torrent->name())); + if (port != this->port()) { + m_port = port; + configureListeningInterface(); + } } -void Session::handleTorrentMetadataReceived(TorrentHandle *const torrent) +bool Session::useRandomPort() const { - saveTorrentResumeData(torrent); + return m_useRandomPort; +} - // Save metadata - const QDir resumeDataDir(m_resumeFolderPath); - QString torrentFile = resumeDataDir.absoluteFilePath(QString("%1.torrent").arg(torrent->hash())); - if (torrent->saveTorrentFile(torrentFile)) { - // Copy the torrent file to the export folder - if (m_torrentExportEnabled) - exportTorrentFile(torrent); - } +void Session::setUseRandomPort(bool value) +{ + m_useRandomPort = value; +} - emit torrentMetadataLoaded(torrent); +QString Session::networkInterface() const +{ + return m_networkInterface; } -void Session::handleTorrentPaused(TorrentHandle *const torrent) +void Session::setNetworkInterface(const QString &interface) { - if (!torrent->hasError() && !torrent->hasMissingFiles()) - saveTorrentResumeData(torrent); - emit torrentPaused(torrent); + if (interface != networkInterface()) { + m_networkInterface = interface; + configureListeningInterface(); + } } -void Session::handleTorrentResumed(TorrentHandle *const torrent) +QString Session::networkInterfaceAddress() const { - emit torrentResumed(torrent); + return m_networkInterfaceAddress; } -void Session::handleTorrentChecked(TorrentHandle *const torrent) +void Session::setNetworkInterfaceAddress(const QString &address) { - emit torrentFinishedChecking(torrent); + if (address != networkInterfaceAddress()) { + m_networkInterfaceAddress = address; + configureListeningInterface(); + } } -void Session::handleTorrentFinished(TorrentHandle *const torrent) +bool Session::isIPv6Enabled() const { - if (!torrent->hasError() && !torrent->hasMissingFiles()) - saveTorrentResumeData(torrent); - emit torrentFinished(torrent); + return m_isIPv6Enabled; +} - qDebug("Checking if the torrent contains torrent files to download"); - // Check if there are torrent files inside - for (int i = 0; i < torrent->filesCount(); ++i) { - const QString torrentRelpath = torrent->filePath(i); - if (torrentRelpath.endsWith(".torrent", Qt::CaseInsensitive)) { - qDebug("Found possible recursive torrent download."); - const QString torrentFullpath = torrent->savePath(true) + "/" + torrentRelpath; - qDebug("Full subtorrent path is %s", qPrintable(torrentFullpath)); - TorrentInfo torrentInfo = TorrentInfo::loadFromFile(torrentFullpath); - if (torrentInfo.isValid()) { - qDebug("emitting recursiveTorrentDownloadPossible()"); - emit recursiveTorrentDownloadPossible(torrent); - break; - } - else { - qDebug("Caught error loading torrent"); - Logger::instance()->addMessage(tr("Unable to decode '%1' torrent file.").arg(Utils::Fs::toNativePath(torrentFullpath)), Log::CRITICAL); - } - } +void Session::setIPv6Enabled(bool enabled) +{ + if (enabled != isIPv6Enabled()) { + m_isIPv6Enabled = enabled; + configureListeningInterface(); } +} - Preferences *const pref = Preferences::instance(); - // Move .torrent file to another folder - if (pref->isFinishedTorrentExportEnabled()) - exportTorrentFile(torrent, TorrentExportFolder::Finished); +int Session::encryption() const +{ + return m_encryption; +} - if (!hasUnfinishedTorrents()) - emit allTorrentsFinished(); +void Session::setEncryption(int state) +{ + if (state != encryption()) { + m_encryption = state; + configureEncryption(); + } } -void Session::handleTorrentResumeDataReady(TorrentHandle *const torrent, const libtorrent::entry &data) +bool Session::isForceProxyEnabled() const +{ + return m_isForceProxyEnabled; +} + +void Session::setForceProxyEnabled(bool enabled) +{ + if (enabled != isForceProxyEnabled()) { + m_isForceProxyEnabled = enabled; + configureDeferred(); + } +} + +bool Session::isProxyPeerConnectionsEnabled() const +{ + return m_isProxyPeerConnectionsEnabled; +} + +void Session::setProxyPeerConnectionsEnabled(bool enabled) +{ + if (enabled != isProxyPeerConnectionsEnabled()) { + m_isProxyPeerConnectionsEnabled = enabled; + configureDeferred(); + } +} + +bool Session::isAddTrackersEnabled() const +{ + return m_isAddTrackersEnabled; +} + +void Session::setAddTrackersEnabled(bool enabled) +{ + m_isAddTrackersEnabled = enabled; +} + +QString Session::additionalTrackers() const +{ + return m_additionalTrackers; +} + +void Session::setAdditionalTrackers(const QString &trackers) +{ + if (trackers != additionalTrackers()) { + m_additionalTrackers = trackers; + populateAdditionalTrackers(); + } +} + +bool Session::isFilteringEnabled() const +{ + return m_isFilteringEnabled; +} + +void Session::setFilteringEnabled(bool enabled) +{ + if (enabled != m_isFilteringEnabled) { + m_isFilteringEnabled = enabled; + configureDeferred(); + } +} + +QString Session::IPFilterFile() const +{ + return Utils::Fs::fromNativePath(m_IPFilterFile); +} + +void Session::setIPFilterFile(QString path) +{ + path = Utils::Fs::fromNativePath(path); + if (path != IPFilterFile()) { + m_IPFilterFile = path; + configureDeferred(); + } +} + +int Session::maxConnectionsPerTorrent() const +{ + return m_maxConnectionsPerTorrent; +} + +void Session::setMaxConnectionsPerTorrent(int max) +{ + max = (max > 0) ? max : -1; + if (max != maxConnectionsPerTorrent()) { + m_maxConnectionsPerTorrent = max; + + // Apply this to all session torrents + for (const auto &handle: m_nativeSession->get_torrents()) { + if (!handle.is_valid()) continue; + try { + handle.set_max_connections(max); + } + catch(std::exception) {} + } + } +} + +int Session::maxUploadsPerTorrent() const +{ + return m_maxUploadsPerTorrent; +} + +void Session::setMaxUploadsPerTorrent(int max) +{ + max = (max > 0) ? max : -1; + if (max != maxUploadsPerTorrent()) { + m_maxUploadsPerTorrent = max; + + // Apply this to all session torrents + for (const auto &handle: m_nativeSession->get_torrents()) { + if (!handle.is_valid()) continue; + try { + handle.set_max_uploads(max); + } + catch(std::exception) {} + } + } +} + +bool Session::announceToAllTrackers() const +{ + return m_announceToAllTrackers; +} + +void Session::setAnnounceToAllTrackers(bool val) +{ + if (val != m_announceToAllTrackers) { + m_announceToAllTrackers = val; + configureDeferred(); + } +} + +uint Session::diskCacheSize() const +{ + uint size = m_diskCacheSize; + // These macros may not be available on compilers other than MSVC and GCC +#if defined(__x86_64__) || defined(_M_X64) + size = qMin(size, 4096u); // 4GiB +#else + // When build as 32bit binary, set the maximum at less than 2GB to prevent crashes + // allocate 1536MiB and leave 512MiB to the rest of program data in RAM + size = qMin(size, 1536u); +#endif + return size; +} + +void Session::setDiskCacheSize(uint size) +{ +#if defined(__x86_64__) || defined(_M_X64) + size = qMin(size, 4096u); // 4GiB +#else + // allocate 1536MiB and leave 512MiB to the rest of program data in RAM + size = qMin(size, 1536u); +#endif + if (size != m_diskCacheSize) { + m_diskCacheSize = size; + configureDeferred(); + } +} + +uint Session::diskCacheTTL() const +{ + return m_diskCacheTTL; +} + +void Session::setDiskCacheTTL(uint ttl) +{ + if (ttl != m_diskCacheTTL) { + m_diskCacheTTL = ttl; + configureDeferred(); + } +} + +bool Session::useOSCache() const +{ + return m_useOSCache; +} + +void Session::setUseOSCache(bool use) +{ + if (use != m_useOSCache) { + m_useOSCache = use; + configureDeferred(); + } +} + +bool Session::isAnonymousModeEnabled() const +{ + return m_isAnonymousModeEnabled; +} + +void Session::setAnonymousModeEnabled(bool enabled) +{ + if (enabled != m_isAnonymousModeEnabled) { + m_isAnonymousModeEnabled = enabled; + configureDeferred(); + } +} + +bool Session::isQueueingSystemEnabled() const +{ + return m_isQueueingEnabled; +} + +void Session::setQueueingSystemEnabled(bool enabled) +{ + if (enabled != m_isQueueingEnabled) { + m_isQueueingEnabled = enabled; + configureDeferred(); + } +} + +int Session::maxActiveDownloads() const +{ + return m_maxActiveDownloads; +} + +void Session::setMaxActiveDownloads(int max) +{ + max = std::max(max, -1); + if (max != m_maxActiveDownloads) { + m_maxActiveDownloads = max; + configureDeferred(); + } +} + +int Session::maxActiveUploads() const +{ + return m_maxActiveUploads; +} + +void Session::setMaxActiveUploads(int max) +{ + max = std::max(max, -1); + if (max != m_maxActiveUploads) { + m_maxActiveUploads = max; + configureDeferred(); + } +} + +int Session::maxActiveTorrents() const +{ + return m_maxActiveTorrents; +} + +void Session::setMaxActiveTorrents(int max) +{ + max = std::max(max, -1); + if (max != m_maxActiveTorrents) { + m_maxActiveTorrents = max; + configureDeferred(); + } +} + +bool Session::ignoreSlowTorrentsForQueueing() const +{ + return m_ignoreSlowTorrentsForQueueing; +} + +void Session::setIgnoreSlowTorrentsForQueueing(bool ignore) +{ + if (ignore != m_ignoreSlowTorrentsForQueueing) { + m_ignoreSlowTorrentsForQueueing = ignore; + configureDeferred(); + } +} + +uint Session::outgoingPortsMin() const +{ + return m_outgoingPortsMin; +} + +void Session::setOutgoingPortsMin(uint min) +{ + if (min != m_outgoingPortsMin) { + m_outgoingPortsMin = min; + configureDeferred(); + } +} + +uint Session::outgoingPortsMax() const +{ + return m_outgoingPortsMax; +} + +void Session::setOutgoingPortsMax(uint max) +{ + if (max != m_outgoingPortsMax) { + m_outgoingPortsMax = max; + configureDeferred(); + } +} + +bool Session::ignoreLimitsOnLAN() const +{ + return m_ignoreLimitsOnLAN; +} + +void Session::setIgnoreLimitsOnLAN(bool ignore) +{ + if (ignore != m_ignoreLimitsOnLAN) { + m_ignoreLimitsOnLAN = ignore; + configureDeferred(); + } +} + +bool Session::includeOverheadInLimits() const +{ + return m_includeOverheadInLimits; +} + +void Session::setIncludeOverheadInLimits(bool include) +{ + if (include != m_includeOverheadInLimits) { + m_includeOverheadInLimits = include; + configureDeferred(); + } +} + +QString Session::networkAddress() const +{ + return m_networkAddress; +} + +void Session::setNetworkAddress(const QString &addr) +{ + if (addr != m_networkAddress) { + m_networkAddress = addr; + configureDeferred(); + } +} + +bool Session::isSuperSeedingEnabled() const +{ + return m_isSuperSeedingEnabled; +} + +void Session::setSuperSeedingEnabled(bool enabled) +{ + if (enabled != m_isSuperSeedingEnabled) { + m_isSuperSeedingEnabled = enabled; + configureDeferred(); + } +} + +int Session::maxConnections() const +{ + return m_maxConnections; +} + +void Session::setMaxConnections(int max) +{ + max = (max > 0) ? max : -1; + if (max != m_maxConnections) { + m_maxConnections = max; + configureDeferred(); + } +} + +int Session::maxHalfOpenConnections() const +{ + return m_maxHalfOpenConnections; +} + +void Session::setMaxHalfOpenConnections(int max) +{ + max = (max > 0) ? max : -1; + if (max != m_maxHalfOpenConnections) { + m_maxHalfOpenConnections = max; + configureDeferred(); + } +} + +int Session::maxUploads() const +{ + return m_maxUploads; +} + +void Session::setMaxUploads(int max) +{ + max = (max > 0) ? max : -1; + if (max != m_maxUploads) { + m_maxUploads = max; + configureDeferred(); + } +} + +bool Session::isUTPEnabled() const +{ + return m_isUTPEnabled; +} + +void Session::setUTPEnabled(bool enabled) +{ + if (enabled != m_isUTPEnabled) { + m_isUTPEnabled = enabled; + configureDeferred(); + } +} + +bool Session::isUTPRateLimited() const +{ + return m_isUTPRateLimited; +} + +void Session::setUTPRateLimited(bool limited) +{ + if (limited != m_isUTPRateLimited) { + m_isUTPRateLimited = limited; + configureDeferred(); + } +} + +bool Session::isTrackerFilteringEnabled() const +{ + return m_isTrackerFilteringEnabled; +} + +void Session::setTrackerFilteringEnabled(bool enabled) +{ + if (enabled != m_isTrackerFilteringEnabled) { + m_isTrackerFilteringEnabled = enabled; + configureDeferred(); + } +} + +void Session::configureEncryption() +{ + Logger *const logger = Logger::instance(); + + // The most secure, rc4 only so that all streams and encrypted + libt::pe_settings encryptionSettings; + encryptionSettings.allowed_enc_level = libt::pe_settings::rc4; + encryptionSettings.prefer_rc4 = true; + switch (encryption()) { + case 0: //Enabled + encryptionSettings.out_enc_policy = libt::pe_settings::enabled; + encryptionSettings.in_enc_policy = libt::pe_settings::enabled; + logger->addMessage(tr("Encryption support [ON]"), Log::INFO); + break; + case 1: // Forced + encryptionSettings.out_enc_policy = libt::pe_settings::forced; + encryptionSettings.in_enc_policy = libt::pe_settings::forced; + logger->addMessage(tr("Encryption support [FORCED]"), Log::INFO); + break; + default: // Disabled + encryptionSettings.out_enc_policy = libt::pe_settings::disabled; + encryptionSettings.in_enc_policy = libt::pe_settings::disabled; + logger->addMessage(tr("Encryption support [OFF]"), Log::INFO); + } + + m_nativeSession->set_pe_settings(encryptionSettings); +} + +bool Session::isListening() const +{ + return m_nativeSession->is_listening(); +} + +MaxRatioAction Session::maxRatioAction() const +{ + return static_cast(m_maxRatioAction.value()); +} + +void Session::setMaxRatioAction(MaxRatioAction act) +{ + m_maxRatioAction = static_cast(act); +} + +// If this functions returns true, we cannot add torrent to session, +// but it is still possible to merge trackers in some case +bool Session::isKnownTorrent(const InfoHash &hash) const +{ + return (m_torrents.contains(hash) + || m_addingTorrents.contains(hash) + || m_loadedMetadata.contains(hash)); +} + +void Session::updateRatioTimer() +{ + if ((globalMaxRatio() == -1) && !hasPerTorrentRatioLimit()) { + if (m_bigRatioTimer->isActive()) + m_bigRatioTimer->stop(); + } + else if (!m_bigRatioTimer->isActive()) { + m_bigRatioTimer->start(); + } +} + +void Session::handleTorrentRatioLimitChanged(TorrentHandle *const torrent) +{ + Q_UNUSED(torrent); + updateRatioTimer(); +} + +void Session::saveTorrentResumeData(TorrentHandle *const torrent) +{ + torrent->saveResumeData(); + ++m_numResumeData; +} + +void Session::handleTorrentSavePathChanged(TorrentHandle *const torrent) +{ + emit torrentSavePathChanged(torrent); +} + +void Session::handleTorrentCategoryChanged(TorrentHandle *const torrent, const QString &oldCategory) +{ + emit torrentCategoryChanged(torrent, oldCategory); +} + +void Session::handleTorrentSavingModeChanged(TorrentHandle * const torrent) +{ + emit torrentSavingModeChanged(torrent); +} + +void Session::handleTorrentTrackersAdded(TorrentHandle *const torrent, const QList &newTrackers) +{ + foreach (const TrackerEntry &newTracker, newTrackers) + Logger::instance()->addMessage(tr("Tracker '%1' was added to torrent '%2'").arg(newTracker.url()).arg(torrent->name())); + emit trackersAdded(torrent, newTrackers); + if (torrent->trackers().size() == newTrackers.size()) + emit trackerlessStateChanged(torrent, false); + emit trackersChanged(torrent); +} + +void Session::handleTorrentTrackersRemoved(TorrentHandle *const torrent, const QList &deletedTrackers) +{ + foreach (const TrackerEntry &deletedTracker, deletedTrackers) + Logger::instance()->addMessage(tr("Tracker '%1' was deleted from torrent '%2'").arg(deletedTracker.url()).arg(torrent->name())); + emit trackersRemoved(torrent, deletedTrackers); + if (torrent->trackers().size() == 0) + emit trackerlessStateChanged(torrent, true); + emit trackersChanged(torrent); +} + +void Session::handleTorrentTrackersChanged(TorrentHandle *const torrent) +{ + emit trackersChanged(torrent); +} + +void Session::handleTorrentUrlSeedsAdded(TorrentHandle *const torrent, const QList &newUrlSeeds) +{ + foreach (const QUrl &newUrlSeed, newUrlSeeds) + Logger::instance()->addMessage(tr("URL seed '%1' was added to torrent '%2'").arg(newUrlSeed.toString()).arg(torrent->name())); +} + +void Session::handleTorrentUrlSeedsRemoved(TorrentHandle *const torrent, const QList &urlSeeds) +{ + foreach (const QUrl &urlSeed, urlSeeds) + Logger::instance()->addMessage(tr("URL seed '%1' was removed from torrent '%2'").arg(urlSeed.toString()).arg(torrent->name())); +} + +void Session::handleTorrentMetadataReceived(TorrentHandle *const torrent) +{ + saveTorrentResumeData(torrent); + + // Save metadata + const QDir resumeDataDir(m_resumeFolderPath); + QString torrentFile = resumeDataDir.absoluteFilePath(QString("%1.torrent").arg(torrent->hash())); + if (torrent->saveTorrentFile(torrentFile)) { + // Copy the torrent file to the export folder + if (!torrentExportDirectory().isEmpty()) + exportTorrentFile(torrent); + } + + emit torrentMetadataLoaded(torrent); +} + +void Session::handleTorrentPaused(TorrentHandle *const torrent) +{ + if (!torrent->hasError() && !torrent->hasMissingFiles()) + saveTorrentResumeData(torrent); + emit torrentPaused(torrent); +} + +void Session::handleTorrentResumed(TorrentHandle *const torrent) +{ + emit torrentResumed(torrent); +} + +void Session::handleTorrentChecked(TorrentHandle *const torrent) +{ + emit torrentFinishedChecking(torrent); +} + +void Session::handleTorrentFinished(TorrentHandle *const torrent) +{ + if (!torrent->hasError() && !torrent->hasMissingFiles()) + saveTorrentResumeData(torrent); + emit torrentFinished(torrent); + + qDebug("Checking if the torrent contains torrent files to download"); + // Check if there are torrent files inside + for (int i = 0; i < torrent->filesCount(); ++i) { + const QString torrentRelpath = torrent->filePath(i); + if (torrentRelpath.endsWith(".torrent", Qt::CaseInsensitive)) { + qDebug("Found possible recursive torrent download."); + const QString torrentFullpath = torrent->savePath(true) + "/" + torrentRelpath; + qDebug("Full subtorrent path is %s", qPrintable(torrentFullpath)); + TorrentInfo torrentInfo = TorrentInfo::loadFromFile(torrentFullpath); + if (torrentInfo.isValid()) { + qDebug("emitting recursiveTorrentDownloadPossible()"); + emit recursiveTorrentDownloadPossible(torrent); + break; + } + else { + qDebug("Caught error loading torrent"); + Logger::instance()->addMessage(tr("Unable to decode '%1' torrent file.").arg(Utils::Fs::toNativePath(torrentFullpath)), Log::CRITICAL); + } + } + } + + // Move .torrent file to another folder + if (!finishedTorrentExportDirectory().isEmpty()) + exportTorrentFile(torrent, TorrentExportFolder::Finished); + + if (!hasUnfinishedTorrents()) + emit allTorrentsFinished(); +} + +void Session::handleTorrentResumeDataReady(TorrentHandle *const torrent, const libtorrent::entry &data) { --m_numResumeData; @@ -2115,6 +2706,14 @@ void Session::initResumeFolder() } } +void Session::configureDeferred() +{ + if (!m_deferredConfigureScheduled) { + QMetaObject::invokeMethod(this, "configure", Qt::QueuedConnection); + m_deferredConfigureScheduled = true; + } +} + // Enable IP Filtering void Session::enableIPFilter(const QString &filterPath, bool force) { @@ -2175,51 +2774,55 @@ CacheStatus Session::cacheStatus() const } // Set Proxy -void Session::setProxySettings(libt::proxy_settings proxySettings) +void Session::configureProxy() { - qDebug() << Q_FUNC_INFO; + auto proxyManager = Net::ProxyConfigurationManager::instance(); + Net::ProxyConfiguration config = proxyManager->proxyConfiguration(); + if (!m_useProxy && (config.type == Net::ProxyType::None)) return; - proxySettings.proxy_peer_connections = Preferences::instance()->proxyPeerConnections(); - m_nativeSession->set_proxy(proxySettings); + libt::proxy_settings proxySettings; - // Define environment variables for urllib in search engine plugins - if (Preferences::instance()->isProxyOnlyForTorrents()) { - qputenv("http_proxy", QByteArray()); - qputenv("https_proxy", QByteArray()); - qputenv("sock_proxy", QByteArray()); - } - else { - QString proxy_str; - switch(proxySettings.type) { - case libt::proxy_settings::http_pw: - proxy_str = QString("http://%1:%2@%3:%4").arg(Utils::String::fromStdString(proxySettings.username)).arg(Utils::String::fromStdString(proxySettings.password)) - .arg(Utils::String::fromStdString(proxySettings.hostname)).arg(proxySettings.port); - break; - case libt::proxy_settings::http: - proxy_str = QString("http://%1:%2").arg(Utils::String::fromStdString(proxySettings.hostname)).arg(proxySettings.port); - break; - case libt::proxy_settings::socks5: - proxy_str = QString("%1:%2").arg(Utils::String::fromStdString(proxySettings.hostname)).arg(proxySettings.port); - break; - case libt::proxy_settings::socks5_pw: - proxy_str = QString("%1:%2@%3:%4").arg(Utils::String::fromStdString(proxySettings.username)).arg(Utils::String::fromStdString(proxySettings.password)) - .arg(Utils::String::fromStdString(proxySettings.hostname)).arg(proxySettings.port); - break; - default: - qDebug("Disabling HTTP communications proxy"); - qputenv("http_proxy", QByteArray()); - qputenv("https_proxy", QByteArray()); - qputenv("sock_proxy", QByteArray()); - return; - } - qDebug("HTTP communications proxy string: %s", qPrintable(proxy_str)); - if ((proxySettings.type == libt::proxy_settings::socks5) || (proxySettings.type == libt::proxy_settings::socks5_pw)) - qputenv("sock_proxy", proxy_str.toLocal8Bit()); - else { - qputenv("http_proxy", proxy_str.toLocal8Bit()); - qputenv("https_proxy", proxy_str.toLocal8Bit()); + if (config.type != Net::ProxyType::None) { + qDebug("Enabling P2P proxy"); + proxySettings.hostname = Utils::String::toStdString(config.ip); + qDebug("hostname is %s", proxySettings.hostname.c_str()); + proxySettings.port = config.port; + qDebug("port is %d", proxySettings.port); + if (proxyManager->isAuthenticationRequired()) { + proxySettings.username = Utils::String::toStdString(config.username); + proxySettings.password = Utils::String::toStdString(config.password); + qDebug("username is %s", proxySettings.username.c_str()); + qDebug("password is %s", proxySettings.password.c_str()); } + proxySettings.proxy_peer_connections = isProxyPeerConnectionsEnabled(); + } + + switch (config.type) { + case Net::ProxyType::HTTP: + qDebug("type: http"); + proxySettings.type = libt::proxy_settings::http; + break; + case Net::ProxyType::HTTP_PW: + qDebug("type: http_pw"); + proxySettings.type = libt::proxy_settings::http_pw; + break; + case Net::ProxyType::SOCKS4: + proxySettings.type = libt::proxy_settings::socks4; + break; + case Net::ProxyType::SOCKS5: + qDebug("type: socks5"); + proxySettings.type = libt::proxy_settings::socks5; + break; + case Net::ProxyType::SOCKS5_PW: + qDebug("type: socks5_pw"); + proxySettings.type = libt::proxy_settings::socks5_pw; + break; + default: + proxySettings.type = libt::proxy_settings::none; } + + m_nativeSession->set_proxy(proxySettings); + m_useProxy = (config.type != Net::ProxyType::None); } // Will resume torrents in backup directory @@ -2306,13 +2909,13 @@ void Session::refresh() void Session::handleIPFilterParsed(int ruleCount) { Logger::instance()->addMessage(tr("Successfully parsed the provided IP filter: %1 rules were applied.", "%1 is a number").arg(ruleCount)); - emit ipFilterParsed(false, ruleCount); + emit IPFilterParsed(false, ruleCount); } void Session::handleIPFilterError() { Logger::instance()->addMessage(tr("Error: Failed to parse the provided IP filter."), Log::CRITICAL); - emit ipFilterParsed(true, 0); + emit IPFilterParsed(true, 0); } #if LIBTORRENT_VERSION_NUM < 10100 @@ -2453,7 +3056,6 @@ void Session::createTorrentHandle(const libt::torrent_handle &nativeHandle) TorrentHandle *const torrent = new TorrentHandle(this, nativeHandle, data); m_torrents.insert(torrent->hash(), torrent); - Preferences *const pref = Preferences::instance(); Logger *const logger = Logger::instance(); bool fromMagnetUri = !torrent->hasMetadata(); @@ -2475,7 +3077,7 @@ void Session::createTorrentHandle(const libt::torrent_handle &nativeHandle) const QString newFile = resumeDataDir.absoluteFilePath(QString("%1.torrent").arg(torrent->hash())); if (torrent->saveTorrentFile(newFile)) { // Copy the torrent file to the export folder - if (m_torrentExportEnabled) + if (!torrentExportDirectory().isEmpty()) exportTorrentFile(torrent); } else { @@ -2483,8 +3085,8 @@ void Session::createTorrentHandle(const libt::torrent_handle &nativeHandle) } } - if (pref->isAddTrackersEnabled() && !torrent->isPrivate()) - torrent->addTrackers(m_additionalTrackers); + if (isAddTrackersEnabled() && !torrent->isPrivate()) + torrent->addTrackers(m_additionalTrackerList); bool addPaused = data.addPaused; if (data.addPaused == TriStateBool::Undefined) diff --git a/src/base/bittorrent/session.h b/src/base/bittorrent/session.h index 38cf8b98e..073d5958b 100644 --- a/src/base/bittorrent/session.h +++ b/src/base/bittorrent/session.h @@ -30,17 +30,22 @@ #ifndef BITTORRENT_SESSION_H #define BITTORRENT_SESSION_H +#include +#include + #include #include #include +#if LIBTORRENT_VERSION_NUM < 10100 +#include +#endif +#include #include +#include #include -#include #include -#include - -#include +#include "base/settingvalue.h" #include "base/tristatebool.h" #include "base/types.h" #include "torrentinfo.h" @@ -55,17 +60,6 @@ namespace libtorrent struct session_settings; struct session_status; -#if LIBTORRENT_VERSION_NUM < 10100 - struct proxy_settings; -#else - namespace aux - { - struct proxy_settings; - } - - typedef aux::proxy_settings proxy_settings; -#endif - class alert; struct torrent_alert; struct state_update_alert; @@ -111,7 +105,6 @@ class FilterParserThread; class BandwidthScheduler; class Statistics; class ResumeDataSavingManager; -class SettingsStorage; enum MaxRatioAction { @@ -172,13 +165,6 @@ namespace BitTorrent static void freeInstance(); static Session *instance(); - bool isDHTEnabled() const; - bool isLSDEnabled() const; - bool isPexEnabled() const; - bool isQueueingEnabled() const; - qreal globalMaxRatio() const; - bool isAppendExtensionEnabled() const; - QString defaultSavePath() const; void setDefaultSavePath(QString path); QString tempPath() const; @@ -219,8 +205,122 @@ namespace BitTorrent bool isDisableAutoTMMWhenCategorySavePathChanged() const; void setDisableAutoTMMWhenCategorySavePathChanged(bool value); + qreal globalMaxRatio() const; + void setGlobalMaxRatio(qreal ratio); + bool isDHTEnabled() const; + void setDHTEnabled(bool enabled); + bool isLSDEnabled() const; + void setLSDEnabled(bool enabled); + bool isPeXEnabled() const; + void setPeXEnabled(bool enabled); + bool isTrackerExchangeEnabled() const; + void setTrackerExchangeEnabled(bool enabled); bool isAddTorrentPaused() const; void setAddTorrentPaused(bool value); + bool isTrackerEnabled() const; + void setTrackerEnabled(bool enabled); + bool isAppendExtensionEnabled() const; + void setAppendExtensionEnabled(bool enabled); + uint refreshInterval() const; + void setRefreshInterval(uint value); + bool isPreallocationEnabled() const; + void setPreallocationEnabled(bool enabled); + QString torrentExportDirectory() const; + void setTorrentExportDirectory(const QString &path); + QString finishedTorrentExportDirectory() const; + void setFinishedTorrentExportDirectory(const QString &path); + + int globalDownloadSpeedLimit() const; + void setGlobalDownloadSpeedLimit(int limit); + int globalUploadSpeedLimit() const; + void setGlobalUploadSpeedLimit(int limit); + int altGlobalDownloadSpeedLimit() const; + void setAltGlobalDownloadSpeedLimit(int limit); + int altGlobalUploadSpeedLimit() const; + void setAltGlobalUploadSpeedLimit(int limit); + int downloadSpeedLimit() const; + void setDownloadSpeedLimit(int limit); + int uploadSpeedLimit() const; + void setUploadSpeedLimit(int limit); + bool isAltGlobalSpeedLimitEnabled() const; + void setAltGlobalSpeedLimitEnabled(bool enabled); + bool isBandwidthSchedulerEnabled() const; + void setBandwidthSchedulerEnabled(bool enabled); + + uint saveResumeDataInterval() const; + void setSaveResumeDataInterval(uint value); + int port() const; + void setPort(int port); + bool useRandomPort() const; + void setUseRandomPort(bool value); + QString networkInterface() const; + void setNetworkInterface(const QString &interface); + QString networkInterfaceAddress() const; + void setNetworkInterfaceAddress(const QString &address); + bool isIPv6Enabled() const; + void setIPv6Enabled(bool enabled); + int encryption() const; + void setEncryption(int state); + bool isForceProxyEnabled() const; + void setForceProxyEnabled(bool enabled); + bool isProxyPeerConnectionsEnabled() const; + void setProxyPeerConnectionsEnabled(bool enabled); + bool isAddTrackersEnabled() const; + void setAddTrackersEnabled(bool enabled); + QString additionalTrackers() const; + void setAdditionalTrackers(const QString &trackers); + bool isFilteringEnabled() const; + void setFilteringEnabled(bool enabled); + QString IPFilterFile() const; + void setIPFilterFile(QString path); + bool announceToAllTrackers() const; + void setAnnounceToAllTrackers(bool val); + uint diskCacheSize() const; + void setDiskCacheSize(uint size); + uint diskCacheTTL() const; + void setDiskCacheTTL(uint ttl); + bool useOSCache() const; + void setUseOSCache(bool use); + bool isAnonymousModeEnabled() const; + void setAnonymousModeEnabled(bool enabled); + bool isQueueingSystemEnabled() const; + void setQueueingSystemEnabled(bool enabled); + bool ignoreSlowTorrentsForQueueing() const; + void setIgnoreSlowTorrentsForQueueing(bool ignore); + uint outgoingPortsMin() const; + void setOutgoingPortsMin(uint min); + uint outgoingPortsMax() const; + void setOutgoingPortsMax(uint max); + bool ignoreLimitsOnLAN() const; + void setIgnoreLimitsOnLAN(bool ignore); + bool includeOverheadInLimits() const; + void setIncludeOverheadInLimits(bool include); + QString networkAddress() const; + void setNetworkAddress(const QString &addr); + bool isSuperSeedingEnabled() const; + void setSuperSeedingEnabled(bool enabled); + int maxConnections() const; + void setMaxConnections(int max); + int maxHalfOpenConnections() const; + void setMaxHalfOpenConnections(int max); + int maxConnectionsPerTorrent() const; + void setMaxConnectionsPerTorrent(int max); + int maxUploads() const; + void setMaxUploads(int max); + int maxUploadsPerTorrent() const; + void setMaxUploadsPerTorrent(int max); + int maxActiveDownloads() const; + void setMaxActiveDownloads(int max); + int maxActiveUploads() const; + void setMaxActiveUploads(int max); + int maxActiveTorrents() const; + void setMaxActiveTorrents(int max); + bool isUTPEnabled() const; + void setUTPEnabled(bool enabled); + bool isUTPRateLimited() const; + void setUTPRateLimited(bool limited); + bool isTrackerFilteringEnabled() const; + void setTrackerFilteringEnabled(bool enabled); TorrentHandle *findTorrent(const InfoHash &hash) const; QHash torrents() const; @@ -231,17 +331,11 @@ namespace BitTorrent CacheStatus cacheStatus() const; quint64 getAlltimeDL() const; quint64 getAlltimeUL() const; - int downloadRateLimit() const; - int uploadRateLimit() const; bool isListening() const; MaxRatioAction maxRatioAction() const; void setMaxRatioAction(MaxRatioAction act); - void changeSpeedLimitMode(bool alternative); - void setDownloadRateLimit(int rate); - void setUploadRateLimit(int rate); - void setGlobalMaxRatio(qreal ratio); void enableIPFilter(const QString &filterPath, bool force = false); void disableIPFilter(); void banIP(const QString &ip); @@ -304,7 +398,7 @@ namespace BitTorrent void trackerAuthenticationRequired(BitTorrent::TorrentHandle *const torrent); void recursiveTorrentDownloadPossible(BitTorrent::TorrentHandle *const torrent); void speedLimitModeChanged(bool alternative); - void ipFilterParsed(bool error, int ruleCount); + void IPFilterParsed(bool error, int ruleCount); void trackersAdded(BitTorrent::TorrentHandle *const torrent, const QList &trackers); void trackersRemoved(BitTorrent::TorrentHandle *const torrent, const QList &trackers); void trackersChanged(BitTorrent::TorrentHandle *const torrent); @@ -316,7 +410,7 @@ namespace BitTorrent void subcategoriesSupportChanged(); private slots: - void configure(); + void configureDeferred(); void readAlerts(); void refresh(); void processBigRatios(); @@ -341,20 +435,19 @@ namespace BitTorrent void initResumeFolder(); // Session configuration - void setSessionSettings(); - void setProxySettings(libtorrent::proxy_settings proxySettings); + Q_INVOKABLE void configure(); void adjustLimits(); void adjustLimits(libtorrent::session_settings &sessionSettings); const QStringList getListeningIPs(); - void setListeningPort(); - void preAllocateAllFiles(bool b); - void setMaxConnectionsPerTorrent(int max); - void setMaxUploadsPerTorrent(int max); + void configureListeningInterface(); void enableLSD(bool enable); void enableDHT(bool enable); void changeSpeedLimitMode_impl(bool alternative); - - void setAppendExtension(bool append); + void enableTracker(bool enable); + void enableBandwidthScheduler(); + void populateAdditionalTrackers(); + void configureEncryption(); + void configureProxy(); void startUpTorrents(); bool addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri, @@ -393,31 +486,85 @@ namespace BitTorrent #endif void getPendingAlerts(std::vector &out, ulong time = 0); - SettingsStorage *m_settings; - // BitTorrent libtorrent::session *m_nativeSession; - bool m_LSDEnabled; - bool m_DHTEnabled; - bool m_PeXEnabled; - bool m_queueingEnabled; - bool m_torrentExportEnabled; - bool m_finishedTorrentExportEnabled; - bool m_preAllocateAll; - qreal m_globalMaxRatio; + bool m_deferredConfigureScheduled; + CachedSettingValue m_isDHTEnabled; + CachedSettingValue m_isLSDEnabled; + CachedSettingValue m_isPeXEnabled; + CachedSettingValue m_isTrackerExchangeEnabled; + CachedSettingValue m_isFilteringEnabled; + CachedSettingValue m_isTrackerFilteringEnabled; + CachedSettingValue m_IPFilterFile; + CachedSettingValue m_announceToAllTrackers; + CachedSettingValue m_diskCacheSize; + CachedSettingValue m_diskCacheTTL; + CachedSettingValue m_useOSCache; + CachedSettingValue m_isAnonymousModeEnabled; + CachedSettingValue m_isQueueingEnabled; + CachedSettingValue m_maxActiveDownloads; + CachedSettingValue m_maxActiveUploads; + CachedSettingValue m_maxActiveTorrents; + CachedSettingValue m_ignoreSlowTorrentsForQueueing; + CachedSettingValue m_outgoingPortsMin; + CachedSettingValue m_outgoingPortsMax; + CachedSettingValue m_ignoreLimitsOnLAN; + CachedSettingValue m_includeOverheadInLimits; + CachedSettingValue m_networkAddress; + CachedSettingValue m_isSuperSeedingEnabled; + CachedSettingValue m_maxConnections; + CachedSettingValue m_maxHalfOpenConnections; + CachedSettingValue m_maxUploads; + CachedSettingValue m_maxConnectionsPerTorrent; + CachedSettingValue m_maxUploadsPerTorrent; + CachedSettingValue m_isUTPEnabled; + CachedSettingValue m_isUTPRateLimited; + CachedSettingValue m_isAddTrackersEnabled; + CachedSettingValue m_additionalTrackers; + CachedSettingValue m_globalMaxRatio; + CachedSettingValue m_isAddTorrentPaused; + CachedSettingValue m_isAppendExtensionEnabled; + CachedSettingValue m_refreshInterval; + CachedSettingValue m_isPreallocationEnabled; + CachedSettingValue m_torrentExportDirectory; + CachedSettingValue m_finishedTorrentExportDirectory; + CachedSettingValue m_globalDownloadSpeedLimit; + CachedSettingValue m_globalUploadSpeedLimit; + CachedSettingValue m_altGlobalDownloadSpeedLimit; + CachedSettingValue m_altGlobalUploadSpeedLimit; + CachedSettingValue m_isAltGlobalSpeedLimitEnabled; + CachedSettingValue m_isBandwidthSchedulerEnabled; + CachedSettingValue m_saveResumeDataInterval; + CachedSettingValue m_port; + CachedSettingValue m_useRandomPort; + CachedSettingValue m_networkInterface; + CachedSettingValue m_networkInterfaceAddress; + CachedSettingValue m_isIPv6Enabled; + CachedSettingValue m_encryption; + CachedSettingValue m_isForceProxyEnabled; + CachedSettingValue m_isProxyPeerConnectionsEnabled; + CachedSettingValue m_storedCategories; + CachedSettingValue m_maxRatioAction; + CachedSettingValue m_defaultSavePath; + CachedSettingValue m_tempPath; + CachedSettingValue m_isSubcategoriesEnabled; + CachedSettingValue m_isTempPathEnabled; + CachedSettingValue m_isAutoTMMDisabledByDefault; + CachedSettingValue m_isDisableAutoTMMWhenCategoryChanged; + CachedSettingValue m_isDisableAutoTMMWhenDefaultSavePathChanged; + CachedSettingValue m_isDisableAutoTMMWhenCategorySavePathChanged; + CachedSettingValue m_isTrackerEnabled; + CachedSettingValue m_bannedIPs; + int m_numResumeData; int m_extraLimit; - bool m_appendExtension; - uint m_refreshInterval; - MaxRatioAction m_maxRatioAction; - QList m_additionalTrackers; - QString m_defaultSavePath; - QString m_tempPath; + QList m_additionalTrackerList; QString m_filterPath; QString m_resumeFolderPath; QFile m_resumeFolderLock; QHash m_savePathsToRemove; + bool m_useProxy; QTimer *m_refreshTimer; QTimer *m_bigRatioTimer; diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp index fce7c2359..4f20fb437 100644 --- a/src/base/bittorrent/torrenthandle.cpp +++ b/src/base/bittorrent/torrenthandle.cpp @@ -752,7 +752,7 @@ void TorrentHandle::updateState() m_state = isSeed() ? TorrentState::PausedUploading : TorrentState::PausedDownloading; } else { - if (m_session->isQueueingEnabled() && isQueued() && !isChecking()) { + if (m_session->isQueueingSystemEnabled() && isQueued() && !isChecking()) { m_state = isSeed() ? TorrentState::QueuedUploading : TorrentState::QueuedDownloading; } else { diff --git a/src/base/net/downloadmanager.cpp b/src/base/net/downloadmanager.cpp index 28c6b40c4..ef8072ce6 100644 --- a/src/base/net/downloadmanager.cpp +++ b/src/base/net/downloadmanager.cpp @@ -27,20 +27,21 @@ * exception statement from your version. */ +#include "downloadmanager.h" + #include -#include -#include -#include -#include +#include #include #include +#include +#include +#include #include #include -#include #include "base/preferences.h" #include "downloadhandler.h" -#include "downloadmanager.h" +#include "proxyconfigurationmanager.h" // Spoof Firefox 38 user agent to avoid web server banning const char DEFAULT_USER_AGENT[] = "Mozilla/5.0 (X11; Linux i686; rv:38.0) Gecko/20100101 Firefox/38.0"; @@ -208,16 +209,16 @@ bool DownloadManager::deleteCookie(const QNetworkCookie &cookie) void DownloadManager::applyProxySettings() { + auto proxyManager = ProxyConfigurationManager::instance(); + ProxyConfiguration proxyConfig = proxyManager->proxyConfiguration(); QNetworkProxy proxy; - const Preferences* const pref = Preferences::instance(); - if (pref->isProxyEnabled() && !pref->isProxyOnlyForTorrents()) { + if (!proxyManager->isProxyDisabled() && (proxyConfig.type != ProxyType::None)) { // Proxy enabled - proxy.setHostName(pref->getProxyIp()); - proxy.setPort(pref->getProxyPort()); + proxy.setHostName(proxyConfig.ip); + proxy.setPort(proxyConfig.port); // Default proxy type is HTTP, we must change if it is SOCKS5 - const int proxyType = pref->getProxyType(); - if ((proxyType == Proxy::SOCKS5) || (proxyType == Proxy::SOCKS5_PW)) { + if ((proxyConfig.type == ProxyType::SOCKS5) || (proxyConfig.type == ProxyType::SOCKS5_PW)) { qDebug() << Q_FUNC_INFO << "using SOCKS proxy"; proxy.setType(QNetworkProxy::Socks5Proxy); } @@ -226,10 +227,10 @@ void DownloadManager::applyProxySettings() proxy.setType(QNetworkProxy::HttpProxy); } // Authentication? - if (pref->isProxyAuthEnabled()) { + if (proxyManager->isAuthenticationRequired()) { qDebug("Proxy requires authentication, authenticating"); - proxy.setUser(pref->getProxyUsername()); - proxy.setPassword(pref->getProxyPassword()); + proxy.setUser(proxyConfig.username); + proxy.setPassword(proxyConfig.password); } } else { diff --git a/src/base/net/proxyconfigurationmanager.cpp b/src/base/net/proxyconfigurationmanager.cpp new file mode 100644 index 000000000..0dba21fe2 --- /dev/null +++ b/src/base/net/proxyconfigurationmanager.cpp @@ -0,0 +1,160 @@ +/* + * Bittorrent Client using Qt and libtorrent. + * Copyright (C) 2016 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 "proxyconfigurationmanager.h" +#include "base/settingsstorage.h" + +#define SETTINGS_KEY(name) "Network/Proxy/" name +const QString KEY_DISABLED = SETTINGS_KEY("Disabled"); +const QString KEY_TYPE = SETTINGS_KEY("Type"); +const QString KEY_IP = SETTINGS_KEY("IP"); +const QString KEY_PORT = SETTINGS_KEY("Port"); +const QString KEY_AUTHENTICATION = SETTINGS_KEY("Authentication"); +const QString KEY_USERNAME = SETTINGS_KEY("Username"); +const QString KEY_PASSWORD = SETTINGS_KEY("Password"); + +namespace +{ + inline SettingsStorage *settings() { return SettingsStorage::instance(); } + + inline bool isSameConfig(const Net::ProxyConfiguration &conf1, const Net::ProxyConfiguration &conf2) + { + return conf1.type == conf2.type + && conf1.ip == conf2.ip + && conf1.port == conf2.port + && conf1.username == conf2.username + && conf1.password == conf2.password; + } +} + +using namespace Net; + +ProxyConfigurationManager *ProxyConfigurationManager::m_instance = nullptr; + +ProxyConfigurationManager::ProxyConfigurationManager(QObject *parent) + : QObject(parent) +{ + m_proxyDisabled = settings()->loadValue(KEY_DISABLED, false).toBool(); + m_config.type = static_cast( + settings()->loadValue(KEY_TYPE, static_cast(ProxyType::None)).toInt()); + if ((m_config.type < ProxyType::None) || (m_config.type > ProxyType::SOCKS4)) + m_config.type = ProxyType::None; + m_config.ip = settings()->loadValue(KEY_IP, "0.0.0.0").toString(); + m_config.port = static_cast(settings()->loadValue(KEY_PORT, 8080).toUInt()); + m_config.username = settings()->loadValue(KEY_USERNAME).toString(); + m_config.password = settings()->loadValue(KEY_PASSWORD).toString(); +} + +void ProxyConfigurationManager::initInstance() +{ + if (!m_instance) + m_instance = new ProxyConfigurationManager; +} + +void ProxyConfigurationManager::freeInstance() +{ + delete m_instance; +} + +ProxyConfigurationManager *ProxyConfigurationManager::instance() +{ + return m_instance; +} + +ProxyConfiguration ProxyConfigurationManager::proxyConfiguration() const +{ + return m_config; +} + +void ProxyConfigurationManager::setProxyConfiguration(const ProxyConfiguration &config) +{ + if (!isSameConfig(config, m_config)) { + m_config = config; + settings()->storeValue(KEY_TYPE, static_cast(config.type)); + settings()->storeValue(KEY_IP, config.ip); + settings()->storeValue(KEY_PORT, config.port); + settings()->storeValue(KEY_USERNAME, config.username); + settings()->storeValue(KEY_PASSWORD, config.password); + configureProxy(); + + emit proxyConfigurationChanged(); + } +} + +bool ProxyConfigurationManager::isProxyDisabled() const +{ + return m_proxyDisabled; +} + +void ProxyConfigurationManager::setProxyDisabled(bool disabled) +{ + if (m_proxyDisabled != disabled) { + settings()->storeValue(KEY_DISABLED, disabled); + m_proxyDisabled = disabled; + } +} + +bool ProxyConfigurationManager::isAuthenticationRequired() const +{ + return m_config.type == ProxyType::SOCKS5_PW + || m_config.type == ProxyType::HTTP_PW; +} + +void ProxyConfigurationManager::configureProxy() +{ + // Define environment variables for urllib in search engine plugins + QString proxyStrHTTP, proxyStrSOCK; + if (!m_proxyDisabled) { + switch (m_config.type) { + case ProxyType::HTTP_PW: + proxyStrHTTP = QString("http://%1:%2@%3:%4").arg(m_config.username) + .arg(m_config.password).arg(m_config.ip).arg(m_config.port); + break; + case ProxyType::HTTP: + proxyStrHTTP = QString("http://%1:%2").arg(m_config.ip).arg(m_config.port); + break; + case ProxyType::SOCKS5: + proxyStrSOCK = QString("%1:%2").arg(m_config.ip).arg(m_config.port); + break; + case ProxyType::SOCKS5_PW: + proxyStrSOCK = QString("%1:%2@%3:%4").arg(m_config.username) + .arg(m_config.password).arg(m_config.ip).arg(m_config.port); + break; + default: + qDebug("Disabling HTTP communications proxy"); + } + + qDebug("HTTP communications proxy string: %s" + , qPrintable((m_config.type == ProxyType::SOCKS5) || (m_config.type == ProxyType::SOCKS5_PW) + ? proxyStrSOCK : proxyStrHTTP)); + } + + qputenv("http_proxy", proxyStrHTTP.toLocal8Bit()); + qputenv("https_proxy", proxyStrHTTP.toLocal8Bit()); + qputenv("sock_proxy", proxyStrSOCK.toLocal8Bit()); +} diff --git a/src/base/net/proxyconfigurationmanager.h b/src/base/net/proxyconfigurationmanager.h new file mode 100644 index 000000000..ef3c34033 --- /dev/null +++ b/src/base/net/proxyconfigurationmanager.h @@ -0,0 +1,87 @@ +/* + * Bittorrent Client using Qt and libtorrent. + * Copyright (C) 2016 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. + */ + +#ifndef NET_PROXYCONFIGURATIONMANAGER_H +#define NET_PROXYCONFIGURATIONMANAGER_H + +#include + +namespace Net +{ + enum class ProxyType + { + None = 0, + HTTP = 1, + SOCKS5 = 2, + HTTP_PW = 3, + SOCKS5_PW = 4, + SOCKS4 = 5 + }; + + struct ProxyConfiguration + { + ProxyType type = ProxyType::None; + QString ip = "0.0.0.0"; + ushort port = 8080; + QString username; + QString password; + }; + + class ProxyConfigurationManager: public QObject + { + Q_OBJECT + Q_DISABLE_COPY(ProxyConfigurationManager) + + explicit ProxyConfigurationManager(QObject *parent = nullptr); + ~ProxyConfigurationManager() = default; + + public: + static void initInstance(); + static void freeInstance(); + static ProxyConfigurationManager *instance(); + + ProxyConfiguration proxyConfiguration() const; + void setProxyConfiguration(const ProxyConfiguration &config); + bool isProxyDisabled() const; + void setProxyDisabled(bool disabled); + + bool isAuthenticationRequired() const; + + signals: + void proxyConfigurationChanged(); + + private: + void configureProxy(); + + static ProxyConfigurationManager *m_instance; + ProxyConfiguration m_config; + bool m_proxyDisabled; + }; +} + +#endif // NET_PROXYCONFIGURATIONMANAGER_H diff --git a/src/base/preferences.cpp b/src/base/preferences.cpp index 4de87be34..b47295f4a 100644 --- a/src/base/preferences.cpp +++ b/src/base/preferences.cpp @@ -50,8 +50,6 @@ #include #endif -#include - #include "utils/fs.h" #include "utils/misc.h" #include "settingsstorage.h" @@ -60,10 +58,7 @@ Preferences* Preferences::m_instance = 0; -Preferences::Preferences() - : m_randomPort(rand() % 64512 + 1024) -{ -} +Preferences::Preferences() {} Preferences *Preferences::instance() { @@ -165,16 +160,6 @@ void Preferences::setHideZeroComboValues(int n) setValue("Preferences/General/HideZeroComboValues", n); } -bool Preferences::useRandomPort() const -{ - return value("Preferences/General/UseRandomPort", false).toBool(); -} - -void Preferences::setRandomPort(bool b) -{ - setValue("Preferences/General/UseRandomPort", b); -} - bool Preferences::systrayIntegration() const { return value("Preferences/General/SystrayEnabled", true).toBool(); @@ -267,16 +252,6 @@ void Preferences::setWinStartup(bool b) #endif // Downloads -bool Preferences::useIncompleteFilesExtension() const -{ - return value("Preferences/Downloads/UseIncompleteExtension", false).toBool(); -} - -void Preferences::useIncompleteFilesExtension(bool enabled) -{ - setValue("Preferences/Downloads/UseIncompleteExtension", enabled); -} - QString Preferences::lastLocationPath() const { return Utils::Fs::fromNativePath(value("Preferences/Downloads/LastLocationPath").toString()); @@ -287,16 +262,6 @@ void Preferences::setLastLocationPath(const QString &path) setValue("Preferences/Downloads/LastLocationPath", Utils::Fs::fromNativePath(path)); } -bool Preferences::preAllocateAllFiles() const -{ - return value("Preferences/Downloads/PreAllocation", false).toBool(); -} - -void Preferences::preAllocateAllFiles(bool enabled) -{ - return setValue("Preferences/Downloads/PreAllocation", enabled); -} - QVariantHash Preferences::getScanDirs() const { return value("Preferences/Downloads/ScanDirsV2").toHash(); @@ -318,36 +283,6 @@ void Preferences::setScanDirsLastPath(const QString &path) setValue("Preferences/Downloads/ScanDirsLastPath", Utils::Fs::fromNativePath(path)); } -bool Preferences::isTorrentExportEnabled() const -{ - return !value("Preferences/Downloads/TorrentExportDir").toString().isEmpty(); -} - -QString Preferences::getTorrentExportDir() const -{ - return Utils::Fs::fromNativePath(value("Preferences/Downloads/TorrentExportDir").toString()); -} - -void Preferences::setTorrentExportDir(QString path) -{ - setValue("Preferences/Downloads/TorrentExportDir", Utils::Fs::fromNativePath(path.trimmed())); -} - -bool Preferences::isFinishedTorrentExportEnabled() const -{ - return !value("Preferences/Downloads/FinishedTorrentExportDir").toString().isEmpty(); -} - -QString Preferences::getFinishedTorrentExportDir() const -{ - return Utils::Fs::fromNativePath(value("Preferences/Downloads/FinishedTorrentExportDir").toString()); -} - -void Preferences::setFinishedTorrentExportDir(QString path) -{ - setValue("Preferences/Downloads/FinishedTorrentExportDir", Utils::Fs::fromNativePath(path.trimmed())); -} - bool Preferences::isMailNotificationEnabled() const { return value("Preferences/MailNotification/enabled", false).toBool(); @@ -439,18 +374,6 @@ void Preferences::setActionOnDblClOnTorrentFn(int act) } // Connection options -int Preferences::getSessionPort() const -{ - if (useRandomPort()) - return m_randomPort; - return value("Preferences/Connection/PortRangeMin", 8999).toInt(); -} - -void Preferences::setSessionPort(int port) -{ - setValue("Preferences/Connection/PortRangeMin", port); -} - bool Preferences::isUPnPEnabled() const { return value("Preferences/Connection/UPnP", true).toBool(); @@ -461,74 +384,6 @@ void Preferences::setUPnPEnabled(bool enabled) setValue("Preferences/Connection/UPnP", enabled); } -int Preferences::getGlobalDownloadLimit() const -{ - return value("Preferences/Connection/GlobalDLLimit", -1).toInt(); -} - -void Preferences::setGlobalDownloadLimit(int limit) -{ - if (limit <= 0) - limit = -1; - setValue("Preferences/Connection/GlobalDLLimit", limit); -} - -int Preferences::getGlobalUploadLimit() const -{ - return value("Preferences/Connection/GlobalUPLimit", -1).toInt(); -} - -void Preferences::setGlobalUploadLimit(int limit) -{ - if (limit <= 0) - limit = -1; - setValue("Preferences/Connection/GlobalUPLimit", limit); -} - -int Preferences::getAltGlobalDownloadLimit() const -{ - return value("Preferences/Connection/GlobalDLLimitAlt", 10).toInt(); -} - -void Preferences::setAltGlobalDownloadLimit(int limit) -{ - if (limit <= 0) - limit = -1; - setValue("Preferences/Connection/GlobalDLLimitAlt", limit); -} - -int Preferences::getAltGlobalUploadLimit() const -{ - return value("Preferences/Connection/GlobalUPLimitAlt", 10).toInt(); -} - -void Preferences::setAltGlobalUploadLimit(int limit) -{ - if (limit <= 0) - limit = -1; - setValue("Preferences/Connection/GlobalUPLimitAlt", limit); -} - -bool Preferences::isAltBandwidthEnabled() const -{ - return value("Preferences/Connection/alt_speeds_on", false).toBool(); -} - -void Preferences::setAltBandwidthEnabled(bool enabled) -{ - setValue("Preferences/Connection/alt_speeds_on", enabled); -} - -bool Preferences::isSchedulerEnabled() const -{ - return value("Preferences/Scheduler/Enabled", false).toBool(); -} - -void Preferences::setSchedulerEnabled(bool enabled) -{ - setValue("Preferences/Scheduler/Enabled", enabled); -} - QTime Preferences::getSchedulerStartTime() const { return value("Preferences/Scheduler/start_time", QTime(8,0)).toTime(); @@ -559,286 +414,6 @@ void Preferences::setSchedulerDays(scheduler_days days) setValue("Preferences/Scheduler/days", (int)days); } -// Proxy options -bool Preferences::isProxyEnabled() const -{ - return getProxyType() > 0; -} - -bool Preferences::isProxyAuthEnabled() const -{ - return value("Preferences/Connection/Proxy/Authentication", false).toBool(); -} - -void Preferences::setProxyAuthEnabled(bool enabled) -{ - setValue("Preferences/Connection/Proxy/Authentication", enabled); -} - -QString Preferences::getProxyIp() const -{ - return value("Preferences/Connection/Proxy/IP", "0.0.0.0").toString(); -} - -void Preferences::setProxyIp(const QString &ip) -{ - setValue("Preferences/Connection/Proxy/IP", ip); -} - -unsigned short Preferences::getProxyPort() const -{ - return value("Preferences/Connection/Proxy/Port", 8080).toInt(); -} - -void Preferences::setProxyPort(unsigned short port) -{ - setValue("Preferences/Connection/Proxy/Port", port); -} - -QString Preferences::getProxyUsername() const -{ - return value("Preferences/Connection/Proxy/Username").toString(); -} - -void Preferences::setProxyUsername(const QString &username) -{ - setValue("Preferences/Connection/Proxy/Username", username); -} - -QString Preferences::getProxyPassword() const -{ - return value("Preferences/Connection/Proxy/Password").toString(); -} - -void Preferences::setProxyPassword(const QString &password) -{ - setValue("Preferences/Connection/Proxy/Password", password); -} - -int Preferences::getProxyType() const -{ - return value("Preferences/Connection/ProxyType", 0).toInt(); -} - -void Preferences::setProxyType(int type) -{ - setValue("Preferences/Connection/ProxyType", type); -} - -bool Preferences::proxyPeerConnections() const -{ - return value("Preferences/Connection/ProxyPeerConnections", false).toBool(); -} - -void Preferences::setProxyPeerConnections(bool enabled) -{ - setValue("Preferences/Connection/ProxyPeerConnections", enabled); -} - -bool Preferences::getForceProxy() const -{ - return value("Preferences/Connection/ProxyForce", true).toBool(); -} - -void Preferences::setForceProxy(bool enabled) -{ - setValue("Preferences/Connection/ProxyForce", enabled); -} - -void Preferences::setProxyOnlyForTorrents(bool enabled) -{ - setValue("Preferences/Connection/ProxyOnlyForTorrents", enabled); -} - -bool Preferences::isProxyOnlyForTorrents() const -{ - return value("Preferences/Connection/ProxyOnlyForTorrents", false).toBool(); -} - -// Bittorrent options -int Preferences::getMaxConnecs() const -{ - return value("Preferences/Bittorrent/MaxConnecs", 500).toInt(); -} - -void Preferences::setMaxConnecs(int val) -{ - if (val <= 0) - val = -1; - setValue("Preferences/Bittorrent/MaxConnecs", val); -} - -int Preferences::getMaxConnecsPerTorrent() const -{ - return value("Preferences/Bittorrent/MaxConnecsPerTorrent", 100).toInt(); -} - -void Preferences::setMaxConnecsPerTorrent(int val) -{ - if (val <= 0) - val = -1; - setValue("Preferences/Bittorrent/MaxConnecsPerTorrent", val); -} - -int Preferences::getMaxUploads() const -{ - return value("Preferences/Bittorrent/MaxUploads", -1).toInt(); -} - -void Preferences::setMaxUploads(int val) -{ - if (val <= 0) - val = -1; - setValue("Preferences/Bittorrent/MaxUploads", val); -} - -int Preferences::getMaxUploadsPerTorrent() const -{ - return value("Preferences/Bittorrent/MaxUploadsPerTorrent", -1).toInt(); -} - -void Preferences::setMaxUploadsPerTorrent(int val) -{ - if (val <= 0) - val = -1; - setValue("Preferences/Bittorrent/MaxUploadsPerTorrent", val); -} - -bool Preferences::isuTPEnabled() const -{ - return value("Preferences/Bittorrent/uTP", true).toBool(); -} - -void Preferences::setuTPEnabled(bool enabled) -{ - setValue("Preferences/Bittorrent/uTP", enabled); -} - -bool Preferences::isuTPRateLimited() const -{ - return value("Preferences/Bittorrent/uTP_rate_limited", true).toBool(); -} - -void Preferences::setuTPRateLimited(bool enabled) -{ - setValue("Preferences/Bittorrent/uTP_rate_limited", enabled); -} - -bool Preferences::isDHTEnabled() const -{ - return value("Preferences/Bittorrent/DHT", true).toBool(); -} - -void Preferences::setDHTEnabled(bool enabled) -{ - setValue("Preferences/Bittorrent/DHT", enabled); -} - -bool Preferences::isPeXEnabled() const -{ - return value("Preferences/Bittorrent/PeX", true).toBool(); -} - -void Preferences::setPeXEnabled(bool enabled) -{ - setValue("Preferences/Bittorrent/PeX", enabled); -} - -bool Preferences::isLSDEnabled() const -{ - return value("Preferences/Bittorrent/LSD", true).toBool(); -} - -void Preferences::setLSDEnabled(bool enabled) -{ - setValue("Preferences/Bittorrent/LSD", enabled); -} - -int Preferences::getEncryptionSetting() const -{ - return value("Preferences/Bittorrent/Encryption", 0).toInt(); -} - -void Preferences::setEncryptionSetting(int val) -{ - setValue("Preferences/Bittorrent/Encryption", val); -} - -bool Preferences::isAddTrackersEnabled() const -{ - return value("Preferences/Bittorrent/AddTrackers", false).toBool(); -} - -void Preferences::setAddTrackersEnabled(bool enabled) -{ - setValue("Preferences/Bittorrent/AddTrackers", enabled); -} - -QString Preferences::getTrackersList() const -{ - return value("Preferences/Bittorrent/TrackersList").toString(); -} - -void Preferences::setTrackersList(const QString &val) -{ - setValue("Preferences/Bittorrent/TrackersList", val); -} - -qreal Preferences::getGlobalMaxRatio() const -{ - return value("Preferences/Bittorrent/MaxRatio", -1).toReal(); -} - -void Preferences::setGlobalMaxRatio(qreal ratio) -{ - setValue("Preferences/Bittorrent/MaxRatio", ratio); -} - -// IP Filter -bool Preferences::isFilteringEnabled() const -{ - return value("Preferences/IPFilter/Enabled", false).toBool(); -} - -void Preferences::setFilteringEnabled(bool enabled) -{ - setValue("Preferences/IPFilter/Enabled", enabled); -} - -bool Preferences::isFilteringTrackerEnabled() const -{ - return value("Preferences/IPFilter/FilterTracker", false).toBool(); -} - -void Preferences::setFilteringTrackerEnabled(bool enabled) -{ - setValue("Preferences/IPFilter/FilterTracker", enabled); -} - -QString Preferences::getFilter() const -{ - return Utils::Fs::fromNativePath(value("Preferences/IPFilter/File").toString()); -} - -void Preferences::setFilter(const QString &path) -{ - setValue("Preferences/IPFilter/File", Utils::Fs::fromNativePath(path)); -} - -QStringList Preferences::bannedIPs() const -{ - return value("Preferences/IPFilter/BannedIPs").toStringList(); -} - -void Preferences::banIP(const QString &ip) -{ - QStringList banned_ips = value("Preferences/IPFilter/BannedIPs").toStringList(); - if (!banned_ips.contains(ip)) { - banned_ips << ip; - setValue("Preferences/IPFilter/BannedIPs", banned_ips); - } -} - // Search bool Preferences::isSearchEnabled() const { @@ -850,63 +425,6 @@ void Preferences::setSearchEnabled(bool enabled) setValue("Preferences/Search/SearchEnabled", enabled); } -// Queueing system -bool Preferences::isQueueingSystemEnabled() const -{ - return value("Preferences/Queueing/QueueingEnabled", true).toBool(); -} - -void Preferences::setQueueingSystemEnabled(bool enabled) -{ - setValue("Preferences/Queueing/QueueingEnabled", enabled); -} - -int Preferences::getMaxActiveDownloads() const -{ - return value("Preferences/Queueing/MaxActiveDownloads", 3).toInt(); -} - -void Preferences::setMaxActiveDownloads(int val) -{ - if (val < 0) - val = -1; - setValue("Preferences/Queueing/MaxActiveDownloads", val); -} - -int Preferences::getMaxActiveUploads() const -{ - return value("Preferences/Queueing/MaxActiveUploads", 3).toInt(); -} - -void Preferences::setMaxActiveUploads(int val) -{ - if (val < 0) - val = -1; - setValue("Preferences/Queueing/MaxActiveUploads", val); -} - -int Preferences::getMaxActiveTorrents() const -{ - return value("Preferences/Queueing/MaxActiveTorrents", 5).toInt(); -} - -void Preferences::setMaxActiveTorrents(int val) -{ - if (val < 0) - val = -1; - setValue("Preferences/Queueing/MaxActiveTorrents", val); -} - -bool Preferences::ignoreSlowTorrentsForQueueing() const -{ - return value("Preferences/Queueing/IgnoreSlowTorrents", false).toBool(); -} - -void Preferences::setIgnoreSlowTorrentsForQueueing(bool ignore) -{ - setValue("Preferences/Queueing/IgnoreSlowTorrents", ignore); -} - bool Preferences::isWebUiEnabled() const { #ifdef DISABLE_GUI @@ -1164,111 +682,6 @@ void Preferences::setDontConfirmAutoExit(bool dontConfirmAutoExit) setValue("ShutdownConfirmDlg/DontConfirmAutoExit", dontConfirmAutoExit); } -uint Preferences::diskCacheSize() const -{ - uint size = value("Preferences/Downloads/DiskWriteCacheSize", 0).toUInt(); - // These macros may not be available on compilers other than MSVC and GCC -#if defined(__x86_64__) || defined(_M_X64) - size = qMin(size, (uint) 4096); // 4GiB -#else - // When build as 32bit binary, set the maximum at less than 2GB to prevent crashes - // allocate 1536MiB and leave 512MiB to the rest of program data in RAM - size = qMin(size, (uint) 1536); -#endif - return size; -} - -void Preferences::setDiskCacheSize(uint size) -{ -#if defined(__x86_64__) || defined(_M_X64) - size = qMin(size, (uint) 4096); // 4GiB -#else - // allocate 1536MiB and leave 512MiB to the rest of program data in RAM - size = qMin(size, (uint) 1536); -#endif - setValue("Preferences/Downloads/DiskWriteCacheSize", size); -} - -uint Preferences::diskCacheTTL() const -{ - return value("Preferences/Downloads/DiskWriteCacheTTL", 60).toUInt(); -} - -void Preferences::setDiskCacheTTL(uint ttl) -{ - setValue("Preferences/Downloads/DiskWriteCacheTTL", ttl); -} - -bool Preferences::osCache() const -{ - return value("Preferences/Advanced/osCache", true).toBool(); -} - -void Preferences::setOsCache(bool enable) -{ - setValue("Preferences/Advanced/osCache", enable); -} - -uint Preferences::saveResumeDataInterval() const -{ - return value("Preferences/Downloads/SaveResumeDataInterval", 3).toUInt(); -} - -void Preferences::setSaveResumeDataInterval(uint m) -{ - setValue("Preferences/Downloads/SaveResumeDataInterval", m); -} - -uint Preferences::outgoingPortsMin() const -{ - return value("Preferences/Advanced/OutgoingPortsMin", 0).toUInt(); -} - -void Preferences::setOutgoingPortsMin(uint val) -{ - setValue("Preferences/Advanced/OutgoingPortsMin", val); -} - -uint Preferences::outgoingPortsMax() const -{ - return value("Preferences/Advanced/OutgoingPortsMax", 0).toUInt(); -} - -void Preferences::setOutgoingPortsMax(uint val) -{ - setValue("Preferences/Advanced/OutgoingPortsMax", val); -} - -bool Preferences::getIgnoreLimitsOnLAN() const -{ - return value("Preferences/Advanced/IgnoreLimitsLAN", true).toBool(); -} - -void Preferences::setIgnoreLimitsOnLAN(bool ignore) -{ - setValue("Preferences/Advanced/IgnoreLimitsLAN", ignore); -} - -bool Preferences::includeOverheadInLimits() const -{ - return value("Preferences/Advanced/IncludeOverhead", false).toBool(); -} - -void Preferences::includeOverheadInLimits(bool include) -{ - setValue("Preferences/Advanced/IncludeOverhead", include); -} - -bool Preferences::trackerExchangeEnabled() const -{ - return value("Preferences/Advanced/LtTrackerExchange", false).toBool(); -} - -void Preferences::setTrackerExchangeEnabled(bool enable) -{ - setValue("Preferences/Advanced/LtTrackerExchange", enable); -} - bool Preferences::recheckTorrentsOnCompletion() const { return value("Preferences/Advanced/RecheckOnCompletion", false).toBool(); @@ -1279,16 +692,6 @@ void Preferences::recheckTorrentsOnCompletion(bool recheck) setValue("Preferences/Advanced/RecheckOnCompletion", recheck); } -unsigned int Preferences::getRefreshInterval() const -{ - return value("Preferences/General/RefreshInterval", 1500).toUInt(); -} - -void Preferences::setRefreshInterval(uint interval) -{ - setValue("Preferences/General/RefreshInterval", interval); -} - bool Preferences::resolvePeerCountries() const { return value("Preferences/Connection/ResolvePeerCountries", true).toBool(); @@ -1309,31 +712,6 @@ void Preferences::resolvePeerHostNames(bool resolve) setValue("Preferences/Connection/ResolvePeerHostNames", resolve); } -int Preferences::getMaxHalfOpenConnections() const -{ - const int val = value("Preferences/Connection/MaxHalfOpenConnec", 20).toInt(); - if (val <= 0) - return -1; - return val; -} - -void Preferences::setMaxHalfOpenConnections(int value) -{ - if (value <= 0) - value = -1; - setValue("Preferences/Connection/MaxHalfOpenConnec", value); -} - -QString Preferences::getNetworkInterface() const -{ - return value("Preferences/Connection/Interface").toString(); -} - -void Preferences::setNetworkInterface(const QString& iface) -{ - setValue("Preferences/Connection/Interface", iface); -} - QString Preferences::getNetworkInterfaceName() const { return value("Preferences/Connection/InterfaceName").toString(); @@ -1354,56 +732,6 @@ QString Preferences::getNetworkInterfaceAddress() const return value("Preferences/Connection/InterfaceAddress").toString(); } -bool Preferences::getListenIPv6() const -{ - return value("Preferences/Connection/InterfaceListenIPv6", false).toBool(); -} - -void Preferences::setListenIPv6(bool enable) -{ - setValue("Preferences/Connection/InterfaceListenIPv6", enable); -} - -QString Preferences::getNetworkAddress() const -{ - return value("Preferences/Connection/InetAddress").toString(); -} - -void Preferences::setNetworkAddress(const QString& addr) -{ - setValue("Preferences/Connection/InetAddress", addr); -} - -bool Preferences::isAnonymousModeEnabled() const -{ - return value("Preferences/Advanced/AnonymousMode", false).toBool(); -} - -void Preferences::enableAnonymousMode(bool enabled) -{ - setValue("Preferences/Advanced/AnonymousMode", enabled); -} - -bool Preferences::isSuperSeedingEnabled() const -{ - return value("Preferences/Advanced/SuperSeeding", false).toBool(); -} - -void Preferences::enableSuperSeeding(bool enabled) -{ - setValue("Preferences/Advanced/SuperSeeding", enabled); -} - -bool Preferences::announceToAllTrackers() const -{ - return value("Preferences/Advanced/AnnounceToAllTrackers", true).toBool(); -} - -void Preferences::setAnnounceToAllTrackers(bool enabled) -{ - setValue("Preferences/Advanced/AnnounceToAllTrackers", enabled); -} - #if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC)) bool Preferences::useSystemIconTheme() const { @@ -1710,16 +1038,6 @@ void Preferences::setMagnetLinkAssoc() } #endif -bool Preferences::isTrackerEnabled() const -{ - return value("Preferences/Advanced/trackerEnabled", false).toBool(); -} - -void Preferences::setTrackerEnabled(bool enabled) -{ - setValue("Preferences/Advanced/trackerEnabled", enabled); -} - int Preferences::getTrackerPort() const { return value("Preferences/Advanced/trackerPort", 9000).toInt(); diff --git a/src/base/preferences.h b/src/base/preferences.h index cc5948b43..83d56209f 100644 --- a/src/base/preferences.h +++ b/src/base/preferences.h @@ -57,18 +57,6 @@ enum scheduler_days SUN }; -namespace Proxy -{ - enum ProxyType - { - HTTP = 1, - SOCKS5 = 2, - HTTP_PW = 3, - SOCKS5_PW = 4, - SOCKS4 = 5 - }; -} - namespace TrayIcon { enum Style @@ -102,7 +90,6 @@ class Preferences: public QObject void setValue(const QString &key, const QVariant &value); static Preferences* m_instance; - int m_randomPort; signals: void changed(); @@ -127,8 +114,6 @@ public: void setHideZeroValues(bool b); int getHideZeroComboValues() const; void setHideZeroComboValues(int n); - bool useRandomPort() const; - void setRandomPort(bool b); bool systrayIntegration() const; void setSystrayIntegration(bool enabled); bool isToolbarDisplayed() const; @@ -149,22 +134,12 @@ public: #endif // Downloads - bool useIncompleteFilesExtension() const; - void useIncompleteFilesExtension(bool enabled); QString lastLocationPath() const; void setLastLocationPath(const QString &path); - bool preAllocateAllFiles() const; - void preAllocateAllFiles(bool enabled); QVariantHash getScanDirs() const; void setScanDirs(const QVariantHash &dirs); QString getScanDirsLastPath() const; void setScanDirsLastPath(const QString &path); - bool isTorrentExportEnabled() const; - QString getTorrentExportDir() const; - void setTorrentExportDir(QString path); - bool isFinishedTorrentExportEnabled() const; - QString getFinishedTorrentExportDir() const; - void setFinishedTorrentExportDir(QString path); bool isMailNotificationEnabled() const; void setMailNotificationEnabled(bool enabled); QString getMailNotificationEmail() const; @@ -185,22 +160,8 @@ public: void setActionOnDblClOnTorrentFn(int act); // Connection options - int getSessionPort() const; - void setSessionPort(int port); bool isUPnPEnabled() const; void setUPnPEnabled(bool enabled); - int getGlobalDownloadLimit() const; - void setGlobalDownloadLimit(int limit); - int getGlobalUploadLimit() const; - void setGlobalUploadLimit(int limit); - int getAltGlobalDownloadLimit() const; - void setAltGlobalDownloadLimit(int limit); - int getAltGlobalUploadLimit() const; - void setAltGlobalUploadLimit(int limit); - bool isAltBandwidthEnabled() const; - void setAltBandwidthEnabled(bool enabled); - bool isSchedulerEnabled() const; - void setSchedulerEnabled(bool enabled); QTime getSchedulerStartTime() const; void setSchedulerStartTime(const QTime &time); QTime getSchedulerEndTime() const; @@ -208,80 +169,10 @@ public: scheduler_days getSchedulerDays() const; void setSchedulerDays(scheduler_days days); - // Proxy options - bool isProxyEnabled() const; - bool isProxyAuthEnabled() const; - void setProxyAuthEnabled(bool enabled); - QString getProxyIp() const; - void setProxyIp(const QString &ip); - unsigned short getProxyPort() const; - void setProxyPort(unsigned short port); - QString getProxyUsername() const; - void setProxyUsername(const QString &username); - QString getProxyPassword() const; - void setProxyPassword(const QString &password); - int getProxyType() const; - void setProxyType(int type); - bool proxyPeerConnections() const; - void setProxyPeerConnections(bool enabled); - bool getForceProxy() const; - void setForceProxy(bool enabled); - void setProxyOnlyForTorrents(bool enabled); - bool isProxyOnlyForTorrents() const; - - // Bittorrent options - int getMaxConnecs() const; - void setMaxConnecs(int val); - int getMaxConnecsPerTorrent() const; - void setMaxConnecsPerTorrent(int val); - int getMaxUploads() const; - void setMaxUploads(int val); - int getMaxUploadsPerTorrent() const; - void setMaxUploadsPerTorrent(int val); - bool isuTPEnabled() const; - void setuTPEnabled(bool enabled); - bool isuTPRateLimited() const; - void setuTPRateLimited(bool enabled); - bool isDHTEnabled() const; - void setDHTEnabled(bool enabled); - bool isPeXEnabled() const; - void setPeXEnabled(bool enabled); - bool isLSDEnabled() const; - void setLSDEnabled(bool enabled); - int getEncryptionSetting() const; - void setEncryptionSetting(int val); - bool isAddTrackersEnabled() const; - void setAddTrackersEnabled(bool enabled); - QString getTrackersList() const; - void setTrackersList(const QString &val); - qreal getGlobalMaxRatio() const; - void setGlobalMaxRatio(qreal ratio); - - // IP Filter - bool isFilteringEnabled() const; - void setFilteringEnabled(bool enabled); - bool isFilteringTrackerEnabled() const; - void setFilteringTrackerEnabled(bool enabled); - QString getFilter() const; - void setFilter(const QString &path); - QStringList bannedIPs() const; - void banIP(const QString &ip); - // Search bool isSearchEnabled() const; void setSearchEnabled(bool enabled); - // Queueing system - bool isQueueingSystemEnabled() const; - void setQueueingSystemEnabled(bool enabled); - int getMaxActiveDownloads() const; - void setMaxActiveDownloads(int val); - int getMaxActiveUploads() const; - void setMaxActiveUploads(int val); - int getMaxActiveTorrents() const; - void setMaxActiveTorrents(int val); - bool ignoreSlowTorrentsForQueueing() const; - void setIgnoreSlowTorrentsForQueueing(bool ignore); bool isWebUiEnabled() const; void setWebUiEnabled(bool enabled); bool isWebUiLocalAuthEnabled() const; @@ -331,50 +222,16 @@ public: void setShutdownqBTWhenDownloadsComplete(bool shutdown); bool dontConfirmAutoExit() const; void setDontConfirmAutoExit(bool dontConfirmAutoExit); - uint diskCacheSize() const; - void setDiskCacheSize(uint size); - uint diskCacheTTL() const; - void setDiskCacheTTL(uint ttl); - bool osCache() const; - void setOsCache(bool enable); - uint saveResumeDataInterval() const; - void setSaveResumeDataInterval(uint m); - uint outgoingPortsMin() const; - void setOutgoingPortsMin(uint val); - uint outgoingPortsMax() const; - void setOutgoingPortsMax(uint val); - bool getIgnoreLimitsOnLAN() const; - void setIgnoreLimitsOnLAN(bool ignore); - bool includeOverheadInLimits() const; - void includeOverheadInLimits(bool include); - bool trackerExchangeEnabled() const; - void setTrackerExchangeEnabled(bool enable); bool recheckTorrentsOnCompletion() const; void recheckTorrentsOnCompletion(bool recheck); - unsigned int getRefreshInterval() const; - void setRefreshInterval(uint interval); bool resolvePeerCountries() const; void resolvePeerCountries(bool resolve); bool resolvePeerHostNames() const; void resolvePeerHostNames(bool resolve); - int getMaxHalfOpenConnections() const; - void setMaxHalfOpenConnections(int value); - QString getNetworkInterface() const; - void setNetworkInterface(const QString& iface); QString getNetworkInterfaceName() const; void setNetworkInterfaceName(const QString& iface); QString getNetworkInterfaceAddress() const; void setNetworkInterfaceAddress(const QString& addr); - bool getListenIPv6() const; - void setListenIPv6(bool enable); - QString getNetworkAddress() const; - void setNetworkAddress(const QString& addr); - bool isAnonymousModeEnabled() const; - void enableAnonymousMode(bool enabled); - bool isSuperSeedingEnabled() const; - void enableSuperSeeding(bool enabled); - bool announceToAllTrackers() const; - void setAnnounceToAllTrackers(bool enabled); #if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC)) bool useSystemIconTheme() const; void useSystemIconTheme(bool enabled); @@ -396,8 +253,6 @@ public: static void setTorrentFileAssoc(); static void setMagnetLinkAssoc(); #endif - bool isTrackerEnabled() const; - void setTrackerEnabled(bool enabled); int getTrackerPort() const; void setTrackerPort(int port); #if defined(Q_OS_WIN) || defined(Q_OS_MAC) diff --git a/src/base/settingsstorage.cpp b/src/base/settingsstorage.cpp index a853aee3a..1b62aef5d 100644 --- a/src/base/settingsstorage.cpp +++ b/src/base/settingsstorage.cpp @@ -98,22 +98,84 @@ namespace { static const MappingTable keyMapping = { - { "BitTorrent/Session/MaxRatioAction", "Preferences/Bittorrent/MaxRatioAction" }, - { "BitTorrent/Session/DefaultSavePath", "Preferences/Downloads/SavePath" }, - { "BitTorrent/Session/TempPath", "Preferences/Downloads/TempPath" }, - { "BitTorrent/Session/TempPathEnabled", "Preferences/Downloads/TempPathEnabled" }, - { "BitTorrent/Session/AddTorrentPaused", "Preferences/Downloads/StartInPause" }, + {"BitTorrent/Session/MaxRatioAction", "Preferences/Bittorrent/MaxRatioAction"}, + {"BitTorrent/Session/DefaultSavePath", "Preferences/Downloads/SavePath"}, + {"BitTorrent/Session/TempPath", "Preferences/Downloads/TempPath"}, + {"BitTorrent/Session/TempPathEnabled", "Preferences/Downloads/TempPathEnabled"}, + {"BitTorrent/Session/AddTorrentPaused", "Preferences/Downloads/StartInPause"}, + {"BitTorrent/Session/RefreshInterval", "Preferences/General/RefreshInterval"}, + {"BitTorrent/Session/Preallocation", "Preferences/Downloads/PreAllocation"}, + {"BitTorrent/Session/AddExtensionToIncompleteFiles", "Preferences/Downloads/UseIncompleteExtension"}, + {"BitTorrent/Session/TorrentExportDirectory", "Preferences/Downloads/TorrentExportDir"}, + {"BitTorrent/Session/FinishedTorrentExportDirectory", "Preferences/Downloads/FinishedTorrentExportDir"}, + {"BitTorrent/Session/GlobalUPSpeedLimit", "Preferences/Connection/GlobalUPLimit"}, + {"BitTorrent/Session/GlobalDLSpeedLimit", "Preferences/Connection/GlobalDLLimit"}, + {"BitTorrent/Session/AlternativeGlobalUPSpeedLimit", "Preferences/Connection/GlobalUPLimitAlt"}, + {"BitTorrent/Session/AlternativeGlobalDLSpeedLimit", "Preferences/Connection/GlobalDLLimitAlt"}, + {"BitTorrent/Session/UseAlternativeGlobalSpeedLimit", "Preferences/Connection/alt_speeds_on"}, + {"BitTorrent/Session/BandwidthSchedulerEnabled", "Preferences/Scheduler/Enabled"}, + {"BitTorrent/Session/Port", "Preferences/Connection/PortRangeMin"}, + {"BitTorrent/Session/UseRandomPort", "Preferences/General/UseRandomPort"}, + {"BitTorrent/Session/IPv6Enabled", "Preferences/Connection/InterfaceListenIPv6"}, + {"BitTorrent/Session/Interface", "Preferences/Connection/Interface"}, + {"BitTorrent/Session/SaveResumeDataInterval", "Preferences/Downloads/SaveResumeDataInterval"}, + {"BitTorrent/Session/Encryption", "Preferences/Bittorrent/Encryption"}, + {"BitTorrent/Session/ForceProxy", "Preferences/Connection/ProxyForce"}, + {"BitTorrent/Session/ProxyPeerConnections", "Preferences/Connection/ProxyPeerConnections"}, + {"BitTorrent/Session/MaxConnections", "Preferences/Bittorrent/MaxConnecs"}, + {"BitTorrent/Session/MaxUploads", "Preferences/Bittorrent/MaxUploads"}, + {"BitTorrent/Session/MaxConnectionsPerTorrent", "Preferences/Bittorrent/MaxConnecsPerTorrent"}, + {"BitTorrent/Session/MaxUploadsPerTorrent", "Preferences/Bittorrent/MaxUploadsPerTorrent"}, + {"BitTorrent/Session/DHTEnabled", "Preferences/Bittorrent/DHT"}, + {"BitTorrent/Session/LSDEnabled", "Preferences/Bittorrent/LSD"}, + {"BitTorrent/Session/PeXEnabled", "Preferences/Bittorrent/PeX"}, + {"BitTorrent/Session/TrackerExchangeEnabled", "Preferences/Advanced/LtTrackerExchange"}, + {"BitTorrent/Session/AddTrackersEnabled", "Preferences/Bittorrent/AddTrackers"}, + {"BitTorrent/Session/AdditionalTrackers", "Preferences/Bittorrent/TrackersList"}, + {"BitTorrent/Session/FilteringEnabled", "Preferences/IPFilter/Enabled"}, + {"BitTorrent/Session/TrackerFilteringEnabled", "Preferences/IPFilter/FilterTracker"}, + {"BitTorrent/Session/IPFilter", "Preferences/IPFilter/File"}, + {"BitTorrent/Session/GlobalMaxRatio", "Preferences/Bittorrent/MaxRatio"}, + {"BitTorrent/Session/AnnounceToAllTrackers", "Preferences/Advanced/AnnounceToAllTrackers"}, + {"BitTorrent/Session/DiskCacheSize", "Preferences/Downloads/DiskWriteCacheSize"}, + {"BitTorrent/Session/DiskCacheTTL", "Preferences/Downloads/DiskWriteCacheTTL"}, + {"BitTorrent/Session/UseOSCache", "Preferences/Advanced/osCache"}, + {"BitTorrent/Session/AnonymousModeEnabled", "Preferences/Advanced/AnonymousMode"}, + {"BitTorrent/Session/QueueingSystemEnabled", "Preferences/Queueing/QueueingEnabled"}, + {"BitTorrent/Session/MaxActiveDownloads", "Preferences/Queueing/MaxActiveDownloads"}, + {"BitTorrent/Session/MaxActiveUploads", "Preferences/Queueing/MaxActiveUploads"}, + {"BitTorrent/Session/MaxActiveTorrents", "Preferences/Queueing/MaxActiveTorrents"}, + {"BitTorrent/Session/IgnoreSlowTorrentsForQueueing", "Preferences/Queueing/IgnoreSlowTorrents"}, + {"BitTorrent/Session/OutgoingPortsMin", "Preferences/Advanced/OutgoingPortsMin"}, + {"BitTorrent/Session/OutgoingPortsMax", "Preferences/Advanced/OutgoingPortsMax"}, + {"BitTorrent/Session/IgnoreLimitsOnLAN", "Preferences/Advanced/IgnoreLimitsLAN"}, + {"BitTorrent/Session/IncludeOverheadInLimits", "Preferences/Advanced/IncludeOverhead"}, + {"BitTorrent/Session/NetworkAddress", "Preferences/Connection/InetAddress"}, + {"BitTorrent/Session/SuperSeedingEnabled", "Preferences/Advanced/SuperSeeding"}, + {"BitTorrent/Session/MaxHalfOpenConnections", "Preferences/Connection/MaxHalfOpenConnec"}, + {"BitTorrent/Session/uTPEnabled", "Preferences/Bittorrent/uTP"}, + {"BitTorrent/Session/uTPRateLimited", "Preferences/Bittorrent/uTP_rate_limited"}, + {"BitTorrent/TrackerEnabled", "Preferences/TrackerEnabled"}, + {"Network/Proxy/Disabled", "Preferences/Connection/ProxyOnlyForTorrents"}, + {"Network/Proxy/Type", "Preferences/Connection/ProxyType"}, + {"Network/Proxy/Authentication", "Preferences/Connection/Proxy/Authentication"}, + {"Network/Proxy/Username", "Preferences/Connection/Proxy/Username"}, + {"Network/Proxy/Password", "Preferences/Connection/Proxy/Password"}, + {"Network/Proxy/IP", "Preferences/Connection/Proxy/IP"}, + {"Network/Proxy/Port", "Preferences/Connection/Proxy/Port"}, #ifdef QBT_USES_QT5 - { "AddNewTorrentDialog/TreeHeaderState", "AddNewTorrentDialog/qt5/treeHeaderState" }, + {"AddNewTorrentDialog/TreeHeaderState", "AddNewTorrentDialog/qt5/treeHeaderState"}, #else - { "AddNewTorrentDialog/TreeHeaderState", "AddNewTorrentDialog/treeHeaderState" }, + {"AddNewTorrentDialog/TreeHeaderState", "AddNewTorrentDialog/treeHeaderState"}, #endif - { "AddNewTorrentDialog/Width", "AddNewTorrentDialog/width" }, - { "AddNewTorrentDialog/Position", "AddNewTorrentDialog/y" }, - { "AddNewTorrentDialog/Expanded", "AddNewTorrentDialog/expanded" }, - { "AddNewTorrentDialog/SavePathHistory", "TorrentAdditionDlg/save_path_history" }, - { "AddNewTorrentDialog/Enabled", "Preferences/Downloads/NewAdditionDialog" }, - { "AddNewTorrentDialog/TopLevel", "Preferences/Downloads/NewAdditionDialogFront" } + {"AddNewTorrentDialog/Width", "AddNewTorrentDialog/width"}, + {"AddNewTorrentDialog/Position", "AddNewTorrentDialog/y"}, + {"AddNewTorrentDialog/Expanded", "AddNewTorrentDialog/expanded"}, + {"AddNewTorrentDialog/SavePathHistory", "TorrentAdditionDlg/save_path_history"}, + {"AddNewTorrentDialog/Enabled", "Preferences/Downloads/NewAdditionDialog"}, + {"AddNewTorrentDialog/TopLevel", "Preferences/Downloads/NewAdditionDialogFront"}, + + {"State/BannedIPs", "Preferences/IPFilter/BannedIPs"} }; diff --git a/src/base/settingvalue.h b/src/base/settingvalue.h new file mode 100644 index 000000000..d04f1ad8e --- /dev/null +++ b/src/base/settingvalue.h @@ -0,0 +1,73 @@ +/* + * Bittorrent Client using Qt and libtorrent. + * Copyright (C) 2016 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. + */ + +#ifndef SETTINGVALUE_H +#define SETTINGVALUE_H + +#include +#include + +#include "settingsstorage.h" + +template +class CachedSettingValue +{ + using ProxyFunc = std::function; + +public: + explicit CachedSettingValue(const char *keyName, const T &defaultValue = T() + , ProxyFunc proxyFunc = [](const T &value) { return value; }) + : m_keyName(QLatin1String(keyName)) + , m_value(proxyFunc(SettingsStorage::instance()->loadValue( + m_keyName, defaultValue).template value())) + { + } + + T value() const + { + return m_value; + } + + CachedSettingValue &operator=(const T &newValue) + { + m_value = newValue; + SettingsStorage::instance()->storeValue(m_keyName, m_value); + return *this; + } + + operator T() const + { + return value(); + } + +private: + const QString m_keyName; + T m_value; +}; + +#endif // SETTINGVALUE_H diff --git a/src/gui/advancedsettings.cpp b/src/gui/advancedsettings.cpp index cf8b287d1..05cb5cb5a 100644 --- a/src/gui/advancedsettings.cpp +++ b/src/gui/advancedsettings.cpp @@ -27,11 +27,14 @@ */ #include "advancedsettings.h" + #include #include #include #include + #include "app/application.h" +#include "base/bittorrent/session.h" #include "base/preferences.h" #include "gui/mainwindow.h" @@ -116,39 +119,40 @@ AdvancedSettings::AdvancedSettings(QWidget *parent) void AdvancedSettings::saveAdvancedSettings() { Preferences* const pref = Preferences::instance(); + BitTorrent::Session *const session = BitTorrent::Session::instance(); + // Disk write cache - pref->setDiskCacheSize(spin_cache.value()); - pref->setDiskCacheTTL(spin_cache_ttl.value()); + session->setDiskCacheSize(spin_cache.value()); + session->setDiskCacheTTL(spin_cache_ttl.value()); // Enable OS cache - pref->setOsCache(cb_os_cache.isChecked()); + session->setUseOSCache(cb_os_cache.isChecked()); // Save resume data interval - pref->setSaveResumeDataInterval(spin_save_resume_data_interval.value()); + session->setSaveResumeDataInterval(spin_save_resume_data_interval.value()); // Outgoing ports - pref->setOutgoingPortsMin(outgoing_ports_min.value()); - pref->setOutgoingPortsMax(outgoing_ports_max.value()); + session->setOutgoingPortsMin(outgoing_ports_min.value()); + session->setOutgoingPortsMax(outgoing_ports_max.value()); // Recheck torrents on completion pref->recheckTorrentsOnCompletion(cb_recheck_completed.isChecked()); // Transfer list refresh interval - pref->setRefreshInterval(spin_list_refresh.value()); + session->setRefreshInterval(spin_list_refresh.value()); // Peer resolution pref->resolvePeerCountries(cb_resolve_countries.isChecked()); pref->resolvePeerHostNames(cb_resolve_hosts.isChecked()); // Max Half-Open connections - pref->setMaxHalfOpenConnections(spin_maxhalfopen.value()); + session->setMaxHalfOpenConnections(spin_maxhalfopen.value()); // Super seeding - pref->enableSuperSeeding(cb_super_seeding.isChecked()); + session->setSuperSeedingEnabled(cb_super_seeding.isChecked()); // Network interface if (combo_iface.currentIndex() == 0) { // All interfaces (default) - pref->setNetworkInterface(QString::null); - pref->setNetworkInterfaceName(QString::null); + session->setNetworkInterface(QString()); + pref->setNetworkInterfaceName(QString()); } else { - pref->setNetworkInterface(combo_iface.itemData(combo_iface.currentIndex()).toString()); + session->setNetworkInterface(combo_iface.itemData(combo_iface.currentIndex()).toString()); pref->setNetworkInterfaceName(combo_iface.currentText()); } - // Listen on IPv6 address - pref->setListenIPv6(cb_listen_ipv6.isChecked()); + // Interface address if (combo_iface_address.currentIndex() == 0) { // All addresses (default) @@ -158,19 +162,18 @@ void AdvancedSettings::saveAdvancedSettings() QHostAddress ifaceAddr(combo_iface_address.currentText().trimmed()); ifaceAddr.isNull() ? pref->setNetworkInterfaceAddress(QString::null) : pref->setNetworkInterfaceAddress(ifaceAddr.toString()); } - // Network Announce address - QHostAddress networkAddr(txt_network_address.text().trimmed()); - if (networkAddr.isNull()) - pref->setNetworkAddress(""); - else - pref->setNetworkAddress(networkAddr.toString()); + session->setIPv6Enabled(cb_listen_ipv6.isChecked()); + // Network address + QHostAddress addr(txt_network_address.text().trimmed()); + session->setNetworkAddress(addr.isNull() ? "" : addr.toString()); // Program notification MainWindow * const mainWindow = static_cast(QCoreApplication::instance())->mainWindow(); mainWindow->setNotificationsEnabled(cb_program_notifications.isChecked()); mainWindow->setTorrentAddedNotificationsEnabled(cb_torrent_added_notifications.isChecked()); + // Tracker - pref->setTrackerEnabled(cb_tracker_status.isChecked()); + session->setTrackerEnabled(cb_tracker_status.isChecked()); pref->setTrackerPort(spin_tracker_port.value()); #if defined(Q_OS_WIN) || defined(Q_OS_MAC) pref->setUpdateCheckEnabled(cb_update_check.isChecked()); @@ -181,8 +184,8 @@ void AdvancedSettings::saveAdvancedSettings() #endif pref->setConfirmTorrentRecheck(cb_confirm_torrent_recheck.isChecked()); // Tracker exchange - pref->setTrackerExchangeEnabled(cb_enable_tracker_ext.isChecked()); - pref->setAnnounceToAllTrackers(cb_announce_all_trackers.isChecked()); + session->setTrackerExchangeEnabled(cb_enable_tracker_ext.isChecked()); + session->setAnnounceToAllTrackers(cb_announce_all_trackers.isChecked()); } void AdvancedSettings::updateCacheSpinSuffix(int value) @@ -233,6 +236,8 @@ void AdvancedSettings::updateInterfaceAddressCombo() void AdvancedSettings::loadAdvancedSettings() { const Preferences* const pref = Preferences::instance(); + BitTorrent::Session *const session = BitTorrent::Session::instance(); + // add section headers QFont boldFont; boldFont.setBold(true); @@ -255,33 +260,33 @@ void AdvancedSettings::loadAdvancedSettings() // allocate 1536MiB and leave 512MiB to the rest of program data in RAM spin_cache.setMaximum(1536); #endif - spin_cache.setValue(pref->diskCacheSize()); + spin_cache.setValue(session->diskCacheSize()); updateCacheSpinSuffix(spin_cache.value()); addRow(DISK_CACHE, tr("Disk write cache size"), &spin_cache); // Disk cache expiry spin_cache_ttl.setMinimum(15); spin_cache_ttl.setMaximum(600); - spin_cache_ttl.setValue(pref->diskCacheTTL()); + spin_cache_ttl.setValue(session->diskCacheTTL()); spin_cache_ttl.setSuffix(tr(" s", " seconds")); addRow(DISK_CACHE_TTL, tr("Disk cache expiry interval"), &spin_cache_ttl); // Enable OS cache - cb_os_cache.setChecked(pref->osCache()); + cb_os_cache.setChecked(session->useOSCache()); addRow(OS_CACHE, tr("Enable OS cache"), &cb_os_cache); // Save resume data interval spin_save_resume_data_interval.setMinimum(1); spin_save_resume_data_interval.setMaximum(1440); - spin_save_resume_data_interval.setValue(pref->saveResumeDataInterval()); + spin_save_resume_data_interval.setValue(session->saveResumeDataInterval()); spin_save_resume_data_interval.setSuffix(tr(" m", " minutes")); addRow(SAVE_RESUME_DATA_INTERVAL, tr("Save resume data interval", "How often the fastresume file is saved."), &spin_save_resume_data_interval); // Outgoing port Min outgoing_ports_min.setMinimum(0); outgoing_ports_min.setMaximum(65535); - outgoing_ports_min.setValue(pref->outgoingPortsMin()); + outgoing_ports_min.setValue(session->outgoingPortsMin()); addRow(OUTGOING_PORT_MIN, tr("Outgoing ports (Min) [0: Disabled]"), &outgoing_ports_min); // Outgoing port Min outgoing_ports_max.setMinimum(0); outgoing_ports_max.setMaximum(65535); - outgoing_ports_max.setValue(pref->outgoingPortsMax()); + outgoing_ports_max.setValue(session->outgoingPortsMax()); addRow(OUTGOING_PORT_MAX, tr("Outgoing ports (Max) [0: Disabled]"), &outgoing_ports_max); // Recheck completed torrents cb_recheck_completed.setChecked(pref->recheckTorrentsOnCompletion()); @@ -289,7 +294,7 @@ void AdvancedSettings::loadAdvancedSettings() // Transfer list refresh interval spin_list_refresh.setMinimum(30); spin_list_refresh.setMaximum(99999); - spin_list_refresh.setValue(pref->getRefreshInterval()); + spin_list_refresh.setValue(session->refreshInterval()); spin_list_refresh.setSuffix(tr(" ms", " milliseconds")); addRow(LIST_REFRESH, tr("Transfer list refresh interval"), &spin_list_refresh); // Resolve Peer countries @@ -301,14 +306,14 @@ void AdvancedSettings::loadAdvancedSettings() // Max Half Open connections spin_maxhalfopen.setMinimum(0); spin_maxhalfopen.setMaximum(99999); - spin_maxhalfopen.setValue(pref->getMaxHalfOpenConnections()); + spin_maxhalfopen.setValue(session->maxHalfOpenConnections()); addRow(MAX_HALF_OPEN, tr("Maximum number of half-open connections [0: Unlimited]"), &spin_maxhalfopen); // Super seeding - cb_super_seeding.setChecked(pref->isSuperSeedingEnabled()); + cb_super_seeding.setChecked(session->isSuperSeedingEnabled()); addRow(SUPER_SEEDING, tr("Strict super seeding"), &cb_super_seeding); // Network interface combo_iface.addItem(tr("Any interface", "i.e. Any network interface")); - const QString current_iface = pref->getNetworkInterface(); + const QString current_iface = session->networkInterface(); bool interface_exists = current_iface.isEmpty(); int i = 1; foreach (const QNetworkInterface& iface, QNetworkInterface::allInterfaces()) { @@ -336,10 +341,10 @@ void AdvancedSettings::loadAdvancedSettings() updateInterfaceAddressCombo(); addRow(NETWORK_IFACE_ADDRESS, tr("Optional IP Address to bind to (requires restart)"), &combo_iface_address); // Listen on IPv6 address - cb_listen_ipv6.setChecked(pref->getListenIPv6()); + cb_listen_ipv6.setChecked(session->isIPv6Enabled()); addRow(NETWORK_LISTEN_IPV6, tr("Listen on IPv6 address (requires restart)"), &cb_listen_ipv6); // Announce address - txt_network_address.setText(pref->getNetworkAddress()); + txt_network_address.setText(session->networkAddress()); addRow(NETWORK_ADDRESS, tr("IP Address to report to trackers (requires restart)"), &txt_network_address); // Program notifications @@ -349,8 +354,9 @@ void AdvancedSettings::loadAdvancedSettings() // Torrent added notifications cb_torrent_added_notifications.setChecked(mainWindow->isTorrentAddedNotificationsEnabled()); addRow(TORRENT_ADDED_NOTIFICATIONS, tr("Display notifications for added torrents"), &cb_torrent_added_notifications); + // Tracker State - cb_tracker_status.setChecked(pref->isTrackerEnabled()); + cb_tracker_status.setChecked(session->isTrackerEnabled()); addRow(TRACKER_STATUS, tr("Enable embedded tracker"), &cb_tracker_status); // Tracker port spin_tracker_port.setMinimum(1); @@ -369,10 +375,10 @@ void AdvancedSettings::loadAdvancedSettings() cb_confirm_torrent_recheck.setChecked(pref->confirmTorrentRecheck()); addRow(CONFIRM_RECHECK_TORRENT, tr("Confirm torrent recheck"), &cb_confirm_torrent_recheck); // Tracker exchange - cb_enable_tracker_ext.setChecked(pref->trackerExchangeEnabled()); + cb_enable_tracker_ext.setChecked(session->isTrackerExchangeEnabled()); addRow(TRACKER_EXCHANGE, tr("Exchange trackers with other peers"), &cb_enable_tracker_ext); // Announce to all trackers - cb_announce_all_trackers.setChecked(pref->announceToAllTrackers()); + cb_announce_all_trackers.setChecked(session->announceToAllTrackers()); addRow(ANNOUNCE_ALL_TRACKERS, tr("Always announce to all trackers"), &cb_announce_all_trackers); } diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp index 23bef83b4..956d318b0 100644 --- a/src/gui/mainwindow.cpp +++ b/src/gui/mainwindow.cpp @@ -820,32 +820,26 @@ void MainWindow::handleDownloadFromUrlFailure(QString url, QString reason) const void MainWindow::on_actionSetGlobalUploadLimit_triggered() { qDebug() << Q_FUNC_INFO; + BitTorrent::Session *const session = BitTorrent::Session::instance(); bool ok; - int curLimit = BitTorrent::Session::instance()->uploadRateLimit(); - const long newLimit = SpeedLimitDialog::askSpeedLimit(&ok, tr("Global Upload Speed Limit"), curLimit); + const long newLimit = SpeedLimitDialog::askSpeedLimit( + &ok, tr("Global Upload Speed Limit"), session->uploadSpeedLimit()); if (ok) { qDebug("Setting global upload rate limit to %.1fKb/s", newLimit / 1024.); - BitTorrent::Session::instance()->setUploadRateLimit(newLimit); - if (newLimit <= 0) - Preferences::instance()->setGlobalUploadLimit(-1); - else - Preferences::instance()->setGlobalUploadLimit(newLimit / 1024.); + session->setUploadSpeedLimit(newLimit); } } void MainWindow::on_actionSetGlobalDownloadLimit_triggered() { qDebug() << Q_FUNC_INFO; + BitTorrent::Session *const session = BitTorrent::Session::instance(); bool ok; - int curLimit = BitTorrent::Session::instance()->downloadRateLimit(); - const long newLimit = SpeedLimitDialog::askSpeedLimit(&ok, tr("Global Download Speed Limit"), curLimit); + const long newLimit = SpeedLimitDialog::askSpeedLimit( + &ok, tr("Global Download Speed Limit"), session->downloadSpeedLimit()); if (ok) { qDebug("Setting global download rate limit to %.1fKb/s", newLimit / 1024.); - BitTorrent::Session::instance()->setDownloadRateLimit(newLimit); - if (newLimit <= 0) - Preferences::instance()->setGlobalDownloadLimit(-1); - else - Preferences::instance()->setGlobalDownloadLimit(newLimit / 1024.); + session->setDownloadSpeedLimit(newLimit); } } @@ -1221,7 +1215,7 @@ void MainWindow::loadPreferences(bool configureSession) m_propertiesWidget->getPeerList()->setAlternatingRowColors(pref->useAlternatingRowColors()); // Queueing System - if (pref->isQueueingSystemEnabled()) { + if (BitTorrent::Session::instance()->isQueueingSystemEnabled()) { if (!m_ui->actionDecreasePriority->isVisible()) { m_transferListWidget->hidePriorityColumn(false); m_ui->actionDecreasePriority->setVisible(true); @@ -1412,7 +1406,7 @@ QMenu* MainWindow::trayIconMenu() m_trayIconMenu->addAction(m_ui->actionOpen); m_trayIconMenu->addAction(m_ui->actionDownloadFromURL); m_trayIconMenu->addSeparator(); - const bool isAltBWEnabled = Preferences::instance()->isAltBandwidthEnabled(); + const bool isAltBWEnabled = BitTorrent::Session::instance()->isAltGlobalSpeedLimitEnabled(); updateAltSpeedsBtn(isAltBWEnabled); m_ui->actionUseAlternativeSpeedLimits->setChecked(isAltBWEnabled); m_trayIconMenu->addAction(m_ui->actionUseAlternativeSpeedLimits); diff --git a/src/gui/optionsdlg.cpp b/src/gui/optionsdlg.cpp index 3777ef95e..e688e4d1c 100644 --- a/src/gui/optionsdlg.cpp +++ b/src/gui/optionsdlg.cpp @@ -51,6 +51,7 @@ #include "app/application.h" #include "base/bittorrent/session.h" #include "base/net/dnsupdater.h" +#include "base/net/proxyconfigurationmanager.h" #include "base/preferences.h" #include "base/scanfoldersmodel.h" #include "base/torrentfileguard.h" @@ -506,8 +507,8 @@ void OptionsDialog::saveOptions() session->setDisableAutoTMMWhenDefaultSavePathChanged(m_ui->comboCategoryDefaultPathChanged->currentIndex() == 1); session->setTempPathEnabled(m_ui->checkTempFolder->isChecked()); session->setTempPath(Utils::Fs::expandPathAbs(m_ui->textTempPath->text())); - pref->useIncompleteFilesExtension(m_ui->checkAppendqB->isChecked()); - pref->preAllocateAllFiles(preAllocateAllFiles()); + session->setAppendExtensionEnabled(m_ui->checkAppendqB->isChecked()); + session->setPreallocationEnabled(preAllocateAllFiles()); AddNewTorrentDialog::setEnabled(useAdditionDialog()); AddNewTorrentDialog::setTopLevel(m_ui->checkAdditionDialogFront->isChecked()); session->setAddTorrentPaused(addTorrentsInPause()); @@ -516,8 +517,8 @@ void OptionsDialog::saveOptions() ScanFoldersModel::instance()->makePersistent(); removedScanDirs.clear(); addedScanDirs.clear(); - pref->setTorrentExportDir(getTorrentExportDir()); - pref->setFinishedTorrentExportDir(getFinishedTorrentExportDir()); + session->setTorrentExportDirectory(getTorrentExportDir()); + session->setFinishedTorrentExportDirectory(getFinishedTorrentExportDir()); pref->setMailNotificationEnabled(m_ui->groupMailNotification->isChecked()); pref->setMailNotificationEmail(m_ui->dest_email_txt->text()); pref->setMailNotificationSMTP(m_ui->smtp_server_txt->text()); @@ -535,61 +536,66 @@ void OptionsDialog::saveOptions() // End Downloads preferences // Connection preferences - pref->setSessionPort(getPort()); - pref->setRandomPort(m_ui->checkRandomPort->isChecked()); + session->setPort(getPort()); + session->setUseRandomPort(m_ui->checkRandomPort->isChecked()); pref->setUPnPEnabled(isUPnPEnabled()); const QPair down_up_limit = getGlobalBandwidthLimits(); - pref->setGlobalDownloadLimit(down_up_limit.first); - pref->setGlobalUploadLimit(down_up_limit.second); - pref->setuTPEnabled(m_ui->checkuTP->isChecked()); - pref->setuTPRateLimited(m_ui->checkLimituTPConnections->isChecked()); - pref->includeOverheadInLimits(m_ui->checkLimitTransportOverhead->isChecked()); - pref->setIgnoreLimitsOnLAN(!m_ui->checkLimitLocalPeerRate->isChecked()); + session->setGlobalDownloadSpeedLimit(down_up_limit.first); + session->setGlobalUploadSpeedLimit(down_up_limit.second); + session->setUTPEnabled(m_ui->checkuTP->isChecked()); + session->setUTPRateLimited(m_ui->checkLimituTPConnections->isChecked()); + session->setIncludeOverheadInLimits(m_ui->checkLimitTransportOverhead->isChecked()); + session->setIgnoreLimitsOnLAN(!m_ui->checkLimitLocalPeerRate->isChecked()); const QPair alt_down_up_limit = getAltGlobalBandwidthLimits(); - pref->setAltGlobalDownloadLimit(alt_down_up_limit.first); - pref->setAltGlobalUploadLimit(alt_down_up_limit.second); - pref->setSchedulerEnabled(m_ui->check_schedule->isChecked()); + session->setAltGlobalDownloadSpeedLimit(alt_down_up_limit.first); + session->setAltGlobalUploadSpeedLimit(alt_down_up_limit.second); + session->setBandwidthSchedulerEnabled(m_ui->check_schedule->isChecked()); pref->setSchedulerStartTime(m_ui->schedule_from->time()); pref->setSchedulerEndTime(m_ui->schedule_to->time()); pref->setSchedulerDays((scheduler_days)m_ui->schedule_days->currentIndex()); - pref->setProxyType(getProxyType()); - pref->setProxyIp(getProxyIp()); - pref->setProxyPort(getProxyPort()); - pref->setProxyPeerConnections(m_ui->checkProxyPeerConnecs->isChecked()); - pref->setForceProxy(m_ui->checkForceProxy->isChecked()); - pref->setProxyOnlyForTorrents(m_ui->isProxyOnlyForTorrents->isChecked()); - pref->setProxyAuthEnabled(isProxyAuthEnabled()); - pref->setProxyUsername(getProxyUsername()); - pref->setProxyPassword(getProxyPassword()); + + auto proxyConfigManager = Net::ProxyConfigurationManager::instance(); + Net::ProxyConfiguration proxyConf; + proxyConf.type = getProxyType(); + proxyConf.ip = getProxyIp(); + proxyConf.port = getProxyPort(); + proxyConf.username = getProxyUsername(); + proxyConf.password = getProxyPassword(); + proxyConfigManager->setProxyDisabled(m_ui->isProxyOnlyForTorrents->isChecked()); + proxyConfigManager->setProxyConfiguration(proxyConf); + + session->setProxyPeerConnectionsEnabled(m_ui->checkProxyPeerConnecs->isChecked()); + session->setForceProxyEnabled(m_ui->checkForceProxy->isChecked()); // End Connection preferences + // Bittorrent preferences - pref->setMaxConnecs(getMaxConnecs()); - pref->setMaxConnecsPerTorrent(getMaxConnecsPerTorrent()); - pref->setMaxUploads(getMaxUploads()); - pref->setMaxUploadsPerTorrent(getMaxUploadsPerTorrent()); - pref->setDHTEnabled(isDHTEnabled()); - pref->setPeXEnabled(m_ui->checkPeX->isChecked()); - pref->setLSDEnabled(isLSDEnabled()); - pref->setEncryptionSetting(getEncryptionSetting()); - pref->enableAnonymousMode(m_ui->checkAnonymousMode->isChecked()); - pref->setAddTrackersEnabled(m_ui->checkEnableAddTrackers->isChecked()); - pref->setTrackersList(m_ui->textTrackers->toPlainText()); - pref->setGlobalMaxRatio(getMaxRatio()); + session->setMaxConnections(getMaxConnecs()); + session->setMaxConnectionsPerTorrent(getMaxConnecsPerTorrent()); + session->setMaxUploads(getMaxUploads()); + session->setMaxUploadsPerTorrent(getMaxUploadsPerTorrent()); + session->setDHTEnabled(isDHTEnabled()); + session->setPeXEnabled(m_ui->checkPeX->isChecked()); + session->setLSDEnabled(isLSDEnabled()); + session->setEncryption(getEncryptionSetting()); + session->setAnonymousModeEnabled(m_ui->checkAnonymousMode->isChecked()); + session->setAddTrackersEnabled(m_ui->checkEnableAddTrackers->isChecked()); + session->setAdditionalTrackers(m_ui->textTrackers->toPlainText()); + session->setGlobalMaxRatio(getMaxRatio()); session->setMaxRatioAction(static_cast(m_ui->comboRatioLimitAct->currentIndex())); // End Bittorrent preferences // Misc preferences // * IPFilter - pref->setFilteringEnabled(isFilteringEnabled()); - pref->setFilteringTrackerEnabled(m_ui->checkIpFilterTrackers->isChecked()); - pref->setFilter(m_ui->textFilterPath->text()); + session->setFilteringEnabled(isFilteringEnabled()); + session->setTrackerFilteringEnabled(m_ui->checkIpFilterTrackers->isChecked()); + session->setIPFilterFile(m_ui->textFilterPath->text()); // End IPFilter preferences // Queueing system - pref->setQueueingSystemEnabled(isQueueingSystemEnabled()); - pref->setMaxActiveDownloads(m_ui->spinMaxActiveDownloads->value()); - pref->setMaxActiveUploads(m_ui->spinMaxActiveUploads->value()); - pref->setMaxActiveTorrents(m_ui->spinMaxActiveTorrents->value()); - pref->setIgnoreSlowTorrentsForQueueing(m_ui->checkIgnoreSlowTorrentsForQueueing->isChecked()); + session->setQueueingSystemEnabled(isQueueingSystemEnabled()); + session->setMaxActiveDownloads(m_ui->spinMaxActiveDownloads->value()); + session->setMaxActiveUploads(m_ui->spinMaxActiveUploads->value()); + session->setMaxActiveTorrents(m_ui->spinMaxActiveTorrents->value()); + session->setIgnoreSlowTorrentsForQueueing(m_ui->checkIgnoreSlowTorrentsForQueueing->isChecked()); // End Queueing system preferences // Web UI pref->setWebUiEnabled(isWebUiEnabled()); @@ -625,29 +631,28 @@ bool OptionsDialog::isFilteringEnabled() const return m_ui->checkIPFilter->isChecked(); } -int OptionsDialog::getProxyType() const +Net::ProxyType OptionsDialog::getProxyType() const { switch (m_ui->comboProxyType->currentIndex()) { case 1: - return Proxy::SOCKS4; + return Net::ProxyType::SOCKS4; break; case 2: if (isProxyAuthEnabled()) - return Proxy::SOCKS5_PW; - return Proxy::SOCKS5; + return Net::ProxyType::SOCKS5_PW; + return Net::ProxyType::SOCKS5; case 3: if (isProxyAuthEnabled()) - return Proxy::HTTP_PW; - return Proxy::HTTP; + return Net::ProxyType::HTTP_PW; + return Net::ProxyType::HTTP; default: - return -1; + return Net::ProxyType::None; } } void OptionsDialog::loadOptions() { int intValue; - qreal floatValue; QString strValue; bool fileLogBackup = true; bool fileLogDelete = true; @@ -722,10 +727,10 @@ void OptionsDialog::loadOptions() m_ui->textTempPath->setEnabled(m_ui->checkTempFolder->isChecked()); m_ui->browseTempDirButton->setEnabled(m_ui->checkTempFolder->isChecked()); m_ui->textTempPath->setText(Utils::Fs::toNativePath(session->tempPath())); - m_ui->checkAppendqB->setChecked(pref->useIncompleteFilesExtension()); - m_ui->checkPreallocateAll->setChecked(pref->preAllocateAllFiles()); + m_ui->checkAppendqB->setChecked(session->isAppendExtensionEnabled()); + m_ui->checkPreallocateAll->setChecked(session->isPreallocationEnabled()); - strValue = Utils::Fs::toNativePath(pref->getTorrentExportDir()); + strValue = Utils::Fs::toNativePath(session->torrentExportDirectory()); if (strValue.isEmpty()) { // Disable m_ui->checkExportDir->setChecked(false); @@ -740,7 +745,7 @@ void OptionsDialog::loadOptions() m_ui->textExportDir->setText(strValue); } - strValue = Utils::Fs::toNativePath(pref->getFinishedTorrentExportDir()); + strValue = Utils::Fs::toNativePath(session->finishedTorrentExportDirectory()); if (strValue.isEmpty()) { // Disable m_ui->checkExportDirFin->setChecked(false); @@ -777,11 +782,11 @@ void OptionsDialog::loadOptions() // Connection preferences m_ui->checkUPnP->setChecked(pref->isUPnPEnabled()); - m_ui->checkRandomPort->setChecked(pref->useRandomPort()); - m_ui->spinPort->setValue(pref->getSessionPort()); + m_ui->checkRandomPort->setChecked(session->useRandomPort()); + m_ui->spinPort->setValue(session->port()); m_ui->spinPort->setDisabled(m_ui->checkRandomPort->isChecked()); - intValue = pref->getMaxConnecs(); + intValue = session->maxConnections(); if (intValue > 0) { // enable m_ui->checkMaxConnecs->setChecked(true); @@ -793,7 +798,7 @@ void OptionsDialog::loadOptions() m_ui->checkMaxConnecs->setChecked(false); m_ui->spinMaxConnec->setEnabled(false); } - intValue = pref->getMaxConnecsPerTorrent(); + intValue = session->maxConnectionsPerTorrent(); if (intValue > 0) { // enable m_ui->checkMaxConnecsPerTorrent->setChecked(true); @@ -805,7 +810,7 @@ void OptionsDialog::loadOptions() m_ui->checkMaxConnecsPerTorrent->setChecked(false); m_ui->spinMaxConnecPerTorrent->setEnabled(false); } - intValue = pref->getMaxUploads(); + intValue = session->maxUploads(); if (intValue > 0) { // enable m_ui->checkMaxUploads->setChecked(true); @@ -817,7 +822,7 @@ void OptionsDialog::loadOptions() m_ui->checkMaxUploads->setChecked(false); m_ui->spinMaxUploads->setEnabled(false); } - intValue = pref->getMaxUploadsPerTorrent(); + intValue = session->maxUploadsPerTorrent(); if (intValue > 0) { // enable m_ui->checkMaxUploadsPerTorrent->setChecked(true); @@ -830,39 +835,45 @@ void OptionsDialog::loadOptions() m_ui->spinMaxUploadsPerTorrent->setEnabled(false); } - intValue = pref->getProxyType(); - switch (intValue) { - case Proxy::SOCKS4: + auto proxyConfigManager = Net::ProxyConfigurationManager::instance(); + Net::ProxyConfiguration proxyConf = proxyConfigManager->proxyConfiguration(); + using Net::ProxyType; + bool useProxyAuth = false; + switch (proxyConf.type) { + case ProxyType::SOCKS4: m_ui->comboProxyType->setCurrentIndex(1); break; - case Proxy::SOCKS5: - case Proxy::SOCKS5_PW: + case ProxyType::SOCKS5_PW: + useProxyAuth = true; + case ProxyType::SOCKS5: m_ui->comboProxyType->setCurrentIndex(2); break; - case Proxy::HTTP: - case Proxy::HTTP_PW: + case ProxyType::HTTP_PW: + useProxyAuth = true; + case ProxyType::HTTP: m_ui->comboProxyType->setCurrentIndex(3); break; default: m_ui->comboProxyType->setCurrentIndex(0); } - enableProxy(m_ui->comboProxyType->currentIndex()); - m_ui->textProxyIP->setText(pref->getProxyIp()); - m_ui->spinProxyPort->setValue(pref->getProxyPort()); - m_ui->checkProxyPeerConnecs->setChecked(pref->proxyPeerConnections()); - m_ui->checkForceProxy->setChecked(pref->getForceProxy()); - m_ui->isProxyOnlyForTorrents->setChecked(pref->isProxyOnlyForTorrents()); - m_ui->checkProxyAuth->setChecked(pref->isProxyAuthEnabled()); - m_ui->textProxyUsername->setText(pref->getProxyUsername()); - m_ui->textProxyPassword->setText(pref->getProxyPassword()); - - m_ui->checkIPFilter->setChecked(pref->isFilteringEnabled()); - m_ui->checkIpFilterTrackers->setChecked(pref->isFilteringTrackerEnabled()); - m_ui->textFilterPath->setText(Utils::Fs::toNativePath(pref->getFilter())); + enableProxy(m_ui->comboProxyType->currentIndex() > 0); + m_ui->textProxyIP->setText(proxyConf.ip); + m_ui->spinProxyPort->setValue(proxyConf.port); + m_ui->checkProxyAuth->setChecked(useProxyAuth); + m_ui->textProxyUsername->setText(proxyConf.username); + m_ui->textProxyPassword->setText(proxyConf.password); + + m_ui->checkProxyPeerConnecs->setChecked(session->isProxyPeerConnectionsEnabled()); + m_ui->checkForceProxy->setChecked(session->isForceProxyEnabled()); + m_ui->isProxyOnlyForTorrents->setChecked(proxyConfigManager->isProxyDisabled()); + + m_ui->checkIPFilter->setChecked(session->isFilteringEnabled()); + m_ui->checkIpFilterTrackers->setChecked(session->isTrackerFilteringEnabled()); + m_ui->textFilterPath->setText(Utils::Fs::toNativePath(session->IPFilterFile())); // End Connection preferences // Speed preferences - intValue = pref->getGlobalDownloadLimit(); + intValue = session->globalDownloadSpeedLimit(); if (intValue > 0) { // Enabled m_ui->checkDownloadLimit->setChecked(true); @@ -874,8 +885,8 @@ void OptionsDialog::loadOptions() m_ui->checkDownloadLimit->setChecked(false); m_ui->spinDownloadLimit->setEnabled(false); } - intValue = pref->getGlobalUploadLimit(); - if (intValue != -1) { + intValue = session->globalUploadSpeedLimit(); + if (intValue > 0) { // Enabled m_ui->checkUploadLimit->setChecked(true); m_ui->spinUploadLimit->setEnabled(true); @@ -887,7 +898,7 @@ void OptionsDialog::loadOptions() m_ui->spinUploadLimit->setEnabled(false); } - intValue = pref->getAltGlobalDownloadLimit(); + intValue = session->altGlobalDownloadSpeedLimit(); if (intValue > 0) { // Enabled m_ui->checkDownloadLimitAlt->setChecked(true); @@ -899,8 +910,8 @@ void OptionsDialog::loadOptions() m_ui->checkDownloadLimitAlt->setChecked(false); m_ui->spinDownloadLimitAlt->setEnabled(false); } - intValue = pref->getAltGlobalUploadLimit(); - if (intValue != -1) { + intValue = session->altGlobalUploadSpeedLimit(); + if (intValue > 0) { // Enabled m_ui->checkUploadLimitAlt->setChecked(true); m_ui->spinUploadLimitAlt->setEnabled(true); @@ -912,40 +923,39 @@ void OptionsDialog::loadOptions() m_ui->spinUploadLimitAlt->setEnabled(false); } - m_ui->checkuTP->setChecked(pref->isuTPEnabled()); + m_ui->checkuTP->setChecked(session->isUTPEnabled()); m_ui->checkLimituTPConnections->setEnabled(m_ui->checkuTP->isChecked()); - m_ui->checkLimituTPConnections->setChecked(pref->isuTPRateLimited()); - m_ui->checkLimitTransportOverhead->setChecked(pref->includeOverheadInLimits()); - m_ui->checkLimitLocalPeerRate->setChecked(!pref->getIgnoreLimitsOnLAN()); + m_ui->checkLimituTPConnections->setChecked(session->isUTPRateLimited()); + m_ui->checkLimitTransportOverhead->setChecked(session->includeOverheadInLimits()); + m_ui->checkLimitLocalPeerRate->setChecked(!session->ignoreLimitsOnLAN()); - m_ui->check_schedule->setChecked(pref->isSchedulerEnabled()); + m_ui->check_schedule->setChecked(session->isBandwidthSchedulerEnabled()); m_ui->schedule_from->setTime(pref->getSchedulerStartTime()); m_ui->schedule_to->setTime(pref->getSchedulerEndTime()); m_ui->schedule_days->setCurrentIndex((int)pref->getSchedulerDays()); // End Speed preferences // Bittorrent preferences - m_ui->checkDHT->setChecked(pref->isDHTEnabled()); - m_ui->checkPeX->setChecked(pref->isPeXEnabled()); - m_ui->checkLSD->setChecked(pref->isLSDEnabled()); - m_ui->comboEncryption->setCurrentIndex(pref->getEncryptionSetting()); - m_ui->checkAnonymousMode->setChecked(pref->isAnonymousModeEnabled()); - m_ui->checkEnableAddTrackers->setChecked(pref->isAddTrackersEnabled()); - m_ui->textTrackers->setPlainText(pref->getTrackersList()); - - m_ui->checkEnableQueueing->setChecked(pref->isQueueingSystemEnabled()); - m_ui->spinMaxActiveDownloads->setValue(pref->getMaxActiveDownloads()); - m_ui->spinMaxActiveUploads->setValue(pref->getMaxActiveUploads()); - m_ui->spinMaxActiveTorrents->setValue(pref->getMaxActiveTorrents()); - m_ui->checkIgnoreSlowTorrentsForQueueing->setChecked(pref->ignoreSlowTorrentsForQueueing()); - - floatValue = pref->getGlobalMaxRatio(); - if (floatValue >= 0.) { + m_ui->checkDHT->setChecked(session->isDHTEnabled()); + m_ui->checkPeX->setChecked(session->isPeXEnabled()); + m_ui->checkLSD->setChecked(session->isLSDEnabled()); + m_ui->comboEncryption->setCurrentIndex(session->encryption()); + m_ui->checkAnonymousMode->setChecked(session->isAnonymousModeEnabled()); + m_ui->checkEnableAddTrackers->setChecked(session->isAddTrackersEnabled()); + m_ui->textTrackers->setPlainText(session->additionalTrackers()); + + m_ui->checkEnableQueueing->setChecked(session->isQueueingSystemEnabled()); + m_ui->spinMaxActiveDownloads->setValue(session->maxActiveDownloads()); + m_ui->spinMaxActiveUploads->setValue(session->maxActiveUploads()); + m_ui->spinMaxActiveTorrents->setValue(session->maxActiveTorrents()); + m_ui->checkIgnoreSlowTorrentsForQueueing->setChecked(session->ignoreSlowTorrentsForQueueing()); + + if (session->globalMaxRatio() >= 0.) { // Enable m_ui->checkMaxRatio->setChecked(true); m_ui->spinMaxRatio->setEnabled(true); m_ui->comboRatioLimitAct->setEnabled(true); - m_ui->spinMaxRatio->setValue(floatValue); + m_ui->spinMaxRatio->setValue(session->globalMaxRatio()); } else { // Disable @@ -1521,13 +1531,12 @@ void OptionsDialog::on_IpFilterRefreshBtn_clicked() if (m_refreshingIpFilter) return; m_refreshingIpFilter = true; // Updating program preferences - Preferences* const pref = Preferences::instance(); - pref->setFilteringEnabled(true); - pref->setFilter(getFilter()); - // Force refresh - connect(BitTorrent::Session::instance(), SIGNAL(ipFilterParsed(bool, int)), SLOT(handleIPFilterParsed(bool, int))); + BitTorrent::Session *const session = BitTorrent::Session::instance(); + session->setFilteringEnabled(true); + session->setIPFilterFile(""); // forcing Session reload filter file + session->setIPFilterFile(getFilter()); + connect(session, SIGNAL(IPFilterParsed(bool, int)), SLOT(handleIPFilterParsed(bool, int))); setCursor(QCursor(Qt::WaitCursor)); - BitTorrent::Session::instance()->enableIPFilter(getFilter(), true); } void OptionsDialog::handleIPFilterParsed(bool error, int ruleCount) @@ -1538,7 +1547,7 @@ void OptionsDialog::handleIPFilterParsed(bool error, int ruleCount) else QMessageBox::information(this, tr("Successfully refreshed"), tr("Successfully parsed the provided IP filter: %1 rules were applied.", "%1 is a number").arg(ruleCount)); m_refreshingIpFilter = false; - disconnect(BitTorrent::Session::instance(), SIGNAL(ipFilterParsed(bool, int)), this, SLOT(handleIPFilterParsed(bool, int))); + disconnect(BitTorrent::Session::instance(), SIGNAL(IPFilterParsed(bool, int)), this, SLOT(handleIPFilterParsed(bool, int))); } QString OptionsDialog::languageToLocalizedString(const QLocale &locale) diff --git a/src/gui/optionsdlg.h b/src/gui/optionsdlg.h index 672b1ff9e..c1f19a497 100644 --- a/src/gui/optionsdlg.h +++ b/src/gui/optionsdlg.h @@ -47,6 +47,11 @@ enum DoubleClickAction NO_ACTION }; +namespace Net +{ + enum class ProxyType; +} + namespace Ui { class OptionsDialog; @@ -149,7 +154,7 @@ private: unsigned short getProxyPort() const; QString getProxyUsername() const; QString getProxyPassword() const; - int getProxyType() const; + Net::ProxyType getProxyType() const; // IP Filter bool isFilteringEnabled() const; QString getFilter() const; diff --git a/src/gui/properties/trackerlist.cpp b/src/gui/properties/trackerlist.cpp index 9772c38cf..71c2b0175 100644 --- a/src/gui/properties/trackerlist.cpp +++ b/src/gui/properties/trackerlist.cpp @@ -224,7 +224,7 @@ void TrackerList::loadStickyItems(BitTorrent::TorrentHandle *const torrent) { dht_item->setText(COL_STATUS, disabled); // Load PeX Information - if (BitTorrent::Session::instance()->isPexEnabled() && !torrent->isPrivate()) + if (BitTorrent::Session::instance()->isPeXEnabled() && !torrent->isPrivate()) pex_item->setText(COL_STATUS, working); else pex_item->setText(COL_STATUS, disabled); diff --git a/src/gui/statusbar.cpp b/src/gui/statusbar.cpp index 4e4c4ce84..02c65bbf7 100644 --- a/src/gui/statusbar.cpp +++ b/src/gui/statusbar.cpp @@ -43,7 +43,6 @@ #include "base/bittorrent/sessionstatus.h" #include "speedlimitdlg.h" #include "guiiconprovider.h" -#include "base/preferences.h" #include "base/utils/misc.h" #include "base/logger.h" @@ -52,8 +51,8 @@ StatusBar::StatusBar(QStatusBar *bar) { qApp->setStyleSheet("QStatusBar::item { border-width: 0; }"); - Preferences* const pref = Preferences::instance(); - connect(BitTorrent::Session::instance(), SIGNAL(speedLimitModeChanged(bool)), this, SLOT(updateAltSpeedsBtn(bool))); + BitTorrent::Session *const session = BitTorrent::Session::instance(); + connect(session, SIGNAL(speedLimitModeChanged(bool)), this, SLOT(updateAltSpeedsBtn(bool))); m_container = new QWidget(bar); m_layout = new QHBoxLayout(m_container); m_layout->setContentsMargins(0,0,0,0); @@ -91,7 +90,7 @@ StatusBar::StatusBar(QStatusBar *bar) m_altSpeedsBtn->setFlat(true); m_altSpeedsBtn->setFocusPolicy(Qt::NoFocus); m_altSpeedsBtn->setCursor(Qt::PointingHandCursor); - updateAltSpeedsBtn(pref->isAltBandwidthEnabled()); + updateAltSpeedsBtn(session->isAltGlobalSpeedLimitEnabled()); connect(m_altSpeedsBtn, SIGNAL(clicked()), this, SLOT(toggleAlternativeSpeeds())); // Because on some platforms the default icon size is bigger @@ -134,7 +133,7 @@ StatusBar::StatusBar(QStatusBar *bar) m_container->adjustSize(); bar->adjustSize(); // Is DHT enabled - m_DHTLbl->setVisible(pref->isDHTEnabled()); + m_DHTLbl->setVisible(session->isDHTEnabled()); m_refreshTimer = new QTimer(bar); refreshStatusBar(); connect(m_refreshTimer, SIGNAL(timeout()), this, SLOT(refreshStatusBar())); @@ -175,18 +174,18 @@ void StatusBar::stopTimer() void StatusBar::updateConnectionStatus(const BitTorrent::SessionStatus &sessionStatus) { if (!BitTorrent::Session::instance()->isListening()) { - m_connecStatusLblIcon->setIcon(QIcon(QString::fromUtf8(":/icons/skin/disconnected.png"))); - m_connecStatusLblIcon->setToolTip(QString::fromUtf8("") + tr("Connection Status:") + QString::fromUtf8("
") + tr("Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections.")); + m_connecStatusLblIcon->setIcon(QIcon(QLatin1String(":/icons/skin/disconnected.png"))); + m_connecStatusLblIcon->setToolTip(QLatin1String("") + tr("Connection Status:") + QLatin1String("
") + tr("Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections.")); } else { if (sessionStatus.hasIncomingConnections()) { // Connection OK - m_connecStatusLblIcon->setIcon(QIcon(QString::fromUtf8(":/icons/skin/connected.png"))); - m_connecStatusLblIcon->setToolTip(QString::fromUtf8("") + tr("Connection Status:") + QString::fromUtf8("
") + tr("Online")); + m_connecStatusLblIcon->setIcon(QIcon(QLatin1String(":/icons/skin/connected.png"))); + m_connecStatusLblIcon->setToolTip(QLatin1String("") + tr("Connection Status:") + QLatin1String("
") + tr("Online")); } else { - m_connecStatusLblIcon->setIcon(QIcon(QString::fromUtf8(":/icons/skin/firewalled.png"))); - m_connecStatusLblIcon->setToolTip(QString::fromUtf8("") + tr("Connection status:") + QString::fromUtf8("
") + QString::fromUtf8("") + tr("No direct connections. This may indicate network configuration problems.") + QString::fromUtf8("")); + m_connecStatusLblIcon->setIcon(QIcon(QLatin1String(":/icons/skin/firewalled.png"))); + m_connecStatusLblIcon->setToolTip(QLatin1String("") + tr("Connection status:") + QLatin1String("
") + QLatin1String("") + tr("No direct connections. This may indicate network configuration problems.") + QLatin1String("")); } } } @@ -205,14 +204,14 @@ void StatusBar::updateDHTNodesNumber(const BitTorrent::SessionStatus &sessionSta void StatusBar::updateSpeedLabels(const BitTorrent::SessionStatus &sessionStatus) { QString speedLbl = Utils::Misc::friendlyUnit(sessionStatus.payloadDownloadRate(), true); - int speedLimit = BitTorrent::Session::instance()->downloadRateLimit(); - if (speedLimit) + int speedLimit = BitTorrent::Session::instance()->downloadSpeedLimit(); + if (speedLimit >= 0) speedLbl += " [" + Utils::Misc::friendlyUnit(speedLimit, true) + "]"; speedLbl += " (" + Utils::Misc::friendlyUnit(sessionStatus.totalPayloadDownload()) + ")"; m_dlSpeedLbl->setText(speedLbl); - speedLimit = BitTorrent::Session::instance()->uploadRateLimit(); + speedLimit = BitTorrent::Session::instance()->uploadSpeedLimit(); speedLbl = Utils::Misc::friendlyUnit(sessionStatus.payloadUploadRate(), true); - if (speedLimit) + if (speedLimit >= 0) speedLbl += " [" + Utils::Misc::friendlyUnit(speedLimit, true) + "]"; speedLbl += " (" + Utils::Misc::friendlyUnit(sessionStatus.totalPayloadUpload()) + ")"; m_upSpeedLbl->setText(speedLbl); @@ -243,35 +242,26 @@ void StatusBar::updateAltSpeedsBtn(bool alternative) void StatusBar::toggleAlternativeSpeeds() { - Preferences* const pref = Preferences::instance(); - if (pref->isSchedulerEnabled()) + BitTorrent::Session *const session = BitTorrent::Session::instance(); + if (session->isBandwidthSchedulerEnabled()) m_bar->showMessage(tr("Manual change of rate limits mode. The scheduler is disabled."), 5000); - BitTorrent::Session::instance()->changeSpeedLimitMode(!pref->isAltBandwidthEnabled()); + session->setAltGlobalSpeedLimitEnabled(!session->isAltGlobalSpeedLimitEnabled()); } void StatusBar::capDownloadSpeed() { + BitTorrent::Session *const session = BitTorrent::Session::instance(); bool ok = false; - int curLimit = BitTorrent::Session::instance()->downloadRateLimit(); - long newLimit = SpeedLimitDialog::askSpeedLimit(&ok, tr("Global Download Speed Limit"), curLimit); + long newLimit = SpeedLimitDialog::askSpeedLimit( + &ok, tr("Global Download Speed Limit"), session->downloadSpeedLimit()); if (ok) { - Preferences* const pref = Preferences::instance(); - bool alt = pref->isAltBandwidthEnabled(); if (newLimit <= 0) { qDebug("Setting global download rate limit to Unlimited"); - BitTorrent::Session::instance()->setDownloadRateLimit(-1); - if (!alt) - pref->setGlobalDownloadLimit(-1); - else - pref->setAltGlobalDownloadLimit(-1); + session->setDownloadSpeedLimit(-1); } else { qDebug("Setting global download rate limit to %.1fKb/s", newLimit / 1024.); - BitTorrent::Session::instance()->setDownloadRateLimit(newLimit); - if (!alt) - pref->setGlobalDownloadLimit(newLimit / 1024.); - else - pref->setAltGlobalDownloadLimit(newLimit / 1024.); + session->setDownloadSpeedLimit(newLimit); } refreshStatusBar(); } @@ -279,27 +269,18 @@ void StatusBar::capDownloadSpeed() void StatusBar::capUploadSpeed() { + BitTorrent::Session *const session = BitTorrent::Session::instance(); bool ok = false; - int curLimit = BitTorrent::Session::instance()->uploadRateLimit(); - long newLimit = SpeedLimitDialog::askSpeedLimit(&ok, tr("Global Upload Speed Limit"), curLimit); + long newLimit = SpeedLimitDialog::askSpeedLimit( + &ok, tr("Global Upload Speed Limit"), session->uploadSpeedLimit()); if (ok) { - Preferences* const pref = Preferences::instance(); - bool alt = pref->isAltBandwidthEnabled(); if (newLimit <= 0) { qDebug("Setting global upload rate limit to Unlimited"); - BitTorrent::Session::instance()->setUploadRateLimit(-1); - if (!alt) - Preferences::instance()->setGlobalUploadLimit(-1); - else - Preferences::instance()->setAltGlobalUploadLimit(-1); + session->setUploadSpeedLimit(-1); } else { qDebug("Setting global upload rate limit to %.1fKb/s", newLimit / 1024.); - BitTorrent::Session::instance()->setUploadRateLimit(newLimit); - if (!alt) - Preferences::instance()->setGlobalUploadLimit(newLimit / 1024.); - else - Preferences::instance()->setAltGlobalUploadLimit(newLimit / 1024.); + session->setUploadSpeedLimit(newLimit); } refreshStatusBar(); } diff --git a/src/gui/transferlistwidget.cpp b/src/gui/transferlistwidget.cpp index 92287c9de..63b111fb5 100644 --- a/src/gui/transferlistwidget.cpp +++ b/src/gui/transferlistwidget.cpp @@ -437,7 +437,9 @@ void TransferListWidget::setDlLimitSelectedTorrents() int default_limit = -1; if (all_same_limit) default_limit = selected_torrents.first()->downloadLimit(); - const long new_limit = SpeedLimitDialog::askSpeedLimit(&ok, tr("Torrent Download Speed Limiting"), default_limit, Preferences::instance()->getGlobalDownloadLimit() * 1024.); + const long new_limit = SpeedLimitDialog::askSpeedLimit( + &ok, tr("Torrent Download Speed Limiting"), default_limit + , BitTorrent::Session::instance()->globalDownloadSpeedLimit()); if (ok) { foreach (BitTorrent::TorrentHandle *const torrent, selected_torrents) { qDebug("Applying download speed limit of %ld Kb/s to torrent %s", (long)(new_limit / 1024.), qPrintable(torrent->hash())); @@ -466,7 +468,9 @@ void TransferListWidget::setUpLimitSelectedTorrents() int default_limit = -1; if (all_same_limit) default_limit = selected_torrents.first()->uploadLimit(); - const long new_limit = SpeedLimitDialog::askSpeedLimit(&ok, tr("Torrent Upload Speed Limiting"), default_limit, Preferences::instance()->getGlobalUploadLimit() * 1024.); + const long new_limit = SpeedLimitDialog::askSpeedLimit( + &ok, tr("Torrent Upload Speed Limiting"), default_limit + , BitTorrent::Session::instance()->globalUploadSpeedLimit()); if (ok) { foreach (BitTorrent::TorrentHandle *const torrent, selected_torrents) { qDebug("Applying upload speed limit of %ld Kb/s to torrent %s", (long)(new_limit / 1024.), qPrintable(torrent->hash())); @@ -512,7 +516,7 @@ void TransferListWidget::displayDLHoSMenu(const QPoint&) hideshowColumn.setTitle(tr("Column visibility")); QList actions; for (int i = 0; i < listModel->columnCount(); ++i) { - if (!BitTorrent::Session::instance()->isQueueingEnabled() && i == TorrentModel::TR_PRIORITY) { + if (!BitTorrent::Session::instance()->isQueueingSystemEnabled() && i == TorrentModel::TR_PRIORITY) { actions.append(0); continue; } @@ -827,7 +831,7 @@ void TransferListWidget::displayListMenu(const QPoint&) listMenu.addSeparator(); } listMenu.addAction(&actionOpen_destination_folder); - if (BitTorrent::Session::instance()->isQueueingEnabled() && one_not_seed) { + if (BitTorrent::Session::instance()->isQueueingSystemEnabled() && one_not_seed) { listMenu.addSeparator(); QMenu *prioMenu = listMenu.addMenu(tr("Priority")); prioMenu->addAction(&actionTopPriority); diff --git a/src/gui/updownratiodlg.cpp b/src/gui/updownratiodlg.cpp index d6c753e01..5d9400b19 100644 --- a/src/gui/updownratiodlg.cpp +++ b/src/gui/updownratiodlg.cpp @@ -1,5 +1,5 @@ /* - * Bittorrent Client using Qt4 and libtorrent. + * Bittorrent Client using Qt and libtorrent. * Copyright (C) 2011 Christian Kandeler, Christophe Dumez * * This program is free software; you can redistribute it and/or @@ -29,28 +29,32 @@ */ #include "updownratiodlg.h" -#include "ui_updownratiodlg.h" -#include "base/preferences.h" +#include "base/bittorrent/session.h" +#include "ui_updownratiodlg.h" UpDownRatioDlg::UpDownRatioDlg(bool useDefault, qreal initialValue, - qreal maxValue, QWidget *parent) - : QDialog(parent), ui(new Ui::UpDownRatioDlg) + qreal maxValue, QWidget *parent) + : QDialog(parent) + , ui(new Ui::UpDownRatioDlg) { ui->setupUi(this); + if (useDefault) { ui->useDefaultButton->setChecked(true); - } else if (initialValue == -1) { + } + else if (initialValue == -1) { ui->noLimitButton->setChecked(true); - initialValue = Preferences::instance()->getGlobalMaxRatio(); - } else { + initialValue = BitTorrent::Session::instance()->globalMaxRatio(); + } + else { ui->torrentLimitButton->setChecked(true); } + ui->ratioSpinBox->setMinimum(0); ui->ratioSpinBox->setMaximum(maxValue); ui->ratioSpinBox->setValue(initialValue); - connect(ui->buttonGroup, SIGNAL(buttonClicked(int)), - SLOT(handleRatioTypeChanged())); + connect(ui->buttonGroup, SIGNAL(buttonClicked(int)), SLOT(handleRatioTypeChanged())); handleRatioTypeChanged(); } diff --git a/src/webui/btjson.cpp b/src/webui/btjson.cpp index 495c208ff..960e8a3be 100644 --- a/src/webui/btjson.cpp +++ b/src/webui/btjson.cpp @@ -364,7 +364,9 @@ QByteArray btjson::getSyncMainData(int acceptedResponseId, QVariantMap &lastData QVariantMap data; QVariantHash torrents; - foreach (BitTorrent::TorrentHandle *const torrent, BitTorrent::Session::instance()->torrents()) { + BitTorrent::Session *const session = BitTorrent::Session::instance(); + + foreach (BitTorrent::TorrentHandle *const torrent, session->torrents()) { QVariantMap map = toMap(torrent); map.remove(KEY_TORRENT_HASH); torrents[torrent->hash()] = map; @@ -373,15 +375,15 @@ QByteArray btjson::getSyncMainData(int acceptedResponseId, QVariantMap &lastData data["torrents"] = torrents; QVariantList categories; - foreach (const QString &category, BitTorrent::Session::instance()->categories()) + foreach (const QString &category, session->categories()) categories << category; data["categories"] = categories; QVariantMap serverState = getTranserInfoMap(); - serverState[KEY_SYNC_MAINDATA_QUEUEING] = BitTorrent::Session::instance()->isQueueingEnabled(); - serverState[KEY_SYNC_MAINDATA_USE_ALT_SPEED_LIMITS] = Preferences::instance()->isAltBandwidthEnabled(); - serverState[KEY_SYNC_MAINDATA_REFRESH_INTERVAL] = Preferences::instance()->getRefreshInterval(); + serverState[KEY_SYNC_MAINDATA_QUEUEING] = session->isQueueingSystemEnabled(); + serverState[KEY_SYNC_MAINDATA_USE_ALT_SPEED_LIMITS] = session->isAltGlobalSpeedLimitEnabled(); + serverState[KEY_SYNC_MAINDATA_REFRESH_INTERVAL] = session->refreshInterval(); data["server_state"] = serverState; return json::toJson(generateSyncData(acceptedResponseId, data, lastAcceptedData, lastData)); @@ -669,8 +671,8 @@ QVariantMap getTranserInfoMap() map[KEY_TRANSFER_DLDATA] = sessionStatus.totalPayloadDownload(); map[KEY_TRANSFER_UPSPEED] = sessionStatus.payloadUploadRate(); map[KEY_TRANSFER_UPDATA] = sessionStatus.totalPayloadUpload(); - map[KEY_TRANSFER_DLRATELIMIT] = BitTorrent::Session::instance()->downloadRateLimit(); - map[KEY_TRANSFER_UPRATELIMIT] = BitTorrent::Session::instance()->uploadRateLimit(); + map[KEY_TRANSFER_DLRATELIMIT] = BitTorrent::Session::instance()->downloadSpeedLimit(); + map[KEY_TRANSFER_UPRATELIMIT] = BitTorrent::Session::instance()->uploadSpeedLimit(); map[KEY_TRANSFER_DHT_NODES] = sessionStatus.dhtNodes(); if (!BitTorrent::Session::instance()->isListening()) map[KEY_TRANSFER_CONNECTION_STATUS] = "disconnected"; diff --git a/src/webui/prefjson.cpp b/src/webui/prefjson.cpp index 7f456fca4..875b526cf 100644 --- a/src/webui/prefjson.cpp +++ b/src/webui/prefjson.cpp @@ -28,20 +28,22 @@ * Contact : chris@qbittorrent.org */ +#include "prefjson.h" + +#include #ifndef QT_NO_OPENSSL #include #include #endif #include #include -#include +#include "base/bittorrent/session.h" +#include "base/net/proxyconfigurationmanager.h" #include "base/preferences.h" #include "base/scanfoldersmodel.h" #include "base/utils/fs.h" -#include "base/bittorrent/session.h" #include "jsonutils.h" -#include "prefjson.h" prefjson::prefjson() { @@ -58,8 +60,8 @@ QByteArray prefjson::getPreferences() data["save_path"] = Utils::Fs::toNativePath(session->defaultSavePath()); data["temp_path_enabled"] = session->isTempPathEnabled(); data["temp_path"] = Utils::Fs::toNativePath(session->tempPath()); - data["preallocate_all"] = pref->preAllocateAllFiles(); - data["incomplete_files_ext"] = pref->useIncompleteFilesExtension(); + data["preallocate_all"] = session->isPreallocationEnabled(); + data["incomplete_files_ext"] = session->isAppendExtensionEnabled(); QVariantHash dirs = pref->getScanDirs(); QVariantMap nativeDirs; for (QVariantHash::const_iterator i = dirs.begin(), e = dirs.end(); i != e; ++i) { @@ -69,8 +71,8 @@ QByteArray prefjson::getPreferences() nativeDirs.insert(Utils::Fs::toNativePath(i.key()), Utils::Fs::toNativePath(i.value().toString())); } data["scan_dirs"] = nativeDirs; - data["export_dir"] = Utils::Fs::toNativePath(pref->getTorrentExportDir()); - data["export_dir_fin"] = Utils::Fs::toNativePath(pref->getFinishedTorrentExportDir()); + data["export_dir"] = Utils::Fs::toNativePath(session->torrentExportDirectory()); + data["export_dir_fin"] = Utils::Fs::toNativePath(session->finishedTorrentExportDirectory()); // Email notification upon download completion data["mail_notification_enabled"] = pref->isMailNotificationEnabled(); data["mail_notification_email"] = pref->getMailNotificationEmail(); @@ -85,39 +87,44 @@ QByteArray prefjson::getPreferences() // Connection // Listening Port - data["listen_port"] = pref->getSessionPort(); + data["listen_port"] = session->port(); data["upnp"] = pref->isUPnPEnabled(); - data["random_port"] = pref->useRandomPort(); + data["random_port"] = session->useRandomPort(); // Connections Limits - data["max_connec"] = pref->getMaxConnecs(); - data["max_connec_per_torrent"] = pref->getMaxConnecsPerTorrent(); - data["max_uploads"] = pref->getMaxUploads(); - data["max_uploads_per_torrent"] = pref->getMaxUploadsPerTorrent(); + data["max_connec"] = session->maxConnections(); + data["max_connec_per_torrent"] = session->maxConnectionsPerTorrent(); + data["max_uploads"] = session->maxUploads(); + data["max_uploads_per_torrent"] = session->maxUploadsPerTorrent(); + // Proxy Server - data["proxy_type"] = pref->getProxyType(); - data["proxy_ip"] = pref->getProxyIp(); - data["proxy_port"] = pref->getProxyPort(); - data["proxy_peer_connections"] = pref->proxyPeerConnections(); - data["force_proxy"] = pref->getForceProxy(); - data["proxy_auth_enabled"] = pref->isProxyAuthEnabled(); - data["proxy_username"] = pref->getProxyUsername(); - data["proxy_password"] = pref->getProxyPassword(); + auto proxyManager = Net::ProxyConfigurationManager::instance(); + Net::ProxyConfiguration proxyConf = proxyManager->proxyConfiguration(); + data["proxy_type"] = static_cast(proxyConf.type); + data["proxy_ip"] = proxyConf.ip; + data["proxy_port"] = proxyConf.port; + data["proxy_auth_enabled"] = proxyManager->isAuthenticationRequired(); // deprecated + data["proxy_username"] = proxyConf.username; + data["proxy_password"] = proxyConf.password; + + data["proxy_peer_connections"] = session->isProxyPeerConnectionsEnabled(); + data["force_proxy"] = session->isForceProxyEnabled(); + // IP Filtering - data["ip_filter_enabled"] = pref->isFilteringEnabled(); - data["ip_filter_path"] = Utils::Fs::toNativePath(pref->getFilter()); - data["ip_filter_trackers"] = pref->isFilteringTrackerEnabled(); + data["ip_filter_enabled"] = session->isFilteringEnabled(); + data["ip_filter_path"] = Utils::Fs::toNativePath(session->IPFilterFile()); + data["ip_filter_trackers"] = session->isTrackerFilteringEnabled(); // Speed // Global Rate Limits - data["dl_limit"] = pref->getGlobalDownloadLimit(); - data["up_limit"] = pref->getGlobalUploadLimit(); - data["enable_utp"] = pref->isuTPEnabled(); - data["limit_utp_rate"] = pref->isuTPRateLimited(); - data["limit_tcp_overhead"] = pref->includeOverheadInLimits(); - data["alt_dl_limit"] = pref->getAltGlobalDownloadLimit(); - data["alt_up_limit"] = pref->getAltGlobalUploadLimit(); + data["dl_limit"] = session->globalDownloadSpeedLimit(); + data["up_limit"] = session->globalUploadSpeedLimit(); + data["enable_utp"] = session->isUTPEnabled(); + data["limit_utp_rate"] = session->isUTPRateLimited(); + data["limit_tcp_overhead"] = session->includeOverheadInLimits(); + data["alt_dl_limit"] = session->altGlobalDownloadSpeedLimit(); + data["alt_up_limit"] = session->altGlobalUploadSpeedLimit(); // Scheduling - data["scheduler_enabled"] = pref->isSchedulerEnabled(); + data["scheduler_enabled"] = session->isBandwidthSchedulerEnabled(); const QTime start_time = pref->getSchedulerStartTime(); data["schedule_from_hour"] = start_time.hour(); data["schedule_from_min"] = start_time.minute(); @@ -128,24 +135,24 @@ QByteArray prefjson::getPreferences() // Bittorrent // Privacy - data["dht"] = pref->isDHTEnabled(); - data["pex"] = pref->isPeXEnabled(); - data["lsd"] = pref->isLSDEnabled(); - data["encryption"] = pref->getEncryptionSetting(); - data["anonymous_mode"] = pref->isAnonymousModeEnabled(); + data["dht"] = session->isDHTEnabled(); + data["pex"] = session->isPeXEnabled(); + data["lsd"] = session->isLSDEnabled(); + data["encryption"] = session->encryption(); + data["anonymous_mode"] = session->isAnonymousModeEnabled(); // Torrent Queueing - data["queueing_enabled"] = pref->isQueueingSystemEnabled(); - data["max_active_downloads"] = pref->getMaxActiveDownloads(); - data["max_active_torrents"] = pref->getMaxActiveTorrents(); - data["max_active_uploads"] = pref->getMaxActiveUploads(); - data["dont_count_slow_torrents"] = pref->ignoreSlowTorrentsForQueueing(); + data["queueing_enabled"] = session->isQueueingSystemEnabled(); + data["max_active_downloads"] = session->maxActiveDownloads(); + data["max_active_torrents"] = session->maxActiveTorrents(); + data["max_active_uploads"] = session->maxActiveUploads(); + data["dont_count_slow_torrents"] = session->ignoreSlowTorrentsForQueueing(); // Share Ratio Limiting - data["max_ratio_enabled"] = (pref->getGlobalMaxRatio() >= 0.); - data["max_ratio"] = pref->getGlobalMaxRatio(); - data["max_ratio_act"] = BitTorrent::Session::instance()->maxRatioAction(); + data["max_ratio_enabled"] = (session->globalMaxRatio() >= 0.); + data["max_ratio"] = session->globalMaxRatio(); + data["max_ratio_act"] = session->maxRatioAction(); // Add trackers - data["add_trackers_enabled"] = pref->isAddTrackersEnabled(); - data["add_trackers"] = pref->getTrackersList(); + data["add_trackers_enabled"] = session->isAddTrackersEnabled(); + data["add_trackers"] = session->additionalTrackers(); // Web UI // Language @@ -185,9 +192,9 @@ void prefjson::setPreferences(const QString& json) if (m.contains("temp_path")) session->setTempPath(m["temp_path"].toString()); if (m.contains("preallocate_all")) - pref->preAllocateAllFiles(m["preallocate_all"].toBool()); + session->setPreallocationEnabled(m["preallocate_all"].toBool()); if (m.contains("incomplete_files_ext")) - pref->useIncompleteFilesExtension(m["incomplete_files_ext"].toBool()); + session->setAppendExtensionEnabled(m["incomplete_files_ext"].toBool()); if (m.contains("scan_dirs")) { QVariantMap nativeDirs = m["scan_dirs"].toMap(); QVariantHash oldScanDirs = pref->getScanDirs(); @@ -232,9 +239,9 @@ void prefjson::setPreferences(const QString& json) pref->setScanDirs(scanDirs); } if (m.contains("export_dir")) - pref->setTorrentExportDir(m["export_dir"].toString()); + session->setTorrentExportDirectory(m["export_dir"].toString()); if (m.contains("export_dir_fin")) - pref->setFinishedTorrentExportDir(m["export_dir_fin"].toString()); + session->setFinishedTorrentExportDirectory(m["export_dir_fin"].toString()); // Email notification upon download completion if (m.contains("mail_notification_enabled")) pref->setMailNotificationEnabled(m["mail_notification_enabled"].toBool()); @@ -259,109 +266,108 @@ void prefjson::setPreferences(const QString& json) // Connection // Listening Port if (m.contains("listen_port")) - pref->setSessionPort(m["listen_port"].toInt()); + session->setPort(m["listen_port"].toInt()); if (m.contains("upnp")) pref->setUPnPEnabled(m["upnp"].toBool()); if (m.contains("random_port")) - pref->setRandomPort(m["random_port"].toBool()); + session->setUseRandomPort(m["random_port"].toBool()); // Connections Limits if (m.contains("max_connec")) - pref->setMaxConnecs(m["max_connec"].toInt()); + session->setMaxConnections(m["max_connec"].toInt()); if (m.contains("max_connec_per_torrent")) - pref->setMaxConnecsPerTorrent(m["max_connec_per_torrent"].toInt()); + session->setMaxConnectionsPerTorrent(m["max_connec_per_torrent"].toInt()); if (m.contains("max_uploads")) - pref->setMaxUploads(m["max_uploads"].toInt()); + session->setMaxUploads(m["max_uploads"].toInt()); if (m.contains("max_uploads_per_torrent")) - pref->setMaxUploadsPerTorrent(m["max_uploads_per_torrent"].toInt()); + session->setMaxUploadsPerTorrent(m["max_uploads_per_torrent"].toInt()); + // Proxy Server + auto proxyManager = Net::ProxyConfigurationManager::instance(); + Net::ProxyConfiguration proxyConf = proxyManager->proxyConfiguration(); if (m.contains("proxy_type")) - pref->setProxyType(m["proxy_type"].toInt()); + proxyConf.type = static_cast(m["proxy_type"].toInt()); if (m.contains("proxy_ip")) - pref->setProxyIp(m["proxy_ip"].toString()); + proxyConf.ip = m["proxy_ip"].toString(); if (m.contains("proxy_port")) - pref->setProxyPort(m["proxy_port"].toUInt()); - if (m.contains("proxy_peer_connections")) - pref->setProxyPeerConnections(m["proxy_peer_connections"].toBool()); - if (m.contains("force_proxy")) - pref->setForceProxy(m["force_proxy"].toBool()); - if (m.contains("proxy_auth_enabled")) - pref->setProxyAuthEnabled(m["proxy_auth_enabled"].toBool()); + proxyConf.port = m["proxy_port"].toUInt(); if (m.contains("proxy_username")) - pref->setProxyUsername(m["proxy_username"].toString()); + proxyConf.username = m["proxy_username"].toString(); if (m.contains("proxy_password")) - pref->setProxyPassword(m["proxy_password"].toString()); + proxyConf.password = m["proxy_password"].toString(); + proxyManager->setProxyConfiguration(proxyConf); + + if (m.contains("proxy_peer_connections")) + session->setProxyPeerConnectionsEnabled(m["proxy_peer_connections"].toBool()); + if (m.contains("force_proxy")) + session->setForceProxyEnabled(m["force_proxy"].toBool()); + // IP Filtering if (m.contains("ip_filter_enabled")) - pref->setFilteringEnabled(m["ip_filter_enabled"].toBool()); + session->setFilteringEnabled(m["ip_filter_enabled"].toBool()); if (m.contains("ip_filter_path")) - pref->setFilter(m["ip_filter_path"].toString()); + session->setIPFilterFile(m["ip_filter_path"].toString()); if (m.contains("ip_filter_trackers")) - pref->setFilteringTrackerEnabled(m["ip_filter_trackers"].toBool()); + session->setTrackerFilteringEnabled(m["ip_filter_trackers"].toBool()); // Speed // Global Rate Limits if (m.contains("dl_limit")) - pref->setGlobalDownloadLimit(m["dl_limit"].toInt()); + session->setGlobalDownloadSpeedLimit(m["dl_limit"].toInt()); if (m.contains("up_limit")) - pref->setGlobalUploadLimit(m["up_limit"].toInt()); + session->setGlobalUploadSpeedLimit(m["up_limit"].toInt()); if (m.contains("enable_utp")) - pref->setuTPEnabled(m["enable_utp"].toBool()); + session->setUTPEnabled(m["enable_utp"].toBool()); if (m.contains("limit_utp_rate")) - pref->setuTPRateLimited(m["limit_utp_rate"].toBool()); + session->setUTPRateLimited(m["limit_utp_rate"].toBool()); if (m.contains("limit_tcp_overhead")) - pref->includeOverheadInLimits(m["limit_tcp_overhead"].toBool()); + session->setIncludeOverheadInLimits(m["limit_tcp_overhead"].toBool()); if (m.contains("alt_dl_limit")) - pref->setAltGlobalDownloadLimit(m["alt_dl_limit"].toInt()); + session->setAltGlobalDownloadSpeedLimit(m["alt_dl_limit"].toInt()); if (m.contains("alt_up_limit")) - pref->setAltGlobalUploadLimit(m["alt_up_limit"].toInt()); + session->setAltGlobalUploadSpeedLimit(m["alt_up_limit"].toInt()); // Scheduling if (m.contains("scheduler_enabled")) - pref->setSchedulerEnabled(m["scheduler_enabled"].toBool()); - if (m.contains("schedule_from_hour") && m.contains("schedule_from_min")) { - pref->setSchedulerStartTime(QTime(m["schedule_from_hour"].toInt(), - m["schedule_from_min"].toInt())); - } - if (m.contains("schedule_to_hour") && m.contains("schedule_to_min")) { - pref->setSchedulerEndTime(QTime(m["schedule_to_hour"].toInt(), - m["schedule_to_min"].toInt())); - } + session->setBandwidthSchedulerEnabled(m["scheduler_enabled"].toBool()); + if (m.contains("schedule_from_hour") && m.contains("schedule_from_min")) + pref->setSchedulerStartTime(QTime(m["schedule_from_hour"].toInt(), m["schedule_from_min"].toInt())); + if (m.contains("schedule_to_hour") && m.contains("schedule_to_min")) + pref->setSchedulerEndTime(QTime(m["schedule_to_hour"].toInt(), m["schedule_to_min"].toInt())); if (m.contains("scheduler_days")) pref->setSchedulerDays(scheduler_days(m["scheduler_days"].toInt())); // Bittorrent // Privacy if (m.contains("dht")) - pref->setDHTEnabled(m["dht"].toBool()); + session->setDHTEnabled(m["dht"].toBool()); if (m.contains("pex")) - pref->setPeXEnabled(m["pex"].toBool()); + session->setPeXEnabled(m["pex"].toBool()); if (m.contains("lsd")) - pref->setLSDEnabled(m["lsd"].toBool()); + session->setLSDEnabled(m["lsd"].toBool()); if (m.contains("encryption")) - pref->setEncryptionSetting(m["encryption"].toInt()); + session->setEncryption(m["encryption"].toInt()); if (m.contains("anonymous_mode")) - pref->enableAnonymousMode(m["anonymous_mode"].toBool()); + session->setAnonymousModeEnabled(m["anonymous_mode"].toBool()); // Torrent Queueing if (m.contains("queueing_enabled")) - pref->setQueueingSystemEnabled(m["queueing_enabled"].toBool()); + session->setQueueingSystemEnabled(m["queueing_enabled"].toBool()); if (m.contains("max_active_downloads")) - pref->setMaxActiveDownloads(m["max_active_downloads"].toInt()); + session->setMaxActiveDownloads(m["max_active_downloads"].toInt()); if (m.contains("max_active_torrents")) - pref->setMaxActiveTorrents(m["max_active_torrents"].toInt()); + session->setMaxActiveTorrents(m["max_active_torrents"].toInt()); if (m.contains("max_active_uploads")) - pref->setMaxActiveUploads(m["max_active_uploads"].toInt()); + session->setMaxActiveUploads(m["max_active_uploads"].toInt()); if (m.contains("dont_count_slow_torrents")) - pref->setIgnoreSlowTorrentsForQueueing(m["dont_count_slow_torrents"].toBool()); + session->setIgnoreSlowTorrentsForQueueing(m["dont_count_slow_torrents"].toBool()); // Share Ratio Limiting if (m.contains("max_ratio_enabled")) - pref->setGlobalMaxRatio(m["max_ratio"].toReal()); + session->setGlobalMaxRatio(m["max_ratio"].toReal()); else - pref->setGlobalMaxRatio(-1); + session->setGlobalMaxRatio(-1); if (m.contains("max_ratio_act")) - BitTorrent::Session::instance()->setMaxRatioAction( - static_cast(m["max_ratio_act"].toInt())); + session->setMaxRatioAction(static_cast(m["max_ratio_act"].toInt())); // Add trackers - pref->setAddTrackersEnabled(m["add_trackers_enabled"].toBool()); - pref->setTrackersList(m["add_trackers"].toString()); + session->setAddTrackersEnabled(m["add_trackers_enabled"].toBool()); + session->setAdditionalTrackers(m["add_trackers"].toString()); // Web UI // Language diff --git a/src/webui/webapplication.cpp b/src/webui/webapplication.cpp index 82e4ec006..889227358 100644 --- a/src/webui/webapplication.cpp +++ b/src/webui/webapplication.cpp @@ -518,13 +518,13 @@ void WebApplication::action_command_setFilePrio() void WebApplication::action_command_getGlobalUpLimit() { CHECK_URI(0); - print(QByteArray::number(BitTorrent::Session::instance()->uploadRateLimit()), Http::CONTENT_TYPE_TXT); + print(QByteArray::number(BitTorrent::Session::instance()->uploadSpeedLimit()), Http::CONTENT_TYPE_TXT); } void WebApplication::action_command_getGlobalDlLimit() { CHECK_URI(0); - print(QByteArray::number(BitTorrent::Session::instance()->downloadRateLimit()), Http::CONTENT_TYPE_TXT); + print(QByteArray::number(BitTorrent::Session::instance()->downloadSpeedLimit()), Http::CONTENT_TYPE_TXT); } void WebApplication::action_command_setGlobalUpLimit() @@ -534,11 +534,7 @@ void WebApplication::action_command_setGlobalUpLimit() qlonglong limit = request().posts["limit"].toLongLong(); if (limit == 0) limit = -1; - BitTorrent::Session::instance()->setUploadRateLimit(limit); - if (Preferences::instance()->isAltBandwidthEnabled()) - Preferences::instance()->setAltGlobalUploadLimit(limit / 1024.); - else - Preferences::instance()->setGlobalUploadLimit(limit / 1024.); + BitTorrent::Session::instance()->setUploadSpeedLimit(limit); } void WebApplication::action_command_setGlobalDlLimit() @@ -548,11 +544,7 @@ void WebApplication::action_command_setGlobalDlLimit() qlonglong limit = request().posts["limit"].toLongLong(); if (limit == 0) limit = -1; - BitTorrent::Session::instance()->setDownloadRateLimit(limit); - if (Preferences::instance()->isAltBandwidthEnabled()) - Preferences::instance()->setAltGlobalDownloadLimit(limit / 1024.); - else - Preferences::instance()->setGlobalDownloadLimit(limit / 1024.); + BitTorrent::Session::instance()->setDownloadSpeedLimit(limit); } void WebApplication::action_command_getTorrentsUpLimit() @@ -608,13 +600,15 @@ void WebApplication::action_command_setTorrentsDlLimit() void WebApplication::action_command_toggleAlternativeSpeedLimits() { CHECK_URI(0); - BitTorrent::Session::instance()->changeSpeedLimitMode(!Preferences::instance()->isAltBandwidthEnabled()); + BitTorrent::Session *const session = BitTorrent::Session::instance(); + session->setAltGlobalSpeedLimitEnabled(!session->isAltGlobalSpeedLimitEnabled()); } void WebApplication::action_command_alternativeSpeedLimitsEnabled() { CHECK_URI(0); - print(QByteArray::number(Preferences::instance()->isAltBandwidthEnabled()), Http::CONTENT_TYPE_TXT); + print(QByteArray::number(BitTorrent::Session::instance()->isAltGlobalSpeedLimitEnabled()) + , Http::CONTENT_TYPE_TXT); } void WebApplication::action_command_toggleSequentialDownload() @@ -690,7 +684,7 @@ void WebApplication::action_command_increasePrio() CHECK_URI(0); CHECK_PARAMETERS("hashes"); - if (!Preferences::instance()->isQueueingSystemEnabled()) { + if (!BitTorrent::Session::instance()->isQueueingSystemEnabled()) { status(403, "Torrent queueing must be enabled"); return; } @@ -704,7 +698,7 @@ void WebApplication::action_command_decreasePrio() CHECK_URI(0); CHECK_PARAMETERS("hashes"); - if (!Preferences::instance()->isQueueingSystemEnabled()) { + if (!BitTorrent::Session::instance()->isQueueingSystemEnabled()) { status(403, "Torrent queueing must be enabled"); return; } @@ -718,7 +712,7 @@ void WebApplication::action_command_topPrio() CHECK_URI(0); CHECK_PARAMETERS("hashes"); - if (!Preferences::instance()->isQueueingSystemEnabled()) { + if (!BitTorrent::Session::instance()->isQueueingSystemEnabled()) { status(403, "Torrent queueing must be enabled"); return; } @@ -732,7 +726,7 @@ void WebApplication::action_command_bottomPrio() CHECK_URI(0); CHECK_PARAMETERS("hashes"); - if (!Preferences::instance()->isQueueingSystemEnabled()) { + if (!BitTorrent::Session::instance()->isQueueingSystemEnabled()) { status(403, "Torrent queueing must be enabled"); return; }