Browse Source

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
adaptive-webui-19844
thalieht 5 years ago
parent
commit
5f415c292d
  1. 10
      src/base/bittorrent/peeraddress.cpp
  2. 3
      src/base/bittorrent/peeraddress.h
  3. 59
      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 @@ -68,3 +68,13 @@ QString PeerAddress::toString() const
: ip.toString();
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 @@ -42,4 +42,7 @@ namespace BitTorrent
static PeerAddress parse(const QString &address);
QString toString() const;
};
bool operator==(const PeerAddress &left, const PeerAddress &right);
uint qHash(const PeerAddress &addr, uint seed);
}

59
src/gui/properties/peerlistwidget.cpp

@ -57,6 +57,22 @@ @@ -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) @@ -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 @@ -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 @@ -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)
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)

6
src/gui/properties/peerlistwidget.h

@ -38,6 +38,8 @@ class QStandardItemModel; @@ -38,6 +38,8 @@ class QStandardItemModel;
class PeerListSortModel;
class PropertiesWidget;
struct PeerEndpoint;
namespace BitTorrent
{
class TorrentHandle;
@ -73,7 +75,7 @@ private slots: @@ -73,7 +75,7 @@ private slots:
void handleResolved(const QString &ip, const QString &hostname);
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;
@ -81,7 +83,7 @@ private: @@ -81,7 +83,7 @@ private:
PeerListSortModel *m_proxyModel = nullptr;
PropertiesWidget *m_properties = nullptr;
Net::ReverseResolution *m_resolver = nullptr;
QHash<QString, QStandardItem *> m_peerItems;
QHash<PeerEndpoint, QStandardItem *> m_peerItems;
bool m_resolveCountries;
};

Loading…
Cancel
Save