Browse Source

Merge pull request #11918 from thalieht/peerssameip

Show any multiple connections from the same IP in peer list
adaptive-webui-19844
Mike Tzou 5 years ago committed by GitHub
parent
commit
11bea8d393
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      src/base/bittorrent/peeraddress.cpp
  2. 3
      src/base/bittorrent/peeraddress.h
  3. 61
      src/gui/properties/peerlistwidget.cpp
  4. 6
      src/gui/properties/peerlistwidget.h

10
src/base/bittorrent/peeraddress.cpp

@ -68,3 +68,13 @@ QString PeerAddress::toString() const
: ip.toString(); : ip.toString();
return (ipStr + ':' + QString::number(port)); return (ipStr + ':' + QString::number(port));
} }
bool BitTorrent::operator==(const BitTorrent::PeerAddress &left, const BitTorrent::PeerAddress &right)
{
return (left.ip == right.ip) && (left.port == right.port);
}
uint BitTorrent::qHash(const BitTorrent::PeerAddress &addr, const uint seed)
{
return (::qHash(addr.ip, seed) ^ ::qHash(addr.port));
}

3
src/base/bittorrent/peeraddress.h

@ -42,4 +42,7 @@ namespace BitTorrent
static PeerAddress parse(const QString &address); static PeerAddress parse(const QString &address);
QString toString() const; QString toString() const;
}; };
bool operator==(const PeerAddress &left, const PeerAddress &right);
uint qHash(const PeerAddress &addr, uint seed);
} }

61
src/gui/properties/peerlistwidget.cpp

@ -57,6 +57,22 @@
#include "propertieswidget.h" #include "propertieswidget.h"
#include "uithememanager.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) PeerListWidget::PeerListWidget(PropertiesWidget *parent)
: QTreeView(parent) : QTreeView(parent)
, m_properties(parent) , m_properties(parent)
@ -331,42 +347,45 @@ void PeerListWidget::loadPeers(const BitTorrent::TorrentHandle *torrent)
if (!torrent) return; if (!torrent) return;
const QVector<BitTorrent::PeerInfo> peers = torrent->peers(); const QVector<BitTorrent::PeerInfo> peers = torrent->peers();
QSet<QString> existingPeers; QSet<PeerEndpoint> existingPeers;
for (auto i = m_peerItems.cbegin(); i != m_peerItems.cend(); ++i) for (auto i = m_peerItems.cbegin(); i != m_peerItems.cend(); ++i)
existingPeers << i.key(); existingPeers << i.key();
for (const BitTorrent::PeerInfo &peer : peers) { for (const BitTorrent::PeerInfo &peer : peers) {
const BitTorrent::PeerAddress addr = peer.address(); if (peer.address().ip.isNull()) continue;
if (addr.ip.isNull()) continue;
const QString peerIp = addr.ip.toString();
bool isNewPeer = false; bool isNewPeer = false;
updatePeer(peerIp, torrent, peer, isNewPeer); updatePeer(torrent, peer, isNewPeer);
if (!isNewPeer) if (!isNewPeer) {
existingPeers.remove(peerIp); const PeerEndpoint peerEndpoint {peer.address(), peer.connectionType()};
existingPeers.remove(peerEndpoint);
}
} }
// Remove peers that are gone // Remove peers that are gone
for (const QString &ip : asConst(existingPeers)) { for (const PeerEndpoint &peerEndpoint : asConst(existingPeers)) {
const QStandardItem *item = m_peerItems.take(ip); const QStandardItem *item = m_peerItems.take(peerEndpoint);
m_listModel->removeRow(item->row()); 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()); isNewPeer = (itemIter == m_peerItems.end());
if (isNewPeer) { if (isNewPeer) {
// new item // new item
const int row = m_listModel->rowCount(); const int row = m_listModel->rowCount();
m_listModel->insertRow(row); m_listModel->insertRow(row);
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP), ip); m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP), peerIp);
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP), ip, Qt::ToolTipRole); 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::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(); 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); m_listModel->setData(m_listModel->index(row, PeerListDelegate::DOWNLOADING_PIECE), downloadingFiles.join('\n'), Qt::ToolTipRole);
if (m_resolver) if (m_resolver)
m_resolver->resolve(ip); m_resolver->resolve(peerIp);
if (m_resolveCountries) { if (m_resolveCountries) {
const QIcon icon = UIThemeManager::instance()->getFlagIcon(peer.country()); 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) void PeerListWidget::handleResolved(const QString &ip, const QString &hostname)
{ {
QStandardItem *item = m_peerItems.value(ip, nullptr); for (auto iter = m_peerItems.cbegin(); iter != m_peerItems.cend(); ++iter) {
if (item) if (iter.key().address.ip.toString() == ip) {
item->setData(hostname, Qt::DisplayRole); QStandardItem *item {iter.value()};
item->setData(hostname, Qt::DisplayRole);
break;
}
}
} }
void PeerListWidget::handleSortColumnChanged(const int col) void PeerListWidget::handleSortColumnChanged(const int col)

6
src/gui/properties/peerlistwidget.h

@ -38,6 +38,8 @@ class QStandardItemModel;
class PeerListSortModel; class PeerListSortModel;
class PropertiesWidget; class PropertiesWidget;
struct PeerEndpoint;
namespace BitTorrent namespace BitTorrent
{ {
class TorrentHandle; class TorrentHandle;
@ -73,7 +75,7 @@ private slots:
void handleResolved(const QString &ip, const QString &hostname); void handleResolved(const QString &ip, const QString &hostname);
private: private:
void updatePeer(const QString &ip, const BitTorrent::TorrentHandle *torrent, const BitTorrent::PeerInfo &peer, bool &isNewPeer); void updatePeer(const BitTorrent::TorrentHandle *torrent, const BitTorrent::PeerInfo &peer, bool &isNewPeer);
void wheelEvent(QWheelEvent *event) override; void wheelEvent(QWheelEvent *event) override;
@ -81,7 +83,7 @@ private:
PeerListSortModel *m_proxyModel = nullptr; PeerListSortModel *m_proxyModel = nullptr;
PropertiesWidget *m_properties = nullptr; PropertiesWidget *m_properties = nullptr;
Net::ReverseResolution *m_resolver = nullptr; Net::ReverseResolution *m_resolver = nullptr;
QHash<QString, QStandardItem *> m_peerItems; QHash<PeerEndpoint, QStandardItem *> m_peerItems;
bool m_resolveCountries; bool m_resolveCountries;
}; };

Loading…
Cancel
Save