diff --git a/libretroshare/src/chat/distributedchat.cc b/libretroshare/src/chat/distributedchat.cc index 0a72cadf6..40f62fbe9 100644 --- a/libretroshare/src/chat/distributedchat.cc +++ b/libretroshare/src/chat/distributedchat.cc @@ -23,8 +23,9 @@ * */ -#include +#include #include +#include #include #include "util/rsprint.h" @@ -535,8 +536,9 @@ void DistributedChatService::handleRecvChatLobbyList(RsChatLobbyListItem *item) #ifdef DEBUG_CHAT_LOBBIES std::cerr << " lobby is flagged as autosubscribed. Adding it to subscribe list." << std::endl; #endif - ChatLobbyId clid = item->lobbies[i].id; - chatLobbyToSubscribe.push_back(clid); + ChatLobbyId clid = item->lobbies[i].id; + if(_chat_lobbys.find(clid) == _chat_lobbys.end()) + chatLobbyToSubscribe.push_back(clid); } // for subscribed lobbies, check that item->PeerId() is among the participating friends. If not, add him! @@ -554,9 +556,37 @@ void DistributedChatService::handleRecvChatLobbyList(RsChatLobbyListItem *item) } } - std::list::iterator it; - for (it = chatLobbyToSubscribe.begin(); it != chatLobbyToSubscribe.end(); ++it) - joinVisibleChatLobby(*it,_default_identity); + std::list::iterator it; + for (it = chatLobbyToSubscribe.begin(); it != chatLobbyToSubscribe.end(); ++it) + { + RsGxsId gxsId = _lobby_default_identity[*it]; + if (gxsId.isNull()) + gxsId = _default_identity; + + //Check if gxsId can connect to this lobby + ChatLobbyFlags flags(0); + std::map::const_iterator vlIt = _visible_lobbies.find(*it) ; + if(vlIt != _visible_lobbies.end()) + flags = vlIt->second.lobby_flags; + else + { + std::map::const_iterator clIt = _chat_lobbys.find(*it) ; + + if(clIt != _chat_lobbys.end()) + flags = clIt->second.lobby_flags; + } + + RsIdentityDetails idd ; + if(IS_PGP_SIGNED_LOBBY(flags) + && (!rsIdentity->getIdDetails(gxsId,idd) + || !(idd.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED)) ) + { + std::cerr << "(EE) Attempt to auto-subscribe to signed lobby with non signed Id. Remove it." << std::endl; + setLobbyAutoSubscribe(*it, false); + } else { + joinVisibleChatLobby(*it,gxsId); + } + } for(std::list::const_iterator it = invitationNeeded.begin();it!=invitationNeeded.end();++it) invitePeerToLobby(*it,item->PeerId(),false) ; @@ -1765,13 +1795,18 @@ bool DistributedChatService::setIdentityForChatLobby(const ChatLobbyId& lobby_id void DistributedChatService::setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe) { - if(autoSubscribe) - _known_lobbies_flags[lobby_id] |= RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE ; - else + if(autoSubscribe){ + _known_lobbies_flags[lobby_id] |= RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE; + RsGxsId gxsId; + if (getIdentityForChatLobby(lobby_id, gxsId)) + _lobby_default_identity[lobby_id] = gxsId; + } else { _known_lobbies_flags[lobby_id] &= ~RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE ; - + _lobby_default_identity.erase(lobby_id); + } + RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_ADD) ; - triggerConfigSave(); + triggerConfigSave(); } bool DistributedChatService::getLobbyAutoSubscribe(const ChatLobbyId& lobby_id) @@ -1891,7 +1926,7 @@ void DistributedChatService::cleanLobbyCaches() void DistributedChatService::addToSaveList(std::list& list) const { /* Save Lobby Auto Subscribe */ - for(std::map::const_iterator it=_known_lobbies_flags.begin();it!=_known_lobbies_flags.end();++it) + for(std::map::const_iterator it=_known_lobbies_flags.begin(); it!=_known_lobbies_flags.end(); ++it) { RsChatLobbyConfigItem *clci = new RsChatLobbyConfigItem ; clci->lobby_Id=it->first; @@ -1899,37 +1934,85 @@ void DistributedChatService::addToSaveList(std::list& list) const list.push_back(clci) ; } + /* Save Default Nick Name */ + { + RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ; + RsTlvKeyValue kv; + kv.key = "DEFAULT_IDENTITY"; + kv.value = _default_identity.toStdString(); + vitem->tlvkvs.pairs.push_back(kv); + list.push_back(vitem); + } - RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ; - RsTlvKeyValue kv; - kv.key = "DEFAULT_IDENTITY" ; - kv.value = _default_identity.toStdString() ; - vitem->tlvkvs.pairs.push_back(kv) ; + /* Save Default Nick Name by Lobby*/ + for(std::map::const_iterator it=_lobby_default_identity.begin(); it!=_lobby_default_identity.end(); ++it) + { + RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ; + ChatLobbyId cli = it->first; + RsGxsId gxsId = it->second; + + std::stringstream stream; + stream << std::setfill ('0') << std::setw(sizeof(ChatLobbyId)*2) + << std::hex << cli; + std::string strCli( stream.str() ); + + RsTlvKeyValue kv; + kv.key = "LOBBY_DEFAULT_IDENTITY:"+strCli; + kv.value = gxsId.toStdString(); + vitem->tlvkvs.pairs.push_back(kv); + list.push_back(vitem); + } - list.push_back(vitem) ; } bool DistributedChatService::processLoadListItem(const RsItem *item) { - const RsConfigKeyValueSet *vitem = NULL ; + const RsConfigKeyValueSet *vitem = NULL; + const std::string strldID = "LOBBY_DEFAULT_IDENTITY:"; if(NULL != (vitem = dynamic_cast(item))) - for(std::list::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) - if(kit->key == "DEFAULT_IDENTITY") - { + for(std::list::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) + { + if( kit->key == "DEFAULT_IDENTITY" ) + { #ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Loaded config default nick name for distributed chat: " << kit->value << std::endl ; + std::cerr << "Loaded config default nick name for distributed chat: " << kit->value << std::endl ; #endif - if (!kit->value.empty()) - { - _default_identity = RsGxsId(kit->value) ; - if(_default_identity.isNull()) - std::cerr << "ERROR: default identity is malformed." << std::endl; - } + if (!kit->value.empty()) + { + _default_identity = RsGxsId(kit->value) ; + if(_default_identity.isNull()) + std::cerr << "ERROR: default identity is malformed." << std::endl; + } - return true; - } + return true; + } + + if( kit->key.compare(0, strldID.length(), strldID) == 0) + { +#ifdef DEBUG_CHAT_LOBBIES + std::cerr << "Loaded config lobby default nick name: " << kit->key << " " << kit->value << std::endl ; +#endif + + std::string strCli = kit->key.substr(strldID.length()); + std::stringstream stream; + stream << std::hex << strCli; + ChatLobbyId cli = 0; + stream >> cli; + + if (!kit->value.empty() && (cli != 0)) + { + RsGxsId gxsId(kit->value); + if (gxsId.isNull()) + std::cerr << "ERROR: lobby default identity is malformed." << std::endl; + else + _lobby_default_identity[cli] = gxsId ; + } + + return true; + } + } const RsChatLobbyConfigItem *clci = NULL ; diff --git a/libretroshare/src/chat/distributedchat.h b/libretroshare/src/chat/distributedchat.h index fef46b278..ed5a438f9 100644 --- a/libretroshare/src/chat/distributedchat.h +++ b/libretroshare/src/chat/distributedchat.h @@ -158,7 +158,8 @@ class DistributedChatService time_t last_lobby_challenge_time ; // prevents bruteforce attack time_t last_visible_lobby_info_request_time ; // allows to ask for updates bool _should_reset_lobby_counts ; - RsGxsId _default_identity ; + RsGxsId _default_identity; + std::map _lobby_default_identity; uint32_t mServType ; RsMutex mDistributedChatMtx ; diff --git a/retroshare-gui/src/gui/ChatLobbyWidget.cpp b/retroshare-gui/src/gui/ChatLobbyWidget.cpp index dadf04939..d36602f64 100644 --- a/retroshare-gui/src/gui/ChatLobbyWidget.cpp +++ b/retroshare-gui/src/gui/ChatLobbyWidget.cpp @@ -820,7 +820,8 @@ void ChatLobbyWidget::autoSubscribeLobby(QTreeWidgetItem *item) ChatLobbyId id = item->data(COLUMN_DATA, ROLE_ID).toULongLong(); bool isAutoSubscribe = rsMsgs->getLobbyAutoSubscribe(id); rsMsgs->setLobbyAutoSubscribe(id, !isAutoSubscribe); - if (!isAutoSubscribe) subscribeChatLobbyAtItem(item); + if (!isAutoSubscribe && !item->data(COLUMN_DATA, ROLE_SUBSCRIBED).toBool()) + subscribeChatLobbyAtItem(item); } void ChatLobbyWidget::showBlankPage(ChatLobbyId id)