From d32daaa111520712fd28a3ba2e72a3173ed37d01 Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 1 May 2020 00:00:13 +0200 Subject: [PATCH] made group notifications separate so that they can be treated more easily and added group item to new_group notifications, to allow more GUI notifications --- libretroshare/src/gxs/rsgenexchange.cc | 104 +++++---- libretroshare/src/gxs/rsgxsnotify.h | 25 +-- libretroshare/src/gxstrans/p3gxstrans.cc | 7 +- libretroshare/src/services/p3gxschannels.cc | 75 +++---- libretroshare/src/services/p3gxscircles.cc | 229 +++++++++----------- libretroshare/src/services/p3gxsforums.cc | 151 +++++-------- libretroshare/src/services/p3idservice.cc | 18 +- libretroshare/src/services/p3postbase.cc | 59 ++--- 8 files changed, 293 insertions(+), 375 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 7ed1b498a..18f62a4a3 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -236,14 +236,19 @@ void RsGenExchange::tick() if (!grpIds.empty()) { - RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED, false); - gc->mGrpIdList = grpIds; + for(auto& groupId:grpIds) + { + RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_MESSAGES_DELETED, false); + + gc->mGroupId = groupId; + #ifdef GEN_EXCH_DEBUG - std::cerr << " adding the following grp ids to notification: " << std::endl; - for(std::list::const_iterator it(grpIds.begin());it!=grpIds.end();++it) - std::cerr << " " << *it << std::endl; + std::cerr << " adding the following grp ids to notification: " << std::endl; + for(std::list::const_iterator it(grpIds.begin());it!=grpIds.end();++it) + std::cerr << " " << *it << std::endl; #endif - mNotifications.push_back(gc); + mNotifications.push_back(gc); + } // also notify the network exchange service that these groups no longer exist. @@ -1686,7 +1691,8 @@ void RsGenExchange::notifyReceivePublishKey(const RsGxsGroupId &grpId) RS_STACK_MUTEX(mGenMtx); RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY, true); - gc->mGrpIdList.push_back(grpId); + gc->mGroupId = grpId; + mNotifications.push_back(gc); } @@ -1695,7 +1701,8 @@ void RsGenExchange::notifyChangedGroupStats(const RsGxsGroupId &grpId) RS_STACK_MUTEX(mGenMtx); RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_STATISTICS_CHANGED, false); - gc->mGrpIdList.push_back(grpId); + gc->mGroupId = grpId; + mNotifications.push_back(gc); } @@ -2101,11 +2108,13 @@ void RsGenExchange::processGrpMetaChanges() } } - if(!grpChanged.empty()) + for(auto& groupId:grpChanged) { RS_STACK_MUTEX(mGenMtx); + RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED, true); - gc->mGrpIdList = grpChanged; + gc->mGroupId = groupId; + mNotifications.push_back(gc); #ifdef GEN_EXCH_DEBUG std::cerr << " adding the following grp ids to notification: " << std::endl; @@ -2496,15 +2505,17 @@ void RsGenExchange::processGroupDelete() grpDeleted.push_back(note.second); } - if(!grpDeleted.empty()) + for(auto& groupId:grpDeleted) { - RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PUBLISHED, false); - gc->mGrpIdList = grpDeleted; + RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_GROUP_DELETED, false); + gc->mGroupId = groupId; + mNotifications.push_back(gc); } mGroupDeletePublish.clear(); } + void RsGenExchange::processMessageDelete() { RS_STACK_MUTEX(mGenMtx) ; @@ -2523,31 +2534,29 @@ void RsGenExchange::processMessageDelete() mDataStore->removeMsgs( (*vit).mMsgs ); } +// std::list grpDeleted; +// std::map::iterator mit = toNotify.begin(); +// for(; mit != toNotify.end(); ++mit) +// { +// GrpNote& note = mit->second; +// uint8_t status = note.first ? RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE +// : RsTokenService::GXS_REQUEST_V2_STATUS_FAILED; +// +// mGrpNotify.insert(std::make_pair(mit->first, note.second)); +// mDataAccess->updatePublicRequestStatus(mit->first, status); +// +// if(note.first) +// grpDeleted.push_back(note.second); +// } -#warning csoler: TODO: notify for deleted messages -#ifdef SUSPENDED - std::list grpDeleted; - std::map::iterator mit = toNotify.begin(); - for(; mit != toNotify.end(); ++mit) - { - GrpNote& note = mit->second; - uint8_t status = note.first ? RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE - : RsTokenService::GXS_REQUEST_V2_STATUS_FAILED; + for(uint32_t i=0;imGroupId = it->first; - mGrpNotify.insert(std::make_pair(mit->first, note.second)); - mDataAccess->updatePublicRequestStatus(mit->first, status); - - if(note.first) - grpDeleted.push_back(note.second); - } - - if(!grpDeleted.empty()) - { - RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PUBLISH, false); - gc->mGrpIdList = grpDeleted; - mNotifications.push_back(gc); - } -#endif + mNotifications.push_back(gc); + } mMsgDeletePublish.clear(); } @@ -2807,10 +2816,12 @@ void RsGenExchange::publishGrps() grpChanged.push_back(note.second); } - if(!grpChanged.empty()) + for(auto& groupId:grpChanged) { RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, true); - gc->mGrpIdList = grpChanged; + + gc->mGroupId = groupId; + mNotifications.push_back(gc); #ifdef GEN_EXCH_DEBUG std::cerr << " adding the following grp ids to notification: " << std::endl; @@ -3207,11 +3218,18 @@ void RsGenExchange::processRecvdGroups() vit = tmp ; } - if(!grpIds.empty()) + if(!grps_to_store.empty()) { - RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, false); - c->mGrpIdList = grpIds; - mNotifications.push_back(c); + for(auto Grp:grps_to_store) + { + RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, false); + + c->mGroupId = Grp->grpId; + c->mNewGroupItem = dynamic_cast(mSerialiser->deserialise(Grp->grp.bin_data,&Grp->grp.bin_len)); + + mNotifications.push_back(c); + } + mDataStore->storeGroup(grps_to_store); #ifdef GEN_EXCH_DEBUG std::cerr << " adding the following grp ids to notification: " << std::endl; @@ -3286,7 +3304,7 @@ void RsGenExchange::performUpdateValidation() // Now prepare notification of the client - RsGxsGroupUpdate *c = new RsGxsGroupUpdate(); + RsGxsGroupChange *c = new RsGxsGroupChange(RsGxsNotify::TYPE_UPDATED,false); c->mNewGroupItem = dynamic_cast(mSerialiser->deserialise(gu.newGrp->grp.bin_data,&gu.newGrp->grp.bin_len)); c->mNewGroupItem->meta = *gu.newGrp->metaData; // gu.newGrp will be deleted because mDataStore will destroy it on update diff --git a/libretroshare/src/gxs/rsgxsnotify.h b/libretroshare/src/gxs/rsgxsnotify.h index 847a78d38..0e6d39877 100644 --- a/libretroshare/src/gxs/rsgxsnotify.h +++ b/libretroshare/src/gxs/rsgxsnotify.h @@ -38,6 +38,8 @@ struct RsGxsNotify TYPE_RECEIVED_DISTANT_SEARCH_RESULTS = 0x05, TYPE_STATISTICS_CHANGED = 0x06, TYPE_UPDATED = 0x07, + TYPE_MESSAGES_DELETED = 0x08, + TYPE_GROUP_DELETED = 0x09, }; virtual ~RsGxsNotify() {} @@ -50,29 +52,22 @@ struct RsGxsNotify class RsGxsGroupChange : public RsGxsNotify { public: - RsGxsGroupChange(NotifyType type, bool metaChange) : mNotifyType(type), mMetaChange(metaChange) {} - std::list mGrpIdList; + RsGxsGroupChange(NotifyType type, bool metaChange) : mNewGroupItem(nullptr),mOldGroupItem(nullptr), mNotifyType(type), mMetaChange(metaChange) {} + virtual ~RsGxsGroupChange() { delete mOldGroupItem; delete mNewGroupItem ; } + NotifyType getType() override { return mNotifyType;} bool metaChange() { return mMetaChange; } + RsGxsGroupId mGroupId; // Group id of the group we're talking about. When the group is deleted, it's useful to know which group + // that was although there is no pointers to the actual group data anymore. + RsGxsGrpItem *mNewGroupItem; // Valid when a group has changed, or a new group is received. + RsGxsGrpItem *mOldGroupItem; // only valid when mNotifyType is TYPE_UPDATED + protected: NotifyType mNotifyType; bool mMetaChange; }; -class RsGxsGroupUpdate : public RsGxsNotify -{ -public: - RsGxsGroupUpdate() : mOldGroupItem(nullptr),mNewGroupItem(nullptr) {} - virtual ~RsGxsGroupUpdate() { delete mOldGroupItem; delete mNewGroupItem ; } - - RsGxsGrpItem *mOldGroupItem; - RsGxsGrpItem *mNewGroupItem; - - NotifyType getType() override { return RsGxsNotify::TYPE_UPDATED;} -}; - - class RsGxsDistantSearchResultChange: public RsGxsNotify { public: diff --git a/libretroshare/src/gxstrans/p3gxstrans.cc b/libretroshare/src/gxstrans/p3gxstrans.cc index 92af56f08..b85bcea9a 100644 --- a/libretroshare/src/gxstrans/p3gxstrans.cc +++ b/libretroshare/src/gxstrans/p3gxstrans.cc @@ -656,6 +656,8 @@ void p3GxsTrans::notifyChanges(std::vector& changes) #ifdef DEBUG_GXSTRANS std::cout << "p3GxsTrans::notifyChanges(...)" << std::endl; #endif + std::list grps_to_request; + for( auto it = changes.begin(); it != changes.end(); ++it ) { RsGxsGroupChange* grpChange = dynamic_cast(*it); @@ -666,7 +668,7 @@ void p3GxsTrans::notifyChanges(std::vector& changes) #ifdef DEBUG_GXSTRANS std::cout << "p3GxsTrans::notifyChanges(...) grpChange" << std::endl; #endif - requestGroupsData(&(grpChange->mGrpIdList)); + grps_to_request.push_back(grpChange->mGroupId); } else if(msgChange) { @@ -698,6 +700,9 @@ void p3GxsTrans::notifyChanges(std::vector& changes) } delete *it; } + + if(!grps_to_request.empty()) + requestGroupsData(&grps_to_request); } uint32_t p3GxsTrans::AuthenPolicy() diff --git a/libretroshare/src/services/p3gxschannels.cc b/libretroshare/src/services/p3gxschannels.cc index 9e0072d5b..40df82862 100644 --- a/libretroshare/src/services/p3gxschannels.cc +++ b/libretroshare/src/services/p3gxschannels.cc @@ -304,71 +304,52 @@ void p3GxsChannels::notifyChanges(std::vector &changes) { case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed { - std::list &grpList = grpChange->mGrpIdList; - std::list::iterator git; - for (git = grpList.begin(); git != grpList.end(); ++git) - { - auto ev = std::make_shared(); - ev->mChannelGroupId = *git; - ev->mChannelEventCode = RsChannelEventCode::SUBSCRIBE_STATUS_CHANGED; - rsEvents->postEvent(ev); - } - + auto ev = std::make_shared(); + ev->mChannelGroupId = grpChange->mGroupId; + ev->mChannelEventCode = RsChannelEventCode::SUBSCRIBE_STATUS_CHANGED; + rsEvents->postEvent(ev); } break; case RsGxsNotify::TYPE_STATISTICS_CHANGED: - { - std::list &grpList = grpChange->mGrpIdList; - std::list::iterator git; - for (git = grpList.begin(); git != grpList.end(); ++git) - { - auto ev = std::make_shared(); - ev->mChannelGroupId = *git; - ev->mChannelEventCode = RsChannelEventCode::STATISTICS_CHANGED; - rsEvents->postEvent(ev); - } - } + { + auto ev = std::make_shared(); + ev->mChannelGroupId = grpChange->mGroupId; + ev->mChannelEventCode = RsChannelEventCode::STATISTICS_CHANGED; + rsEvents->postEvent(ev); + } break; case RsGxsNotify::TYPE_PUBLISHED: case RsGxsNotify::TYPE_RECEIVED_NEW: { /* group received */ - std::list &grpList = grpChange->mGrpIdList; - std::list::iterator git; - RS_STACK_MUTEX(mKnownChannelsMutex); - for (git = grpList.begin(); git != grpList.end(); ++git) - { - if(mKnownChannels.find(*git) == mKnownChannels.end()) - { - mKnownChannels.insert(std::make_pair(*git,time(NULL))) ; - IndicateConfigChanged(); - auto ev = std::make_shared(); - ev->mChannelGroupId = *git; - ev->mChannelEventCode = RsChannelEventCode::NEW_CHANNEL; - rsEvents->postEvent(ev); - } - else - std::cerr << "(II) Not notifying already known channel " << *git << std::endl; + RS_STACK_MUTEX(mKnownChannelsMutex); + + if(mKnownChannels.find(grpChange->mGroupId) == mKnownChannels.end()) + { + mKnownChannels.insert(std::make_pair(grpChange->mGroupId,time(NULL))) ; + IndicateConfigChanged(); + + auto ev = std::make_shared(); + ev->mChannelGroupId = grpChange->mGroupId; + ev->mChannelEventCode = RsChannelEventCode::NEW_CHANNEL; + rsEvents->postEvent(ev); } - break; + else + std::cerr << "(II) Not notifying already known channel " << grpChange->mGroupId << std::endl; } + break; case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY: { /* group received */ - std::list &grpList = grpChange->mGrpIdList; - std::list::iterator git; - for (git = grpList.begin(); git != grpList.end(); ++git) - { - auto ev = std::make_shared(); - ev->mChannelGroupId = *git; - ev->mChannelEventCode = RsChannelEventCode::RECEIVED_PUBLISH_KEY; + auto ev = std::make_shared(); + ev->mChannelGroupId = grpChange->mGroupId; + ev->mChannelEventCode = RsChannelEventCode::RECEIVED_PUBLISH_KEY; - rsEvents->postEvent(ev); - } + rsEvents->postEvent(ev); } break; diff --git a/libretroshare/src/services/p3gxscircles.cc b/libretroshare/src/services/p3gxscircles.cc index 44b095ac5..e300f8a11 100644 --- a/libretroshare/src/services/p3gxscircles.cc +++ b/libretroshare/src/services/p3gxscircles.cc @@ -535,7 +535,6 @@ void p3GxsCircles::notifyChanges(std::vector &changes) for(auto it = changes.begin(); it != changes.end(); ++it) { - RsGxsGroupChange *groupChange = dynamic_cast(*it); RsGxsMsgChange *msgChange = dynamic_cast(*it); RsGxsNotify *c = *it; @@ -581,93 +580,127 @@ void p3GxsCircles::notifyChanges(std::vector &changes) } } + RsGxsGroupChange *groupChange = dynamic_cast(*it); + /* add groups to ExternalIdList (Might get Personal Circles here until NetChecks in place) */ - if (groupChange && !groupChange->metaChange()) - { -#ifdef DEBUG_CIRCLES - std::cerr << " Found Group Change Notification" << std::endl; -#endif - for(std::list::iterator git = groupChange->mGrpIdList.begin(); git != groupChange->mGrpIdList.end(); ++git) - { -#ifdef DEBUG_CIRCLES - std::cerr << " Incoming Group: " << *git << ". Forcing cache load." << std::endl; -#endif - - // for new circles we need to add them to the list. - // we don't know the type of this circle here - // original behavior was to add all ids to the external ids list - - addCircleIdToList(RsGxsCircleId(*git), 0); - - // reset the cached circle data for this id - { - RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ - mCircleCache.erase(RsGxsCircleId(*git)); - mCacheUpdated = true; - } - } - } - - if(groupChange) + if (groupChange) { - std::list own_ids; - rsIdentity->getOwnIds(own_ids); + const RsGxsGroupId *git(&groupChange->mGroupId); - for(std::list::const_iterator git(groupChange->mGrpIdList.begin());git!=groupChange->mGrpIdList.end();++git) + if(!groupChange->metaChange()) { #ifdef DEBUG_CIRCLES - std::cerr << " forcing cache loading for circle " << *git << " in order to trigger subscribe update." << std::endl; + std::cerr << " Found Group Change Notification" << std::endl; +#endif + //for(std::list::iterator git = groupChange->mGrpIdList.begin(); git != groupChange->mGrpIdList.end(); ++git) + { +#ifdef DEBUG_CIRCLES + std::cerr << " Incoming Group: " << *git << ". Forcing cache load." << std::endl; #endif -#ifdef TODO - // This code will not work: we would like to detect changes in the circle data that reflects the fact that one of the - // owned GXS ids is invited. But there's no way to compare the old circle data to the new if cache has to be updated. - // For this we need to add the old metadata and group data in the RsGxsGroupChange structure and account for it. + // for new circles we need to add them to the list. + // we don't know the type of this circle here + // original behavior was to add all ids to the external ids list - if(rsEvents && (c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) ) - { - RsGxsCircleId circle_id(*git); - force_cache_reload(circle_id); + addCircleIdToList(RsGxsCircleId(*git), 0); - RsGxsCircleDetails details; - getCircleDetails(circle_id,details); - - // We check that the change corresponds to one of our own ids. Since we do not know what the change is, we notify - // for whatever is different from what is currently known. Other ids, that get invited only trigger a notification when the - // ID also accepts the invitation, so it becomes a member of the circle. - - for(auto own_id: own_ids) + // reset the cached circle data for this id { - auto it = details.mSubscriptionFlags.find(own_id); - - if(it == details.mSubscriptionFlags.end()) - continue; - - bool invited ( it->second & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST ); - bool subscrb ( it->second & GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED ); - - if(std::find(details.mAllowedGxsIds.begin(),details.mAllowedGxsIds.end(),id) != details.mAllowedGxsIds.end() && !me_in_circle) - { - auto ev = std::make_shared(); - - ev->mType = RsGxsCircleEvent::CIRCLE_MEMBERSHIP_INVITE; - ev->mCircleId = circle_id; - ev->mGxsId = ; - - rsEvents->sendEvent(ev); - } + RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ + mCircleCache.erase(RsGxsCircleId(*git)); + mCacheUpdated = true; } - } -#endif + } - if(rsEvents && (c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW|| c->getType() == RsGxsNotify::TYPE_PUBLISHED) ) + if(rsEvents) + { + std::list own_ids_lst; + rsIdentity->getOwnIds(own_ids_lst,false); // retrieve own identities + + std::set own_ids; + for(auto& id:own_ids_lst) + own_ids.insert(id); // put them in a std::set for O(log(n)) search + + if(c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW|| c->getType() == RsGxsNotify::TYPE_PUBLISHED) { auto ev = std::make_shared(); ev->mCircleId = RsGxsCircleId(*git); ev->mCircleEventType = RsGxsCircleEventCode::NEW_CIRCLE; + rsEvents->postEvent(ev); + + // we also need to look into invitee list here! + + RsGxsCircleGroupItem *new_circle_grp_item = dynamic_cast(groupChange->mNewGroupItem); + + std::list added_identities; + + for(auto& gxs_id: new_circle_grp_item->gxsIdSet.ids) + if(own_ids.find(gxs_id)!=own_ids.end()) + added_identities.push_back(gxs_id); + + for(auto& gxs_id:added_identities) + { + auto ev = std::make_shared(); + + ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_INVITE; + ev->mCircleId = RsGxsCircleId(*git); + ev->mGxsId = gxs_id; + + rsEvents->sendEvent(ev); + } } + else if(c->getType()==RsGxsNotify::TYPE_UPDATED) + { + // Happens when the group data has changed. In this case we need to analyse the old and new group in order to detect possible notifications for clients + + RsGxsCircleGroupItem *old_circle_grp_item = dynamic_cast(groupChange->mOldGroupItem); + RsGxsCircleGroupItem *new_circle_grp_item = dynamic_cast(groupChange->mNewGroupItem); + + const RsGxsCircleId circle_id ( old_circle_grp_item->meta.mGroupId ); + + if(old_circle_grp_item == nullptr || new_circle_grp_item == nullptr) + { + RsErr() << __PRETTY_FUNCTION__ << " received GxsGroupUpdate item with mOldGroup and mNewGroup not of type RsGxsCircleGroupItem. This is inconsistent!" << std::endl; + delete groupChange; + continue; + } + + // First of all, we check if there is a difference between the old and new list of invited members + + std::list added_identities, removed_identities; + + for(auto& gxs_id: new_circle_grp_item->gxsIdSet.ids) + if(old_circle_grp_item->gxsIdSet.ids.find(gxs_id) == old_circle_grp_item->gxsIdSet.ids.end() && own_ids.find(gxs_id)!=own_ids.end()) + added_identities.push_back(gxs_id); + + for(auto& gxs_id: old_circle_grp_item->gxsIdSet.ids) + if(new_circle_grp_item->gxsIdSet.ids.find(gxs_id) == old_circle_grp_item->gxsIdSet.ids.end() && own_ids.find(gxs_id)!=own_ids.end()) + removed_identities.push_back(gxs_id); + + for(auto& gxs_id:added_identities) + { + auto ev = std::make_shared(); + + ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_INVITE; + ev->mCircleId = circle_id; + ev->mGxsId = gxs_id; + + rsEvents->sendEvent(ev); + } + for(auto& gxs_id:removed_identities) + { + auto ev = std::make_shared(); + + ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REVOKED; + ev->mCircleId = circle_id; + ev->mGxsId = gxs_id; + + rsEvents->sendEvent(ev); + } + + } // reset circle from cache since the number of invitee may have changed. { @@ -679,64 +712,6 @@ void p3GxsCircles::notifyChanges(std::vector &changes) } } - RsGxsGroupUpdate *grpUpdate = dynamic_cast(*it); - - if (grpUpdate && rsEvents) - { - // Happens when the group data has changed. In this case we need to analyse the old and new group in order to detect possible notifications for clients - - RsGxsCircleGroupItem *old_circle_grp_item = dynamic_cast(grpUpdate->mOldGroupItem); - RsGxsCircleGroupItem *new_circle_grp_item = dynamic_cast(grpUpdate->mNewGroupItem); - - const RsGxsCircleId circle_id ( old_circle_grp_item->meta.mGroupId ); - - if(old_circle_grp_item == nullptr || new_circle_grp_item == nullptr) - { - RsErr() << __PRETTY_FUNCTION__ << " received GxsGroupUpdate item with mOldGroup and mNewGroup not of type RsGxsCircleGroupItem. This is inconsistent!" << std::endl; - delete grpUpdate; - continue; - } - - // First of all, we check if there is a difference between the old and new list of invited members - - std::list added_identities, removed_identities; - std::list own_ids_lst; - rsIdentity->getOwnIds(own_ids_lst,false); // retrieve own identities - - std::set own_ids; - for(auto& id:own_ids_lst) - own_ids.insert(id); // put them in a std::set for O(log(n)) search - - for(auto& gxs_id: new_circle_grp_item->gxsIdSet.ids) - if(old_circle_grp_item->gxsIdSet.ids.find(gxs_id) == old_circle_grp_item->gxsIdSet.ids.end() && own_ids.find(gxs_id)!=own_ids.end()) - added_identities.push_back(gxs_id); - - for(auto& gxs_id: old_circle_grp_item->gxsIdSet.ids) - if(new_circle_grp_item->gxsIdSet.ids.find(gxs_id) == old_circle_grp_item->gxsIdSet.ids.end() && own_ids.find(gxs_id)!=own_ids.end()) - removed_identities.push_back(gxs_id); - - for(auto& gxs_id:added_identities) - { - auto ev = std::make_shared(); - - ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_INVITE; - ev->mCircleId = circle_id; - ev->mGxsId = gxs_id; - - rsEvents->sendEvent(ev); - } - for(auto& gxs_id:removed_identities) - { - auto ev = std::make_shared(); - - ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REVOKED; - ev->mCircleId = circle_id; - ev->mGxsId = gxs_id; - - rsEvents->sendEvent(ev); - } - } - delete *it; } } diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index 6b8f91f9f..b81a31479 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -249,16 +249,10 @@ void p3GxsForums::notifyChanges(std::vector &changes) { case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed { - std::list &grpList = grpChange->mGrpIdList; - std::list::iterator git; - for (git = grpList.begin(); git != grpList.end(); ++git) - { auto ev = std::make_shared(); - ev->mForumGroupId = *git; + ev->mForumGroupId = grpChange->mGroupId; ev->mForumEventCode = RsForumEventCode::SUBSCRIBE_STATUS_CHANGED; rsEvents->postEvent(ev); - } - } break; @@ -266,112 +260,81 @@ void p3GxsForums::notifyChanges(std::vector &changes) case RsGxsNotify::TYPE_RECEIVED_NEW: { /* group received */ - std::list &grpList = grpChange->mGrpIdList; - std::list::iterator git; RS_STACK_MUTEX(mKnownForumsMutex); - for (git = grpList.begin(); git != grpList.end(); ++git) - { - if(mKnownForums.find(*git) == mKnownForums.end()) - { - mKnownForums.insert( - std::make_pair(*git, time(nullptr))); - IndicateConfigChanged(); - auto ev = std::make_shared(); - ev->mForumGroupId = *git; - ev->mForumEventCode = RsForumEventCode::NEW_FORUM; - rsEvents->postEvent(ev); - } - else - RsInfo() << __PRETTY_FUNCTION__ - << " Not notifying already known forum " - << *git << std::endl; + if(mKnownForums.find(grpChange->mGroupId) == mKnownForums.end()) + { + mKnownForums.insert( std::make_pair(grpChange->mGroupId, time(nullptr))); + IndicateConfigChanged(); + + auto ev = std::make_shared(); + ev->mForumGroupId = grpChange->mGroupId; + ev->mForumEventCode = RsForumEventCode::NEW_FORUM; + rsEvents->postEvent(ev); } + else + RsInfo() << __PRETTY_FUNCTION__ + << " Not notifying already known forum " + << grpChange->mGroupId << std::endl; } break; case RsGxsNotify::TYPE_STATISTICS_CHANGED: { - std::list &grpList = grpChange->mGrpIdList; - std::list::iterator git; - for (git = grpList.begin(); git != grpList.end(); ++git) + auto ev = std::make_shared(); + ev->mForumGroupId = grpChange->mGroupId; + ev->mForumEventCode = RsForumEventCode::STATISTICS_CHANGED; + rsEvents->postEvent(ev); + } + break; + + case RsGxsNotify::TYPE_UPDATED: + { + // Happens when the group data has changed. In this case we need to analyse the old and new group in order to detect possible notifications for clients + + RsGxsForumGroupItem *old_forum_grp_item = dynamic_cast(grpChange->mOldGroupItem); + RsGxsForumGroupItem *new_forum_grp_item = dynamic_cast(grpChange->mNewGroupItem); + + if(old_forum_grp_item == nullptr || new_forum_grp_item == nullptr) + { + RsErr() << __PRETTY_FUNCTION__ << " received GxsGroupUpdate item with mOldGroup and mNewGroup not of type RsGxsForumGroupItem. This is inconsistent!" << std::endl; + delete grpChange; + continue; + } + + // First of all, we check if there is a difference between the old and new list of moderators + + std::list added_mods, removed_mods; + + for(auto& gxs_id: new_forum_grp_item->mGroup.mAdminList.ids) + if(old_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) == old_forum_grp_item->mGroup.mAdminList.ids.end()) + added_mods.push_back(gxs_id); + + for(auto& gxs_id: old_forum_grp_item->mGroup.mAdminList.ids) + if(new_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) == new_forum_grp_item->mGroup.mAdminList.ids.end()) + removed_mods.push_back(gxs_id); + + if(!added_mods.empty() || !removed_mods.empty()) { auto ev = std::make_shared(); - ev->mForumGroupId = *git; - ev->mForumEventCode = RsForumEventCode::STATISTICS_CHANGED; + + ev->mForumGroupId = new_forum_grp_item->meta.mGroupId; + ev->mModeratorsAdded = added_mods; + ev->mModeratorsRemoved = removed_mods; + ev->mForumEventCode = RsForumEventCode::MODERATOR_LIST_CHANGED; + rsEvents->postEvent(ev); } } - break; + break; + + default: RsErr() << " Got a GXS event of type " << grpChange->getType() << " Currently not handled." << std::endl; break; - - -#ifdef NOT_USED_YET - case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY: - { - /* group received */ - std::list &grpList = grpChange->mGrpIdList; - std::list::iterator git; - for (git = grpList.begin(); git != grpList.end(); ++git) - { - auto ev = std::make_shared(); - - ev->mChannelGroupId = *git; - ev->mChannelEventCode = RsGxsChannelEvent::RECEIVED_PUBLISH_KEY; - - rsEvents->sendEvent(ev); - } - } - break; -#endif } } - - RsGxsGroupUpdate *grpUpdate = dynamic_cast(*it); - - if (grpUpdate && rsEvents) - { - // Happens when the group data has changed. In this case we need to analyse the old and new group in order to detect possible notifications for clients - - RsGxsForumGroupItem *old_forum_grp_item = dynamic_cast(grpUpdate->mOldGroupItem); - RsGxsForumGroupItem *new_forum_grp_item = dynamic_cast(grpUpdate->mNewGroupItem); - - if(old_forum_grp_item == nullptr || new_forum_grp_item == nullptr) - { - RsErr() << __PRETTY_FUNCTION__ << " received GxsGroupUpdate item with mOldGroup and mNewGroup not of type RsGxsForumGroupItem. This is inconsistent!" << std::endl; - delete grpUpdate; - continue; - } - - // First of all, we check if there is a difference between the old and new list of moderators - - std::list added_mods, removed_mods; - - for(auto& gxs_id: new_forum_grp_item->mGroup.mAdminList.ids) - if(old_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) == old_forum_grp_item->mGroup.mAdminList.ids.end()) - added_mods.push_back(gxs_id); - - for(auto& gxs_id: old_forum_grp_item->mGroup.mAdminList.ids) - if(new_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) == new_forum_grp_item->mGroup.mAdminList.ids.end()) - removed_mods.push_back(gxs_id); - - if(!added_mods.empty() || !removed_mods.empty()) - { - auto ev = std::make_shared(); - - ev->mForumGroupId = new_forum_grp_item->meta.mGroupId; - ev->mModeratorsAdded = added_mods; - ev->mModeratorsRemoved = removed_mods; - ev->mForumEventCode = RsForumEventCode::MODERATOR_LIST_CHANGED; - - rsEvents->postEvent(ev); - } - - } - } } diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index b3e30d8ca..4c17a1dda 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -631,16 +631,13 @@ void p3IdService::notifyChanges(std::vector &changes) std::cerr << "p3IdService::notifyChanges() Found Group Change Notification"; std::cerr << std::endl; #endif - std::list &groupList = groupChange->mGrpIdList; - - for(auto git = groupList.begin(); git != groupList.end();++git) - { #ifdef DEBUG_IDS std::cerr << "p3IdService::notifyChanges() Auto Subscribe to Incoming Groups: " << *git; std::cerr << std::endl; #endif + const RsGxsGroupId& gid(groupChange->mGroupId); - if(!rsReputations->isIdentityBanned(RsGxsId(*git))) + if(!rsReputations->isIdentityBanned(RsGxsId(gid))) { // notify that a new identity is received, if needed @@ -654,12 +651,12 @@ void p3IdService::notifyChanges(std::vector &changes) case RsGxsNotify::TYPE_PUBLISHED: { auto ev = std::make_shared(); - ev->mIdentityId = *git; + ev->mIdentityId = gid; ev->mIdentityEventCode = RsGxsIdentityEventCode::UPDATED_IDENTITY; rsEvents->postEvent(ev); // also time_stamp the key that this group represents - timeStampKey(RsGxsId(*git),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ; + timeStampKey(RsGxsId(gid),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ; should_subscribe = true; } break; @@ -667,12 +664,12 @@ void p3IdService::notifyChanges(std::vector &changes) case RsGxsNotify::TYPE_RECEIVED_NEW: { auto ev = std::make_shared(); - ev->mIdentityId = *git; + ev->mIdentityId = gid; ev->mIdentityEventCode = RsGxsIdentityEventCode::NEW_IDENTITY; rsEvents->postEvent(ev); // also time_stamp the key that this group represents - timeStampKey(RsGxsId(*git),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ; + timeStampKey(RsGxsId(gid),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ; should_subscribe = true; } break; @@ -684,11 +681,10 @@ void p3IdService::notifyChanges(std::vector &changes) if(should_subscribe) { uint32_t token; - RsGenExchange::subscribeToGroup(token, *git, true); + RsGenExchange::subscribeToGroup(token, gid, true); } } - } } delete changes[i]; diff --git a/libretroshare/src/services/p3postbase.cc b/libretroshare/src/services/p3postbase.cc index 771103eb0..9c11dcd64 100644 --- a/libretroshare/src/services/p3postbase.cc +++ b/libretroshare/src/services/p3postbase.cc @@ -131,36 +131,25 @@ void p3PostBase::notifyChanges(std::vector &changes) std::cerr << "p3PostBase::notifyChanges() Found Group Change Notification"; std::cerr << std::endl; #endif + const RsGxsGroupId& group_id(grpChange->mGroupId); switch(grpChange->getType()) { case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed { - std::list &grpList = grpChange->mGrpIdList; - std::list::iterator git; - for (git = grpList.begin(); git != grpList.end(); ++git) - { - auto ev = std::make_shared(); - ev->mPostedGroupId = *git; - ev->mPostedEventCode = RsPostedEventCode::SUBSCRIBE_STATUS_CHANGED; - rsEvents->postEvent(ev); - } - + auto ev = std::make_shared(); + ev->mPostedGroupId = group_id; + ev->mPostedEventCode = RsPostedEventCode::SUBSCRIBE_STATUS_CHANGED; + rsEvents->postEvent(ev); } break; case RsGxsNotify::TYPE_STATISTICS_CHANGED: { - std::list &grpList = grpChange->mGrpIdList; - std::list::iterator git; - - for (git = grpList.begin(); git != grpList.end(); ++git) - { - auto ev = std::make_shared(); - ev->mPostedGroupId = *git; - ev->mPostedEventCode = RsPostedEventCode::STATISTICS_CHANGED; - rsEvents->postEvent(ev); - } + auto ev = std::make_shared(); + ev->mPostedGroupId = group_id; + ev->mPostedEventCode = RsPostedEventCode::STATISTICS_CHANGED; + rsEvents->postEvent(ev); } break; @@ -168,30 +157,26 @@ void p3PostBase::notifyChanges(std::vector &changes) case RsGxsNotify::TYPE_RECEIVED_NEW: { /* group received */ - const std::list& grpList = grpChange->mGrpIdList; - for (auto git = grpList.begin(); git != grpList.end(); ++git) + if(mKnownPosted.find(group_id) == mKnownPosted.end()) { - if(mKnownPosted.find(*git) == mKnownPosted.end()) - { - mKnownPosted.insert(std::make_pair(*git, time(nullptr))); - IndicateConfigChanged(); + mKnownPosted.insert(std::make_pair(group_id, time(nullptr))); + IndicateConfigChanged(); - auto ev = std::make_shared(); - ev->mPostedGroupId = *git; - ev->mPostedEventCode = RsPostedEventCode::NEW_POSTED_GROUP; - rsEvents->postEvent(ev); + auto ev = std::make_shared(); + ev->mPostedGroupId = group_id; + ev->mPostedEventCode = RsPostedEventCode::NEW_POSTED_GROUP; + rsEvents->postEvent(ev); #ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << *git; - std::cerr << std::endl; + std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << group_id; + std::cerr << std::endl; #endif - } - else - RsInfo() << __PRETTY_FUNCTION__ - << " Not notifying already known forum " - << *git << std::endl; } + else + RsInfo() << __PRETTY_FUNCTION__ + << " Not notifying already known forum " + << group_id << std::endl; } break;