automaticall save/restore subscribed chat rooms. The advantage is that auto-subscribed is not needed anymore and chat rooms will survive automatically

This commit is contained in:
csoler 2019-06-15 13:54:34 +02:00
parent ee9c240fb0
commit c72b49c296
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
7 changed files with 136 additions and 16 deletions

View File

@ -39,12 +39,12 @@
//#define DEBUG_CHAT_LOBBIES 1
static const int CONNECTION_CHALLENGE_MAX_COUNT = 20 ; // sends a connection challenge every 20 messages
static const rstime_t CONNECTION_CHALLENGE_MAX_MSG_AGE = 30 ; // maximum age of a message to be used in a connection challenge
static const int CONNECTION_CHALLENGE_MIN_DELAY = 15 ; // sends a connection at most every 15 seconds
static const int LOBBY_CACHE_CLEANING_PERIOD = 10 ; // clean lobby caches every 10 secs (remove old messages)
static const int CONNECTION_CHALLENGE_MAX_COUNT = 20 ; // sends a connection challenge every 20 messages
static const rstime_t CONNECTION_CHALLENGE_MAX_MSG_AGE = 30 ; // maximum age of a message to be used in a connection challenge
static const int CONNECTION_CHALLENGE_MIN_DELAY = 15 ; // sends a connection at most every 15 seconds
static const int LOBBY_CACHE_CLEANING_PERIOD = 10 ; // clean lobby caches every 10 secs (remove old messages)
static const rstime_t MAX_KEEP_MSG_RECORD = 1200 ; // keep msg record for 1200 secs max.
static const rstime_t MAX_KEEP_MSG_RECORD = 1200 ; // keep msg record for 1200 secs max.
static const rstime_t MAX_KEEP_INACTIVE_NICKNAME = 180 ; // keep inactive nicknames for 3 mn max.
static const rstime_t MAX_DELAY_BETWEEN_LOBBY_KEEP_ALIVE = 120 ; // send keep alive packet every 2 minutes.
static const rstime_t MAX_KEEP_PUBLIC_LOBBY_RECORD = 60 ; // keep inactive lobbies records for 60 secs max.
@ -52,7 +52,7 @@ static const rstime_t MIN_DELAY_BETWEEN_PUBLIC_LOBBY_REQ = 20 ; // don't ask
static const rstime_t LOBBY_LIST_AUTO_UPDATE_TIME = 121 ; // regularly ask for available lobbies every 5 minutes, to allow auto-subscribe to work
static const uint32_t MAX_ALLOWED_LOBBIES_IN_LIST_WARNING = 50 ;
//static const uint32_t MAX_MESSAGES_PER_SECONDS_NUMBER = 5 ; // max number of messages from a given peer in a window for duration below
//static const uint32_t MAX_MESSAGES_PER_SECONDS_NUMBER = 5 ; // max number of messages from a given peer in a window for duration below
static const uint32_t MAX_MESSAGES_PER_SECONDS_PERIOD = 10 ; // duration window for max number of messages before messages get dropped.
#define IS_PUBLIC_LOBBY(flags) (flags & RS_CHAT_LOBBY_FLAGS_PUBLIC )
@ -1629,6 +1629,8 @@ ChatLobbyId DistributedChatService::createChatLobby(const std::string& lobby_nam
RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_ADD) ;
triggerConfigSave();
return lobby_id ;
}
@ -1826,14 +1828,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;
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);
{
RS_STACK_MUTEX(mDistributedChatMtx);
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) ;
@ -1966,6 +1972,15 @@ void DistributedChatService::addToSaveList(std::list<RsItem*>& list) const
list.push_back(clci) ;
}
for(auto it(_chat_lobbys.begin());it!=_chat_lobbys.end();++it)
{
RsSubscribedChatLobbyConfigItem *scli = new RsSubscribedChatLobbyConfigItem;
scli->info = it->second; // copies the ChatLobbyInfo part only
list.push_back(scli);
}
/* Save Default Nick Name */
{
RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ;
@ -2061,6 +2076,56 @@ bool DistributedChatService::processLoadListItem(const RsItem *item)
if(!own_ids.empty())
_default_identity = own_ids.front() ;
}
const RsSubscribedChatLobbyConfigItem *scli = dynamic_cast<const RsSubscribedChatLobbyConfigItem*>(item);
if(scli != NULL)
{
if(_chat_lobbys.find(scli->info.lobby_id) != _chat_lobbys.end()) // do nothing if the lobby is already subscribed
return true;
std::cerr << "Re-subscribing to chat lobby " << (void*)scli->info.lobby_id << ", flags = " << scli->info.lobby_flags << std::endl;
rstime_t now = time(NULL);
// Add the chat room into visible chat rooms
{
RS_STACK_MUTEX(mDistributedChatMtx); /********** STACK LOCKED MTX ******/
VisibleChatLobbyRecord& rec(_visible_lobbies[scli->info.lobby_id]) ;
rec.lobby_id = scli->info.lobby_id ;
rec.lobby_name = scli->info.lobby_name ;
rec.lobby_topic = scli->info.lobby_topic ;
rec.participating_friends = scli->info.participating_friends;
rec.total_number_of_peers = 0;
rec.last_report_time = now ;
rec.lobby_flags = EXTRACT_PRIVACY_FLAGS(scli->info.lobby_flags) ;
_known_lobbies_flags[scli->info.lobby_id] |= RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE;
}
// Add the chat room into subscribed chat rooms
ChatLobbyEntry entry ;
(ChatLobbyInfo&)entry = scli->info;
entry.virtual_peer_id = makeVirtualPeerId(entry.lobby_id) ; // not random, so we keep the same id at restart
entry.connexion_challenge_count = 0 ;
entry.last_activity = now ;
entry.last_connexion_challenge_time = now ;
entry.last_keep_alive_packet_time = now ;
RS_STACK_MUTEX(mDistributedChatMtx); /********** STACK LOCKED MTX ******/
_chat_lobbys[entry.lobby_id] = entry ;
// make the UI aware of the existing chat room
RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_ADD) ;
return true;
}
return false ;
}

View File

@ -21,6 +21,7 @@
*******************************************************************************/
#include <stdexcept>
#include "retroshare/rsmsgs.h"
#include "util/rstime.h"
#include "serialiser/rsbaseserial.h"
#include "serialiser/rstlvbase.h"
@ -52,6 +53,7 @@ RsItem *RsChatSerialiser::create_item(uint16_t service_id,uint8_t item_sub_id) c
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST: return new RsChatLobbyListRequestItem();
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST: return new RsChatLobbyListItem();
case RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG: return new RsChatLobbyConfigItem();
case RS_PKT_SUBTYPE_SUBSCRIBED_CHAT_LOBBY_CONFIG: return new RsSubscribedChatLobbyConfigItem();
case RS_PKT_SUBTYPE_OUTGOING_MAP: return new PrivateOugoingMapItem();
default:
std::cerr << "Unknown packet type in chat!" << std::endl;
@ -172,6 +174,11 @@ void RsChatAvatarItem::serial_process(RsGenericSerializer::SerializeJob j,RsGene
RsTypeSerializer::serial_process(j,ctx,b,"image data") ;
}
void RsSubscribedChatLobbyConfigItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
info.serial_process(j,ctx);
}
void RsChatLobbyConfigItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
RsTypeSerializer::serial_process<uint64_t>(j,ctx,lobby_Id,"lobby_Id") ;

View File

@ -34,6 +34,7 @@
#include "serialiser/rstlvidset.h"
#include "serialiser/rstlvfileitem.h"
#include "retroshare/rsmsgs.h"
/* chat Flags */
const uint32_t RS_CHAT_FLAG_PRIVATE = 0x0001;
@ -82,6 +83,8 @@ const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE_DEPRECATED = 0x1A ; // to be remo
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE = 0x1B ;
const uint8_t RS_PKT_SUBTYPE_OUTGOING_MAP = 0x1C ;
const uint8_t RS_PKT_SUBTYPE_SUBSCRIBED_CHAT_LOBBY_CONFIG = 0x1D ;
typedef uint64_t ChatLobbyId ;
typedef uint64_t ChatLobbyMsgId ;
typedef std::string ChatLobbyNickName ;
@ -298,6 +301,19 @@ struct RsPrivateChatMsgConfigItem : RsChatItem
uint32_t recvTime;
};
class RsSubscribedChatLobbyConfigItem: public RsChatItem
{
public:
RsSubscribedChatLobbyConfigItem() :RsChatItem(RS_PKT_SUBTYPE_SUBSCRIBED_CHAT_LOBBY_CONFIG) {}
virtual ~RsSubscribedChatLobbyConfigItem() {}
virtual void clear() { RsChatItem::clear(); info.clear(); }
void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
ChatLobbyInfo info;
};
class RsChatLobbyConfigItem: public RsChatItem
{
public:

View File

@ -470,6 +470,8 @@ public:
std::map<RsGxsId, rstime_t> gxs_ids ; // list of non direct friend who participate. Used to display only.
rstime_t last_activity ; // last recorded activity. Useful for removing dead lobbies.
virtual void clear() { gxs_ids.clear(); lobby_id = 0; lobby_name.clear(); lobby_topic.clear(); participating_friends.clear(); }
// RsSerializable interface
public:
void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext &ctx) {

View File

@ -331,10 +331,14 @@ void ChatLobbyWidget::lobbyTreeWidgetCustomPopupMenu(QPoint)
}
}
#ifdef TO_BE_REMOVED
// This code is not needed anymore because AutoSubscribe is now automatically handled with chat room subscription.
if (item->data(COLUMN_DATA, ROLE_AUTOSUBSCRIBE).toBool())
contextMnu.addAction(QIcon(IMAGE_AUTOSUBSCRIBE), tr("Remove Auto Subscribe"), this, SLOT(autoSubscribeItem()));
else if(!own_identities.empty())
contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Add Auto Subscribe"), this, SLOT(autoSubscribeItem()));
#endif
contextMnu.addAction(QIcon(IMAGE_COPYRSLINK), tr("Copy RetroShare Link"), this, SLOT(copyItemLink()));
}
@ -603,9 +607,12 @@ void ChatLobbyWidget::updateDisplay()
item->setIcon(COLUMN_NAME, subscribed ? icon : icon.pixmap(ui.lobbyTreeWidget->iconSize(), QIcon::Disabled));
}
// In the new model (after lobby save to disk) the auto-subscribe flag is used to automatically join lobbies that where
// previously being used when the software quits.
bool autoSubscribe = rsMsgs->getLobbyAutoSubscribe(lobby.lobby_id);
if (autoSubscribe && subscribed)
if (autoSubscribe && !subscribed)
{
if(_lobby_infos.find(lobby.lobby_id) == _lobby_infos.end())
{
@ -674,6 +681,16 @@ void ChatLobbyWidget::updateDisplay()
bool autoSubscribe = rsMsgs->getLobbyAutoSubscribe(lobby.lobby_id);
updateItem(ui.lobbyTreeWidget, item, lobby.lobby_id, lobby.lobby_name,lobby.lobby_topic, lobby.gxs_ids.size(), true, autoSubscribe,lobby_flags);
std::map<ChatLobbyId,ChatLobbyInfoStruct>::iterator it = _lobby_infos.find(lobby.lobby_id) ;
// look for chat rooms that are subscribed but not displayed as such
if(it == _lobby_infos.end() && rsMsgs->joinVisibleChatLobby(lobby.lobby_id,lobby.gxs_id))
{
std::cerr << "Adding back ChatLobbyDialog for subscribed lobby " << std::hex << lobby.lobby_id << std::dec << std::endl;
ChatDialog::chatFriend(ChatId(lobby.lobby_id),false) ;
}
}
publicSubLobbyItem->setHidden(publicSubLobbyItem->childCount()==0);
publicSubLobbyItem->setText(COLUMN_NAME, tr("Public Subscribed chat rooms")+ QString(" (") + QString::number(publicSubLobbyItem->childCount())+QString(")"));

View File

@ -172,6 +172,16 @@ MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags flags)
ui = new Ui::MainWindow;
trayIcon = NULL;
friendsDialog=NULL;
idDialog=NULL;
chatLobbyDialog=NULL;
settingsDialog=NULL;
transfersDialog=NULL;
messagesDialog=NULL;
gxschannelDialog=NULL;
gxsforumDialog=NULL;
postedDialog=NULL;
/* Invoke the Qt Designer generated QObject setup routine */
ui->setupUi(this);

View File

@ -912,7 +912,10 @@ void ChatLobbyDialog::showDialog(uint chatflags)
if (chatflags & RS_CHAT_FOCUS)
{
MainWindow::showWindow(MainWindow::ChatLobby);
dynamic_cast<ChatLobbyWidget*>(MainWindow::getPage(MainWindow::ChatLobby))->setCurrentChatPage(this) ;
MainPage *p = MainWindow::getPage(MainWindow::ChatLobby);
if(p != NULL)
dynamic_cast<ChatLobbyWidget*>(p)->setCurrentChatPage(this) ;
}
}