diff --git a/libretroshare/src/retroshare/rsdisc.h b/libretroshare/src/retroshare/rsdisc.h index 7e7bb5c9a..16a10e12c 100644 --- a/libretroshare/src/retroshare/rsdisc.h +++ b/libretroshare/src/retroshare/rsdisc.h @@ -42,7 +42,8 @@ class RsDisc RsDisc() { return; } virtual ~RsDisc() { return; } -virtual bool getDiscFriends(std::string id, std::list &friends) = 0; +virtual bool getDiscFriends(std::string id, std::list& friends) = 0; +virtual bool getDiscGPGFriends(std::string id, std::list& gpg_friends) = 0; virtual bool getDiscVersions(std::map &versions) = 0; }; diff --git a/libretroshare/src/rsserver/p3discovery.cc b/libretroshare/src/rsserver/p3discovery.cc index 8ed6afd68..7c2fc7adc 100644 --- a/libretroshare/src/rsserver/p3discovery.cc +++ b/libretroshare/src/rsserver/p3discovery.cc @@ -29,6 +29,14 @@ RsDisc *rsDisc = NULL; +bool p3Discovery::getDiscGPGFriends(std::string id, std::list& gpg_friends) +{ + if (mDisc) + { + return mDisc->potentialGPGproxies(id, gpg_friends); + } + return false; +} bool p3Discovery::getDiscFriends(std::string id, std::list &friends) { if (mDisc) diff --git a/libretroshare/src/rsserver/p3discovery.h b/libretroshare/src/rsserver/p3discovery.h index 1ca9b6fc9..e1ccda1d8 100644 --- a/libretroshare/src/rsserver/p3discovery.h +++ b/libretroshare/src/rsserver/p3discovery.h @@ -38,6 +38,7 @@ class p3Discovery: public RsDisc virtual ~p3Discovery() { return; } virtual bool getDiscFriends(std::string id, std::list &friends); +virtual bool getDiscGPGFriends(std::string id, std::list &gpg_friends); virtual bool getDiscVersions(std::map &versions); private: diff --git a/libretroshare/src/services/p3disc.cc b/libretroshare/src/services/p3disc.cc index 0e3aadd9d..bfae895b0 100644 --- a/libretroshare/src/services/p3disc.cc +++ b/libretroshare/src/services/p3disc.cc @@ -615,7 +615,7 @@ void p3disc::recvPeerDetails(RsDiscReply *item, const std::string &certGpgId) for (std::list::iterator pitem = item->rsPeerList.begin(); pitem != item->rsPeerList.end(); pitem++) { bool new_info ; - addDiscoveryData(item->PeerId(), pitem->pid, pitem->currentlocaladdr, pitem->currentremoteaddr, 0, time(NULL),new_info); + addDiscoveryData(item->PeerId(), pitem->pid,rsPeers->getGPGId(item->PeerId()),item->aboutId, pitem->currentlocaladdr, pitem->currentremoteaddr, 0, time(NULL),new_info); if(new_info) should_notify_discovery = true ; @@ -895,11 +895,14 @@ void p3disc::setGPGOperation(AuthGPGOperation *operation) /*************************************************************************************/ /* Storing Network Graph */ /*************************************************************************************/ -int p3disc::addDiscoveryData(std::string fromId, std::string aboutId, struct sockaddr_in laddr, struct sockaddr_in raddr, uint32_t flags, time_t ts,bool& new_info) +int p3disc::addDiscoveryData(const std::string& fromId, const std::string& aboutId,const std::string& from_gpg_id,const std::string& about_gpg_id, const struct sockaddr_in& laddr, const struct sockaddr_in& raddr, uint32_t flags, time_t ts,bool& new_info) { RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/ new_info = false ; + + gpg_neighbors[from_gpg_id].insert(about_gpg_id) ; + std::cerr << "Adding discovery data " << fromId << " - " << aboutId << std::endl ; /* Store Network information */ std::map::iterator it; @@ -963,7 +966,7 @@ int p3disc::addDiscoveryData(std::string fromId, std::string aboutId, struct soc /*************************************************************************************/ /* Extracting Network Graph Details */ /*************************************************************************************/ -bool p3disc::potentialproxies(std::string id, std::list &proxyIds) +bool p3disc::potentialproxies(const std::string& id, std::list &proxyIds) { /* find id -> and extract the neighbour_of ids */ @@ -979,13 +982,31 @@ bool p3disc::potentialproxies(std::string id, std::list &proxyIds) return false; } - for(sit = it->second.neighbour_of.begin(); - sit != it->second.neighbour_of.end(); sit++) + for(sit = it->second.neighbour_of.begin(); sit != it->second.neighbour_of.end(); sit++) { proxyIds.push_back(sit->first); } return true; } +bool p3disc::potentialGPGproxies(const std::string& gpg_id, std::list &proxyGPGIds) +{ + /* find id -> and extract the neighbour_of ids */ + + if(gpg_id == rsPeers->getGPGOwnId()) // SSL id // This is treated appart, because otherwise we don't receive any disc info about us + return rsPeers->getGPGAcceptedList(proxyGPGIds) ; + + RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/ + + std::map >::iterator it = gpg_neighbors.find(gpg_id) ; + + if(it == gpg_neighbors.end()) + return false; + + for(std::set::const_iterator sit(it->second.begin()); sit != it->second.end(); ++sit) + proxyGPGIds.push_back(*sit); + + return true; +} void p3disc::getversions(std::map &versions) { diff --git a/libretroshare/src/services/p3disc.h b/libretroshare/src/services/p3disc.h index b1acca257..dfdd94614 100644 --- a/libretroshare/src/services/p3disc.h +++ b/libretroshare/src/services/p3disc.h @@ -89,7 +89,8 @@ virtual void statusChange(const std::list &plist); int tick(); /* GUI requires access */ -bool potentialproxies(std::string id, std::list &proxyIds); +bool potentialGPGproxies(const std::string& id, std::list &proxyGPGIds); +bool potentialproxies(const std::string& id, std::list &proxyIds); void getversions(std::map &versions); /************* from AuthGPService ****************/ @@ -130,8 +131,9 @@ void recvHeartbeatMsg(RsDiscHeartbeat *item); void removeFriend(std::string ssl_id); //keep tracks of removed friend so we're not gonna add them again immediately /* handle network shape */ -int addDiscoveryData(std::string fromId, std::string aboutId, - struct sockaddr_in laddr, struct sockaddr_in raddr, +int addDiscoveryData(const std::string& fromId, const std::string& aboutId, + const std::string& fromGPGId,const std::string& aboutGPGId, + const struct sockaddr_in& laddr, const struct sockaddr_in& raddr, uint32_t flags, time_t ts,bool& new_info); int idServers(); @@ -152,6 +154,10 @@ int idServers(); std::map > sendIdList; std::list pendingDiscReplyInList; + + // Neighbors at the gpg level. + // + std::map > gpg_neighbors ; }; diff --git a/retroshare-gui/src/gui/NetworkView.cpp b/retroshare-gui/src/gui/NetworkView.cpp index 279b23775..eae445947 100644 --- a/retroshare-gui/src/gui/NetworkView.cpp +++ b/retroshare-gui/src/gui/NetworkView.cpp @@ -54,11 +54,10 @@ NetworkView::NetworkView(QWidget *parent) setMaxFriendLevel(ui.maxFriendLevelSB->value()) ; /* add button */ - connect( ui.refreshButton, SIGNAL( clicked( void ) ), this, SLOT( updateDisplay( void ) ) ); + connect( ui.refreshButton, SIGNAL( clicked( void ) ), this, SLOT( redraw( void ) ) ); connect( mScene, SIGNAL( changed ( const QList & ) ), this, SLOT ( changedScene( void ) ) ); /* Hide Settings frame */ - shownwSettingsFrame(false); connect( ui.maxFriendLevelSB, SIGNAL(valueChanged(int)), this, SLOT(setMaxFriendLevel(int))); connect( ui.edgeLengthSB, SIGNAL(valueChanged(int)), this, SLOT(setEdgeLength(int))); @@ -71,6 +70,8 @@ void NetworkView::setEdgeLength(int l) } void NetworkView::setMaxFriendLevel(int m) { + ui.graphicsView->snapshotNodesPositions() ; + clear() ; _max_friend_level = m ; updateDisplay() ; } @@ -78,51 +79,26 @@ void NetworkView::changedFoFCheckBox( ) { updateDisplay(); } - -void NetworkView::clearPeerItems() +void NetworkView::redraw() { - std::map::iterator pit; - - for(pit = mPeerItems.begin(); pit != mPeerItems.end(); pit++) - { - mScene->destroyItemGroup((QGraphicsItemGroup *) pit->second); - } - mPeerItems.clear(); + ui.graphicsView->clearNodesPositions() ; + clear() ; + updateDisplay() ; } - -void NetworkView::clearOtherItems() +void NetworkView::clear() { - std::list::iterator oit; - - for(oit = mOtherItems.begin(); oit != mOtherItems.end(); oit++) - { - mScene->removeItem(*oit); - delete (*oit); - } - mOtherItems.clear(); -} - - -void NetworkView::clearLineItems() -{ - std::list::iterator oit; - - for(oit = mLineItems.begin(); oit != mLineItems.end(); oit++) - { - mScene->removeItem(*oit); - delete (*oit); - } - mLineItems.clear(); + ui.graphicsView->clearGraph() ; + _node_ids.clear() ; + update() ; } class NodeInfo { public: - NodeInfo(const std::string& _gpg_id,const std::string& _ssl_id,uint32_t lev) : gpg_id(_gpg_id),ssl_id(_ssl_id),friend_level(lev) {} + NodeInfo(const std::string& _gpg_id,uint32_t lev) : gpg_id(_gpg_id),friend_level(lev) {} std::string gpg_id ; - std::string ssl_id ; uint32_t friend_level ; } ; @@ -139,7 +115,6 @@ void NetworkView::updateDisplay() /* add all friends */ std::string ownGPGId = rsPeers->getGPGOwnId(); - std::string ownSSLId = rsPeers->getOwnId(); #ifdef DEBUG_NETWORKVIEW std::cerr << "NetworkView::updateDisplay()" << std::endl; #endif @@ -149,31 +124,9 @@ void NetworkView::updateDisplay() std::deque nodes_to_treat ; // list of nodes to be treated. Used as a queue. The int is the level of friendness std::set nodes_considered ; // list of nodes already considered. Eases lookup. - nodes_to_treat.push_front(NodeInfo(ownGPGId,ownSSLId,0)) ; // initialize queue with own id. + nodes_to_treat.push_front(NodeInfo(ownGPGId,0)) ; // initialize queue with own id. nodes_considered.insert(rsPeers->getOwnId()) ; - // compute the list of GPG friends - - std::set gpg_friends ; - std::list friends ; - std::set ssl_friends ; - - if(!rsPeers->getFriendList(friends)) - return ; - - for(std::list::const_iterator it(friends.begin());it!=friends.end();++it) - { - RsPeerDetails d ; - if(!rsPeers->getPeerDetails(*it,d)) - continue ; - - gpg_friends.insert(d.gpg_id) ; - ssl_friends.insert(d.id) ; - } -#ifdef DEBUG_NETWORKVIEW - std::cerr << "Found " << ssl_friends.size() << " gpg friends." << std::endl ; -#endif - // Put own id in queue, and empty the queue, treating all nodes. // while(!nodes_to_treat.empty()) @@ -181,85 +134,63 @@ void NetworkView::updateDisplay() NodeInfo info(nodes_to_treat.back()) ; nodes_to_treat.pop_back() ; #ifdef DEBUG_NETWORKVIEW - std::cerr << " Poped out of queue: " << info.ssl_id << ", with level " << info.friend_level << std::endl ; + std::cerr << " Poped out of queue: " << info.gpg_id << ", with level " << info.friend_level << std::endl ; #endif + GraphWidget::NodeType type ; + GraphWidget::AuthType auth ; + + switch(info.friend_level) + { + case 0: type = GraphWidget::ELASTIC_NODE_TYPE_OWN ; + break ; + case 1: type = GraphWidget::ELASTIC_NODE_TYPE_FRIEND ; + break ; + case 2: type = GraphWidget::ELASTIC_NODE_TYPE_F_OF_F ; + break ; + default: + type = GraphWidget::ELASTIC_NODE_TYPE_UNKNOWN ; + } + + RsPeerDetails detail ; + if(!rsPeers->getPeerDetails(info.gpg_id, detail)) + continue ; + + switch(detail.validLvl) + { + case GPGME_VALIDITY_MARGINAL: auth = GraphWidget::ELASTIC_NODE_AUTH_MARGINAL ; break; + case GPGME_VALIDITY_FULL: + case GPGME_VALIDITY_ULTIMATE: auth = GraphWidget::ELASTIC_NODE_AUTH_FULL ; break; + case GPGME_VALIDITY_UNKNOWN: + case GPGME_VALIDITY_UNDEFINED: + case GPGME_VALIDITY_NEVER: + default: auth = GraphWidget::ELASTIC_NODE_AUTH_UNKNOWN ; break ; + } + + if(info.friend_level <= _max_friend_level && _node_ids.find(info.gpg_id) == _node_ids.end()) + { + _node_ids[info.gpg_id] = ui.graphicsView->addNode(" "+detail.name, detail.name+"@"+detail.gpg_id,type,auth,"",info.gpg_id); +#ifdef DEBUG_NETWORKVIEW + std::cerr << " inserted node " << info.gpg_id << ", type=" << type << ", auth=" << auth << std::endl ; +#endif + } + std::list friendList; - rsDisc->getDiscFriends(info.ssl_id, friendList); + rsDisc->getDiscGPGFriends(info.gpg_id, friendList); #ifdef DEBUG_NETWORKVIEW std::cerr << " Got a list of " << friendList.size() << " friends for this peer." << std::endl ; #endif -// if(!rsPeers->getPeerDetails(info.gpg_id,detail)) -// { -// std::cerr << "Could not request GPG details for node " << info.gpg_id << std::endl ; -// continue ; -// } - -// if(info.friend_level <= _max_friend_level && (info.friend_level != 1 || ssl_friends.find(info.ssl_id) != ssl_friends.end())) - { - GraphWidget::NodeType type ; - GraphWidget::AuthType auth ; - - switch(info.friend_level) - { - case 0: type = GraphWidget::ELASTIC_NODE_TYPE_OWN ; - break ; - case 1: type = GraphWidget::ELASTIC_NODE_TYPE_FRIEND ; - break ; - case 2: type = GraphWidget::ELASTIC_NODE_TYPE_F_OF_F ; - break ; - default: - type = GraphWidget::ELASTIC_NODE_TYPE_UNKNOWN ; - } - - RsPeerDetails detail ; - if (!rsPeers->getPeerDetails(info.ssl_id, detail)) - continue ; - - switch(detail.validLvl) - { - case GPGME_VALIDITY_MARGINAL: auth = GraphWidget::ELASTIC_NODE_AUTH_MARGINAL ; break; - case GPGME_VALIDITY_FULL: - case GPGME_VALIDITY_ULTIMATE: auth = GraphWidget::ELASTIC_NODE_AUTH_FULL ; break; - case GPGME_VALIDITY_UNKNOWN: - case GPGME_VALIDITY_UNDEFINED: - case GPGME_VALIDITY_NEVER: - default: auth = GraphWidget::ELASTIC_NODE_AUTH_UNKNOWN ; break ; - } - - if(_node_ids.find(info.ssl_id) == _node_ids.end()) - { - _node_ids[info.ssl_id] = ui.graphicsView->addNode(" "+detail.name +"("+detail.location+")", "("+detail.name+","+info.ssl_id+","+detail.gpg_id+")",type,auth,info.ssl_id,info.gpg_id); -#ifdef DEBUG_NETWORKVIEW - std::cerr << " inserted node " << info.ssl_id << ", type=" << type << ", auth=" << auth << std::endl ; - std::cerr << " NetworkView::updateDisplay() Added Friend: " << info.ssl_id << std::endl; -#endif - } + if(info.friend_level+1 <= _max_friend_level) for(std::list::const_iterator sit(friendList.begin()); sit != friendList.end(); ++sit) if(nodes_considered.find(*sit) == nodes_considered.end()) { #ifdef DEBUG_NETWORKVIEW std::cerr << " adding to queue: " << *sit << ", with level " << info.friend_level+1 << std::endl ; #endif - nodes_to_treat.push_front( NodeInfo("unknown",*sit,info.friend_level + 1) ) ; + nodes_to_treat.push_front( NodeInfo(*sit,info.friend_level + 1) ) ; nodes_considered.insert(*sit) ; } - - // now insert in list the GPG signers that are not our friends, to get 2nd order peers in the network. - // - for(std::list::const_iterator sit(detail.gpgSigners.begin()); sit != detail.gpgSigners.end(); ++sit) - if(nodes_considered.find(*sit) == nodes_considered.end() && gpg_friends.find(*sit) == gpg_friends.end()) - { -#ifdef DEBUG_NETWORKVIEW - std::cerr << " adding to queue: " << *sit << ", with level " << info.friend_level+1 << std::endl ; -#endif - nodes_to_treat.push_front( NodeInfo(*sit,*sit,info.friend_level + 1) ) ; - nodes_considered.insert(*sit) ; - gpg_friends.insert(*sit) ; - } - - } } /* iterate through all friends */ @@ -272,39 +203,20 @@ void NetworkView::updateDisplay() { std::list friendList ; - if(rsDisc->getDiscFriends(it->first,friendList)) + if(rsDisc->getDiscGPGFriends(it->first,friendList)) for(std::list::const_iterator sit(friendList.begin()); sit != friendList.end(); sit++) { - if(it->first < *sit) - { #ifdef DEBUG_NETWORKVIEW - std::cerr << "NetworkView: Adding Arrow: "; + std::cerr << "NetworkView: Adding Edge: "; std::cerr << *sit << " <-> " << it->first; std::cerr << std::endl; #endif if(_node_ids.find(*sit) != _node_ids.end()) ui.graphicsView->addEdge(_node_ids[*sit], it->second); - } } } _should_update = false ; } -/** -Toggles the Settings pane on and off, changes toggle button text - */ -void NetworkView::shownwSettingsFrame(bool show) -{ - if (show) { -// ui.viewsettingsframe->setVisible(true); -// ui.nviewsettingsButton->setChecked(true); -// ui.nviewsettingsButton->setToolTip(tr("Hide Settings")); - } else { -// ui.viewsettingsframe->setVisible(false); -// ui.nviewsettingsButton->setChecked(false); -// ui.nviewsettingsButton->setToolTip(tr("Show Settings")); - } -} - diff --git a/retroshare-gui/src/gui/NetworkView.h b/retroshare-gui/src/gui/NetworkView.h index 9c69f3481..c3f2f2c2d 100644 --- a/retroshare-gui/src/gui/NetworkView.h +++ b/retroshare-gui/src/gui/NetworkView.h @@ -46,25 +46,14 @@ class NetworkView : public RsAutoUpdatePage void setEdgeLength(int) ; void changedFoFCheckBox( ); - - /** Called when Settings button is toggled */ - void shownwSettingsFrame(bool show); + void redraw(); private: - void clearPeerItems(); - void clearOtherItems(); - void clearLineItems(); + void clear(); QGraphicsScene *mScene; - std::map mPeerItems; - std::list mOtherItems; - - std::list mLineItems; - bool mLineChanged; - - /** Qt Designer generated object */ Ui::NetworkView ui; int _max_friend_level ; diff --git a/retroshare-gui/src/gui/NetworkView.ui b/retroshare-gui/src/gui/NetworkView.ui index 8f0628df1..43ca36e9b 100644 --- a/retroshare-gui/src/gui/NetworkView.ui +++ b/retroshare-gui/src/gui/NetworkView.ui @@ -54,6 +54,9 @@ + + false + Basic @@ -73,6 +76,9 @@ + + false + Display mode: @@ -84,7 +90,10 @@ 0 - 10 + 2 + + + 1 diff --git a/retroshare-gui/src/gui/elastic/graphwidget.cpp b/retroshare-gui/src/gui/elastic/graphwidget.cpp index 130f0e27e..1d5c432f1 100644 --- a/retroshare-gui/src/gui/elastic/graphwidget.cpp +++ b/retroshare-gui/src/gui/elastic/graphwidget.cpp @@ -166,10 +166,34 @@ GraphWidget::NodeId GraphWidget::addNode(const std::string& node_short_string,co node->setToolTip(QString::fromStdString(node_complete_string)) ; _nodes.push_back(node) ; scene()->addItem(node); - node->setPos(rand()%1000/53.0f, rand()%1000/53.0f); + + std::map::const_iterator it(_node_cached_positions.find(gpg_id)) ; + if(_node_cached_positions.end() != it) + node->setPos(it->second) ; + else + { + qreal x1,y1,x2,y2 ; + sceneRect().getCoords(&x1,&y1,&x2,&y2) ; + + float f1 = rand()/(float)RAND_MAX ; + float f2 = rand()/(float)RAND_MAX ; + + node->setPos(x1+f1*(x2-x1),y1+f2*(y2-y1)); + } + std::cerr << "Added node " << _nodes.size()-1 << std::endl ; return _nodes.size()-1 ; } +void GraphWidget::snapshotNodesPositions() +{ + for(uint32_t i=0;i<_nodes.size();++i) + _node_cached_positions[_nodes[i]->idString()] = _nodes[i]->mapToScene(QPointF(0,0)) ; +} +void GraphWidget::clearNodesPositions() +{ + _node_cached_positions.clear() ; +} + GraphWidget::EdgeId GraphWidget::addEdge(NodeId n1,NodeId n2) { std::pair ed(std::min(n1,n2),std::max(n1,n2)) ; diff --git a/retroshare-gui/src/gui/elastic/graphwidget.h b/retroshare-gui/src/gui/elastic/graphwidget.h index 4e337862f..de71b59a2 100644 --- a/retroshare-gui/src/gui/elastic/graphwidget.h +++ b/retroshare-gui/src/gui/elastic/graphwidget.h @@ -75,6 +75,8 @@ public: NodeId addNode(const std::string& NodeShortText,const std::string& nodeCompleteText,NodeType type,AuthType auth,const std::string& ssl_id,const std::string& gpg_id) ; EdgeId addEdge(NodeId n1,NodeId n2) ; + void snapshotNodesPositions() ; + void clearNodesPositions() ; void clearGraph() ; virtual void itemMoved(); @@ -96,6 +98,7 @@ private: std::vector _nodes ; std::map,Edge *> _edges ; + std::map _node_cached_positions ; uint32_t _edge_length ; }; diff --git a/retroshare-gui/src/gui/elastic/node.cpp b/retroshare-gui/src/gui/elastic/node.cpp index ca99b9ec8..0e7d7f0c8 100644 --- a/retroshare-gui/src/gui/elastic/node.cpp +++ b/retroshare-gui/src/gui/elastic/node.cpp @@ -187,8 +187,10 @@ void Node::calculateForces(const double *map,int width,int height,int W,int H,fl // now time filter: - _speedx += xforce / MASS_FACTOR; - _speedy += yforce / MASS_FACTOR; + float f = (_type == GraphWidget::ELASTIC_NODE_TYPE_OWN)?10.0f:1.0f ; + + _speedx += xforce / (MASS_FACTOR * f); + _speedy += yforce / (MASS_FACTOR * f); if(_speedx > 10) _speedx = 10.0f ; if(_speedy > 10) _speedy = 10.0f ; @@ -203,8 +205,8 @@ void Node::calculateForces(const double *map,int width,int height,int W,int H,fl bool Node::advance() { - if(_type == GraphWidget::ELASTIC_NODE_TYPE_OWN) - return false; +// if(_type == GraphWidget::ELASTIC_NODE_TYPE_OWN) +// return false; float f = std::max(fabs(newPos.x() - pos().x()), fabs(newPos.y() - pos().y())) ; diff --git a/retroshare-gui/src/gui/elastic/node.h b/retroshare-gui/src/gui/elastic/node.h index 0eebdcc3f..12094fc13 100644 --- a/retroshare-gui/src/gui/elastic/node.h +++ b/retroshare-gui/src/gui/elastic/node.h @@ -63,6 +63,7 @@ public: const QList& edges() const; int type() const { return Type; } + const std::string& idString() const { return _gpg_id ; } void calculateForces(const double *data,int width,int height,int W,int H,float x,float y,float speedf); bool advance();