diff --git a/src/app/upgrade.cpp b/src/app/upgrade.cpp index 5a9d9b896..ee10916be 100644 --- a/src/app/upgrade.cpp +++ b/src/app/upgrade.cpp @@ -46,7 +46,7 @@ namespace { - const int MIGRATION_VERSION = 8; + const int MIGRATION_VERSION = 9; const QString MIGRATION_VERSION_KEY = u"Meta/MigrationVersion"_s; void exportWebUIHttpsFiles() @@ -283,7 +283,8 @@ namespace {u"BitTorrent/Session/MaxActiveTorrents"_s, u"Preferences/Queueing/MaxActiveTorrents"_s}, {u"BitTorrent/Session/MaxActiveUploads"_s, u"Preferences/Queueing/MaxActiveUploads"_s}, {u"BitTorrent/Session/MaxConnections"_s, u"Preferences/Bittorrent/MaxConnecs"_s}, - {u"BitTorrent/Session/MaxConnectionsPerTorrent"_s, u"Preferences/Bittorrent/MaxConnecsPerTorrent"_s}, + {u"BitTorrent/Session/MaxConnectionsPerDownloadingTorrent"_s, u"Preferences/Bittorrent/MaxConnecsPerTorrent"_s}, + {u"BitTorrent/Session/MaxConnectionsPerDownloadingTorrent"_s, u"BitTorrent/Session/MaxConnectionsPerTorrent"_s}, {u"BitTorrent/Session/MaxHalfOpenConnections"_s, u"Preferences/Connection/MaxHalfOpenConnec"_s}, {u"BitTorrent/Session/MaxRatioAction"_s, u"Preferences/Bittorrent/MaxRatioAction"_s}, {u"BitTorrent/Session/MaxUploads"_s, u"Preferences/Bittorrent/MaxUploads"_s}, diff --git a/src/base/bittorrent/session.h b/src/base/bittorrent/session.h index cae03ba83..fcb746154 100644 --- a/src/base/bittorrent/session.h +++ b/src/base/bittorrent/session.h @@ -404,8 +404,10 @@ namespace BitTorrent virtual void setStopTrackerTimeout(int value) = 0; virtual int maxConnections() const = 0; virtual void setMaxConnections(int max) = 0; - virtual int maxConnectionsPerTorrent() const = 0; - virtual void setMaxConnectionsPerTorrent(int max) = 0; + virtual int maxConnectionsPerDownloadingTorrent() const = 0; + virtual void setMaxConnectionsPerDownloadingTorrent(int max) = 0; + virtual int maxConnectionsPerSeedingTorrent() const = 0; + virtual void setMaxConnectionsPerSeedingTorrent(int max) = 0; virtual int maxUploads() const = 0; virtual void setMaxUploads(int max) = 0; virtual int maxUploadsPerTorrent() const = 0; diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index a1b665e58..874dc633f 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -494,7 +494,8 @@ SessionImpl::SessionImpl(QObject *parent) , m_stopTrackerTimeout(BITTORRENT_SESSION_KEY(u"StopTrackerTimeout"_s), 2) , m_maxConnections(BITTORRENT_SESSION_KEY(u"MaxConnections"_s), 500, lowerLimited(0, -1)) , m_maxUploads(BITTORRENT_SESSION_KEY(u"MaxUploads"_s), 20, lowerLimited(0, -1)) - , m_maxConnectionsPerTorrent(BITTORRENT_SESSION_KEY(u"MaxConnectionsPerTorrent"_s), 100, lowerLimited(0, -1)) + , m_maxConnectionsPerDownloadingTorrent(BITTORRENT_SESSION_KEY(u"MaxConnectionsPerDownloadingTorrent"_s), 100, lowerLimited(0, -1)) + , m_maxConnectionsPerSeedingTorrent(BITTORRENT_SESSION_KEY(u"MaxConnectionsPerSeedingTorrent"_s), 40, lowerLimited(0, -1)) , m_maxUploadsPerTorrent(BITTORRENT_SESSION_KEY(u"MaxUploadsPerTorrent"_s), 4, lowerLimited(0, -1)) , m_btProtocol(BITTORRENT_SESSION_KEY(u"BTProtocol"_s), BTProtocol::Both , clampValue(BTProtocol::Both, BTProtocol::UTP)) @@ -2917,7 +2918,7 @@ bool SessionImpl::addTorrent_impl(const TorrentDescriptor &source, const AddTorr p.added_time = std::time(nullptr); // Limits - p.max_connections = maxConnectionsPerTorrent(); + p.max_connections = maxConnectionsPerDownloadingTorrent(); p.max_uploads = maxUploadsPerTorrent(); p.userdata = LTClientData(new ExtensionData); @@ -3115,7 +3116,7 @@ bool SessionImpl::downloadMetadata(const TorrentDescriptor &torrentDescr) p.storage_mode = lt::storage_mode_sparse; // Limits - p.max_connections = maxConnectionsPerTorrent(); + p.max_connections = maxConnectionsPerDownloadingTorrent(); p.max_uploads = maxUploadsPerTorrent(); const auto id = TorrentID::fromInfoHash(infoHash); @@ -4286,23 +4287,52 @@ void SessionImpl::resume() } } -int SessionImpl::maxConnectionsPerTorrent() const +int SessionImpl::maxConnectionsPerDownloadingTorrent() const { - return m_maxConnectionsPerTorrent; + return m_maxConnectionsPerDownloadingTorrent; } -void SessionImpl::setMaxConnectionsPerTorrent(int max) +int SessionImpl::maxConnectionsPerSeedingTorrent() const +{ + return m_maxConnectionsPerSeedingTorrent; +} + +void SessionImpl::setMaxConnectionsPerDownloadingTorrent(int max) { max = (max > 0) ? max : -1; - if (max != maxConnectionsPerTorrent()) + if (max != maxConnectionsPerDownloadingTorrent()) { - m_maxConnectionsPerTorrent = max; + m_maxConnectionsPerDownloadingTorrent = max; for (const TorrentImpl *torrent : asConst(m_torrents)) { try { - torrent->nativeHandle().set_max_connections(max); + if (m_maxConnectionsPerSeedingTorrent == -1 || !torrent->isUploading()) + { + torrent->nativeHandle().set_max_connections(max); + } + } + catch (const std::exception &) {} + } + } +} + +void SessionImpl::setMaxConnectionsPerSeedingTorrent(int max) +{ + max = (max > 0) ? max : -1; + if (max != maxConnectionsPerSeedingTorrent()) + { + m_maxConnectionsPerSeedingTorrent = max; + + for (const TorrentImpl *torrent : asConst(m_torrents)) + { + try + { + if (torrent->isUploading()) + { + torrent->nativeHandle().set_max_connections(max); + } } catch (const std::exception &) {} } diff --git a/src/base/bittorrent/sessionimpl.h b/src/base/bittorrent/sessionimpl.h index 40572895e..e15f812b8 100644 --- a/src/base/bittorrent/sessionimpl.h +++ b/src/base/bittorrent/sessionimpl.h @@ -378,8 +378,10 @@ namespace BitTorrent void setStopTrackerTimeout(int value) override; int maxConnections() const override; void setMaxConnections(int max) override; - int maxConnectionsPerTorrent() const override; - void setMaxConnectionsPerTorrent(int max) override; + int maxConnectionsPerDownloadingTorrent() const override; + void setMaxConnectionsPerDownloadingTorrent(int max) override; + int maxConnectionsPerSeedingTorrent() const override; + void setMaxConnectionsPerSeedingTorrent(int max) override; int maxUploads() const override; void setMaxUploads(int max) override; int maxUploadsPerTorrent() const override; @@ -699,7 +701,8 @@ namespace BitTorrent CachedSettingValue m_stopTrackerTimeout; CachedSettingValue m_maxConnections; CachedSettingValue m_maxUploads; - CachedSettingValue m_maxConnectionsPerTorrent; + CachedSettingValue m_maxConnectionsPerDownloadingTorrent; + CachedSettingValue m_maxConnectionsPerSeedingTorrent; CachedSettingValue m_maxUploadsPerTorrent; CachedSettingValue m_btProtocol; CachedSettingValue m_isUTPRateLimited; diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index 1c101d0be..5d11423b6 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -2539,8 +2539,14 @@ void TorrentImpl::updateStatus(const lt::torrent_status &nativeStatus) if (m_nativeStatus.last_seen_complete != oldStatus.last_seen_complete) m_lastSeenComplete = QDateTime::fromSecsSinceEpoch(m_nativeStatus.last_seen_complete); + const bool wasUploading = isUploading(); updateState(); + if (wasUploading ^ isUploading()) { + // Switching from Stopped to Uploading or vice versa may require updating the connection limits. + updateMaxConnections(); + } + m_payloadRateMonitor.addSample({nativeStatus.download_payload_rate , nativeStatus.upload_payload_rate}); @@ -2596,6 +2602,19 @@ void TorrentImpl::updateProgress() } } +void TorrentImpl::updateMaxConnections() +{ + const int maxDownloadingConnections = m_session->maxConnectionsPerDownloadingTorrent(); + const int maxSeedingConnections = m_session->maxConnectionsPerSeedingTorrent(); + const bool useSeedingLimit = (maxSeedingConnections != -1) && isUploading(); + const int max = useSeedingLimit ? maxSeedingConnections : maxDownloadingConnections; + + if (nativeHandle().max_connections() == max) + return; + + nativeHandle().set_max_connections(max); +} + void TorrentImpl::setRatioLimit(qreal limit) { if (limit < USE_GLOBAL_RATIO) diff --git a/src/base/bittorrent/torrentimpl.h b/src/base/bittorrent/torrentimpl.h index e44d875c9..ce8230ff7 100644 --- a/src/base/bittorrent/torrentimpl.h +++ b/src/base/bittorrent/torrentimpl.h @@ -295,6 +295,7 @@ namespace BitTorrent void updateStatus(const lt::torrent_status &nativeStatus); void updateProgress(); void updateState(); + void updateMaxConnections(); bool isMoveInProgress() const; diff --git a/src/gui/optionsdialog.cpp b/src/gui/optionsdialog.cpp index ad2eb348b..741551eed 100644 --- a/src/gui/optionsdialog.cpp +++ b/src/gui/optionsdialog.cpp @@ -846,19 +846,32 @@ void OptionsDialog::loadConnectionTabOptions() m_ui->checkMaxConnections->setChecked(false); m_ui->spinMaxConnec->setEnabled(false); } - intValue = session->maxConnectionsPerTorrent(); + intValue = session->maxConnectionsPerDownloadingTorrent(); if (intValue > 0) { // enable - m_ui->checkMaxConnectionsPerTorrent->setChecked(true); - m_ui->spinMaxConnecPerTorrent->setEnabled(true); - m_ui->spinMaxConnecPerTorrent->setValue(intValue); + m_ui->checkMaxConnectionsPerDownloadingTorrent->setChecked(true); + m_ui->spinMaxConnecPerDownloadingTorrent->setEnabled(true); + m_ui->spinMaxConnecPerDownloadingTorrent->setValue(intValue); } else { // disable - m_ui->checkMaxConnectionsPerTorrent->setChecked(false); - m_ui->spinMaxConnecPerTorrent->setEnabled(false); + m_ui->checkMaxConnectionsPerDownloadingTorrent->setChecked(false); + m_ui->spinMaxConnecPerDownloadingTorrent->setEnabled(false); + } + intValue = session->maxConnectionsPerSeedingTorrent(); + if (intValue > 0) + { + // enable + m_ui->checkMaxConnectionsPerSeedingTorrent->setChecked(true); + m_ui->spinMaxConnecPerSeedingTorrent->setValue(intValue); + } + else + { + // disable + m_ui->checkMaxConnectionsPerSeedingTorrent->setChecked(false); + m_ui->spinMaxConnecPerSeedingTorrent->setEnabled(false); } intValue = session->maxUploads(); if (intValue > 0) @@ -936,14 +949,17 @@ void OptionsDialog::loadConnectionTabOptions() connect(m_ui->checkMaxConnections, &QAbstractButton::toggled, m_ui->spinMaxConnec, &QWidget::setEnabled); connect(m_ui->checkMaxConnections, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); - connect(m_ui->checkMaxConnectionsPerTorrent, &QAbstractButton::toggled, m_ui->spinMaxConnecPerTorrent, &QWidget::setEnabled); - connect(m_ui->checkMaxConnectionsPerTorrent, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); + connect(m_ui->checkMaxConnectionsPerDownloadingTorrent, &QAbstractButton::toggled, m_ui->spinMaxConnecPerDownloadingTorrent, &QWidget::setEnabled); + connect(m_ui->checkMaxConnectionsPerDownloadingTorrent, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); + connect(m_ui->checkMaxConnectionsPerSeedingTorrent, &QAbstractButton::toggled, m_ui->spinMaxConnecPerSeedingTorrent, &QWidget::setEnabled); + connect(m_ui->checkMaxConnectionsPerSeedingTorrent, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); connect(m_ui->checkMaxUploads, &QAbstractButton::toggled, m_ui->spinMaxUploads, &QWidget::setEnabled); connect(m_ui->checkMaxUploads, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); connect(m_ui->checkMaxUploadsPerTorrent, &QAbstractButton::toggled, m_ui->spinMaxUploadsPerTorrent, &QWidget::setEnabled); connect(m_ui->checkMaxUploadsPerTorrent, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); connect(m_ui->spinMaxConnec, qSpinBoxValueChanged, this, &ThisType::enableApplyButton); - connect(m_ui->spinMaxConnecPerTorrent, qSpinBoxValueChanged, this, &ThisType::enableApplyButton); + connect(m_ui->spinMaxConnecPerDownloadingTorrent, qSpinBoxValueChanged, this, &ThisType::enableApplyButton); + connect(m_ui->spinMaxConnecPerSeedingTorrent, qSpinBoxValueChanged, this, &ThisType::enableApplyButton); connect(m_ui->spinMaxUploads, qSpinBoxValueChanged, this, &ThisType::enableApplyButton); connect(m_ui->spinMaxUploadsPerTorrent, qSpinBoxValueChanged, this, &ThisType::enableApplyButton); @@ -986,7 +1002,8 @@ void OptionsDialog::saveConnectionTabOptions() const Net::PortForwarder::instance()->setEnabled(isUPnPEnabled()); session->setMaxConnections(getMaxConnections()); - session->setMaxConnectionsPerTorrent(getMaxConnectionsPerTorrent()); + session->setMaxConnectionsPerDownloadingTorrent(getMaxConnectionsPerDownloadingTorrent()); + session->setMaxConnectionsPerSeedingTorrent(getMaxConnectionsPerSeedingTorrent()); session->setMaxUploads(getMaxUploads()); session->setMaxUploadsPerTorrent(getMaxUploadsPerTorrent()); @@ -1606,12 +1623,20 @@ int OptionsDialog::getMaxConnections() const return m_ui->spinMaxConnec->value(); } -int OptionsDialog::getMaxConnectionsPerTorrent() const +int OptionsDialog::getMaxConnectionsPerDownloadingTorrent() const { - if (!m_ui->checkMaxConnectionsPerTorrent->isChecked()) + if (!m_ui->checkMaxConnectionsPerDownloadingTorrent->isChecked()) return -1; - return m_ui->spinMaxConnecPerTorrent->value(); + return m_ui->spinMaxConnecPerDownloadingTorrent->value(); +} + +int OptionsDialog::getMaxConnectionsPerSeedingTorrent() const +{ + if (!m_ui->checkMaxConnectionsPerSeedingTorrent->isChecked()) + return -1; + + return m_ui->spinMaxConnecPerSeedingTorrent->value(); } int OptionsDialog::getMaxUploads() const diff --git a/src/gui/optionsdialog.h b/src/gui/optionsdialog.h index c1e29c1d6..aad00a2c6 100644 --- a/src/gui/optionsdialog.h +++ b/src/gui/optionsdialog.h @@ -165,7 +165,8 @@ private: bool isUPnPEnabled() const; // Bittorrent options int getMaxConnections() const; - int getMaxConnectionsPerTorrent() const; + int getMaxConnectionsPerDownloadingTorrent() const; + int getMaxConnectionsPerSeedingTorrent() const; int getMaxUploads() const; int getMaxUploadsPerTorrent() const; bool isDHTEnabled() const; diff --git a/src/gui/optionsdialog.ui b/src/gui/optionsdialog.ui index a0afed167..bac3857b1 100644 --- a/src/gui/optionsdialog.ui +++ b/src/gui/optionsdialog.ui @@ -1910,7 +1910,7 @@ readme[0-9].txt: filter 'readme1.txt', 'readme2.txt' but not 'readme10.txt'. - + Maximum number of connections per torrent: @@ -1920,7 +1920,7 @@ readme[0-9].txt: filter 'readme1.txt', 'readme2.txt' but not 'readme10.txt'. - + 2 @@ -1933,13 +1933,36 @@ readme[0-9].txt: filter 'readme1.txt', 'readme2.txt' but not 'readme10.txt'. + + + Maximum number of connections per seeding torrent: + + + true + + + + + + + 2 + + + 2000 + + + 40 + + + + Global maximum number of upload slots: - + 2000 @@ -1949,14 +1972,14 @@ readme[0-9].txt: filter 'readme1.txt', 'readme2.txt' but not 'readme10.txt'. - + Maximum number of upload slots per torrent: - + 500 diff --git a/src/webui/api/appcontroller.cpp b/src/webui/api/appcontroller.cpp index e2e465acd..4228452d3 100644 --- a/src/webui/api/appcontroller.cpp +++ b/src/webui/api/appcontroller.cpp @@ -229,7 +229,8 @@ void AppController::preferencesAction() data[u"upnp"_s] = Net::PortForwarder::instance()->isEnabled(); // Connections Limits data[u"max_connec"_s] = session->maxConnections(); - data[u"max_connec_per_torrent"_s] = session->maxConnectionsPerTorrent(); + data[u"max_connec_per_downloading_torrent"_s] = session->maxConnectionsPerDownloadingTorrent(); + data[u"max_connec_per_seeding_torrent"_s] = session->maxConnectionsPerSeedingTorrent(); data[u"max_uploads"_s] = session->maxUploads(); data[u"max_uploads_per_torrent"_s] = session->maxUploadsPerTorrent(); @@ -709,8 +710,10 @@ void AppController::setPreferencesAction() // Connections Limits if (hasKey(u"max_connec"_s)) session->setMaxConnections(it.value().toInt()); - if (hasKey(u"max_connec_per_torrent"_s)) - session->setMaxConnectionsPerTorrent(it.value().toInt()); + if (hasKey(u"max_connec_per_downloading_torrent"_s)) + session->setMaxConnectionsPerDownloadingTorrent(it.value().toInt()); + if (hasKey(u"max_connec_per_seeding_torrent"_s)) + session->setMaxConnectionsPerSeedingTorrent(it.value().toInt()); if (hasKey(u"max_uploads"_s)) session->setMaxUploads(it.value().toInt()); if (hasKey(u"max_uploads_per_torrent"_s)) diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html index b2e81856f..df6b701b0 100644 --- a/src/webui/www/private/views/preferences.html +++ b/src/webui/www/private/views/preferences.html @@ -436,10 +436,17 @@ - - + + - + + + + + + + + @@ -1771,7 +1778,8 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD updateAutoRunOnTorrentAdded: updateAutoRunOnTorrentAdded, generateRandomPort: generateRandomPort, updateMaxConnecEnabled: updateMaxConnecEnabled, - updateMaxConnecPerTorrentEnabled: updateMaxConnecPerTorrentEnabled, + updateMaxConnecPerDownloadingTorrentEnabled: updateMaxConnecPerDownloadingTorrentEnabled, + updateMaxConnecPerSeedingTorrentEnabled: updateMaxConnecPerSeedingTorrentEnabled, updateMaxUploadsEnabled: updateMaxUploadsEnabled, updateMaxUploadsPerTorrentEnabled: updateMaxUploadsPerTorrentEnabled, updateI2PSettingsEnabled: updateI2PSettingsEnabled, @@ -1976,9 +1984,14 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD document.getElementById("maxConnectionsValue").disabled = !isMaxConnecEnabled; }; - const updateMaxConnecPerTorrentEnabled = () => { - const isMaxConnecPerTorrentEnabled = document.getElementById("maxConnectionsPerTorrentCheckbox").checked; - document.getElementById("maxConnectionsPerTorrentValue").disabled = !isMaxConnecPerTorrentEnabled; + const updateMaxConnecPerDownloadingTorrentEnabled = () => { + const isMaxConnecPerDownloadingTorrentEnabled = document.getElementById("maxConnectionsPerDownloadingTorrentCheckbox").checked; + document.getElementById("maxConnectionsPerDownloadingTorrentValue").disabled = !isMaxConnecPerDownloadingTorrentEnabled; + }; + + const updateMaxConnecPerSeedingTorrentEnabled = () => { + const isMaxConnecPerSeedingTorrentEnabled = document.getElementById("maxConnectionsPerSeedingTorrentCheckbox").checked; + document.getElementById("maxConnectionsPerSeedingTorrentValue").disabled = !isMaxConnecPerSeedingTorrentEnabled; }; const updateMaxUploadsEnabled = () => { @@ -2377,16 +2390,27 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD } updateMaxConnecEnabled(); - const maxConnecPerTorrent = Number(pref.max_connec_per_torrent); - if (maxConnecPerTorrent <= 0) { - document.getElementById("maxConnectionsPerTorrentCheckbox").checked = false; - document.getElementById("maxConnectionsPerTorrentValue").value = 100; + const maxConnecPerDownloadingTorrent = Number(pref.max_connec_per_downloading_torrent); + if (maxConnecPerDownloadingTorrent <= 0) { + document.getElementById("maxConnectionsPerDownloadingTorrentCheckbox").checked = false; + document.getElementById("maxConnectionsPerDownloadingTorrentValue").value = 100; } else { - document.getElementById("maxConnectionsPerTorrentCheckbox").checked = true; - document.getElementById("maxConnectionsPerTorrentValue").value = maxConnecPerTorrent; + document.getElementById("maxConnectionsPerDownloadingTorrentCheckbox").checked = true; + document.getElementById("maxConnectionsPerDownloadingTorrentValue").value = maxConnecPerDownloadingTorrent; } - updateMaxConnecPerTorrentEnabled(); + updateMaxConnecPerDownloadingTorrentEnabled(); + + const maxConnecPerSeedingTorrent = Number(pref.max_connec_per_seeding_torrent); + if (maxConnecPerSeedingTorrent <= 0) { + document.getElementById("maxConnectionsPerSeedingTorrentCheckbox").checked = false; + document.getElementById("maxConnectionsPerSeedingTorrentValue").value = 100; + } + else { + document.getElementById("maxConnectionsPerSeedingTorrentCheckbox").checked = true; + document.getElementById("maxConnectionsPerSeedingTorrentValue").value = maxConnecPerSeedingTorrent; + } + updateMaxConnecPerSeedingTorrentEnabled(); const maxUploads = Number(pref.max_uploads); if (maxUploads <= 0) { @@ -2763,15 +2787,25 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD } settings["max_connec"] = maxConnec; - let maxConnecPerTorrent = -1; - if (document.getElementById("maxConnectionsPerTorrentCheckbox").checked) { - maxConnecPerTorrent = Number(document.getElementById("maxConnectionsPerTorrentValue").value); - if (Number.isNaN(maxConnecPerTorrent) || (maxConnecPerTorrent <= 0)) { + let maxConnecPerDownloadingTorrent = -1; + if (document.getElementById("maxConnectionsPerDownloadingTorrentCheckbox").checked) { + maxConnecPerDownloadingTorrent = Number(document.getElementById("maxConnectionsPerDownloadingTorrentValue").value); + if (Number.isNaN(maxConnecPerDownloadingTorrent) || (maxConnecPerDownloadingTorrent <= 0)) { alert("QBT_TR(Maximum number of connections per torrent limit must be greater than 0 or disabled.)QBT_TR[CONTEXT=HttpServer]"); return; } } - settings["max_connec_per_torrent"] = maxConnecPerTorrent; + settings["max_connec_per_downloading_torrent"] = maxConnecPerDownloadingTorrent; + + let maxConnecPerSeedingTorrent = -1; + if (document.getElementById("maxConnectionsPerSeedingTorrentCheckbox").checked) { + maxConnecPerSeedingTorrent = Number(document.getElementById("maxConnectionsPerSeedingTorrentValue").value); + if (Number.isNaN(maxConnecPerSeedingTorrent) || (maxConnecPerSeedingTorrent <= 0)) { + alert("QBT_TR(Maximum number of seed connections per torrent limit must be greater than 0 or disabled.)QBT_TR[CONTEXT=HttpServer]"); + return; + } + } + settings["max_connec_per_seeding_torrent"] = maxConnecPerSeedingTorrent; let maxUploads = -1; if (document.getElementById("maxUploadsCheckbox").checked) {