mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-07-16 02:03:07 -07:00
Show any multiple connections from the same IP in peer list
The uniqueness of peers is now determined by their IP, port and connection type (uTP etc.) instead of just their IP
This commit is contained in:
parent
c3ce1aaa3d
commit
5f415c292d
4 changed files with 59 additions and 21 deletions
|
@ -57,6 +57,22 @@
|
|||
#include "propertieswidget.h"
|
||||
#include "uithememanager.h"
|
||||
|
||||
struct PeerEndpoint
|
||||
{
|
||||
BitTorrent::PeerAddress address;
|
||||
QString connectionType; // matches return type of `PeerInfo::connectionType()`
|
||||
};
|
||||
|
||||
bool operator==(const PeerEndpoint &left, const PeerEndpoint &right)
|
||||
{
|
||||
return (left.address == right.address) && (left.connectionType == right.connectionType);
|
||||
}
|
||||
|
||||
uint qHash(const PeerEndpoint &peerEndpoint, const uint seed)
|
||||
{
|
||||
return (qHash(peerEndpoint.address, seed) ^ ::qHash(peerEndpoint.connectionType));
|
||||
}
|
||||
|
||||
PeerListWidget::PeerListWidget(PropertiesWidget *parent)
|
||||
: QTreeView(parent)
|
||||
, m_properties(parent)
|
||||
|
@ -331,42 +347,45 @@ void PeerListWidget::loadPeers(const BitTorrent::TorrentHandle *torrent)
|
|||
if (!torrent) return;
|
||||
|
||||
const QVector<BitTorrent::PeerInfo> peers = torrent->peers();
|
||||
QSet<QString> existingPeers;
|
||||
QSet<PeerEndpoint> existingPeers;
|
||||
for (auto i = m_peerItems.cbegin(); i != m_peerItems.cend(); ++i)
|
||||
existingPeers << i.key();
|
||||
|
||||
for (const BitTorrent::PeerInfo &peer : peers) {
|
||||
const BitTorrent::PeerAddress addr = peer.address();
|
||||
if (addr.ip.isNull()) continue;
|
||||
if (peer.address().ip.isNull()) continue;
|
||||
|
||||
const QString peerIp = addr.ip.toString();
|
||||
bool isNewPeer = false;
|
||||
updatePeer(peerIp, torrent, peer, isNewPeer);
|
||||
if (!isNewPeer)
|
||||
existingPeers.remove(peerIp);
|
||||
updatePeer(torrent, peer, isNewPeer);
|
||||
if (!isNewPeer) {
|
||||
const PeerEndpoint peerEndpoint {peer.address(), peer.connectionType()};
|
||||
existingPeers.remove(peerEndpoint);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove peers that are gone
|
||||
for (const QString &ip : asConst(existingPeers)) {
|
||||
const QStandardItem *item = m_peerItems.take(ip);
|
||||
for (const PeerEndpoint &peerEndpoint : asConst(existingPeers)) {
|
||||
const QStandardItem *item = m_peerItems.take(peerEndpoint);
|
||||
m_listModel->removeRow(item->row());
|
||||
}
|
||||
}
|
||||
|
||||
void PeerListWidget::updatePeer(const QString &ip, const BitTorrent::TorrentHandle *torrent, const BitTorrent::PeerInfo &peer, bool &isNewPeer)
|
||||
void PeerListWidget::updatePeer(const BitTorrent::TorrentHandle *torrent, const BitTorrent::PeerInfo &peer, bool &isNewPeer)
|
||||
{
|
||||
auto itemIter = m_peerItems.find(ip);
|
||||
const PeerEndpoint peerEndpoint {peer.address(), peer.connectionType()};
|
||||
const QString peerIp = peerEndpoint.address.ip.toString();
|
||||
|
||||
auto itemIter = m_peerItems.find(peerEndpoint);
|
||||
isNewPeer = (itemIter == m_peerItems.end());
|
||||
if (isNewPeer) {
|
||||
// new item
|
||||
const int row = m_listModel->rowCount();
|
||||
m_listModel->insertRow(row);
|
||||
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP), ip);
|
||||
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP), ip, Qt::ToolTipRole);
|
||||
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP), peerIp);
|
||||
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP), peerIp, Qt::ToolTipRole);
|
||||
m_listModel->setData(m_listModel->index(row, PeerListDelegate::PORT), peer.address().port);
|
||||
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP_HIDDEN), ip);
|
||||
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP_HIDDEN), peerIp);
|
||||
|
||||
itemIter = m_peerItems.insert(ip, m_listModel->item(row, PeerListDelegate::IP));
|
||||
itemIter = m_peerItems.insert(peerEndpoint, m_listModel->item(row, PeerListDelegate::IP));
|
||||
}
|
||||
|
||||
const int row = (*itemIter)->row();
|
||||
|
@ -386,7 +405,7 @@ void PeerListWidget::updatePeer(const QString &ip, const BitTorrent::TorrentHand
|
|||
m_listModel->setData(m_listModel->index(row, PeerListDelegate::DOWNLOADING_PIECE), downloadingFiles.join('\n'), Qt::ToolTipRole);
|
||||
|
||||
if (m_resolver)
|
||||
m_resolver->resolve(ip);
|
||||
m_resolver->resolve(peerIp);
|
||||
|
||||
if (m_resolveCountries) {
|
||||
const QIcon icon = UIThemeManager::instance()->getFlagIcon(peer.country());
|
||||
|
@ -400,9 +419,13 @@ void PeerListWidget::updatePeer(const QString &ip, const BitTorrent::TorrentHand
|
|||
|
||||
void PeerListWidget::handleResolved(const QString &ip, const QString &hostname)
|
||||
{
|
||||
QStandardItem *item = m_peerItems.value(ip, nullptr);
|
||||
if (item)
|
||||
item->setData(hostname, Qt::DisplayRole);
|
||||
for (auto iter = m_peerItems.cbegin(); iter != m_peerItems.cend(); ++iter) {
|
||||
if (iter.key().address.ip.toString() == ip) {
|
||||
QStandardItem *item {iter.value()};
|
||||
item->setData(hostname, Qt::DisplayRole);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PeerListWidget::handleSortColumnChanged(const int col)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue