mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-12-21 08:09:35 +08:00
Merge pull request #11918 from thalieht/peerssameip
Show any multiple connections from the same IP in peer list
This commit is contained in:
commit
11bea8d393
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -38,6 +38,8 @@ class QStandardItemModel;
|
||||
class PeerListSortModel;
|
||||
class PropertiesWidget;
|
||||
|
||||
struct PeerEndpoint;
|
||||
|
||||
namespace BitTorrent
|
||||
{
|
||||
class TorrentHandle;
|
||||
@ -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:
|
||||
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…
Reference in New Issue
Block a user